Commit 6b102865 authored by Amerigo Wang's avatar Amerigo Wang Committed by David S. Miller

ipv6: unify fragment thresh handling code

Cc: Herbert Xu <herbert@gondor.apana.org.au>
Cc: Michal Kubeček <mkubecek@suse.cz>
Cc: David Miller <davem@davemloft.net>
Signed-off-by: default avatarCong Wang <amwang@redhat.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent d4915c08
...@@ -61,7 +61,7 @@ void inet_frags_exit_net(struct netns_frags *nf, struct inet_frags *f); ...@@ -61,7 +61,7 @@ void inet_frags_exit_net(struct netns_frags *nf, struct inet_frags *f);
void inet_frag_kill(struct inet_frag_queue *q, struct inet_frags *f); void inet_frag_kill(struct inet_frag_queue *q, struct inet_frags *f);
void inet_frag_destroy(struct inet_frag_queue *q, void inet_frag_destroy(struct inet_frag_queue *q,
struct inet_frags *f, int *work); struct inet_frags *f, int *work);
int inet_frag_evictor(struct netns_frags *nf, struct inet_frags *f); int inet_frag_evictor(struct netns_frags *nf, struct inet_frags *f, bool force);
struct inet_frag_queue *inet_frag_find(struct netns_frags *nf, struct inet_frag_queue *inet_frag_find(struct netns_frags *nf,
struct inet_frags *f, void *key, unsigned int hash) struct inet_frags *f, void *key, unsigned int hash)
__releases(&f->lock); __releases(&f->lock);
......
...@@ -89,7 +89,7 @@ void inet_frags_exit_net(struct netns_frags *nf, struct inet_frags *f) ...@@ -89,7 +89,7 @@ void inet_frags_exit_net(struct netns_frags *nf, struct inet_frags *f)
nf->low_thresh = 0; nf->low_thresh = 0;
local_bh_disable(); local_bh_disable();
inet_frag_evictor(nf, f); inet_frag_evictor(nf, f, true);
local_bh_enable(); local_bh_enable();
} }
EXPORT_SYMBOL(inet_frags_exit_net); EXPORT_SYMBOL(inet_frags_exit_net);
...@@ -158,11 +158,16 @@ void inet_frag_destroy(struct inet_frag_queue *q, struct inet_frags *f, ...@@ -158,11 +158,16 @@ void inet_frag_destroy(struct inet_frag_queue *q, struct inet_frags *f,
} }
EXPORT_SYMBOL(inet_frag_destroy); EXPORT_SYMBOL(inet_frag_destroy);
int inet_frag_evictor(struct netns_frags *nf, struct inet_frags *f) int inet_frag_evictor(struct netns_frags *nf, struct inet_frags *f, bool force)
{ {
struct inet_frag_queue *q; struct inet_frag_queue *q;
int work, evicted = 0; int work, evicted = 0;
if (!force) {
if (atomic_read(&nf->mem) <= nf->high_thresh)
return 0;
}
work = atomic_read(&nf->mem) - nf->low_thresh; work = atomic_read(&nf->mem) - nf->low_thresh;
while (work > 0) { while (work > 0) {
read_lock(&f->lock); read_lock(&f->lock);
......
...@@ -219,7 +219,7 @@ static void ip_evictor(struct net *net) ...@@ -219,7 +219,7 @@ static void ip_evictor(struct net *net)
{ {
int evicted; int evicted;
evicted = inet_frag_evictor(&net->ipv4.frags, &ip4_frags); evicted = inet_frag_evictor(&net->ipv4.frags, &ip4_frags, false);
if (evicted) if (evicted)
IP_ADD_STATS_BH(net, IPSTATS_MIB_REASMFAILS, evicted); IP_ADD_STATS_BH(net, IPSTATS_MIB_REASMFAILS, evicted);
} }
...@@ -684,8 +684,7 @@ int ip_defrag(struct sk_buff *skb, u32 user) ...@@ -684,8 +684,7 @@ int ip_defrag(struct sk_buff *skb, u32 user)
IP_INC_STATS_BH(net, IPSTATS_MIB_REASMREQDS); IP_INC_STATS_BH(net, IPSTATS_MIB_REASMREQDS);
/* Start by cleaning up the memory. */ /* Start by cleaning up the memory. */
if (atomic_read(&net->ipv4.frags.mem) > net->ipv4.frags.high_thresh) ip_evictor(net);
ip_evictor(net);
/* Lookup (or create) queue header */ /* Lookup (or create) queue header */
if ((qp = ip_find(net, ip_hdr(skb), user)) != NULL) { if ((qp = ip_find(net, ip_hdr(skb), user)) != NULL) {
......
...@@ -566,11 +566,9 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb, u32 user) ...@@ -566,11 +566,9 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb, u32 user)
hdr = ipv6_hdr(clone); hdr = ipv6_hdr(clone);
fhdr = (struct frag_hdr *)skb_transport_header(clone); fhdr = (struct frag_hdr *)skb_transport_header(clone);
if (atomic_read(&net->nf_frag.frags.mem) > net->nf_frag.frags.high_thresh) { local_bh_disable();
local_bh_disable(); inet_frag_evictor(&net->nf_frag.frags, &nf_frags, false);
inet_frag_evictor(&net->nf_frag.frags, &nf_frags); local_bh_enable();
local_bh_enable();
}
fq = fq_find(net, fhdr->identification, user, &hdr->saddr, &hdr->daddr); fq = fq_find(net, fhdr->identification, user, &hdr->saddr, &hdr->daddr);
if (fq == NULL) { if (fq == NULL) {
......
...@@ -131,15 +131,6 @@ void ip6_frag_init(struct inet_frag_queue *q, void *a) ...@@ -131,15 +131,6 @@ void ip6_frag_init(struct inet_frag_queue *q, void *a)
} }
EXPORT_SYMBOL(ip6_frag_init); EXPORT_SYMBOL(ip6_frag_init);
static void ip6_evictor(struct net *net, struct inet6_dev *idev)
{
int evicted;
evicted = inet_frag_evictor(&net->ipv6.frags, &ip6_frags);
if (evicted)
IP6_ADD_STATS_BH(net, idev, IPSTATS_MIB_REASMFAILS, evicted);
}
void ip6_expire_frag_queue(struct net *net, struct frag_queue *fq, void ip6_expire_frag_queue(struct net *net, struct frag_queue *fq,
struct inet_frags *frags) struct inet_frags *frags)
{ {
...@@ -515,6 +506,7 @@ static int ipv6_frag_rcv(struct sk_buff *skb) ...@@ -515,6 +506,7 @@ static int ipv6_frag_rcv(struct sk_buff *skb)
struct frag_queue *fq; struct frag_queue *fq;
const struct ipv6hdr *hdr = ipv6_hdr(skb); const struct ipv6hdr *hdr = ipv6_hdr(skb);
struct net *net = dev_net(skb_dst(skb)->dev); struct net *net = dev_net(skb_dst(skb)->dev);
int evicted;
IP6_INC_STATS_BH(net, ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_REASMREQDS); IP6_INC_STATS_BH(net, ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_REASMREQDS);
...@@ -539,8 +531,10 @@ static int ipv6_frag_rcv(struct sk_buff *skb) ...@@ -539,8 +531,10 @@ static int ipv6_frag_rcv(struct sk_buff *skb)
return 1; return 1;
} }
if (atomic_read(&net->ipv6.frags.mem) > net->ipv6.frags.high_thresh) evicted = inet_frag_evictor(&net->ipv6.frags, &ip6_frags, false);
ip6_evictor(net, ip6_dst_idev(skb_dst(skb))); if (evicted)
IP6_ADD_STATS_BH(net, ip6_dst_idev(skb_dst(skb)),
IPSTATS_MIB_REASMFAILS, evicted);
fq = fq_find(net, fhdr->identification, &hdr->saddr, &hdr->daddr); fq = fq_find(net, fhdr->identification, &hdr->saddr, &hdr->daddr);
if (fq != NULL) { if (fq != NULL) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment