diff options
Diffstat (limited to 'net/8021q')
-rw-r--r-- | net/8021q/vlan.c | 147 | ||||
-rw-r--r-- | net/8021q/vlan.h | 15 | ||||
-rw-r--r-- | net/8021q/vlan_dev.c | 15 | ||||
-rw-r--r-- | net/8021q/vlan_netlink.c | 2 | ||||
-rw-r--r-- | net/8021q/vlanproc.c | 70 | ||||
-rw-r--r-- | net/8021q/vlanproc.h | 10 |
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 | ||
45 | int vlan_net_id; | ||
46 | |||
44 | /* Our listing of VLAN group(s) */ | 47 | /* Our listing of VLAN group(s) */ |
45 | static struct hlist_head vlan_group_hash[VLAN_GRP_HASH_SIZE]; | 48 | static struct hlist_head vlan_group_hash[VLAN_GRP_HASH_SIZE]; |
46 | 49 | ||
@@ -49,9 +52,6 @@ static char vlan_version[] = DRV_VERSION; | |||
49 | static char vlan_copyright[] = "Ben Greear <greearb@candelatech.com>"; | 52 | static char vlan_copyright[] = "Ben Greear <greearb@candelatech.com>"; |
50 | static char vlan_buggyright[] = "David S. Miller <davem@redhat.com>"; | 53 | static char vlan_buggyright[] = "David S. Miller <davem@redhat.com>"; |
51 | 54 | ||
52 | /* Determines interface naming scheme. */ | ||
53 | unsigned short vlan_name_type = VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD; | ||
54 | |||
55 | static struct packet_type vlan_packet_type = { | 55 | static 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) */ |
68 | static struct vlan_group *__vlan_find_group(int real_dev_ifindex) | 68 | static 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) | |||
86 | struct net_device *__find_vlan_dev(struct net_device *real_dev, | 86 | struct 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 | ||
106 | static struct vlan_group *vlan_group_alloc(int ifindex) | 106 | static 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 | ||
129 | err: | 120 | static 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 | ||
134 | static void vlan_rcu_free(struct rcu_head *rcu) | 140 | static 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 | ||
276 | out_free_group: | 281 | out_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 | ||
634 | static 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 | |||
656 | err_proc: | ||
657 | /* nothing */ | ||
658 | err_assign: | ||
659 | kfree(vn); | ||
660 | err_alloc: | ||
661 | return err; | ||
662 | } | ||
663 | |||
664 | static 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 | |||
674 | static struct pernet_operations vlan_net_ops = { | ||
675 | .init = vlan_init_net, | ||
676 | .exit = vlan_exit_net, | ||
677 | }; | ||
678 | |||
618 | static int __init vlan_proto_init(void) | 679 | static 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) | |||
641 | err3: | 702 | err3: |
642 | unregister_netdevice_notifier(&vlan_notifier_block); | 703 | unregister_netdevice_notifier(&vlan_notifier_block); |
643 | err2: | 704 | err2: |
644 | vlan_proc_cleanup(); | 705 | unregister_pernet_gen_device(vlan_net_id, &vlan_net_ops); |
645 | err1: | 706 | err0: |
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 | ||
6 | extern 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 | ||
51 | extern int vlan_net_id; | ||
52 | |||
53 | struct proc_dir_entry; | ||
54 | |||
55 | struct 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 | ||
80 | static int vlan_seq_open(struct inode *inode, struct file *file) | 81 | static 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 | ||
85 | static const struct file_operations vlan_fops = { | 87 | static 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 | |||
118 | static struct proc_dir_entry *proc_vlan_dir; | ||
119 | |||
120 | /* | ||
121 | * /proc/net/vlan/config | ||
122 | */ | ||
123 | |||
124 | static struct proc_dir_entry *proc_vlan_conf; | ||
125 | |||
126 | /* Strings */ | 116 | /* Strings */ |
127 | static const char *vlan_name_type_str[VLAN_NAME_TYPE_HIGHEST] = { | 117 | static 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 | ||
141 | void vlan_proc_cleanup(void) | 131 | void 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 | ||
158 | int __init vlan_proc_init(void) | 150 | int 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 | ||
170 | err: | 164 | err: |
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: | |||
180 | int vlan_proc_add_dev(struct net_device *vlandev) | 174 | int 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 | */ |
196 | int vlan_proc_rem_dev(struct net_device *vlandev) | 191 | int 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) | |||
236 | static void *vlan_seq_next(struct seq_file *seq, void *v, loff_t *pos) | 234 | static 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 | ||
262 | static int vlan_seq_show(struct seq_file *seq, void *v) | 261 | static 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 |
5 | int vlan_proc_init(void); | 5 | struct net; |
6 | |||
7 | int vlan_proc_init(struct net *net); | ||
6 | int vlan_proc_rem_dev(struct net_device *vlandev); | 8 | int vlan_proc_rem_dev(struct net_device *vlandev); |
7 | int vlan_proc_add_dev(struct net_device *vlandev); | 9 | int vlan_proc_add_dev(struct net_device *vlandev); |
8 | void vlan_proc_cleanup(void); | 10 | void 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 |