aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2019-04-19 16:58:17 -0400
committerDavid S. Miller <davem@davemloft.net>2019-04-19 16:58:17 -0400
commit1ab839281cf72476988901a2606378d76530f99c (patch)
treeba9d30159bb848eb705fa8d3c88e31b819e3921f
parent7d26c96052cd42439180edfeee48cc784075b78a (diff)
parent8e1acd4fc552f5590e9d5ff6e5cb5eeafd638d30 (diff)
Merge branch 'net-support-binding-vlan-dev-link-state-to-vlan-member-bridge-ports'
Mike Manning says: ==================== net: support binding vlan dev link state to vlan member bridge ports For vlan filtering on bridges, the bridge may also have vlan devices as upper devices. For switches, these are used to provide L3 packet processing for ports that are members of a given vlan. While it is correct that the admin state for these vlan devices is either set directly for the device or inherited from the lower device, the link state is also transferred from the lower device. So this is always up if the bridge is in admin up state and there is at least one bridge port that is up, regardless of the vlan that the port is in. The link state of the vlan device may need to track only the state of the subset of ports that are also members of the corresponding vlan, rather than that of all ports. This series provides an optional vlan flag so that the link state of the vlan device is only up if there is at least one bridge port that is up AND is a member of the corresponding vlan. v2: - Address review comments from Nikolay Aleksandrov in patches 3 & 4 and add patch 5 to address bridge link down due to STP v3: - Address review comment from Nikolay Aleksandrov in patch 4 so as to remove unnecessary inline #ifdef ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/uapi/linux/if_vlan.h9
-rw-r--r--net/8021q/vlan.c18
-rw-r--r--net/8021q/vlan_dev.c22
-rw-r--r--net/8021q/vlan_netlink.c3
-rw-r--r--net/bridge/br.c13
-rw-r--r--net/bridge/br_private.h14
-rw-r--r--net/bridge/br_vlan.c214
7 files changed, 272 insertions, 21 deletions
diff --git a/include/uapi/linux/if_vlan.h b/include/uapi/linux/if_vlan.h
index 7a0e8bd65b6b..90a2c89afc8f 100644
--- a/include/uapi/linux/if_vlan.h
+++ b/include/uapi/linux/if_vlan.h
@@ -32,10 +32,11 @@ enum vlan_ioctl_cmds {
32}; 32};
33 33
34enum vlan_flags { 34enum vlan_flags {
35 VLAN_FLAG_REORDER_HDR = 0x1, 35 VLAN_FLAG_REORDER_HDR = 0x1,
36 VLAN_FLAG_GVRP = 0x2, 36 VLAN_FLAG_GVRP = 0x2,
37 VLAN_FLAG_LOOSE_BINDING = 0x4, 37 VLAN_FLAG_LOOSE_BINDING = 0x4,
38 VLAN_FLAG_MVRP = 0x8, 38 VLAN_FLAG_MVRP = 0x8,
39 VLAN_FLAG_BRIDGE_BINDING = 0x10,
39}; 40};
40 41
41enum vlan_name_types { 42enum vlan_name_types {
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
index dc4411165e43..1f99678751df 100644
--- a/net/8021q/vlan.c
+++ b/net/8021q/vlan.c
@@ -75,6 +75,14 @@ static int vlan_group_prealloc_vid(struct vlan_group *vg,
75 return 0; 75 return 0;
76} 76}
77 77
78static void vlan_stacked_transfer_operstate(const struct net_device *rootdev,
79 struct net_device *dev,
80 struct vlan_dev_priv *vlan)
81{
82 if (!(vlan->flags & VLAN_FLAG_BRIDGE_BINDING))
83 netif_stacked_transfer_operstate(rootdev, dev);
84}
85
78void unregister_vlan_dev(struct net_device *dev, struct list_head *head) 86void unregister_vlan_dev(struct net_device *dev, struct list_head *head)
79{ 87{
80 struct vlan_dev_priv *vlan = vlan_dev_priv(dev); 88 struct vlan_dev_priv *vlan = vlan_dev_priv(dev);
@@ -180,7 +188,7 @@ int register_vlan_dev(struct net_device *dev, struct netlink_ext_ack *extack)
180 /* Account for reference in struct vlan_dev_priv */ 188 /* Account for reference in struct vlan_dev_priv */
181 dev_hold(real_dev); 189 dev_hold(real_dev);
182 190
183 netif_stacked_transfer_operstate(real_dev, dev); 191 vlan_stacked_transfer_operstate(real_dev, dev, vlan);
184 linkwatch_fire_event(dev); /* _MUST_ call rfc2863_policy() */ 192 linkwatch_fire_event(dev); /* _MUST_ call rfc2863_policy() */
185 193
186 /* So, got the sucker initialized, now lets place 194 /* So, got the sucker initialized, now lets place
@@ -399,7 +407,8 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
399 case NETDEV_CHANGE: 407 case NETDEV_CHANGE:
400 /* Propagate real device state to vlan devices */ 408 /* Propagate real device state to vlan devices */
401 vlan_group_for_each_dev(grp, i, vlandev) 409 vlan_group_for_each_dev(grp, i, vlandev)
402 netif_stacked_transfer_operstate(dev, vlandev); 410 vlan_stacked_transfer_operstate(dev, vlandev,
411 vlan_dev_priv(vlandev));
403 break; 412 break;
404 413
405 case NETDEV_CHANGEADDR: 414 case NETDEV_CHANGEADDR:
@@ -446,7 +455,8 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
446 dev_close_many(&close_list, false); 455 dev_close_many(&close_list, false);
447 456
448 list_for_each_entry_safe(vlandev, tmp, &close_list, close_list) { 457 list_for_each_entry_safe(vlandev, tmp, &close_list, close_list) {
449 netif_stacked_transfer_operstate(dev, vlandev); 458 vlan_stacked_transfer_operstate(dev, vlandev,
459 vlan_dev_priv(vlandev));
450 list_del_init(&vlandev->close_list); 460 list_del_init(&vlandev->close_list);
451 } 461 }
452 list_del(&close_list); 462 list_del(&close_list);
@@ -463,7 +473,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
463 if (!(vlan->flags & VLAN_FLAG_LOOSE_BINDING)) 473 if (!(vlan->flags & VLAN_FLAG_LOOSE_BINDING))
464 dev_change_flags(vlandev, flgs | IFF_UP, 474 dev_change_flags(vlandev, flgs | IFF_UP,
465 extack); 475 extack);
466 netif_stacked_transfer_operstate(dev, vlandev); 476 vlan_stacked_transfer_operstate(dev, vlandev, vlan);
467 } 477 }
468 break; 478 break;
469 479
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index 8d77b6ee4477..f044ae56a313 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -223,7 +223,8 @@ int vlan_dev_change_flags(const struct net_device *dev, u32 flags, u32 mask)
223 u32 old_flags = vlan->flags; 223 u32 old_flags = vlan->flags;
224 224
225 if (mask & ~(VLAN_FLAG_REORDER_HDR | VLAN_FLAG_GVRP | 225 if (mask & ~(VLAN_FLAG_REORDER_HDR | VLAN_FLAG_GVRP |
226 VLAN_FLAG_LOOSE_BINDING | VLAN_FLAG_MVRP)) 226 VLAN_FLAG_LOOSE_BINDING | VLAN_FLAG_MVRP |
227 VLAN_FLAG_BRIDGE_BINDING))
227 return -EINVAL; 228 return -EINVAL;
228 229
229 vlan->flags = (old_flags & ~mask) | (flags & mask); 230 vlan->flags = (old_flags & ~mask) | (flags & mask);
@@ -296,7 +297,8 @@ static int vlan_dev_open(struct net_device *dev)
296 if (vlan->flags & VLAN_FLAG_MVRP) 297 if (vlan->flags & VLAN_FLAG_MVRP)
297 vlan_mvrp_request_join(dev); 298 vlan_mvrp_request_join(dev);
298 299
299 if (netif_carrier_ok(real_dev)) 300 if (netif_carrier_ok(real_dev) &&
301 !(vlan->flags & VLAN_FLAG_BRIDGE_BINDING))
300 netif_carrier_on(dev); 302 netif_carrier_on(dev);
301 return 0; 303 return 0;
302 304
@@ -326,7 +328,8 @@ static int vlan_dev_stop(struct net_device *dev)
326 if (!ether_addr_equal(dev->dev_addr, real_dev->dev_addr)) 328 if (!ether_addr_equal(dev->dev_addr, real_dev->dev_addr))
327 dev_uc_del(real_dev, dev->dev_addr); 329 dev_uc_del(real_dev, dev->dev_addr);
328 330
329 netif_carrier_off(dev); 331 if (!(vlan->flags & VLAN_FLAG_BRIDGE_BINDING))
332 netif_carrier_off(dev);
330 return 0; 333 return 0;
331} 334}
332 335
@@ -550,7 +553,8 @@ static const struct net_device_ops vlan_netdev_ops;
550 553
551static int vlan_dev_init(struct net_device *dev) 554static int vlan_dev_init(struct net_device *dev)
552{ 555{
553 struct net_device *real_dev = vlan_dev_priv(dev)->real_dev; 556 struct vlan_dev_priv *vlan = vlan_dev_priv(dev);
557 struct net_device *real_dev = vlan->real_dev;
554 558
555 netif_carrier_off(dev); 559 netif_carrier_off(dev);
556 560
@@ -561,6 +565,9 @@ static int vlan_dev_init(struct net_device *dev)
561 (1<<__LINK_STATE_DORMANT))) | 565 (1<<__LINK_STATE_DORMANT))) |
562 (1<<__LINK_STATE_PRESENT); 566 (1<<__LINK_STATE_PRESENT);
563 567
568 if (vlan->flags & VLAN_FLAG_BRIDGE_BINDING)
569 dev->state |= (1 << __LINK_STATE_NOCARRIER);
570
564 dev->hw_features = NETIF_F_HW_CSUM | NETIF_F_SG | 571 dev->hw_features = NETIF_F_HW_CSUM | NETIF_F_SG |
565 NETIF_F_FRAGLIST | NETIF_F_GSO_SOFTWARE | 572 NETIF_F_FRAGLIST | NETIF_F_GSO_SOFTWARE |
566 NETIF_F_GSO_ENCAP_ALL | 573 NETIF_F_GSO_ENCAP_ALL |
@@ -591,8 +598,7 @@ static int vlan_dev_init(struct net_device *dev)
591#endif 598#endif
592 599
593 dev->needed_headroom = real_dev->needed_headroom; 600 dev->needed_headroom = real_dev->needed_headroom;
594 if (vlan_hw_offload_capable(real_dev->features, 601 if (vlan_hw_offload_capable(real_dev->features, vlan->vlan_proto)) {
595 vlan_dev_priv(dev)->vlan_proto)) {
596 dev->header_ops = &vlan_passthru_header_ops; 602 dev->header_ops = &vlan_passthru_header_ops;
597 dev->hard_header_len = real_dev->hard_header_len; 603 dev->hard_header_len = real_dev->hard_header_len;
598 } else { 604 } else {
@@ -606,8 +612,8 @@ static int vlan_dev_init(struct net_device *dev)
606 612
607 vlan_dev_set_lockdep_class(dev, vlan_dev_get_lock_subclass(dev)); 613 vlan_dev_set_lockdep_class(dev, vlan_dev_get_lock_subclass(dev));
608 614
609 vlan_dev_priv(dev)->vlan_pcpu_stats = netdev_alloc_pcpu_stats(struct vlan_pcpu_stats); 615 vlan->vlan_pcpu_stats = netdev_alloc_pcpu_stats(struct vlan_pcpu_stats);
610 if (!vlan_dev_priv(dev)->vlan_pcpu_stats) 616 if (!vlan->vlan_pcpu_stats)
611 return -ENOMEM; 617 return -ENOMEM;
612 618
613 return 0; 619 return 0;
diff --git a/net/8021q/vlan_netlink.c b/net/8021q/vlan_netlink.c
index 9b60c1e399e2..a624dccf68fd 100644
--- a/net/8021q/vlan_netlink.c
+++ b/net/8021q/vlan_netlink.c
@@ -84,7 +84,8 @@ static int vlan_validate(struct nlattr *tb[], struct nlattr *data[],
84 flags = nla_data(data[IFLA_VLAN_FLAGS]); 84 flags = nla_data(data[IFLA_VLAN_FLAGS]);
85 if ((flags->flags & flags->mask) & 85 if ((flags->flags & flags->mask) &
86 ~(VLAN_FLAG_REORDER_HDR | VLAN_FLAG_GVRP | 86 ~(VLAN_FLAG_REORDER_HDR | VLAN_FLAG_GVRP |
87 VLAN_FLAG_LOOSE_BINDING | VLAN_FLAG_MVRP)) { 87 VLAN_FLAG_LOOSE_BINDING | VLAN_FLAG_MVRP |
88 VLAN_FLAG_BRIDGE_BINDING)) {
88 NL_SET_ERR_MSG_MOD(extack, "Invalid VLAN flags"); 89 NL_SET_ERR_MSG_MOD(extack, "Invalid VLAN flags");
89 return -EINVAL; 90 return -EINVAL;
90 } 91 }
diff --git a/net/bridge/br.c b/net/bridge/br.c
index a5174e5001d8..e69fc87a13e0 100644
--- a/net/bridge/br.c
+++ b/net/bridge/br.c
@@ -40,10 +40,13 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v
40 bool changed_addr; 40 bool changed_addr;
41 int err; 41 int err;
42 42
43 /* register of bridge completed, add sysfs entries */ 43 if (dev->priv_flags & IFF_EBRIDGE) {
44 if ((dev->priv_flags & IFF_EBRIDGE) && event == NETDEV_REGISTER) { 44 if (event == NETDEV_REGISTER) {
45 br_sysfs_addbr(dev); 45 /* register of bridge completed, add sysfs entries */
46 return NOTIFY_DONE; 46 br_sysfs_addbr(dev);
47 return NOTIFY_DONE;
48 }
49 br_vlan_bridge_event(dev, event, ptr);
47 } 50 }
48 51
49 /* not a port of a bridge */ 52 /* not a port of a bridge */
@@ -126,6 +129,8 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v
126 break; 129 break;
127 } 130 }
128 131
132 br_vlan_port_event(p, event);
133
129 /* Events that may cause spanning tree to refresh */ 134 /* Events that may cause spanning tree to refresh */
130 if (!notified && (event == NETDEV_CHANGEADDR || event == NETDEV_UP || 135 if (!notified && (event == NETDEV_CHANGEADDR || event == NETDEV_UP ||
131 event == NETDEV_CHANGE || event == NETDEV_DOWN)) 136 event == NETDEV_CHANGE || event == NETDEV_DOWN))
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 4bea2f11da9b..334a8c496b50 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -321,6 +321,7 @@ enum net_bridge_opts {
321 BROPT_MTU_SET_BY_USER, 321 BROPT_MTU_SET_BY_USER,
322 BROPT_VLAN_STATS_PER_PORT, 322 BROPT_VLAN_STATS_PER_PORT,
323 BROPT_NO_LL_LEARN, 323 BROPT_NO_LL_LEARN,
324 BROPT_VLAN_BRIDGE_BINDING,
324}; 325};
325 326
326struct net_bridge { 327struct net_bridge {
@@ -895,6 +896,9 @@ int nbp_vlan_init(struct net_bridge_port *port, struct netlink_ext_ack *extack);
895int nbp_get_num_vlan_infos(struct net_bridge_port *p, u32 filter_mask); 896int nbp_get_num_vlan_infos(struct net_bridge_port *p, u32 filter_mask);
896void br_vlan_get_stats(const struct net_bridge_vlan *v, 897void br_vlan_get_stats(const struct net_bridge_vlan *v,
897 struct br_vlan_stats *stats); 898 struct br_vlan_stats *stats);
899void br_vlan_port_event(struct net_bridge_port *p, unsigned long event);
900void br_vlan_bridge_event(struct net_device *dev, unsigned long event,
901 void *ptr);
898 902
899static inline struct net_bridge_vlan_group *br_vlan_group( 903static inline struct net_bridge_vlan_group *br_vlan_group(
900 const struct net_bridge *br) 904 const struct net_bridge *br)
@@ -1078,6 +1082,16 @@ static inline void br_vlan_get_stats(const struct net_bridge_vlan *v,
1078 struct br_vlan_stats *stats) 1082 struct br_vlan_stats *stats)
1079{ 1083{
1080} 1084}
1085
1086static inline void br_vlan_port_event(struct net_bridge_port *p,
1087 unsigned long event)
1088{
1089}
1090
1091static inline void br_vlan_bridge_event(struct net_device *dev,
1092 unsigned long event, void *ptr)
1093{
1094}
1081#endif 1095#endif
1082 1096
1083struct nf_br_ops { 1097struct nf_br_ops {
diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c
index 0a02822b5667..2db63997f313 100644
--- a/net/bridge/br_vlan.c
+++ b/net/bridge/br_vlan.c
@@ -7,6 +7,8 @@
7#include "br_private.h" 7#include "br_private.h"
8#include "br_private_tunnel.h" 8#include "br_private_tunnel.h"
9 9
10static void nbp_vlan_set_vlan_dev_state(struct net_bridge_port *p, u16 vid);
11
10static inline int br_vlan_cmp(struct rhashtable_compare_arg *arg, 12static inline int br_vlan_cmp(struct rhashtable_compare_arg *arg,
11 const void *ptr) 13 const void *ptr)
12{ 14{
@@ -293,6 +295,9 @@ static int __vlan_add(struct net_bridge_vlan *v, u16 flags,
293 295
294 __vlan_add_list(v); 296 __vlan_add_list(v);
295 __vlan_add_flags(v, flags); 297 __vlan_add_flags(v, flags);
298
299 if (p)
300 nbp_vlan_set_vlan_dev_state(p, v->vid);
296out: 301out:
297 return err; 302 return err;
298 303
@@ -357,6 +362,7 @@ static int __vlan_del(struct net_bridge_vlan *v)
357 rhashtable_remove_fast(&vg->vlan_hash, &v->vnode, 362 rhashtable_remove_fast(&vg->vlan_hash, &v->vnode,
358 br_vlan_rht_params); 363 br_vlan_rht_params);
359 __vlan_del_list(v); 364 __vlan_del_list(v);
365 nbp_vlan_set_vlan_dev_state(p, v->vid);
360 call_rcu(&v->rcu, nbp_vlan_rcu_free); 366 call_rcu(&v->rcu, nbp_vlan_rcu_free);
361 } 367 }
362 368
@@ -1264,3 +1270,211 @@ int br_vlan_get_info(const struct net_device *dev, u16 vid,
1264 return 0; 1270 return 0;
1265} 1271}
1266EXPORT_SYMBOL_GPL(br_vlan_get_info); 1272EXPORT_SYMBOL_GPL(br_vlan_get_info);
1273
1274static int br_vlan_is_bind_vlan_dev(const struct net_device *dev)
1275{
1276 return is_vlan_dev(dev) &&
1277 !!(vlan_dev_priv(dev)->flags & VLAN_FLAG_BRIDGE_BINDING);
1278}
1279
1280static int br_vlan_is_bind_vlan_dev_fn(struct net_device *dev,
1281 __always_unused void *data)
1282{
1283 return br_vlan_is_bind_vlan_dev(dev);
1284}
1285
1286static bool br_vlan_has_upper_bind_vlan_dev(struct net_device *dev)
1287{
1288 int found;
1289
1290 rcu_read_lock();
1291 found = netdev_walk_all_upper_dev_rcu(dev, br_vlan_is_bind_vlan_dev_fn,
1292 NULL);
1293 rcu_read_unlock();
1294
1295 return !!found;
1296}
1297
1298struct br_vlan_bind_walk_data {
1299 u16 vid;
1300 struct net_device *result;
1301};
1302
1303static int br_vlan_match_bind_vlan_dev_fn(struct net_device *dev,
1304 void *data_in)
1305{
1306 struct br_vlan_bind_walk_data *data = data_in;
1307 int found = 0;
1308
1309 if (br_vlan_is_bind_vlan_dev(dev) &&
1310 vlan_dev_priv(dev)->vlan_id == data->vid) {
1311 data->result = dev;
1312 found = 1;
1313 }
1314
1315 return found;
1316}
1317
1318static struct net_device *
1319br_vlan_get_upper_bind_vlan_dev(struct net_device *dev, u16 vid)
1320{
1321 struct br_vlan_bind_walk_data data = {
1322 .vid = vid,
1323 };
1324
1325 rcu_read_lock();
1326 netdev_walk_all_upper_dev_rcu(dev, br_vlan_match_bind_vlan_dev_fn,
1327 &data);
1328 rcu_read_unlock();
1329
1330 return data.result;
1331}
1332
1333static bool br_vlan_is_dev_up(const struct net_device *dev)
1334{
1335 return !!(dev->flags & IFF_UP) && netif_oper_up(dev);
1336}
1337
1338static void br_vlan_set_vlan_dev_state(const struct net_bridge *br,
1339 struct net_device *vlan_dev)
1340{
1341 u16 vid = vlan_dev_priv(vlan_dev)->vlan_id;
1342 struct net_bridge_vlan_group *vg;
1343 struct net_bridge_port *p;
1344 bool has_carrier = false;
1345
1346 if (!netif_carrier_ok(br->dev)) {
1347 netif_carrier_off(vlan_dev);
1348 return;
1349 }
1350
1351 list_for_each_entry(p, &br->port_list, list) {
1352 vg = nbp_vlan_group(p);
1353 if (br_vlan_find(vg, vid) && br_vlan_is_dev_up(p->dev)) {
1354 has_carrier = true;
1355 break;
1356 }
1357 }
1358
1359 if (has_carrier)
1360 netif_carrier_on(vlan_dev);
1361 else
1362 netif_carrier_off(vlan_dev);
1363}
1364
1365static void br_vlan_set_all_vlan_dev_state(struct net_bridge_port *p)
1366{
1367 struct net_bridge_vlan_group *vg = nbp_vlan_group(p);
1368 struct net_bridge_vlan *vlan;
1369 struct net_device *vlan_dev;
1370
1371 list_for_each_entry(vlan, &vg->vlan_list, vlist) {
1372 vlan_dev = br_vlan_get_upper_bind_vlan_dev(p->br->dev,
1373 vlan->vid);
1374 if (vlan_dev) {
1375 if (br_vlan_is_dev_up(p->dev)) {
1376 if (netif_carrier_ok(p->br->dev))
1377 netif_carrier_on(vlan_dev);
1378 } else {
1379 br_vlan_set_vlan_dev_state(p->br, vlan_dev);
1380 }
1381 }
1382 }
1383}
1384
1385static void br_vlan_upper_change(struct net_device *dev,
1386 struct net_device *upper_dev,
1387 bool linking)
1388{
1389 struct net_bridge *br = netdev_priv(dev);
1390
1391 if (!br_vlan_is_bind_vlan_dev(upper_dev))
1392 return;
1393
1394 if (linking) {
1395 br_vlan_set_vlan_dev_state(br, upper_dev);
1396 br_opt_toggle(br, BROPT_VLAN_BRIDGE_BINDING, true);
1397 } else {
1398 br_opt_toggle(br, BROPT_VLAN_BRIDGE_BINDING,
1399 br_vlan_has_upper_bind_vlan_dev(dev));
1400 }
1401}
1402
1403struct br_vlan_link_state_walk_data {
1404 struct net_bridge *br;
1405};
1406
1407static int br_vlan_link_state_change_fn(struct net_device *vlan_dev,
1408 void *data_in)
1409{
1410 struct br_vlan_link_state_walk_data *data = data_in;
1411
1412 if (br_vlan_is_bind_vlan_dev(vlan_dev))
1413 br_vlan_set_vlan_dev_state(data->br, vlan_dev);
1414
1415 return 0;
1416}
1417
1418static void br_vlan_link_state_change(struct net_device *dev,
1419 struct net_bridge *br)
1420{
1421 struct br_vlan_link_state_walk_data data = {
1422 .br = br
1423 };
1424
1425 rcu_read_lock();
1426 netdev_walk_all_upper_dev_rcu(dev, br_vlan_link_state_change_fn,
1427 &data);
1428 rcu_read_unlock();
1429}
1430
1431/* Must be protected by RTNL. */
1432static void nbp_vlan_set_vlan_dev_state(struct net_bridge_port *p, u16 vid)
1433{
1434 struct net_device *vlan_dev;
1435
1436 if (!br_opt_get(p->br, BROPT_VLAN_BRIDGE_BINDING))
1437 return;
1438
1439 vlan_dev = br_vlan_get_upper_bind_vlan_dev(p->br->dev, vid);
1440 if (vlan_dev)
1441 br_vlan_set_vlan_dev_state(p->br, vlan_dev);
1442}
1443
1444/* Must be protected by RTNL. */
1445void br_vlan_bridge_event(struct net_device *dev, unsigned long event,
1446 void *ptr)
1447{
1448 struct netdev_notifier_changeupper_info *info;
1449 struct net_bridge *br;
1450
1451 switch (event) {
1452 case NETDEV_CHANGEUPPER:
1453 info = ptr;
1454 br_vlan_upper_change(dev, info->upper_dev, info->linking);
1455 break;
1456
1457 case NETDEV_CHANGE:
1458 case NETDEV_UP:
1459 br = netdev_priv(dev);
1460 if (!br_opt_get(br, BROPT_VLAN_BRIDGE_BINDING))
1461 return;
1462 br_vlan_link_state_change(dev, br);
1463 break;
1464 }
1465}
1466
1467/* Must be protected by RTNL. */
1468void br_vlan_port_event(struct net_bridge_port *p, unsigned long event)
1469{
1470 if (!br_opt_get(p->br, BROPT_VLAN_BRIDGE_BINDING))
1471 return;
1472
1473 switch (event) {
1474 case NETDEV_CHANGE:
1475 case NETDEV_DOWN:
1476 case NETDEV_UP:
1477 br_vlan_set_all_vlan_dev_state(p);
1478 break;
1479 }
1480}