diff options
-rw-r--r-- | include/net/inet_frag.h | 4 | ||||
-rw-r--r-- | include/net/ip.h | 2 | ||||
-rw-r--r-- | include/net/ipv6.h | 2 | ||||
-rw-r--r-- | net/ipv4/inet_fragment.c | 21 | ||||
-rw-r--r-- | net/ipv4/ip_fragment.c | 29 | ||||
-rw-r--r-- | net/ipv4/proc.c | 2 | ||||
-rw-r--r-- | net/ipv6/netfilter/nf_conntrack_reasm.c | 14 | ||||
-rw-r--r-- | net/ipv6/proc.c | 2 | ||||
-rw-r--r-- | net/ipv6/reassembly.c | 28 |
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 | ||
4 | struct netns_frags { | 4 | struct netns_frags { |
5 | int nqueues; | 5 | int nqueues; |
6 | atomic_t mem; | ||
6 | }; | 7 | }; |
7 | 8 | ||
8 | struct inet_frag_queue { | 9 | struct 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); | |||
60 | void inet_frag_kill(struct inet_frag_queue *q, struct inet_frags *f); | 60 | void inet_frag_kill(struct inet_frag_queue *q, struct inet_frags *f); |
61 | void inet_frag_destroy(struct inet_frag_queue *q, | 61 | void inet_frag_destroy(struct inet_frag_queue *q, |
62 | struct inet_frags *f, int *work); | 62 | struct inet_frags *f, int *work); |
63 | int inet_frag_evictor(struct inet_frags *f); | 63 | int inet_frag_evictor(struct netns_frags *nf, struct inet_frags *f); |
64 | struct inet_frag_queue *inet_frag_find(struct netns_frags *nf, | 64 | struct 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 | ||
333 | int ip_defrag(struct sk_buff *skb, u32 user); | 333 | int ip_defrag(struct sk_buff *skb, u32 user); |
334 | int ip_frag_mem(void); | 334 | int ip_frag_mem(struct net *net); |
335 | int ip_frag_nqueues(struct net *net); | 335 | int 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, | |||
246 | extern int ipv6_opt_accepted(struct sock *sk, struct sk_buff *skb); | 246 | extern int ipv6_opt_accepted(struct sock *sk, struct sk_buff *skb); |
247 | 247 | ||
248 | int ip6_frag_nqueues(struct net *net); | 248 | int ip6_frag_nqueues(struct net *net); |
249 | int ip6_frag_mem(void); | 249 | int 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); | |||
75 | void inet_frags_init_net(struct netns_frags *nf) | 73 | void 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 | } |
79 | EXPORT_SYMBOL(inet_frags_init_net); | 78 | EXPORT_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 | ||
108 | EXPORT_SYMBOL(inet_frag_kill); | 107 | EXPORT_SYMBOL(inet_frag_kill); |
109 | 108 | ||
110 | static inline void frag_kfree_skb(struct inet_frags *f, struct sk_buff *skb, | 109 | static 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 | } |
148 | EXPORT_SYMBOL(inet_frag_destroy); | 149 | EXPORT_SYMBOL(inet_frag_destroy); |
149 | 150 | ||
150 | int inet_frag_evictor(struct inet_frags *f) | 151 | int 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 | ||
103 | int ip_frag_mem(void) | 103 | int 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 | ||
108 | static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev, | 108 | static 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. */ |
145 | static __inline__ void frag_kfree_skb(struct sk_buff *skb, int *work) | 145 | static __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 | */ |
195 | static void ip_evictor(void) | 196 | static 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 | ||
178 | static void nf_ct_frag6_evictor(void) | 178 | static 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 | ||
183 | static void nf_ct_frag6_expire(unsigned long data) | 183 | static 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 | ||
92 | int ip6_frag_mem(void) | 92 | int 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 | ||
97 | static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev, | 97 | static 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) | |||
149 | EXPORT_SYMBOL(ip6_frag_match); | 149 | EXPORT_SYMBOL(ip6_frag_match); |
150 | 150 | ||
151 | /* Memory Tracking Functions. */ | 151 | /* Memory Tracking Functions. */ |
152 | static inline void frag_kfree_skb(struct sk_buff *skb, int *work) | 152 | static 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 | ||
186 | static void ip6_evictor(struct inet6_dev *idev) | 187 | static 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) { |