Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 24 Apr 2016 16:41:54 +0000 (UTC)
From:      "Bjoern A. Zeeb" <bz@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r298548 - in projects/vnet/sys: net netinet netinet6
Message-ID:  <201604241641.u3OGfsG5080361@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: bz
Date: Sun Apr 24 16:41:54 2016
New Revision: 298548
URL: https://svnweb.freebsd.org/changeset/base/298548

Log:
  Virtualise the netisr registration in order to do a per-vnet
  de-registration to prevent further packets for a specific protocol
  (IP, ARP, IPv6) to come up from ether_demux().
  We currently have not better "plug-and-play" hook in place at that
  level but should think about that in some distant future (e.g.,
  to one day be able to load ip, or ipv6).
  
  Note: this commit will be reverted soon.  It turns out that while
  the idea is good, and basically works, it can possibly lead to
  deadlocks.
  
  Sponsored by:	The FreeBSD Foundation

Modified:
  projects/vnet/sys/net/if_epair.c
  projects/vnet/sys/net/if_ethersubr.c
  projects/vnet/sys/net/netisr.c
  projects/vnet/sys/net/rtsock.c
  projects/vnet/sys/netinet/if_ether.c
  projects/vnet/sys/netinet/igmp.c
  projects/vnet/sys/netinet/ip_input.c
  projects/vnet/sys/netinet6/ip6_input.c

Modified: projects/vnet/sys/net/if_epair.c
==============================================================================
--- projects/vnet/sys/net/if_epair.c	Sun Apr 24 16:36:33 2016	(r298547)
+++ projects/vnet/sys/net/if_epair.c	Sun Apr 24 16:41:54 2016	(r298548)
@@ -959,6 +959,7 @@ vnet_epair_init(const void *unused __unu
 
 	V_epair_cloner = if_clone_advanced(epairname, 0,
 	    epair_clone_match, epair_clone_create, epair_clone_destroy);
+	netisr_register(&epair_nh);
 }
 VNET_SYSINIT(vnet_epair_init, SI_SUB_PSEUDO, SI_ORDER_ANY,
     vnet_epair_init, NULL);
