Skip to content

Commit 1fd9b1f

Browse files
kaberdavem330
authored andcommitted
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>
1 parent 80d5c36 commit 1fd9b1f

File tree

12 files changed

+108
-84
lines changed

12 files changed

+108
-84
lines changed

drivers/net/bonding/bond_main.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -782,7 +782,7 @@ static void bond_resend_igmp_join_requests(struct bonding *bond)
782782

783783
/* rejoin all groups on vlan devices */
784784
list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
785-
vlan_dev = __vlan_find_dev_deep(bond_dev,
785+
vlan_dev = __vlan_find_dev_deep(bond_dev, htons(ETH_P_8021Q),
786786
vlan->vlan_id);
787787
if (vlan_dev)
788788
__bond_resend_igmp_join_requests(vlan_dev);
@@ -2512,7 +2512,8 @@ static int bond_has_this_ip(struct bonding *bond, __be32 ip)
25122512

25132513
list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
25142514
rcu_read_lock();
2515-
vlan_dev = __vlan_find_dev_deep(bond->dev, vlan->vlan_id);
2515+
vlan_dev = __vlan_find_dev_deep(bond->dev, htons(ETH_P_8021Q),
2516+
vlan->vlan_id);
25162517
rcu_read_unlock();
25172518
if (vlan_dev && ip == bond_confirm_addr(vlan_dev, 0, ip))
25182519
return 1;
@@ -2541,7 +2542,7 @@ static void bond_arp_send(struct net_device *slave_dev, int arp_op, __be32 dest_
25412542
return;
25422543
}
25432544
if (vlan_id) {
2544-
skb = vlan_put_tag(skb, vlan_id);
2545+
skb = vlan_put_tag(skb, htons(ETH_P_8021Q), vlan_id);
25452546
if (!skb) {
25462547
pr_err("failed to insert VLAN tag\n");
25472548
return;
@@ -2603,6 +2604,7 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
26032604
list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
26042605
rcu_read_lock();
26052606
vlan_dev = __vlan_find_dev_deep(bond->dev,
2607+
htons(ETH_P_8021Q),
26062608
vlan->vlan_id);
26072609
rcu_read_unlock();
26082610
if (vlan_dev == rt->dst.dev) {

drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ static struct net_device *get_iff_from_mac(struct adapter *adapter,
185185
if (!memcmp(dev->dev_addr, mac, ETH_ALEN)) {
186186
rcu_read_lock();
187187
if (vlan && vlan != VLAN_VID_MASK) {
188-
dev = __vlan_find_dev_deep(dev, vlan);
188+
dev = __vlan_find_dev_deep(dev, htons(ETH_P_8021Q), vlan);
189189
} else if (netif_is_bond_slave(dev)) {
190190
struct net_device *upper_dev;
191191

drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3346,7 +3346,7 @@ void qlcnic_restore_indev_addr(struct net_device *netdev, unsigned long event)
33463346

33473347
rcu_read_lock();
33483348
for_each_set_bit(vid, adapter->vlans, VLAN_N_VID) {
3349-
dev = __vlan_find_dev_deep(netdev, vid);
3349+
dev = __vlan_find_dev_deep(netdev, htons(ETH_P_8021Q), vid);
33503350
if (!dev)
33513351
continue;
33523352
qlcnic_config_indev_addr(adapter, dev, event);

include/linux/if_vlan.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ static inline int is_vlan_dev(struct net_device *dev)
8686
#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
8787

8888
extern struct net_device *__vlan_find_dev_deep(struct net_device *real_dev,
89-
u16 vlan_id);
89+
__be16 vlan_proto, u16 vlan_id);
9090
extern struct net_device *vlan_dev_real_dev(const struct net_device *dev);
9191
extern u16 vlan_dev_vlan_id(const struct net_device *dev);
9292

net/8021q/vlan.c

Lines changed: 30 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,18 @@ const char vlan_version[] = DRV_VERSION;
5151

5252
/* End of global variables definitions. */
5353

54-
static int vlan_group_prealloc_vid(struct vlan_group *vg, u16 vlan_id)
54+
static int vlan_group_prealloc_vid(struct vlan_group *vg,
55+
__be16 vlan_proto, u16 vlan_id)
5556
{
5657
struct net_device **array;
58+
unsigned int pidx, vidx;
5759
unsigned int size;
5860

5961
ASSERT_RTNL();
6062

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];
6266
if (array != NULL)
6367
return 0;
6468

@@ -67,7 +71,7 @@ static int vlan_group_prealloc_vid(struct vlan_group *vg, u16 vlan_id)
6771
if (array == NULL)
6872
return -ENOBUFS;
6973

70-
vg->vlan_devices_arrays[vlan_id / VLAN_GROUP_ARRAY_PART_LEN] = array;
74+
vg->vlan_devices_arrays[pidx][vidx] = array;
7175
return 0;
7276
}
7377

@@ -93,7 +97,7 @@ void unregister_vlan_dev(struct net_device *dev, struct list_head *head)
9397
if (vlan->flags & VLAN_FLAG_GVRP)
9498
vlan_gvrp_request_leave(dev);
9599

96-
vlan_group_set_device(grp, vlan_id, NULL);
100+
vlan_group_set_device(grp, vlan->vlan_proto, vlan_id, NULL);
97101
/* Because unregister_netdevice_queue() makes sure at least one rcu
98102
* grace period is respected before device freeing,
99103
* we dont need to call synchronize_net() here.
@@ -112,13 +116,14 @@ void unregister_vlan_dev(struct net_device *dev, struct list_head *head)
112116
* VLAN is not 0 (leave it there for 802.1p).
113117
*/
114118
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);
116120

117121
/* Get rid of the vlan's reference to real_dev */
118122
dev_put(real_dev);
119123
}
120124

121-
int vlan_check_real_dev(struct net_device *real_dev, u16 vlan_id)
125+
int vlan_check_real_dev(struct net_device *real_dev,
126+
__be16 protocol, u16 vlan_id)
122127
{
123128
const char *name = real_dev->name;
124129

@@ -127,7 +132,7 @@ int vlan_check_real_dev(struct net_device *real_dev, u16 vlan_id)
127132
return -EOPNOTSUPP;
128133
}
129134

130-
if (vlan_find_dev(real_dev, vlan_id) != NULL)
135+
if (vlan_find_dev(real_dev, protocol, vlan_id) != NULL)
131136
return -EEXIST;
132137

133138
return 0;
@@ -142,7 +147,7 @@ int register_vlan_dev(struct net_device *dev)
142147
struct vlan_group *grp;
143148
int err;
144149

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);
146151
if (err)
147152
return err;
148153

@@ -160,7 +165,7 @@ int register_vlan_dev(struct net_device *dev)
160165
goto out_uninit_gvrp;
161166
}
162167

163-
err = vlan_group_prealloc_vid(grp, vlan_id);
168+
err = vlan_group_prealloc_vid(grp, vlan->vlan_proto, vlan_id);
164169
if (err < 0)
165170
goto out_uninit_mvrp;
166171

@@ -181,7 +186,7 @@ int register_vlan_dev(struct net_device *dev)
181186
/* So, got the sucker initialized, now lets place
182187
* it into our local structure.
183188
*/
184-
vlan_group_set_device(grp, vlan_id, dev);
189+
vlan_group_set_device(grp, vlan->vlan_proto, vlan_id, dev);
185190
grp->nr_vlan_devs++;
186191

187192
return 0;
@@ -195,7 +200,7 @@ int register_vlan_dev(struct net_device *dev)
195200
if (grp->nr_vlan_devs == 0)
196201
vlan_gvrp_uninit_applicant(real_dev);
197202
out_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);
199204
return err;
200205
}
201206

