Commit 8ecd4591 authored by Nogah Frankel's avatar Nogah Frankel Committed by David S. Miller

mlxsw: spectrum: Add an option to flood mc by mc_router_port

The decision whether to flood a multicast packet to a port dependent
on three flags: mc_disabled, mc_router_port, mc_flood.

If mc_disabled is on, the port will be flooded according to mc_flood,
otherwise, according to mc_router_port. To accomplish that, add those
flags into the mlxsw_sp_port struct and update the mc flood table
accordingly.

Update mc_router_port by switchdev attribute
SWITCHDEV_ATTR_ID_PORT_MC_ROUTER_PORT.
Signed-off-by: default avatarNogah Frankel <nogahf@mellanox.com>
Signed-off-by: default avatarYotam Gigi <yotamg@mellanox.com>
Signed-off-by: default avatarJiri Pirko <jiri@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 71c365bd
...@@ -4073,6 +4073,8 @@ static int mlxsw_sp_port_bridge_join(struct mlxsw_sp_port *mlxsw_sp_port, ...@@ -4073,6 +4073,8 @@ static int mlxsw_sp_port_bridge_join(struct mlxsw_sp_port *mlxsw_sp_port,
mlxsw_sp_port->learning_sync = 1; mlxsw_sp_port->learning_sync = 1;
mlxsw_sp_port->uc_flood = 1; mlxsw_sp_port->uc_flood = 1;
mlxsw_sp_port->mc_flood = 1; mlxsw_sp_port->mc_flood = 1;
mlxsw_sp_port->mc_router = 0;
mlxsw_sp_port->mc_disabled = 1;
mlxsw_sp_port->bridged = 1; mlxsw_sp_port->bridged = 1;
return 0; return 0;
...@@ -4090,6 +4092,7 @@ static void mlxsw_sp_port_bridge_leave(struct mlxsw_sp_port *mlxsw_sp_port) ...@@ -4090,6 +4092,7 @@ static void mlxsw_sp_port_bridge_leave(struct mlxsw_sp_port *mlxsw_sp_port)
mlxsw_sp_port->learning_sync = 0; mlxsw_sp_port->learning_sync = 0;
mlxsw_sp_port->uc_flood = 0; mlxsw_sp_port->uc_flood = 0;
mlxsw_sp_port->mc_flood = 0; mlxsw_sp_port->mc_flood = 0;
mlxsw_sp_port->mc_router = 0;
mlxsw_sp_port->bridged = 0; mlxsw_sp_port->bridged = 0;
/* Add implicit VLAN interface in the device, so that untagged /* Add implicit VLAN interface in the device, so that untagged
...@@ -4753,6 +4756,8 @@ static int mlxsw_sp_vport_bridge_join(struct mlxsw_sp_port *mlxsw_sp_vport, ...@@ -4753,6 +4756,8 @@ static int mlxsw_sp_vport_bridge_join(struct mlxsw_sp_port *mlxsw_sp_vport,
mlxsw_sp_vport->learning_sync = 1; mlxsw_sp_vport->learning_sync = 1;
mlxsw_sp_vport->uc_flood = 1; mlxsw_sp_vport->uc_flood = 1;
mlxsw_sp_vport->mc_flood = 1; mlxsw_sp_vport->mc_flood = 1;
mlxsw_sp_vport->mc_router = 0;
mlxsw_sp_vport->mc_disabled = 1;
mlxsw_sp_vport->bridged = 1; mlxsw_sp_vport->bridged = 1;
return 0; return 0;
...@@ -4774,6 +4779,7 @@ static void mlxsw_sp_vport_bridge_leave(struct mlxsw_sp_port *mlxsw_sp_vport) ...@@ -4774,6 +4779,7 @@ static void mlxsw_sp_vport_bridge_leave(struct mlxsw_sp_port *mlxsw_sp_vport)
mlxsw_sp_vport->learning_sync = 0; mlxsw_sp_vport->learning_sync = 0;
mlxsw_sp_vport->uc_flood = 0; mlxsw_sp_vport->uc_flood = 0;
mlxsw_sp_vport->mc_flood = 0; mlxsw_sp_vport->mc_flood = 0;
mlxsw_sp_vport->mc_router = 0;
mlxsw_sp_vport->bridged = 0; mlxsw_sp_vport->bridged = 0;
} }
......
...@@ -339,10 +339,12 @@ struct mlxsw_sp_port { ...@@ -339,10 +339,12 @@ struct mlxsw_sp_port {
struct mlxsw_sp *mlxsw_sp; struct mlxsw_sp *mlxsw_sp;
u8 local_port; u8 local_port;
u8 stp_state; u8 stp_state;
u8 learning:1, u16 learning:1,
learning_sync:1, learning_sync:1,
uc_flood:1, uc_flood:1,
mc_flood:1, mc_flood:1,
mc_router:1,
mc_disabled:1,
bridged:1, bridged:1,
lagged:1, lagged:1,
split:1; split:1;
......
...@@ -264,14 +264,20 @@ static int mlxsw_sp_port_flood_table_set(struct mlxsw_sp_port *mlxsw_sp_port, ...@@ -264,14 +264,20 @@ static int mlxsw_sp_port_flood_table_set(struct mlxsw_sp_port *mlxsw_sp_port,
int mlxsw_sp_vport_flood_set(struct mlxsw_sp_port *mlxsw_sp_vport, u16 fid, int mlxsw_sp_vport_flood_set(struct mlxsw_sp_port *mlxsw_sp_vport, u16 fid,
bool set) bool set)
{ {
bool mc_set = set;
u16 vfid; u16 vfid;
/* In case of vFIDs, index into the flooding table is relative to /* In case of vFIDs, index into the flooding table is relative to
* the start of the vFIDs range. * the start of the vFIDs range.
*/ */
vfid = mlxsw_sp_fid_to_vfid(fid); vfid = mlxsw_sp_fid_to_vfid(fid);
if (set)
mc_set = mlxsw_sp_vport->mc_disabled ?
mlxsw_sp_vport->mc_flood : mlxsw_sp_vport->mc_router;
return __mlxsw_sp_port_flood_set(mlxsw_sp_vport, vfid, vfid, set, set, return __mlxsw_sp_port_flood_set(mlxsw_sp_vport, vfid, vfid, set, set,
set); mc_set);
} }
static int mlxsw_sp_port_learning_set(struct mlxsw_sp_port *mlxsw_sp_port, static int mlxsw_sp_port_learning_set(struct mlxsw_sp_port *mlxsw_sp_port,
...@@ -393,6 +399,22 @@ static int mlxsw_sp_port_attr_br_vlan_set(struct mlxsw_sp_port *mlxsw_sp_port, ...@@ -393,6 +399,22 @@ static int mlxsw_sp_port_attr_br_vlan_set(struct mlxsw_sp_port *mlxsw_sp_port,
return 0; return 0;
} }
static int mlxsw_sp_port_attr_mc_router_set(struct mlxsw_sp_port *mlxsw_sp_port,
struct switchdev_trans *trans,
bool is_port_mc_router)
{
if (switchdev_trans_ph_prepare(trans))
return 0;
mlxsw_sp_port->mc_router = is_port_mc_router;
if (!mlxsw_sp_port->mc_disabled)
return mlxsw_sp_port_flood_table_set(mlxsw_sp_port,
MLXSW_SP_FLOOD_TABLE_MC,
is_port_mc_router);
return 0;
}
static int mlxsw_sp_port_attr_set(struct net_device *dev, static int mlxsw_sp_port_attr_set(struct net_device *dev,
const struct switchdev_attr *attr, const struct switchdev_attr *attr,
struct switchdev_trans *trans) struct switchdev_trans *trans)
...@@ -422,6 +444,10 @@ static int mlxsw_sp_port_attr_set(struct net_device *dev, ...@@ -422,6 +444,10 @@ static int mlxsw_sp_port_attr_set(struct net_device *dev,
attr->orig_dev, attr->orig_dev,
attr->u.vlan_filtering); attr->u.vlan_filtering);
break; break;
case SWITCHDEV_ATTR_ID_PORT_MROUTER:
err = mlxsw_sp_port_attr_mc_router_set(mlxsw_sp_port, trans,
attr->u.mrouter);
break;
default: default:
err = -EOPNOTSUPP; err = -EOPNOTSUPP;
break; break;
...@@ -567,6 +593,7 @@ static int mlxsw_sp_port_fid_map(struct mlxsw_sp_port *mlxsw_sp_port, u16 fid, ...@@ -567,6 +593,7 @@ static int mlxsw_sp_port_fid_map(struct mlxsw_sp_port *mlxsw_sp_port, u16 fid,
static int mlxsw_sp_port_fid_join(struct mlxsw_sp_port *mlxsw_sp_port, static int mlxsw_sp_port_fid_join(struct mlxsw_sp_port *mlxsw_sp_port,
u16 fid_begin, u16 fid_end) u16 fid_begin, u16 fid_end)
{ {
bool mc_flood;
int fid, err; int fid, err;
for (fid = fid_begin; fid <= fid_end; fid++) { for (fid = fid_begin; fid <= fid_end; fid++) {
...@@ -575,9 +602,12 @@ static int mlxsw_sp_port_fid_join(struct mlxsw_sp_port *mlxsw_sp_port, ...@@ -575,9 +602,12 @@ static int mlxsw_sp_port_fid_join(struct mlxsw_sp_port *mlxsw_sp_port,
goto err_port_fid_join; goto err_port_fid_join;
} }
mc_flood = mlxsw_sp_port->mc_disabled ?
mlxsw_sp_port->mc_flood : mlxsw_sp_port->mc_router;
err = __mlxsw_sp_port_flood_set(mlxsw_sp_port, fid_begin, fid_end, err = __mlxsw_sp_port_flood_set(mlxsw_sp_port, fid_begin, fid_end,
mlxsw_sp_port->uc_flood, true, mlxsw_sp_port->uc_flood, true,
mlxsw_sp_port->mc_flood); mc_flood);
if (err) if (err)
goto err_port_flood_set; goto err_port_flood_set;
......
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