aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPavel Emelyanov <xemul@openvz.org>2008-01-22 09:07:25 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 18:10:36 -0500
commit6ddc082223ef0f73717b4133fa7e648842bbfd02 (patch)
tree62315ac04e396bc6e68543502fb6aeec50be6662
parente5a2bb842cd9681d00d4ca963e63e4d3647e66f8 (diff)
[NETNS][FRAGS]: Make the mem counter per-namespace.
This is also simple, but introduces more changes, since then mem counter is altered in more places. Signed-off-by: Pavel Emelyanov <xemul@openvz.org> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/net/inet_frag.h4
-rw-r--r--include/net/ip.h2
-rw-r--r--include/net/ipv6.h2
-rw-r--r--net/ipv4/inet_fragment.c21
-rw-r--r--net/ipv4/ip_fragment.c29
-rw-r--r--net/ipv4/proc.c2
-rw-r--r--net/ipv6/netfilter/nf_conntrack_reasm.c14
-rw-r--r--net/ipv6/proc.c2
-rw-r--r--net/ipv6/reassembly.c28
9 files changed, 54 insertions, 50 deletions
diff --git a/include/net/inet_frag.h b/include/net/inet_frag.h
index d36f3a6e6d4e..6edce7b2ff13 100644
--- a/include/net/inet_frag.h
+++ b/include/net/inet_frag.h
@@ -3,6 +3,7 @@
3 3
4struct netns_frags { 4struct netns_frags {
5 int nqueues; 5 int nqueues;
6 atomic_t mem;
6}; 7};
7 8
8struct inet_frag_queue { 9struct inet_frag_queue {
@@ -38,7 +39,6 @@ struct inet_frags {
38 rwlock_t lock; 39 rwlock_t lock;
39 u32 rnd; 40 u32 rnd;
40 int qsize; 41 int qsize;
41 atomic_t mem;
42 struct timer_list secret_timer; 42 struct timer_list secret_timer;
43 struct inet_frags_ctl *ctl; 43 struct inet_frags_ctl *ctl;
44 44
@@ -60,7 +60,7 @@ void inet_frags_init_net(struct netns_frags *nf);
60void inet_frag_kill(struct inet_frag_queue *q, struct inet_frags *f); 60void inet_frag_kill(struct inet_frag_queue *q, struct inet_frags *f);
61void inet_frag_destroy(struct inet_frag_queue *q, 61void inet_frag_destroy(struct inet_frag_queue *q,
62 struct inet_frags *f, int *work); 62 struct inet_frags *f, int *work);
63int inet_frag_evictor(struct inet_frags *f); 63int inet_frag_evictor(struct netns_frags *nf, struct inet_frags *f);
64struct inet_frag_queue *inet_frag_find(struct netns_frags *nf, 64struct inet_frag_queue *inet_frag_find(struct netns_frags *nf,
65 struct inet_frags *f, void *key, unsigned int hash); 65 struct inet_frags *f, void *key, unsigned int hash);
66 66
diff --git a/include/net/ip.h b/include/net/ip.h
index fbe28308bf73..9f50d4f1f157 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -331,7 +331,7 @@ enum ip_defrag_users
331}; 331};
332 332
333int ip_defrag(struct sk_buff *skb, u32 user); 333int ip_defrag(struct sk_buff *skb, u32 user);
334int ip_frag_mem(void); 334int ip_frag_mem(struct net *net);
335int ip_frag_nqueues(struct net *net); 335int ip_frag_nqueues(struct net *net);
336 336
337/* 337/*
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index da1c089680d8..fa80ea48639d 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -246,7 +246,7 @@ struct ipv6_txoptions *ipv6_fixup_options(struct ipv6_txoptions *opt_space,
246extern int ipv6_opt_accepted(struct sock *sk, struct sk_buff *skb); 246extern int ipv6_opt_accepted(struct sock *sk, struct sk_buff *skb);
247 247
248int ip6_frag_nqueues(struct net *net); 248int ip6_frag_nqueues(struct net *net);
249int ip6_frag_mem(void); 249int ip6_frag_mem(struct net *net);
250 250
251#define IPV6_FRAG_TIMEOUT (60*HZ) /* 60 seconds */ 251#define IPV6_FRAG_TIMEOUT (60*HZ) /* 60 seconds */
252 252
diff --git a/net/ipv4/inet_fragment.c b/net/ipv4/inet_fragment.c
index 4fec0b911f85..ad79ae0c0264 100644
--- a/net/ipv4/inet_fragment.c
+++ b/net/ipv4/inet_fragment.c
@@ -63,8 +63,6 @@ void inet_frags_init(struct inet_frags *f)
63 f->rnd = (u32) ((num_physpages ^ (num_physpages>>7)) ^ 63 f->rnd = (u32) ((num_physpages ^ (num_physpages>>7)) ^
64 (jiffies ^ (jiffies >> 6))); 64 (jiffies ^ (jiffies >> 6)));
65 65
66 atomic_set(&f->mem, 0);
67
68 setup_timer(&f->secret_timer, inet_frag_secret_rebuild, 66 setup_timer(&f->secret_timer, inet_frag_secret_rebuild,
69 (unsigned long)f); 67 (unsigned long)f);
70 f->secret_timer.expires = jiffies + f->ctl->secret_interval; 68 f->secret_timer.expires = jiffies + f->ctl->secret_interval;
@@ -75,6 +73,7 @@ EXPORT_SYMBOL(inet_frags_init);
75void inet_frags_init_net(struct netns_frags *nf) 73void inet_frags_init_net(struct netns_frags *nf)
76{ 74{
77 nf->nqueues = 0; 75 nf->nqueues = 0;
76 atomic_set(&nf->mem, 0);
78} 77}
79EXPORT_SYMBOL(inet_frags_init_net); 78EXPORT_SYMBOL(inet_frags_init_net);
80 79
@@ -107,13 +106,13 @@ void inet_frag_kill(struct inet_frag_queue *fq, struct inet_frags *f)
107 106
108EXPORT_SYMBOL(inet_frag_kill); 107EXPORT_SYMBOL(inet_frag_kill);
109 108
110static inline void frag_kfree_skb(struct inet_frags *f, struct sk_buff *skb, 109static inline void frag_kfree_skb(struct netns_frags *nf, struct inet_frags *f,
111 int *work) 110 struct sk_buff *skb, int *work)
112{ 111{
113 if (work) 112 if (work)
114 *work -= skb->truesize; 113 *work -= skb->truesize;
115 114
116 atomic_sub(skb->truesize, &f->mem); 115 atomic_sub(skb->truesize, &nf->mem);
117 if (f->skb_free) 116 if (f->skb_free)
118 f->skb_free(skb); 117 f->skb_free(skb);
119 kfree_skb(skb); 118 kfree_skb(skb);
@@ -123,22 +122,24 @@ void inet_frag_destroy(struct inet_frag_queue *q, struct inet_frags *f,
123 int *work) 122 int *work)
124{ 123{
125 struct sk_buff *fp; 124 struct sk_buff *fp;
125 struct netns_frags *nf;
126 126
127 BUG_TRAP(q->last_in & COMPLETE); 127 BUG_TRAP(q->last_in & COMPLETE);
128 BUG_TRAP(del_timer(&q->timer) == 0); 128 BUG_TRAP(del_timer(&q->timer) == 0);
129 129
130 /* Release all fragment data. */ 130 /* Release all fragment data. */
131 fp = q->fragments; 131 fp = q->fragments;
132 nf = q->net;
132 while (fp) { 133 while (fp) {
133 struct sk_buff *xp = fp->next; 134 struct sk_buff *xp = fp->next;
134 135
135 frag_kfree_skb(f, fp, work); 136 frag_kfree_skb(nf, f, fp, work);
136 fp = xp; 137 fp = xp;
137 } 138 }
138 139
139 if (work) 140 if (work)
140 *work -= f->qsize; 141 *work -= f->qsize;
141 atomic_sub(f->qsize, &f->mem); 142 atomic_sub(f->qsize, &nf->mem);
142 143
143 if (f->destructor) 144 if (f->destructor)
144 f->destructor(q); 145 f->destructor(q);
@@ -147,12 +148,12 @@ void inet_frag_destroy(struct inet_frag_queue *q, struct inet_frags *f,
147} 148}
148EXPORT_SYMBOL(inet_frag_destroy); 149EXPORT_SYMBOL(inet_frag_destroy);
149 150
150int inet_frag_evictor(struct inet_frags *f) 151int inet_frag_evictor(struct netns_frags *nf, struct inet_frags *f)
151{ 152{
152 struct inet_frag_queue *q; 153 struct inet_frag_queue *q;
153 int work, evicted = 0; 154 int work, evicted = 0;
154 155
155 work = atomic_read(&f->mem) - f->ctl->low_thresh; 156 work = atomic_read(&nf->mem) - f->ctl->low_thresh;
156 while (work > 0) { 157 while (work > 0) {
157 read_lock(&f->lock); 158 read_lock(&f->lock);
158 if (list_empty(&f->lru_list)) { 159 if (list_empty(&f->lru_list)) {
@@ -226,7 +227,7 @@ static struct inet_frag_queue *inet_frag_alloc(struct netns_frags *nf,
226 return NULL; 227 return NULL;
227 228
228 f->constructor(q, arg); 229 f->constructor(q, arg);
229 atomic_add(f->qsize, &f->mem); 230 atomic_add(f->qsize, &nf->mem);
230 setup_timer(&q->timer, f->frag_expire, (unsigned long)q); 231 setup_timer(&q->timer, f->frag_expire, (unsigned long)q);
231 spin_lock_init(&q->lock); 232 spin_lock_init(&q->lock);
232 atomic_set(&q->refcnt, 1); 233 atomic_set(&q->refcnt, 1);
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
index cd8c83025b48..4f013343cef7 100644
--- a/net/ipv4/ip_fragment.c
+++ b/net/ipv4/ip_fragment.c
@@ -100,9 +100,9 @@ int ip_frag_nqueues(struct net *net)
100 return net->ipv4.frags.nqueues; 100 return net->ipv4.frags.nqueues;
101} 101}
102 102
103int ip_frag_mem(void) 103int ip_frag_mem(struct net *net)
104{ 104{
105 return atomic_read(&ip4_frags.mem); 105 return atomic_read(&net->ipv4.frags.mem);
106} 106}
107 107
108static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev, 108static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
@@ -142,11 +142,12 @@ static int ip4_frag_match(struct inet_frag_queue *q, void *a)
142} 142}
143 143
144/* Memory Tracking Functions. */ 144/* Memory Tracking Functions. */
145static __inline__ void frag_kfree_skb(struct sk_buff *skb, int *work) 145static __inline__ void frag_kfree_skb(struct netns_frags *nf,
146 struct sk_buff *skb, int *work)
146{ 147{
147 if (work) 148 if (work)
148 *work -= skb->truesize; 149 *work -= skb->truesize;
149 atomic_sub(skb->truesize, &ip4_frags.mem); 150 atomic_sub(skb->truesize, &nf->mem);
150 kfree_skb(skb); 151 kfree_skb(skb);
151} 152}
152 153
@@ -192,11 +193,11 @@ static void ipq_kill(struct ipq *ipq)
192/* Memory limiting on fragments. Evictor trashes the oldest 193/* Memory limiting on fragments. Evictor trashes the oldest
193 * fragment queue until we are back under the threshold. 194 * fragment queue until we are back under the threshold.
194 */ 195 */
195static void ip_evictor(void) 196static void ip_evictor(struct net *net)
196{ 197{
197 int evicted; 198 int evicted;
198 199
199 evicted = inet_frag_evictor(&ip4_frags); 200 evicted = inet_frag_evictor(&net->ipv4.frags, &ip4_frags);
200 if (evicted) 201 if (evicted)
201 IP_ADD_STATS_BH(IPSTATS_MIB_REASMFAILS, evicted); 202 IP_ADD_STATS_BH(IPSTATS_MIB_REASMFAILS, evicted);
202} 203}
@@ -294,7 +295,7 @@ static int ip_frag_reinit(struct ipq *qp)
294 fp = qp->q.fragments; 295 fp = qp->q.fragments;
295 do { 296 do {
296 struct sk_buff *xp = fp->next; 297 struct sk_buff *xp = fp->next;
297 frag_kfree_skb(fp, NULL); 298 frag_kfree_skb(qp->q.net, fp, NULL);
298 fp = xp; 299 fp = xp;
299 } while (fp); 300 } while (fp);
300 301
@@ -431,7 +432,7 @@ static int ip_frag_queue(struct ipq *qp, struct sk_buff *skb)
431 qp->q.fragments = next; 432 qp->q.fragments = next;
432 433
433 qp->q.meat -= free_it->len; 434 qp->q.meat -= free_it->len;
434 frag_kfree_skb(free_it, NULL); 435 frag_kfree_skb(qp->q.net, free_it, NULL);
435 } 436 }
436 } 437 }
437 438
@@ -451,7 +452,7 @@ static int ip_frag_queue(struct ipq *qp, struct sk_buff *skb)
451 } 452 }
452 qp->q.stamp = skb->tstamp; 453 qp->q.stamp = skb->tstamp;
453 qp->q.meat += skb->len; 454 qp->q.meat += skb->len;
454 atomic_add(skb->truesize, &ip4_frags.mem); 455 atomic_add(skb->truesize, &qp->q.net->mem);
455 if (offset == 0) 456 if (offset == 0)
456 qp->q.last_in |= FIRST_IN; 457 qp->q.last_in |= FIRST_IN;
457 458
@@ -534,12 +535,12 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
534 head->len -= clone->len; 535 head->len -= clone->len;
535 clone->csum = 0; 536 clone->csum = 0;
536 clone->ip_summed = head->ip_summed; 537 clone->ip_summed = head->ip_summed;
537 atomic_add(clone->truesize, &ip4_frags.mem); 538 atomic_add(clone->truesize, &qp->q.net->mem);
538 } 539 }
539 540
540 skb_shinfo(head)->frag_list = head->next; 541 skb_shinfo(head)->frag_list = head->next;
541 skb_push(head, head->data - skb_network_header(head)); 542 skb_push(head, head->data - skb_network_header(head));
542 atomic_sub(head->truesize, &ip4_frags.mem); 543 atomic_sub(head->truesize, &qp->q.net->mem);
543 544
544 for (fp=head->next; fp; fp = fp->next) { 545 for (fp=head->next; fp; fp = fp->next) {
545 head->data_len += fp->len; 546 head->data_len += fp->len;
@@ -549,7 +550,7 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
549 else if (head->ip_summed == CHECKSUM_COMPLETE) 550 else if (head->ip_summed == CHECKSUM_COMPLETE)
550 head->csum = csum_add(head->csum, fp->csum); 551 head->csum = csum_add(head->csum, fp->csum);
551 head->truesize += fp->truesize; 552 head->truesize += fp->truesize;
552 atomic_sub(fp->truesize, &ip4_frags.mem); 553 atomic_sub(fp->truesize, &qp->q.net->mem);
553 } 554 }
554 555
555 head->next = NULL; 556 head->next = NULL;
@@ -588,8 +589,8 @@ int ip_defrag(struct sk_buff *skb, u32 user)
588 589
589 net = skb->dev->nd_net; 590 net = skb->dev->nd_net;
590 /* Start by cleaning up the memory. */ 591 /* Start by cleaning up the memory. */
591 if (atomic_read(&ip4_frags.mem) > ip4_frags_ctl.high_thresh) 592 if (atomic_read(&net->ipv4.frags.mem) > ip4_frags_ctl.high_thresh)
592 ip_evictor(); 593 ip_evictor(net);
593 594
594 /* Lookup (or create) queue header */ 595 /* Lookup (or create) queue header */
595 if ((qp = ip_find(net, ip_hdr(skb), user)) != NULL) { 596 if ((qp = ip_find(net, ip_hdr(skb), user)) != NULL) {
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c
index bae32808616e..d63474c6b400 100644
--- a/net/ipv4/proc.c
+++ b/net/ipv4/proc.c
@@ -62,7 +62,7 @@ static int sockstat_seq_show(struct seq_file *seq, void *v)
62 seq_printf(seq, "UDPLITE: inuse %d\n", sock_prot_inuse_get(&udplite_prot)); 62 seq_printf(seq, "UDPLITE: inuse %d\n", sock_prot_inuse_get(&udplite_prot));
63 seq_printf(seq, "RAW: inuse %d\n", sock_prot_inuse_get(&raw_prot)); 63 seq_printf(seq, "RAW: inuse %d\n", sock_prot_inuse_get(&raw_prot));
64 seq_printf(seq, "FRAG: inuse %d memory %d\n", 64 seq_printf(seq, "FRAG: inuse %d memory %d\n",
65 ip_frag_nqueues(&init_net), ip_frag_mem()); 65 ip_frag_nqueues(&init_net), ip_frag_mem(&init_net));
66 return 0; 66 return 0;
67} 67}
68 68
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index 0b9d0097b68d..cb826bea4b1b 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -155,7 +155,7 @@ static inline void frag_kfree_skb(struct sk_buff *skb, unsigned int *work)
155{ 155{
156 if (work) 156 if (work)
157 *work -= skb->truesize; 157 *work -= skb->truesize;
158 atomic_sub(skb->truesize, &nf_frags.mem); 158 atomic_sub(skb->truesize, &nf_init_frags.mem);
159 nf_skb_free(skb); 159 nf_skb_free(skb);
160 kfree_skb(skb); 160 kfree_skb(skb);
161} 161}
@@ -177,7 +177,7 @@ static __inline__ void fq_kill(struct nf_ct_frag6_queue *fq)
177 177
178static void nf_ct_frag6_evictor(void) 178static void nf_ct_frag6_evictor(void)
179{ 179{
180 inet_frag_evictor(&nf_frags); 180 inet_frag_evictor(&nf_init_frags, &nf_frags);
181} 181}
182 182
183static void nf_ct_frag6_expire(unsigned long data) 183static void nf_ct_frag6_expire(unsigned long data)
@@ -382,7 +382,7 @@ static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb,
382 skb->dev = NULL; 382 skb->dev = NULL;
383 fq->q.stamp = skb->tstamp; 383 fq->q.stamp = skb->tstamp;
384 fq->q.meat += skb->len; 384 fq->q.meat += skb->len;
385 atomic_add(skb->truesize, &nf_frags.mem); 385 atomic_add(skb->truesize, &nf_init_frags.mem);
386 386
387 /* The first fragment. 387 /* The first fragment.
388 * nhoffset is obtained from the first fragment, of course. 388 * nhoffset is obtained from the first fragment, of course.
@@ -459,7 +459,7 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev)
459 clone->ip_summed = head->ip_summed; 459 clone->ip_summed = head->ip_summed;
460 460
461 NFCT_FRAG6_CB(clone)->orig = NULL; 461 NFCT_FRAG6_CB(clone)->orig = NULL;
462 atomic_add(clone->truesize, &nf_frags.mem); 462 atomic_add(clone->truesize, &nf_init_frags.mem);
463 } 463 }
464 464
465 /* We have to remove fragment header from datagram and to relocate 465 /* We have to remove fragment header from datagram and to relocate
@@ -473,7 +473,7 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev)
473 skb_shinfo(head)->frag_list = head->next; 473 skb_shinfo(head)->frag_list = head->next;
474 skb_reset_transport_header(head); 474 skb_reset_transport_header(head);
475 skb_push(head, head->data - skb_network_header(head)); 475 skb_push(head, head->data - skb_network_header(head));
476 atomic_sub(head->truesize, &nf_frags.mem); 476 atomic_sub(head->truesize, &nf_init_frags.mem);
477 477
478 for (fp=head->next; fp; fp = fp->next) { 478 for (fp=head->next; fp; fp = fp->next) {
479 head->data_len += fp->len; 479 head->data_len += fp->len;
@@ -483,7 +483,7 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev)
483 else if (head->ip_summed == CHECKSUM_COMPLETE) 483 else if (head->ip_summed == CHECKSUM_COMPLETE)
484 head->csum = csum_add(head->csum, fp->csum); 484 head->csum = csum_add(head->csum, fp->csum);
485 head->truesize += fp->truesize; 485 head->truesize += fp->truesize;
486 atomic_sub(fp->truesize, &nf_frags.mem); 486 atomic_sub(fp->truesize, &nf_init_frags.mem);
487 } 487 }
488 488
489 head->next = NULL; 489 head->next = NULL;
@@ -633,7 +633,7 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb)
633 goto ret_orig; 633 goto ret_orig;
634 } 634 }
635 635
636 if (atomic_read(&nf_frags.mem) > nf_frags_ctl.high_thresh) 636 if (atomic_read(&nf_init_frags.mem) > nf_frags_ctl.high_thresh)
637 nf_ct_frag6_evictor(); 637 nf_ct_frag6_evictor();
638 638
639 fq = fq_find(fhdr->identification, &hdr->saddr, &hdr->daddr); 639 fq = fq_find(fhdr->identification, &hdr->saddr, &hdr->daddr);
diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c
index dec34c87cb4a..35e502a72495 100644
--- a/net/ipv6/proc.c
+++ b/net/ipv6/proc.c
@@ -44,7 +44,7 @@ static int sockstat6_seq_show(struct seq_file *seq, void *v)
44 seq_printf(seq, "RAW6: inuse %d\n", 44 seq_printf(seq, "RAW6: inuse %d\n",
45 sock_prot_inuse_get(&rawv6_prot)); 45 sock_prot_inuse_get(&rawv6_prot));
46 seq_printf(seq, "FRAG6: inuse %d memory %d\n", 46 seq_printf(seq, "FRAG6: inuse %d memory %d\n",
47 ip6_frag_nqueues(&init_net), ip6_frag_mem()); 47 ip6_frag_nqueues(&init_net), ip6_frag_mem(&init_net));
48 return 0; 48 return 0;
49} 49}
50 50
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index 77a874020f3a..241b2cc49bf5 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -89,9 +89,9 @@ int ip6_frag_nqueues(struct net *net)
89 return net->ipv6.frags.nqueues; 89 return net->ipv6.frags.nqueues;
90} 90}
91 91
92int ip6_frag_mem(void) 92int ip6_frag_mem(struct net *net)
93{ 93{
94 return atomic_read(&ip6_frags.mem); 94 return atomic_read(&net->ipv6.frags.mem);
95} 95}
96 96
97static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev, 97static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev,
@@ -149,11 +149,12 @@ int ip6_frag_match(struct inet_frag_queue *q, void *a)
149EXPORT_SYMBOL(ip6_frag_match); 149EXPORT_SYMBOL(ip6_frag_match);
150 150
151/* Memory Tracking Functions. */ 151/* Memory Tracking Functions. */
152static inline void frag_kfree_skb(struct sk_buff *skb, int *work) 152static inline void frag_kfree_skb(struct netns_frags *nf,
153 struct sk_buff *skb, int *work)
153{ 154{
154 if (work) 155 if (work)
155 *work -= skb->truesize; 156 *work -= skb->truesize;
156 atomic_sub(skb->truesize, &ip6_frags.mem); 157 atomic_sub(skb->truesize, &nf->mem);
157 kfree_skb(skb); 158 kfree_skb(skb);
158} 159}
159 160
@@ -183,11 +184,11 @@ static __inline__ void fq_kill(struct frag_queue *fq)
183 inet_frag_kill(&fq->q, &ip6_frags); 184 inet_frag_kill(&fq->q, &ip6_frags);
184} 185}
185 186
186static void ip6_evictor(struct inet6_dev *idev) 187static void ip6_evictor(struct net *net, struct inet6_dev *idev)
187{ 188{
188 int evicted; 189 int evicted;
189 190
190 evicted = inet_frag_evictor(&ip6_frags); 191 evicted = inet_frag_evictor(&net->ipv6.frags, &ip6_frags);
191 if (evicted) 192 if (evicted)
192 IP6_ADD_STATS_BH(idev, IPSTATS_MIB_REASMFAILS, evicted); 193 IP6_ADD_STATS_BH(idev, IPSTATS_MIB_REASMFAILS, evicted);
193} 194}
@@ -389,7 +390,7 @@ static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
389 fq->q.fragments = next; 390 fq->q.fragments = next;
390 391
391 fq->q.meat -= free_it->len; 392 fq->q.meat -= free_it->len;
392 frag_kfree_skb(free_it, NULL); 393 frag_kfree_skb(fq->q.net, free_it, NULL);
393 } 394 }
394 } 395 }
395 396
@@ -409,7 +410,7 @@ static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
409 } 410 }
410 fq->q.stamp = skb->tstamp; 411 fq->q.stamp = skb->tstamp;
411 fq->q.meat += skb->len; 412 fq->q.meat += skb->len;
412 atomic_add(skb->truesize, &ip6_frags.mem); 413 atomic_add(skb->truesize, &fq->q.net->mem);
413 414
414 /* The first fragment. 415 /* The first fragment.
415 * nhoffset is obtained from the first fragment, of course. 416 * nhoffset is obtained from the first fragment, of course.
@@ -503,7 +504,7 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev,
503 head->len -= clone->len; 504 head->len -= clone->len;
504 clone->csum = 0; 505 clone->csum = 0;
505 clone->ip_summed = head->ip_summed; 506 clone->ip_summed = head->ip_summed;
506 atomic_add(clone->truesize, &ip6_frags.mem); 507 atomic_add(clone->truesize, &fq->q.net->mem);
507 } 508 }
508 509
509 /* We have to remove fragment header from datagram and to relocate 510 /* We have to remove fragment header from datagram and to relocate
@@ -518,7 +519,7 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev,
518 skb_shinfo(head)->frag_list = head->next; 519 skb_shinfo(head)->frag_list = head->next;
519 skb_reset_transport_header(head); 520 skb_reset_transport_header(head);
520 skb_push(head, head->data - skb_network_header(head)); 521 skb_push(head, head->data - skb_network_header(head));
521 atomic_sub(head->truesize, &ip6_frags.mem); 522 atomic_sub(head->truesize, &fq->q.net->mem);
522 523
523 for (fp=head->next; fp; fp = fp->next) { 524 for (fp=head->next; fp; fp = fp->next) {
524 head->data_len += fp->len; 525 head->data_len += fp->len;
@@ -528,7 +529,7 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev,
528 else if (head->ip_summed == CHECKSUM_COMPLETE) 529 else if (head->ip_summed == CHECKSUM_COMPLETE)
529 head->csum = csum_add(head->csum, fp->csum); 530 head->csum = csum_add(head->csum, fp->csum);
530 head->truesize += fp->truesize; 531 head->truesize += fp->truesize;
531 atomic_sub(fp->truesize, &ip6_frags.mem); 532 atomic_sub(fp->truesize, &fq->q.net->mem);
532 } 533 }
533 534
534 head->next = NULL; 535 head->next = NULL;
@@ -600,8 +601,9 @@ static int ipv6_frag_rcv(struct sk_buff *skb)
600 } 601 }
601 602
602 net = skb->dev->nd_net; 603 net = skb->dev->nd_net;
603 if (atomic_read(&ip6_frags.mem) > init_net.ipv6.sysctl.frags.high_thresh) 604 if (atomic_read(&net->ipv6.frags.mem) >
604 ip6_evictor(ip6_dst_idev(skb->dst)); 605 init_net.ipv6.sysctl.frags.high_thresh)
606 ip6_evictor(net, ip6_dst_idev(skb->dst));
605 607
606 if ((fq = fq_find(net, fhdr->identification, &hdr->saddr, &hdr->daddr, 608 if ((fq = fq_find(net, fhdr->identification, &hdr->saddr, &hdr->daddr,
607 ip6_dst_idev(skb->dst))) != NULL) { 609 ip6_dst_idev(skb->dst))) != NULL) {