Commit 6b102865e7ba9ff1e3c49c32c7187bb427d91798

Authored by Amerigo Wang
Committed by David S. Miller
1 parent d4915c087f

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: Cong Wang <amwang@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 5 changed files with 18 additions and 22 deletions Side-by-side Diff

include/net/inet_frag.h
... ... @@ -61,7 +61,7 @@
61 61 void inet_frag_kill(struct inet_frag_queue *q, struct inet_frags *f);
62 62 void inet_frag_destroy(struct inet_frag_queue *q,
63 63 struct inet_frags *f, int *work);
64   -int inet_frag_evictor(struct netns_frags *nf, struct inet_frags *f);
  64 +int inet_frag_evictor(struct netns_frags *nf, struct inet_frags *f, bool force);
65 65 struct inet_frag_queue *inet_frag_find(struct netns_frags *nf,
66 66 struct inet_frags *f, void *key, unsigned int hash)
67 67 __releases(&f->lock);
net/ipv4/inet_fragment.c
... ... @@ -89,7 +89,7 @@
89 89 nf->low_thresh = 0;
90 90  
91 91 local_bh_disable();
92   - inet_frag_evictor(nf, f);
  92 + inet_frag_evictor(nf, f, true);
93 93 local_bh_enable();
94 94 }
95 95 EXPORT_SYMBOL(inet_frags_exit_net);
96 96  
... ... @@ -158,10 +158,15 @@
158 158 }
159 159 EXPORT_SYMBOL(inet_frag_destroy);
160 160  
161   -int inet_frag_evictor(struct netns_frags *nf, struct inet_frags *f)
  161 +int inet_frag_evictor(struct netns_frags *nf, struct inet_frags *f, bool force)
162 162 {
163 163 struct inet_frag_queue *q;
164 164 int work, evicted = 0;
  165 +
  166 + if (!force) {
  167 + if (atomic_read(&nf->mem) <= nf->high_thresh)
  168 + return 0;
  169 + }
165 170  
166 171 work = atomic_read(&nf->mem) - nf->low_thresh;
167 172 while (work > 0) {
net/ipv4/ip_fragment.c
... ... @@ -219,7 +219,7 @@
219 219 {
220 220 int evicted;
221 221  
222   - evicted = inet_frag_evictor(&net->ipv4.frags, &ip4_frags);
  222 + evicted = inet_frag_evictor(&net->ipv4.frags, &ip4_frags, false);
223 223 if (evicted)
224 224 IP_ADD_STATS_BH(net, IPSTATS_MIB_REASMFAILS, evicted);
225 225 }
... ... @@ -684,8 +684,7 @@
684 684 IP_INC_STATS_BH(net, IPSTATS_MIB_REASMREQDS);
685 685  
686 686 /* Start by cleaning up the memory. */
687   - if (atomic_read(&net->ipv4.frags.mem) > net->ipv4.frags.high_thresh)
688   - ip_evictor(net);
  687 + ip_evictor(net);
689 688  
690 689 /* Lookup (or create) queue header */
691 690 if ((qp = ip_find(net, ip_hdr(skb), user)) != NULL) {
net/ipv6/netfilter/nf_conntrack_reasm.c
... ... @@ -566,11 +566,9 @@
566 566 hdr = ipv6_hdr(clone);
567 567 fhdr = (struct frag_hdr *)skb_transport_header(clone);
568 568  
569   - if (atomic_read(&net->nf_frag.frags.mem) > net->nf_frag.frags.high_thresh) {
570   - local_bh_disable();
571   - inet_frag_evictor(&net->nf_frag.frags, &nf_frags);
572   - local_bh_enable();
573   - }
  569 + local_bh_disable();
  570 + inet_frag_evictor(&net->nf_frag.frags, &nf_frags, false);
  571 + local_bh_enable();
574 572  
575 573 fq = fq_find(net, fhdr->identification, user, &hdr->saddr, &hdr->daddr);
576 574 if (fq == NULL) {
net/ipv6/reassembly.c
... ... @@ -131,15 +131,6 @@
131 131 }
132 132 EXPORT_SYMBOL(ip6_frag_init);
133 133  
134   -static void ip6_evictor(struct net *net, struct inet6_dev *idev)
135   -{
136   - int evicted;
137   -
138   - evicted = inet_frag_evictor(&net->ipv6.frags, &ip6_frags);
139   - if (evicted)
140   - IP6_ADD_STATS_BH(net, idev, IPSTATS_MIB_REASMFAILS, evicted);
141   -}
142   -
143 134 void ip6_expire_frag_queue(struct net *net, struct frag_queue *fq,
144 135 struct inet_frags *frags)
145 136 {
... ... @@ -515,6 +506,7 @@
515 506 struct frag_queue *fq;
516 507 const struct ipv6hdr *hdr = ipv6_hdr(skb);
517 508 struct net *net = dev_net(skb_dst(skb)->dev);
  509 + int evicted;
518 510  
519 511 IP6_INC_STATS_BH(net, ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_REASMREQDS);
520 512  
... ... @@ -539,8 +531,10 @@
539 531 return 1;
540 532 }
541 533  
542   - if (atomic_read(&net->ipv6.frags.mem) > net->ipv6.frags.high_thresh)
543   - ip6_evictor(net, ip6_dst_idev(skb_dst(skb)));
  534 + evicted = inet_frag_evictor(&net->ipv6.frags, &ip6_frags, false);
  535 + if (evicted)
  536 + IP6_ADD_STATS_BH(net, ip6_dst_idev(skb_dst(skb)),
  537 + IPSTATS_MIB_REASMFAILS, evicted);
544 538  
545 539 fq = fq_find(net, fhdr->identification, &hdr->saddr, &hdr->daddr);
546 540 if (fq != NULL) {