summaryrefslogtreecommitdiffstats
path: root/sys/netinet
diff options
context:
space:
mode:
authorglebius <glebius@FreeBSD.org>2013-02-11 10:58:22 +0000
committerglebius <glebius@FreeBSD.org>2013-02-11 10:58:22 +0000
commita47c0295c5e9d047b28372a33fcabe99a178107f (patch)
treea4b3a19176d84f646cb98e85f72832bbb0fa72ae /sys/netinet
parentc990c7deec1df4c9024ad3f642005c53e9d7f9c9 (diff)
downloadFreeBSD-src-a47c0295c5e9d047b28372a33fcabe99a178107f.zip
FreeBSD-src-a47c0295c5e9d047b28372a33fcabe99a178107f.tar.gz
Resolve source address selection in presense of CARP. Add a couple
of helper functions: - carp_master() - boolean function which is true if an address is in the MASTER state. - ifa_preferred() - boolean function that compares two addresses, and is aware of CARP. Utilize ifa_preferred() in ifa_ifwithnet(). The previous version of patch also changed source address selection logic in jails using carp_master(), but we failed to negotiate this part with Bjoern. May be we will approach this problem again later. Reported & tested by: Anton Yuzhaninov <citrin citrin.ru> Sponsored by: Nginx, Inc
Diffstat (limited to 'sys/netinet')
-rw-r--r--sys/netinet/ip_carp.c10
-rw-r--r--sys/netinet/ip_carp.h2
2 files changed, 12 insertions, 0 deletions
diff --git a/sys/netinet/ip_carp.c b/sys/netinet/ip_carp.c
index ac6b043..ae3da96 100644
--- a/sys/netinet/ip_carp.c
+++ b/sys/netinet/ip_carp.c
@@ -969,6 +969,14 @@ carp_ifa_delroute(struct ifaddr *ifa)
}
}
+int
+carp_master(struct ifaddr *ifa)
+{
+ struct carp_softc *sc = ifa->ifa_carp;
+
+ return (sc->sc_state == MASTER);
+}
+
#ifdef INET
/*
* Broadcast a gratuitous ARP request containing
@@ -2072,6 +2080,7 @@ carp_mod_cleanup(void)
carp_forus_p = NULL;
carp_output_p = NULL;
carp_demote_adj_p = NULL;
+ carp_master_p = NULL;
mtx_unlock(&carp_mtx);
taskqueue_drain(taskqueue_swi, &carp_sendall_task);
mtx_destroy(&carp_mtx);
@@ -2092,6 +2101,7 @@ carp_mod_load(void)
carp_attach_p = carp_attach;
carp_detach_p = carp_detach;
carp_demote_adj_p = carp_demote_adj;
+ carp_master_p = carp_master;
#ifdef INET6
carp_iamatch6_p = carp_iamatch6;
carp_macmatch6_p = carp_macmatch6;
diff --git a/sys/netinet/ip_carp.h b/sys/netinet/ip_carp.h
index 7be91c0..22b08b2 100644
--- a/sys/netinet/ip_carp.h
+++ b/sys/netinet/ip_carp.h
@@ -148,6 +148,7 @@ void carp_carpdev_state(struct ifnet *);
void carp_input (struct mbuf *, int);
int carp6_input (struct mbuf **, int *, int);
int carp_output (struct ifnet *, struct mbuf *, struct sockaddr *);
+int carp_master(struct ifaddr *);
int carp_iamatch(struct ifaddr *, uint8_t **);
struct ifaddr *carp_iamatch6(struct ifnet *, struct in6_addr *);
caddr_t carp_macmatch6(struct ifnet *, struct mbuf *, const struct in6_addr *);
@@ -160,6 +161,7 @@ extern int (*carp_attach_p)(struct ifaddr *, int);
extern void (*carp_detach_p)(struct ifaddr *);
extern void (*carp_linkstate_p)(struct ifnet *);
extern void (*carp_demote_adj_p)(int, char *);
+extern int (*carp_master_p)(struct ifaddr *);
/* net/if_bridge.c net/if_ethersubr.c */
extern int (*carp_forus_p)(struct ifnet *, u_char *);
/* net/if_ethersubr.c */
OpenPOWER on IntegriCloud