aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/pppol2tp.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/pppol2tp.c')
-rw-r--r--drivers/net/pppol2tp.c192
1 files changed, 114 insertions, 78 deletions
diff --git a/drivers/net/pppol2tp.c b/drivers/net/pppol2tp.c
index f1a946785c6a..15f4a43a6890 100644
--- a/drivers/net/pppol2tp.c
+++ b/drivers/net/pppol2tp.c
@@ -90,7 +90,9 @@
90#include <linux/hash.h> 90#include <linux/hash.h>
91#include <linux/sort.h> 91#include <linux/sort.h>
92#include <linux/proc_fs.h> 92#include <linux/proc_fs.h>
93#include <linux/nsproxy.h>
93#include <net/net_namespace.h> 94#include <net/net_namespace.h>
95#include <net/netns/generic.h>
94#include <net/dst.h> 96#include <net/dst.h>
95#include <net/ip.h> 97#include <net/ip.h>
96#include <net/udp.h> 98#include <net/udp.h>
@@ -204,6 +206,7 @@ struct pppol2tp_tunnel
204 struct sock *sock; /* Parent socket */ 206 struct sock *sock; /* Parent socket */
205 struct list_head list; /* Keep a list of all open 207 struct list_head list; /* Keep a list of all open
206 * prepared sockets */ 208 * prepared sockets */
209 struct net *pppol2tp_net; /* the net we belong to */
207 210
208 atomic_t ref_count; 211 atomic_t ref_count;
209}; 212};
@@ -227,8 +230,20 @@ static atomic_t pppol2tp_tunnel_count;
227static atomic_t pppol2tp_session_count; 230static atomic_t pppol2tp_session_count;
228static struct ppp_channel_ops pppol2tp_chan_ops = { pppol2tp_xmit , NULL }; 231static struct ppp_channel_ops pppol2tp_chan_ops = { pppol2tp_xmit , NULL };
229static struct proto_ops pppol2tp_ops; 232static struct proto_ops pppol2tp_ops;
230static LIST_HEAD(pppol2tp_tunnel_list); 233
231static DEFINE_RWLOCK(pppol2tp_tunnel_list_lock); 234/* per-net private data for this module */
235static unsigned int pppol2tp_net_id;
236struct pppol2tp_net {
237 struct list_head pppol2tp_tunnel_list;
238 rwlock_t pppol2tp_tunnel_list_lock;
239};
240
241static inline struct pppol2tp_net *pppol2tp_pernet(struct net *net)
242{
243 BUG_ON(!net);
244
245 return net_generic(net, pppol2tp_net_id);
246}
232 247
233/* Helpers to obtain tunnel/session contexts from sockets. 248/* Helpers to obtain tunnel/session contexts from sockets.
234 */ 249 */
@@ -321,18 +336,19 @@ pppol2tp_session_find(struct pppol2tp_tunnel *tunnel, u16 session_id)
321 336
322/* Lookup a tunnel by id 337/* Lookup a tunnel by id
323 */ 338 */
324static struct pppol2tp_tunnel *pppol2tp_tunnel_find(u16 tunnel_id) 339static struct pppol2tp_tunnel *pppol2tp_tunnel_find(struct net *net, u16 tunnel_id)
325{ 340{
326 struct pppol2tp_tunnel *tunnel = NULL; 341 struct pppol2tp_tunnel *tunnel;
342 struct pppol2tp_net *pn = pppol2tp_pernet(net);
327 343
328 read_lock_bh(&pppol2tp_tunnel_list_lock); 344 read_lock_bh(&pn->pppol2tp_tunnel_list_lock);
329 list_for_each_entry(tunnel, &pppol2tp_tunnel_list, list) { 345 list_for_each_entry(tunnel, &pn->pppol2tp_tunnel_list, list) {
330 if (tunnel->stats.tunnel_id == tunnel_id) { 346 if (tunnel->stats.tunnel_id == tunnel_id) {
331 read_unlock_bh(&pppol2tp_tunnel_list_lock); 347 read_unlock_bh(&pn->pppol2tp_tunnel_list_lock);
332 return tunnel; 348 return tunnel;
333 } 349 }
334 } 350 }
335 read_unlock_bh(&pppol2tp_tunnel_list_lock); 351 read_unlock_bh(&pn->pppol2tp_tunnel_list_lock);
336 352
337 return NULL; 353 return NULL;
338} 354}
@@ -1287,10 +1303,12 @@ again:
1287 */ 1303 */
1288static void pppol2tp_tunnel_free(struct pppol2tp_tunnel *tunnel) 1304static void pppol2tp_tunnel_free(struct pppol2tp_tunnel *tunnel)
1289{ 1305{
1306 struct pppol2tp_net *pn = pppol2tp_pernet(tunnel->pppol2tp_net);
1307
1290 /* Remove from socket list */ 1308 /* Remove from socket list */
1291 write_lock_bh(&pppol2tp_tunnel_list_lock); 1309 write_lock_bh(&pn->pppol2tp_tunnel_list_lock);
1292 list_del_init(&tunnel->list); 1310 list_del_init(&tunnel->list);
1293 write_unlock_bh(&pppol2tp_tunnel_list_lock); 1311 write_unlock_bh(&pn->pppol2tp_tunnel_list_lock);
1294 1312
1295 atomic_dec(&pppol2tp_tunnel_count); 1313 atomic_dec(&pppol2tp_tunnel_count);
1296 kfree(tunnel); 1314 kfree(tunnel);
@@ -1444,13 +1462,14 @@ error:
1444/* Internal function to prepare a tunnel (UDP) socket to have PPPoX 1462/* Internal function to prepare a tunnel (UDP) socket to have PPPoX
1445 * sockets attached to it. 1463 * sockets attached to it.
1446 */ 1464 */
1447static struct sock *pppol2tp_prepare_tunnel_socket(int fd, u16 tunnel_id, 1465static struct sock *pppol2tp_prepare_tunnel_socket(struct net *net,
1448 int *error) 1466 int fd, u16 tunnel_id, int *error)
1449{ 1467{
1450 int err; 1468 int err;
1451 struct socket *sock = NULL; 1469 struct socket *sock = NULL;
1452 struct sock *sk; 1470 struct sock *sk;
1453 struct pppol2tp_tunnel *tunnel; 1471 struct pppol2tp_tunnel *tunnel;
1472 struct pppol2tp_net *pn;
1454 struct sock *ret = NULL; 1473 struct sock *ret = NULL;
1455 1474
1456 /* Get the tunnel UDP socket from the fd, which was opened by 1475 /* Get the tunnel UDP socket from the fd, which was opened by
@@ -1524,11 +1543,15 @@ static struct sock *pppol2tp_prepare_tunnel_socket(int fd, u16 tunnel_id,
1524 /* Misc init */ 1543 /* Misc init */
1525 rwlock_init(&tunnel->hlist_lock); 1544 rwlock_init(&tunnel->hlist_lock);
1526 1545
1546 /* The net we belong to */
1547 tunnel->pppol2tp_net = net;
1548 pn = pppol2tp_pernet(net);
1549
1527 /* Add tunnel to our list */ 1550 /* Add tunnel to our list */
1528 INIT_LIST_HEAD(&tunnel->list); 1551 INIT_LIST_HEAD(&tunnel->list);
1529 write_lock_bh(&pppol2tp_tunnel_list_lock); 1552 write_lock_bh(&pn->pppol2tp_tunnel_list_lock);
1530 list_add(&tunnel->list, &pppol2tp_tunnel_list); 1553 list_add(&tunnel->list, &pn->pppol2tp_tunnel_list);
1531 write_unlock_bh(&pppol2tp_tunnel_list_lock); 1554 write_unlock_bh(&pn->pppol2tp_tunnel_list_lock);
1532 atomic_inc(&pppol2tp_tunnel_count); 1555 atomic_inc(&pppol2tp_tunnel_count);
1533 1556
1534 /* Bump the reference count. The tunnel context is deleted 1557 /* Bump the reference count. The tunnel context is deleted
@@ -1629,7 +1652,8 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
1629 * tunnel id. 1652 * tunnel id.
1630 */ 1653 */
1631 if ((sp->pppol2tp.s_session == 0) && (sp->pppol2tp.d_session == 0)) { 1654 if ((sp->pppol2tp.s_session == 0) && (sp->pppol2tp.d_session == 0)) {
1632 tunnel_sock = pppol2tp_prepare_tunnel_socket(sp->pppol2tp.fd, 1655 tunnel_sock = pppol2tp_prepare_tunnel_socket(sock_net(sk),
1656 sp->pppol2tp.fd,
1633 sp->pppol2tp.s_tunnel, 1657 sp->pppol2tp.s_tunnel,
1634 &error); 1658 &error);
1635 if (tunnel_sock == NULL) 1659 if (tunnel_sock == NULL)
@@ -1637,7 +1661,7 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
1637 1661
1638 tunnel = tunnel_sock->sk_user_data; 1662 tunnel = tunnel_sock->sk_user_data;
1639 } else { 1663 } else {
1640 tunnel = pppol2tp_tunnel_find(sp->pppol2tp.s_tunnel); 1664 tunnel = pppol2tp_tunnel_find(sock_net(sk), sp->pppol2tp.s_tunnel);
1641 1665
1642 /* Error if we can't find the tunnel */ 1666 /* Error if we can't find the tunnel */
1643 error = -ENOENT; 1667 error = -ENOENT;
@@ -1725,7 +1749,7 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
1725 po->chan.ops = &pppol2tp_chan_ops; 1749 po->chan.ops = &pppol2tp_chan_ops;
1726 po->chan.mtu = session->mtu; 1750 po->chan.mtu = session->mtu;
1727 1751
1728 error = ppp_register_channel(&po->chan); 1752 error = ppp_register_net_channel(sock_net(sk), &po->chan);
1729 if (error) 1753 if (error)
1730 goto end_put_tun; 1754 goto end_put_tun;
1731 1755
@@ -2347,8 +2371,9 @@ end:
2347#include <linux/seq_file.h> 2371#include <linux/seq_file.h>
2348 2372
2349struct pppol2tp_seq_data { 2373struct pppol2tp_seq_data {
2350 struct pppol2tp_tunnel *tunnel; /* current tunnel */ 2374 struct seq_net_private p;
2351 struct pppol2tp_session *session; /* NULL means get first session in tunnel */ 2375 struct pppol2tp_tunnel *tunnel; /* current tunnel */
2376 struct pppol2tp_session *session; /* NULL means get first session in tunnel */
2352}; 2377};
2353 2378
2354static struct pppol2tp_session *next_session(struct pppol2tp_tunnel *tunnel, struct pppol2tp_session *curr) 2379static struct pppol2tp_session *next_session(struct pppol2tp_tunnel *tunnel, struct pppol2tp_session *curr)
@@ -2384,17 +2409,18 @@ out:
2384 return session; 2409 return session;
2385} 2410}
2386 2411
2387static struct pppol2tp_tunnel *next_tunnel(struct pppol2tp_tunnel *curr) 2412static struct pppol2tp_tunnel *next_tunnel(struct pppol2tp_net *pn,
2413 struct pppol2tp_tunnel *curr)
2388{ 2414{
2389 struct pppol2tp_tunnel *tunnel = NULL; 2415 struct pppol2tp_tunnel *tunnel = NULL;
2390 2416
2391 read_lock_bh(&pppol2tp_tunnel_list_lock); 2417 read_lock_bh(&pn->pppol2tp_tunnel_list_lock);
2392 if (list_is_last(&curr->list, &pppol2tp_tunnel_list)) { 2418 if (list_is_last(&curr->list, &pn->pppol2tp_tunnel_list)) {
2393 goto out; 2419 goto out;
2394 } 2420 }
2395 tunnel = list_entry(curr->list.next, struct pppol2tp_tunnel, list); 2421 tunnel = list_entry(curr->list.next, struct pppol2tp_tunnel, list);
2396out: 2422out:
2397 read_unlock_bh(&pppol2tp_tunnel_list_lock); 2423 read_unlock_bh(&pn->pppol2tp_tunnel_list_lock);
2398 2424
2399 return tunnel; 2425 return tunnel;
2400} 2426}
@@ -2402,6 +2428,7 @@ out:
2402static void *pppol2tp_seq_start(struct seq_file *m, loff_t *offs) 2428static void *pppol2tp_seq_start(struct seq_file *m, loff_t *offs)
2403{ 2429{
2404 struct pppol2tp_seq_data *pd = SEQ_START_TOKEN; 2430 struct pppol2tp_seq_data *pd = SEQ_START_TOKEN;
2431 struct pppol2tp_net *pn;
2405 loff_t pos = *offs; 2432 loff_t pos = *offs;
2406 2433
2407 if (!pos) 2434 if (!pos)
@@ -2409,14 +2436,15 @@ static void *pppol2tp_seq_start(struct seq_file *m, loff_t *offs)
2409 2436
2410 BUG_ON(m->private == NULL); 2437 BUG_ON(m->private == NULL);
2411 pd = m->private; 2438 pd = m->private;
2439 pn = pppol2tp_pernet(seq_file_net(m));
2412 2440
2413 if (pd->tunnel == NULL) { 2441 if (pd->tunnel == NULL) {
2414 if (!list_empty(&pppol2tp_tunnel_list)) 2442 if (!list_empty(&pn->pppol2tp_tunnel_list))
2415 pd->tunnel = list_entry(pppol2tp_tunnel_list.next, struct pppol2tp_tunnel, list); 2443 pd->tunnel = list_entry(pn->pppol2tp_tunnel_list.next, struct pppol2tp_tunnel, list);
2416 } else { 2444 } else {
2417 pd->session = next_session(pd->tunnel, pd->session); 2445 pd->session = next_session(pd->tunnel, pd->session);
2418 if (pd->session == NULL) { 2446 if (pd->session == NULL) {
2419 pd->tunnel = next_tunnel(pd->tunnel); 2447 pd->tunnel = next_tunnel(pn, pd->tunnel);
2420 } 2448 }
2421 } 2449 }
2422 2450
@@ -2517,7 +2545,7 @@ out:
2517 return 0; 2545 return 0;
2518} 2546}
2519 2547
2520static struct seq_operations pppol2tp_seq_ops = { 2548static const struct seq_operations pppol2tp_seq_ops = {
2521 .start = pppol2tp_seq_start, 2549 .start = pppol2tp_seq_start,
2522 .next = pppol2tp_seq_next, 2550 .next = pppol2tp_seq_next,
2523 .stop = pppol2tp_seq_stop, 2551 .stop = pppol2tp_seq_stop,
@@ -2530,51 +2558,18 @@ static struct seq_operations pppol2tp_seq_ops = {
2530 */ 2558 */
2531static int pppol2tp_proc_open(struct inode *inode, struct file *file) 2559static int pppol2tp_proc_open(struct inode *inode, struct file *file)
2532{ 2560{
2533 struct seq_file *m; 2561 return seq_open_net(inode, file, &pppol2tp_seq_ops,
2534 struct pppol2tp_seq_data *pd; 2562 sizeof(struct pppol2tp_seq_data));
2535 int ret = 0;
2536
2537 ret = seq_open(file, &pppol2tp_seq_ops);
2538 if (ret < 0)
2539 goto out;
2540
2541 m = file->private_data;
2542
2543 /* Allocate and fill our proc_data for access later */
2544 ret = -ENOMEM;
2545 m->private = kzalloc(sizeof(struct pppol2tp_seq_data), GFP_KERNEL);
2546 if (m->private == NULL)
2547 goto out;
2548
2549 pd = m->private;
2550 ret = 0;
2551
2552out:
2553 return ret;
2554}
2555
2556/* Called when /proc file access completes.
2557 */
2558static int pppol2tp_proc_release(struct inode *inode, struct file *file)
2559{
2560 struct seq_file *m = (struct seq_file *)file->private_data;
2561
2562 kfree(m->private);
2563 m->private = NULL;
2564
2565 return seq_release(inode, file);
2566} 2563}
2567 2564
2568static struct file_operations pppol2tp_proc_fops = { 2565static const struct file_operations pppol2tp_proc_fops = {
2569 .owner = THIS_MODULE, 2566 .owner = THIS_MODULE,
2570 .open = pppol2tp_proc_open, 2567 .open = pppol2tp_proc_open,
2571 .read = seq_read, 2568 .read = seq_read,
2572 .llseek = seq_lseek, 2569 .llseek = seq_lseek,
2573 .release = pppol2tp_proc_release, 2570 .release = seq_release_net,
2574}; 2571};
2575 2572
2576static struct proc_dir_entry *pppol2tp_proc;
2577
2578#endif /* CONFIG_PROC_FS */ 2573#endif /* CONFIG_PROC_FS */
2579 2574
2580/***************************************************************************** 2575/*****************************************************************************
@@ -2606,6 +2601,57 @@ static struct pppox_proto pppol2tp_proto = {
2606 .ioctl = pppol2tp_ioctl 2601 .ioctl = pppol2tp_ioctl
2607}; 2602};
2608 2603
2604static __net_init int pppol2tp_init_net(struct net *net)
2605{
2606 struct pppol2tp_net *pn;
2607 struct proc_dir_entry *pde;
2608 int err;
2609
2610 pn = kzalloc(sizeof(*pn), GFP_KERNEL);
2611 if (!pn)
2612 return -ENOMEM;
2613
2614 INIT_LIST_HEAD(&pn->pppol2tp_tunnel_list);
2615 rwlock_init(&pn->pppol2tp_tunnel_list_lock);
2616
2617 err = net_assign_generic(net, pppol2tp_net_id, pn);
2618 if (err)
2619 goto out;
2620
2621 pde = proc_net_fops_create(net, "pppol2tp", S_IRUGO, &pppol2tp_proc_fops);
2622#ifdef CONFIG_PROC_FS
2623 if (!pde) {
2624 err = -ENOMEM;
2625 goto out;
2626 }
2627#endif
2628
2629 return 0;
2630
2631out:
2632 kfree(pn);
2633 return err;
2634}
2635
2636static __net_exit void pppol2tp_exit_net(struct net *net)
2637{
2638 struct pppoe_net *pn;
2639
2640 proc_net_remove(net, "pppol2tp");
2641 pn = net_generic(net, pppol2tp_net_id);
2642 /*
2643 * if someone has cached our net then
2644 * further net_generic call will return NULL
2645 */
2646 net_assign_generic(net, pppol2tp_net_id, NULL);
2647 kfree(pn);
2648}
2649
2650static __net_initdata struct pernet_operations pppol2tp_net_ops = {
2651 .init = pppol2tp_init_net,
2652 .exit = pppol2tp_exit_net,
2653};
2654
2609static int __init pppol2tp_init(void) 2655static int __init pppol2tp_init(void)
2610{ 2656{
2611 int err; 2657 int err;
@@ -2617,23 +2663,17 @@ static int __init pppol2tp_init(void)
2617 if (err) 2663 if (err)
2618 goto out_unregister_pppol2tp_proto; 2664 goto out_unregister_pppol2tp_proto;
2619 2665
2620#ifdef CONFIG_PROC_FS 2666 err = register_pernet_gen_device(&pppol2tp_net_id, &pppol2tp_net_ops);
2621 pppol2tp_proc = proc_net_fops_create(&init_net, "pppol2tp", 0, 2667 if (err)
2622 &pppol2tp_proc_fops);
2623 if (!pppol2tp_proc) {
2624 err = -ENOMEM;
2625 goto out_unregister_pppox_proto; 2668 goto out_unregister_pppox_proto;
2626 } 2669
2627#endif /* CONFIG_PROC_FS */
2628 printk(KERN_INFO "PPPoL2TP kernel driver, %s\n", 2670 printk(KERN_INFO "PPPoL2TP kernel driver, %s\n",
2629 PPPOL2TP_DRV_VERSION); 2671 PPPOL2TP_DRV_VERSION);
2630 2672
2631out: 2673out:
2632 return err; 2674 return err;
2633#ifdef CONFIG_PROC_FS
2634out_unregister_pppox_proto: 2675out_unregister_pppox_proto:
2635 unregister_pppox_proto(PX_PROTO_OL2TP); 2676 unregister_pppox_proto(PX_PROTO_OL2TP);
2636#endif
2637out_unregister_pppol2tp_proto: 2677out_unregister_pppol2tp_proto:
2638 proto_unregister(&pppol2tp_sk_proto); 2678 proto_unregister(&pppol2tp_sk_proto);
2639 goto out; 2679 goto out;
@@ -2642,10 +2682,6 @@ out_unregister_pppol2tp_proto:
2642static void __exit pppol2tp_exit(void) 2682static void __exit pppol2tp_exit(void)
2643{ 2683{
2644 unregister_pppox_proto(PX_PROTO_OL2TP); 2684 unregister_pppox_proto(PX_PROTO_OL2TP);
2645
2646#ifdef CONFIG_PROC_FS
2647 remove_proc_entry("pppol2tp", init_net.proc_net);
2648#endif
2649 proto_unregister(&pppol2tp_sk_proto); 2685 proto_unregister(&pppol2tp_sk_proto);
2650} 2686}
2651 2687