@@ -967,6 +968,7 @@ static void
 vnet_epair_uninit(const void *unused __unused)
 {
 
+	netisr_unregister(&epair_nh);
 	if_clone_detach(V_epair_cloner);
 }
 VNET_SYSUNINIT(vnet_epair_uninit, SI_SUB_INIT_IF, SI_ORDER_ANY,
@@ -984,12 +986,10 @@ epair_modevent(module_t mod, int type, v
 		epair_nh.nh_qlimit = 42 * ifqmaxlen; /* 42 shall be the number. */
 		if (TUNABLE_INT_FETCH("net.link.epair.netisr_maxqlen", &qlimit))
 		    epair_nh.nh_qlimit = qlimit;
-		netisr_register(&epair_nh);
 		if (bootverbose)
 			printf("%s initialized.\n", epairname);
 		break;
 	case MOD_UNLOAD:
-		netisr_unregister(&epair_nh);
 		epair_dpcpu_detach();
 		if (bootverbose)
 			printf("%s unloaded.\n", epairname);
@@ -1006,5 +1006,5 @@ static moduledata_t epair_mod = {
 	0
 };
 
-DECLARE_MODULE(if_epair, epair_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
+DECLARE_MODULE(if_epair, epair_mod, SI_SUB_PSEUDO, SI_ORDER_MIDDLE);
 MODULE_VERSION(if_epair, 1);

Modified: projects/vnet/sys/net/if_ethersubr.c
==============================================================================
--- projects/vnet/sys/net/if_ethersubr.c	Sun Apr 24 16:36:33 2016	(r298547)
+++ projects/vnet/sys/net/if_ethersubr.c	Sun Apr 24 16:41:54 2016	(r298548)
@@ -654,14 +654,6 @@ static struct netisr_handler	ether_nh = 
 };
 
 static void
-ether_init(__unused void *arg)
-{
-
-	netisr_register(&ether_nh);
-}
-SYSINIT(ether, SI_SUB_INIT_IF, SI_ORDER_ANY, ether_init, NULL);
-
-static void
 vnet_ether_init(__unused void *arg)
 {
 	int i;
@@ -672,12 +664,13 @@ vnet_ether_init(__unused void *arg)
 	if ((i = pfil_head_register(&V_link_pfil_hook)) != 0)
 		printf("%s: WARNING: unable to register pfil link hook, "
 			"error %d\n", __func__, i);
+	netisr_register(&ether_nh);
 }
 VNET_SYSINIT(vnet_ether_init, SI_SUB_PROTO_IF, SI_ORDER_ANY,
     vnet_ether_init, NULL);
  
 static void
-vnet_ether_destroy(__unused void *arg)
+vnet_ether_pfil_destroy(__unused void *arg)
 {
 	int i;
 
@@ -685,10 +678,17 @@ vnet_ether_destroy(__unused void *arg)
 		printf("%s: WARNING: unable to unregister pfil link hook, "
 			"error %d\n", __func__, i);
 }
-VNET_SYSUNINIT(vnet_ether_uninit, SI_SUB_PROTO_PFIL, SI_ORDER_ANY,
-    vnet_ether_destroy, NULL);
+VNET_SYSUNINIT(vnet_ether_pfil_uninit, SI_SUB_PROTO_PFIL, SI_ORDER_ANY,
+    vnet_ether_pfil_destroy, NULL);
 
+static void
+vnet_ether_destroy(__unused void *arg)
+{
 
+	netisr_unregister(&ether_nh);
+}
+VNET_SYSUNINIT(vnet_ether_uninit, SI_SUB_PROTO_IF, SI_ORDER_ANY,
+    vnet_ether_destroy, NULL);
 
 static void
 ether_input(struct ifnet *ifp, struct mbuf *m)
@@ -710,7 +710,9 @@ ether_input(struct ifnet *ifp, struct mb
 		 * so assert it is correct here.
 		 */
 		KASSERT(m->m_pkthdr.rcvif == ifp, ("%s: ifnet mismatch", __func__));
+		CURVNET_SET_QUIET(ifp->if_vnet);
 		netisr_dispatch(NETISR_ETHER, m);
+		CURVNET_RESTORE();
 		m = mn;
 	}
 }

Modified: projects/vnet/sys/net/netisr.c
==============================================================================
--- projects/vnet/sys/net/netisr.c	Sun Apr 24 16:36:33 2016	(r298547)
+++ projects/vnet/sys/net/netisr.c	Sun Apr 24 16:41:54 2016	(r298548)
@@ -208,7 +208,8 @@ SYSCTL_UINT(_net_isr, OID_AUTO, maxprot,
  * The netisr_proto array describes all registered protocols, indexed by
  * protocol number.  See netisr_internal.h for more details.
  */
-static struct netisr_proto	netisr_proto[NETISR_MAXPROT];
+static VNET_DEFINE(struct netisr_proto,	netisr_proto[NETISR_MAXPROT]);
+#define	V_netisr_proto		VNET(netisr_proto)
 
 /*
  * Per-CPU workstream data.  See netisr_internal.h for more details.
@@ -396,31 +397,31 @@ netisr_register(const struct netisr_hand
 	 * Test that no existing registration exists for this protocol.
 	 */
 	NETISR_WLOCK();
-	KASSERT(netisr_proto[proto].np_name == NULL,
+	KASSERT(V_netisr_proto[proto].np_name == NULL,
 	    ("%s(%u, %s): name present", __func__, proto, name));
-	KASSERT(netisr_proto[proto].np_handler == NULL,
+	KASSERT(V_netisr_proto[proto].np_handler == NULL,
 	    ("%s(%u, %s): handler present", __func__, proto, name));
 
-	netisr_proto[proto].np_name = name;
-	netisr_proto[proto].np_handler = nhp->nh_handler;
-	netisr_proto[proto].np_m2flow = nhp->nh_m2flow;
-	netisr_proto[proto].np_m2cpuid = nhp->nh_m2cpuid;
-	netisr_proto[proto].np_drainedcpu = nhp->nh_drainedcpu;
+	V_netisr_proto[proto].np_name = name;
+	V_netisr_proto[proto].np_handler = nhp->nh_handler;
+	V_netisr_proto[proto].np_m2flow = nhp->nh_m2flow;
+	V_netisr_proto[proto].np_m2cpuid = nhp->nh_m2cpuid;
+	V_netisr_proto[proto].np_drainedcpu = nhp->nh_drainedcpu;
 	if (nhp->nh_qlimit == 0)
-		netisr_proto[proto].np_qlimit = netisr_defaultqlimit;
+		V_netisr_proto[proto].np_qlimit = netisr_defaultqlimit;
 	else if (nhp->nh_qlimit > netisr_maxqlimit) {
 		printf("%s: %s requested queue limit %u capped to "
 		    "net.isr.maxqlimit %u\n", __func__, name, nhp->nh_qlimit,
 		    netisr_maxqlimit);
-		netisr_proto[proto].np_qlimit = netisr_maxqlimit;
+		V_netisr_proto[proto].np_qlimit = netisr_maxqlimit;
 	} else
-		netisr_proto[proto].np_qlimit = nhp->nh_qlimit;
-	netisr_proto[proto].np_policy = nhp->nh_policy;
-	netisr_proto[proto].np_dispatch = nhp->nh_dispatch;
+		V_netisr_proto[proto].np_qlimit = nhp->nh_qlimit;
+	V_netisr_proto[proto].np_policy = nhp->nh_policy;
+	V_netisr_proto[proto].np_dispatch = nhp->nh_dispatch;
 	CPU_FOREACH(i) {
 		npwp = &(DPCPU_ID_PTR(i, nws))->nws_work[proto];
 		bzero(npwp, sizeof(*npwp));
-		npwp->nw_qlimit = netisr_proto[proto].np_qlimit;
+		npwp->nw_qlimit = V_netisr_proto[proto].np_qlimit;
 	}
 	NETISR_WUNLOCK();
 }
@@ -445,7 +446,7 @@ netisr_clearqdrops(const struct netisr_h
 	    ("%s(%u): protocol too big for %s", __func__, proto, name));
 
 	NETISR_WLOCK();
-	KASSERT(netisr_proto[proto].np_handler != NULL,
+	KASSERT(V_netisr_proto[proto].np_handler != NULL,
 	    ("%s(%u): protocol not registered for %s", __func__, proto,
 	    name));
 
@@ -478,7 +479,7 @@ netisr_getqdrops(const struct netisr_han
 	    ("%s(%u): protocol too big for %s", __func__, proto, name));
 
 	NETISR_RLOCK(&tracker);
-	KASSERT(netisr_proto[proto].np_handler != NULL,
+	KASSERT(V_netisr_proto[proto].np_handler != NULL,
 	    ("%s(%u): protocol not registered for %s", __func__, proto,
 	    name));
 
@@ -509,10 +510,10 @@ netisr_getqlimit(const struct netisr_han
 	    ("%s(%u): protocol too big for %s", __func__, proto, name));
 
 	NETISR_RLOCK(&tracker);
-	KASSERT(netisr_proto[proto].np_handler != NULL,
+	KASSERT(V_netisr_proto[proto].np_handler != NULL,
 	    ("%s(%u): protocol not registered for %s", __func__, proto,
 	    name));
-	*qlimitp = netisr_proto[proto].np_qlimit;
+	*qlimitp = V_netisr_proto[proto].np_qlimit;
 	NETISR_RUNLOCK(&tracker);
 }
 
@@ -541,11 +542,11 @@ netisr_setqlimit(const struct netisr_han
 	    ("%s(%u): protocol too big for %s", __func__, proto, name));
 
 	NETISR_WLOCK();
-	KASSERT(netisr_proto[proto].np_handler != NULL,
+	KASSERT(V_netisr_proto[proto].np_handler != NULL,
 	    ("%s(%u): protocol not registered for %s", __func__, proto,
 	    name));
 
-	netisr_proto[proto].np_qlimit = qlimit;
+	V_netisr_proto[proto].np_qlimit = qlimit;
 	CPU_FOREACH(i) {
 		npwp = &(DPCPU_ID_PTR(i, nws))->nws_work[proto];
 		npwp->nw_qlimit = qlimit;
@@ -600,16 +601,16 @@ netisr_unregister(const struct netisr_ha
 	    ("%s(%u): protocol too big for %s", __func__, proto, name));
 
 	NETISR_WLOCK();
-	KASSERT(netisr_proto[proto].np_handler != NULL,
+	KASSERT(V_netisr_proto[proto].np_handler != NULL,
 	    ("%s(%u): protocol not registered for %s", __func__, proto,
 	    name));
 
-	netisr_proto[proto].np_name = NULL;
-	netisr_proto[proto].np_handler = NULL;
-	netisr_proto[proto].np_m2flow = NULL;
-	netisr_proto[proto].np_m2cpuid = NULL;
-	netisr_proto[proto].np_qlimit = 0;
-	netisr_proto[proto].np_policy = 0;
+	V_netisr_proto[proto].np_name = NULL;
+	V_netisr_proto[proto].np_handler = NULL;
+	V_netisr_proto[proto].np_m2flow = NULL;
+	V_netisr_proto[proto].np_m2cpuid = NULL;
+	V_netisr_proto[proto].np_qlimit = 0;
+	V_netisr_proto[proto].np_policy = 0;
 	CPU_FOREACH(i) {
 		npwp = &(DPCPU_ID_PTR(i, nws))->nws_work[proto];
 		netisr_drain_proto(npwp);
@@ -763,13 +764,16 @@ netisr_process_workstream_proto(struct n
 		VNET_ASSERT(m->m_pkthdr.rcvif != NULL,
 		    ("%s:%d rcvif == NULL: m=%p", __func__, __LINE__, m));
 		CURVNET_SET(m->m_pkthdr.rcvif->if_vnet);
-		netisr_proto[proto].np_handler(m);
+		V_netisr_proto[proto].np_handler(m);
 		CURVNET_RESTORE();
 	}
 	KASSERT(local_npw.nw_len == 0,
 	    ("%s(%u): len %u", __func__, proto, local_npw.nw_len));
-	if (netisr_proto[proto].np_drainedcpu)
-		netisr_proto[proto].np_drainedcpu(nwsp->nws_cpu);
+	/* We can just use the one from the default VNET. */
+	CURVNET_SET_QUIET(vnet0);
+	if (V_netisr_proto[proto].np_drainedcpu)
+		V_netisr_proto[proto].np_drainedcpu(nwsp->nws_cpu);
+	CURVNET_RESTORE();
 	NWS_LOCK(nwsp);
 	npwp->nw_handled += handled;
 	return (handled);
@@ -905,10 +909,12 @@ netisr_queue_src(u_int proto, uintptr_t 
 #ifdef NETISR_LOCKING
 	NETISR_RLOCK(&tracker);
 #endif
-	KASSERT(netisr_proto[proto].np_handler != NULL,
-	    ("%s: invalid proto %u", __func__, proto));
+	if (V_netisr_proto[proto].np_handler == NULL) {
+		m_freem(m);
+		return (ENOPROTOOPT);
+	}
 
-	m = netisr_select_cpuid(&netisr_proto[proto], NETISR_DISPATCH_DEFERRED,
+	m = netisr_select_cpuid(&V_netisr_proto[proto], NETISR_DISPATCH_DEFERRED,
 	    source, m, &cpuid);
 	if (m != NULL) {
 		KASSERT(!CPU_ABSENT(cpuid), ("%s: CPU %u absent", __func__,
@@ -950,9 +956,11 @@ netisr_dispatch_src(u_int proto, uintptr
 #ifdef NETISR_LOCKING
 	NETISR_RLOCK(&tracker);
 #endif
-	npp = &netisr_proto[proto];
-	KASSERT(npp->np_handler != NULL, ("%s: invalid proto %u", __func__,
-	    proto));
+	npp = &V_netisr_proto[proto];
+	if (npp->np_handler == NULL) {
+		m_freem(m);
+		return (ENOPROTOOPT);
+	}
 
 	dispatch_policy = netisr_get_dispatch(npp);
 	if (dispatch_policy == NETISR_DISPATCH_DEFERRED)
@@ -970,7 +978,7 @@ netisr_dispatch_src(u_int proto, uintptr
 		npwp = &nwsp->nws_work[proto];
 		npwp->nw_dispatched++;
 		npwp->nw_handled++;
-		netisr_proto[proto].np_handler(m);
+		V_netisr_proto[proto].np_handler(m);
 		error = 0;
 		goto out_unlock;
 	}
@@ -984,7 +992,7 @@ netisr_dispatch_src(u_int proto, uintptr
 	 * already running.
 	 */
 	sched_pin();
-	m = netisr_select_cpuid(&netisr_proto[proto], NETISR_DISPATCH_HYBRID,
+	m = netisr_select_cpuid(&V_netisr_proto[proto], NETISR_DISPATCH_HYBRID,
 	    source, m, &cpuid);
 	if (m == NULL) {
 		error = ENOBUFS;
@@ -1021,7 +1029,7 @@ netisr_dispatch_src(u_int proto, uintptr
 	 */
 	nwsp->nws_flags |= NWS_DISPATCHING;
 	NWS_UNLOCK(nwsp);
-	netisr_proto[proto].np_handler(m);
+	V_netisr_proto[proto].np_handler(m);
 	NWS_LOCK(nwsp);
 	nwsp->nws_flags &= ~NWS_DISPATCHING;
 	npwp->nw_handled++;
@@ -1194,7 +1202,7 @@ sysctl_netisr_proto(SYSCTL_HANDLER_ARGS)
 	counter = 0;
 	NETISR_RLOCK(&tracker);
 	for (proto = 0; proto < NETISR_MAXPROT; proto++) {
-		npp = &netisr_proto[proto];
+		npp = &V_netisr_proto[proto];
 		if (npp->np_name == NULL)
 			continue;
 		snpp = &snp_array[counter];
@@ -1303,7 +1311,7 @@ sysctl_netisr_work(SYSCTL_HANDLER_ARGS)
 			continue;
 		NWS_LOCK(nwsp);
 		for (proto = 0; proto < NETISR_MAXPROT; proto++) {
-			npp = &netisr_proto[proto];
+			npp = &V_netisr_proto[proto];
 			if (npp->np_name == NULL)
 				continue;
 			nwp = &nwsp->nws_work[proto];
@@ -1352,7 +1360,7 @@ DB_SHOW_COMMAND(netisr, db_show_netisr)
 			continue;
 		first = 1;
 		for (proto = 0; proto < NETISR_MAXPROT; proto++) {
-			if (netisr_proto[proto].np_handler == NULL)
+			if (V_netisr_proto[proto].np_handler == NULL)
 				continue;
 			nwp = &nwsp->nws_work[proto];
 			if (first) {
@@ -1362,7 +1370,7 @@ DB_SHOW_COMMAND(netisr, db_show_netisr)
 				db_printf("%3s ", "");
 			db_printf(
 			    "%6s %5d %5d %5d %8ju %8ju %8ju %8ju\n",
-			    netisr_proto[proto].np_name, nwp->nw_len,
+			    V_netisr_proto[proto].np_name, nwp->nw_len,
 			    nwp->nw_watermark, nwp->nw_qlimit,
 			    nwp->nw_dispatched, nwp->nw_hybrid_dispatched,
 			    nwp->nw_qdrops, nwp->nw_queued);

Modified: projects/vnet/sys/net/rtsock.c
==============================================================================
--- projects/vnet/sys/net/rtsock.c	Sun Apr 24 16:36:33 2016	(r298547)
+++ projects/vnet/sys/net/rtsock.c	Sun Apr 24 16:41:54 2016	(r298548)
@@ -197,10 +197,27 @@ rts_init(void)
 
 	if (TUNABLE_INT_FETCH("net.route.netisr_maxqlen", &tmp))
 		rtsock_nh.nh_qlimit = tmp;
-	netisr_register(&rtsock_nh);
 }
 SYSINIT(rtsock, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD, rts_init, 0);
 
+static void
+vnet_rts_init(void)
+{
+
+	netisr_register(&rtsock_nh);
+}
+VNET_SYSINIT(vnet_rtsock, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD,
+    vnet_rts_init, 0);
+
+static void
+vnet_rts_uninit(void)
+{
+
+	netisr_unregister(&rtsock_nh);
+}
+VNET_SYSUNINIT(vnet_rts_uninit, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD,
+    vnet_rts_uninit, 0);
+
 static int
 raw_input_rts_cb(struct mbuf *m, struct sockproto *proto, struct sockaddr *src,
     struct rawcb *rp)

Modified: projects/vnet/sys/netinet/if_ether.c
==============================================================================
--- projects/vnet/sys/netinet/if_ether.c	Sun Apr 24 16:36:33 2016	(r298547)
+++ projects/vnet/sys/netinet/if_ether.c	Sun Apr 24 16:41:54 2016	(r298548)
@@ -143,7 +143,6 @@ SYSCTL_INT(_net_link_ether_inet, OID_AUT
 } while (0)
 
 
-static void	arp_init(void);
 static void	arpintr(struct mbuf *);
 static void	arptimer(void *);
 #ifdef INET
@@ -1327,7 +1326,7 @@ arp_iflladdr(void *arg __unused, struct 
 }
 
 static void
-arp_init(void)
+vnet_arp_init(void)
 {
 
 	netisr_register(&arp_nh);
@@ -1335,4 +1334,20 @@ arp_init(void)
 		iflladdr_tag = EVENTHANDLER_REGISTER(iflladdr_event,
 		    arp_iflladdr, NULL, EVENTHANDLER_PRI_ANY);
 }
-SYSINIT(arp, SI_SUB_PROTO_DOMAIN, SI_ORDER_SECOND, arp_init, 0);
+VNET_SYSINIT(vnet_arp_init, SI_SUB_PROTO_DOMAIN, SI_ORDER_SECOND,
+    vnet_arp_init, 0);
+
+#ifdef VIMAGE
+/*
+ * We have to unregister ARP along with IP otherwise we risk doing INADDR_HASH
+ * lookups after destroying the hash.  Ideally this would go on SI_ORDER_3.5.
+ */
+static void
+vnet_arp_destroy(__unused void *arg)
+{
+
+	netisr_unregister(&arp_nh);
+}
+VNET_SYSUNINIT(vnet_arp_uninit, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD,
+    vnet_arp_destroy, NULL);
+#endif

Modified: projects/vnet/sys/netinet/igmp.c
==============================================================================
--- projects/vnet/sys/netinet/igmp.c	Sun Apr 24 16:36:33 2016	(r298547)
+++ projects/vnet/sys/netinet/igmp.c	Sun Apr 24 16:41:54 2016	(r298548)
@@ -3592,6 +3592,15 @@ igmp_rec_type_to_str(const int type)
 }
 #endif
 
+static void
+vnet_igmp_init(const void *unused __unused)
+{
+
+	netisr_register(&igmp_nh);
+}
+VNET_SYSINIT(vnet_igmp_init, SI_SUB_PROTO_MC, SI_ORDER_ANY,
+    vnet_igmp_init, NULL);
+
 #ifdef VIMAGE
 static void
 vnet_igmp_uninit(const void *unused __unused)
@@ -3599,6 +3608,8 @@ vnet_igmp_uninit(const void *unused __un
 
 	/* This can happen when we shutdown the entire network stack. */
 	CTR1(KTR_IGMPV3, "%s: tearing down", __func__);
+
+	netisr_unregister(&igmp_nh);
 }
 VNET_SYSUNINIT(vnet_igmp_uninit, SI_SUB_PROTO_MC, SI_ORDER_ANY,
     vnet_igmp_uninit, NULL);
@@ -3644,11 +3655,9 @@ igmp_modevent(module_t mod, int type, vo
 		CTR1(KTR_IGMPV3, "%s: initializing", __func__);
 		IGMP_LOCK_INIT();
 		m_raopt = igmp_ra_alloc();
-		netisr_register(&igmp_nh);
 		break;
 	case MOD_UNLOAD:
 		CTR1(KTR_IGMPV3, "%s: tearing down", __func__);
-		netisr_unregister(&igmp_nh);
 		m_free(m_raopt);
 		m_raopt = NULL;
 		IGMP_LOCK_DESTROY();
@@ -3664,4 +3673,4 @@ static moduledata_t igmp_mod = {
     igmp_modevent,
     0
 };
-DECLARE_MODULE(igmp, igmp_mod, SI_SUB_PROTO_MC, SI_ORDER_ANY);
+DECLARE_MODULE(igmp, igmp_mod, SI_SUB_PROTO_MC, SI_ORDER_MIDDLE);

Modified: projects/vnet/sys/netinet/ip_input.c
==============================================================================
--- projects/vnet/sys/netinet/ip_input.c	Sun Apr 24 16:36:33 2016	(r298547)
+++ projects/vnet/sys/netinet/ip_input.c	Sun Apr 24 16:41:54 2016	(r298548)
@@ -332,7 +332,7 @@ ip_init(void)
 
 	/* Skip initialization of globals for non-default instances. */
 	if (!IS_DEFAULT_VNET(curvnet))
-		return;
+		goto out;
 
 	pr = pffindproto(PF_INET, IPPROTO_RAW, SOCK_RAW);
 	if (pr == NULL)
@@ -354,6 +354,7 @@ ip_init(void)
 				ip_protox[pr->pr_protocol] = pr - inetsw;
 		}
 
+out:
 	netisr_register(&ip_nh);
 #ifdef	RSS
 	netisr_register(&ip_direct_nh);
@@ -367,6 +368,11 @@ ip_destroy(void *unused __unused)
 	struct ifnet *ifp;
 	int error;
 
+#ifdef	RSS
+	netisr_unregister(&ip_direct_nh);
+#endif
+	netisr_unregister(&ip_nh);
+
 	if ((error = pfil_head_unregister(&V_inet_pfil_hook)) != 0)
 		printf("%s: WARNING: unable to unregister pfil hook, "
 		    "error %d\n", __func__, error);

Modified: projects/vnet/sys/netinet6/ip6_input.c
==============================================================================
--- projects/vnet/sys/netinet6/ip6_input.c	Sun Apr 24 16:36:33 2016	(r298547)
+++ projects/vnet/sys/netinet6/ip6_input.c	Sun Apr 24 16:41:54 2016	(r298548)
@@ -219,7 +219,7 @@ ip6_init(void)
 
 	/* Skip global initialization stuff for non-default instances. */
 	if (!IS_DEFAULT_VNET(curvnet))
-		return;
+		goto out;
 
 	pr = pffindproto(PF_INET6, IPPROTO_RAW, SOCK_RAW);
 	if (pr == NULL)
@@ -241,6 +241,7 @@ ip6_init(void)
 				ip6_protox[pr->pr_protocol] = pr - inet6sw;
 		}
 
+out:
 	netisr_register(&ip6_nh);
 #ifdef RSS
 	netisr_register(&ip6_direct_nh);
@@ -313,6 +314,11 @@ ip6_destroy(void *unused __unused)
 	struct ifnet *ifp;
 	int error;
 
+#ifdef RSS
+	netisr_unregister(&ip6_direct_nh);
+#endif
+	netisr_unregister(&ip6_nh);
+
 	if ((error = pfil_head_unregister(&V_inet6_pfil_hook)) != 0)
 		printf("%s: WARNING: unable to unregister pfil hook, "
 		    "error %d\n", __func__, error);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201604241641.u3OGfsG5080361>