diff options
author | bz <bz@FreeBSD.org> | 2010-02-20 19:59:52 +0000 |
---|---|---|
committer | bz <bz@FreeBSD.org> | 2010-02-20 19:59:52 +0000 |
commit | 29381991cf960220b44aa20487b64388a3fa5947 (patch) | |
tree | 5ec75ede6a751d9bc70d82667be1b9df3611beb8 /sys/netinet/ip_input.c | |
parent | 7dc6a1e18b26c51d1b47d35a6b92a45cf198bf64 (diff) | |
download | FreeBSD-src-29381991cf960220b44aa20487b64388a3fa5947.zip FreeBSD-src-29381991cf960220b44aa20487b64388a3fa5947.tar.gz |
Split up ip_drain() into an outer lock and iterator part and
a "locked" version that will only handle a single network stack
instance. The latter is called directly from ip_destroy().
Hook up an ip_destroy() function to release resources from the
legacy IP network layer upon virtual network stack teardown.
Sponsored by: ISPsystem
Reviewed by: rwatson
MFC After: 5 days
Diffstat (limited to 'sys/netinet/ip_input.c')
-rw-r--r-- | sys/netinet/ip_input.c | 42 |
1 files changed, 34 insertions, 8 deletions
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c index 8ffa01a..084bac0 100644 --- a/sys/netinet/ip_input.c +++ b/sys/netinet/ip_input.c @@ -199,6 +199,7 @@ static struct mtx ipqlock; static void maxnipq_update(void); static void ipq_zone_change(void *); +static void ip_drain_locked(void); SYSCTL_VNET_INT(_net_inet_ip, OID_AUTO, fragpackets, CTLFLAG_RD, &VNET_NAME(nipq), 0, @@ -368,6 +369,22 @@ ip_init(void) netisr_register(&ip_nh); } +#ifdef VIMAGE +void +ip_destroy(void) +{ + + /* Cleanup in_ifaddr hash table; should be empty. */ + hashdestroy(V_in_ifaddrhashtbl, M_IFADDR, V_in_ifaddrhmask); + + IPQ_LOCK(); + ip_drain_locked(); + IPQ_UNLOCK(); + + uma_zdestroy(V_ipq_zone); +} +#endif + void ip_fini(void *xtp) { @@ -1237,23 +1254,32 @@ ip_slowtimo(void) /* * Drain off all datagram fragments. */ +static void +ip_drain_locked(void) +{ + int i; + + IPQ_LOCK_ASSERT(); + + for (i = 0; i < IPREASS_NHASH; i++) { + while(!TAILQ_EMPTY(&V_ipq[i])) { + IPSTAT_ADD(ips_fragdropped, + TAILQ_FIRST(&V_ipq[i])->ipq_nfrags); + ip_freef(&V_ipq[i], TAILQ_FIRST(&V_ipq[i])); + } + } +} + void ip_drain(void) { VNET_ITERATOR_DECL(vnet_iter); - int i; VNET_LIST_RLOCK_NOSLEEP(); IPQ_LOCK(); VNET_FOREACH(vnet_iter) { CURVNET_SET(vnet_iter); - for (i = 0; i < IPREASS_NHASH; i++) { - while(!TAILQ_EMPTY(&V_ipq[i])) { - IPSTAT_ADD(ips_fragdropped, - TAILQ_FIRST(&V_ipq[i])->ipq_nfrags); - ip_freef(&V_ipq[i], TAILQ_FIRST(&V_ipq[i])); - } - } + ip_drain_locked(); CURVNET_RESTORE(); } IPQ_UNLOCK(); |