mirror of
https://github.com/torvalds/linux.git
synced 2024-11-26 14:12:06 +00:00
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: Jiri Pirko <jiri@mellanox.com> Signed-off-by: Ido Schimmel <idosch@mellanox.com> Acked-by: Scott Feldman <sfeldma@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
3703ebe403
commit
0944d6b5a2
@ -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)
|
|||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user