summaryrefslogtreecommitdiffstats
path: root/sys/net
diff options
context:
space:
mode:
authorwill <will@FreeBSD.org>2010-08-11 00:51:50 +0000
committerwill <will@FreeBSD.org>2010-08-11 00:51:50 +0000
commitaa4e762c4a720fc3e1b4d3f08d09c5b65bb07735 (patch)
tree5194d90f80d5d4fac28f6f736d5c02cf80511112 /sys/net
parent8afd703de9fc0419708d83e8c31c1f0facca78dd (diff)
downloadFreeBSD-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.c25
-rw-r--r--sys/net/if_bridge.c13
-rw-r--r--sys/net/if_ethersubr.c21
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
OpenPOWER on IntegriCloud