Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 12 Jan 2026 17:15:30 +0100
From:      Mateusz Guzik <mjguzik@gmail.com>
To:        Gleb Smirnoff <glebius@freebsd.org>
Cc:        src-committers@freebsd.org, dev-commits-src-all@freebsd.org,  dev-commits-src-main@freebsd.org
Subject:   Re: git: 0d469d23715d - main - net: attach IPv4 and IPv6 stacks to an interface with EVENTHANDLER(9)
Message-ID:  <CAGudoHGX%2B8CUVwbuuWK_-BcLxMRKvUN8uYgMPcxtzCvXAR05pA@mail.gmail.com>
In-Reply-To: <694452f3.32deb.4d0ab2a7@gitrepo.freebsd.org>

index | next in thread | previous in thread | raw e-mail

In addition to the other reports there is also the following:
panic: mtx_lock() of spin mutex (null) @
/var/jenkins/workspace/pfSense-Plus-snapshots-master-main/sources/FreeBSD-src-plus-devel-main/sys/netinet/igmp.c:627
cpuid = 1
time = 1
KDB: enter: panic
[ thread pid 0 tid 100000 ]
Stopped at      kdb_enter+0x33: movq    $0,0x1b23e72(%rip)
db> bt
Tracing pid 0 tid 100000 td 0xffffffff828665e0
kdb_enter() at kdb_enter+0x33/frame 0xffffffff83963cb0
panic() at panic+0x43/frame 0xffffffff83963d10
__mtx_lock_flags() at __mtx_lock_flags+0x12f/frame 0xffffffff83963d60
igmp_domifattach() at igmp_domifattach+0x24/frame 0xffffffff83963d80
in_ifattach() at in_ifattach+0xb2/frame 0xffffffff83963db0
if_attach_internal() at if_attach_internal+0x374/frame 0xffffffff83963e00
enc_clone_create() at enc_clone_create+0x7e/frame 0xffffffff83963e30
if_clone_createif_nl() at if_clone_createif_nl+0x166/frame 0xffffffff83963ea0
ifc_create_ifp() at ifc_create_ifp+0x102/frame 0xffffffff83963f10
vnet_enc_init() at vnet_enc_init+0x97/frame 0xffffffff83963f70
vnet_register_sysinit() at vnet_register_sysinit+0x125/frame 0xffffffff83963fa0
mi_startup() at mi_startup+0x1f4/frame 0xffffffff83963ff0
db>

the igmp mutex is not yet initialized

