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/net | |
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/net')
-rw-r--r-- | sys/net/if.c | 25 | ||||
-rw-r--r-- | sys/net/if_bridge.c | 13 | ||||
-rw-r--r-- | sys/net/if_ethersubr.c | 21 |
3 files changed, 19 insertions, 40 deletions
diff --git a/sys/net/if.c b/sys/net/if.c index da323cc..3c4ad16 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -33,7 +33,6 @@ #include "opt_compat.h" #include "opt_inet6.h" #include "opt_inet.h" -#include "opt_carp.h" #include "opt_ddb.h" #include <sys/param.h> @@ -89,11 +88,6 @@ #ifdef INET #include <netinet/if_ether.h> #endif -#if defined(INET) || defined(INET6) -#ifdef DEV_CARP -#include <netinet/ip_carp.h> -#endif -#endif #include <security/mac/mac_framework.h> @@ -130,6 +124,7 @@ SX_SYSINIT(ifdescr_sx, &ifdescr_sx, "ifnet descr"); void (*bstp_linkstate_p)(struct ifnet *ifp, int state); void (*ng_ether_link_state_p)(struct ifnet *ifp, int state); void (*lagg_linkstate_p)(struct ifnet *ifp, int state); +void (*carp_linkstate_p)(struct ifnet *ifp); struct mbuf *(*tbr_dequeue_ptr)(struct ifaltq *, int) = NULL; @@ -1813,12 +1808,8 @@ if_unroute(struct ifnet *ifp, int flag, int fam) pfctlinput(PRC_IFDOWN, ifa->ifa_addr); ifp->if_qflush(ifp); -#if defined(INET) || defined(INET6) -#ifdef DEV_CARP if (ifp->if_carp) - carp_carpdev_state(ifp->if_carp); -#endif -#endif + (*carp_linkstate_p)(ifp); rt_ifmsg(ifp); } @@ -1839,12 +1830,8 @@ if_route(struct ifnet *ifp, int flag, int fam) TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) if (fam == PF_UNSPEC || (fam == ifa->ifa_addr->sa_family)) pfctlinput(PRC_IFUP, ifa->ifa_addr); -#if defined(INET) || defined(INET6) -#ifdef DEV_CARP if (ifp->if_carp) - carp_carpdev_state(ifp->if_carp); -#endif -#endif + (*carp_linkstate_p)(ifp); rt_ifmsg(ifp); #ifdef INET6 in6_if_up(ifp); @@ -1887,12 +1874,8 @@ do_link_state_change(void *arg, int pending) if ((ifp->if_type == IFT_ETHER || ifp->if_type == IFT_L2VLAN) && IFP2AC(ifp)->ac_netgraph != NULL) (*ng_ether_link_state_p)(ifp, link_state); -#if defined(INET) || defined(INET6) -#ifdef DEV_CARP if (ifp->if_carp) - carp_carpdev_state(ifp->if_carp); -#endif -#endif + (*carp_linkstate_p)(ifp); if (ifp->if_bridge) { KASSERT(bstp_linkstate_p != NULL,("if_bridge bstp not loaded!")); (*bstp_linkstate_p)(ifp, link_state); diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c index 5f33dd5..fb04731 100644 --- a/sys/net/if_bridge.c +++ b/sys/net/if_bridge.c @@ -79,7 +79,6 @@ __FBSDID("$FreeBSD$"); #include "opt_inet.h" #include "opt_inet6.h" -#include "opt_carp.h" #include <sys/param.h> #include <sys/mbuf.h> @@ -121,10 +120,8 @@ __FBSDID("$FreeBSD$"); #include <netinet6/ip6_var.h> #endif #if defined(INET) || defined(INET6) -#ifdef DEV_CARP #include <netinet/ip_carp.h> #endif -#endif #include <machine/in_cksum.h> #include <netinet/if_ether.h> /* for struct arpcom */ #include <net/bridgestp.h> @@ -2144,6 +2141,10 @@ drop: m_freem(m); } +#if defined(INET) || defined(INET6) +int (*carp_forus_p)(struct carp_if *, u_char *); +#endif + /* * bridge_input: * @@ -2252,13 +2253,13 @@ bridge_input(struct ifnet *ifp, struct mbuf *m) return (m); } -#if (defined(INET) || defined(INET6)) && defined(DEV_CARP) +#if (defined(INET) || defined(INET6)) # define OR_CARP_CHECK_WE_ARE_DST(iface) \ || ((iface)->if_carp \ - && carp_forus((iface)->if_carp, eh->ether_dhost)) + && (*carp_forus_p)((iface)->if_carp, eh->ether_dhost)) # define OR_CARP_CHECK_WE_ARE_SRC(iface) \ || ((iface)->if_carp \ - && carp_forus((iface)->if_carp, eh->ether_shost)) + && (*carp_forus_p)((iface)->if_carp, eh->ether_shost)) #else # define OR_CARP_CHECK_WE_ARE_DST(iface) # define OR_CARP_CHECK_WE_ARE_SRC(iface) diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c index bbf9753..984d0bb 100644 --- a/sys/net/if_ethersubr.c +++ b/sys/net/if_ethersubr.c @@ -35,7 +35,6 @@ #include "opt_inet6.h" #include "opt_ipx.h" #include "opt_netgraph.h" -#include "opt_carp.h" #include "opt_mbuf_profiling.h" #include <sys/param.h> @@ -70,6 +69,7 @@ #include <netinet/in.h> #include <netinet/in_var.h> #include <netinet/if_ether.h> +#include <netinet/ip_carp.h> #include <netinet/ip_var.h> #include <netinet/ip_fw.h> #include <netinet/ipfw/ip_fw_private.h> @@ -78,12 +78,6 @@ #include <netinet6/nd6.h> #endif -#if defined(INET) || defined(INET6) -#ifdef DEV_CARP -#include <netinet/ip_carp.h> -#endif -#endif - #ifdef IPX #include <netipx/ipx.h> #include <netipx/ipx_if.h> @@ -120,6 +114,11 @@ void (*ng_ether_attach_p)(struct ifnet *ifp); void (*ng_ether_detach_p)(struct ifnet *ifp); void (*vlan_input_p)(struct ifnet *, struct mbuf *); +#if defined(INET) || defined(INET6) +int (*carp_forus_p)(struct ifnet *, u_char *); +int (*carp_output_p)(struct ifnet *, struct mbuf *, struct sockaddr *, + struct rtentry *); +#endif /* if_bridge(4) support */ struct mbuf *(*bridge_input_p)(struct ifnet *, struct mbuf *); @@ -399,12 +398,10 @@ ether_output(struct ifnet *ifp, struct mbuf *m, } #if defined(INET) || defined(INET6) -#ifdef DEV_CARP if (ifp->if_carp && - (error = carp_output(ifp, m, dst, NULL))) + (error = (*carp_output_p)(ifp, m, dst, NULL))) goto bad; #endif -#endif /* Handle ng_ether(4) processing, if any */ if (IFP2AC(ifp)->ac_netgraph != NULL) { @@ -724,7 +721,6 @@ ether_input(struct ifnet *ifp, struct mbuf *m) } #if defined(INET) || defined(INET6) -#ifdef DEV_CARP /* * Clear M_PROMISC on frame so that carp(4) will see it when the * mbuf flows up to Layer 3. @@ -735,11 +731,10 @@ ether_input(struct ifnet *ifp, struct mbuf *m) * TODO: Maintain a hash table of ethernet addresses other than * ether_dhost which may be active on this ifp. */ - if (ifp->if_carp && carp_forus(ifp->if_carp, eh->ether_dhost)) { + if (ifp->if_carp && (*carp_forus_p)(ifp, eh->ether_dhost)) { m->m_flags &= ~M_PROMISC; } else #endif -#endif { /* * If the frame received was not for our MAC address, set the |