diff options
author | Jiri Pirko <jiri@mellanox.com> | 2015-10-14 19:40:55 +0200 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-10-15 06:09:53 -0700 |
commit | 771acac2ffa5957b91e881908cd4c9657978a209 (patch) | |
tree | 7d6671c6e2f27c0b04ce775d913f09384b89e07f | |
parent | d33eeb645d59ffd14bbc6db977c3783af42dd700 (diff) | |
download | lwn-771acac2ffa5957b91e881908cd4c9657978a209.tar.gz lwn-771acac2ffa5957b91e881908cd4c9657978a209.zip |
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>
-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); * @id: object ID * @obj: object to dump * @cb: function to call with a filled object + * + * rtnl_lock must be held. */ int switchdev_port_obj_dump(struct net_device *dev, struct switchdev_obj *obj, switchdev_obj_dump_cb_t *cb) @@ -529,6 +531,8 @@ int switchdev_port_obj_dump(struct net_device *dev, struct switchdev_obj *obj, struct list_head *iter; int err = -EOPNOTSUPP; + ASSERT_RTNL(); + if (ops && ops->switchdev_port_obj_dump) return ops->switchdev_port_obj_dump(dev, obj, cb); @@ -1097,6 +1101,8 @@ static struct net_device *switchdev_get_dev_by_nhs(struct fib_info *fi) struct net_device *dev = NULL; int nhsel; + ASSERT_RTNL(); + /* For this route, all nexthop devs must be on the same switch. */ for (nhsel = 0; nhsel < fi->fib_nhs; nhsel++) { @@ -1327,10 +1333,11 @@ void switchdev_port_fwd_mark_set(struct net_device *dev, u32 mark = dev->ifindex; u32 reset_mark = 0; - if (group_dev && joining) { - mark = switchdev_port_fwd_mark_get(dev, group_dev); - } else if (group_dev && !joining) { - if (dev->offload_fwd_mark == mark) + if (group_dev) { + ASSERT_RTNL(); + if (joining) + mark = switchdev_port_fwd_mark_get(dev, group_dev); + else if (dev->offload_fwd_mark == mark) /* Ohoh, this port was the mark reference port, * but it's leaving the group, so reset the * mark for the remaining ports in the group. |