On Thu, Dec 18, 2025 at 8:16 PM Gleb Smirnoff <glebius@freebsd.org> wrote:
>
> The branch main has been updated by glebius:
>
> URL: https://cgit.FreeBSD.org/src/commit/?id=0d469d23715d690b863787ebfa51529e1f6a9092
>
> commit 0d469d23715d690b863787ebfa51529e1f6a9092
> Author:     Gleb Smirnoff <glebius@FreeBSD.org>
> AuthorDate: 2025-12-18 16:47:39 +0000
> Commit:     Gleb Smirnoff <glebius@FreeBSD.org>
> CommitDate: 2025-12-18 19:15:53 +0000
>
>     net: attach IPv4 and IPv6 stacks to an interface with EVENTHANDLER(9)
>
>     This change retires two historic relics: the if_afdata[] array and the
>     dom_ifattach/dom_ifdetach methods.
>
>     The if_afdata[] array is a relic of the era, when there was expectation
>     that many transport protocols will coexist with IP, e.g. IPX or NetAtalk.
>     The array hasn't had any members except AF_INET and AF_INET6 for over a
>     decade already. This change removes the array and just leaves two pointer
>     fields: if_inet and if_inet6.
>
>     The dom_ifattach/dom_ifdetach predates the EVENTHANDLER(9) framework and
>     was a good enough method to initialize protocol contexts back then.  Today
>     there is no good reason to treat IPv4 and IPv6 stacks differently to other
>     protocols/features that attach and detach from an interface.
>
>     The locking of if_afdata[] is a relic of SMPng times, when the system
>     startup and the interface attach was even more convoluted than before this
>     change, and we also had unloadable protocols that used a field in
>     if_afdata[].  Note that IPv4 and IPv6 are not unloadable.
>
>     Note that this change removes NET_EPOCH_WAIT() from the interface detach
>     sequence.  This may surface several new races associated with interface
>     removal.  I failed to hit any with consecutive test suite runs, though.
>     The expected general race scenario is that while struct ifnet is freed
>     with proper epoch_call(9) itself, some structures hanging off ifnet are
>     freed with direct free(9).  The proper fix is either make if_foo point at
>     some static "dead" structure providing SMP visibility of this store, or
>     free those structure with epoch_call(9).  All of these cases are planned
>     to be found and resolved during 16.0-CURRENT lifetime.
>
>     Reviewed by:            zlei, gallatin, melifaro
>     Differential Revision:  https://reviews.freebsd.org/D54089
> ---
>  sys/kern/uipc_debug.c       |   4 --
>  sys/net/if.c                | 122 ++++----------------------------------------
>  sys/net/if_loop.c           |   2 +-
>  sys/net/if_private.h        |  19 +------
>  sys/net/if_var.h            |   3 +-
>  sys/net/vnet.h              |   3 ++
>  sys/netinet/icmp6.h         |   2 +-
>  sys/netinet/if_ether.c      |   4 +-
>  sys/netinet/igmp.c          |  10 ++--
>  sys/netinet/in.c            |  98 +++++++++++++++++++----------------
>  sys/netinet/in.h            |   1 -
>  sys/netinet/in_mcast.c      |   2 +-
>  sys/netinet/in_proto.c      |   2 -
>  sys/netinet/in_var.h        |   7 ++-
>  sys/netinet/ip_input.c      |   9 ++++
>  sys/netinet6/in6.c          |  49 +++++-------------
>  sys/netinet6/in6_ifattach.c |  39 +++++++++++++-
>  sys/netinet6/in6_mcast.c    |   2 +-
>  sys/netinet6/in6_proto.c    |   2 -
>  sys/netinet6/in6_var.h      |  11 ++--
>  sys/netinet6/ip6_input.c    |   7 +++
>  sys/netinet6/ip6_output.c   |   2 +-
>  sys/netinet6/mld6_var.h     |   3 +-
>  sys/netinet6/nd6.c          |  11 ++--
>  sys/netinet6/nd6.h          |   3 +-
>  sys/netinet6/scope6.c       |  10 ++--
>  sys/sys/domain.h            |   2 -
>  sys/sys/kernel.h            |   2 +-
>  28 files changed, 173 insertions(+), 258 deletions(-)
>
> diff --git a/sys/kern/uipc_debug.c b/sys/kern/uipc_debug.c
> index df36ec75cb5f..f6b7b1899d02 100644
> --- a/sys/kern/uipc_debug.c
> +++ b/sys/kern/uipc_debug.c
> @@ -242,10 +242,6 @@ db_print_domain(struct domain *d, const char *domain_name, int indent)
>
>         db_print_indent(indent);
>         db_printf("dom_rtattach: %p   ", d->dom_rtattach);
> -
> -       db_print_indent(indent);
> -       db_printf("dom_ifattach: %p   ", d->dom_ifattach);
> -       db_printf("dom_ifdetach: %p\n", d->dom_ifdetach);
>  }
>
>  static void
> diff --git a/sys/net/if.c b/sys/net/if.c
> index b603c72bd106..3c16246e8b62 100644
> --- a/sys/net/if.c
> +++ b/sys/net/if.c
> @@ -102,7 +102,6 @@
>  #endif /* INET */
>  #ifdef INET6
>  #include <netinet6/in6_var.h>
> -#include <netinet6/in6_ifattach.h>
>  #endif /* INET6 */
>  #endif /* INET || INET6 */
>
> @@ -270,8 +269,6 @@ struct mbuf *(*tbr_dequeue_ptr)(struct ifaltq *, int) = NULL;
>   * static functions should be prototyped. Currently they are sorted by
>   * declaration order.
>   */
> -static void    if_attachdomain(void *);
> -static void    if_attachdomain1(struct ifnet *);
>  static int     ifconf(u_long, caddr_t);
>  static void    if_input_default(struct ifnet *, struct mbuf *);
>  static int     if_requestencap_default(struct ifnet *, struct if_encap_req *);
> @@ -348,11 +345,6 @@ struct sx ifnet_detach_sxlock;
>  SX_SYSINIT_FLAGS(ifnet_detach, &ifnet_detach_sxlock, "ifnet_detach_sx",
>      SX_RECURSE);
>
> -#ifdef VIMAGE
> -#define        VNET_IS_SHUTTING_DOWN(_vnet)                                    \
> -    ((_vnet)->vnet_shutdown && (_vnet)->vnet_state < SI_SUB_VNET_DONE)
> -#endif
> -
>  static if_com_alloc_t *if_com_alloc[256];
>  static if_com_free_t *if_com_free[256];
>
> @@ -553,8 +545,6 @@ if_alloc_domain(u_char type, int numa_domain)
>         IF_ADDR_LOCK_INIT(ifp);
>         TASK_INIT(&ifp->if_linktask, 0, do_link_state_change, ifp);
>         TASK_INIT(&ifp->if_addmultitask, 0, if_siocaddmulti, ifp);
> -       ifp->if_afdata_initialized = 0;
> -       IF_AFDATA_LOCK_INIT(ifp);
>         CK_STAILQ_INIT(&ifp->if_addrhead);
>         CK_STAILQ_INIT(&ifp->if_multiaddrs);
>         CK_STAILQ_INIT(&ifp->if_groups);
> @@ -641,7 +631,6 @@ if_free_deferred(epoch_context_t ctx)
>  #ifdef MAC
>         mac_ifnet_destroy(ifp);
>  #endif /* MAC */
> -       IF_AFDATA_DESTROY(ifp);
>         IF_ADDR_LOCK_DESTROY(ifp);
>         ifq_delete(&ifp->if_snd);
>
> @@ -930,8 +919,6 @@ if_attach_internal(struct ifnet *ifp, bool vmove)
>  #endif
>         }
>
> -       if (domain_init_status >= 2)
> -               if_attachdomain1(ifp);
>         EVENTHANDLER_INVOKE(ifnet_arrival_event, ifp);
>         if_link_ifnet(ifp);
>         EVENTHANDLER_INVOKE(ifnet_attached_event, ifp);
> @@ -947,45 +934,6 @@ if_epochalloc(void *dummy __unused)
>  }
>  SYSINIT(ifepochalloc, SI_SUB_EPOCH, SI_ORDER_ANY, if_epochalloc, NULL);
>
> -static void
> -if_attachdomain(void *dummy)
> -{
> -       struct ifnet *ifp;
> -
> -       CK_STAILQ_FOREACH(ifp, &V_ifnet, if_link)
> -               if_attachdomain1(ifp);
> -}
> -SYSINIT(domainifattach, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_SECOND,
> -    if_attachdomain, NULL);
> -
> -static void
> -if_attachdomain1(struct ifnet *ifp)
> -{
> -       struct domain *dp;
> -
> -       /*
> -        * Since dp->dom_ifattach calls malloc() with M_WAITOK, we
> -        * cannot lock ifp->if_afdata initialization, entirely.
> -        */
> -       IF_AFDATA_LOCK(ifp);
> -       if (ifp->if_afdata_initialized >= domain_init_status) {
> -               IF_AFDATA_UNLOCK(ifp);
> -               log(LOG_WARNING, "%s called more than once on %s\n",
> -                   __func__, ifp->if_xname);
> -               return;
> -       }
> -       ifp->if_afdata_initialized = domain_init_status;
> -       IF_AFDATA_UNLOCK(ifp);
> -
> -       /* address family dependent data region */
> -       bzero(ifp->if_afdata, sizeof(ifp->if_afdata));
> -       SLIST_FOREACH(dp, &domains, dom_next) {
> -               if (dp->dom_ifattach)
> -                       ifp->if_afdata[dp->dom_family] =
> -                           (*dp->dom_ifattach)(ifp);
> -       }
> -}
> -
>  /*
>   * Remove any unicast or broadcast network addresses from an interface.
>   */
> @@ -1098,9 +1046,6 @@ static void
>  if_detach_internal(struct ifnet *ifp, bool vmove)
>  {
>         struct ifaddr *ifa;
> -       int i;
> -       struct domain *dp;
> -       void *if_afdata[AF_MAX];
>  #ifdef VIMAGE
>         bool shutdown;
>
> @@ -1151,7 +1096,7 @@ if_detach_internal(struct ifnet *ifp, bool vmove)
>                  * if_detach() calls us in void context and does not care
>                  * about an early abort notification, so life is splendid :)
>                  */
> -               goto finish_vnet_shutdown;
> +               return;
>         }
>  #endif
>
> @@ -1172,20 +1117,6 @@ if_detach_internal(struct ifnet *ifp, bool vmove)
>  #endif
>
>         if_purgeaddrs(ifp);
> -
> -#ifdef INET
> -       in_ifdetach(ifp);
> -#endif
> -
> -#ifdef INET6
> -       /*
> -        * Remove all IPv6 kernel structs related to ifp.  This should be done
> -        * before removing routing entries below, since IPv6 interface direct
> -        * routes are expected to be removed by the IPv6-specific kernel API.
> -        * Otherwise, the kernel will detect some inconsistency and bark it.
> -        */
> -       in6_ifdetach(ifp);
> -#endif
>         if_purgemaddrs(ifp);
>
>         EVENTHANDLER_INVOKE(ifnet_departure_event, ifp);
> @@ -1212,43 +1143,6 @@ if_detach_internal(struct ifnet *ifp, bool vmove)
>         }
>
>         rt_flushifroutes(ifp);
> -
> -#ifdef VIMAGE
> -finish_vnet_shutdown:
> -#endif
> -       /*
> -        * We cannot hold the lock over dom_ifdetach calls as they might
> -        * sleep, for example trying to drain a callout, thus open up the
> -        * theoretical race with re-attaching.
> -        */
> -       IF_AFDATA_LOCK(ifp);
> -       i = ifp->if_afdata_initialized;
> -       ifp->if_afdata_initialized = 0;
> -       if (i != 0) {
> -               /*
> -                * Defer the dom_ifdetach call.
> -                */
> -               _Static_assert(sizeof(if_afdata) == sizeof(ifp->if_afdata),
> -                   "array size mismatch");
> -               memcpy(if_afdata, ifp->if_afdata, sizeof(if_afdata));
> -               memset(ifp->if_afdata, 0, sizeof(ifp->if_afdata));
> -       }
> -       IF_AFDATA_UNLOCK(ifp);
> -       if (i == 0)
> -               return;
> -       /*
> -        * XXXZL: This net epoch wait is not necessary if we have done right.
> -        * But if we do not, at least we can make a guarantee that threads those
> -        * enter net epoch will see NULL address family dependent data,
> -        * e.g. if_afdata[AF_INET6]. A clear NULL pointer derefence is much
> -        * better than writing to freed memory.
> -        */
> -       NET_EPOCH_WAIT();
> -       SLIST_FOREACH(dp, &domains, dom_next) {
> -               if (dp->dom_ifdetach != NULL &&
> -                   if_afdata[dp->dom_family] != NULL)
> -                       (*dp->dom_ifdetach)(ifp, if_afdata[dp->dom_family]);
> -       }
>  }
>
>  #ifdef VIMAGE
> @@ -5121,10 +5015,16 @@ if_getvnet(if_t ifp)
>         return (ifp->if_vnet);
>  }
>
> -void *
> -if_getafdata(if_t ifp, int af)
> +struct in_ifinfo *
> +if_getinet(if_t ifp)
> +{
> +       return (ifp->if_inet);
> +}
> +
> +struct in6_ifextra *
> +if_getinet6(if_t ifp)
>  {
> -       return (ifp->if_afdata[af]);
> +       return (ifp->if_inet6);
>  }
>
>  u_int
> @@ -5189,8 +5089,6 @@ if_show_ifnet(struct ifnet *ifp)
>         IF_DB_PRINTF("%d", if_amcount);
>         IF_DB_PRINTF("%p", if_addr);
>         IF_DB_PRINTF("%p", if_broadcastaddr);
> -       IF_DB_PRINTF("%p", if_afdata);
> -       IF_DB_PRINTF("%d", if_afdata_initialized);
>         IF_DB_PRINTF("%u", if_fib);
>         IF_DB_PRINTF("%p", if_vnet);
>         IF_DB_PRINTF("%p", if_home_vnet);
> diff --git a/sys/net/if_loop.c b/sys/net/if_loop.c
> index ec0ff0e77aa6..37309260a0d3 100644
> --- a/sys/net/if_loop.c
> +++ b/sys/net/if_loop.c
> @@ -151,7 +151,7 @@ vnet_loif_init(const void *unused __unused)
>         struct ifc_data ifd = { .unit = 0 };
>         ifc_create_ifp(loname, &ifd, &V_loif);
>  }
> -VNET_SYSINIT(vnet_loif_init, SI_SUB_PSEUDO, SI_ORDER_ANY,
> +VNET_SYSINIT(vnet_loif_init, SI_SUB_PROTO_IF, SI_ORDER_ANY,
>      vnet_loif_init, NULL);
>
>  #ifdef VIMAGE
> diff --git a/sys/net/if_private.h b/sys/net/if_private.h
> index b8cd0722eba6..c4ade7308df4 100644
> --- a/sys/net/if_private.h
> +++ b/sys/net/if_private.h
> @@ -101,9 +101,8 @@ struct ifnet {
>         struct  ifaddr  *if_addr;       /* pointer to link-level address */
>         void    *if_hw_addr;            /* hardware link-level address */
>         const u_int8_t *if_broadcastaddr; /* linklevel broadcast bytestring */
> -       struct  mtx if_afdata_lock;
> -       void    *if_afdata[AF_MAX];
> -       int     if_afdata_initialized;
> +       struct in_ifinfo        *if_inet;
> +       struct in6_ifextra      *if_inet6;
>
>         /* Additional features hung off the interface. */
>         u_int   if_fib;                 /* interface FIB */
> @@ -193,20 +192,6 @@ struct ifnet {
>         int     if_ispare[4];           /* general use */
>  };
>
> -#define        IF_AFDATA_LOCK_INIT(ifp)        \
> -       mtx_init(&(ifp)->if_afdata_lock, "if_afdata", NULL, MTX_DEF)
> -
> -#define        IF_AFDATA_WLOCK(ifp)    mtx_lock(&(ifp)->if_afdata_lock)
> -#define        IF_AFDATA_WUNLOCK(ifp)  mtx_unlock(&(ifp)->if_afdata_lock)
> -#define        IF_AFDATA_LOCK(ifp)     IF_AFDATA_WLOCK(ifp)
> -#define        IF_AFDATA_UNLOCK(ifp)   IF_AFDATA_WUNLOCK(ifp)
> -#define        IF_AFDATA_TRYLOCK(ifp)  mtx_trylock(&(ifp)->if_afdata_lock)
> -#define        IF_AFDATA_DESTROY(ifp)  mtx_destroy(&(ifp)->if_afdata_lock)
> -
> -#define        IF_AFDATA_LOCK_ASSERT(ifp)      MPASS(in_epoch(net_epoch_preempt) || mtx_owned(&(ifp)->if_afdata_lock))
> -#define        IF_AFDATA_WLOCK_ASSERT(ifp)     mtx_assert(&(ifp)->if_afdata_lock, MA_OWNED)
> -#define        IF_AFDATA_UNLOCK_ASSERT(ifp)    mtx_assert(&(ifp)->if_afdata_lock, MA_NOTOWNED)
> -
>  #define IF_LLADDR(ifp)                                                 \
>      LLADDR((struct sockaddr_dl *)((ifp)->if_addr->ifa_addr))
>
> diff --git a/sys/net/if_var.h b/sys/net/if_var.h
> index cbc4969918ba..4fb51aca0cd7 100644
> --- a/sys/net/if_var.h
> +++ b/sys/net/if_var.h
> @@ -673,7 +673,8 @@ void *if_getl2com(if_t ifp);
>  struct ifvlantrunk *if_getvlantrunk(if_t ifp);
>  bool if_altq_is_enabled(if_t ifp);
>
> -void *if_getafdata(if_t ifp, int);
> +struct in_ifinfo *if_getinet(if_t ifp);
> +struct in6_ifextra *if_getinet6(if_t ifp);
>
>  int if_snd_tag_alloc(if_t ifp, union if_snd_tag_alloc_params *params,
>      struct m_snd_tag **mstp);
> diff --git a/sys/net/vnet.h b/sys/net/vnet.h
> index 670e99a455ae..f8ffcb4e2b76 100644
> --- a/sys/net/vnet.h
> +++ b/sys/net/vnet.h
> @@ -395,6 +395,9 @@ do {                                                                        \
>         }                                                               \
>  } while(0)
>
> +#define        VNET_IS_SHUTTING_DOWN(_vnet)    \
> +           ((_vnet)->vnet_shutdown && (_vnet)->vnet_state < SI_SUB_VNET_DONE)
> +
>  #else /* !VIMAGE */
>
>  /*
> diff --git a/sys/netinet/icmp6.h b/sys/netinet/icmp6.h
> index 2ca5b3433e47..082ef5d29ce9 100644
> --- a/sys/netinet/icmp6.h
> +++ b/sys/netinet/icmp6.h
> @@ -718,7 +718,7 @@ int icmp6_ratelimit(const struct in6_addr *, const int, const int);
>  do {                                                           \
>         if (ifp)                                                \
>                 counter_u64_add(((struct in6_ifextra *)         \
> -                   ((ifp)->if_afdata[AF_INET6]))->icmp6_ifstat[\
> +                   ((ifp)->if_inet6))->icmp6_ifstat[           \
>                     offsetof(struct icmp6_ifstat, tag) / sizeof(uint64_t)], 1);\
>  } while (/*CONSTCOND*/ 0)
>
> diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c
> index 7b223f1f2f11..8d65b88913b8 100644
> --- a/sys/netinet/if_ether.c
> +++ b/sys/netinet/if_ether.c
> @@ -1485,8 +1485,8 @@ static void
>  arp_iflladdr(void *arg __unused, struct ifnet *ifp)
>  {
>         /* if_bridge can update its lladdr during if_vmove(), after we've done
> -        * if_detach_internal()/dom_ifdetach(). */
> -       if (ifp->if_afdata[AF_INET] == NULL)
> +        * with in_ifdetach(). XXXGL: needs to be fixed. */
> +       if (ifp->if_inet == NULL)
>                 return;
>
>         lltable_update_ifaddr(LLTABLE(ifp));
> diff --git a/sys/netinet/igmp.c b/sys/netinet/igmp.c
> index ad22efb16495..de9d38c7fb9d 100644
> --- a/sys/netinet/igmp.c
> +++ b/sys/netinet/igmp.c
> @@ -690,7 +690,7 @@ igmp_ifdetach(struct ifnet *ifp)
>         SLIST_INIT(&inm_free_tmp);
>         IGMP_LOCK();
>
> -       igi = ((struct in_ifinfo *)ifp->if_afdata[AF_INET])->ii_igmp;
> +       igi = ((struct in_ifinfo *)ifp->if_inet)->ii_igmp;
>         if (igi->igi_version == IGMP_VERSION_3) {
>                 IF_ADDR_WLOCK(ifp);
>                 NET_EPOCH_ENTER(et);
> @@ -781,7 +781,7 @@ igmp_input_v1_query(struct ifnet *ifp, const struct ip *ip,
>         IN_MULTI_LIST_LOCK();
>         IGMP_LOCK();
>
> -       igi = ((struct in_ifinfo *)ifp->if_afdata[AF_INET])->ii_igmp;
> +       igi = ((struct in_ifinfo *)ifp->if_inet)->ii_igmp;
>         KASSERT(igi != NULL, ("%s: no igmp_ifsoftc for ifp %p", __func__, ifp));
>
>         if (igi->igi_flags & IGIF_LOOPBACK) {
> @@ -874,7 +874,7 @@ igmp_input_v2_query(struct ifnet *ifp, const struct ip *ip,
>         IN_MULTI_LIST_LOCK();
>         IGMP_LOCK();
>
> -       igi = ((struct in_ifinfo *)ifp->if_afdata[AF_INET])->ii_igmp;
> +       igi = ((struct in_ifinfo *)ifp->if_inet)->ii_igmp;
>         KASSERT(igi != NULL, ("%s: no igmp_ifsoftc for ifp %p", __func__, ifp));
>
>         if (igi->igi_flags & IGIF_LOOPBACK) {
> @@ -1066,7 +1066,7 @@ igmp_input_v3_query(struct ifnet *ifp, const struct ip *ip,
>         IN_MULTI_LIST_LOCK();
>         IGMP_LOCK();
>
> -       igi = ((struct in_ifinfo *)ifp->if_afdata[AF_INET])->ii_igmp;
> +       igi = ((struct in_ifinfo *)ifp->if_inet)->ii_igmp;
>         KASSERT(igi != NULL, ("%s: no igmp_ifsoftc for ifp %p", __func__, ifp));
>
>         if (igi->igi_flags & IGIF_LOOPBACK) {
> @@ -2347,7 +2347,7 @@ igmp_change_state(struct in_multi *inm)
>
>         IGMP_LOCK();
>
> -       igi = ((struct in_ifinfo *)ifp->if_afdata[AF_INET])->ii_igmp;
> +       igi = ((struct in_ifinfo *)ifp->if_inet)->ii_igmp;
>         KASSERT(igi != NULL, ("%s: no igmp_ifsoftc for ifp %p", __func__, ifp));
>
>         /*
> diff --git a/sys/netinet/in.c b/sys/netinet/in.c
> index e824c937af8e..510cfa79d54b 100644
> --- a/sys/netinet/in.c
> +++ b/sys/netinet/in.c
> @@ -669,7 +669,7 @@ in_aifaddr_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp, struct ucred *cred
>                 struct in_addr allhosts_addr;
>                 struct in_ifinfo *ii;
>
> -               ii = ((struct in_ifinfo *)ifp->if_afdata[AF_INET]);
> +               ii = (struct in_ifinfo *)ifp->if_inet;
>                 allhosts_addr.s_addr = htonl(INADDR_ALLHOSTS_GROUP);
>
>                 error = in_joingroup(ifp, &allhosts_addr, NULL,
> @@ -789,7 +789,7 @@ in_difaddr_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp, struct ucred *cred
>         if (iaIsLast && (ifp->if_flags & IFF_MULTICAST)) {
>                 struct in_ifinfo *ii;
>
> -               ii = ((struct in_ifinfo *)ifp->if_afdata[AF_INET]);
> +               ii = (struct in_ifinfo *)ifp->if_inet;
>                 if (ii->ii_allhosts) {
>                         (void)in_leavegroup(ii->ii_allhosts, NULL);
>                         ii->ii_allhosts = NULL;
> @@ -1329,26 +1329,62 @@ in_ifnet_broadcast(struct in_addr in, struct ifnet *ifp)
>         return (false);
>  }
>
> +
> +static struct lltable *in_lltattach(struct ifnet *);
> +void
> +in_ifattach(void *arg __unused, struct ifnet *ifp)
> +{
> +       struct in_ifinfo *ii;
> +
> +       ii = malloc(sizeof(struct in_ifinfo), M_IFADDR, M_WAITOK|M_ZERO);
> +       ii->ii_llt = in_lltattach(ifp);
> +       ii->ii_igmp = igmp_domifattach(ifp);
> +       ifp->if_inet = ii;
> +}
> +EVENTHANDLER_DEFINE(ifnet_arrival_event, in_ifattach, NULL,
> +    EVENTHANDLER_PRI_ANY);
> +
>  /*
>   * On interface removal, clean up IPv4 data structures hung off of the ifnet.
>   */
> -void
> -in_ifdetach(struct ifnet *ifp)
> +static void
> +in_ifdetach(void *arg __unused, struct ifnet *ifp)
>  {
> -       IN_MULTI_LOCK();
> -       in_pcbpurgeif0(&V_ripcbinfo, ifp);
> -       in_pcbpurgeif0(&V_udbinfo, ifp);
> -       in_pcbpurgeif0(&V_ulitecbinfo, ifp);
> -       in_purgemaddrs(ifp);
> -       IN_MULTI_UNLOCK();
> +       struct in_ifinfo *ii = ifp->if_inet;
>
> +#ifdef VIMAGE
>         /*
> -        * Make sure all multicast deletions invoking if_ioctl() are
> -        * completed before returning. Else we risk accessing a freed
> -        * ifnet structure pointer.
> +        * On VNET shutdown abort here as the stack teardown will do all
> +        * the work top-down for us.  XXXGL: this logic is copied from
> +        * if_detach() before dom_ifattach removal.  Ideally we'd like to have
> +        * same logic for VNET shutdown and normal detach.  This means that
> +        * interfaces should be detach before protocols destroyed during VNET
> +        * shutdown.
>          */
> -       inm_release_wait(NULL);
> +       if (!VNET_IS_SHUTTING_DOWN(ifp->if_vnet))
> +#endif
> +       {
> +               IN_MULTI_LOCK();
> +               in_pcbpurgeif0(&V_ripcbinfo, ifp);
> +               in_pcbpurgeif0(&V_udbinfo, ifp);
> +               in_pcbpurgeif0(&V_ulitecbinfo, ifp);
> +               in_purgemaddrs(ifp);
> +               IN_MULTI_UNLOCK();
> +
> +               /*
> +                * Make sure all multicast deletions invoking if_ioctl() are
> +                * completed before returning. Else we risk accessing a freed
> +                * ifnet structure pointer.
> +                */
> +               inm_release_wait(NULL);
> +       }
> +
> +       igmp_domifdetach(ifp);
> +       lltable_free(ii->ii_llt);
> +       free(ii, M_IFADDR);
>  }
> +EVENTHANDLER_DEFINE(ifnet_departure_event, in_ifdetach, NULL,
> +    EVENTHANDLER_PRI_ANY);
>
>  static void
>  in_ifnet_event(void *arg __unused, struct ifnet *ifp, int event)
> @@ -1862,35 +1898,9 @@ in_lltattach(struct ifnet *ifp)
>  struct lltable *
>  in_lltable_get(struct ifnet *ifp)
>  {
> -       struct lltable *llt = NULL;
> -
> -       void *afdata_ptr = ifp->if_afdata[AF_INET];
> -       if (afdata_ptr != NULL)
> -               llt = ((struct in_ifinfo *)afdata_ptr)->ii_llt;
> -       return (llt);
> -}
> -
> -void *
> -in_domifattach(struct ifnet *ifp)
> -{
> -       struct in_ifinfo *ii;
> -
> -       ii = malloc(sizeof(struct in_ifinfo), M_IFADDR, M_WAITOK|M_ZERO);
> -
> -       ii->ii_llt = in_lltattach(ifp);
> -       ii->ii_igmp = igmp_domifattach(ifp);
> -
> -       return (ii);
> -}
> -
> -void
> -in_domifdetach(struct ifnet *ifp, void *aux)
> -{
> -       struct in_ifinfo *ii = (struct in_ifinfo *)aux;
> -
> -       MPASS(ifp->if_afdata[AF_INET] == NULL);
> +       /* XXXGL: ??? */
> +       if (ifp->if_inet == NULL)
> +               return (NULL);
>
> -       igmp_domifdetach(ifp);
> -       lltable_free(ii->ii_llt);
> -       free(ii, M_IFADDR);
> +       return (((struct in_ifinfo *)ifp->if_inet)->ii_llt);
>  }
> diff --git a/sys/netinet/in.h b/sys/netinet/in.h
> index 3f2c388548ec..0cd55bd1e409 100644
> --- a/sys/netinet/in.h
> +++ b/sys/netinet/in.h
> @@ -684,7 +684,6 @@ int  inet_aton(const char *, struct in_addr *); /* in libkern */
>  char   *inet_ntoa_r(struct in_addr ina, char *buf); /* in libkern */
>  char   *inet_ntop(int, const void *, char *, socklen_t); /* in libkern */
>  int     inet_pton(int af, const char *, void *); /* in libkern */
> -void    in_ifdetach(struct ifnet *);
>
>  static inline bool
>  in_broadcast(struct in_addr in)
> diff --git a/sys/netinet/in_mcast.c b/sys/netinet/in_mcast.c
> index ba112afbf002..131e72780ebe 100644
> --- a/sys/netinet/in_mcast.c
> +++ b/sys/netinet/in_mcast.c
> @@ -500,7 +500,7 @@ in_getmulti(struct ifnet *ifp, const struct in_addr *group,
>
>         IN_MULTI_LOCK_ASSERT();
>
> -       ii = (struct in_ifinfo *)ifp->if_afdata[AF_INET];
> +       ii = (struct in_ifinfo *)ifp->if_inet;
>         IN_MULTI_LIST_LOCK();
>         inm = inm_lookup(ifp, *group);
>         if (inm != NULL) {
> diff --git a/sys/netinet/in_proto.c b/sys/netinet/in_proto.c
> index 3ec515d216fa..ff3040bfc7b1 100644
> --- a/sys/netinet/in_proto.c
> +++ b/sys/netinet/in_proto.c
> @@ -76,8 +76,6 @@ struct domain inetdomain = {
>  #ifdef VIMAGE
>         .dom_rtdetach =         in_detachhead,
>  #endif
> -       .dom_ifattach =         in_domifattach,
> -       .dom_ifdetach =         in_domifdetach,
>         .dom_nprotosw =         14,
>         .dom_protosw = {
>                 &tcp_protosw,
> diff --git a/sys/netinet/in_var.h b/sys/netinet/in_var.h
> index 1f6f6edb9219..311d82da4605 100644
> --- a/sys/netinet/in_var.h
> +++ b/sys/netinet/in_var.h
> @@ -102,8 +102,7 @@ struct in_ifaddr {
>         ((((d).s_addr ^ (a).s_addr) & (m).s_addr)) == 0 )
>  #endif
>
> -#define LLTABLE(ifp)   \
> -       ((struct in_ifinfo *)(ifp)->if_afdata[AF_INET])->ii_llt
> +#define LLTABLE(ifp)   ((struct in_ifinfo *)(ifp)->if_inet)->ii_llt
>  /*
>   * Hash table for IP addresses.
>   */
> @@ -471,9 +470,9 @@ void        ip_input(struct mbuf *);
>  void   ip_direct_input(struct mbuf *);
>  void   in_ifadown(struct ifaddr *ifa, int);
>  struct mbuf    *ip_tryforward(struct mbuf *);
> -void   *in_domifattach(struct ifnet *);
> -void   in_domifdetach(struct ifnet *, void *);
>  struct rib_head *in_inithead(uint32_t fibnum);
> +void   in_ifattach(void *, struct ifnet *);
> +
>  #ifdef VIMAGE
>  void   in_detachhead(struct rib_head *rh);
>  #endif
> diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
> index 6ddec6726428..2e0635f8e482 100644
> --- a/sys/netinet/ip_input.c
> +++ b/sys/netinet/ip_input.c
> @@ -352,6 +352,7 @@ VNET_SYSINIT(ip_vnet_init, SI_SUB_PROTO_DOMAIN, SI_ORDER_FOURTH,
>  static void
>  ip_init(const void *unused __unused)
>  {
> +       struct ifnet *ifp;
>
>         ipreass_init();
>
> @@ -376,6 +377,14 @@ ip_init(const void *unused __unused)
>  #ifdef RSS
>         netisr_register(&ip_direct_nh);
>  #endif
> +       /*
> +        * XXXGL: we use SYSINIT() here, but go over V_ifnet.  It was the same
> +        * way before dom_ifattach removal.  This worked because when any
> +        * non-default vnet is created, there are no interfaces inside.
> +        * Eventually this needs to be fixed.
> +        */
> +       CK_STAILQ_FOREACH(ifp, &V_ifnet, if_link)
> +               in_ifattach(NULL, ifp);
>  }
>  SYSINIT(ip_init, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD, ip_init, NULL);
>
> diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c
> index 158129258587..a953bb5546d6 100644
> --- a/sys/netinet6/in6.c
> +++ b/sys/netinet6/in6.c
> @@ -478,7 +478,7 @@ in6_control_ioctl(u_long cmd, void *data,
>                 /* FALLTHROUGH */
>         case SIOCGIFSTAT_IN6:
>         case SIOCGIFSTAT_ICMP6:
> -               if (ifp->if_afdata[AF_INET6] == NULL) {
> +               if (ifp->if_inet6 == NULL) {
>                         error = EPFNOSUPPORT;
>                         goto out;
>                 }
> @@ -525,15 +525,13 @@ in6_control_ioctl(u_long cmd, void *data,
>                 break;
>
>         case SIOCGIFSTAT_IN6:
> -               COUNTER_ARRAY_COPY(((struct in6_ifextra *)
> -                   ifp->if_afdata[AF_INET6])->in6_ifstat,
> +               COUNTER_ARRAY_COPY(ifp->if_inet6->in6_ifstat,
>                     &ifr->ifr_ifru.ifru_stat,
>                     sizeof(struct in6_ifstat) / sizeof(uint64_t));
>                 break;
>
>         case SIOCGIFSTAT_ICMP6:
> -               COUNTER_ARRAY_COPY(((struct in6_ifextra *)
> -                   ifp->if_afdata[AF_INET6])->icmp6_ifstat,
> +               COUNTER_ARRAY_COPY(ifp->if_inet6->icmp6_ifstat,
>                     &ifr->ifr_ifru.ifru_icmp6stat,
>                     sizeof(struct icmp6_ifstat) / sizeof(uint64_t));
>                 break;
> @@ -2567,16 +2565,14 @@ in6_lltattach(struct ifnet *ifp)
>  struct lltable *
>  in6_lltable_get(struct ifnet *ifp)
>  {
> -       struct lltable *llt = NULL;
> +       if (ifp->if_inet6 == NULL)
> +               return (NULL);
>
> -       void *afdata_ptr = ifp->if_afdata[AF_INET6];
> -       if (afdata_ptr != NULL)
> -               llt = ((struct in6_ifextra *)afdata_ptr)->lltable;
> -       return (llt);
> +       return (ifp->if_inet6->lltable);
>  }
>
> -void *
> -in6_domifattach(struct ifnet *ifp)
> +void
> +in6_ifarrival(void *arg __unused, struct ifnet *ifp)
>  {
>         struct in6_ifextra *ext;
>
> @@ -2584,7 +2580,8 @@ in6_domifattach(struct ifnet *ifp)
>         switch (ifp->if_type) {
>         case IFT_PFLOG:
>         case IFT_PFSYNC:
> -               return (NULL);
> +               ifp->if_inet6 = NULL;
> +               return;
>         }
>         ext = (struct in6_ifextra *)malloc(sizeof(*ext), M_IFADDR, M_WAITOK);
>         bzero(ext, sizeof(*ext));
> @@ -2606,8 +2603,10 @@ in6_domifattach(struct ifnet *ifp)
>
>         ext->mld_ifinfo = mld_domifattach(ifp);
>
> -       return ext;
> +       ifp->if_inet6 = ext;
>  }
> +EVENTHANDLER_DEFINE(ifnet_arrival_event, in6_ifarrival, NULL,
> +    EVENTHANDLER_PRI_ANY);
>
>  uint32_t
>  in6_ifmtu(struct ifnet *ifp)
> @@ -2615,26 +2614,6 @@ in6_ifmtu(struct ifnet *ifp)
>         return (IN6_LINKMTU(ifp));
>  }
>
> -void
> -in6_domifdetach(struct ifnet *ifp, void *aux)
> -{
> -       struct in6_ifextra *ext = (struct in6_ifextra *)aux;
> -
> -       MPASS(ifp->if_afdata[AF_INET6] == NULL);
> -
> -       mld_domifdetach(ifp);
> -       scope6_ifdetach(ext->scope6_id);
> -       nd6_ifdetach(ifp, ext->nd_ifinfo);
> -       lltable_free(ext->lltable);
> -       COUNTER_ARRAY_FREE(ext->in6_ifstat,
> -           sizeof(struct in6_ifstat) / sizeof(uint64_t));
> -       free(ext->in6_ifstat, M_IFADDR);
> -       COUNTER_ARRAY_FREE(ext->icmp6_ifstat,
> -           sizeof(struct icmp6_ifstat) / sizeof(uint64_t));
> -       free(ext->icmp6_ifstat, M_IFADDR);
> -       free(ext, M_IFADDR);
> -}
> -
>  /*
>   * Convert sockaddr_in6 to sockaddr_in.  Original sockaddr_in6 must be
>   * v4 mapped addr or v4 compat addr
> @@ -2736,7 +2715,7 @@ in6_purge_proxy_ndp(struct ifnet *ifp)
>         struct lltable *llt;
>         bool need_purge;
>
> -       if (ifp->if_afdata[AF_INET6] == NULL)
> +       if (ifp->if_inet6 == NULL)
>                 return;
>
>         llt = LLTABLE6(ifp);
> diff --git a/sys/netinet6/in6_ifattach.c b/sys/netinet6/in6_ifattach.c
> index 090ba610460b..a2d236cccc41 100644
> --- a/sys/netinet6/in6_ifattach.c
> +++ b/sys/netinet6/in6_ifattach.c
> @@ -50,6 +50,7 @@
>  #include <net/if_dl.h>
>  #include <net/if_private.h>
>  #include <net/if_types.h>
> +#include <net/if_llatbl.h>
>  #include <net/route.h>
>  #include <net/vnet.h>
>
> @@ -783,7 +784,8 @@ in6_ifattach(struct ifnet *ifp, struct ifnet *altifp)
>  {
>         struct in6_ifaddr *ia;
>
> -       if (ifp->if_afdata[AF_INET6] == NULL)
> +       /* XXXGL: can this happen after IFT_PFLOG and IFT_PFSYNC are gone? */
> +       if (ifp->if_inet6 == NULL)
>                 return;
>         /*
>          * quirks based on interface type
> @@ -857,7 +859,8 @@ _in6_ifdetach(struct ifnet *ifp, int purgeulp)
>  {
>         struct ifaddr *ifa, *next;
>
> -       if (ifp->if_afdata[AF_INET6] == NULL)
> +       /* XXXGL: can this happen after IFT_PFLOG and IFT_PFSYNC are gone? */
> +       if (ifp->if_inet6 == NULL)
>                 return;
>
>         /*
> @@ -895,6 +898,38 @@ in6_ifdetach(struct ifnet *ifp)
>         _in6_ifdetach(ifp, 1);
>  }
>
> +static void
> +in6_ifdeparture(void *arg __unused, struct ifnet *ifp)
> +{
> +       struct in6_ifextra *ext = ifp->if_inet6;
> +
> +       /* XXXGL: can this happen after IFT_PFLOG and IFT_PFSYNC are gone? */
> +       if (ifp->if_inet6 == NULL)
> +               return;
> +
> +#ifdef VIMAGE
> +       /*
> +        * On VNET shutdown abort here as the stack teardown will do all
> +        * the work top-down for us.  XXXGL: see comment in in.c:in_ifdetach().
> +        */
> +       if (!VNET_IS_SHUTTING_DOWN(ifp->if_vnet))
> +#endif
> +               _in6_ifdetach(ifp, 1);
> +       mld_domifdetach(ifp);
> +       scope6_ifdetach(ext->scope6_id);
> +       nd6_ifdetach(ifp, ext->nd_ifinfo);
> +       lltable_free(ext->lltable);
> +       COUNTER_ARRAY_FREE(ext->in6_ifstat,
> +           sizeof(struct in6_ifstat) / sizeof(uint64_t));
> +       free(ext->in6_ifstat, M_IFADDR);
> +       COUNTER_ARRAY_FREE(ext->icmp6_ifstat,
> +           sizeof(struct icmp6_ifstat) / sizeof(uint64_t));
> +       free(ext->icmp6_ifstat, M_IFADDR);
> +       free(ext, M_IFADDR);
> +}
> +EVENTHANDLER_DEFINE(ifnet_departure_event, in6_ifdeparture, NULL,
> +    EVENTHANDLER_PRI_ANY);
> +
>  void
>  in6_ifdetach_destroy(struct ifnet *ifp)
>  {
> diff --git a/sys/netinet6/in6_mcast.c b/sys/netinet6/in6_mcast.c
> index 613bd14428bb..4075e75eac85 100644
> --- a/sys/netinet6/in6_mcast.c
> +++ b/sys/netinet6/in6_mcast.c
> @@ -400,7 +400,7 @@ in6_getmulti(struct ifnet *ifp, const struct in6_addr *group,
>         /*
>          * Does ifp support IPv6 multicasts?
>          */
> -       if (ifp->if_afdata[AF_INET6] == NULL)
> +       if (ifp->if_inet6 == NULL)
>                 error = ENODEV;
>         else
>                 inm = in6m_lookup_locked(ifp, group);
> diff --git a/sys/netinet6/in6_proto.c b/sys/netinet6/in6_proto.c
> index f3ed72719abf..dbbe7c4b3eca 100644
> --- a/sys/netinet6/in6_proto.c
> +++ b/sys/netinet6/in6_proto.c
> @@ -111,8 +111,6 @@ struct domain inet6domain = {
>  #ifdef VIMAGE
>         .dom_rtdetach =         in6_detachhead,
>  #endif
> -       .dom_ifattach =         in6_domifattach,
> -       .dom_ifdetach =         in6_domifdetach,
>         .dom_nprotosw =         14,
>         .dom_protosw = {
>                 &tcp6_protosw,
> diff --git a/sys/netinet6/in6_var.h b/sys/netinet6/in6_var.h
> index 1210937a5dc4..0cfdde652c0a 100644
> --- a/sys/netinet6/in6_var.h
> +++ b/sys/netinet6/in6_var.h
> @@ -109,8 +109,8 @@ struct in6_ifextra {
>         u_int dad_failures;     /* DAD failures when using RFC 7217 stable addresses */
>  };
>
> -#define        LLTABLE6(ifp)   (((struct in6_ifextra *)(ifp)->if_afdata[AF_INET6])->lltable)
> -#define        DAD_FAILURES(ifp)       (((struct in6_ifextra *)(ifp)->if_afdata[AF_INET6])->dad_failures)
> +#define        LLTABLE6(ifp)   ((ifp)->if_inet6->lltable)
> +#define        DAD_FAILURES(ifp)       ((ifp)->if_inet6->dad_failures)
>
>  #ifdef _KERNEL
>
> @@ -545,8 +545,7 @@ extern struct rmlock in6_ifaddr_lock;
>  #define in6_ifstat_inc(ifp, tag) \
>  do {                                                           \
>         if (ifp)                                                \
> -               counter_u64_add(((struct in6_ifextra *)         \
> -                   ((ifp)->if_afdata[AF_INET6]))->in6_ifstat[  \
> +               counter_u64_add((ifp)->if_inet6->in6_ifstat[    \
>                     offsetof(struct in6_ifstat, tag) / sizeof(uint64_t)], 1);\
>  } while (/*CONSTCOND*/ 0)
>  #endif /* _KERNEL */
> @@ -867,8 +866,6 @@ void        in6_purgeaddr(struct ifaddr *);
>  void   in6_purgeifaddr(struct in6_ifaddr *);
>  int    in6if_do_dad(struct ifnet *);
>  void   in6_savemkludge(struct in6_ifaddr *);
> -void   *in6_domifattach(struct ifnet *);
> -void   in6_domifdetach(struct ifnet *, void *);
>  uint32_t in6_ifmtu(struct ifnet *);
>  struct rib_head *in6_inithead(uint32_t fibnum);
>  void   in6_detachhead(struct rib_head *rh);
> @@ -893,6 +890,8 @@ int in6_src_ioctl(u_long, caddr_t);
>  void   in6_newaddrmsg(struct in6_ifaddr *, int);
>
>  void   in6_purge_proxy_ndp(struct ifnet *);
> +void   in6_ifarrival(void *, struct ifnet *);
> +
>  /*
>   * Extended API for IPv6 FIB support.
>   */
> diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c
> index 380391fd71f4..29fa4741a509 100644
> --- a/sys/netinet6/ip6_input.c
> +++ b/sys/netinet6/ip6_input.c
> @@ -286,6 +286,7 @@ VNET_SYSINIT(ip6_vnet_init, SI_SUB_PROTO_DOMAIN, SI_ORDER_FOURTH,
>  static void
>  ip6_init(void *arg __unused)
>  {
> +       struct ifnet *ifp;
>
>         /*
>          * Register statically those protocols that are unlikely to ever go
> @@ -312,6 +313,12 @@ ip6_init(void *arg __unused)
>  #ifdef RSS
>         netisr_register(&ip6_direct_nh);
>  #endif
> +       /*
> +         * XXXGL: we use SYSINIT() here, but go over V_ifnet.  See comment
> +        * in sys/netinet/ip_input.c:ip_init().
> +         */
> +        CK_STAILQ_FOREACH(ifp, &V_ifnet, if_link)
> +                in6_ifarrival(NULL, ifp);
>  }
>  SYSINIT(ip6_init, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD, ip6_init, NULL);
>
> diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c
> index 8ade50b13568..eb5a3a971ea0 100644
> --- a/sys/netinet6/ip6_output.c
> +++ b/sys/netinet6/ip6_output.c
> @@ -2920,7 +2920,7 @@ ip6_setpktopt(int optname, u_char *buf, int len, struct ip6_pktopts *opt,
>                         if (ifp == NULL)
>                                 return (ENXIO);
>                 }
> -               if (ifp != NULL && (ifp->if_afdata[AF_INET6] == NULL ||
> +               if (ifp != NULL && (ifp->if_inet6 == NULL ||
>                     (ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED) != 0))
>                         return (ENETDOWN);
>
> diff --git a/sys/netinet6/mld6_var.h b/sys/netinet6/mld6_var.h
> index 96b841f1564b..d75ac2450c10 100644
> --- a/sys/netinet6/mld6_var.h
> +++ b/sys/netinet6/mld6_var.h
> @@ -155,8 +155,7 @@ struct mld_ifsoftc {
>  /*
>   * Per-link MLD context.
>   */
> *** 133 LINES SKIPPED ***
>


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAGudoHGX%2B8CUVwbuuWK_-BcLxMRKvUN8uYgMPcxtzCvXAR05pA>