Date: Mon, 25 Apr 2016 11:21:02 +0200 From: Marko Zec <zec@fer.hr> To: "Bjoern A. Zeeb" <bz@freebsd.org> Cc: <src-committers@freebsd.org>, <svn-src-projects@freebsd.org> Subject: Re: svn commit: r298548 - in projects/vnet/sys: net netinet netinet6 Message-ID: <20160425112102.1f3a8876@x23> In-Reply-To: <201604241641.u3OGfsG5080361@repo.freebsd.org> References: <201604241641.u3OGfsG5080361@repo.freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
On Sun, 24 Apr 2016 16:41:54 +0000 "Bjoern A. Zeeb" <bz@freebsd.org> wrote: > 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(). There's still a single PCPU mbuf queue per protocol, so if a vnet referenced by a queued mbuf disappears before netisr processing takes place, all we gain here is that we'll panic earlier due to referencing freed memory in netisr_dispatch(), instead of panicing later, in ether_demux(). This patch introduces redundant (per-vnet) copies of handler fuction pointers, along with several extra per-packet checks whether those function pointers are NULL or not. If the goal was to reduce the possibility for the race described above, wouldn't it be simpler to add a single "dying" flag to a vnet, and prevent any further netisr queuing of mbufs once the flag was set?, In both cases, we'd need to walk all PCPU netisr queues and prune any stale mbufs referencing a dying vnet, before we could let the vnet go. Or am I missing something here? > 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(ðer_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(ðer_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(ðer_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?20160425112102.1f3a8876>