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
This commit is contained in:
parent
7dc6a1e18b
commit
29381991cf
@ -114,6 +114,9 @@ struct protosw inetsw[] = {
|
||||
.pr_domain = &inetdomain,
|
||||
.pr_protocol = IPPROTO_IP,
|
||||
.pr_init = ip_init,
|
||||
#ifdef VIMAGE
|
||||
.pr_destroy = ip_destroy,
|
||||
#endif
|
||||
.pr_slowtimo = ip_slowtimo,
|
||||
.pr_drain = ip_drain,
|
||||
.pr_usrreqs = &nousrreqs
|
||||
|
@ -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();
|
||||
|
@ -212,6 +212,9 @@ int ip_fragment(struct ip *ip, struct mbuf **m_frag, int mtu,
|
||||
u_long if_hwassist_flags, int sw_csum);
|
||||
void ip_forward(struct mbuf *m, int srcrt);
|
||||
void ip_init(void);
|
||||
#ifdef VIMAGE
|
||||
void ip_destroy(void);
|
||||
#endif
|
||||
extern int
|
||||
(*ip_mforward)(struct ip *, struct ifnet *, struct mbuf *,
|
||||
struct ip_moptions *);
|
||||
|
Loading…
x
Reference in New Issue
Block a user