svn commit: r298548 - in projects/vnet/sys: net netinet netinet6
Marko Zec
zec at fer.hr
Mon Apr 25 09:20:46 UTC 2016
On Sun, 24 Apr 2016 16:41:54 +0000
"Bjoern A. Zeeb" <bz at 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);
>
More information about the svn-src-projects
mailing list