diff options
author | Pavel Emelyanov <xemul@openvz.org> | 2008-01-22 09:02:14 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 18:10:34 -0500 |
commit | ac18e7509e7df327e30d6e073a787d922eaf211d (patch) | |
tree | 26be1582b59956c389a667d5426fdc538072795b /net/ipv4/inet_fragment.c | |
parent | 8d8354d2fb9277f165715a6e1cb92bcc89259975 (diff) |
[NETNS][FRAGS]: Make the inet_frag_queue lookup work in namespaces.
Since fragment management code is consolidated, we cannot have the
pointer from inet_frag_queue to struct net, since we must know what
king of fragment this is.
So, I introduce the netns_frags structure. This one is currently
empty, but will be eventually filled with per-namespace
attributes. Each inet_frag_queue is tagged with this one.
The conntrack_reasm is not "netns-izated", so it has one static
netns_frags instance to keep working in init namespace.
Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/inet_fragment.c')
-rw-r--r-- | net/ipv4/inet_fragment.c | 27 |
1 files changed, 15 insertions, 12 deletions
diff --git a/net/ipv4/inet_fragment.c b/net/ipv4/inet_fragment.c index 737910767ff1..158c5f60d023 100644 --- a/net/ipv4/inet_fragment.c +++ b/net/ipv4/inet_fragment.c | |||
@@ -174,8 +174,9 @@ int inet_frag_evictor(struct inet_frags *f) | |||
174 | } | 174 | } |
175 | EXPORT_SYMBOL(inet_frag_evictor); | 175 | EXPORT_SYMBOL(inet_frag_evictor); |
176 | 176 | ||
177 | static struct inet_frag_queue *inet_frag_intern(struct inet_frag_queue *qp_in, | 177 | static struct inet_frag_queue *inet_frag_intern(struct netns_frags *nf, |
178 | struct inet_frags *f, unsigned int hash, void *arg) | 178 | struct inet_frag_queue *qp_in, struct inet_frags *f, |
179 | unsigned int hash, void *arg) | ||
179 | { | 180 | { |
180 | struct inet_frag_queue *qp; | 181 | struct inet_frag_queue *qp; |
181 | #ifdef CONFIG_SMP | 182 | #ifdef CONFIG_SMP |
@@ -189,7 +190,7 @@ static struct inet_frag_queue *inet_frag_intern(struct inet_frag_queue *qp_in, | |||
189 | * promoted read lock to write lock. | 190 | * promoted read lock to write lock. |
190 | */ | 191 | */ |
191 | hlist_for_each_entry(qp, n, &f->hash[hash], list) { | 192 | hlist_for_each_entry(qp, n, &f->hash[hash], list) { |
192 | if (f->match(qp, arg)) { | 193 | if (qp->net == nf && f->match(qp, arg)) { |
193 | atomic_inc(&qp->refcnt); | 194 | atomic_inc(&qp->refcnt); |
194 | write_unlock(&f->lock); | 195 | write_unlock(&f->lock); |
195 | qp_in->last_in |= COMPLETE; | 196 | qp_in->last_in |= COMPLETE; |
@@ -210,7 +211,8 @@ static struct inet_frag_queue *inet_frag_intern(struct inet_frag_queue *qp_in, | |||
210 | return qp; | 211 | return qp; |
211 | } | 212 | } |
212 | 213 | ||
213 | static struct inet_frag_queue *inet_frag_alloc(struct inet_frags *f, void *arg) | 214 | static struct inet_frag_queue *inet_frag_alloc(struct netns_frags *nf, |
215 | struct inet_frags *f, void *arg) | ||
214 | { | 216 | { |
215 | struct inet_frag_queue *q; | 217 | struct inet_frag_queue *q; |
216 | 218 | ||
@@ -223,31 +225,32 @@ static struct inet_frag_queue *inet_frag_alloc(struct inet_frags *f, void *arg) | |||
223 | setup_timer(&q->timer, f->frag_expire, (unsigned long)q); | 225 | setup_timer(&q->timer, f->frag_expire, (unsigned long)q); |
224 | spin_lock_init(&q->lock); | 226 | spin_lock_init(&q->lock); |
225 | atomic_set(&q->refcnt, 1); | 227 | atomic_set(&q->refcnt, 1); |
228 | q->net = nf; | ||
226 | 229 | ||
227 | return q; | 230 | return q; |
228 | } | 231 | } |
229 | 232 | ||
230 | static struct inet_frag_queue *inet_frag_create(struct inet_frags *f, | 233 | static struct inet_frag_queue *inet_frag_create(struct netns_frags *nf, |
231 | void *arg, unsigned int hash) | 234 | struct inet_frags *f, void *arg, unsigned int hash) |
232 | { | 235 | { |
233 | struct inet_frag_queue *q; | 236 | struct inet_frag_queue *q; |
234 | 237 | ||
235 | q = inet_frag_alloc(f, arg); | 238 | q = inet_frag_alloc(nf, f, arg); |
236 | if (q == NULL) | 239 | if (q == NULL) |
237 | return NULL; | 240 | return NULL; |
238 | 241 | ||
239 | return inet_frag_intern(q, f, hash, arg); | 242 | return inet_frag_intern(nf, q, f, hash, arg); |
240 | } | 243 | } |
241 | 244 | ||
242 | struct inet_frag_queue *inet_frag_find(struct inet_frags *f, void *key, | 245 | struct inet_frag_queue *inet_frag_find(struct netns_frags *nf, |
243 | unsigned int hash) | 246 | struct inet_frags *f, void *key, unsigned int hash) |
244 | { | 247 | { |
245 | struct inet_frag_queue *q; | 248 | struct inet_frag_queue *q; |
246 | struct hlist_node *n; | 249 | struct hlist_node *n; |
247 | 250 | ||
248 | read_lock(&f->lock); | 251 | read_lock(&f->lock); |
249 | hlist_for_each_entry(q, n, &f->hash[hash], list) { | 252 | hlist_for_each_entry(q, n, &f->hash[hash], list) { |
250 | if (f->match(q, key)) { | 253 | if (q->net == nf && f->match(q, key)) { |
251 | atomic_inc(&q->refcnt); | 254 | atomic_inc(&q->refcnt); |
252 | read_unlock(&f->lock); | 255 | read_unlock(&f->lock); |
253 | return q; | 256 | return q; |
@@ -255,6 +258,6 @@ struct inet_frag_queue *inet_frag_find(struct inet_frags *f, void *key, | |||
255 | } | 258 | } |
256 | read_unlock(&f->lock); | 259 | read_unlock(&f->lock); |
257 | 260 | ||
258 | return inet_frag_create(f, key, hash); | 261 | return inet_frag_create(nf, f, key, hash); |
259 | } | 262 | } |
260 | EXPORT_SYMBOL(inet_frag_find); | 263 | EXPORT_SYMBOL(inet_frag_find); |