aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCyrill Gorcunov <gorcunov@gmail.com>2009-01-21 18:55:35 -0500
committerDavid S. Miller <davem@davemloft.net>2009-01-21 18:55:35 -0500
commit273ec51dd7ceaa76e038875d85061ec856d8905e (patch)
tree41d73e3a6363c88b7f4fe44ab7713682dace51e9
parent4e9fb8016a351b5b9da7fea32bcfdbc9d836e421 (diff)
net: ppp_generic - introduce net-namespace functionality v2
- Each namespace contains ppp channels and units separately with appropriate locks Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ppp_generic.c275
-rw-r--r--include/linux/ppp_channel.h4
2 files changed, 202 insertions, 77 deletions
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
index 7b2728b8f1b7..4405a76ed3da 100644
--- a/drivers/net/ppp_generic.c
+++ b/drivers/net/ppp_generic.c
@@ -49,6 +49,10 @@
49#include <net/slhc_vj.h> 49#include <net/slhc_vj.h>
50#include <asm/atomic.h> 50#include <asm/atomic.h>
51 51
52#include <linux/nsproxy.h>
53#include <net/net_namespace.h>
54#include <net/netns/generic.h>
55
52#define PPP_VERSION "2.4.2" 56#define PPP_VERSION "2.4.2"
53 57
54/* 58/*
@@ -131,6 +135,7 @@ struct ppp {
131 struct sock_filter *active_filter;/* filter for pkts to reset idle */ 135 struct sock_filter *active_filter;/* filter for pkts to reset idle */
132 unsigned pass_len, active_len; 136 unsigned pass_len, active_len;
133#endif /* CONFIG_PPP_FILTER */ 137#endif /* CONFIG_PPP_FILTER */
138 struct net *ppp_net; /* the net we belong to */
134}; 139};
135 140
136/* 141/*
@@ -155,6 +160,7 @@ struct channel {
155 struct rw_semaphore chan_sem; /* protects `chan' during chan ioctl */ 160 struct rw_semaphore chan_sem; /* protects `chan' during chan ioctl */
156 spinlock_t downl; /* protects `chan', file.xq dequeue */ 161 spinlock_t downl; /* protects `chan', file.xq dequeue */
157 struct ppp *ppp; /* ppp unit we're connected to */ 162 struct ppp *ppp; /* ppp unit we're connected to */
163 struct net *chan_net; /* the net channel belongs to */
158 struct list_head clist; /* link in list of channels per unit */ 164 struct list_head clist; /* link in list of channels per unit */
159 rwlock_t upl; /* protects `ppp' */ 165 rwlock_t upl; /* protects `ppp' */
160#ifdef CONFIG_PPP_MULTILINK 166#ifdef CONFIG_PPP_MULTILINK
@@ -173,26 +179,35 @@ struct channel {
173 * channel.downl. 179 * channel.downl.
174 */ 180 */
175 181
176/*
177 * all_ppp_mutex protects the all_ppp_units mapping.
178 * It also ensures that finding a ppp unit in the all_ppp_units map
179 * and updating its file.refcnt field is atomic.
180 */
181static DEFINE_MUTEX(all_ppp_mutex);
182static atomic_t ppp_unit_count = ATOMIC_INIT(0); 182static atomic_t ppp_unit_count = ATOMIC_INIT(0);
183static DEFINE_IDR(ppp_units_idr);
184
185/*
186 * all_channels_lock protects all_channels and last_channel_index,
187 * and the atomicity of find a channel and updating its file.refcnt
188 * field.
189 */
190static DEFINE_SPINLOCK(all_channels_lock);
191static LIST_HEAD(all_channels);
192static LIST_HEAD(new_channels);
193static int last_channel_index;
194static atomic_t channel_count = ATOMIC_INIT(0); 183static atomic_t channel_count = ATOMIC_INIT(0);
195 184
185/* per-net private data for this module */
186static unsigned int ppp_net_id;
187struct ppp_net {
188 /* units to ppp mapping */
189 struct idr units_idr;
190
191 /*
192 * all_ppp_mutex protects the units_idr mapping.
193 * It also ensures that finding a ppp unit in the units_idr
194 * map and updating its file.refcnt field is atomic.
195 */
196 struct mutex all_ppp_mutex;
197
198 /* channels */
199 struct list_head all_channels;
200 struct list_head new_channels;
201 int last_channel_index;
202
203 /*
204 * all_channels_lock protects all_channels and
205 * last_channel_index, and the atomicity of find
206 * a channel and updating its file.refcnt field.
207 */
208 spinlock_t all_channels_lock;
209};
210
196/* Get the PPP protocol number from a skb */ 211/* Get the PPP protocol number from a skb */
197#define PPP_PROTO(skb) (((skb)->data[0] << 8) + (skb)->data[1]) 212#define PPP_PROTO(skb) (((skb)->data[0] << 8) + (skb)->data[1])
198 213
@@ -216,8 +231,8 @@ static atomic_t channel_count = ATOMIC_INIT(0);
216#define seq_after(a, b) ((s32)((a) - (b)) > 0) 231#define seq_after(a, b) ((s32)((a) - (b)) > 0)
217 232
218/* Prototypes. */ 233/* Prototypes. */
219static int ppp_unattached_ioctl(struct ppp_file *pf, struct file *file, 234static int ppp_unattached_ioctl(struct net *net, struct ppp_file *pf,
220 unsigned int cmd, unsigned long arg); 235 struct file *file, unsigned int cmd, unsigned long arg);
221static void ppp_xmit_process(struct ppp *ppp); 236static void ppp_xmit_process(struct ppp *ppp);
222static void ppp_send_frame(struct ppp *ppp, struct sk_buff *skb); 237static void ppp_send_frame(struct ppp *ppp, struct sk_buff *skb);
223static void ppp_push(struct ppp *ppp); 238static void ppp_push(struct ppp *ppp);
@@ -240,12 +255,12 @@ static void ppp_ccp_peek(struct ppp *ppp, struct sk_buff *skb, int inbound);
240static void ppp_ccp_closed(struct ppp *ppp); 255static void ppp_ccp_closed(struct ppp *ppp);
241static struct compressor *find_compressor(int type); 256static struct compressor *find_compressor(int type);
242static void ppp_get_stats(struct ppp *ppp, struct ppp_stats *st); 257static void ppp_get_stats(struct ppp *ppp, struct ppp_stats *st);
243static struct ppp *ppp_create_interface(int unit, int *retp); 258static struct ppp *ppp_create_interface(struct net *net, int unit, int *retp);
244static void init_ppp_file(struct ppp_file *pf, int kind); 259static void init_ppp_file(struct ppp_file *pf, int kind);
245static void ppp_shutdown_interface(struct ppp *ppp); 260static void ppp_shutdown_interface(struct ppp *ppp);
246static void ppp_destroy_interface(struct ppp *ppp); 261static void ppp_destroy_interface(struct ppp *ppp);
247static struct ppp *ppp_find_unit(int unit); 262static struct ppp *ppp_find_unit(struct ppp_net *pn, int unit);
248static struct channel *ppp_find_channel(int unit); 263static struct channel *ppp_find_channel(struct ppp_net *pn, int unit);
249static int ppp_connect_channel(struct channel *pch, int unit); 264static int ppp_connect_channel(struct channel *pch, int unit);
250static int ppp_disconnect_channel(struct channel *pch); 265static int ppp_disconnect_channel(struct channel *pch);
251static void ppp_destroy_channel(struct channel *pch); 266static void ppp_destroy_channel(struct channel *pch);
@@ -256,6 +271,14 @@ static void *unit_find(struct idr *p, int n);
256 271
257static struct class *ppp_class; 272static struct class *ppp_class;
258 273
274/* per net-namespace data */
275static inline struct ppp_net *ppp_pernet(struct net *net)
276{
277 BUG_ON(!net);
278
279 return net_generic(net, ppp_net_id);
280}
281
259/* Translates a PPP protocol number to a NP index (NP == network protocol) */ 282/* Translates a PPP protocol number to a NP index (NP == network protocol) */
260static inline int proto_to_npindex(int proto) 283static inline int proto_to_npindex(int proto)
261{ 284{
@@ -544,7 +567,8 @@ static long ppp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
544 int __user *p = argp; 567 int __user *p = argp;
545 568
546 if (!pf) 569 if (!pf)
547 return ppp_unattached_ioctl(pf, file, cmd, arg); 570 return ppp_unattached_ioctl(current->nsproxy->net_ns,
571 pf, file, cmd, arg);
548 572
549 if (cmd == PPPIOCDETACH) { 573 if (cmd == PPPIOCDETACH) {
550 /* 574 /*
@@ -763,12 +787,13 @@ static long ppp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
763 return err; 787 return err;
764} 788}
765 789
766static int ppp_unattached_ioctl(struct ppp_file *pf, struct file *file, 790static int ppp_unattached_ioctl(struct net *net, struct ppp_file *pf,
767 unsigned int cmd, unsigned long arg) 791 struct file *file, unsigned int cmd, unsigned long arg)
768{ 792{
769 int unit, err = -EFAULT; 793 int unit, err = -EFAULT;
770 struct ppp *ppp; 794 struct ppp *ppp;
771 struct channel *chan; 795 struct channel *chan;
796 struct ppp_net *pn;
772 int __user *p = (int __user *)arg; 797 int __user *p = (int __user *)arg;
773 798
774 lock_kernel(); 799 lock_kernel();
@@ -777,7 +802,7 @@ static int ppp_unattached_ioctl(struct ppp_file *pf, struct file *file,
777 /* Create a new ppp unit */ 802 /* Create a new ppp unit */
778 if (get_user(unit, p)) 803 if (get_user(unit, p))
779 break; 804 break;
780 ppp = ppp_create_interface(unit, &err); 805 ppp = ppp_create_interface(net, unit, &err);
781 if (!ppp) 806 if (!ppp)
782 break; 807 break;
783 file->private_data = &ppp->file; 808 file->private_data = &ppp->file;
@@ -792,29 +817,31 @@ static int ppp_unattached_ioctl(struct ppp_file *pf, struct file *file,
792 /* Attach to an existing ppp unit */ 817 /* Attach to an existing ppp unit */
793 if (get_user(unit, p)) 818 if (get_user(unit, p))
794 break; 819 break;
795 mutex_lock(&all_ppp_mutex);
796 err = -ENXIO; 820 err = -ENXIO;
797 ppp = ppp_find_unit(unit); 821 pn = ppp_pernet(net);
822 mutex_lock(&pn->all_ppp_mutex);
823 ppp = ppp_find_unit(pn, unit);
798 if (ppp) { 824 if (ppp) {
799 atomic_inc(&ppp->file.refcnt); 825 atomic_inc(&ppp->file.refcnt);
800 file->private_data = &ppp->file; 826 file->private_data = &ppp->file;
801 err = 0; 827 err = 0;
802 } 828 }
803 mutex_unlock(&all_ppp_mutex); 829 mutex_unlock(&pn->all_ppp_mutex);
804 break; 830 break;
805 831
806 case PPPIOCATTCHAN: 832 case PPPIOCATTCHAN:
807 if (get_user(unit, p)) 833 if (get_user(unit, p))
808 break; 834 break;
809 spin_lock_bh(&all_channels_lock);
810 err = -ENXIO; 835 err = -ENXIO;
811 chan = ppp_find_channel(unit); 836 pn = ppp_pernet(net);
837 spin_lock_bh(&pn->all_channels_lock);
838 chan = ppp_find_channel(pn, unit);
812 if (chan) { 839 if (chan) {
813 atomic_inc(&chan->file.refcnt); 840 atomic_inc(&chan->file.refcnt);
814 file->private_data = &chan->file; 841 file->private_data = &chan->file;
815 err = 0; 842 err = 0;
816 } 843 }
817 spin_unlock_bh(&all_channels_lock); 844 spin_unlock_bh(&pn->all_channels_lock);
818 break; 845 break;
819 846
820 default: 847 default:
@@ -834,6 +861,51 @@ static const struct file_operations ppp_device_fops = {
834 .release = ppp_release 861 .release = ppp_release
835}; 862};
836 863
864static __net_init int ppp_init_net(struct net *net)
865{
866 struct ppp_net *pn;
867 int err;
868
869 pn = kzalloc(sizeof(*pn), GFP_KERNEL);
870 if (!pn)
871 return -ENOMEM;
872
873 idr_init(&pn->units_idr);
874 mutex_init(&pn->all_ppp_mutex);
875
876 INIT_LIST_HEAD(&pn->all_channels);
877 INIT_LIST_HEAD(&pn->new_channels);
878
879 spin_lock_init(&pn->all_channels_lock);
880
881 err = net_assign_generic(net, ppp_net_id, pn);
882 if (err) {
883 kfree(pn);
884 return err;
885 }
886
887 return 0;
888}
889
890static __net_exit void ppp_exit_net(struct net *net)
891{
892 struct ppp_net *pn;
893
894 pn = net_generic(net, ppp_net_id);
895 idr_destroy(&pn->units_idr);
896 /*
897 * if someone has cached our net then
898 * further net_generic call will return NULL
899 */
900 net_assign_generic(net, ppp_net_id, NULL);
901 kfree(pn);
902}
903
904static __net_initdata struct pernet_operations ppp_net_ops = {
905 .init = ppp_init_net,
906 .exit = ppp_exit_net,
907};
908
837#define PPP_MAJOR 108 909#define PPP_MAJOR 108
838 910
839/* Called at boot time if ppp is compiled into the kernel, 911/* Called at boot time if ppp is compiled into the kernel,
@@ -843,25 +915,36 @@ static int __init ppp_init(void)
843 int err; 915 int err;
844 916
845 printk(KERN_INFO "PPP generic driver version " PPP_VERSION "\n"); 917 printk(KERN_INFO "PPP generic driver version " PPP_VERSION "\n");
846 err = register_chrdev(PPP_MAJOR, "ppp", &ppp_device_fops); 918
847 if (!err) { 919 err = register_pernet_gen_device(&ppp_net_id, &ppp_net_ops);
848 ppp_class = class_create(THIS_MODULE, "ppp"); 920 if (err) {
849 if (IS_ERR(ppp_class)) { 921 printk(KERN_ERR "failed to register PPP pernet device (%d)\n", err);
850 err = PTR_ERR(ppp_class); 922 goto out;
851 goto out_chrdev;
852 }
853 device_create(ppp_class, NULL, MKDEV(PPP_MAJOR, 0), NULL,
854 "ppp");
855 } 923 }
856 924
857out: 925 err = register_chrdev(PPP_MAJOR, "ppp", &ppp_device_fops);
858 if (err) 926 if (err) {
859 printk(KERN_ERR "failed to register PPP device (%d)\n", err); 927 printk(KERN_ERR "failed to register PPP device (%d)\n", err);
860 return err; 928 goto out_net;
929 }
930
931 ppp_class = class_create(THIS_MODULE, "ppp");
932 if (IS_ERR(ppp_class)) {
933 err = PTR_ERR(ppp_class);
934 goto out_chrdev;
935 }
936
937 /* not a big deal if we fail here :-) */
938 device_create(ppp_class, NULL, MKDEV(PPP_MAJOR, 0), NULL, "ppp");
939
940 return 0;
861 941
862out_chrdev: 942out_chrdev:
863 unregister_chrdev(PPP_MAJOR, "ppp"); 943 unregister_chrdev(PPP_MAJOR, "ppp");
864 goto out; 944out_net:
945 unregister_pernet_gen_device(ppp_net_id, &ppp_net_ops);
946out:
947 return err;
865} 948}
866 949
867/* 950/*
@@ -969,6 +1052,7 @@ static void ppp_setup(struct net_device *dev)
969 dev->tx_queue_len = 3; 1052 dev->tx_queue_len = 3;
970 dev->type = ARPHRD_PPP; 1053 dev->type = ARPHRD_PPP;
971 dev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST; 1054 dev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST;
1055 dev->features |= NETIF_F_NETNS_LOCAL;
972} 1056}
973 1057
974/* 1058/*
@@ -1986,19 +2070,27 @@ ppp_mp_reconstruct(struct ppp *ppp)
1986 * Channel interface. 2070 * Channel interface.
1987 */ 2071 */
1988 2072
1989/* 2073/* Create a new, unattached ppp channel. */
1990 * Create a new, unattached ppp channel. 2074int ppp_register_channel(struct ppp_channel *chan)
1991 */ 2075{
1992int 2076 return ppp_register_net_channel(current->nsproxy->net_ns, chan);
1993ppp_register_channel(struct ppp_channel *chan) 2077}
2078
2079/* Create a new, unattached ppp channel for specified net. */
2080int ppp_register_net_channel(struct net *net, struct ppp_channel *chan)
1994{ 2081{
1995 struct channel *pch; 2082 struct channel *pch;
2083 struct ppp_net *pn;
1996 2084
1997 pch = kzalloc(sizeof(struct channel), GFP_KERNEL); 2085 pch = kzalloc(sizeof(struct channel), GFP_KERNEL);
1998 if (!pch) 2086 if (!pch)
1999 return -ENOMEM; 2087 return -ENOMEM;
2088
2089 pn = ppp_pernet(net);
2090
2000 pch->ppp = NULL; 2091 pch->ppp = NULL;
2001 pch->chan = chan; 2092 pch->chan = chan;
2093 pch->chan_net = net;
2002 chan->ppp = pch; 2094 chan->ppp = pch;
2003 init_ppp_file(&pch->file, CHANNEL); 2095 init_ppp_file(&pch->file, CHANNEL);
2004 pch->file.hdrlen = chan->hdrlen; 2096 pch->file.hdrlen = chan->hdrlen;
@@ -2008,11 +2100,13 @@ ppp_register_channel(struct ppp_channel *chan)
2008 init_rwsem(&pch->chan_sem); 2100 init_rwsem(&pch->chan_sem);
2009 spin_lock_init(&pch->downl); 2101 spin_lock_init(&pch->downl);
2010 rwlock_init(&pch->upl); 2102 rwlock_init(&pch->upl);
2011 spin_lock_bh(&all_channels_lock); 2103
2012 pch->file.index = ++last_channel_index; 2104 spin_lock_bh(&pn->all_channels_lock);
2013 list_add(&pch->list, &new_channels); 2105 pch->file.index = ++pn->last_channel_index;
2106 list_add(&pch->list, &pn->new_channels);
2014 atomic_inc(&channel_count); 2107 atomic_inc(&channel_count);
2015 spin_unlock_bh(&all_channels_lock); 2108 spin_unlock_bh(&pn->all_channels_lock);
2109
2016 return 0; 2110 return 0;
2017} 2111}
2018 2112
@@ -2053,9 +2147,11 @@ void
2053ppp_unregister_channel(struct ppp_channel *chan) 2147ppp_unregister_channel(struct ppp_channel *chan)
2054{ 2148{
2055 struct channel *pch = chan->ppp; 2149 struct channel *pch = chan->ppp;
2150 struct ppp_net *pn;
2056 2151
2057 if (!pch) 2152 if (!pch)
2058 return; /* should never happen */ 2153 return; /* should never happen */
2154
2059 chan->ppp = NULL; 2155 chan->ppp = NULL;
2060 2156
2061 /* 2157 /*
@@ -2068,9 +2164,12 @@ ppp_unregister_channel(struct ppp_channel *chan)
2068 spin_unlock_bh(&pch->downl); 2164 spin_unlock_bh(&pch->downl);
2069 up_write(&pch->chan_sem); 2165 up_write(&pch->chan_sem);
2070 ppp_disconnect_channel(pch); 2166 ppp_disconnect_channel(pch);
2071 spin_lock_bh(&all_channels_lock); 2167
2168 pn = ppp_pernet(pch->chan_net);
2169 spin_lock_bh(&pn->all_channels_lock);
2072 list_del(&pch->list); 2170 list_del(&pch->list);
2073 spin_unlock_bh(&all_channels_lock); 2171 spin_unlock_bh(&pn->all_channels_lock);
2172
2074 pch->file.dead = 1; 2173 pch->file.dead = 1;
2075 wake_up_interruptible(&pch->file.rwait); 2174 wake_up_interruptible(&pch->file.rwait);
2076 if (atomic_dec_and_test(&pch->file.refcnt)) 2175 if (atomic_dec_and_test(&pch->file.refcnt))
@@ -2395,9 +2494,10 @@ ppp_get_stats(struct ppp *ppp, struct ppp_stats *st)
2395 * unit == -1 means allocate a new number. 2494 * unit == -1 means allocate a new number.
2396 */ 2495 */
2397static struct ppp * 2496static struct ppp *
2398ppp_create_interface(int unit, int *retp) 2497ppp_create_interface(struct net *net, int unit, int *retp)
2399{ 2498{
2400 struct ppp *ppp; 2499 struct ppp *ppp;
2500 struct ppp_net *pn;
2401 struct net_device *dev = NULL; 2501 struct net_device *dev = NULL;
2402 int ret = -ENOMEM; 2502 int ret = -ENOMEM;
2403 int i; 2503 int i;
@@ -2406,6 +2506,8 @@ ppp_create_interface(int unit, int *retp)
2406 if (!dev) 2506 if (!dev)
2407 goto out1; 2507 goto out1;
2408 2508
2509 pn = ppp_pernet(net);
2510
2409 ppp = netdev_priv(dev); 2511 ppp = netdev_priv(dev);
2410 ppp->dev = dev; 2512 ppp->dev = dev;
2411 ppp->mru = PPP_MRU; 2513 ppp->mru = PPP_MRU;
@@ -2421,17 +2523,23 @@ ppp_create_interface(int unit, int *retp)
2421 skb_queue_head_init(&ppp->mrq); 2523 skb_queue_head_init(&ppp->mrq);
2422#endif /* CONFIG_PPP_MULTILINK */ 2524#endif /* CONFIG_PPP_MULTILINK */
2423 2525
2526 /*
2527 * drum roll: don't forget to set
2528 * the net device is belong to
2529 */
2530 dev_net_set(dev, net);
2531
2424 ret = -EEXIST; 2532 ret = -EEXIST;
2425 mutex_lock(&all_ppp_mutex); 2533 mutex_lock(&pn->all_ppp_mutex);
2426 2534
2427 if (unit < 0) { 2535 if (unit < 0) {
2428 unit = unit_get(&ppp_units_idr, ppp); 2536 unit = unit_get(&pn->units_idr, ppp);
2429 if (unit < 0) { 2537 if (unit < 0) {
2430 *retp = unit; 2538 *retp = unit;
2431 goto out2; 2539 goto out2;
2432 } 2540 }
2433 } else { 2541 } else {
2434 if (unit_find(&ppp_units_idr, unit)) 2542 if (unit_find(&pn->units_idr, unit))
2435 goto out2; /* unit already exists */ 2543 goto out2; /* unit already exists */
2436 /* 2544 /*
2437 * if caller need a specified unit number 2545 * if caller need a specified unit number
@@ -2442,7 +2550,7 @@ ppp_create_interface(int unit, int *retp)
2442 * fair but at least pppd will ask us to allocate 2550 * fair but at least pppd will ask us to allocate
2443 * new unit in this case so user is happy :) 2551 * new unit in this case so user is happy :)
2444 */ 2552 */
2445 unit = unit_set(&ppp_units_idr, ppp, unit); 2553 unit = unit_set(&pn->units_idr, ppp, unit);
2446 if (unit < 0) 2554 if (unit < 0)
2447 goto out2; 2555 goto out2;
2448 } 2556 }
@@ -2453,20 +2561,22 @@ ppp_create_interface(int unit, int *retp)
2453 2561
2454 ret = register_netdev(dev); 2562 ret = register_netdev(dev);
2455 if (ret != 0) { 2563 if (ret != 0) {
2456 unit_put(&ppp_units_idr, unit); 2564 unit_put(&pn->units_idr, unit);
2457 printk(KERN_ERR "PPP: couldn't register device %s (%d)\n", 2565 printk(KERN_ERR "PPP: couldn't register device %s (%d)\n",
2458 dev->name, ret); 2566 dev->name, ret);
2459 goto out2; 2567 goto out2;
2460 } 2568 }
2461 2569
2570 ppp->ppp_net = net;
2571
2462 atomic_inc(&ppp_unit_count); 2572 atomic_inc(&ppp_unit_count);
2463 mutex_unlock(&all_ppp_mutex); 2573 mutex_unlock(&pn->all_ppp_mutex);
2464 2574
2465 *retp = 0; 2575 *retp = 0;
2466 return ppp; 2576 return ppp;
2467 2577
2468out2: 2578out2:
2469 mutex_unlock(&all_ppp_mutex); 2579 mutex_unlock(&pn->all_ppp_mutex);
2470 free_netdev(dev); 2580 free_netdev(dev);
2471out1: 2581out1:
2472 *retp = ret; 2582 *retp = ret;
@@ -2492,7 +2602,11 @@ init_ppp_file(struct ppp_file *pf, int kind)
2492 */ 2602 */
2493static void ppp_shutdown_interface(struct ppp *ppp) 2603static void ppp_shutdown_interface(struct ppp *ppp)
2494{ 2604{
2495 mutex_lock(&all_ppp_mutex); 2605 struct ppp_net *pn;
2606
2607 pn = ppp_pernet(ppp->ppp_net);
2608 mutex_lock(&pn->all_ppp_mutex);
2609
2496 /* This will call dev_close() for us. */ 2610 /* This will call dev_close() for us. */
2497 ppp_lock(ppp); 2611 ppp_lock(ppp);
2498 if (!ppp->closing) { 2612 if (!ppp->closing) {
@@ -2502,11 +2616,12 @@ static void ppp_shutdown_interface(struct ppp *ppp)
2502 } else 2616 } else
2503 ppp_unlock(ppp); 2617 ppp_unlock(ppp);
2504 2618
2505 unit_put(&ppp_units_idr, ppp->file.index); 2619 unit_put(&pn->units_idr, ppp->file.index);
2506 ppp->file.dead = 1; 2620 ppp->file.dead = 1;
2507 ppp->owner = NULL; 2621 ppp->owner = NULL;
2508 wake_up_interruptible(&ppp->file.rwait); 2622 wake_up_interruptible(&ppp->file.rwait);
2509 mutex_unlock(&all_ppp_mutex); 2623
2624 mutex_unlock(&pn->all_ppp_mutex);
2510} 2625}
2511 2626
2512/* 2627/*
@@ -2554,9 +2669,9 @@ static void ppp_destroy_interface(struct ppp *ppp)
2554 * The caller should have locked the all_ppp_mutex. 2669 * The caller should have locked the all_ppp_mutex.
2555 */ 2670 */
2556static struct ppp * 2671static struct ppp *
2557ppp_find_unit(int unit) 2672ppp_find_unit(struct ppp_net *pn, int unit)
2558{ 2673{
2559 return unit_find(&ppp_units_idr, unit); 2674 return unit_find(&pn->units_idr, unit);
2560} 2675}
2561 2676
2562/* 2677/*
@@ -2568,20 +2683,22 @@ ppp_find_unit(int unit)
2568 * when we have a lot of channels in use. 2683 * when we have a lot of channels in use.
2569 */ 2684 */
2570static struct channel * 2685static struct channel *
2571ppp_find_channel(int unit) 2686ppp_find_channel(struct ppp_net *pn, int unit)
2572{ 2687{
2573 struct channel *pch; 2688 struct channel *pch;
2574 2689
2575 list_for_each_entry(pch, &new_channels, list) { 2690 list_for_each_entry(pch, &pn->new_channels, list) {
2576 if (pch->file.index == unit) { 2691 if (pch->file.index == unit) {
2577 list_move(&pch->list, &all_channels); 2692 list_move(&pch->list, &pn->all_channels);
2578 return pch; 2693 return pch;
2579 } 2694 }
2580 } 2695 }
2581 list_for_each_entry(pch, &all_channels, list) { 2696
2697 list_for_each_entry(pch, &pn->all_channels, list) {
2582 if (pch->file.index == unit) 2698 if (pch->file.index == unit)
2583 return pch; 2699 return pch;
2584 } 2700 }
2701
2585 return NULL; 2702 return NULL;
2586} 2703}
2587 2704
@@ -2592,11 +2709,14 @@ static int
2592ppp_connect_channel(struct channel *pch, int unit) 2709ppp_connect_channel(struct channel *pch, int unit)
2593{ 2710{
2594 struct ppp *ppp; 2711 struct ppp *ppp;
2712 struct ppp_net *pn;
2595 int ret = -ENXIO; 2713 int ret = -ENXIO;
2596 int hdrlen; 2714 int hdrlen;
2597 2715
2598 mutex_lock(&all_ppp_mutex); 2716 pn = ppp_pernet(pch->chan_net);
2599 ppp = ppp_find_unit(unit); 2717
2718 mutex_lock(&pn->all_ppp_mutex);
2719 ppp = ppp_find_unit(pn, unit);
2600 if (!ppp) 2720 if (!ppp)
2601 goto out; 2721 goto out;
2602 write_lock_bh(&pch->upl); 2722 write_lock_bh(&pch->upl);
@@ -2620,7 +2740,7 @@ ppp_connect_channel(struct channel *pch, int unit)
2620 outl: 2740 outl:
2621 write_unlock_bh(&pch->upl); 2741 write_unlock_bh(&pch->upl);
2622 out: 2742 out:
2623 mutex_unlock(&all_ppp_mutex); 2743 mutex_unlock(&pn->all_ppp_mutex);
2624 return ret; 2744 return ret;
2625} 2745}
2626 2746
@@ -2677,7 +2797,7 @@ static void __exit ppp_cleanup(void)
2677 unregister_chrdev(PPP_MAJOR, "ppp"); 2797 unregister_chrdev(PPP_MAJOR, "ppp");
2678 device_destroy(ppp_class, MKDEV(PPP_MAJOR, 0)); 2798 device_destroy(ppp_class, MKDEV(PPP_MAJOR, 0));
2679 class_destroy(ppp_class); 2799 class_destroy(ppp_class);
2680 idr_destroy(&ppp_units_idr); 2800 unregister_pernet_gen_device(ppp_net_id, &ppp_net_ops);
2681} 2801}
2682 2802
2683/* 2803/*
@@ -2743,6 +2863,7 @@ static void *unit_find(struct idr *p, int n)
2743module_init(ppp_init); 2863module_init(ppp_init);
2744module_exit(ppp_cleanup); 2864module_exit(ppp_cleanup);
2745 2865
2866EXPORT_SYMBOL(ppp_register_net_channel);
2746EXPORT_SYMBOL(ppp_register_channel); 2867EXPORT_SYMBOL(ppp_register_channel);
2747EXPORT_SYMBOL(ppp_unregister_channel); 2868EXPORT_SYMBOL(ppp_unregister_channel);
2748EXPORT_SYMBOL(ppp_channel_index); 2869EXPORT_SYMBOL(ppp_channel_index);
diff --git a/include/linux/ppp_channel.h b/include/linux/ppp_channel.h
index a942892d6dfe..9d64bdf14770 100644
--- a/include/linux/ppp_channel.h
+++ b/include/linux/ppp_channel.h
@@ -22,6 +22,7 @@
22#include <linux/list.h> 22#include <linux/list.h>
23#include <linux/skbuff.h> 23#include <linux/skbuff.h>
24#include <linux/poll.h> 24#include <linux/poll.h>
25#include <net/net_namespace.h>
25 26
26struct ppp_channel; 27struct ppp_channel;
27 28
@@ -56,6 +57,9 @@ extern void ppp_input(struct ppp_channel *, struct sk_buff *);
56 that we may have missed a packet. */ 57 that we may have missed a packet. */
57extern void ppp_input_error(struct ppp_channel *, int code); 58extern void ppp_input_error(struct ppp_channel *, int code);
58 59
60/* Attach a channel to a given PPP unit in specified net. */
61extern int ppp_register_net_channel(struct net *, struct ppp_channel *);
62
59/* Attach a channel to a given PPP unit. */ 63/* Attach a channel to a given PPP unit. */
60extern int ppp_register_channel(struct ppp_channel *); 64extern int ppp_register_channel(struct ppp_channel *);
61 65