aboutsummaryrefslogtreecommitdiffstats
path: root/net/8021q
diff options
context:
space:
mode:
Diffstat (limited to 'net/8021q')
-rw-r--r--net/8021q/vlan.c147
-rw-r--r--net/8021q/vlan.h15
-rw-r--r--net/8021q/vlan_dev.c15
-rw-r--r--net/8021q/vlan_netlink.c2
-rw-r--r--net/8021q/vlanproc.c70
-rw-r--r--net/8021q/vlanproc.h10
6 files changed, 166 insertions, 93 deletions
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
index b33410abfd6b..2a739adaa92b 100644
--- a/net/8021q/vlan.c
+++ b/net/8021q/vlan.c
@@ -32,6 +32,7 @@
32#include <linux/rtnetlink.h> 32#include <linux/rtnetlink.h>
33#include <linux/notifier.h> 33#include <linux/notifier.h>
34#include <net/net_namespace.h> 34#include <net/net_namespace.h>
35#include <net/netns/generic.h>
35 36
36#include <linux/if_vlan.h> 37#include <linux/if_vlan.h>
37#include "vlan.h" 38#include "vlan.h"
@@ -41,6 +42,8 @@
41 42
42/* Global VLAN variables */ 43/* Global VLAN variables */
43 44
45int vlan_net_id;
46
44/* Our listing of VLAN group(s) */ 47/* Our listing of VLAN group(s) */
45static struct hlist_head vlan_group_hash[VLAN_GRP_HASH_SIZE]; 48static struct hlist_head vlan_group_hash[VLAN_GRP_HASH_SIZE];
46 49
@@ -49,9 +52,6 @@ static char vlan_version[] = DRV_VERSION;
49static char vlan_copyright[] = "Ben Greear <greearb@candelatech.com>"; 52static char vlan_copyright[] = "Ben Greear <greearb@candelatech.com>";
50static char vlan_buggyright[] = "David S. Miller <davem@redhat.com>"; 53static char vlan_buggyright[] = "David S. Miller <davem@redhat.com>";
51 54
52/* Determines interface naming scheme. */
53unsigned short vlan_name_type = VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD;
54
55static struct packet_type vlan_packet_type = { 55static struct packet_type vlan_packet_type = {
56 .type = __constant_htons(ETH_P_8021Q), 56 .type = __constant_htons(ETH_P_8021Q),
57 .func = vlan_skb_recv, /* VLAN receive method */ 57 .func = vlan_skb_recv, /* VLAN receive method */
@@ -65,14 +65,14 @@ static inline unsigned int vlan_grp_hashfn(unsigned int idx)
65} 65}
66 66
67/* Must be invoked with RCU read lock (no preempt) */ 67/* Must be invoked with RCU read lock (no preempt) */
68static struct vlan_group *__vlan_find_group(int real_dev_ifindex) 68static struct vlan_group *__vlan_find_group(struct net_device *real_dev)
69{ 69{
70 struct vlan_group *grp; 70 struct vlan_group *grp;
71 struct hlist_node *n; 71 struct hlist_node *n;
72 int hash = vlan_grp_hashfn(real_dev_ifindex); 72 int hash = vlan_grp_hashfn(real_dev->ifindex);
73 73
74 hlist_for_each_entry_rcu(grp, n, &vlan_group_hash[hash], hlist) { 74 hlist_for_each_entry_rcu(grp, n, &vlan_group_hash[hash], hlist) {
75 if (grp->real_dev_ifindex == real_dev_ifindex) 75 if (grp->real_dev == real_dev)
76 return grp; 76 return grp;
77 } 77 }
78 78
@@ -86,7 +86,7 @@ static struct vlan_group *__vlan_find_group(int real_dev_ifindex)
86struct net_device *__find_vlan_dev(struct net_device *real_dev, 86struct net_device *__find_vlan_dev(struct net_device *real_dev,
87 unsigned short VID) 87 unsigned short VID)
88{ 88{
89 struct vlan_group *grp = __vlan_find_group(real_dev->ifindex); 89 struct vlan_group *grp = __vlan_find_group(real_dev);
90 90
91 if (grp) 91 if (grp)
92 return vlan_group_get_device(grp, VID); 92 return vlan_group_get_device(grp, VID);
@@ -103,32 +103,38 @@ static void vlan_group_free(struct vlan_group *grp)
103 kfree(grp); 103 kfree(grp);
104} 104}
105 105
106static struct vlan_group *vlan_group_alloc(int ifindex) 106static struct vlan_group *vlan_group_alloc(struct net_device *real_dev)
107{ 107{
108 struct vlan_group *grp; 108 struct vlan_group *grp;
109 unsigned int size;
110 unsigned int i;
111 109
112 grp = kzalloc(sizeof(struct vlan_group), GFP_KERNEL); 110 grp = kzalloc(sizeof(struct vlan_group), GFP_KERNEL);
113 if (!grp) 111 if (!grp)
114 return NULL; 112 return NULL;
115 113
116 size = sizeof(struct net_device *) * VLAN_GROUP_ARRAY_PART_LEN; 114 grp->real_dev = real_dev;
117
118 for (i = 0; i < VLAN_GROUP_ARRAY_SPLIT_PARTS; i++) {
119 grp->vlan_devices_arrays[i] = kzalloc(size, GFP_KERNEL);
120 if (!grp->vlan_devices_arrays[i])
121 goto err;
122 }
123
124 grp->real_dev_ifindex = ifindex;
125 hlist_add_head_rcu(&grp->hlist, 115 hlist_add_head_rcu(&grp->hlist,
126 &vlan_group_hash[vlan_grp_hashfn(ifindex)]); 116 &vlan_group_hash[vlan_grp_hashfn(real_dev->ifindex)]);
127 return grp; 117 return grp;
118}
128 119
129err: 120static int vlan_group_prealloc_vid(struct vlan_group *vg, int vid)
130 vlan_group_free(grp); 121{
131 return NULL; 122 struct net_device **array;
123 unsigned int size;
124
125 ASSERT_RTNL();
126
127 array = vg->vlan_devices_arrays[vid / VLAN_GROUP_ARRAY_PART_LEN];
128 if (array != NULL)
129 return 0;
130
131 size = sizeof(struct net_device *) * VLAN_GROUP_ARRAY_PART_LEN;
132 array = kzalloc(size, GFP_KERNEL);
133 if (array == NULL)
134 return -ENOBUFS;
135
136 vg->vlan_devices_arrays[vid / VLAN_GROUP_ARRAY_PART_LEN] = array;
137 return 0;
132} 138}
133 139
134static void vlan_rcu_free(struct rcu_head *rcu) 140static void vlan_rcu_free(struct rcu_head *rcu)
@@ -145,11 +151,9 @@ void unregister_vlan_dev(struct net_device *dev)
145 151
146 ASSERT_RTNL(); 152 ASSERT_RTNL();
147 153
148 grp = __vlan_find_group(real_dev->ifindex); 154 grp = __vlan_find_group(real_dev);
149 BUG_ON(!grp); 155 BUG_ON(!grp);
150 156
151 vlan_proc_rem_dev(dev);
152
153 /* Take it out of our own structures, but be sure to interlock with 157 /* Take it out of our own structures, but be sure to interlock with
154 * HW accelerating devices or SW vlan input packet processing. 158 * HW accelerating devices or SW vlan input packet processing.
155 */ 159 */
@@ -240,13 +244,17 @@ int register_vlan_dev(struct net_device *dev)
240 struct vlan_group *grp, *ngrp = NULL; 244 struct vlan_group *grp, *ngrp = NULL;
241 int err; 245 int err;
242 246
243 grp = __vlan_find_group(real_dev->ifindex); 247 grp = __vlan_find_group(real_dev);
244 if (!grp) { 248 if (!grp) {
245 ngrp = grp = vlan_group_alloc(real_dev->ifindex); 249 ngrp = grp = vlan_group_alloc(real_dev);
246 if (!grp) 250 if (!grp)
247 return -ENOBUFS; 251 return -ENOBUFS;
248 } 252 }
249 253
254 err = vlan_group_prealloc_vid(grp, vlan_id);
255 if (err < 0)
256 goto out_free_group;
257
250 err = register_netdevice(dev); 258 err = register_netdevice(dev);
251 if (err < 0) 259 if (err < 0)
252 goto out_free_group; 260 goto out_free_group;
@@ -268,9 +276,6 @@ int register_vlan_dev(struct net_device *dev)
268 if (real_dev->features & NETIF_F_HW_VLAN_FILTER) 276 if (real_dev->features & NETIF_F_HW_VLAN_FILTER)
269 real_dev->vlan_rx_add_vid(real_dev, vlan_id); 277 real_dev->vlan_rx_add_vid(real_dev, vlan_id);
270 278
271 if (vlan_proc_add_dev(dev) < 0)
272 pr_warning("8021q: failed to add proc entry for %s\n",
273 dev->name);
274 return 0; 279 return 0;
275 280
276out_free_group: 281out_free_group:
@@ -286,6 +291,8 @@ static int register_vlan_device(struct net_device *real_dev,
286 unsigned short VLAN_ID) 291 unsigned short VLAN_ID)
287{ 292{
288 struct net_device *new_dev; 293 struct net_device *new_dev;
294 struct net *net = dev_net(real_dev);
295 struct vlan_net *vn = net_generic(net, vlan_net_id);
289 char name[IFNAMSIZ]; 296 char name[IFNAMSIZ];
290 int err; 297 int err;
291 298
@@ -297,7 +304,7 @@ static int register_vlan_device(struct net_device *real_dev,
297 return err; 304 return err;
298 305
299 /* Gotta set up the fields for the device. */ 306 /* Gotta set up the fields for the device. */
300 switch (vlan_name_type) { 307 switch (vn->name_type) {
301 case VLAN_NAME_TYPE_RAW_PLUS_VID: 308 case VLAN_NAME_TYPE_RAW_PLUS_VID:
302 /* name will look like: eth1.0005 */ 309 /* name will look like: eth1.0005 */
303 snprintf(name, IFNAMSIZ, "%s.%.4i", real_dev->name, VLAN_ID); 310 snprintf(name, IFNAMSIZ, "%s.%.4i", real_dev->name, VLAN_ID);
@@ -328,6 +335,7 @@ static int register_vlan_device(struct net_device *real_dev,
328 if (new_dev == NULL) 335 if (new_dev == NULL)
329 return -ENOBUFS; 336 return -ENOBUFS;
330 337
338 dev_net_set(new_dev, net);
331 /* need 4 bytes for extra VLAN header info, 339 /* need 4 bytes for extra VLAN header info,
332 * hope the underlying device can handle it. 340 * hope the underlying device can handle it.
333 */ 341 */
@@ -383,6 +391,14 @@ static void __vlan_device_event(struct net_device *dev, unsigned long event)
383 pr_warning("8021q: failed to change proc name for %s\n", 391 pr_warning("8021q: failed to change proc name for %s\n",
384 dev->name); 392 dev->name);
385 break; 393 break;
394 case NETDEV_REGISTER:
395 if (vlan_proc_add_dev(dev) < 0)
396 pr_warning("8021q: failed to add proc entry for %s\n",
397 dev->name);
398 break;
399 case NETDEV_UNREGISTER:
400 vlan_proc_rem_dev(dev);
401 break;
386 } 402 }
387} 403}
388 404
@@ -394,15 +410,12 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
394 int i, flgs; 410 int i, flgs;
395 struct net_device *vlandev; 411 struct net_device *vlandev;
396 412
397 if (dev->nd_net != &init_net)
398 return NOTIFY_DONE;
399
400 if (is_vlan_dev(dev)) { 413 if (is_vlan_dev(dev)) {
401 __vlan_device_event(dev, event); 414 __vlan_device_event(dev, event);
402 goto out; 415 goto out;
403 } 416 }
404 417
405 grp = __vlan_find_group(dev->ifindex); 418 grp = __vlan_find_group(dev);
406 if (!grp) 419 if (!grp)
407 goto out; 420 goto out;
408 421
@@ -522,7 +535,7 @@ static int vlan_ioctl_handler(struct net *net, void __user *arg)
522 case GET_VLAN_REALDEV_NAME_CMD: 535 case GET_VLAN_REALDEV_NAME_CMD:
523 case GET_VLAN_VID_CMD: 536 case GET_VLAN_VID_CMD:
524 err = -ENODEV; 537 err = -ENODEV;
525 dev = __dev_get_by_name(&init_net, args.device1); 538 dev = __dev_get_by_name(net, args.device1);
526 if (!dev) 539 if (!dev)
527 goto out; 540 goto out;
528 541
@@ -567,7 +580,10 @@ static int vlan_ioctl_handler(struct net *net, void __user *arg)
567 break; 580 break;
568 if ((args.u.name_type >= 0) && 581 if ((args.u.name_type >= 0) &&
569 (args.u.name_type < VLAN_NAME_TYPE_HIGHEST)) { 582 (args.u.name_type < VLAN_NAME_TYPE_HIGHEST)) {
570 vlan_name_type = args.u.name_type; 583 struct vlan_net *vn;
584
585 vn = net_generic(net, vlan_net_id);
586 vn->name_type = args.u.name_type;
571 err = 0; 587 err = 0;
572 } else { 588 } else {
573 err = -EINVAL; 589 err = -EINVAL;
@@ -615,6 +631,51 @@ out:
615 return err; 631 return err;
616} 632}
617 633
634static int vlan_init_net(struct net *net)
635{
636 int err;
637 struct vlan_net *vn;
638
639 err = -ENOMEM;
640 vn = kzalloc(sizeof(struct vlan_net), GFP_KERNEL);
641 if (vn == NULL)
642 goto err_alloc;
643
644 err = net_assign_generic(net, vlan_net_id, vn);
645 if (err < 0)
646 goto err_assign;
647
648 vn->name_type = VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD;
649
650 err = vlan_proc_init(net);
651 if (err < 0)
652 goto err_proc;
653
654 return 0;
655
656err_proc:
657 /* nothing */
658err_assign:
659 kfree(vn);
660err_alloc:
661 return err;
662}
663
664static void vlan_exit_net(struct net *net)
665{
666 struct vlan_net *vn;
667
668 vn = net_generic(net, vlan_net_id);
669 rtnl_kill_links(net, &vlan_link_ops);
670 vlan_proc_cleanup(net);
671 kfree(vn);
672}
673
674static struct pernet_operations vlan_net_ops = {
675 .init = vlan_init_net,
676 .exit = vlan_exit_net,
677};
678
618static int __init vlan_proto_init(void) 679static int __init vlan_proto_init(void)
619{ 680{
620 int err; 681 int err;
@@ -622,9 +683,9 @@ static int __init vlan_proto_init(void)
622 pr_info("%s v%s %s\n", vlan_fullname, vlan_version, vlan_copyright); 683 pr_info("%s v%s %s\n", vlan_fullname, vlan_version, vlan_copyright);
623 pr_info("All bugs added by %s\n", vlan_buggyright); 684 pr_info("All bugs added by %s\n", vlan_buggyright);
624 685
625 err = vlan_proc_init(); 686 err = register_pernet_gen_device(&vlan_net_id, &vlan_net_ops);
626 if (err < 0) 687 if (err < 0)
627 goto err1; 688 goto err0;
628 689
629 err = register_netdevice_notifier(&vlan_notifier_block); 690 err = register_netdevice_notifier(&vlan_notifier_block);
630 if (err < 0) 691 if (err < 0)
@@ -641,8 +702,8 @@ static int __init vlan_proto_init(void)
641err3: 702err3:
642 unregister_netdevice_notifier(&vlan_notifier_block); 703 unregister_netdevice_notifier(&vlan_notifier_block);
643err2: 704err2:
644 vlan_proc_cleanup(); 705 unregister_pernet_gen_device(vlan_net_id, &vlan_net_ops);
645err1: 706err0:
646 return err; 707 return err;
647} 708}
648 709
@@ -661,7 +722,7 @@ static void __exit vlan_cleanup_module(void)
661 for (i = 0; i < VLAN_GRP_HASH_SIZE; i++) 722 for (i = 0; i < VLAN_GRP_HASH_SIZE; i++)
662 BUG_ON(!hlist_empty(&vlan_group_hash[i])); 723 BUG_ON(!hlist_empty(&vlan_group_hash[i]));
663 724
664 vlan_proc_cleanup(); 725 unregister_pernet_gen_device(vlan_net_id, &vlan_net_ops);
665 726
666 synchronize_net(); 727 synchronize_net();
667} 728}
diff --git a/net/8021q/vlan.h b/net/8021q/vlan.h
index 51271aea402b..5229a72c7ea1 100644
--- a/net/8021q/vlan.h
+++ b/net/8021q/vlan.h
@@ -3,8 +3,6 @@
3 3
4#include <linux/if_vlan.h> 4#include <linux/if_vlan.h>
5 5
6extern unsigned short vlan_name_type;
7
8#define VLAN_GRP_HASH_SHIFT 5 6#define VLAN_GRP_HASH_SHIFT 5
9#define VLAN_GRP_HASH_SIZE (1 << VLAN_GRP_HASH_SHIFT) 7#define VLAN_GRP_HASH_SIZE (1 << VLAN_GRP_HASH_SHIFT)
10#define VLAN_GRP_HASH_MASK (VLAN_GRP_HASH_SIZE - 1) 8#define VLAN_GRP_HASH_MASK (VLAN_GRP_HASH_SIZE - 1)
@@ -50,4 +48,17 @@ static inline int is_vlan_dev(struct net_device *dev)
50 return dev->priv_flags & IFF_802_1Q_VLAN; 48 return dev->priv_flags & IFF_802_1Q_VLAN;
51} 49}
52 50
51extern int vlan_net_id;
52
53struct proc_dir_entry;
54
55struct vlan_net {
56 /* /proc/net/vlan */
57 struct proc_dir_entry *proc_vlan_dir;
58 /* /proc/net/vlan/config */
59 struct proc_dir_entry *proc_vlan_conf;
60 /* Determines interface naming scheme. */
61 unsigned short name_type;
62};
63
53#endif /* !(__BEN_VLAN_802_1Q_INC__) */ 64#endif /* !(__BEN_VLAN_802_1Q_INC__) */
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index 41a76a05e6fd..c961f0826005 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -153,9 +153,6 @@ int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev,
153 struct net_device_stats *stats; 153 struct net_device_stats *stats;
154 unsigned short vlan_TCI; 154 unsigned short vlan_TCI;
155 155
156 if (dev->nd_net != &init_net)
157 goto err_free;
158
159 skb = skb_share_check(skb, GFP_ATOMIC); 156 skb = skb_share_check(skb, GFP_ATOMIC);
160 if (skb == NULL) 157 if (skb == NULL)
161 goto err_free; 158 goto err_free;
@@ -171,7 +168,7 @@ int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev,
171 skb->dev = __find_vlan_dev(dev, vid); 168 skb->dev = __find_vlan_dev(dev, vid);
172 if (!skb->dev) { 169 if (!skb->dev) {
173 pr_debug("%s: ERROR: No net_device for VID: %u on dev: %s\n", 170 pr_debug("%s: ERROR: No net_device for VID: %u on dev: %s\n",
174 __FUNCTION__, (unsigned int)vid, dev->name); 171 __func__, (unsigned int)vid, dev->name);
175 goto err_unlock; 172 goto err_unlock;
176 } 173 }
177 174
@@ -187,7 +184,7 @@ int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev,
187 ntohs(vhdr->h_vlan_TCI)); 184 ntohs(vhdr->h_vlan_TCI));
188 185
189 pr_debug("%s: priority: %u for TCI: %hu\n", 186 pr_debug("%s: priority: %u for TCI: %hu\n",
190 __FUNCTION__, skb->priority, ntohs(vhdr->h_vlan_TCI)); 187 __func__, skb->priority, ntohs(vhdr->h_vlan_TCI));
191 188
192 switch (skb->pkt_type) { 189 switch (skb->pkt_type) {
193 case PACKET_BROADCAST: /* Yeah, stats collect these together.. */ 190 case PACKET_BROADCAST: /* Yeah, stats collect these together.. */
@@ -268,7 +265,7 @@ static int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev,
268 struct net_device *vdev = dev; 265 struct net_device *vdev = dev;
269 266
270 pr_debug("%s: skb: %p type: %hx len: %u vlan_id: %hx, daddr: %p\n", 267 pr_debug("%s: skb: %p type: %hx len: %u vlan_id: %hx, daddr: %p\n",
271 __FUNCTION__, skb, type, len, vlan_dev_info(dev)->vlan_id, 268 __func__, skb, type, len, vlan_dev_info(dev)->vlan_id,
272 daddr); 269 daddr);
273 270
274 /* build vlan header only if re_order_header flag is NOT set. This 271 /* build vlan header only if re_order_header flag is NOT set. This
@@ -340,7 +337,7 @@ static int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev,
340 return -ENOMEM; 337 return -ENOMEM;
341 } 338 }
342 vlan_dev_info(vdev)->cnt_inc_headroom_on_tx++; 339 vlan_dev_info(vdev)->cnt_inc_headroom_on_tx++;
343 pr_debug("%s: %s: had to grow skb\n", __FUNCTION__, vdev->name); 340 pr_debug("%s: %s: had to grow skb\n", __func__, vdev->name);
344 } 341 }
345 342
346 if (build_vlan_header) { 343 if (build_vlan_header) {
@@ -382,7 +379,7 @@ static int vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
382 vlan_dev_info(dev)->cnt_encap_on_xmit++; 379 vlan_dev_info(dev)->cnt_encap_on_xmit++;
383 380
384 pr_debug("%s: proto to encap: 0x%hx\n", 381 pr_debug("%s: proto to encap: 0x%hx\n",
385 __FUNCTION__, ntohs(veth->h_vlan_proto)); 382 __func__, ntohs(veth->h_vlan_proto));
386 /* Construct the second two bytes. This field looks something 383 /* Construct the second two bytes. This field looks something
387 * like: 384 * like:
388 * usr_priority: 3 bits (high bits) 385 * usr_priority: 3 bits (high bits)
@@ -403,7 +400,7 @@ static int vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
403 } 400 }
404 401
405 pr_debug("%s: about to send skb: %p to dev: %s\n", 402 pr_debug("%s: about to send skb: %p to dev: %s\n",
406 __FUNCTION__, skb, skb->dev->name); 403 __func__, skb, skb->dev->name);
407 pr_debug(" " MAC_FMT " " MAC_FMT " %4hx %4hx %4hx\n", 404 pr_debug(" " MAC_FMT " " MAC_FMT " %4hx %4hx %4hx\n",
408 veth->h_dest[0], veth->h_dest[1], veth->h_dest[2], 405 veth->h_dest[0], veth->h_dest[1], veth->h_dest[2],
409 veth->h_dest[3], veth->h_dest[4], veth->h_dest[5], 406 veth->h_dest[3], veth->h_dest[4], veth->h_dest[5],
diff --git a/net/8021q/vlan_netlink.c b/net/8021q/vlan_netlink.c
index e32eeb37987e..c93e69ec28ed 100644
--- a/net/8021q/vlan_netlink.c
+++ b/net/8021q/vlan_netlink.c
@@ -113,7 +113,7 @@ static int vlan_newlink(struct net_device *dev,
113 113
114 if (!tb[IFLA_LINK]) 114 if (!tb[IFLA_LINK])
115 return -EINVAL; 115 return -EINVAL;
116 real_dev = __dev_get_by_index(&init_net, nla_get_u32(tb[IFLA_LINK])); 116 real_dev = __dev_get_by_index(dev_net(dev), nla_get_u32(tb[IFLA_LINK]));
117 if (!real_dev) 117 if (!real_dev)
118 return -ENODEV; 118 return -ENODEV;
119 119
diff --git a/net/8021q/vlanproc.c b/net/8021q/vlanproc.c
index 9671aa51af2c..daad0064e2c2 100644
--- a/net/8021q/vlanproc.c
+++ b/net/8021q/vlanproc.c
@@ -34,6 +34,7 @@
34#include <linux/netdevice.h> 34#include <linux/netdevice.h>
35#include <linux/if_vlan.h> 35#include <linux/if_vlan.h>
36#include <net/net_namespace.h> 36#include <net/net_namespace.h>
37#include <net/netns/generic.h>
37#include "vlanproc.h" 38#include "vlanproc.h"
38#include "vlan.h" 39#include "vlan.h"
39 40
@@ -79,7 +80,8 @@ static const struct seq_operations vlan_seq_ops = {
79 80
80static int vlan_seq_open(struct inode *inode, struct file *file) 81static int vlan_seq_open(struct inode *inode, struct file *file)
81{ 82{
82 return seq_open(file, &vlan_seq_ops); 83 return seq_open_net(inode, file, &vlan_seq_ops,
84 sizeof(struct seq_net_private));
83} 85}
84 86
85static const struct file_operations vlan_fops = { 87static const struct file_operations vlan_fops = {
@@ -87,7 +89,7 @@ static const struct file_operations vlan_fops = {
87 .open = vlan_seq_open, 89 .open = vlan_seq_open,
88 .read = seq_read, 90 .read = seq_read,
89 .llseek = seq_lseek, 91 .llseek = seq_lseek,
90 .release = seq_release, 92 .release = seq_release_net,
91}; 93};
92 94
93/* 95/*
@@ -111,18 +113,6 @@ static const struct file_operations vlandev_fops = {
111 * Proc filesystem derectory entries. 113 * Proc filesystem derectory entries.
112 */ 114 */
113 115
114/*
115 * /proc/net/vlan
116 */
117
118static struct proc_dir_entry *proc_vlan_dir;
119
120/*
121 * /proc/net/vlan/config
122 */
123
124static struct proc_dir_entry *proc_vlan_conf;
125
126/* Strings */ 116/* Strings */
127static const char *vlan_name_type_str[VLAN_NAME_TYPE_HIGHEST] = { 117static const char *vlan_name_type_str[VLAN_NAME_TYPE_HIGHEST] = {
128 [VLAN_NAME_TYPE_RAW_PLUS_VID] = "VLAN_NAME_TYPE_RAW_PLUS_VID", 118 [VLAN_NAME_TYPE_RAW_PLUS_VID] = "VLAN_NAME_TYPE_RAW_PLUS_VID",
@@ -138,13 +128,15 @@ static const char *vlan_name_type_str[VLAN_NAME_TYPE_HIGHEST] = {
138 * Clean up /proc/net/vlan entries 128 * Clean up /proc/net/vlan entries
139 */ 129 */
140 130
141void vlan_proc_cleanup(void) 131void vlan_proc_cleanup(struct net *net)
142{ 132{
143 if (proc_vlan_conf) 133 struct vlan_net *vn = net_generic(net, vlan_net_id);
144 remove_proc_entry(name_conf, proc_vlan_dir); 134
135 if (vn->proc_vlan_conf)
136 remove_proc_entry(name_conf, vn->proc_vlan_dir);
145 137
146 if (proc_vlan_dir) 138 if (vn->proc_vlan_dir)
147 proc_net_remove(&init_net, name_root); 139 proc_net_remove(net, name_root);
148 140
149 /* Dynamically added entries should be cleaned up as their vlan_device 141 /* Dynamically added entries should be cleaned up as their vlan_device
150 * is removed, so we should not have to take care of it here... 142 * is removed, so we should not have to take care of it here...
@@ -155,21 +147,23 @@ void vlan_proc_cleanup(void)
155 * Create /proc/net/vlan entries 147 * Create /proc/net/vlan entries
156 */ 148 */
157 149
158int __init vlan_proc_init(void) 150int vlan_proc_init(struct net *net)
159{ 151{
160 proc_vlan_dir = proc_mkdir(name_root, init_net.proc_net); 152 struct vlan_net *vn = net_generic(net, vlan_net_id);
161 if (!proc_vlan_dir) 153
154 vn->proc_vlan_dir = proc_net_mkdir(net, name_root, net->proc_net);
155 if (!vn->proc_vlan_dir)
162 goto err; 156 goto err;
163 157
164 proc_vlan_conf = proc_create(name_conf, S_IFREG|S_IRUSR|S_IWUSR, 158 vn->proc_vlan_conf = proc_create(name_conf, S_IFREG|S_IRUSR|S_IWUSR,
165 proc_vlan_dir, &vlan_fops); 159 vn->proc_vlan_dir, &vlan_fops);
166 if (!proc_vlan_conf) 160 if (!vn->proc_vlan_conf)
167 goto err; 161 goto err;
168 return 0; 162 return 0;
169 163
170err: 164err:
171 pr_err("%s: can't create entry in proc filesystem!\n", __FUNCTION__); 165 pr_err("%s: can't create entry in proc filesystem!\n", __func__);
172 vlan_proc_cleanup(); 166 vlan_proc_cleanup(net);
173 return -ENOBUFS; 167 return -ENOBUFS;
174} 168}
175 169
@@ -180,9 +174,10 @@ err:
180int vlan_proc_add_dev(struct net_device *vlandev) 174int vlan_proc_add_dev(struct net_device *vlandev)
181{ 175{
182 struct vlan_dev_info *dev_info = vlan_dev_info(vlandev); 176 struct vlan_dev_info *dev_info = vlan_dev_info(vlandev);
177 struct vlan_net *vn = net_generic(dev_net(vlandev), vlan_net_id);
183 178
184 dev_info->dent = proc_create(vlandev->name, S_IFREG|S_IRUSR|S_IWUSR, 179 dev_info->dent = proc_create(vlandev->name, S_IFREG|S_IRUSR|S_IWUSR,
185 proc_vlan_dir, &vlandev_fops); 180 vn->proc_vlan_dir, &vlandev_fops);
186 if (!dev_info->dent) 181 if (!dev_info->dent)
187 return -ENOBUFS; 182 return -ENOBUFS;
188 183
@@ -195,10 +190,12 @@ int vlan_proc_add_dev(struct net_device *vlandev)
195 */ 190 */
196int vlan_proc_rem_dev(struct net_device *vlandev) 191int vlan_proc_rem_dev(struct net_device *vlandev)
197{ 192{
193 struct vlan_net *vn = net_generic(dev_net(vlandev), vlan_net_id);
194
198 /** NOTE: This will consume the memory pointed to by dent, it seems. */ 195 /** NOTE: This will consume the memory pointed to by dent, it seems. */
199 if (vlan_dev_info(vlandev)->dent) { 196 if (vlan_dev_info(vlandev)->dent) {
200 remove_proc_entry(vlan_dev_info(vlandev)->dent->name, 197 remove_proc_entry(vlan_dev_info(vlandev)->dent->name,
201 proc_vlan_dir); 198 vn->proc_vlan_dir);
202 vlan_dev_info(vlandev)->dent = NULL; 199 vlan_dev_info(vlandev)->dent = NULL;
203 } 200 }
204 return 0; 201 return 0;
@@ -215,6 +212,7 @@ static void *vlan_seq_start(struct seq_file *seq, loff_t *pos)
215 __acquires(dev_base_lock) 212 __acquires(dev_base_lock)
216{ 213{
217 struct net_device *dev; 214 struct net_device *dev;
215 struct net *net = seq_file_net(seq);
218 loff_t i = 1; 216 loff_t i = 1;
219 217
220 read_lock(&dev_base_lock); 218 read_lock(&dev_base_lock);
@@ -222,7 +220,7 @@ static void *vlan_seq_start(struct seq_file *seq, loff_t *pos)
222 if (*pos == 0) 220 if (*pos == 0)
223 return SEQ_START_TOKEN; 221 return SEQ_START_TOKEN;
224 222
225 for_each_netdev(&init_net, dev) { 223 for_each_netdev(net, dev) {
226 if (!is_vlan_dev(dev)) 224 if (!is_vlan_dev(dev))
227 continue; 225 continue;
228 226
@@ -236,14 +234,15 @@ static void *vlan_seq_start(struct seq_file *seq, loff_t *pos)
236static void *vlan_seq_next(struct seq_file *seq, void *v, loff_t *pos) 234static void *vlan_seq_next(struct seq_file *seq, void *v, loff_t *pos)
237{ 235{
238 struct net_device *dev; 236 struct net_device *dev;
237 struct net *net = seq_file_net(seq);
239 238
240 ++*pos; 239 ++*pos;
241 240
242 dev = (struct net_device *)v; 241 dev = (struct net_device *)v;
243 if (v == SEQ_START_TOKEN) 242 if (v == SEQ_START_TOKEN)
244 dev = net_device_entry(&init_net.dev_base_head); 243 dev = net_device_entry(&net->dev_base_head);
245 244
246 for_each_netdev_continue(&init_net, dev) { 245 for_each_netdev_continue(net, dev) {
247 if (!is_vlan_dev(dev)) 246 if (!is_vlan_dev(dev))
248 continue; 247 continue;
249 248
@@ -261,13 +260,16 @@ static void vlan_seq_stop(struct seq_file *seq, void *v)
261 260
262static int vlan_seq_show(struct seq_file *seq, void *v) 261static int vlan_seq_show(struct seq_file *seq, void *v)
263{ 262{
263 struct net *net = seq_file_net(seq);
264 struct vlan_net *vn = net_generic(net, vlan_net_id);
265
264 if (v == SEQ_START_TOKEN) { 266 if (v == SEQ_START_TOKEN) {
265 const char *nmtype = NULL; 267 const char *nmtype = NULL;
266 268
267 seq_puts(seq, "VLAN Dev name | VLAN ID\n"); 269 seq_puts(seq, "VLAN Dev name | VLAN ID\n");
268 270
269 if (vlan_name_type < ARRAY_SIZE(vlan_name_type_str)) 271 if (vn->name_type < ARRAY_SIZE(vlan_name_type_str))
270 nmtype = vlan_name_type_str[vlan_name_type]; 272 nmtype = vlan_name_type_str[vn->name_type];
271 273
272 seq_printf(seq, "Name-Type: %s\n", 274 seq_printf(seq, "Name-Type: %s\n",
273 nmtype ? nmtype : "UNKNOWN"); 275 nmtype ? nmtype : "UNKNOWN");
diff --git a/net/8021q/vlanproc.h b/net/8021q/vlanproc.h
index da542cacc5a5..063f60a3d5cc 100644
--- a/net/8021q/vlanproc.h
+++ b/net/8021q/vlanproc.h
@@ -2,15 +2,17 @@
2#define __BEN_VLAN_PROC_INC__ 2#define __BEN_VLAN_PROC_INC__
3 3
4#ifdef CONFIG_PROC_FS 4#ifdef CONFIG_PROC_FS
5int vlan_proc_init(void); 5struct net;
6
7int vlan_proc_init(struct net *net);
6int vlan_proc_rem_dev(struct net_device *vlandev); 8int vlan_proc_rem_dev(struct net_device *vlandev);
7int vlan_proc_add_dev(struct net_device *vlandev); 9int vlan_proc_add_dev(struct net_device *vlandev);
8void vlan_proc_cleanup(void); 10void vlan_proc_cleanup(struct net *net);
9 11
10#else /* No CONFIG_PROC_FS */ 12#else /* No CONFIG_PROC_FS */
11 13
12#define vlan_proc_init() (0) 14#define vlan_proc_init(net) (0)
13#define vlan_proc_cleanup() do {} while (0) 15#define vlan_proc_cleanup(net) do {} while (0)
14#define vlan_proc_add_dev(dev) ({(void)(dev), 0; }) 16#define vlan_proc_add_dev(dev) ({(void)(dev), 0; })
15#define vlan_proc_rem_dev(dev) ({(void)(dev), 0; }) 17#define vlan_proc_rem_dev(dev) ({(void)(dev), 0; })
16#endif 18#endif