Re: [patch net 1/6] switchdev: Execute bridge ndos only for bridge ports

2016-10-19 Thread David Miller
From: Jiri Pirko 
Date: Tue, 18 Oct 2016 18:50:23 +0200

> From: Ido Schimmel 
> 
> We recently got the following warning after setting up a vlan device on
> top of an offloaded bridge and executing 'bridge link':
...
> 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 

Applied and queued up for -stable, thanks.


Re: [patch net 1/6] switchdev: Execute bridge ndos only for bridge ports

2016-10-18 Thread Jiri Pirko
That's it. Only one patch :)


[patch net 1/6] switchdev: Execute bridge ndos only for bridge ports

2016-10-18 Thread Jiri Pirko
From: Ido Schimmel 

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
  0286 e64ab94f 880406e6f8f0 8135eaa3
    880406e6f930 8108c43b
  005106e6f988 8803df398840 880403c60108 880406e6f990
 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 
---
Please queue-up to stable as well. Thanks.
---
 net/switchdev/switchdev.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c
index 02beb35..3b95fe9 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)
-- 
2.5.5