Page MenuHomeFreeBSD

D54089.id167594.diff
No OneTemporary

D54089.id167594.diff

diff --git a/sys/kern/uipc_debug.c b/sys/kern/uipc_debug.c
--- a/sys/kern/uipc_debug.c
+++ b/sys/kern/uipc_debug.c
@@ -242,10 +242,6 @@
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
--- 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 @@
* 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 @@
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_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 @@
#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 @@
#endif
}
- if (domain_init_status >= 2)
- if_attachdomain1(ifp);
EVENTHANDLER_INVOKE(ifnet_arrival_event, ifp);
if_link_ifnet(ifp);
@@ -948,45 +935,6 @@
}
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.
*/
@@ -1099,9 +1047,6 @@
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;
@@ -1152,7 +1097,7 @@
* 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
@@ -1173,20 +1118,6 @@
#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);
@@ -1213,43 +1144,6 @@
}
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 @@
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_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
--- a/sys/net/if_loop.c
+++ b/sys/net/if_loop.c
@@ -151,7 +151,7 @@
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
--- a/sys/net/if_private.h
+++ b/sys/net/if_private.h
@@ -101,9 +101,8 @@
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 @@
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
--- a/sys/net/if_var.h
+++ b/sys/net/if_var.h
@@ -662,7 +662,8 @@
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
--- a/sys/net/vnet.h
+++ b/sys/net/vnet.h
@@ -395,6 +395,9 @@
} \
} 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
--- a/sys/netinet/icmp6.h
+++ b/sys/netinet/icmp6.h
@@ -718,7 +718,7 @@
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
--- a/sys/netinet/if_ether.c
+++ b/sys/netinet/if_ether.c
@@ -1485,8 +1485,8 @@
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
--- a/sys/netinet/igmp.c
+++ b/sys/netinet/igmp.c
@@ -690,7 +690,7 @@
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 @@
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 @@
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 @@
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_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.h b/sys/netinet/in.h
--- a/sys/netinet/in.h
+++ b/sys/netinet/in.h
@@ -684,7 +684,6 @@
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.c b/sys/netinet/in.c
--- a/sys/netinet/in.c
+++ b/sys/netinet/in.c
@@ -669,7 +669,7 @@
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 @@
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 @@
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 @@
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_mcast.c b/sys/netinet/in_mcast.c
--- a/sys/netinet/in_mcast.c
+++ b/sys/netinet/in_mcast.c
@@ -500,7 +500,7 @@
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
--- a/sys/netinet/in_proto.c
+++ b/sys/netinet/in_proto.c
@@ -76,8 +76,6 @@
#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
--- a/sys/netinet/in_var.h
+++ b/sys/netinet/in_var.h
@@ -102,8 +102,7 @@
((((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_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
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -352,6 +352,7 @@
static void
ip_init(const void *unused __unused)
{
+ struct ifnet *ifp;
ipreass_init();
@@ -376,6 +377,14 @@
#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
--- a/sys/netinet6/in6.c
+++ b/sys/netinet6/in6.c
@@ -478,7 +478,7 @@
/* 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 @@
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 @@
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;
@@ -2585,7 +2581,8 @@
case IFT_PFLOG:
case IFT_PFSYNC:
case IFT_USB:
- return (NULL);
+ ifp->if_inet6 = NULL;
+ return;
}
ext = (struct in6_ifextra *)malloc(sizeof(*ext), M_IFADDR, M_WAITOK);
bzero(ext, sizeof(*ext));
@@ -2607,8 +2604,10 @@
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)
@@ -2616,26 +2615,6 @@
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
@@ -2737,7 +2716,7 @@
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
--- 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 @@
{
struct in6_ifaddr *ia;
- if (ifp->if_afdata[AF_INET6] == NULL)
+ /* XXXGL: can this happen? */
+ if (ifp->if_inet6 == NULL)
return;
/*
* quirks based on interface type
@@ -857,7 +859,8 @@
{
struct ifaddr *ifa, *next;
- if (ifp->if_afdata[AF_INET6] == NULL)
+ /* XXXGL: can this happen? */
+ if (ifp->if_inet6 == NULL)
return;
/*
@@ -895,6 +898,34 @@
_in6_ifdetach(ifp, 1);
}
+static void
+in6_ifdeparture(void *arg __unused, struct ifnet *ifp)
+{
+ struct in6_ifextra *ext = ifp->if_inet6;
+
+#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
--- a/sys/netinet6/in6_mcast.c
+++ b/sys/netinet6/in6_mcast.c
@@ -400,7 +400,7 @@
/*
* 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
--- a/sys/netinet6/in6_proto.c
+++ b/sys/netinet6/in6_proto.c
@@ -111,8 +111,6 @@
#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
--- a/sys/netinet6/in6_var.h
+++ b/sys/netinet6/in6_var.h
@@ -109,8 +109,8 @@
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 @@
#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_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 @@
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
--- a/sys/netinet6/ip6_input.c
+++ b/sys/netinet6/ip6_input.c
@@ -286,6 +286,7 @@
static void
ip6_init(void *arg __unused)
{
+ struct ifnet *ifp;
/*
* Register statically those protocols that are unlikely to ever go
@@ -312,6 +313,12 @@
#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
--- a/sys/netinet6/ip6_output.c
+++ b/sys/netinet6/ip6_output.c
@@ -2920,7 +2920,7 @@
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
--- a/sys/netinet6/mld6_var.h
+++ b/sys/netinet6/mld6_var.h
@@ -155,8 +155,7 @@
/*
* Per-link MLD context.
*/
-#define MLD_IFINFO(ifp) \
- (((struct in6_ifextra *)(ifp)->if_afdata[AF_INET6])->mld_ifinfo)
+#define MLD_IFINFO(ifp) ((ifp)->if_inet6->mld_ifinfo)
struct in6_multi_head;
int mld_change_state(struct in6_multi *, const int);
diff --git a/sys/netinet6/nd6.h b/sys/netinet6/nd6.h
--- a/sys/netinet6/nd6.h
+++ b/sys/netinet6/nd6.h
@@ -98,8 +98,7 @@
#endif
#ifdef _KERNEL
-#define ND_IFINFO(ifp) \
- (((struct in6_ifextra *)if_getafdata(ifp, AF_INET6))->nd_ifinfo)
+#define ND_IFINFO(ifp) ((if_getinet6(ifp))->nd_ifinfo)
#define IN6_LINKMTU(ifp) \
((ND_IFINFO(ifp)->linkmtu && ND_IFINFO(ifp)->linkmtu < (ifp)->if_mtu) \
? ND_IFINFO(ifp)->linkmtu \
diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c
--- a/sys/netinet6/nd6.c
+++ b/sys/netinet6/nd6.c
@@ -224,7 +224,8 @@
static void
nd6_iflladdr(void *arg __unused, struct ifnet *ifp)
{
- if (ifp->if_afdata[AF_INET6] == NULL)
+ /* XXXGL: ??? */
+ if (ifp->if_inet6 == NULL)
return;
lltable_update_ifaddr(LLTABLE6(ifp));
@@ -357,7 +358,8 @@
void
nd6_setmtu(struct ifnet *ifp)
{
- if (ifp->if_afdata[AF_INET6] == NULL)
+ /* XXXGL: ??? */
+ if (ifp->if_inet6 == NULL)
return;
nd6_setmtu0(ifp, ND_IFINFO(ifp));
@@ -1644,7 +1646,8 @@
struct epoch_tracker et;
int error = 0;
- if (ifp->if_afdata[AF_INET6] == NULL)
+ /* XXXGL: ??? */
+ if (ifp->if_inet6 == NULL)
return (EPFNOSUPPORT);
switch (cmd) {
case OSIOCGIFINFO_IN6:
@@ -2137,7 +2140,7 @@
nd6_slowtimo, curvnet);
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifp, &V_ifnet, if_link) {
- if (ifp->if_afdata[AF_INET6] == NULL)
+ if (ifp->if_inet6 == NULL)
continue;
nd6if = ND_IFINFO(ifp);
if (nd6if->basereachable && /* already initialized */
diff --git a/sys/netinet6/scope6.c b/sys/netinet6/scope6.c
--- a/sys/netinet6/scope6.c
+++ b/sys/netinet6/scope6.c
@@ -73,8 +73,7 @@
VNET_DEFINE_STATIC(struct scope6_id, sid_default);
#define V_sid_default VNET(sid_default)
-#define SID(ifp) \
- (((struct in6_ifextra *)(ifp)->if_afdata[AF_INET6])->scope6_id)
+#define SID(ifp) ((ifp)->if_inet6->scope6_id)
static int scope6_get(struct ifnet *, struct scope6_id *);
static int scope6_set(struct ifnet *, struct scope6_id *);
@@ -118,7 +117,7 @@
{
struct in6_ifreq *ifr;
- if (ifp->if_afdata[AF_INET6] == NULL)
+ if (ifp->if_inet6 == NULL)
return (EPFNOSUPPORT);
ifr = (struct in6_ifreq *)data;
@@ -433,7 +432,8 @@
struct epoch_tracker et;
NET_EPOCH_ENTER(et);
- if (ifp->if_afdata[AF_INET6] == NULL) {
+ /* XXXGL */
+ if (ifp->if_inet6 == NULL) {
NET_EPOCH_EXIT(et);
return (ENETDOWN);
}
@@ -517,7 +517,7 @@
return (NULL);
/* An interface might not be IPv6 capable. */
- if (ifp->if_afdata[AF_INET6] == NULL) {
+ if (ifp->if_inet6 == NULL) {
log(LOG_NOTICE,
"%s: embedded scope points to an interface without "
"IPv6: %s%%%d.\n", __func__,
diff --git a/sys/sys/domain.h b/sys/sys/domain.h
--- a/sys/sys/domain.h
+++ b/sys/sys/domain.h
@@ -56,8 +56,6 @@
(uint32_t);
void (*dom_rtdetach) /* clean up routing table */
(struct rib_head *);
- void *(*dom_ifattach)(struct ifnet *);
- void (*dom_ifdetach)(struct ifnet *, void *);
struct protosw *dom_protosw[];
};
diff --git a/sys/sys/kernel.h b/sys/sys/kernel.h
--- a/sys/sys/kernel.h
+++ b/sys/sys/kernel.h
@@ -154,9 +154,9 @@
SI_SUB_EXEC = 0x7400000, /* execve() handlers */
SI_SUB_PROTO_BEGIN = 0x8000000, /* VNET initialization */
SI_SUB_PROTO_PFIL = 0x8100000, /* Initialize pfil before FWs */
+ SI_SUB_PROTO_MC = 0x8300000, /* Multicast */
SI_SUB_PROTO_IF = 0x8400000, /* interfaces */
SI_SUB_PROTO_DOMAININIT = 0x8600000, /* domain registration system */
- SI_SUB_PROTO_MC = 0x8700000, /* Multicast */
SI_SUB_PROTO_DOMAIN = 0x8800000, /* domains (address families?) */
SI_SUB_PROTO_FIREWALL = 0x8806000, /* Firewalls */
SI_SUB_PROTO_IFATTACHDOMAIN = 0x8808000,/* domain dependent data init */

File Metadata

Mime Type
text/plain
Expires
Fri, Dec 26, 10:39 PM (34 m, 40 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27291298
Default Alt Text
D54089.id167594.diff (28 KB)

Event Timeline