summaryrefslogtreecommitdiffstats
path: root/sys/net/if.c
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2009-04-23 10:59:40 +0000
committerrwatson <rwatson@FreeBSD.org>2009-04-23 10:59:40 +0000
commitbf5b2167ac0cacf1ff816efc0f73ed8e20386341 (patch)
treeadd4802821083cfeb421bf310a555a943e1a5c29 /sys/net/if.c
parentc797841f0da1dbdd3f6280d977851c0b16d96d9c (diff)
downloadFreeBSD-src-bf5b2167ac0cacf1ff816efc0f73ed8e20386341.zip
FreeBSD-src-bf5b2167ac0cacf1ff816efc0f73ed8e20386341.tar.gz
Move portions of data structure initialization from if_attach() to
if_alloc(), and portions of data structure destruction from if_detach() to if_free(). These changes leave more of the struct ifnet in a safe-to-access condition between alloc and attach, and between detach and free, and focus on attach/detach as stack usage events rather than data structure initialization. Affected fields include the linkstate task queue, if_afdata lock, address lists, kqueue state, and MAC labels. ifq_attach() ifq_detach() are not moved as ifq_attach() may use a queue length set by the device driver between if_alloc() and if_attach(). MFC after: 3 weeks
Diffstat (limited to 'sys/net/if.c')
-rw-r--r--sys/net/if.c45
1 files changed, 21 insertions, 24 deletions
diff --git a/sys/net/if.c b/sys/net/if.c
index d81d06b..54cd916 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -478,7 +478,7 @@ if_check(void *dummy __unused)
* common structure will also be allocated if an allocation routine is
* registered for the passed type.
*/
-struct ifnet*
+struct ifnet *
if_alloc(u_char type)
{
INIT_VNET_NET(curvnet);
@@ -518,6 +518,18 @@ if_alloc(u_char type)
}
IF_ADDR_LOCK_INIT(ifp);
+ TASK_INIT(&ifp->if_linktask, 0, do_link_state_change, ifp);
+ IF_AFDATA_LOCK_INIT(ifp);
+ ifp->if_afdata_initialized = 0;
+ TAILQ_INIT(&ifp->if_addrhead);
+ TAILQ_INIT(&ifp->if_prefixhead);
+ TAILQ_INIT(&ifp->if_multiaddrs);
+ TAILQ_INIT(&ifp->if_groups);
+ knlist_init(&ifp->if_klist, NULL, NULL, NULL, NULL);
+#ifdef MAC
+ mac_ifnet_init(ifp);
+#endif
+
refcount_init(&ifp->if_refcount, 1); /* Index reference. */
IFNET_WLOCK();
ifnet_setbyindex(ifp->if_index, ifp);
@@ -550,6 +562,13 @@ if_free_internal(struct ifnet *ifp)
if_com_free[ifp->if_alloctype](ifp->if_l2com,
ifp->if_alloctype);
+#ifdef MAC
+ mac_ifnet_destroy(ifp);
+#endif /* MAC */
+ KNOTE_UNLOCKED(&ifp->if_klist, NOTE_EXIT);
+ knlist_clear(&ifp->if_klist, 0);
+ knlist_destroy(&ifp->if_klist);
+ IF_AFDATA_DESTROY(ifp);
IF_ADDR_LOCK_DESTROY(ifp);
free(ifp, M_IFNET);
}
@@ -638,8 +657,6 @@ ifq_detach(struct ifaltq *ifq)
* XXX:
* - The decision to return void and thus require this function to
* succeed is questionable.
- * - We do more initialization here then is probably a good idea.
- * Some of this should probably move to if_alloc().
* - We should probably do more sanity checking. For instance we don't
* do anything to insure if_xname is unique or non-empty.
*/
@@ -656,32 +673,21 @@ if_attach(struct ifnet *ifp)
panic ("%s: BUG: if_attach called without if_alloc'd input()\n",
ifp->if_xname);
- TASK_INIT(&ifp->if_linktask, 0, do_link_state_change, ifp);
- IF_AFDATA_LOCK_INIT(ifp);
- ifp->if_afdata_initialized = 0;
-
- TAILQ_INIT(&ifp->if_addrhead);
- TAILQ_INIT(&ifp->if_prefixhead);
- TAILQ_INIT(&ifp->if_multiaddrs);
- TAILQ_INIT(&ifp->if_groups);
-
if_addgroup(ifp, IFG_ALL);
- knlist_init(&ifp->if_klist, NULL, NULL, NULL, NULL);
getmicrotime(&ifp->if_lastchange);
ifp->if_data.ifi_epoch = time_uptime;
ifp->if_data.ifi_datalen = sizeof(struct if_data);
+
KASSERT((ifp->if_transmit == NULL && ifp->if_qflush == NULL) ||
(ifp->if_transmit != NULL && ifp->if_qflush != NULL),
("transmit and qflush must both either be set or both be NULL"));
-
if (ifp->if_transmit == NULL) {
ifp->if_transmit = if_transmit;
ifp->if_qflush = if_qflush;
}
#ifdef MAC
- mac_ifnet_init(ifp);
mac_ifnet_create(ifp);
#endif
@@ -729,7 +735,6 @@ if_attach(struct ifnet *ifp)
TAILQ_INSERT_HEAD(&ifp->if_addrhead, ifa, ifa_link);
ifp->if_broadcastaddr = NULL; /* reliably crash if used uninitialized */
-
IFNET_WLOCK();
TAILQ_INSERT_TAIL(&V_ifnet, ifp, if_link);
IFNET_WUNLOCK();
@@ -967,15 +972,7 @@ if_detach(struct ifnet *ifp)
ifp->if_afdata[dp->dom_family]);
}
IF_AFDATA_UNLOCK(ifp);
-
-#ifdef MAC
- mac_ifnet_destroy(ifp);
-#endif /* MAC */
- KNOTE_UNLOCKED(&ifp->if_klist, NOTE_EXIT);
- knlist_clear(&ifp->if_klist, 0);
- knlist_destroy(&ifp->if_klist);
ifq_detach(&ifp->if_snd);
- IF_AFDATA_DESTROY(ifp);
splx(s);
}
OpenPOWER on IntegriCloud