From 97c242902c209e7d46e365335db5202634484dcb Mon Sep 17 00:00:00 2001 From: Ido Schimmel Date: Tue, 18 Oct 2016 18:50:23 +0200 Subject: switchdev: Execute bridge ndos only for bridge ports We recently got the following warning after setting up a vlan device on top of an offloaded bridge and executing 'bridge link': WARNING: CPU: 0 PID: 18566 at drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c:81 mlxsw_sp_port_orig_get.part.9+0x55/0x70 [mlxsw_spectrum] [...] CPU: 0 PID: 18566 Comm: bridge Not tainted 4.8.0-rc7 #1 Hardware name: Mellanox Technologies Ltd. Mellanox switch/Mellanox switch, BIOS 4.6.5 05/21/2015 0000000000000286 00000000e64ab94f ffff880406e6f8f0 ffffffff8135eaa3 0000000000000000 0000000000000000 ffff880406e6f930 ffffffff8108c43b 0000005106e6f988 ffff8803df398840 ffff880403c60108 ffff880406e6f990 Call Trace: [] dump_stack+0x63/0x90 [] __warn+0xcb/0xf0 [] warn_slowpath_null+0x1d/0x20 [] mlxsw_sp_port_orig_get.part.9+0x55/0x70 [mlxsw_spectrum] [] mlxsw_sp_port_attr_get+0xa5/0xb0 [mlxsw_spectrum] [] switchdev_port_attr_get+0x4f/0x140 [] switchdev_port_attr_get+0x100/0x140 [] switchdev_port_attr_get+0x100/0x140 [] switchdev_port_bridge_getlink+0x5b/0xc0 [] ? switchdev_port_fdb_dump+0x90/0x90 [] rtnl_bridge_getlink+0xe7/0x190 [] netlink_dump+0x122/0x290 [] __netlink_dump_start+0x15f/0x190 [] ? rtnl_bridge_dellink+0x230/0x230 [] rtnetlink_rcv_msg+0x1a6/0x220 [] ? __kmalloc_node_track_caller+0x208/0x2c0 [] ? rtnl_bridge_dellink+0x230/0x230 [] ? rtnl_newlink+0x890/0x890 [] netlink_rcv_skb+0xa4/0xc0 [] rtnetlink_rcv+0x28/0x30 [] netlink_unicast+0x18c/0x240 [] netlink_sendmsg+0x2fb/0x3a0 [] sock_sendmsg+0x38/0x50 [] SYSC_sendto+0x101/0x190 [] ? __sys_recvmsg+0x51/0x90 [] SyS_sendto+0xe/0x10 [] entry_SYSCALL_64_fastpath+0x1a/0xa4 The problem is that the 8021q module propagates the call to ndo_bridge_getlink() via switchdev ops, but the switch driver doesn't recognize the netdev, as it's not offloaded. While we can ignore calls being made to non-bridge ports inside the driver, a better fix would be to push this check up to the switchdev layer. Note that these ndos can be called for non-bridged netdev, but this only happens in certain PF drivers which don't call the corresponding switchdev functions anyway. Fixes: 99f44bb3527b ("mlxsw: spectrum: Enable L3 interfaces on top of bridge devices") Signed-off-by: Ido Schimmel Reported-by: Tamir Winetroub Tested-by: Tamir Winetroub Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- net/switchdev/switchdev.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c index 02beb35f577f..3b95fe980fa2 100644 --- a/net/switchdev/switchdev.c +++ b/net/switchdev/switchdev.c @@ -771,6 +771,9 @@ int switchdev_port_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq, u32 mask = BR_LEARNING | BR_LEARNING_SYNC | BR_FLOOD; int err; + if (!netif_is_bridge_port(dev)) + return -EOPNOTSUPP; + err = switchdev_port_attr_get(dev, &attr); if (err && err != -EOPNOTSUPP) return err; @@ -926,6 +929,9 @@ int switchdev_port_bridge_setlink(struct net_device *dev, struct nlattr *afspec; int err = 0; + if (!netif_is_bridge_port(dev)) + return -EOPNOTSUPP; + protinfo = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_PROTINFO); if (protinfo) { @@ -959,6 +965,9 @@ int switchdev_port_bridge_dellink(struct net_device *dev, { struct nlattr *afspec; + if (!netif_is_bridge_port(dev)) + return -EOPNOTSUPP; + afspec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC); if (afspec) -- cgit v1.2.3