aboutsummaryrefslogtreecommitdiffstats
path: root/net/8021q
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2013-04-18 22:04:29 -0400
committerDavid S. Miller <davem@davemloft.net>2013-04-19 14:45:27 -0400
commit1fd9b1fc310314911f66d2f14a8e4f0ef37bf47b (patch)
tree20422146c46fb38a5cdd0d14e671a0793c3389b4 /net/8021q
parent80d5c3689b886308247da295a228a54df49a44f6 (diff)
net: vlan: prepare for 802.1ad support
Make the encapsulation protocol value a property of VLAN devices and change the device lookup functions to take the protocol value into account. Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/8021q')
-rw-r--r--net/8021q/vlan.c87
-rw-r--r--net/8021q/vlan.h54
-rw-r--r--net/8021q/vlan_core.c10
-rw-r--r--net/8021q/vlan_dev.c7
-rw-r--r--net/8021q/vlan_gvrp.c4
-rw-r--r--net/8021q/vlan_mvrp.c4
-rw-r--r--net/8021q/vlan_netlink.c9
7 files changed, 98 insertions, 77 deletions
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
index 447c5c93434f..9424f3718ea7 100644
--- a/net/8021q/vlan.c
+++ b/net/8021q/vlan.c
@@ -51,14 +51,18 @@ const char vlan_version[] = DRV_VERSION;
51 51
52/* End of global variables definitions. */ 52/* End of global variables definitions. */
53 53
54static int vlan_group_prealloc_vid(struct vlan_group *vg, u16 vlan_id) 54static int vlan_group_prealloc_vid(struct vlan_group *vg,
55 __be16 vlan_proto, u16 vlan_id)
55{ 56{
56 struct net_device **array; 57 struct net_device **array;
58 unsigned int pidx, vidx;
57 unsigned int size; 59 unsigned int size;
58 60
59 ASSERT_RTNL(); 61 ASSERT_RTNL();
60 62
61 array = vg->vlan_devices_arrays[vlan_id / VLAN_GROUP_ARRAY_PART_LEN]; 63 pidx = vlan_proto_idx(vlan_proto);
64 vidx = vlan_id / VLAN_GROUP_ARRAY_PART_LEN;
65 array = vg->vlan_devices_arrays[pidx][vidx];
62 if (array != NULL) 66 if (array != NULL)
63 return 0; 67 return 0;
64 68
@@ -67,7 +71,7 @@ static int vlan_group_prealloc_vid(struct vlan_group *vg, u16 vlan_id)
67 if (array == NULL) 71 if (array == NULL)
68 return -ENOBUFS; 72 return -ENOBUFS;
69 73
70 vg->vlan_devices_arrays[vlan_id / VLAN_GROUP_ARRAY_PART_LEN] = array; 74 vg->vlan_devices_arrays[pidx][vidx] = array;
71 return 0; 75 return 0;
72} 76}
73 77
@@ -93,7 +97,7 @@ void unregister_vlan_dev(struct net_device *dev, struct list_head *head)
93 if (vlan->flags & VLAN_FLAG_GVRP) 97 if (vlan->flags & VLAN_FLAG_GVRP)
94 vlan_gvrp_request_leave(dev); 98 vlan_gvrp_request_leave(dev);
95 99
96 vlan_group_set_device(grp, vlan_id, NULL); 100 vlan_group_set_device(grp, vlan->vlan_proto, vlan_id, NULL);
97 /* Because unregister_netdevice_queue() makes sure at least one rcu 101 /* Because unregister_netdevice_queue() makes sure at least one rcu
98 * grace period is respected before device freeing, 102 * grace period is respected before device freeing,
99 * we dont need to call synchronize_net() here. 103 * we dont need to call synchronize_net() here.
@@ -112,13 +116,14 @@ void unregister_vlan_dev(struct net_device *dev, struct list_head *head)
112 * VLAN is not 0 (leave it there for 802.1p). 116 * VLAN is not 0 (leave it there for 802.1p).
113 */ 117 */
114 if (vlan_id) 118 if (vlan_id)
115 vlan_vid_del(real_dev, htons(ETH_P_8021Q), vlan_id); 119 vlan_vid_del(real_dev, vlan->vlan_proto, vlan_id);
116 120
117 /* Get rid of the vlan's reference to real_dev */ 121 /* Get rid of the vlan's reference to real_dev */
118 dev_put(real_dev); 122 dev_put(real_dev);
119} 123}
120 124
121int vlan_check_real_dev(struct net_device *real_dev, u16 vlan_id) 125int vlan_check_real_dev(struct net_device *real_dev,
126 __be16 protocol, u16 vlan_id)
122{ 127{
123 const char *name = real_dev->name; 128 const char *name = real_dev->name;
124 129
@@ -127,7 +132,7 @@ int vlan_check_real_dev(struct net_device *real_dev, u16 vlan_id)
127 return -EOPNOTSUPP; 132 return -EOPNOTSUPP;
128 } 133 }
129 134
130 if (vlan_find_dev(real_dev, vlan_id) != NULL) 135 if (vlan_find_dev(real_dev, protocol, vlan_id) != NULL)
131 return -EEXIST; 136 return -EEXIST;
132 137
133 return 0; 138 return 0;
@@ -142,7 +147,7 @@ int register_vlan_dev(struct net_device *dev)
142 struct vlan_group *grp; 147 struct vlan_group *grp;
143 int err; 148 int err;
144 149
145 err = vlan_vid_add(real_dev, htons(ETH_P_8021Q), vlan_id); 150 err = vlan_vid_add(real_dev, vlan->vlan_proto, vlan_id);
146 if (err) 151 if (err)
147 return err; 152 return err;
148 153
@@ -160,7 +165,7 @@ int register_vlan_dev(struct net_device *dev)
160 goto out_uninit_gvrp; 165 goto out_uninit_gvrp;
161 } 166 }
162 167
163 err = vlan_group_prealloc_vid(grp, vlan_id); 168 err = vlan_group_prealloc_vid(grp, vlan->vlan_proto, vlan_id);
164 if (err < 0) 169 if (err < 0)
165 goto out_uninit_mvrp; 170 goto out_uninit_mvrp;
166 171
@@ -181,7 +186,7 @@ int register_vlan_dev(struct net_device *dev)
181 /* So, got the sucker initialized, now lets place 186 /* So, got the sucker initialized, now lets place
182 * it into our local structure. 187 * it into our local structure.
183 */ 188 */
184 vlan_group_set_device(grp, vlan_id, dev); 189 vlan_group_set_device(grp, vlan->vlan_proto, vlan_id, dev);
185 grp->nr_vlan_devs++; 190 grp->nr_vlan_devs++;
186 191
187 return 0; 192 return 0;
@@ -195,7 +200,7 @@ out_uninit_gvrp:
195 if (grp->nr_vlan_devs == 0) 200 if (grp->nr_vlan_devs == 0)
196 vlan_gvrp_uninit_applicant(real_dev); 201 vlan_gvrp_uninit_applicant(real_dev);
197out_vid_del: 202out_vid_del:
198 vlan_vid_del(real_dev, htons(ETH_P_8021Q), vlan_id); 203 vlan_vid_del(real_dev, vlan->vlan_proto, vlan_id);
199 return err; 204 return err;
200} 205}
201 206
@@ -213,7 +218,7 @@ static int register_vlan_device(struct net_device *real_dev, u16 vlan_id)
213 if (vlan_id >= VLAN_VID_MASK) 218 if (vlan_id >= VLAN_VID_MASK)
214 return -ERANGE; 219 return -ERANGE;
215 220
216 err = vlan_check_real_dev(real_dev, vlan_id); 221 err = vlan_check_real_dev(real_dev, htons(ETH_P_8021Q), vlan_id);
217 if (err < 0) 222 if (err < 0)
218 return err; 223 return err;
219 224
@@ -255,6 +260,7 @@ static int register_vlan_device(struct net_device *real_dev, u16 vlan_id)
255 new_dev->mtu = real_dev->mtu; 260 new_dev->mtu = real_dev->mtu;
256 new_dev->priv_flags |= (real_dev->priv_flags & IFF_UNICAST_FLT); 261 new_dev->priv_flags |= (real_dev->priv_flags & IFF_UNICAST_FLT);
257 262
263 vlan_dev_priv(new_dev)->vlan_proto = htons(ETH_P_8021Q);
258 vlan_dev_priv(new_dev)->vlan_id = vlan_id; 264 vlan_dev_priv(new_dev)->vlan_id = vlan_id;
259 vlan_dev_priv(new_dev)->real_dev = real_dev; 265 vlan_dev_priv(new_dev)->real_dev = real_dev;
260 vlan_dev_priv(new_dev)->dent = NULL; 266 vlan_dev_priv(new_dev)->dent = NULL;
@@ -341,6 +347,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
341 int i, flgs; 347 int i, flgs;
342 struct net_device *vlandev; 348 struct net_device *vlandev;
343 struct vlan_dev_priv *vlan; 349 struct vlan_dev_priv *vlan;
350 bool last = false;
344 LIST_HEAD(list); 351 LIST_HEAD(list);
345 352
346 if (is_vlan_dev(dev)) 353 if (is_vlan_dev(dev))
@@ -365,22 +372,13 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
365 switch (event) { 372 switch (event) {
366 case NETDEV_CHANGE: 373 case NETDEV_CHANGE:
367 /* Propagate real device state to vlan devices */ 374 /* Propagate real device state to vlan devices */
368 for (i = 0; i < VLAN_N_VID; i++) { 375 vlan_group_for_each_dev(grp, i, vlandev)
369 vlandev = vlan_group_get_device(grp, i);
370 if (!vlandev)
371 continue;
372
373 netif_stacked_transfer_operstate(dev, vlandev); 376 netif_stacked_transfer_operstate(dev, vlandev);
374 }
375 break; 377 break;
376 378
377 case NETDEV_CHANGEADDR: 379 case NETDEV_CHANGEADDR:
378 /* Adjust unicast filters on underlying device */ 380 /* Adjust unicast filters on underlying device */
379 for (i = 0; i < VLAN_N_VID; i++) { 381 vlan_group_for_each_dev(grp, i, vlandev) {
380 vlandev = vlan_group_get_device(grp, i);
381 if (!vlandev)
382 continue;
383
384 flgs = vlandev->flags; 382 flgs = vlandev->flags;
385 if (!(flgs & IFF_UP)) 383 if (!(flgs & IFF_UP))
386 continue; 384 continue;
@@ -390,11 +388,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
390 break; 388 break;
391 389
392 case NETDEV_CHANGEMTU: 390 case NETDEV_CHANGEMTU:
393 for (i = 0; i < VLAN_N_VID; i++) { 391 vlan_group_for_each_dev(grp, i, vlandev) {
394 vlandev = vlan_group_get_device(grp, i);
395 if (!vlandev)
396 continue;
397
398 if (vlandev->mtu <= dev->mtu) 392 if (vlandev->mtu <= dev->mtu)
399 continue; 393 continue;
400 394
@@ -404,14 +398,8 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
404 398
405 case NETDEV_FEAT_CHANGE: 399 case NETDEV_FEAT_CHANGE:
406 /* Propagate device features to underlying device */ 400 /* Propagate device features to underlying device */
407 for (i = 0; i < VLAN_N_VID; i++) { 401 vlan_group_for_each_dev(grp, i, vlandev)
408 vlandev = vlan_group_get_device(grp, i);
409 if (!vlandev)
410 continue;
411
412 vlan_transfer_features(dev, vlandev); 402 vlan_transfer_features(dev, vlandev);
413 }
414
415 break; 403 break;
416 404
417 case NETDEV_DOWN: 405 case NETDEV_DOWN:
@@ -419,11 +407,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
419 vlan_vid_del(dev, htons(ETH_P_8021Q), 0); 407 vlan_vid_del(dev, htons(ETH_P_8021Q), 0);
420 408
421 /* Put all VLANs for this dev in the down state too. */ 409 /* Put all VLANs for this dev in the down state too. */
422 for (i = 0; i < VLAN_N_VID; i++) { 410 vlan_group_for_each_dev(grp, i, vlandev) {
423 vlandev = vlan_group_get_device(grp, i);
424 if (!vlandev)
425 continue;
426
427 flgs = vlandev->flags; 411 flgs = vlandev->flags;
428 if (!(flgs & IFF_UP)) 412 if (!(flgs & IFF_UP))
429 continue; 413 continue;
@@ -437,11 +421,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
437 421
438 case NETDEV_UP: 422 case NETDEV_UP:
439 /* Put all VLANs for this dev in the up state too. */ 423 /* Put all VLANs for this dev in the up state too. */
440 for (i = 0; i < VLAN_N_VID; i++) { 424 vlan_group_for_each_dev(grp, i, vlandev) {
441 vlandev = vlan_group_get_device(grp, i);
442 if (!vlandev)
443 continue;
444
445 flgs = vlandev->flags; 425 flgs = vlandev->flags;
446 if (flgs & IFF_UP) 426 if (flgs & IFF_UP)
447 continue; 427 continue;
@@ -458,17 +438,15 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
458 if (dev->reg_state != NETREG_UNREGISTERING) 438 if (dev->reg_state != NETREG_UNREGISTERING)
459 break; 439 break;
460 440
461 for (i = 0; i < VLAN_N_VID; i++) { 441 vlan_group_for_each_dev(grp, i, vlandev) {
462 vlandev = vlan_group_get_device(grp, i);
463 if (!vlandev)
464 continue;
465
466 /* removal of last vid destroys vlan_info, abort 442 /* removal of last vid destroys vlan_info, abort
467 * afterwards */ 443 * afterwards */
468 if (vlan_info->nr_vids == 1) 444 if (vlan_info->nr_vids == 1)
469 i = VLAN_N_VID; 445 last = true;
470 446
471 unregister_vlan_dev(vlandev, &list); 447 unregister_vlan_dev(vlandev, &list);
448 if (last)
449 break;
472 } 450 }
473 unregister_netdevice_many(&list); 451 unregister_netdevice_many(&list);
474 break; 452 break;
@@ -482,13 +460,8 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
482 case NETDEV_NOTIFY_PEERS: 460 case NETDEV_NOTIFY_PEERS:
483 case NETDEV_BONDING_FAILOVER: 461 case NETDEV_BONDING_FAILOVER:
484 /* Propagate to vlan devices */ 462 /* Propagate to vlan devices */
485 for (i = 0; i < VLAN_N_VID; i++) { 463 vlan_group_for_each_dev(grp, i, vlandev)
486 vlandev = vlan_group_get_device(grp, i);
487 if (!vlandev)
488 continue;
489
490 call_netdevice_notifiers(event, vlandev); 464 call_netdevice_notifiers(event, vlandev);
491 }
492 break; 465 break;
493 } 466 }
494 467
diff --git a/net/8021q/vlan.h b/net/8021q/vlan.h
index 670f1e8cfc0f..245de9653db0 100644
--- a/net/8021q/vlan.h
+++ b/net/8021q/vlan.h
@@ -49,6 +49,7 @@ struct netpoll;
49 * @ingress_priority_map: ingress priority mappings 49 * @ingress_priority_map: ingress priority mappings
50 * @nr_egress_mappings: number of egress priority mappings 50 * @nr_egress_mappings: number of egress priority mappings
51 * @egress_priority_map: hash of egress priority mappings 51 * @egress_priority_map: hash of egress priority mappings
52 * @vlan_proto: VLAN encapsulation protocol
52 * @vlan_id: VLAN identifier 53 * @vlan_id: VLAN identifier
53 * @flags: device flags 54 * @flags: device flags
54 * @real_dev: underlying netdevice 55 * @real_dev: underlying netdevice
@@ -62,6 +63,7 @@ struct vlan_dev_priv {
62 unsigned int nr_egress_mappings; 63 unsigned int nr_egress_mappings;
63 struct vlan_priority_tci_mapping *egress_priority_map[16]; 64 struct vlan_priority_tci_mapping *egress_priority_map[16];
64 65
66 __be16 vlan_proto;
65 u16 vlan_id; 67 u16 vlan_id;
66 u16 flags; 68 u16 flags;
67 69
@@ -87,10 +89,16 @@ static inline struct vlan_dev_priv *vlan_dev_priv(const struct net_device *dev)
87#define VLAN_GROUP_ARRAY_SPLIT_PARTS 8 89#define VLAN_GROUP_ARRAY_SPLIT_PARTS 8
88#define VLAN_GROUP_ARRAY_PART_LEN (VLAN_N_VID/VLAN_GROUP_ARRAY_SPLIT_PARTS) 90#define VLAN_GROUP_ARRAY_PART_LEN (VLAN_N_VID/VLAN_GROUP_ARRAY_SPLIT_PARTS)
89 91
92enum vlan_protos {
93 VLAN_PROTO_8021Q = 0,
94 VLAN_PROTO_NUM,
95};
96
90struct vlan_group { 97struct vlan_group {
91 unsigned int nr_vlan_devs; 98 unsigned int nr_vlan_devs;
92 struct hlist_node hlist; /* linked list */ 99 struct hlist_node hlist; /* linked list */
93 struct net_device **vlan_devices_arrays[VLAN_GROUP_ARRAY_SPLIT_PARTS]; 100 struct net_device **vlan_devices_arrays[VLAN_PROTO_NUM]
101 [VLAN_GROUP_ARRAY_SPLIT_PARTS];
94}; 102};
95 103
96struct vlan_info { 104struct vlan_info {
@@ -103,37 +111,64 @@ struct vlan_info {
103 struct rcu_head rcu; 111 struct rcu_head rcu;
104}; 112};
105 113
106static inline struct net_device *vlan_group_get_device(struct vlan_group *vg, 114static inline unsigned int vlan_proto_idx(__be16 proto)
107 u16 vlan_id) 115{
116 switch (proto) {
117 case __constant_htons(ETH_P_8021Q):
118 return VLAN_PROTO_8021Q;
119 default:
120 BUG();
121 }
122}
123
124static inline struct net_device *__vlan_group_get_device(struct vlan_group *vg,
125 unsigned int pidx,
126 u16 vlan_id)
108{ 127{
109 struct net_device **array; 128 struct net_device **array;
110 array = vg->vlan_devices_arrays[vlan_id / VLAN_GROUP_ARRAY_PART_LEN]; 129
130 array = vg->vlan_devices_arrays[pidx]
131 [vlan_id / VLAN_GROUP_ARRAY_PART_LEN];
111 return array ? array[vlan_id % VLAN_GROUP_ARRAY_PART_LEN] : NULL; 132 return array ? array[vlan_id % VLAN_GROUP_ARRAY_PART_LEN] : NULL;
112} 133}
113 134
135static inline struct net_device *vlan_group_get_device(struct vlan_group *vg,
136 __be16 vlan_proto,
137 u16 vlan_id)
138{
139 return __vlan_group_get_device(vg, vlan_proto_idx(vlan_proto), vlan_id);
140}
141
114static inline void vlan_group_set_device(struct vlan_group *vg, 142static inline void vlan_group_set_device(struct vlan_group *vg,
115 u16 vlan_id, 143 __be16 vlan_proto, u16 vlan_id,
116 struct net_device *dev) 144 struct net_device *dev)
117{ 145{
118 struct net_device **array; 146 struct net_device **array;
119 if (!vg) 147 if (!vg)
120 return; 148 return;
121 array = vg->vlan_devices_arrays[vlan_id / VLAN_GROUP_ARRAY_PART_LEN]; 149 array = vg->vlan_devices_arrays[vlan_proto_idx(vlan_proto)]
150 [vlan_id / VLAN_GROUP_ARRAY_PART_LEN];
122 array[vlan_id % VLAN_GROUP_ARRAY_PART_LEN] = dev; 151 array[vlan_id % VLAN_GROUP_ARRAY_PART_LEN] = dev;
123} 152}
124 153
125/* Must be invoked with rcu_read_lock or with RTNL. */ 154/* Must be invoked with rcu_read_lock or with RTNL. */
126static inline struct net_device *vlan_find_dev(struct net_device *real_dev, 155static inline struct net_device *vlan_find_dev(struct net_device *real_dev,
127 u16 vlan_id) 156 __be16 vlan_proto, u16 vlan_id)
128{ 157{
129 struct vlan_info *vlan_info = rcu_dereference_rtnl(real_dev->vlan_info); 158 struct vlan_info *vlan_info = rcu_dereference_rtnl(real_dev->vlan_info);
130 159
131 if (vlan_info) 160 if (vlan_info)
132 return vlan_group_get_device(&vlan_info->grp, vlan_id); 161 return vlan_group_get_device(&vlan_info->grp,
162 vlan_proto, vlan_id);
133 163
134 return NULL; 164 return NULL;
135} 165}
136 166
167#define vlan_group_for_each_dev(grp, i, dev) \
168 for ((i) = 0; i < VLAN_PROTO_NUM * VLAN_N_VID; i++) \
169 if (((dev) = __vlan_group_get_device((grp), (i) / VLAN_N_VID, \
170 (i) % VLAN_N_VID)))
171
137/* found in vlan_dev.c */ 172/* found in vlan_dev.c */
138void vlan_dev_set_ingress_priority(const struct net_device *dev, 173void vlan_dev_set_ingress_priority(const struct net_device *dev,
139 u32 skb_prio, u16 vlan_prio); 174 u32 skb_prio, u16 vlan_prio);
@@ -142,7 +177,8 @@ int vlan_dev_set_egress_priority(const struct net_device *dev,
142int vlan_dev_change_flags(const struct net_device *dev, u32 flag, u32 mask); 177int vlan_dev_change_flags(const struct net_device *dev, u32 flag, u32 mask);
143void vlan_dev_get_realdev_name(const struct net_device *dev, char *result); 178void vlan_dev_get_realdev_name(const struct net_device *dev, char *result);
144 179
145int vlan_check_real_dev(struct net_device *real_dev, u16 vlan_id); 180int vlan_check_real_dev(struct net_device *real_dev,
181 __be16 protocol, u16 vlan_id);
146void vlan_setup(struct net_device *dev); 182void vlan_setup(struct net_device *dev);
147int register_vlan_dev(struct net_device *dev); 183int register_vlan_dev(struct net_device *dev);
148void unregister_vlan_dev(struct net_device *dev, struct list_head *head); 184void unregister_vlan_dev(struct net_device *dev, struct list_head *head);
diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c
index 04e3b95a0d48..4e4c360353ea 100644
--- a/net/8021q/vlan_core.c
+++ b/net/8021q/vlan_core.c
@@ -12,7 +12,7 @@ bool vlan_do_receive(struct sk_buff **skbp)
12 struct net_device *vlan_dev; 12 struct net_device *vlan_dev;
13 struct vlan_pcpu_stats *rx_stats; 13 struct vlan_pcpu_stats *rx_stats;
14 14
15 vlan_dev = vlan_find_dev(skb->dev, vlan_id); 15 vlan_dev = vlan_find_dev(skb->dev, htons(ETH_P_8021Q), vlan_id);
16 if (!vlan_dev) 16 if (!vlan_dev)
17 return false; 17 return false;
18 18
@@ -62,12 +62,13 @@ bool vlan_do_receive(struct sk_buff **skbp)
62 62
63/* Must be invoked with rcu_read_lock. */ 63/* Must be invoked with rcu_read_lock. */
64struct net_device *__vlan_find_dev_deep(struct net_device *dev, 64struct net_device *__vlan_find_dev_deep(struct net_device *dev,
65 u16 vlan_id) 65 __be16 vlan_proto, u16 vlan_id)
66{ 66{
67 struct vlan_info *vlan_info = rcu_dereference(dev->vlan_info); 67 struct vlan_info *vlan_info = rcu_dereference(dev->vlan_info);
68 68
69 if (vlan_info) { 69 if (vlan_info) {
70 return vlan_group_get_device(&vlan_info->grp, vlan_id); 70 return vlan_group_get_device(&vlan_info->grp,
71 vlan_proto, vlan_id);
71 } else { 72 } else {
72 /* 73 /*
73 * Lower devices of master uppers (bonding, team) do not have 74 * Lower devices of master uppers (bonding, team) do not have
@@ -78,7 +79,8 @@ struct net_device *__vlan_find_dev_deep(struct net_device *dev,
78 79
79 upper_dev = netdev_master_upper_dev_get_rcu(dev); 80 upper_dev = netdev_master_upper_dev_get_rcu(dev);
80 if (upper_dev) 81 if (upper_dev)
81 return __vlan_find_dev_deep(upper_dev, vlan_id); 82 return __vlan_find_dev_deep(upper_dev,
83 vlan_proto, vlan_id);
82 } 84 }
83 85
84 return NULL; 86 return NULL;
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index 5c4892a86410..d7457b7e1b95 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -99,6 +99,7 @@ static int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev,
99 const void *daddr, const void *saddr, 99 const void *daddr, const void *saddr,
100 unsigned int len) 100 unsigned int len)
101{ 101{
102 struct vlan_dev_priv *vlan = vlan_dev_priv(dev);
102 struct vlan_hdr *vhdr; 103 struct vlan_hdr *vhdr;
103 unsigned int vhdrlen = 0; 104 unsigned int vhdrlen = 0;
104 u16 vlan_tci = 0; 105 u16 vlan_tci = 0;
@@ -120,8 +121,8 @@ static int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev,
120 else 121 else
121 vhdr->h_vlan_encapsulated_proto = htons(len); 122 vhdr->h_vlan_encapsulated_proto = htons(len);
122 123
123 skb->protocol = htons(ETH_P_8021Q); 124 skb->protocol = vlan->vlan_proto;
124 type = ETH_P_8021Q; 125 type = ntohs(vlan->vlan_proto);
125 vhdrlen = VLAN_HLEN; 126 vhdrlen = VLAN_HLEN;
126 } 127 }
127 128
@@ -161,7 +162,7 @@ static netdev_tx_t vlan_dev_hard_start_xmit(struct sk_buff *skb,
161 * NOTE: THIS ASSUMES DIX ETHERNET, SPECIFICALLY NOT SUPPORTING 162 * NOTE: THIS ASSUMES DIX ETHERNET, SPECIFICALLY NOT SUPPORTING
162 * OTHER THINGS LIKE FDDI/TokenRing/802.3 SNAPs... 163 * OTHER THINGS LIKE FDDI/TokenRing/802.3 SNAPs...
163 */ 164 */
164 if (veth->h_vlan_proto != htons(ETH_P_8021Q) || 165 if (veth->h_vlan_proto != vlan->vlan_proto ||
165 vlan->flags & VLAN_FLAG_REORDER_HDR) { 166 vlan->flags & VLAN_FLAG_REORDER_HDR) {
166 u16 vlan_tci; 167 u16 vlan_tci;
167 vlan_tci = vlan->vlan_id; 168 vlan_tci = vlan->vlan_id;
diff --git a/net/8021q/vlan_gvrp.c b/net/8021q/vlan_gvrp.c
index 6f9755352760..66a80320b032 100644
--- a/net/8021q/vlan_gvrp.c
+++ b/net/8021q/vlan_gvrp.c
@@ -32,6 +32,8 @@ int vlan_gvrp_request_join(const struct net_device *dev)
32 const struct vlan_dev_priv *vlan = vlan_dev_priv(dev); 32 const struct vlan_dev_priv *vlan = vlan_dev_priv(dev);
33 __be16 vlan_id = htons(vlan->vlan_id); 33 __be16 vlan_id = htons(vlan->vlan_id);
34 34
35 if (vlan->vlan_proto != htons(ETH_P_8021Q))
36 return 0;
35 return garp_request_join(vlan->real_dev, &vlan_gvrp_app, 37 return garp_request_join(vlan->real_dev, &vlan_gvrp_app,
36 &vlan_id, sizeof(vlan_id), GVRP_ATTR_VID); 38 &vlan_id, sizeof(vlan_id), GVRP_ATTR_VID);
37} 39}
@@ -41,6 +43,8 @@ void vlan_gvrp_request_leave(const struct net_device *dev)
41 const struct vlan_dev_priv *vlan = vlan_dev_priv(dev); 43 const struct vlan_dev_priv *vlan = vlan_dev_priv(dev);
42 __be16 vlan_id = htons(vlan->vlan_id); 44 __be16 vlan_id = htons(vlan->vlan_id);
43 45
46 if (vlan->vlan_proto != htons(ETH_P_8021Q))
47 return;
44 garp_request_leave(vlan->real_dev, &vlan_gvrp_app, 48 garp_request_leave(vlan->real_dev, &vlan_gvrp_app,
45 &vlan_id, sizeof(vlan_id), GVRP_ATTR_VID); 49 &vlan_id, sizeof(vlan_id), GVRP_ATTR_VID);
46} 50}
diff --git a/net/8021q/vlan_mvrp.c b/net/8021q/vlan_mvrp.c
index d9ec1d5964aa..e0fe091801b0 100644
--- a/net/8021q/vlan_mvrp.c
+++ b/net/8021q/vlan_mvrp.c
@@ -38,6 +38,8 @@ int vlan_mvrp_request_join(const struct net_device *dev)
38 const struct vlan_dev_priv *vlan = vlan_dev_priv(dev); 38 const struct vlan_dev_priv *vlan = vlan_dev_priv(dev);
39 __be16 vlan_id = htons(vlan->vlan_id); 39 __be16 vlan_id = htons(vlan->vlan_id);
40 40
41 if (vlan->vlan_proto != htons(ETH_P_8021Q))
42 return 0;
41 return mrp_request_join(vlan->real_dev, &vlan_mrp_app, 43 return mrp_request_join(vlan->real_dev, &vlan_mrp_app,
42 &vlan_id, sizeof(vlan_id), MVRP_ATTR_VID); 44 &vlan_id, sizeof(vlan_id), MVRP_ATTR_VID);
43} 45}
@@ -47,6 +49,8 @@ void vlan_mvrp_request_leave(const struct net_device *dev)
47 const struct vlan_dev_priv *vlan = vlan_dev_priv(dev); 49 const struct vlan_dev_priv *vlan = vlan_dev_priv(dev);
48 __be16 vlan_id = htons(vlan->vlan_id); 50 __be16 vlan_id = htons(vlan->vlan_id);
49 51
52 if (vlan->vlan_proto != htons(ETH_P_8021Q))
53 return;
50 mrp_request_leave(vlan->real_dev, &vlan_mrp_app, 54 mrp_request_leave(vlan->real_dev, &vlan_mrp_app,
51 &vlan_id, sizeof(vlan_id), MVRP_ATTR_VID); 55 &vlan_id, sizeof(vlan_id), MVRP_ATTR_VID);
52} 56}
diff --git a/net/8021q/vlan_netlink.c b/net/8021q/vlan_netlink.c
index 1789658b7cd7..a1a956ab39a5 100644
--- a/net/8021q/vlan_netlink.c
+++ b/net/8021q/vlan_netlink.c
@@ -118,11 +118,12 @@ static int vlan_newlink(struct net *src_net, struct net_device *dev,
118 if (!real_dev) 118 if (!real_dev)
119 return -ENODEV; 119 return -ENODEV;
120 120
121 vlan->vlan_id = nla_get_u16(data[IFLA_VLAN_ID]); 121 vlan->vlan_proto = htons(ETH_P_8021Q);
122 vlan->real_dev = real_dev; 122 vlan->vlan_id = nla_get_u16(data[IFLA_VLAN_ID]);
123 vlan->flags = VLAN_FLAG_REORDER_HDR; 123 vlan->real_dev = real_dev;
124 vlan->flags = VLAN_FLAG_REORDER_HDR;
124 125
125 err = vlan_check_real_dev(real_dev, vlan->vlan_id); 126 err = vlan_check_real_dev(real_dev, vlan->vlan_proto, vlan->vlan_id);
126 if (err < 0) 127 if (err < 0)
127 return err; 128 return err;
128 129