diff options
-rw-r--r-- | include/net/inet_frag.h | 2 | ||||
-rw-r--r-- | net/ipv4/inet_fragment.c | 17 | ||||
-rw-r--r-- | net/ipv4/ip_fragment.c | 20 | ||||
-rw-r--r-- | net/ipv6/netfilter/nf_conntrack_reasm.c | 19 | ||||
-rw-r--r-- | net/ipv6/reassembly.c | 19 |
5 files changed, 41 insertions, 36 deletions
diff --git a/include/net/inet_frag.h b/include/net/inet_frag.h index 133e187fbc98..412b8582a616 100644 --- a/include/net/inet_frag.h +++ b/include/net/inet_frag.h | |||
@@ -43,6 +43,7 @@ struct inet_frags { | |||
43 | void (*skb_free)(struct sk_buff *); | 43 | void (*skb_free)(struct sk_buff *); |
44 | int (*equal)(struct inet_frag_queue *q1, | 44 | int (*equal)(struct inet_frag_queue *q1, |
45 | struct inet_frag_queue *q2); | 45 | struct inet_frag_queue *q2); |
46 | void (*frag_expire)(unsigned long data); | ||
46 | }; | 47 | }; |
47 | 48 | ||
48 | void inet_frags_init(struct inet_frags *); | 49 | void inet_frags_init(struct inet_frags *); |
@@ -54,6 +55,7 @@ void inet_frag_destroy(struct inet_frag_queue *q, | |||
54 | int inet_frag_evictor(struct inet_frags *f); | 55 | int inet_frag_evictor(struct inet_frags *f); |
55 | struct inet_frag_queue *inet_frag_intern(struct inet_frag_queue *q, | 56 | struct inet_frag_queue *inet_frag_intern(struct inet_frag_queue *q, |
56 | struct inet_frags *f, unsigned int hash); | 57 | struct inet_frags *f, unsigned int hash); |
58 | struct inet_frag_queue *inet_frag_alloc(struct inet_frags *f); | ||
57 | 59 | ||
58 | static inline void inet_frag_put(struct inet_frag_queue *q, struct inet_frags *f) | 60 | static inline void inet_frag_put(struct inet_frag_queue *q, struct inet_frags *f) |
59 | { | 61 | { |
diff --git a/net/ipv4/inet_fragment.c b/net/ipv4/inet_fragment.c index 15054eb3d4b9..57e15fa307dc 100644 --- a/net/ipv4/inet_fragment.c +++ b/net/ipv4/inet_fragment.c | |||
@@ -209,3 +209,20 @@ struct inet_frag_queue *inet_frag_intern(struct inet_frag_queue *qp_in, | |||
209 | return qp; | 209 | return qp; |
210 | } | 210 | } |
211 | EXPORT_SYMBOL(inet_frag_intern); | 211 | EXPORT_SYMBOL(inet_frag_intern); |
212 | |||
213 | struct inet_frag_queue *inet_frag_alloc(struct inet_frags *f) | ||
214 | { | ||
215 | struct inet_frag_queue *q; | ||
216 | |||
217 | q = kzalloc(f->qsize, GFP_ATOMIC); | ||
218 | if (q == NULL) | ||
219 | return NULL; | ||
220 | |||
221 | atomic_add(f->qsize, &f->mem); | ||
222 | setup_timer(&q->timer, f->frag_expire, (unsigned long)q); | ||
223 | spin_lock_init(&q->lock); | ||
224 | atomic_set(&q->refcnt, 1); | ||
225 | |||
226 | return q; | ||
227 | } | ||
228 | EXPORT_SYMBOL(inet_frag_alloc); | ||
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index 4b1bbbee22c5..fc0d530df522 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c | |||
@@ -158,12 +158,10 @@ static __inline__ void ip4_frag_free(struct inet_frag_queue *q) | |||
158 | 158 | ||
159 | static __inline__ struct ipq *frag_alloc_queue(void) | 159 | static __inline__ struct ipq *frag_alloc_queue(void) |
160 | { | 160 | { |
161 | struct ipq *qp = kzalloc(sizeof(struct ipq), GFP_ATOMIC); | 161 | struct inet_frag_queue *q; |
162 | 162 | ||
163 | if (!qp) | 163 | q = inet_frag_alloc(&ip4_frags); |
164 | return NULL; | 164 | return q ? container_of(q, struct ipq, q) : NULL; |
165 | atomic_add(sizeof(struct ipq), &ip4_frags.mem); | ||
166 | return qp; | ||
167 | } | 165 | } |
168 | 166 | ||
169 | 167 | ||
@@ -199,7 +197,9 @@ static void ip_evictor(void) | |||
199 | */ | 197 | */ |
200 | static void ip_expire(unsigned long arg) | 198 | static void ip_expire(unsigned long arg) |
201 | { | 199 | { |
202 | struct ipq *qp = (struct ipq *) arg; | 200 | struct ipq *qp; |
201 | |||
202 | qp = container_of((struct inet_frag_queue *) arg, struct ipq, q); | ||
203 | 203 | ||
204 | spin_lock(&qp->q.lock); | 204 | spin_lock(&qp->q.lock); |
205 | 205 | ||
@@ -249,13 +249,6 @@ static struct ipq *ip_frag_create(struct iphdr *iph, u32 user, unsigned int h) | |||
249 | qp->user = user; | 249 | qp->user = user; |
250 | qp->peer = sysctl_ipfrag_max_dist ? inet_getpeer(iph->saddr, 1) : NULL; | 250 | qp->peer = sysctl_ipfrag_max_dist ? inet_getpeer(iph->saddr, 1) : NULL; |
251 | 251 | ||
252 | /* Initialize a timer for this entry. */ | ||
253 | init_timer(&qp->q.timer); | ||
254 | qp->q.timer.data = (unsigned long) qp; /* pointer to queue */ | ||
255 | qp->q.timer.function = ip_expire; /* expire function */ | ||
256 | spin_lock_init(&qp->q.lock); | ||
257 | atomic_set(&qp->q.refcnt, 1); | ||
258 | |||
259 | return ip_frag_intern(qp, h); | 252 | return ip_frag_intern(qp, h); |
260 | 253 | ||
261 | out_nomem: | 254 | out_nomem: |
@@ -653,6 +646,7 @@ void __init ipfrag_init(void) | |||
653 | ip4_frags.skb_free = NULL; | 646 | ip4_frags.skb_free = NULL; |
654 | ip4_frags.qsize = sizeof(struct ipq); | 647 | ip4_frags.qsize = sizeof(struct ipq); |
655 | ip4_frags.equal = ip4_frag_equal; | 648 | ip4_frags.equal = ip4_frag_equal; |
649 | ip4_frags.frag_expire = ip_expire; | ||
656 | inet_frags_init(&ip4_frags); | 650 | inet_frags_init(&ip4_frags); |
657 | } | 651 | } |
658 | 652 | ||
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c index d7dc444ec48f..3f8c16b3301e 100644 --- a/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/net/ipv6/netfilter/nf_conntrack_reasm.c | |||
@@ -137,13 +137,10 @@ static void nf_frag_free(struct inet_frag_queue *q) | |||
137 | 137 | ||
138 | static inline struct nf_ct_frag6_queue *frag_alloc_queue(void) | 138 | static inline struct nf_ct_frag6_queue *frag_alloc_queue(void) |
139 | { | 139 | { |
140 | struct nf_ct_frag6_queue *fq; | 140 | struct inet_frag_queue *q; |
141 | 141 | ||
142 | fq = kzalloc(sizeof(struct nf_ct_frag6_queue), GFP_ATOMIC); | 142 | q = inet_frag_alloc(&nf_frags); |
143 | if (fq == NULL) | 143 | return q ? container_of(q, struct nf_ct_frag6_queue, q) : NULL; |
144 | return NULL; | ||
145 | atomic_add(sizeof(struct nf_ct_frag6_queue), &nf_frags.mem); | ||
146 | return fq; | ||
147 | } | 144 | } |
148 | 145 | ||
149 | /* Destruction primitives. */ | 146 | /* Destruction primitives. */ |
@@ -168,7 +165,10 @@ static void nf_ct_frag6_evictor(void) | |||
168 | 165 | ||
169 | static void nf_ct_frag6_expire(unsigned long data) | 166 | static void nf_ct_frag6_expire(unsigned long data) |
170 | { | 167 | { |
171 | struct nf_ct_frag6_queue *fq = (struct nf_ct_frag6_queue *) data; | 168 | struct nf_ct_frag6_queue *fq; |
169 | |||
170 | fq = container_of((struct inet_frag_queue *)data, | ||
171 | struct nf_ct_frag6_queue, q); | ||
172 | 172 | ||
173 | spin_lock(&fq->q.lock); | 173 | spin_lock(&fq->q.lock); |
174 | 174 | ||
@@ -208,10 +208,6 @@ nf_ct_frag6_create(unsigned int hash, __be32 id, struct in6_addr *src, str | |||
208 | ipv6_addr_copy(&fq->saddr, src); | 208 | ipv6_addr_copy(&fq->saddr, src); |
209 | ipv6_addr_copy(&fq->daddr, dst); | 209 | ipv6_addr_copy(&fq->daddr, dst); |
210 | 210 | ||
211 | setup_timer(&fq->q.timer, nf_ct_frag6_expire, (unsigned long)fq); | ||
212 | spin_lock_init(&fq->q.lock); | ||
213 | atomic_set(&fq->q.refcnt, 1); | ||
214 | |||
215 | return nf_ct_frag6_intern(hash, fq); | 211 | return nf_ct_frag6_intern(hash, fq); |
216 | 212 | ||
217 | oom: | 213 | oom: |
@@ -726,6 +722,7 @@ int nf_ct_frag6_init(void) | |||
726 | nf_frags.skb_free = nf_skb_free; | 722 | nf_frags.skb_free = nf_skb_free; |
727 | nf_frags.qsize = sizeof(struct nf_ct_frag6_queue); | 723 | nf_frags.qsize = sizeof(struct nf_ct_frag6_queue); |
728 | nf_frags.equal = ip6_frag_equal; | 724 | nf_frags.equal = ip6_frag_equal; |
725 | nf_frags.frag_expire = nf_ct_frag6_expire; | ||
729 | inet_frags_init(&nf_frags); | 726 | inet_frags_init(&nf_frags); |
730 | 727 | ||
731 | return 0; | 728 | return 0; |
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c index 73ea204eaa6f..21913c78f053 100644 --- a/net/ipv6/reassembly.c +++ b/net/ipv6/reassembly.c | |||
@@ -171,12 +171,10 @@ static void ip6_frag_free(struct inet_frag_queue *fq) | |||
171 | 171 | ||
172 | static inline struct frag_queue *frag_alloc_queue(void) | 172 | static inline struct frag_queue *frag_alloc_queue(void) |
173 | { | 173 | { |
174 | struct frag_queue *fq = kzalloc(sizeof(struct frag_queue), GFP_ATOMIC); | 174 | struct inet_frag_queue *q; |
175 | 175 | ||
176 | if(!fq) | 176 | q = inet_frag_alloc(&ip6_frags); |
177 | return NULL; | 177 | return q ? container_of(q, struct frag_queue, q) : NULL; |
178 | atomic_add(sizeof(struct frag_queue), &ip6_frags.mem); | ||
179 | return fq; | ||
180 | } | 178 | } |
181 | 179 | ||
182 | /* Destruction primitives. */ | 180 | /* Destruction primitives. */ |
@@ -205,9 +203,11 @@ static void ip6_evictor(struct inet6_dev *idev) | |||
205 | 203 | ||
206 | static void ip6_frag_expire(unsigned long data) | 204 | static void ip6_frag_expire(unsigned long data) |
207 | { | 205 | { |
208 | struct frag_queue *fq = (struct frag_queue *) data; | 206 | struct frag_queue *fq; |
209 | struct net_device *dev = NULL; | 207 | struct net_device *dev = NULL; |
210 | 208 | ||
209 | fq = container_of((struct inet_frag_queue *)data, struct frag_queue, q); | ||
210 | |||
211 | spin_lock(&fq->q.lock); | 211 | spin_lock(&fq->q.lock); |
212 | 212 | ||
213 | if (fq->q.last_in & COMPLETE) | 213 | if (fq->q.last_in & COMPLETE) |
@@ -268,12 +268,6 @@ ip6_frag_create(__be32 id, struct in6_addr *src, struct in6_addr *dst, | |||
268 | ipv6_addr_copy(&fq->saddr, src); | 268 | ipv6_addr_copy(&fq->saddr, src); |
269 | ipv6_addr_copy(&fq->daddr, dst); | 269 | ipv6_addr_copy(&fq->daddr, dst); |
270 | 270 | ||
271 | init_timer(&fq->q.timer); | ||
272 | fq->q.timer.function = ip6_frag_expire; | ||
273 | fq->q.timer.data = (long) fq; | ||
274 | spin_lock_init(&fq->q.lock); | ||
275 | atomic_set(&fq->q.refcnt, 1); | ||
276 | |||
277 | return ip6_frag_intern(fq, hash); | 271 | return ip6_frag_intern(fq, hash); |
278 | 272 | ||
279 | oom: | 273 | oom: |
@@ -685,5 +679,6 @@ void __init ipv6_frag_init(void) | |||
685 | ip6_frags.skb_free = NULL; | 679 | ip6_frags.skb_free = NULL; |
686 | ip6_frags.qsize = sizeof(struct frag_queue); | 680 | ip6_frags.qsize = sizeof(struct frag_queue); |
687 | ip6_frags.equal = ip6_frag_equal; | 681 | ip6_frags.equal = ip6_frag_equal; |
682 | ip6_frags.frag_expire = ip6_frag_expire; | ||
688 | inet_frags_init(&ip6_frags); | 683 | inet_frags_init(&ip6_frags); |
689 | } | 684 | } |