svn commit: r212482 - in stable/8/sys: modules modules/if_carp net
netinet netinet6
Will Andrews
will at FreeBSD.org
Sat Sep 11 22:02:36 UTC 2010
Author: will
Date: Sat Sep 11 22:02:36 2010
New Revision: 212482
URL: http://svn.freebsd.org/changeset/base/212482
Log:
MFC r211157, r211193, r212265, r212266: make it possible to load carp(4) as
a kld using function pointer hooks and {pf_,ip,ip6}proto_{un,}register().
Reviewed by: bz
Approved by: ken (mentor)
Added:
stable/8/sys/modules/if_carp/
- copied from r211157, head/sys/modules/if_carp/
Modified:
stable/8/sys/modules/Makefile
stable/8/sys/net/if.c
stable/8/sys/net/if_bridge.c
stable/8/sys/net/if_ethersubr.c
stable/8/sys/netinet/if_ether.c
stable/8/sys/netinet/in.c
stable/8/sys/netinet/in_proto.c
stable/8/sys/netinet/ip_carp.c
stable/8/sys/netinet/ip_carp.h
stable/8/sys/netinet/ip_input.c
stable/8/sys/netinet6/in6_proto.c
stable/8/sys/netinet6/nd6_nbr.c
Directory Properties:
stable/8/sys/ (props changed)
stable/8/sys/amd64/include/xen/ (props changed)
stable/8/sys/cddl/contrib/opensolaris/ (props changed)
stable/8/sys/contrib/dev/acpica/ (props changed)
stable/8/sys/contrib/pf/ (props changed)
stable/8/sys/dev/xen/xenpci/ (props changed)
Modified: stable/8/sys/modules/Makefile
==============================================================================
--- stable/8/sys/modules/Makefile Sat Sep 11 21:52:40 2010 (r212481)
+++ stable/8/sys/modules/Makefile Sat Sep 11 22:02:36 2010 (r212482)
@@ -111,6 +111,7 @@ SUBDIR= ${_3dfx} \
${_ida} \
${_ie} \
if_bridge \
+ if_carp \
if_disc \
if_edsc \
if_ef \
Modified: stable/8/sys/net/if.c
==============================================================================
--- stable/8/sys/net/if.c Sat Sep 11 21:52:40 2010 (r212481)
+++ stable/8/sys/net/if.c Sat Sep 11 22:02:36 2010 (r212482)
@@ -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>
@@ -81,6 +80,7 @@
/*XXX*/
#include <netinet/in.h>
#include <netinet/in_var.h>
+#include <netinet/ip_carp.h>
#ifdef INET6
#include <netinet6/in6_var.h>
#include <netinet6/in6_ifattach.h>
@@ -89,11 +89,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>
@@ -128,6 +123,22 @@ SX_SYSINIT(ifdescr_sx, &ifdescr_sx, "ifn
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);
+/* These are external hooks for CARP. */
+void (*carp_linkstate_p)(struct ifnet *ifp);
+#if defined(INET) || defined(INET6)
+struct ifnet *(*carp_forus_p)(struct ifnet *ifp, u_char *dhost);
+int (*carp_output_p)(struct ifnet *ifp, struct mbuf *m,
+ struct sockaddr *sa, struct rtentry *rt);
+#endif
+#ifdef INET
+int (*carp_iamatch_p)(struct ifnet *, struct in_ifaddr *, struct in_addr *,
+ u_int8_t **);
+#endif
+#ifdef INET6
+struct ifaddr *(*carp_iamatch6_p)(struct ifnet *ifp, struct in6_addr *taddr6);
+caddr_t (*carp_macmatch6_p)(struct ifnet *ifp, struct mbuf *m,
+ const struct in6_addr *taddr);
+#endif
struct mbuf *(*tbr_dequeue_ptr)(struct ifaltq *, int) = NULL;
@@ -1851,12 +1862,8 @@ if_unroute(struct ifnet *ifp, int flag,
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);
}
@@ -1877,12 +1884,8 @@ if_route(struct ifnet *ifp, int flag, in
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);
@@ -1925,12 +1928,8 @@ do_link_state_change(void *arg, int pend
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);
Modified: stable/8/sys/net/if_bridge.c
==============================================================================
--- stable/8/sys/net/if_bridge.c Sat Sep 11 21:52:40 2010 (r212481)
+++ stable/8/sys/net/if_bridge.c Sat Sep 11 22:02:36 2010 (r212482)
@@ -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>
@@ -2252,13 +2249,13 @@ bridge_input(struct ifnet *ifp, struct 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), 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), eh->ether_shost))
#else
# define OR_CARP_CHECK_WE_ARE_DST(iface)
# define OR_CARP_CHECK_WE_ARE_SRC(iface)
Modified: stable/8/sys/net/if_ethersubr.c
==============================================================================
--- stable/8/sys/net/if_ethersubr.c Sat Sep 11 21:52:40 2010 (r212481)
+++ stable/8/sys/net/if_ethersubr.c Sat Sep 11 22:02:36 2010 (r212482)
@@ -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>
@@ -402,12 +396,10 @@ ether_output(struct ifnet *ifp, struct 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) {
@@ -727,7 +719,6 @@ ether_input(struct ifnet *ifp, struct mb
}
#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.
@@ -738,11 +729,10 @@ ether_input(struct ifnet *ifp, struct mb
* 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
Modified: stable/8/sys/netinet/if_ether.c
==============================================================================
--- stable/8/sys/netinet/if_ether.c Sat Sep 11 21:52:40 2010 (r212481)
+++ stable/8/sys/netinet/if_ether.c Sat Sep 11 22:02:36 2010 (r212482)
@@ -39,7 +39,6 @@
__FBSDID("$FreeBSD$");
#include "opt_inet.h"
-#include "opt_carp.h"
#include <sys/param.h>
#include <sys/kernel.h>
@@ -65,14 +64,13 @@ __FBSDID("$FreeBSD$");
#include <netinet/in_var.h>
#include <net/if_llatbl.h>
#include <netinet/if_ether.h>
+#if defined(INET) || defined(INET6)
+#include <netinet/ip_carp.h>
+#endif
#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)
@@ -494,9 +492,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 +535,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 +642,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",
Modified: stable/8/sys/netinet/in.c
==============================================================================
--- stable/8/sys/netinet/in.c Sat Sep 11 21:52:40 2010 (r212481)
+++ stable/8/sys/netinet/in.c Sat Sep 11 22:02:36 2010 (r212482)
@@ -33,7 +33,6 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-#include "opt_carp.h"
#include "opt_mpath.h"
#include <sys/param.h>
@@ -891,13 +890,11 @@ in_ifinit(struct ifnet *ifp, struct in_i
ia->ia_net = i & ia->ia_netmask;
ia->ia_subnet = i & ia->ia_subnetmask;
in_socktrim(&ia->ia_sockmask);
-#ifdef DEV_CARP
/*
* XXX: carp(4) does not have interface route
*/
if (ifp->if_type == IFT_CARP)
return (0);
-#endif
/*
* Add route for the network.
*/
@@ -1153,12 +1150,12 @@ in_scrubprefix(struct in_ifaddr *target)
* the route itself to it. Make sure that routing daemons
* get a heads-up.
*
- * XXX: a special case for carp(4) interface
+ * XXX: a special case for carp(4) interface - this should
+ * be more generally specified as an interface that
+ * doesn't support such action.
*/
if ((ia->ia_flags & IFA_ROUTE) == 0
-#ifdef DEV_CARP
&& (ia->ia_ifp->if_type != IFT_CARP)
-#endif
) {
IN_IFADDR_RUNLOCK();
rtinit(&(target->ia_ifa), (int)RTM_DELETE,
Modified: stable/8/sys/netinet/in_proto.c
==============================================================================
--- stable/8/sys/netinet/in_proto.c Sat Sep 11 21:52:40 2010 (r212481)
+++ stable/8/sys/netinet/in_proto.c Sat Sep 11 22:02:36 2010 (r212482)
@@ -37,7 +37,6 @@ __FBSDID("$FreeBSD$");
#include "opt_ipsec.h"
#include "opt_inet6.h"
#include "opt_pf.h"
-#include "opt_carp.h"
#include "opt_sctp.h"
#include "opt_mpath.h"
@@ -94,10 +93,6 @@ static struct pr_usrreqs nousrreqs;
#include <net/if_pfsync.h>
#endif
-#ifdef DEV_CARP
-#include <netinet/ip_carp.h>
-#endif
-
extern struct domain inetdomain;
/* Spacer for loadable protocols. */
@@ -330,18 +325,6 @@ struct protosw inetsw[] = {
.pr_usrreqs = &rip_usrreqs
},
#endif /* DEV_PFSYNC */
-#ifdef DEV_CARP
-{
- .pr_type = SOCK_RAW,
- .pr_domain = &inetdomain,
- .pr_protocol = IPPROTO_CARP,
- .pr_flags = PR_ATOMIC|PR_ADDR,
- .pr_input = carp_input,
- .pr_output = (pr_output_t*)rip_output,
- .pr_ctloutput = rip_ctloutput,
- .pr_usrreqs = &rip_usrreqs
-},
-#endif /* DEV_CARP */
/* Spacer n-times for loadable protocols. */
IPPROTOSPACER,
IPPROTOSPACER,
@@ -413,6 +396,3 @@ SYSCTL_NODE(_net_inet, IPPROTO_RAW, raw,
#ifdef DEV_PFSYNC
SYSCTL_NODE(_net_inet, IPPROTO_PFSYNC, pfsync, CTLFLAG_RW, 0, "PFSYNC");
#endif
-#ifdef DEV_CARP
-SYSCTL_NODE(_net_inet, IPPROTO_CARP, carp, CTLFLAG_RW, 0, "CARP");
-#endif
Modified: stable/8/sys/netinet/ip_carp.c
==============================================================================
--- stable/8/sys/netinet/ip_carp.c Sat Sep 11 21:52:40 2010 (r212481)
+++ stable/8/sys/netinet/ip_carp.c Sat Sep 11 22:02:36 2010 (r212482)
@@ -27,7 +27,6 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-#include "opt_carp.h"
#include "opt_bpf.h"
#include "opt_inet.h"
#include "opt_inet6.h"
@@ -44,6 +43,7 @@ __FBSDID("$FreeBSD$");
#include <sys/time.h>
#include <sys/priv.h>
#include <sys/proc.h>
+#include <sys/protosw.h>
#include <sys/sysctl.h>
#include <sys/syslog.h>
#include <sys/signalvar.h>
@@ -79,6 +79,7 @@ __FBSDID("$FreeBSD$");
#ifdef INET6
#include <netinet/icmp6.h>
#include <netinet/ip6.h>
+#include <netinet6/ip6protosw.h>
#include <netinet6/ip6_var.h>
#include <netinet6/scope6_var.h>
#include <netinet6/nd6.h>
@@ -136,6 +137,7 @@ struct carp_softc {
int carp_suppress_preempt = 0;
int carp_opts[CARPCTL_MAXID] = { 0, 1, 0, 1, 0, 0 }; /* XXX for now */
+SYSCTL_NODE(_net_inet, IPPROTO_CARP, carp, CTLFLAG_RW, 0, "CARP");
SYSCTL_INT(_net_inet_carp, CARPCTL_ALLOW, allow, CTLFLAG_RW,
&carp_opts[CARPCTL_ALLOW], 0, "Accept incoming CARP packets");
SYSCTL_INT(_net_inet_carp, CARPCTL_PREEMPT, preempt, CTLFLAG_RW,
@@ -160,6 +162,10 @@ struct carp_if {
struct mtx vhif_mtx;
};
+#define CARP_INET 0
+#define CARP_INET6 1
+static int proto_reg[] = {-1, -1};
+
/* Get carp_if from softc. Valid after carp_set_addr{,6}. */
#define SC2CIF(sc) ((struct carp_if *)(sc)->sc_carpdev->if_carp)
@@ -1146,14 +1152,15 @@ carp_addrcount(struct carp_if *cif, stru
}
int
-carp_iamatch(void *v, struct in_ifaddr *ia,
+carp_iamatch(struct ifnet *ifp, struct in_ifaddr *ia,
struct in_addr *isaddr, u_int8_t **enaddr)
{
- struct carp_if *cif = v;
+ struct carp_if *cif;
struct carp_softc *vh;
int index, count = 0;
struct ifaddr *ifa;
+ cif = ifp->if_carp;
CARP_LOCK(cif);
if (carp_opts[CARPCTL_ARPBALANCE]) {
@@ -1222,12 +1229,13 @@ carp_iamatch(void *v, struct in_ifaddr *
#ifdef INET6
struct ifaddr *
-carp_iamatch6(void *v, struct in6_addr *taddr)
+carp_iamatch6(struct ifnet *ifp, struct in6_addr *taddr)
{
- struct carp_if *cif = v;
+ struct carp_if *cif;
struct carp_softc *vh;
struct ifaddr *ifa;
+ cif = ifp->if_carp;
CARP_LOCK(cif);
TAILQ_FOREACH(vh, &cif->vhif_vrs, sc_list) {
IF_ADDR_LOCK(SC2IFP(vh));
@@ -1250,14 +1258,15 @@ carp_iamatch6(void *v, struct in6_addr *
return (NULL);
}
-void *
-carp_macmatch6(void *v, struct mbuf *m, const struct in6_addr *taddr)
+caddr_t
+carp_macmatch6(struct ifnet *ifp, struct mbuf *m, const struct in6_addr *taddr)
{
struct m_tag *mtag;
- struct carp_if *cif = v;
+ struct carp_if *cif;
struct carp_softc *sc;
struct ifaddr *ifa;
+ cif = ifp->if_carp;
CARP_LOCK(cif);
TAILQ_FOREACH(sc, &cif->vhif_vrs, sc_list) {
IF_ADDR_LOCK(SC2IFP(sc));
@@ -1293,15 +1302,16 @@ carp_macmatch6(void *v, struct mbuf *m,
#endif
struct ifnet *
-carp_forus(void *v, void *dhost)
+carp_forus(struct ifnet *ifp, u_char *dhost)
{
- struct carp_if *cif = v;
+ struct carp_if *cif;
struct carp_softc *vh;
u_int8_t *ena = dhost;
if (ena[0] || ena[1] || ena[2] != 0x5e || ena[3] || ena[4] != 1)
return (NULL);
+ cif = ifp->if_carp;
CARP_LOCK(cif);
TAILQ_FOREACH(vh, &cif->vhif_vrs, sc_list)
if ((SC2IFP(vh)->if_flags & IFF_UP) &&
@@ -2209,10 +2219,11 @@ carp_set_state(struct carp_softc *sc, in
}
void
-carp_carpdev_state(void *v)
+carp_carpdev_state(struct ifnet *ifp)
{
- struct carp_if *cif = v;
+ struct carp_if *cif;
+ cif = ifp->if_carp;
CARP_LOCK(cif);
carp_carpdev_state_locked(cif);
CARP_UNLOCK(cif);
@@ -2263,24 +2274,136 @@ carp_sc_state_locked(struct carp_softc *
return;
}
+#ifdef INET
+extern struct domain inetdomain;
+static struct protosw in_carp_protosw = {
+ .pr_type = SOCK_RAW,
+ .pr_domain = &inetdomain,
+ .pr_protocol = IPPROTO_CARP,
+ .pr_flags = PR_ATOMIC|PR_ADDR,
+ .pr_input = carp_input,
+ .pr_output = (pr_output_t *)rip_output,
+ .pr_ctloutput = rip_ctloutput,
+ .pr_usrreqs = &rip_usrreqs
+};
+#endif
+
+#ifdef INET6
+extern struct domain inet6domain;
+static struct ip6protosw in6_carp_protosw = {
+ .pr_type = SOCK_RAW,
+ .pr_domain = &inet6domain,
+ .pr_protocol = IPPROTO_CARP,
+ .pr_flags = PR_ATOMIC|PR_ADDR,
+ .pr_input = carp6_input,
+ .pr_output = rip6_output,
+ .pr_ctloutput = rip6_ctloutput,
+ .pr_usrreqs = &rip6_usrreqs
+};
+#endif
+
+static void
+carp_mod_cleanup(void)
+{
+
+ if (if_detach_event_tag == NULL)
+ return;
+ EVENTHANDLER_DEREGISTER(ifnet_departure_event, if_detach_event_tag);
+ if_clone_detach(&carp_cloner);
+#ifdef INET
+ if (proto_reg[CARP_INET] == 0) {
+ (void)ipproto_unregister(IPPROTO_CARP);
+ pf_proto_unregister(PF_INET, IPPROTO_CARP, SOCK_RAW);
+ proto_reg[CARP_INET] = -1;
+ }
+ carp_iamatch_p = NULL;
+#endif
+#ifdef INET6
+ if (proto_reg[CARP_INET6] == 0) {
+ (void)ip6proto_unregister(IPPROTO_CARP);
+ pf_proto_unregister(PF_INET6, IPPROTO_CARP, SOCK_RAW);
+ proto_reg[CARP_INET6] = -1;
+ }
+ carp_iamatch6_p = NULL;
+ carp_macmatch6_p = NULL;
+#endif
+ carp_linkstate_p = NULL;
+ carp_forus_p = NULL;
+ carp_output_p = NULL;
+ mtx_destroy(&carp_mtx);
+}
+
+static int
+carp_mod_load(void)
+{
+ int err;
+
+ if_detach_event_tag = EVENTHANDLER_REGISTER(ifnet_departure_event,
+ carp_ifdetach, NULL, EVENTHANDLER_PRI_ANY);
+ if (if_detach_event_tag == NULL)
+ return (ENOMEM);
+ mtx_init(&carp_mtx, "carp_mtx", NULL, MTX_DEF);
+ LIST_INIT(&carpif_list);
+ if_clone_attach(&carp_cloner);
+ carp_linkstate_p = carp_carpdev_state;
+ carp_forus_p = carp_forus;
+ carp_output_p = carp_output;
+#ifdef INET6
+ carp_iamatch6_p = carp_iamatch6;
+ carp_macmatch6_p = carp_macmatch6;
+ proto_reg[CARP_INET6] = pf_proto_register(PF_INET6,
+ (struct protosw *)&in6_carp_protosw);
+ if (proto_reg[CARP_INET6] != 0) {
+ printf("carp: error %d attaching to PF_INET6\n",
+ proto_reg[CARP_INET6]);
+ carp_mod_cleanup();
+ return (EINVAL);
+ }
+ err = ip6proto_register(IPPROTO_CARP);
+ if (err) {
+ printf("carp: error %d registering with INET6\n", err);
+ carp_mod_cleanup();
+ return (EINVAL);
+ }
+#endif
+#ifdef INET
+ carp_iamatch_p = carp_iamatch;
+ proto_reg[CARP_INET] = pf_proto_register(PF_INET, &in_carp_protosw);
+ if (proto_reg[CARP_INET] != 0) {
+ printf("carp: error %d attaching to PF_INET\n",
+ proto_reg[CARP_INET]);
+ carp_mod_cleanup();
+ return (EINVAL);
+ }
+ err = ipproto_register(IPPROTO_CARP);
+ if (err) {
+ printf("carp: error %d registering with INET\n", err);
+ carp_mod_cleanup();
+ return (EINVAL);
+ }
+#endif
+ return 0;
+}
+
static int
carp_modevent(module_t mod, int type, void *data)
{
switch (type) {
case MOD_LOAD:
- if_detach_event_tag = EVENTHANDLER_REGISTER(ifnet_departure_event,
- carp_ifdetach, NULL, EVENTHANDLER_PRI_ANY);
- if (if_detach_event_tag == NULL)
- return (ENOMEM);
- mtx_init(&carp_mtx, "carp_mtx", NULL, MTX_DEF);
- LIST_INIT(&carpif_list);
- if_clone_attach(&carp_cloner);
- break;
-
+ return carp_mod_load();
+ /* NOTREACHED */
case MOD_UNLOAD:
- EVENTHANDLER_DEREGISTER(ifnet_departure_event, if_detach_event_tag);
- if_clone_detach(&carp_cloner);
- mtx_destroy(&carp_mtx);
+ /*
+ * XXX: For now, disallow module unloading by default due to
+ * a race condition where a thread may dereference one of the
+ * function pointer hooks after the module has been
+ * unloaded, during processing of a packet, causing a panic.
+ */
+#ifdef CARPMOD_CAN_UNLOAD
+ carp_mod_cleanup();
+#else
+ return (EBUSY);
+#endif
break;
default:
@@ -2296,4 +2419,4 @@ static moduledata_t carp_mod = {
0
};
-DECLARE_MODULE(carp, carp_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
+DECLARE_MODULE(carp, carp_mod, SI_SUB_PROTO_DOMAIN, SI_ORDER_ANY);
Modified: stable/8/sys/netinet/ip_carp.h
==============================================================================
--- stable/8/sys/netinet/ip_carp.h Sat Sep 11 21:52:40 2010 (r212481)
+++ stable/8/sys/netinet/ip_carp.h Sat Sep 11 22:02:36 2010 (r212482)
@@ -157,15 +157,35 @@ struct carpreq {
}
#ifdef _KERNEL
-void carp_carpdev_state(void *);
+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 *,
struct rtentry *);
-int carp_iamatch (void *, struct in_ifaddr *, struct in_addr *,
+int carp_iamatch (struct ifnet *, struct in_ifaddr *, struct in_addr *,
u_int8_t **);
-struct ifaddr *carp_iamatch6(void *, struct in6_addr *);
-void *carp_macmatch6(void *, struct mbuf *, const struct in6_addr *);
-struct ifnet *carp_forus (void *, void *);
+struct ifaddr *carp_iamatch6(struct ifnet *, struct in6_addr *);
+caddr_t carp_macmatch6(struct ifnet *, struct mbuf *, const struct in6_addr *);
+struct ifnet *carp_forus (struct ifnet *, u_char *);
+
+/* These are external networking stack hooks for CARP */
+/* net/if.c */
+extern void (*carp_linkstate_p)(struct ifnet *);
+/* net/if_bridge.c net/if_ethersubr.c */
+extern struct ifnet *(*carp_forus_p)(struct ifnet *, u_char *);
+/* net/if_ethersubr.c */
+extern int (*carp_output_p)(struct ifnet *, struct mbuf *,
+ struct sockaddr *, struct rtentry *);
+#ifdef INET
+/* netinet/if_ether.c */
+extern int (*carp_iamatch_p)(struct ifnet *, struct in_ifaddr *,
+ struct in_addr *, u_int8_t **);
+#endif
+#ifdef INET6
+/* netinet6/nd6_nbr.c */
+extern struct ifaddr *(*carp_iamatch6_p)(struct ifnet *, struct in6_addr *);
+extern caddr_t (*carp_macmatch6_p)(struct ifnet *, struct mbuf *,
+ const struct in6_addr *);
+#endif
#endif
#endif /* _IP_CARP_H */
Modified: stable/8/sys/netinet/ip_input.c
==============================================================================
--- stable/8/sys/netinet/ip_input.c Sat Sep 11 21:52:40 2010 (r212481)
+++ stable/8/sys/netinet/ip_input.c Sat Sep 11 22:02:36 2010 (r212482)
@@ -37,7 +37,6 @@ __FBSDID("$FreeBSD$");
#include "opt_ipstealth.h"
#include "opt_ipsec.h"
#include "opt_route.h"
-#include "opt_carp.h"
#include <sys/param.h>
#include <sys/systm.h>
@@ -74,9 +73,7 @@ __FBSDID("$FreeBSD$");
#include <netinet/ip_icmp.h>
#include <netinet/ip_options.h>
#include <machine/in_cksum.h>
-#ifdef DEV_CARP
#include <netinet/ip_carp.h>
-#endif
#ifdef IPSEC
#include <netinet/ip_ipsec.h>
#endif /* IPSEC */
@@ -606,10 +603,7 @@ passin:
*/
checkif = V_ip_checkinterface && (V_ipforwarding == 0) &&
ifp != NULL && ((ifp->if_flags & IFF_LOOPBACK) == 0) &&
-#ifdef DEV_CARP
- !ifp->if_carp &&
-#endif
- (dchg == 0);
+ ifp->if_carp == NULL && (dchg == 0);
/*
* Check for exact addresses in the hash bucket.
Modified: stable/8/sys/netinet6/in6_proto.c
==============================================================================
--- stable/8/sys/netinet6/in6_proto.c Sat Sep 11 21:52:40 2010 (r212481)
+++ stable/8/sys/netinet6/in6_proto.c Sat Sep 11 22:02:36 2010 (r212482)
@@ -67,7 +67,6 @@ __FBSDID("$FreeBSD$");
#include "opt_inet6.h"
#include "opt_ipsec.h"
#include "opt_ipstealth.h"
-#include "opt_carp.h"
#include "opt_sctp.h"
#include "opt_mpath.h"
@@ -111,10 +110,6 @@ __FBSDID("$FreeBSD$");
#include <netinet6/pim6_var.h>
#include <netinet6/nd6.h>
-#ifdef DEV_CARP
-#include <netinet/ip_carp.h>
-#endif
-
#ifdef SCTP
#include <netinet/in_pcb.h>
#include <netinet/sctp_pcb.h>
@@ -331,18 +326,6 @@ struct ip6protosw inet6sw[] = {
.pr_ctloutput = rip6_ctloutput,
.pr_usrreqs = &rip6_usrreqs
},
-#ifdef DEV_CARP
-{
- .pr_type = SOCK_RAW,
- .pr_domain = &inet6domain,
- .pr_protocol = IPPROTO_CARP,
- .pr_flags = PR_ATOMIC|PR_ADDR,
- .pr_input = carp6_input,
- .pr_output = rip6_output,
- .pr_ctloutput = rip6_ctloutput,
- .pr_usrreqs = &rip6_usrreqs
-},
-#endif /* DEV_CARP */
/* Spacer n-times for loadable protocols. */
IP6PROTOSPACER,
IP6PROTOSPACER,
Modified: stable/8/sys/netinet6/nd6_nbr.c
==============================================================================
--- stable/8/sys/netinet6/nd6_nbr.c Sat Sep 11 21:52:40 2010 (r212481)
+++ stable/8/sys/netinet6/nd6_nbr.c Sat Sep 11 22:02:36 2010 (r212482)
@@ -35,7 +35,6 @@ __FBSDID("$FreeBSD$");
#include "opt_inet.h"
#include "opt_inet6.h"
#include "opt_ipsec.h"
-#include "opt_carp.h"
#include "opt_mpath.h"
#include <sys/param.h>
@@ -73,10 +72,7 @@ __FBSDID("$FreeBSD$");
#include <netinet6/scope6_var.h>
#include <netinet6/nd6.h>
#include <netinet/icmp6.h>
-
-#ifdef DEV_CARP
#include <netinet/ip_carp.h>
-#endif
#define SDL(s) ((struct sockaddr_dl *)s)
@@ -222,14 +218,10 @@ nd6_ns_input(struct mbuf *m, int off, in
* (3) "tentative" address on which DAD is being performed.
*/
/* (1) and (3) check. */
-#ifdef DEV_CARP
if (ifp->if_carp)
- ifa = carp_iamatch6(ifp->if_carp, &taddr6);
+ ifa = (*carp_iamatch6_p)(ifp, &taddr6);
if (ifa == NULL)
ifa = (struct ifaddr *)in6ifa_ifpwithaddr(ifp, &taddr6);
-#else
- ifa = (struct ifaddr *)in6ifa_ifpwithaddr(ifp, &taddr6);
-#endif
/* (2) check. */
if (ifa == NULL) {
@@ -1029,14 +1021,10 @@ nd6_na_output(struct ifnet *ifp, const s
* my address) use lladdr configured for the interface.
*/
if (sdl0 == NULL) {
-#ifdef DEV_CARP
if (ifp->if_carp)
- mac = carp_macmatch6(ifp->if_carp, m, taddr6);
+ mac = (*carp_macmatch6_p)(ifp, m, taddr6);
if (mac == NULL)
mac = nd6_ifptomac(ifp);
-#else
- mac = nd6_ifptomac(ifp);
-#endif
} else if (sdl0->sa_family == AF_LINK) {
struct sockaddr_dl *sdl;
sdl = (struct sockaddr_dl *)sdl0;
More information about the svn-src-stable
mailing list