diff options
author | Jiri Pirko <jiri@mellanox.com> | 2015-10-14 13:40:55 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-10-15 09:09:53 -0400 |
commit | 771acac2ffa5957b91e881908cd4c9657978a209 (patch) | |
tree | 7d6671c6e2f27c0b04ce775d913f09384b89e07f /net/switchdev/switchdev.c | |
parent | d33eeb645d59ffd14bbc6db977c3783af42dd700 (diff) |
switchdev: assert rtnl mutex when going over lower netdevs
netdev_for_each_lower_dev has to be called with rtnl mutex held. So
better enforce it in switchdev functions.
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/switchdev/switchdev.c')
-rw-r--r-- | net/switchdev/switchdev.c | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c index eac68c4e57ec..73e3895175cf 100644 --- a/net/switchdev/switchdev.c +++ b/net/switchdev/switchdev.c | |||
@@ -520,6 +520,8 @@ EXPORT_SYMBOL_GPL(switchdev_port_obj_del); | |||
520 | * @id: object ID | 520 | * @id: object ID |
521 | * @obj: object to dump | 521 | * @obj: object to dump |
522 | * @cb: function to call with a filled object | 522 | * @cb: function to call with a filled object |
523 | * | ||
524 | * rtnl_lock must be held. | ||
523 | */ | 525 | */ |
524 | int switchdev_port_obj_dump(struct net_device *dev, struct switchdev_obj *obj, | 526 | int switchdev_port_obj_dump(struct net_device *dev, struct switchdev_obj *obj, |
525 | switchdev_obj_dump_cb_t *cb) | 527 | switchdev_obj_dump_cb_t *cb) |
@@ -529,6 +531,8 @@ int switchdev_port_obj_dump(struct net_device *dev, struct switchdev_obj *obj, | |||
529 | struct list_head *iter; | 531 | struct list_head *iter; |
530 | int err = -EOPNOTSUPP; | 532 | int err = -EOPNOTSUPP; |
531 | 533 | ||
534 | ASSERT_RTNL(); | ||
535 | |||
532 | if (ops && ops->switchdev_port_obj_dump) | 536 | if (ops && ops->switchdev_port_obj_dump) |
533 | return ops->switchdev_port_obj_dump(dev, obj, cb); | 537 | return ops->switchdev_port_obj_dump(dev, obj, cb); |
534 | 538 | ||
@@ -1097,6 +1101,8 @@ static struct net_device *switchdev_get_dev_by_nhs(struct fib_info *fi) | |||
1097 | struct net_device *dev = NULL; | 1101 | struct net_device *dev = NULL; |
1098 | int nhsel; | 1102 | int nhsel; |
1099 | 1103 | ||
1104 | ASSERT_RTNL(); | ||
1105 | |||
1100 | /* For this route, all nexthop devs must be on the same switch. */ | 1106 | /* For this route, all nexthop devs must be on the same switch. */ |
1101 | 1107 | ||
1102 | for (nhsel = 0; nhsel < fi->fib_nhs; nhsel++) { | 1108 | for (nhsel = 0; nhsel < fi->fib_nhs; nhsel++) { |
@@ -1327,10 +1333,11 @@ void switchdev_port_fwd_mark_set(struct net_device *dev, | |||
1327 | u32 mark = dev->ifindex; | 1333 | u32 mark = dev->ifindex; |
1328 | u32 reset_mark = 0; | 1334 | u32 reset_mark = 0; |
1329 | 1335 | ||
1330 | if (group_dev && joining) { | 1336 | if (group_dev) { |
1331 | mark = switchdev_port_fwd_mark_get(dev, group_dev); | 1337 | ASSERT_RTNL(); |
1332 | } else if (group_dev && !joining) { | 1338 | if (joining) |
1333 | if (dev->offload_fwd_mark == mark) | 1339 | mark = switchdev_port_fwd_mark_get(dev, group_dev); |
1340 | else if (dev->offload_fwd_mark == mark) | ||
1334 | /* Ohoh, this port was the mark reference port, | 1341 | /* Ohoh, this port was the mark reference port, |
1335 | * but it's leaving the group, so reset the | 1342 | * but it's leaving the group, so reset the |
1336 | * mark for the remaining ports in the group. | 1343 | * mark for the remaining ports in the group. |