@@ -213,7 +218,7 @@ static int register_vlan_device(struct net_device *real_dev, u16 vlan_id)
213218
if (vlan_id >= VLAN_VID_MASK)
214219
return -ERANGE;
215220

216-
err = vlan_check_real_dev(real_dev, vlan_id);
221+
err = vlan_check_real_dev(real_dev, htons(ETH_P_8021Q), vlan_id);
217222
if (err < 0)
218223
return err;
219224

@@ -255,6 +260,7 @@ static int register_vlan_device(struct net_device *real_dev, u16 vlan_id)
255260
new_dev->mtu = real_dev->mtu;
256261
new_dev->priv_flags |= (real_dev->priv_flags & IFF_UNICAST_FLT);
257262

263+
vlan_dev_priv(new_dev)->vlan_proto = htons(ETH_P_8021Q);
258264
vlan_dev_priv(new_dev)->vlan_id = vlan_id;
259265
vlan_dev_priv(new_dev)->real_dev = real_dev;
260266
vlan_dev_priv(new_dev)->dent = NULL;
@@ -341,6 +347,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
341347
int i, flgs;
342348
struct net_device *vlandev;
343349
struct vlan_dev_priv *vlan;
350+
bool last = false;
344351
LIST_HEAD(list);
345352

346353
if (is_vlan_dev(dev))
@@ -365,22 +372,13 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
365372
switch (event) {
366373
case NETDEV_CHANGE:
367374
/* Propagate real device state to vlan devices */
368-
for (i = 0; i < VLAN_N_VID; i++) {
369-
vlandev = vlan_group_get_device(grp, i);
370-
if (!vlandev)
371-
continue;
372-
375+
vlan_group_for_each_dev(grp, i, vlandev)
373376
netif_stacked_transfer_operstate(dev, vlandev);
374-
}
375377
break;
376378

377379
case NETDEV_CHANGEADDR:
378380
/* Adjust unicast filters on underlying device */
379-
for (i = 0; i < VLAN_N_VID; i++) {
380-
vlandev = vlan_group_get_device(grp, i);
381-
if (!vlandev)
382-
continue;
383-
381+
vlan_group_for_each_dev(grp, i, vlandev) {
384382
flgs = vlandev->flags;
385383
if (!(flgs & IFF_UP))
386384
continue;
@@ -390,11 +388,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
390388
break;
391389

392390
case NETDEV_CHANGEMTU:
393-
for (i = 0; i < VLAN_N_VID; i++) {
394-
vlandev = vlan_group_get_device(grp, i);
395-
if (!vlandev)
396-
continue;
397-
391+
vlan_group_for_each_dev(grp, i, vlandev) {
398392
if (vlandev->mtu <= dev->mtu)
399393
continue;
400394

@@ -404,26 +398,16 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
404398

405399
case NETDEV_FEAT_CHANGE:
406400
/* Propagate device features to underlying device */
407-
for (i = 0; i < VLAN_N_VID; i++) {
408-
vlandev = vlan_group_get_device(grp, i);
409-
if (!vlandev)
410-
continue;
411-
401+
vlan_group_for_each_dev(grp, i, vlandev)
412402
vlan_transfer_features(dev, vlandev);
413-
}
414-
415403
break;
416404

417405
case NETDEV_DOWN:
418406
if (dev->features & NETIF_F_HW_VLAN_CTAG_FILTER)
419407
vlan_vid_del(dev, htons(ETH_P_8021Q), 0);
420408

421409
/* Put all VLANs for this dev in the down state too. */
422-
for (i = 0; i < VLAN_N_VID; i++) {
423-
vlandev = vlan_group_get_device(grp, i);
424-
if (!vlandev)
425-
continue;
426-
410+
vlan_group_for_each_dev(grp, i, vlandev) {
427411
flgs = vlandev->flags;
428412
if (!(flgs & IFF_UP))
429413
continue;
@@ -437,11 +421,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
437421

438422
case NETDEV_UP:
439423
/* Put all VLANs for this dev in the up state too. */
440-
for (i = 0; i < VLAN_N_VID; i++) {
441-
vlandev = vlan_group_get_device(grp, i);
442-
if (!vlandev)
443-
continue;
444-
424+
vlan_group_for_each_dev(grp, i, vlandev) {
445425
flgs = vlandev->flags;
446426
if (flgs & IFF_UP)
447427
continue;
@@ -458,17 +438,15 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
458438
if (dev->reg_state != NETREG_UNREGISTERING)
459439
break;
460440

461-
for (i = 0; i < VLAN_N_VID; i++) {
462-
vlandev = vlan_group_get_device(grp, i);
463-
if (!vlandev)
464-
continue;
465-
441+
vlan_group_for_each_dev(grp, i, vlandev) {
466442
/* removal of last vid destroys vlan_info, abort
467443
* afterwards */
468444
if (vlan_info->nr_vids == 1)
469-
i = VLAN_N_VID;
445+
last = true;
470446

471447
unregister_vlan_dev(vlandev, &list);
448+
if (last)
449+
break;
472450
}
473451
unregister_netdevice_many(&list);
474452
break;
@@ -482,13 +460,8 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
482460
case NETDEV_NOTIFY_PEERS:
483461
case NETDEV_BONDING_FAILOVER:
484462
/* Propagate to vlan devices */
485-
for (i = 0; i < VLAN_N_VID; i++) {
486-
vlandev = vlan_group_get_device(grp, i);
487-
if (!vlandev)
488-
continue;
489-
463+
vlan_group_for_each_dev(grp, i, vlandev)
490464
call_netdevice_notifiers(event, vlandev);
491-
}
492465
break;
493466
}
494467

0 commit comments

Comments
 (0)