diff options
author | will <will@FreeBSD.org> | 2010-08-11 00:51:50 +0000 |
---|---|---|
committer | will <will@FreeBSD.org> | 2010-08-11 00:51:50 +0000 |
commit | aa4e762c4a720fc3e1b4d3f08d09c5b65bb07735 (patch) | |
tree | 5194d90f80d5d4fac28f6f736d5c02cf80511112 /sys/netinet/if_ether.c | |
parent | 8afd703de9fc0419708d83e8c31c1f0facca78dd (diff) | |
download | FreeBSD-src-aa4e762c4a720fc3e1b4d3f08d09c5b65bb07735.zip FreeBSD-src-aa4e762c4a720fc3e1b4d3f08d09c5b65bb07735.tar.gz |
Allow carp(4) to be loaded as a kernel module. Follow precedent set by
bridge(4), lagg(4) etc. and make use of function pointers and
pf_proto_register() to hook carp into the network stack.
Currently, because of the uncertainty about whether the unload path is free
of race condition panics, unloads are disallowed by default. Compiling with
CARPMOD_CAN_UNLOAD in CFLAGS removes this anti foot shooting measure.
This commit requires IP6PROTOSPACER, introduced in r211115.
Reviewed by: bz, simon
Approved by: ken (mentor)
MFC after: 2 weeks
Diffstat (limited to 'sys/netinet/if_ether.c')
-rw-r--r-- | sys/netinet/if_ether.c | 21 |
1 files changed, 6 insertions, 15 deletions
diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c index ec03268..bdc981a 100644 --- a/sys/netinet/if_ether.c +++ b/sys/netinet/if_ether.c @@ -39,7 +39,6 @@ __FBSDID("$FreeBSD$"); #include "opt_inet.h" -#include "opt_carp.h" #include <sys/param.h> #include <sys/kernel.h> @@ -69,10 +68,6 @@ __FBSDID("$FreeBSD$"); #include <net/if_arc.h> #include <net/iso88025.h> -#ifdef DEV_CARP -#include <netinet/ip_carp.h> -#endif - #include <security/mac/mac_framework.h> #define SIN(s) ((struct sockaddr_in *)s) @@ -123,6 +118,10 @@ static void arptimer(void *); #ifdef INET static void in_arpinput(struct mbuf *); #endif +#if defined(INET) || defined(INET6) +int (*carp_iamatch_p)(struct ifnet *, struct in_ifaddr *, struct in_addr *, + u_int8_t **); +#endif static const struct netisr_handler arp_nh = { .nh_name = "arp", @@ -494,9 +493,7 @@ in_arpinput(struct mbuf *m) int op, flags; int req_len; int bridged = 0, is_bridge = 0; -#ifdef DEV_CARP int carp_match = 0; -#endif struct sockaddr_in sin; sin.sin_len = sizeof(struct sockaddr_in); sin.sin_family = AF_INET; @@ -539,16 +536,14 @@ in_arpinput(struct mbuf *m) IN_IFADDR_RUNLOCK(); goto match; } -#ifdef DEV_CARP if (ifp->if_carp != NULL && - carp_iamatch(ifp->if_carp, ia, &isaddr, &enaddr) && + (*carp_iamatch_p)(ifp, ia, &isaddr, &enaddr) && itaddr.s_addr == ia->ia_addr.sin_addr.s_addr) { carp_match = 1; ifa_ref(&ia->ia_ifa); IN_IFADDR_RUNLOCK(); goto match; } -#endif } LIST_FOREACH(ia, INADDR_HASH(isaddr.s_addr), ia_hash) if (((bridged && ia->ia_ifp->if_bridge != NULL) || @@ -648,11 +643,7 @@ match: IF_AFDATA_UNLOCK(ifp); if (la != NULL) { /* the following is not an error when doing bridging */ - if (!bridged && la->lle_tbl->llt_ifp != ifp -#ifdef DEV_CARP - && (ifp->if_type != IFT_CARP || !carp_match) -#endif - ) { + if (!bridged && la->lle_tbl->llt_ifp != ifp && !carp_match) { if (log_arp_wrong_iface) log(LOG_ERR, "arp: %s is on %s " "but got reply from %*D on %s\n", |