Commit 0944d6b5 authored by Jiri Pirko's avatar Jiri Pirko Committed by David S. Miller

bridge: try switchdev op first in __vlan_vid_add/del

Some drivers need to implement both switchdev vlan ops and
vid_add/kill ndos. For that to work in bridge code, we need to try
switchdev op first when adding/deleting vlan id.
Signed-off-by: default avatarJiri Pirko <jiri@mellanox.com>
Signed-off-by: default avatarIdo Schimmel <idosch@mellanox.com>
Acked-by: default avatarScott Feldman <sfeldma@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 3703ebe4
...@@ -72,28 +72,20 @@ static void __vlan_add_flags(struct net_bridge_vlan *v, u16 flags) ...@@ -72,28 +72,20 @@ static void __vlan_add_flags(struct net_bridge_vlan *v, u16 flags)
static int __vlan_vid_add(struct net_device *dev, struct net_bridge *br, static int __vlan_vid_add(struct net_device *dev, struct net_bridge *br,
u16 vid, u16 flags) u16 vid, u16 flags)
{ {
const struct net_device_ops *ops = dev->netdev_ops; struct switchdev_obj_port_vlan v = {
.obj.id = SWITCHDEV_OBJ_ID_PORT_VLAN,
.flags = flags,
.vid_begin = vid,
.vid_end = vid,
};
int err; int err;
/* If driver uses VLAN ndo ops, use 8021q to install vid /* Try switchdev op first. In case it is not supported, fallback to
* on device, otherwise try switchdev ops to install vid. * 8021q add.
*/ */
err = switchdev_port_obj_add(dev, &v.obj);
if (ops->ndo_vlan_rx_add_vid) { if (err == -EOPNOTSUPP)
err = vlan_vid_add(dev, br->vlan_proto, vid); return vlan_vid_add(dev, br->vlan_proto, vid);
} else {
struct switchdev_obj_port_vlan v = {
.obj.id = SWITCHDEV_OBJ_ID_PORT_VLAN,
.flags = flags,
.vid_begin = vid,
.vid_end = vid,
};
err = switchdev_port_obj_add(dev, &v.obj);
if (err == -EOPNOTSUPP)
err = 0;
}
return err; return err;
} }
...@@ -122,27 +114,21 @@ static void __vlan_del_list(struct net_bridge_vlan *v) ...@@ -122,27 +114,21 @@ static void __vlan_del_list(struct net_bridge_vlan *v)
static int __vlan_vid_del(struct net_device *dev, struct net_bridge *br, static int __vlan_vid_del(struct net_device *dev, struct net_bridge *br,
u16 vid) u16 vid)
{ {
const struct net_device_ops *ops = dev->netdev_ops; struct switchdev_obj_port_vlan v = {
int err = 0; .obj.id = SWITCHDEV_OBJ_ID_PORT_VLAN,
.vid_begin = vid,
.vid_end = vid,
};
int err;
/* If driver uses VLAN ndo ops, use 8021q to delete vid /* Try switchdev op first. In case it is not supported, fallback to
* on device, otherwise try switchdev ops to delete vid. * 8021q del.
*/ */
err = switchdev_port_obj_del(dev, &v.obj);
if (ops->ndo_vlan_rx_kill_vid) { if (err == -EOPNOTSUPP) {
vlan_vid_del(dev, br->vlan_proto, vid); vlan_vid_del(dev, br->vlan_proto, vid);
} else { return 0;
struct switchdev_obj_port_vlan v = {
.obj.id = SWITCHDEV_OBJ_ID_PORT_VLAN,
.vid_begin = vid,
.vid_end = vid,
};
err = switchdev_port_obj_del(dev, &v.obj);
if (err == -EOPNOTSUPP)
err = 0;
} }
return err; return err;
} }
......
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