aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/ip_fragment.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/ip_fragment.c')
-rw-r--r--net/ipv4/ip_fragment.c24
1 files changed, 11 insertions, 13 deletions
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
index f55a4e61bfb8..927fe58caf46 100644
--- a/net/ipv4/ip_fragment.c
+++ b/net/ipv4/ip_fragment.c
@@ -122,7 +122,7 @@ int ip_frag_nqueues(struct net *net)
122 122
123int ip_frag_mem(struct net *net) 123int ip_frag_mem(struct net *net)
124{ 124{
125 return atomic_read(&net->ipv4.frags.mem); 125 return sum_frag_mem_limit(&net->ipv4.frags);
126} 126}
127 127
128static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev, 128static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
@@ -161,13 +161,6 @@ static bool ip4_frag_match(struct inet_frag_queue *q, void *a)
161 qp->user == arg->user; 161 qp->user == arg->user;
162} 162}
163 163
164/* Memory Tracking Functions. */
165static void frag_kfree_skb(struct netns_frags *nf, struct sk_buff *skb)
166{
167 atomic_sub(skb->truesize, &nf->mem);
168 kfree_skb(skb);
169}
170
171static void ip4_frag_init(struct inet_frag_queue *q, void *a) 164static void ip4_frag_init(struct inet_frag_queue *q, void *a)
172{ 165{
173 struct ipq *qp = container_of(q, struct ipq, q); 166 struct ipq *qp = container_of(q, struct ipq, q);
@@ -340,6 +333,7 @@ static inline int ip_frag_too_far(struct ipq *qp)
340static int ip_frag_reinit(struct ipq *qp) 333static int ip_frag_reinit(struct ipq *qp)
341{ 334{
342 struct sk_buff *fp; 335 struct sk_buff *fp;
336 unsigned int sum_truesize = 0;
343 337
344 if (!mod_timer(&qp->q.timer, jiffies + qp->q.net->timeout)) { 338 if (!mod_timer(&qp->q.timer, jiffies + qp->q.net->timeout)) {
345 atomic_inc(&qp->q.refcnt); 339 atomic_inc(&qp->q.refcnt);
@@ -349,9 +343,12 @@ static int ip_frag_reinit(struct ipq *qp)
349 fp = qp->q.fragments; 343 fp = qp->q.fragments;
350 do { 344 do {
351 struct sk_buff *xp = fp->next; 345 struct sk_buff *xp = fp->next;
352 frag_kfree_skb(qp->q.net, fp); 346
347 sum_truesize += fp->truesize;
348 kfree_skb(fp);
353 fp = xp; 349 fp = xp;
354 } while (fp); 350 } while (fp);
351 sub_frag_mem_limit(&qp->q, sum_truesize);
355 352
356 qp->q.last_in = 0; 353 qp->q.last_in = 0;
357 qp->q.len = 0; 354 qp->q.len = 0;
@@ -496,7 +493,8 @@ found:
496 qp->q.fragments = next; 493 qp->q.fragments = next;
497 494
498 qp->q.meat -= free_it->len; 495 qp->q.meat -= free_it->len;
499 frag_kfree_skb(qp->q.net, free_it); 496 sub_frag_mem_limit(&qp->q, free_it->truesize);
497 kfree_skb(free_it);
500 } 498 }
501 } 499 }
502 500
@@ -519,7 +517,7 @@ found:
519 qp->q.stamp = skb->tstamp; 517 qp->q.stamp = skb->tstamp;
520 qp->q.meat += skb->len; 518 qp->q.meat += skb->len;
521 qp->ecn |= ecn; 519 qp->ecn |= ecn;
522 atomic_add(skb->truesize, &qp->q.net->mem); 520 add_frag_mem_limit(&qp->q, skb->truesize);
523 if (offset == 0) 521 if (offset == 0)
524 qp->q.last_in |= INET_FRAG_FIRST_IN; 522 qp->q.last_in |= INET_FRAG_FIRST_IN;
525 523
@@ -617,7 +615,7 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
617 head->len -= clone->len; 615 head->len -= clone->len;
618 clone->csum = 0; 616 clone->csum = 0;
619 clone->ip_summed = head->ip_summed; 617 clone->ip_summed = head->ip_summed;
620 atomic_add(clone->truesize, &qp->q.net->mem); 618 add_frag_mem_limit(&qp->q, clone->truesize);
621 } 619 }
622 620
623 skb_push(head, head->data - skb_network_header(head)); 621 skb_push(head, head->data - skb_network_header(head));
@@ -645,7 +643,7 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
645 } 643 }
646 fp = next; 644 fp = next;
647 } 645 }
648 atomic_sub(sum_truesize, &qp->q.net->mem); 646 sub_frag_mem_limit(&qp->q, sum_truesize);
649 647
650 head->next = NULL; 648 head->next = NULL;
651 head->dev = dev; 649 head->dev = dev;