diff options
author | glebius <glebius@FreeBSD.org> | 2013-02-11 10:58:22 +0000 |
---|---|---|
committer | glebius <glebius@FreeBSD.org> | 2013-02-11 10:58:22 +0000 |
commit | a47c0295c5e9d047b28372a33fcabe99a178107f (patch) | |
tree | a4b3a19176d84f646cb98e85f72832bbb0fa72ae /sys/netinet | |
parent | c990c7deec1df4c9024ad3f642005c53e9d7f9c9 (diff) | |
download | FreeBSD-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.c | 10 | ||||
-rw-r--r-- | sys/netinet/ip_carp.h | 2 |
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 */ |