Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F140610481
D54089.id167594.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
28 KB
Referenced Files
None
Subscribers
None
D54089.id167594.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D54089: net: attach IPv4 and IPv6 stacks to an interface with EVENTHANDLER(9)
Attached
Detach File
Event Timeline
Log In to Comment