diff options
Diffstat (limited to 'drivers/net/pppoe.c')
-rw-r--r-- | drivers/net/pppoe.c | 377 |
1 files changed, 244 insertions, 133 deletions
diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c index c2ceea4f46ba..fb3056334aac 100644 --- a/drivers/net/pppoe.c +++ b/drivers/net/pppoe.c | |||
@@ -78,7 +78,9 @@ | |||
78 | #include <linux/proc_fs.h> | 78 | #include <linux/proc_fs.h> |
79 | #include <linux/seq_file.h> | 79 | #include <linux/seq_file.h> |
80 | 80 | ||
81 | #include <linux/nsproxy.h> | ||
81 | #include <net/net_namespace.h> | 82 | #include <net/net_namespace.h> |
83 | #include <net/netns/generic.h> | ||
82 | #include <net/sock.h> | 84 | #include <net/sock.h> |
83 | 85 | ||
84 | #include <asm/uaccess.h> | 86 | #include <asm/uaccess.h> |
@@ -93,7 +95,24 @@ static int __pppoe_xmit(struct sock *sk, struct sk_buff *skb); | |||
93 | 95 | ||
94 | static const struct proto_ops pppoe_ops; | 96 | static const struct proto_ops pppoe_ops; |
95 | static struct ppp_channel_ops pppoe_chan_ops; | 97 | static struct ppp_channel_ops pppoe_chan_ops; |
96 | static DEFINE_RWLOCK(pppoe_hash_lock); | 98 | |
99 | /* per-net private data for this module */ | ||
100 | static unsigned int pppoe_net_id; | ||
101 | struct pppoe_net { | ||
102 | /* | ||
103 | * we could use _single_ hash table for all | ||
104 | * nets by injecting net id into the hash but | ||
105 | * it would increase hash chains and add | ||
106 | * a few additional math comparations messy | ||
107 | * as well, moreover in case of SMP less locking | ||
108 | * controversy here | ||
109 | */ | ||
110 | struct pppox_sock *hash_table[PPPOE_HASH_SIZE]; | ||
111 | rwlock_t hash_lock; | ||
112 | }; | ||
113 | |||
114 | /* to eliminate a race btw pppoe_flush_dev and pppoe_release */ | ||
115 | static DEFINE_SPINLOCK(flush_lock); | ||
97 | 116 | ||
98 | /* | 117 | /* |
99 | * PPPoE could be in the following stages: | 118 | * PPPoE could be in the following stages: |
@@ -108,16 +127,21 @@ static inline bool stage_session(__be16 sid) | |||
108 | return sid != 0; | 127 | return sid != 0; |
109 | } | 128 | } |
110 | 129 | ||
130 | static inline struct pppoe_net *pppoe_pernet(struct net *net) | ||
131 | { | ||
132 | BUG_ON(!net); | ||
133 | |||
134 | return net_generic(net, pppoe_net_id); | ||
135 | } | ||
136 | |||
111 | static inline int cmp_2_addr(struct pppoe_addr *a, struct pppoe_addr *b) | 137 | static inline int cmp_2_addr(struct pppoe_addr *a, struct pppoe_addr *b) |
112 | { | 138 | { |
113 | return a->sid == b->sid && | 139 | return a->sid == b->sid && !memcmp(a->remote, b->remote, ETH_ALEN); |
114 | (memcmp(a->remote, b->remote, ETH_ALEN) == 0); | ||
115 | } | 140 | } |
116 | 141 | ||
117 | static inline int cmp_addr(struct pppoe_addr *a, __be16 sid, char *addr) | 142 | static inline int cmp_addr(struct pppoe_addr *a, __be16 sid, char *addr) |
118 | { | 143 | { |
119 | return a->sid == sid && | 144 | return a->sid == sid && !memcmp(a->remote, addr, ETH_ALEN); |
120 | (memcmp(a->remote, addr, ETH_ALEN) == 0); | ||
121 | } | 145 | } |
122 | 146 | ||
123 | #if 8 % PPPOE_HASH_BITS | 147 | #if 8 % PPPOE_HASH_BITS |
@@ -139,21 +163,18 @@ static int hash_item(__be16 sid, unsigned char *addr) | |||
139 | return hash & PPPOE_HASH_MASK; | 163 | return hash & PPPOE_HASH_MASK; |
140 | } | 164 | } |
141 | 165 | ||
142 | /* zeroed because its in .bss */ | ||
143 | static struct pppox_sock *item_hash_table[PPPOE_HASH_SIZE]; | ||
144 | |||
145 | /********************************************************************** | 166 | /********************************************************************** |
146 | * | 167 | * |
147 | * Set/get/delete/rehash items (internal versions) | 168 | * Set/get/delete/rehash items (internal versions) |
148 | * | 169 | * |
149 | **********************************************************************/ | 170 | **********************************************************************/ |
150 | static struct pppox_sock *__get_item(__be16 sid, unsigned char *addr, int ifindex) | 171 | static struct pppox_sock *__get_item(struct pppoe_net *pn, __be16 sid, |
172 | unsigned char *addr, int ifindex) | ||
151 | { | 173 | { |
152 | int hash = hash_item(sid, addr); | 174 | int hash = hash_item(sid, addr); |
153 | struct pppox_sock *ret; | 175 | struct pppox_sock *ret; |
154 | 176 | ||
155 | ret = item_hash_table[hash]; | 177 | ret = pn->hash_table[hash]; |
156 | |||
157 | while (ret) { | 178 | while (ret) { |
158 | if (cmp_addr(&ret->pppoe_pa, sid, addr) && | 179 | if (cmp_addr(&ret->pppoe_pa, sid, addr) && |
159 | ret->pppoe_ifindex == ifindex) | 180 | ret->pppoe_ifindex == ifindex) |
@@ -165,12 +186,12 @@ static struct pppox_sock *__get_item(__be16 sid, unsigned char *addr, int ifinde | |||
165 | return NULL; | 186 | return NULL; |
166 | } | 187 | } |
167 | 188 | ||
168 | static int __set_item(struct pppox_sock *po) | 189 | static int __set_item(struct pppoe_net *pn, struct pppox_sock *po) |
169 | { | 190 | { |
170 | int hash = hash_item(po->pppoe_pa.sid, po->pppoe_pa.remote); | 191 | int hash = hash_item(po->pppoe_pa.sid, po->pppoe_pa.remote); |
171 | struct pppox_sock *ret; | 192 | struct pppox_sock *ret; |
172 | 193 | ||
173 | ret = item_hash_table[hash]; | 194 | ret = pn->hash_table[hash]; |
174 | while (ret) { | 195 | while (ret) { |
175 | if (cmp_2_addr(&ret->pppoe_pa, &po->pppoe_pa) && | 196 | if (cmp_2_addr(&ret->pppoe_pa, &po->pppoe_pa) && |
176 | ret->pppoe_ifindex == po->pppoe_ifindex) | 197 | ret->pppoe_ifindex == po->pppoe_ifindex) |
@@ -179,19 +200,20 @@ static int __set_item(struct pppox_sock *po) | |||
179 | ret = ret->next; | 200 | ret = ret->next; |
180 | } | 201 | } |
181 | 202 | ||
182 | po->next = item_hash_table[hash]; | 203 | po->next = pn->hash_table[hash]; |
183 | item_hash_table[hash] = po; | 204 | pn->hash_table[hash] = po; |
184 | 205 | ||
185 | return 0; | 206 | return 0; |
186 | } | 207 | } |
187 | 208 | ||
188 | static struct pppox_sock *__delete_item(__be16 sid, char *addr, int ifindex) | 209 | static struct pppox_sock *__delete_item(struct pppoe_net *pn, __be16 sid, |
210 | char *addr, int ifindex) | ||
189 | { | 211 | { |
190 | int hash = hash_item(sid, addr); | 212 | int hash = hash_item(sid, addr); |
191 | struct pppox_sock *ret, **src; | 213 | struct pppox_sock *ret, **src; |
192 | 214 | ||
193 | ret = item_hash_table[hash]; | 215 | ret = pn->hash_table[hash]; |
194 | src = &item_hash_table[hash]; | 216 | src = &pn->hash_table[hash]; |
195 | 217 | ||
196 | while (ret) { | 218 | while (ret) { |
197 | if (cmp_addr(&ret->pppoe_pa, sid, addr) && | 219 | if (cmp_addr(&ret->pppoe_pa, sid, addr) && |
@@ -212,46 +234,54 @@ static struct pppox_sock *__delete_item(__be16 sid, char *addr, int ifindex) | |||
212 | * Set/get/delete/rehash items | 234 | * Set/get/delete/rehash items |
213 | * | 235 | * |
214 | **********************************************************************/ | 236 | **********************************************************************/ |
215 | static inline struct pppox_sock *get_item(__be16 sid, | 237 | static inline struct pppox_sock *get_item(struct pppoe_net *pn, __be16 sid, |
216 | unsigned char *addr, int ifindex) | 238 | unsigned char *addr, int ifindex) |
217 | { | 239 | { |
218 | struct pppox_sock *po; | 240 | struct pppox_sock *po; |
219 | 241 | ||
220 | read_lock_bh(&pppoe_hash_lock); | 242 | read_lock_bh(&pn->hash_lock); |
221 | po = __get_item(sid, addr, ifindex); | 243 | po = __get_item(pn, sid, addr, ifindex); |
222 | if (po) | 244 | if (po) |
223 | sock_hold(sk_pppox(po)); | 245 | sock_hold(sk_pppox(po)); |
224 | read_unlock_bh(&pppoe_hash_lock); | 246 | read_unlock_bh(&pn->hash_lock); |
225 | 247 | ||
226 | return po; | 248 | return po; |
227 | } | 249 | } |
228 | 250 | ||
229 | static inline struct pppox_sock *get_item_by_addr(struct sockaddr_pppox *sp) | 251 | static inline struct pppox_sock *get_item_by_addr(struct net *net, |
252 | struct sockaddr_pppox *sp) | ||
230 | { | 253 | { |
231 | struct net_device *dev; | 254 | struct net_device *dev; |
255 | struct pppoe_net *pn; | ||
256 | struct pppox_sock *pppox_sock; | ||
257 | |||
232 | int ifindex; | 258 | int ifindex; |
233 | 259 | ||
234 | dev = dev_get_by_name(&init_net, sp->sa_addr.pppoe.dev); | 260 | dev = dev_get_by_name(net, sp->sa_addr.pppoe.dev); |
235 | if (!dev) | 261 | if (!dev) |
236 | return NULL; | 262 | return NULL; |
263 | |||
237 | ifindex = dev->ifindex; | 264 | ifindex = dev->ifindex; |
265 | pn = net_generic(net, pppoe_net_id); | ||
266 | pppox_sock = get_item(pn, sp->sa_addr.pppoe.sid, | ||
267 | sp->sa_addr.pppoe.remote, ifindex); | ||
238 | dev_put(dev); | 268 | dev_put(dev); |
239 | return get_item(sp->sa_addr.pppoe.sid, sp->sa_addr.pppoe.remote, ifindex); | 269 | |
270 | return pppox_sock; | ||
240 | } | 271 | } |
241 | 272 | ||
242 | static inline struct pppox_sock *delete_item(__be16 sid, char *addr, int ifindex) | 273 | static inline struct pppox_sock *delete_item(struct pppoe_net *pn, __be16 sid, |
274 | char *addr, int ifindex) | ||
243 | { | 275 | { |
244 | struct pppox_sock *ret; | 276 | struct pppox_sock *ret; |
245 | 277 | ||
246 | write_lock_bh(&pppoe_hash_lock); | 278 | write_lock_bh(&pn->hash_lock); |
247 | ret = __delete_item(sid, addr, ifindex); | 279 | ret = __delete_item(pn, sid, addr, ifindex); |
248 | write_unlock_bh(&pppoe_hash_lock); | 280 | write_unlock_bh(&pn->hash_lock); |
249 | 281 | ||
250 | return ret; | 282 | return ret; |
251 | } | 283 | } |
252 | 284 | ||
253 | |||
254 | |||
255 | /*************************************************************************** | 285 | /*************************************************************************** |
256 | * | 286 | * |
257 | * Handler for device events. | 287 | * Handler for device events. |
@@ -261,25 +291,33 @@ static inline struct pppox_sock *delete_item(__be16 sid, char *addr, int ifindex | |||
261 | 291 | ||
262 | static void pppoe_flush_dev(struct net_device *dev) | 292 | static void pppoe_flush_dev(struct net_device *dev) |
263 | { | 293 | { |
264 | int hash; | 294 | struct pppoe_net *pn; |
295 | int i; | ||
296 | |||
265 | BUG_ON(dev == NULL); | 297 | BUG_ON(dev == NULL); |
266 | 298 | ||
267 | write_lock_bh(&pppoe_hash_lock); | 299 | pn = pppoe_pernet(dev_net(dev)); |
268 | for (hash = 0; hash < PPPOE_HASH_SIZE; hash++) { | 300 | if (!pn) /* already freed */ |
269 | struct pppox_sock *po = item_hash_table[hash]; | 301 | return; |
302 | |||
303 | write_lock_bh(&pn->hash_lock); | ||
304 | for (i = 0; i < PPPOE_HASH_SIZE; i++) { | ||
305 | struct pppox_sock *po = pn->hash_table[i]; | ||
270 | 306 | ||
271 | while (po != NULL) { | 307 | while (po != NULL) { |
272 | struct sock *sk = sk_pppox(po); | 308 | struct sock *sk; |
273 | if (po->pppoe_dev != dev) { | 309 | if (po->pppoe_dev != dev) { |
274 | po = po->next; | 310 | po = po->next; |
275 | continue; | 311 | continue; |
276 | } | 312 | } |
313 | sk = sk_pppox(po); | ||
314 | spin_lock(&flush_lock); | ||
277 | po->pppoe_dev = NULL; | 315 | po->pppoe_dev = NULL; |
316 | spin_unlock(&flush_lock); | ||
278 | dev_put(dev); | 317 | dev_put(dev); |
279 | 318 | ||
280 | |||
281 | /* We always grab the socket lock, followed by the | 319 | /* We always grab the socket lock, followed by the |
282 | * pppoe_hash_lock, in that order. Since we should | 320 | * hash_lock, in that order. Since we should |
283 | * hold the sock lock while doing any unbinding, | 321 | * hold the sock lock while doing any unbinding, |
284 | * we need to release the lock we're holding. | 322 | * we need to release the lock we're holding. |
285 | * Hold a reference to the sock so it doesn't disappear | 323 | * Hold a reference to the sock so it doesn't disappear |
@@ -288,7 +326,7 @@ static void pppoe_flush_dev(struct net_device *dev) | |||
288 | 326 | ||
289 | sock_hold(sk); | 327 | sock_hold(sk); |
290 | 328 | ||
291 | write_unlock_bh(&pppoe_hash_lock); | 329 | write_unlock_bh(&pn->hash_lock); |
292 | lock_sock(sk); | 330 | lock_sock(sk); |
293 | 331 | ||
294 | if (sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND)) { | 332 | if (sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND)) { |
@@ -304,20 +342,17 @@ static void pppoe_flush_dev(struct net_device *dev) | |||
304 | * While the lock was dropped the chain contents may | 342 | * While the lock was dropped the chain contents may |
305 | * have changed. | 343 | * have changed. |
306 | */ | 344 | */ |
307 | write_lock_bh(&pppoe_hash_lock); | 345 | write_lock_bh(&pn->hash_lock); |
308 | po = item_hash_table[hash]; | 346 | po = pn->hash_table[i]; |
309 | } | 347 | } |
310 | } | 348 | } |
311 | write_unlock_bh(&pppoe_hash_lock); | 349 | write_unlock_bh(&pn->hash_lock); |
312 | } | 350 | } |
313 | 351 | ||
314 | static int pppoe_device_event(struct notifier_block *this, | 352 | static int pppoe_device_event(struct notifier_block *this, |
315 | unsigned long event, void *ptr) | 353 | unsigned long event, void *ptr) |
316 | { | 354 | { |
317 | struct net_device *dev = (struct net_device *) ptr; | 355 | struct net_device *dev = (struct net_device *)ptr; |
318 | |||
319 | if (dev_net(dev) != &init_net) | ||
320 | return NOTIFY_DONE; | ||
321 | 356 | ||
322 | /* Only look at sockets that are using this specific device. */ | 357 | /* Only look at sockets that are using this specific device. */ |
323 | switch (event) { | 358 | switch (event) { |
@@ -339,7 +374,6 @@ static int pppoe_device_event(struct notifier_block *this, | |||
339 | return NOTIFY_DONE; | 374 | return NOTIFY_DONE; |
340 | } | 375 | } |
341 | 376 | ||
342 | |||
343 | static struct notifier_block pppoe_notifier = { | 377 | static struct notifier_block pppoe_notifier = { |
344 | .notifier_call = pppoe_device_event, | 378 | .notifier_call = pppoe_device_event, |
345 | }; | 379 | }; |
@@ -357,8 +391,8 @@ static int pppoe_rcv_core(struct sock *sk, struct sk_buff *skb) | |||
357 | if (sk->sk_state & PPPOX_BOUND) { | 391 | if (sk->sk_state & PPPOX_BOUND) { |
358 | ppp_input(&po->chan, skb); | 392 | ppp_input(&po->chan, skb); |
359 | } else if (sk->sk_state & PPPOX_RELAY) { | 393 | } else if (sk->sk_state & PPPOX_RELAY) { |
360 | relay_po = get_item_by_addr(&po->pppoe_relay); | 394 | relay_po = get_item_by_addr(dev_net(po->pppoe_dev), |
361 | 395 | &po->pppoe_relay); | |
362 | if (relay_po == NULL) | 396 | if (relay_po == NULL) |
363 | goto abort_kfree; | 397 | goto abort_kfree; |
364 | 398 | ||
@@ -387,23 +421,18 @@ abort_kfree: | |||
387 | * Receive wrapper called in BH context. | 421 | * Receive wrapper called in BH context. |
388 | * | 422 | * |
389 | ***********************************************************************/ | 423 | ***********************************************************************/ |
390 | static int pppoe_rcv(struct sk_buff *skb, | 424 | static int pppoe_rcv(struct sk_buff *skb, struct net_device *dev, |
391 | struct net_device *dev, | 425 | struct packet_type *pt, struct net_device *orig_dev) |
392 | struct packet_type *pt, | ||
393 | struct net_device *orig_dev) | ||
394 | |||
395 | { | 426 | { |
396 | struct pppoe_hdr *ph; | 427 | struct pppoe_hdr *ph; |
397 | struct pppox_sock *po; | 428 | struct pppox_sock *po; |
429 | struct pppoe_net *pn; | ||
398 | int len; | 430 | int len; |
399 | 431 | ||
400 | skb = skb_share_check(skb, GFP_ATOMIC); | 432 | skb = skb_share_check(skb, GFP_ATOMIC); |
401 | if (!skb) | 433 | if (!skb) |
402 | goto out; | 434 | goto out; |
403 | 435 | ||
404 | if (dev_net(dev) != &init_net) | ||
405 | goto drop; | ||
406 | |||
407 | if (!pskb_may_pull(skb, sizeof(struct pppoe_hdr))) | 436 | if (!pskb_may_pull(skb, sizeof(struct pppoe_hdr))) |
408 | goto drop; | 437 | goto drop; |
409 | 438 | ||
@@ -417,7 +446,8 @@ static int pppoe_rcv(struct sk_buff *skb, | |||
417 | if (pskb_trim_rcsum(skb, len)) | 446 | if (pskb_trim_rcsum(skb, len)) |
418 | goto drop; | 447 | goto drop; |
419 | 448 | ||
420 | po = get_item(ph->sid, eth_hdr(skb)->h_source, dev->ifindex); | 449 | pn = pppoe_pernet(dev_net(dev)); |
450 | po = get_item(pn, ph->sid, eth_hdr(skb)->h_source, dev->ifindex); | ||
421 | if (!po) | 451 | if (!po) |
422 | goto drop; | 452 | goto drop; |
423 | 453 | ||
@@ -435,17 +465,13 @@ out: | |||
435 | * This is solely for detection of PADT frames | 465 | * This is solely for detection of PADT frames |
436 | * | 466 | * |
437 | ***********************************************************************/ | 467 | ***********************************************************************/ |
438 | static int pppoe_disc_rcv(struct sk_buff *skb, | 468 | static int pppoe_disc_rcv(struct sk_buff *skb, struct net_device *dev, |
439 | struct net_device *dev, | 469 | struct packet_type *pt, struct net_device *orig_dev) |
440 | struct packet_type *pt, | ||
441 | struct net_device *orig_dev) | ||
442 | 470 | ||
443 | { | 471 | { |
444 | struct pppoe_hdr *ph; | 472 | struct pppoe_hdr *ph; |
445 | struct pppox_sock *po; | 473 | struct pppox_sock *po; |
446 | 474 | struct pppoe_net *pn; | |
447 | if (dev_net(dev) != &init_net) | ||
448 | goto abort; | ||
449 | 475 | ||
450 | skb = skb_share_check(skb, GFP_ATOMIC); | 476 | skb = skb_share_check(skb, GFP_ATOMIC); |
451 | if (!skb) | 477 | if (!skb) |
@@ -458,7 +484,8 @@ static int pppoe_disc_rcv(struct sk_buff *skb, | |||
458 | if (ph->code != PADT_CODE) | 484 | if (ph->code != PADT_CODE) |
459 | goto abort; | 485 | goto abort; |
460 | 486 | ||
461 | po = get_item(ph->sid, eth_hdr(skb)->h_source, dev->ifindex); | 487 | pn = pppoe_pernet(dev_net(dev)); |
488 | po = get_item(pn, ph->sid, eth_hdr(skb)->h_source, dev->ifindex); | ||
462 | if (po) { | 489 | if (po) { |
463 | struct sock *sk = sk_pppox(po); | 490 | struct sock *sk = sk_pppox(po); |
464 | 491 | ||
@@ -517,14 +544,14 @@ static int pppoe_create(struct net *net, struct socket *sock) | |||
517 | 544 | ||
518 | sock_init_data(sock, sk); | 545 | sock_init_data(sock, sk); |
519 | 546 | ||
520 | sock->state = SS_UNCONNECTED; | 547 | sock->state = SS_UNCONNECTED; |
521 | sock->ops = &pppoe_ops; | 548 | sock->ops = &pppoe_ops; |
522 | 549 | ||
523 | sk->sk_backlog_rcv = pppoe_rcv_core; | 550 | sk->sk_backlog_rcv = pppoe_rcv_core; |
524 | sk->sk_state = PPPOX_NONE; | 551 | sk->sk_state = PPPOX_NONE; |
525 | sk->sk_type = SOCK_STREAM; | 552 | sk->sk_type = SOCK_STREAM; |
526 | sk->sk_family = PF_PPPOX; | 553 | sk->sk_family = PF_PPPOX; |
527 | sk->sk_protocol = PX_PROTO_OE; | 554 | sk->sk_protocol = PX_PROTO_OE; |
528 | 555 | ||
529 | return 0; | 556 | return 0; |
530 | } | 557 | } |
@@ -533,6 +560,7 @@ static int pppoe_release(struct socket *sock) | |||
533 | { | 560 | { |
534 | struct sock *sk = sock->sk; | 561 | struct sock *sk = sock->sk; |
535 | struct pppox_sock *po; | 562 | struct pppox_sock *po; |
563 | struct pppoe_net *pn; | ||
536 | 564 | ||
537 | if (!sk) | 565 | if (!sk) |
538 | return 0; | 566 | return 0; |
@@ -548,26 +576,39 @@ static int pppoe_release(struct socket *sock) | |||
548 | /* Signal the death of the socket. */ | 576 | /* Signal the death of the socket. */ |
549 | sk->sk_state = PPPOX_DEAD; | 577 | sk->sk_state = PPPOX_DEAD; |
550 | 578 | ||
579 | /* | ||
580 | * pppoe_flush_dev could lead to a race with | ||
581 | * this routine so we use flush_lock to eliminate | ||
582 | * such a case (we only need per-net specific data) | ||
583 | */ | ||
584 | spin_lock(&flush_lock); | ||
585 | po = pppox_sk(sk); | ||
586 | if (!po->pppoe_dev) { | ||
587 | spin_unlock(&flush_lock); | ||
588 | goto out; | ||
589 | } | ||
590 | pn = pppoe_pernet(dev_net(po->pppoe_dev)); | ||
591 | spin_unlock(&flush_lock); | ||
551 | 592 | ||
552 | /* Write lock on hash lock protects the entire "po" struct from | 593 | /* |
553 | * concurrent updates via pppoe_flush_dev. The "po" struct should | 594 | * protect "po" from concurrent updates |
554 | * be considered part of the hash table contents, thus protected | 595 | * on pppoe_flush_dev |
555 | * by the hash table lock */ | 596 | */ |
556 | write_lock_bh(&pppoe_hash_lock); | 597 | write_lock_bh(&pn->hash_lock); |
557 | 598 | ||
558 | po = pppox_sk(sk); | 599 | po = pppox_sk(sk); |
559 | if (stage_session(po->pppoe_pa.sid)) { | 600 | if (stage_session(po->pppoe_pa.sid)) |
560 | __delete_item(po->pppoe_pa.sid, | 601 | __delete_item(pn, po->pppoe_pa.sid, po->pppoe_pa.remote, |
561 | po->pppoe_pa.remote, po->pppoe_ifindex); | 602 | po->pppoe_ifindex); |
562 | } | ||
563 | 603 | ||
564 | if (po->pppoe_dev) { | 604 | if (po->pppoe_dev) { |
565 | dev_put(po->pppoe_dev); | 605 | dev_put(po->pppoe_dev); |
566 | po->pppoe_dev = NULL; | 606 | po->pppoe_dev = NULL; |
567 | } | 607 | } |
568 | 608 | ||
569 | write_unlock_bh(&pppoe_hash_lock); | 609 | write_unlock_bh(&pn->hash_lock); |
570 | 610 | ||
611 | out: | ||
571 | sock_orphan(sk); | 612 | sock_orphan(sk); |
572 | sock->sk = NULL; | 613 | sock->sk = NULL; |
573 | 614 | ||
@@ -582,9 +623,10 @@ static int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr, | |||
582 | int sockaddr_len, int flags) | 623 | int sockaddr_len, int flags) |
583 | { | 624 | { |
584 | struct sock *sk = sock->sk; | 625 | struct sock *sk = sock->sk; |
585 | struct net_device *dev; | 626 | struct sockaddr_pppox *sp = (struct sockaddr_pppox *)uservaddr; |
586 | struct sockaddr_pppox *sp = (struct sockaddr_pppox *) uservaddr; | ||
587 | struct pppox_sock *po = pppox_sk(sk); | 627 | struct pppox_sock *po = pppox_sk(sk); |
628 | struct net_device *dev; | ||
629 | struct pppoe_net *pn; | ||
588 | int error; | 630 | int error; |
589 | 631 | ||
590 | lock_sock(sk); | 632 | lock_sock(sk); |
@@ -610,9 +652,12 @@ static int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr, | |||
610 | /* Delete the old binding */ | 652 | /* Delete the old binding */ |
611 | if (stage_session(po->pppoe_pa.sid)) { | 653 | if (stage_session(po->pppoe_pa.sid)) { |
612 | pppox_unbind_sock(sk); | 654 | pppox_unbind_sock(sk); |
613 | delete_item(po->pppoe_pa.sid, po->pppoe_pa.remote, po->pppoe_ifindex); | 655 | if (po->pppoe_dev) { |
614 | if (po->pppoe_dev) | 656 | pn = pppoe_pernet(dev_net(po->pppoe_dev)); |
657 | delete_item(pn, po->pppoe_pa.sid, | ||
658 | po->pppoe_pa.remote, po->pppoe_ifindex); | ||
615 | dev_put(po->pppoe_dev); | 659 | dev_put(po->pppoe_dev); |
660 | } | ||
616 | memset(sk_pppox(po) + 1, 0, | 661 | memset(sk_pppox(po) + 1, 0, |
617 | sizeof(struct pppox_sock) - sizeof(struct sock)); | 662 | sizeof(struct pppox_sock) - sizeof(struct sock)); |
618 | sk->sk_state = PPPOX_NONE; | 663 | sk->sk_state = PPPOX_NONE; |
@@ -620,18 +665,17 @@ static int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr, | |||
620 | 665 | ||
621 | /* Re-bind in session stage only */ | 666 | /* Re-bind in session stage only */ |
622 | if (stage_session(sp->sa_addr.pppoe.sid)) { | 667 | if (stage_session(sp->sa_addr.pppoe.sid)) { |
623 | dev = dev_get_by_name(&init_net, sp->sa_addr.pppoe.dev); | ||
624 | |||
625 | error = -ENODEV; | 668 | error = -ENODEV; |
669 | dev = dev_get_by_name(sock_net(sk), sp->sa_addr.pppoe.dev); | ||
626 | if (!dev) | 670 | if (!dev) |
627 | goto end; | 671 | goto end; |
628 | 672 | ||
629 | po->pppoe_dev = dev; | 673 | po->pppoe_dev = dev; |
630 | po->pppoe_ifindex = dev->ifindex; | 674 | po->pppoe_ifindex = dev->ifindex; |
631 | 675 | pn = pppoe_pernet(dev_net(dev)); | |
632 | write_lock_bh(&pppoe_hash_lock); | 676 | write_lock_bh(&pn->hash_lock); |
633 | if (!(dev->flags & IFF_UP)) { | 677 | if (!(dev->flags & IFF_UP)) { |
634 | write_unlock_bh(&pppoe_hash_lock); | 678 | write_unlock_bh(&pn->hash_lock); |
635 | goto err_put; | 679 | goto err_put; |
636 | } | 680 | } |
637 | 681 | ||
@@ -639,8 +683,8 @@ static int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr, | |||
639 | &sp->sa_addr.pppoe, | 683 | &sp->sa_addr.pppoe, |
640 | sizeof(struct pppoe_addr)); | 684 | sizeof(struct pppoe_addr)); |
641 | 685 | ||
642 | error = __set_item(po); | 686 | error = __set_item(pn, po); |
643 | write_unlock_bh(&pppoe_hash_lock); | 687 | write_unlock_bh(&pn->hash_lock); |
644 | if (error < 0) | 688 | if (error < 0) |
645 | goto err_put; | 689 | goto err_put; |
646 | 690 | ||
@@ -700,7 +744,6 @@ static int pppoe_ioctl(struct socket *sock, unsigned int cmd, | |||
700 | switch (cmd) { | 744 | switch (cmd) { |
701 | case PPPIOCGMRU: | 745 | case PPPIOCGMRU: |
702 | err = -ENXIO; | 746 | err = -ENXIO; |
703 | |||
704 | if (!(sk->sk_state & PPPOX_CONNECTED)) | 747 | if (!(sk->sk_state & PPPOX_CONNECTED)) |
705 | break; | 748 | break; |
706 | 749 | ||
@@ -708,7 +751,7 @@ static int pppoe_ioctl(struct socket *sock, unsigned int cmd, | |||
708 | if (put_user(po->pppoe_dev->mtu - | 751 | if (put_user(po->pppoe_dev->mtu - |
709 | sizeof(struct pppoe_hdr) - | 752 | sizeof(struct pppoe_hdr) - |
710 | PPP_HDRLEN, | 753 | PPP_HDRLEN, |
711 | (int __user *) arg)) | 754 | (int __user *)arg)) |
712 | break; | 755 | break; |
713 | err = 0; | 756 | err = 0; |
714 | break; | 757 | break; |
@@ -764,8 +807,7 @@ static int pppoe_ioctl(struct socket *sock, unsigned int cmd, | |||
764 | 807 | ||
765 | /* Check that the socket referenced by the address | 808 | /* Check that the socket referenced by the address |
766 | actually exists. */ | 809 | actually exists. */ |
767 | relay_po = get_item_by_addr(&po->pppoe_relay); | 810 | relay_po = get_item_by_addr(sock_net(sk), &po->pppoe_relay); |
768 | |||
769 | if (!relay_po) | 811 | if (!relay_po) |
770 | break; | 812 | break; |
771 | 813 | ||
@@ -837,11 +879,10 @@ static int pppoe_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
837 | skb->priority = sk->sk_priority; | 879 | skb->priority = sk->sk_priority; |
838 | skb->protocol = __constant_htons(ETH_P_PPP_SES); | 880 | skb->protocol = __constant_htons(ETH_P_PPP_SES); |
839 | 881 | ||
840 | ph = (struct pppoe_hdr *) skb_put(skb, total_len + sizeof(struct pppoe_hdr)); | 882 | ph = (struct pppoe_hdr *)skb_put(skb, total_len + sizeof(struct pppoe_hdr)); |
841 | start = (char *) &ph->tag[0]; | 883 | start = (char *)&ph->tag[0]; |
842 | 884 | ||
843 | error = memcpy_fromiovec(start, m->msg_iov, total_len); | 885 | error = memcpy_fromiovec(start, m->msg_iov, total_len); |
844 | |||
845 | if (error < 0) { | 886 | if (error < 0) { |
846 | kfree_skb(skb); | 887 | kfree_skb(skb); |
847 | goto end; | 888 | goto end; |
@@ -919,7 +960,7 @@ abort: | |||
919 | ***********************************************************************/ | 960 | ***********************************************************************/ |
920 | static int pppoe_xmit(struct ppp_channel *chan, struct sk_buff *skb) | 961 | static int pppoe_xmit(struct ppp_channel *chan, struct sk_buff *skb) |
921 | { | 962 | { |
922 | struct sock *sk = (struct sock *) chan->private; | 963 | struct sock *sk = (struct sock *)chan->private; |
923 | return __pppoe_xmit(sk, skb); | 964 | return __pppoe_xmit(sk, skb); |
924 | } | 965 | } |
925 | 966 | ||
@@ -941,7 +982,6 @@ static int pppoe_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
941 | 982 | ||
942 | skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, | 983 | skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, |
943 | flags & MSG_DONTWAIT, &error); | 984 | flags & MSG_DONTWAIT, &error); |
944 | |||
945 | if (error < 0) | 985 | if (error < 0) |
946 | goto end; | 986 | goto end; |
947 | 987 | ||
@@ -964,6 +1004,7 @@ static int pppoe_seq_show(struct seq_file *seq, void *v) | |||
964 | { | 1004 | { |
965 | struct pppox_sock *po; | 1005 | struct pppox_sock *po; |
966 | char *dev_name; | 1006 | char *dev_name; |
1007 | DECLARE_MAC_BUF(mac); | ||
967 | 1008 | ||
968 | if (v == SEQ_START_TOKEN) { | 1009 | if (v == SEQ_START_TOKEN) { |
969 | seq_puts(seq, "Id Address Device\n"); | 1010 | seq_puts(seq, "Id Address Device\n"); |
@@ -974,44 +1015,47 @@ static int pppoe_seq_show(struct seq_file *seq, void *v) | |||
974 | dev_name = po->pppoe_pa.dev; | 1015 | dev_name = po->pppoe_pa.dev; |
975 | 1016 | ||
976 | seq_printf(seq, "%08X %pM %8s\n", | 1017 | seq_printf(seq, "%08X %pM %8s\n", |
977 | po->pppoe_pa.sid, po->pppoe_pa.remote, dev_name); | 1018 | po->pppoe_pa.sid, po->pppoe_pa.remote, dev_name); |
978 | out: | 1019 | out: |
979 | return 0; | 1020 | return 0; |
980 | } | 1021 | } |
981 | 1022 | ||
982 | static __inline__ struct pppox_sock *pppoe_get_idx(loff_t pos) | 1023 | static inline struct pppox_sock *pppoe_get_idx(struct pppoe_net *pn, loff_t pos) |
983 | { | 1024 | { |
984 | struct pppox_sock *po; | 1025 | struct pppox_sock *po; |
985 | int i; | 1026 | int i; |
986 | 1027 | ||
987 | for (i = 0; i < PPPOE_HASH_SIZE; i++) { | 1028 | for (i = 0; i < PPPOE_HASH_SIZE; i++) { |
988 | po = item_hash_table[i]; | 1029 | po = pn->hash_table[i]; |
989 | while (po) { | 1030 | while (po) { |
990 | if (!pos--) | 1031 | if (!pos--) |
991 | goto out; | 1032 | goto out; |
992 | po = po->next; | 1033 | po = po->next; |
993 | } | 1034 | } |
994 | } | 1035 | } |
1036 | |||
995 | out: | 1037 | out: |
996 | return po; | 1038 | return po; |
997 | } | 1039 | } |
998 | 1040 | ||
999 | static void *pppoe_seq_start(struct seq_file *seq, loff_t *pos) | 1041 | static void *pppoe_seq_start(struct seq_file *seq, loff_t *pos) |
1000 | __acquires(pppoe_hash_lock) | 1042 | __acquires(pn->hash_lock) |
1001 | { | 1043 | { |
1044 | struct pppoe_net *pn = pppoe_pernet(seq->private); | ||
1002 | loff_t l = *pos; | 1045 | loff_t l = *pos; |
1003 | 1046 | ||
1004 | read_lock_bh(&pppoe_hash_lock); | 1047 | read_lock_bh(&pn->hash_lock); |
1005 | return l ? pppoe_get_idx(--l) : SEQ_START_TOKEN; | 1048 | return l ? pppoe_get_idx(pn, --l) : SEQ_START_TOKEN; |
1006 | } | 1049 | } |
1007 | 1050 | ||
1008 | static void *pppoe_seq_next(struct seq_file *seq, void *v, loff_t *pos) | 1051 | static void *pppoe_seq_next(struct seq_file *seq, void *v, loff_t *pos) |
1009 | { | 1052 | { |
1053 | struct pppoe_net *pn = pppoe_pernet(seq->private); | ||
1010 | struct pppox_sock *po; | 1054 | struct pppox_sock *po; |
1011 | 1055 | ||
1012 | ++*pos; | 1056 | ++*pos; |
1013 | if (v == SEQ_START_TOKEN) { | 1057 | if (v == SEQ_START_TOKEN) { |
1014 | po = pppoe_get_idx(0); | 1058 | po = pppoe_get_idx(pn, 0); |
1015 | goto out; | 1059 | goto out; |
1016 | } | 1060 | } |
1017 | po = v; | 1061 | po = v; |
@@ -1021,19 +1065,21 @@ static void *pppoe_seq_next(struct seq_file *seq, void *v, loff_t *pos) | |||
1021 | int hash = hash_item(po->pppoe_pa.sid, po->pppoe_pa.remote); | 1065 | int hash = hash_item(po->pppoe_pa.sid, po->pppoe_pa.remote); |
1022 | 1066 | ||
1023 | while (++hash < PPPOE_HASH_SIZE) { | 1067 | while (++hash < PPPOE_HASH_SIZE) { |
1024 | po = item_hash_table[hash]; | 1068 | po = pn->hash_table[hash]; |
1025 | if (po) | 1069 | if (po) |
1026 | break; | 1070 | break; |
1027 | } | 1071 | } |
1028 | } | 1072 | } |
1073 | |||
1029 | out: | 1074 | out: |
1030 | return po; | 1075 | return po; |
1031 | } | 1076 | } |
1032 | 1077 | ||
1033 | static void pppoe_seq_stop(struct seq_file *seq, void *v) | 1078 | static void pppoe_seq_stop(struct seq_file *seq, void *v) |
1034 | __releases(pppoe_hash_lock) | 1079 | __releases(pn->hash_lock) |
1035 | { | 1080 | { |
1036 | read_unlock_bh(&pppoe_hash_lock); | 1081 | struct pppoe_net *pn = pppoe_pernet(seq->private); |
1082 | read_unlock_bh(&pn->hash_lock); | ||
1037 | } | 1083 | } |
1038 | 1084 | ||
1039 | static const struct seq_operations pppoe_seq_ops = { | 1085 | static const struct seq_operations pppoe_seq_ops = { |
@@ -1045,7 +1091,30 @@ static const struct seq_operations pppoe_seq_ops = { | |||
1045 | 1091 | ||
1046 | static int pppoe_seq_open(struct inode *inode, struct file *file) | 1092 | static int pppoe_seq_open(struct inode *inode, struct file *file) |
1047 | { | 1093 | { |
1048 | return seq_open(file, &pppoe_seq_ops); | 1094 | struct seq_file *m; |
1095 | struct net *net; | ||
1096 | int err; | ||
1097 | |||
1098 | err = seq_open(file, &pppoe_seq_ops); | ||
1099 | if (err) | ||
1100 | return err; | ||
1101 | |||
1102 | m = file->private_data; | ||
1103 | net = maybe_get_net(PDE_NET(PDE(inode))); | ||
1104 | BUG_ON(!net); | ||
1105 | m->private = net; | ||
1106 | |||
1107 | return err; | ||
1108 | } | ||
1109 | |||
1110 | static int pppoe_seq_release(struct inode *inode, struct file *file) | ||
1111 | { | ||
1112 | struct seq_file *m; | ||
1113 | |||
1114 | m = file->private_data; | ||
1115 | put_net((struct net*)m->private); | ||
1116 | |||
1117 | return seq_release(inode, file); | ||
1049 | } | 1118 | } |
1050 | 1119 | ||
1051 | static const struct file_operations pppoe_seq_fops = { | 1120 | static const struct file_operations pppoe_seq_fops = { |
@@ -1053,20 +1122,9 @@ static const struct file_operations pppoe_seq_fops = { | |||
1053 | .open = pppoe_seq_open, | 1122 | .open = pppoe_seq_open, |
1054 | .read = seq_read, | 1123 | .read = seq_read, |
1055 | .llseek = seq_lseek, | 1124 | .llseek = seq_lseek, |
1056 | .release = seq_release, | 1125 | .release = pppoe_seq_release, |
1057 | }; | 1126 | }; |
1058 | 1127 | ||
1059 | static int __init pppoe_proc_init(void) | ||
1060 | { | ||
1061 | struct proc_dir_entry *p; | ||
1062 | |||
1063 | p = proc_net_fops_create(&init_net, "pppoe", S_IRUGO, &pppoe_seq_fops); | ||
1064 | if (!p) | ||
1065 | return -ENOMEM; | ||
1066 | return 0; | ||
1067 | } | ||
1068 | #else /* CONFIG_PROC_FS */ | ||
1069 | static inline int pppoe_proc_init(void) { return 0; } | ||
1070 | #endif /* CONFIG_PROC_FS */ | 1128 | #endif /* CONFIG_PROC_FS */ |
1071 | 1129 | ||
1072 | static const struct proto_ops pppoe_ops = { | 1130 | static const struct proto_ops pppoe_ops = { |
@@ -1095,10 +1153,61 @@ static struct pppox_proto pppoe_proto = { | |||
1095 | .owner = THIS_MODULE, | 1153 | .owner = THIS_MODULE, |
1096 | }; | 1154 | }; |
1097 | 1155 | ||
1156 | static __net_init int pppoe_init_net(struct net *net) | ||
1157 | { | ||
1158 | struct pppoe_net *pn; | ||
1159 | struct proc_dir_entry *pde; | ||
1160 | int err; | ||
1161 | |||
1162 | pn = kzalloc(sizeof(*pn), GFP_KERNEL); | ||
1163 | if (!pn) | ||
1164 | return -ENOMEM; | ||
1165 | |||
1166 | rwlock_init(&pn->hash_lock); | ||
1167 | |||
1168 | err = net_assign_generic(net, pppoe_net_id, pn); | ||
1169 | if (err) | ||
1170 | goto out; | ||
1171 | |||
1172 | pde = proc_net_fops_create(net, "pppoe", S_IRUGO, &pppoe_seq_fops); | ||
1173 | #ifdef CONFIG_PROC_FS | ||
1174 | if (!pde) { | ||
1175 | err = -ENOMEM; | ||
1176 | goto out; | ||
1177 | } | ||
1178 | #endif | ||
1179 | |||
1180 | return 0; | ||
1181 | |||
1182 | out: | ||
1183 | kfree(pn); | ||
1184 | return err; | ||
1185 | } | ||
1186 | |||
1187 | static __net_exit void pppoe_exit_net(struct net *net) | ||
1188 | { | ||
1189 | struct pppoe_net *pn; | ||
1190 | |||
1191 | proc_net_remove(net, "pppoe"); | ||
1192 | pn = net_generic(net, pppoe_net_id); | ||
1193 | /* | ||
1194 | * if someone has cached our net then | ||
1195 | * further net_generic call will return NULL | ||
1196 | */ | ||
1197 | net_assign_generic(net, pppoe_net_id, NULL); | ||
1198 | kfree(pn); | ||
1199 | } | ||
1200 | |||
1201 | static __net_initdata struct pernet_operations pppoe_net_ops = { | ||
1202 | .init = pppoe_init_net, | ||
1203 | .exit = pppoe_exit_net, | ||
1204 | }; | ||
1205 | |||
1098 | static int __init pppoe_init(void) | 1206 | static int __init pppoe_init(void) |
1099 | { | 1207 | { |
1100 | int err = proto_register(&pppoe_sk_proto, 0); | 1208 | int err; |
1101 | 1209 | ||
1210 | err = proto_register(&pppoe_sk_proto, 0); | ||
1102 | if (err) | 1211 | if (err) |
1103 | goto out; | 1212 | goto out; |
1104 | 1213 | ||
@@ -1106,20 +1215,22 @@ static int __init pppoe_init(void) | |||
1106 | if (err) | 1215 | if (err) |
1107 | goto out_unregister_pppoe_proto; | 1216 | goto out_unregister_pppoe_proto; |
1108 | 1217 | ||
1109 | err = pppoe_proc_init(); | 1218 | err = register_pernet_gen_device(&pppoe_net_id, &pppoe_net_ops); |
1110 | if (err) | 1219 | if (err) |
1111 | goto out_unregister_pppox_proto; | 1220 | goto out_unregister_pppox_proto; |
1112 | 1221 | ||
1113 | dev_add_pack(&pppoes_ptype); | 1222 | dev_add_pack(&pppoes_ptype); |
1114 | dev_add_pack(&pppoed_ptype); | 1223 | dev_add_pack(&pppoed_ptype); |
1115 | register_netdevice_notifier(&pppoe_notifier); | 1224 | register_netdevice_notifier(&pppoe_notifier); |
1116 | out: | 1225 | |
1117 | return err; | 1226 | return 0; |
1227 | |||
1118 | out_unregister_pppox_proto: | 1228 | out_unregister_pppox_proto: |
1119 | unregister_pppox_proto(PX_PROTO_OE); | 1229 | unregister_pppox_proto(PX_PROTO_OE); |
1120 | out_unregister_pppoe_proto: | 1230 | out_unregister_pppoe_proto: |
1121 | proto_unregister(&pppoe_sk_proto); | 1231 | proto_unregister(&pppoe_sk_proto); |
1122 | goto out; | 1232 | out: |
1233 | return err; | ||
1123 | } | 1234 | } |
1124 | 1235 | ||
1125 | static void __exit pppoe_exit(void) | 1236 | static void __exit pppoe_exit(void) |
@@ -1128,7 +1239,7 @@ static void __exit pppoe_exit(void) | |||
1128 | dev_remove_pack(&pppoes_ptype); | 1239 | dev_remove_pack(&pppoes_ptype); |
1129 | dev_remove_pack(&pppoed_ptype); | 1240 | dev_remove_pack(&pppoed_ptype); |
1130 | unregister_netdevice_notifier(&pppoe_notifier); | 1241 | unregister_netdevice_notifier(&pppoe_notifier); |
1131 | remove_proc_entry("pppoe", init_net.proc_net); | 1242 | unregister_pernet_gen_device(pppoe_net_id, &pppoe_net_ops); |
1132 | proto_unregister(&pppoe_sk_proto); | 1243 | proto_unregister(&pppoe_sk_proto); |
1133 | } | 1244 | } |
1134 | 1245 | ||