Commit 9b63ef88 authored by Ido Schimmel's avatar Ido Schimmel Committed by David S. Miller

mlxsw: spectrum: Propagate extack further for bridge enslavements

The code that actually takes care of bridge offload introduces a few
more non-trivial constraints with regards to bridge enslavements.
Propagate extack there to indicate the reason.

$ ip link add link enp1s0np1 name enp1s0np1.10 type vlan id 10
$ ip link add link enp1s0np1 name enp1s0np1.20 type vlan id 20
$ ip link add name br0 type bridge
$ ip link set dev enp1s0np1.10 master br0
$ ip link set dev enp1s0np1.20 master br0
Error: spectrum: Can not bridge VLAN uppers of the same port.
Signed-off-by: default avatarIdo Schimmel <idosch@mellanox.com>
Signed-off-by: default avatarJiri Pirko <jiri@mellanox.com>
Acked-by: default avatarDavid Ahern <dsahern@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent c1f2c6d0
...@@ -4299,7 +4299,8 @@ static int mlxsw_sp_netdevice_port_upper_event(struct net_device *lower_dev, ...@@ -4299,7 +4299,8 @@ static int mlxsw_sp_netdevice_port_upper_event(struct net_device *lower_dev,
if (info->linking) if (info->linking)
err = mlxsw_sp_port_bridge_join(mlxsw_sp_port, err = mlxsw_sp_port_bridge_join(mlxsw_sp_port,
lower_dev, lower_dev,
upper_dev); upper_dev,
extack);
else else
mlxsw_sp_port_bridge_leave(mlxsw_sp_port, mlxsw_sp_port_bridge_leave(mlxsw_sp_port,
lower_dev, lower_dev,
...@@ -4416,7 +4417,8 @@ static int mlxsw_sp_netdevice_port_vlan_event(struct net_device *vlan_dev, ...@@ -4416,7 +4417,8 @@ static int mlxsw_sp_netdevice_port_vlan_event(struct net_device *vlan_dev,
if (info->linking) if (info->linking)
err = mlxsw_sp_port_bridge_join(mlxsw_sp_port, err = mlxsw_sp_port_bridge_join(mlxsw_sp_port,
vlan_dev, vlan_dev,
upper_dev); upper_dev,
extack);
else else
mlxsw_sp_port_bridge_leave(mlxsw_sp_port, mlxsw_sp_port_bridge_leave(mlxsw_sp_port,
vlan_dev, vlan_dev,
......
...@@ -326,7 +326,8 @@ void ...@@ -326,7 +326,8 @@ void
mlxsw_sp_port_vlan_bridge_leave(struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan); mlxsw_sp_port_vlan_bridge_leave(struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan);
int mlxsw_sp_port_bridge_join(struct mlxsw_sp_port *mlxsw_sp_port, int mlxsw_sp_port_bridge_join(struct mlxsw_sp_port *mlxsw_sp_port,
struct net_device *brport_dev, struct net_device *brport_dev,
struct net_device *br_dev); struct net_device *br_dev,
struct netlink_ext_ack *extack);
void mlxsw_sp_port_bridge_leave(struct mlxsw_sp_port *mlxsw_sp_port, void mlxsw_sp_port_bridge_leave(struct mlxsw_sp_port *mlxsw_sp_port,
struct net_device *brport_dev, struct net_device *brport_dev,
struct net_device *br_dev); struct net_device *br_dev);
......
...@@ -46,6 +46,7 @@ ...@@ -46,6 +46,7 @@
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/rtnetlink.h> #include <linux/rtnetlink.h>
#include <linux/netlink.h>
#include <net/switchdev.h> #include <net/switchdev.h>
#include "spectrum.h" #include "spectrum.h"
...@@ -107,7 +108,8 @@ struct mlxsw_sp_bridge_vlan { ...@@ -107,7 +108,8 @@ struct mlxsw_sp_bridge_vlan {
struct mlxsw_sp_bridge_ops { struct mlxsw_sp_bridge_ops {
int (*port_join)(struct mlxsw_sp_bridge_device *bridge_device, int (*port_join)(struct mlxsw_sp_bridge_device *bridge_device,
struct mlxsw_sp_bridge_port *bridge_port, struct mlxsw_sp_bridge_port *bridge_port,
struct mlxsw_sp_port *mlxsw_sp_port); struct mlxsw_sp_port *mlxsw_sp_port,
struct netlink_ext_ack *extack);
void (*port_leave)(struct mlxsw_sp_bridge_device *bridge_device, void (*port_leave)(struct mlxsw_sp_bridge_device *bridge_device,
struct mlxsw_sp_bridge_port *bridge_port, struct mlxsw_sp_bridge_port *bridge_port,
struct mlxsw_sp_port *mlxsw_sp_port); struct mlxsw_sp_port *mlxsw_sp_port);
...@@ -1735,12 +1737,15 @@ static const struct switchdev_ops mlxsw_sp_port_switchdev_ops = { ...@@ -1735,12 +1737,15 @@ static const struct switchdev_ops mlxsw_sp_port_switchdev_ops = {
static int static int
mlxsw_sp_bridge_8021q_port_join(struct mlxsw_sp_bridge_device *bridge_device, mlxsw_sp_bridge_8021q_port_join(struct mlxsw_sp_bridge_device *bridge_device,
struct mlxsw_sp_bridge_port *bridge_port, struct mlxsw_sp_bridge_port *bridge_port,
struct mlxsw_sp_port *mlxsw_sp_port) struct mlxsw_sp_port *mlxsw_sp_port,
struct netlink_ext_ack *extack)
{ {
struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan; struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan;
if (is_vlan_dev(bridge_port->dev)) if (is_vlan_dev(bridge_port->dev)) {
NL_SET_ERR_MSG(extack, "spectrum: Can not enslave a VLAN device to a VLAN-aware bridge");
return -EINVAL; return -EINVAL;
}
mlxsw_sp_port_vlan = mlxsw_sp_port_vlan_find_by_vid(mlxsw_sp_port, 1); mlxsw_sp_port_vlan = mlxsw_sp_port_vlan_find_by_vid(mlxsw_sp_port, 1);
if (WARN_ON(!mlxsw_sp_port_vlan)) if (WARN_ON(!mlxsw_sp_port_vlan))
...@@ -1797,13 +1802,16 @@ mlxsw_sp_port_is_br_member(const struct mlxsw_sp_port *mlxsw_sp_port, ...@@ -1797,13 +1802,16 @@ mlxsw_sp_port_is_br_member(const struct mlxsw_sp_port *mlxsw_sp_port,
static int static int
mlxsw_sp_bridge_8021d_port_join(struct mlxsw_sp_bridge_device *bridge_device, mlxsw_sp_bridge_8021d_port_join(struct mlxsw_sp_bridge_device *bridge_device,
struct mlxsw_sp_bridge_port *bridge_port, struct mlxsw_sp_bridge_port *bridge_port,
struct mlxsw_sp_port *mlxsw_sp_port) struct mlxsw_sp_port *mlxsw_sp_port,
struct netlink_ext_ack *extack)
{ {
struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan; struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan;
u16 vid; u16 vid;
if (!is_vlan_dev(bridge_port->dev)) if (!is_vlan_dev(bridge_port->dev)) {
NL_SET_ERR_MSG(extack, "spectrum: Only VLAN devices can be enslaved to a VLAN-unaware bridge");
return -EINVAL; return -EINVAL;
}
vid = vlan_dev_vlan_id(bridge_port->dev); vid = vlan_dev_vlan_id(bridge_port->dev);
mlxsw_sp_port_vlan = mlxsw_sp_port_vlan_find_by_vid(mlxsw_sp_port, vid); mlxsw_sp_port_vlan = mlxsw_sp_port_vlan_find_by_vid(mlxsw_sp_port, vid);
...@@ -1811,7 +1819,7 @@ mlxsw_sp_bridge_8021d_port_join(struct mlxsw_sp_bridge_device *bridge_device, ...@@ -1811,7 +1819,7 @@ mlxsw_sp_bridge_8021d_port_join(struct mlxsw_sp_bridge_device *bridge_device,
return -EINVAL; return -EINVAL;
if (mlxsw_sp_port_is_br_member(mlxsw_sp_port, bridge_device->dev)) { if (mlxsw_sp_port_is_br_member(mlxsw_sp_port, bridge_device->dev)) {
netdev_err(mlxsw_sp_port->dev, "Can't bridge VLAN uppers of the same port\n"); NL_SET_ERR_MSG(extack, "spectrum: Can not bridge VLAN uppers of the same port");
return -EINVAL; return -EINVAL;
} }
...@@ -1854,7 +1862,8 @@ static const struct mlxsw_sp_bridge_ops mlxsw_sp_bridge_8021d_ops = { ...@@ -1854,7 +1862,8 @@ static const struct mlxsw_sp_bridge_ops mlxsw_sp_bridge_8021d_ops = {
int mlxsw_sp_port_bridge_join(struct mlxsw_sp_port *mlxsw_sp_port, int mlxsw_sp_port_bridge_join(struct mlxsw_sp_port *mlxsw_sp_port,
struct net_device *brport_dev, struct net_device *brport_dev,
struct net_device *br_dev) struct net_device *br_dev,
struct netlink_ext_ack *extack)
{ {
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp; struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
struct mlxsw_sp_bridge_device *bridge_device; struct mlxsw_sp_bridge_device *bridge_device;
...@@ -1867,7 +1876,7 @@ int mlxsw_sp_port_bridge_join(struct mlxsw_sp_port *mlxsw_sp_port, ...@@ -1867,7 +1876,7 @@ int mlxsw_sp_port_bridge_join(struct mlxsw_sp_port *mlxsw_sp_port,
bridge_device = bridge_port->bridge_device; bridge_device = bridge_port->bridge_device;
err = bridge_device->ops->port_join(bridge_device, bridge_port, err = bridge_device->ops->port_join(bridge_device, bridge_port,
mlxsw_sp_port); mlxsw_sp_port, extack);
if (err) if (err)
goto err_port_join; goto err_port_join;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment