Skip to content

Commit

Permalink
Merge branch 'bridge-replay-helpers'
Browse files Browse the repository at this point in the history
Vladimir Oltean says:

====================
Cleanup for the bridge replay helpers

This patch series brings some improvements to the logic added to the
bridge and DSA to handle LAG interfaces sandwiched between a bridge and
a DSA switch port.

        br0
        /  \
       /    \
     bond0  swp2
     /  \
    /    \
  swp0  swp1

In particular, it ensures that the switchdev object additions and
deletions are well balanced per physical port. This is important for
future work in the area of offloading local bridge FDB entries to
hardware in the context of DSA requesting a replay of those entries at
bridge join time (this will be submitted in a future patch series).
Due to some difficulty ensuring that the deletion of local FDB entries
pointing towards the bridge device itself is notified to switchdev in
time (before the switchdev port disconnects from the bridge), this is
potentially still not the final form in which the replay helpers will
exist. I'm thinking about moving from the pull mode (in which DSA
requests the replay) to a push mode (in which the bridge initiates the
replay). Nonetheless, these preliminary changes are needed either way.

The patch series also addresses some feedback from Nikolai which is long
overdue by now (sorry).

Switchdev driver maintainers were deliberately omitted due to the
trivial nature of the driver changes (just a function prototype).

Changes in v2:
- fix build issue in patch 4 (function prototype mismatch)
- move switchdev object unsync to the NETDEV_PRECHANGEUPPER code path
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Jun 28, 2021
2 parents a1b0563 + 7491894 commit 3095f51
Show file tree
Hide file tree
Showing 18 changed files with 267 additions and 98 deletions.
2 changes: 1 addition & 1 deletion drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
Original file line number Diff line number Diff line change
Expand Up @@ -1625,7 +1625,7 @@ static int dpaa2_switch_port_bridge_flags(struct net_device *netdev,
return 0;
}

static int dpaa2_switch_port_attr_set(struct net_device *netdev,
static int dpaa2_switch_port_attr_set(struct net_device *netdev, const void *ctx,
const struct switchdev_attr *attr,
struct netlink_ext_ack *extack)
{
Expand Down
6 changes: 3 additions & 3 deletions drivers/net/ethernet/marvell/prestera/prestera_switchdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -708,7 +708,7 @@ static int prestera_port_attr_stp_state_set(struct prestera_port *port,
return err;
}

static int prestera_port_obj_attr_set(struct net_device *dev,
static int prestera_port_obj_attr_set(struct net_device *dev, const void *ctx,
const struct switchdev_attr *attr,
struct netlink_ext_ack *extack)
{
Expand Down Expand Up @@ -1040,7 +1040,7 @@ static int prestera_port_vlans_add(struct prestera_port *port,
flag_pvid, extack);
}

static int prestera_port_obj_add(struct net_device *dev,
static int prestera_port_obj_add(struct net_device *dev, const void *ctx,
const struct switchdev_obj *obj,
struct netlink_ext_ack *extack)
{
Expand Down Expand Up @@ -1078,7 +1078,7 @@ static int prestera_port_vlans_del(struct prestera_port *port,
return 0;
}

static int prestera_port_obj_del(struct net_device *dev,
static int prestera_port_obj_del(struct net_device *dev, const void *ctx,
const struct switchdev_obj *obj)
{
struct prestera_port *port = netdev_priv(dev);
Expand Down
3 changes: 3 additions & 0 deletions drivers/net/ethernet/mellanox/mlx5/core/en/rep/bridge.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ static int mlx5_esw_bridge_switchdev_port_event(struct notifier_block *nb,
}

static int mlx5_esw_bridge_port_obj_add(struct net_device *dev,
const void *ctx,
const struct switchdev_obj *obj,
struct netlink_ext_ack *extack)
{
Expand Down Expand Up @@ -107,6 +108,7 @@ static int mlx5_esw_bridge_port_obj_add(struct net_device *dev,
}

static int mlx5_esw_bridge_port_obj_del(struct net_device *dev,
const void *ctx,
const struct switchdev_obj *obj)
{
const struct switchdev_obj_port_vlan *vlan;
Expand Down Expand Up @@ -136,6 +138,7 @@ static int mlx5_esw_bridge_port_obj_del(struct net_device *dev,
}

static int mlx5_esw_bridge_port_obj_attr_set(struct net_device *dev,
const void *ctx,
const struct switchdev_attr *attr,
struct netlink_ext_ack *extack)
{
Expand Down
6 changes: 3 additions & 3 deletions drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -898,7 +898,7 @@ mlxsw_sp_port_attr_br_mrouter_set(struct mlxsw_sp_port *mlxsw_sp_port,
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 void *ctx,
const struct switchdev_attr *attr,
struct netlink_ext_ack *extack)
{
Expand Down Expand Up @@ -1766,7 +1766,7 @@ mlxsw_sp_port_mrouter_update_mdb(struct mlxsw_sp_port *mlxsw_sp_port,
}
}

static int mlxsw_sp_port_obj_add(struct net_device *dev,
static int mlxsw_sp_port_obj_add(struct net_device *dev, const void *ctx,
const struct switchdev_obj *obj,
struct netlink_ext_ack *extack)
{
Expand Down Expand Up @@ -1916,7 +1916,7 @@ mlxsw_sp_bridge_port_mdb_flush(struct mlxsw_sp_port *mlxsw_sp_port,
}
}

static int mlxsw_sp_port_obj_del(struct net_device *dev,
static int mlxsw_sp_port_obj_del(struct net_device *dev, const void *ctx,
const struct switchdev_obj *obj)
{
struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/microchip/sparx5/sparx5_switchdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ static void sparx5_port_attr_ageing_set(struct sparx5_port *port,
sparx5_set_ageing(port->sparx5, ageing_time);
}

static int sparx5_port_attr_set(struct net_device *dev,
static int sparx5_port_attr_set(struct net_device *dev, const void *ctx,
const struct switchdev_attr *attr,
struct netlink_ext_ack *extack)
{
Expand Down
29 changes: 20 additions & 9 deletions drivers/net/ethernet/mscc/ocelot_net.c
Original file line number Diff line number Diff line change
Expand Up @@ -939,7 +939,7 @@ static void ocelot_port_attr_mc_set(struct ocelot *ocelot, int port, bool mc)
ANA_PORT_CPU_FWD_CFG, port);
}

static int ocelot_port_attr_set(struct net_device *dev,
static int ocelot_port_attr_set(struct net_device *dev, const void *ctx,
const struct switchdev_attr *attr,
struct netlink_ext_ack *extack)
{
Expand All @@ -948,6 +948,9 @@ static int ocelot_port_attr_set(struct net_device *dev,
int port = priv->chip_port;
int err = 0;

if (ctx && ctx != priv)
return 0;

switch (attr->id) {
case SWITCHDEV_ATTR_ID_PORT_STP_STATE:
ocelot_port_attr_stp_state_set(ocelot, port, attr->u.stp_state);
Expand Down Expand Up @@ -1058,12 +1061,16 @@ ocelot_port_obj_mrp_del_ring_role(struct net_device *dev,
return ocelot_mrp_del_ring_role(ocelot, port, mrp);
}

static int ocelot_port_obj_add(struct net_device *dev,
static int ocelot_port_obj_add(struct net_device *dev, const void *ctx,
const struct switchdev_obj *obj,
struct netlink_ext_ack *extack)
{
struct ocelot_port_private *priv = netdev_priv(dev);
int ret = 0;

if (ctx && ctx != priv)
return 0;

switch (obj->id) {
case SWITCHDEV_OBJ_ID_PORT_VLAN:
ret = ocelot_port_obj_add_vlan(dev,
Expand All @@ -1086,11 +1093,15 @@ static int ocelot_port_obj_add(struct net_device *dev,
return ret;
}

static int ocelot_port_obj_del(struct net_device *dev,
static int ocelot_port_obj_del(struct net_device *dev, const void *ctx,
const struct switchdev_obj *obj)
{
struct ocelot_port_private *priv = netdev_priv(dev);
int ret = 0;

if (ctx && ctx != priv)
return 0;

switch (obj->id) {
case SWITCHDEV_OBJ_ID_PORT_VLAN:
ret = ocelot_vlan_vid_del(dev,
Expand Down Expand Up @@ -1143,10 +1154,14 @@ static int ocelot_switchdev_sync(struct ocelot *ocelot, int port,
struct net_device *bridge_dev,
struct netlink_ext_ack *extack)
{
struct ocelot_port *ocelot_port = ocelot->ports[port];
struct ocelot_port_private *priv;
clock_t ageing_time;
u8 stp_state;
int err;

priv = container_of(ocelot_port, struct ocelot_port_private, port);

ocelot_inherit_brport_flags(ocelot, port, brport_dev);

stp_state = br_port_get_stp_state(brport_dev);
Expand All @@ -1160,16 +1175,12 @@ static int ocelot_switchdev_sync(struct ocelot *ocelot, int port,
ageing_time = br_get_ageing_time(bridge_dev);
ocelot_port_attr_ageing_set(ocelot, port, ageing_time);

err = br_mdb_replay(bridge_dev, brport_dev,
err = br_mdb_replay(bridge_dev, brport_dev, priv, true,
&ocelot_switchdev_blocking_nb, extack);
if (err && err != -EOPNOTSUPP)
return err;

err = br_fdb_replay(bridge_dev, brport_dev, &ocelot_switchdev_nb);
if (err)
return err;

err = br_vlan_replay(bridge_dev, brport_dev,
err = br_vlan_replay(bridge_dev, brport_dev, priv, true,
&ocelot_switchdev_blocking_nb, extack);
if (err && err != -EOPNOTSUPP)
return err;
Expand Down
6 changes: 3 additions & 3 deletions drivers/net/ethernet/ti/am65-cpsw-switchdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ static int am65_cpsw_port_attr_br_flags_pre_set(struct net_device *netdev,
return 0;
}

static int am65_cpsw_port_attr_set(struct net_device *ndev,
static int am65_cpsw_port_attr_set(struct net_device *ndev, const void *ctx,
const struct switchdev_attr *attr,
struct netlink_ext_ack *extack)
{
Expand Down Expand Up @@ -302,7 +302,7 @@ static int am65_cpsw_port_mdb_del(struct am65_cpsw_port *port,
return 0;
}

static int am65_cpsw_port_obj_add(struct net_device *ndev,
static int am65_cpsw_port_obj_add(struct net_device *ndev, const void *ctx,
const struct switchdev_obj *obj,
struct netlink_ext_ack *extack)
{
Expand All @@ -329,7 +329,7 @@ static int am65_cpsw_port_obj_add(struct net_device *ndev,
return err;
}

static int am65_cpsw_port_obj_del(struct net_device *ndev,
static int am65_cpsw_port_obj_del(struct net_device *ndev, const void *ctx,
const struct switchdev_obj *obj)
{
struct switchdev_obj_port_vlan *vlan = SWITCHDEV_OBJ_PORT_VLAN(obj);
Expand Down
6 changes: 3 additions & 3 deletions drivers/net/ethernet/ti/cpsw_switchdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ static int cpsw_port_attr_br_flags_pre_set(struct net_device *netdev,
return 0;
}

static int cpsw_port_attr_set(struct net_device *ndev,
static int cpsw_port_attr_set(struct net_device *ndev, const void *ctx,
const struct switchdev_attr *attr,
struct netlink_ext_ack *extack)
{
Expand Down Expand Up @@ -310,7 +310,7 @@ static int cpsw_port_mdb_del(struct cpsw_priv *priv,
return err;
}

static int cpsw_port_obj_add(struct net_device *ndev,
static int cpsw_port_obj_add(struct net_device *ndev, const void *ctx,
const struct switchdev_obj *obj,
struct netlink_ext_ack *extack)
{
Expand Down Expand Up @@ -338,7 +338,7 @@ static int cpsw_port_obj_add(struct net_device *ndev,
return err;
}

static int cpsw_port_obj_del(struct net_device *ndev,
static int cpsw_port_obj_del(struct net_device *ndev, const void *ctx,
const struct switchdev_obj *obj)
{
struct switchdev_obj_port_vlan *vlan = SWITCHDEV_OBJ_PORT_VLAN(obj);
Expand Down
30 changes: 16 additions & 14 deletions include/linux/if_bridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ bool br_multicast_has_router_adjacent(struct net_device *dev, int proto);
bool br_multicast_enabled(const struct net_device *dev);
bool br_multicast_router(const struct net_device *dev);
int br_mdb_replay(struct net_device *br_dev, struct net_device *dev,
struct notifier_block *nb, struct netlink_ext_ack *extack);
const void *ctx, bool adding, struct notifier_block *nb,
struct netlink_ext_ack *extack);
#else
static inline int br_multicast_list_adjacent(struct net_device *dev,
struct list_head *br_ip_list)
Expand Down Expand Up @@ -103,9 +104,9 @@ static inline bool br_multicast_router(const struct net_device *dev)
{
return false;
}
static inline int br_mdb_replay(struct net_device *br_dev,
struct net_device *dev,
struct notifier_block *nb,
static inline int br_mdb_replay(const struct net_device *br_dev,
const struct net_device *dev, const void *ctx,
bool adding, struct notifier_block *nb,
struct netlink_ext_ack *extack)
{
return -EOPNOTSUPP;
Expand All @@ -120,7 +121,8 @@ int br_vlan_get_proto(const struct net_device *dev, u16 *p_proto);
int br_vlan_get_info(const struct net_device *dev, u16 vid,
struct bridge_vlan_info *p_vinfo);
int br_vlan_replay(struct net_device *br_dev, struct net_device *dev,
struct notifier_block *nb, struct netlink_ext_ack *extack);
const void *ctx, bool adding, struct notifier_block *nb,
struct netlink_ext_ack *extack);
#else
static inline bool br_vlan_enabled(const struct net_device *dev)
{
Expand Down Expand Up @@ -149,8 +151,8 @@ static inline int br_vlan_get_info(const struct net_device *dev, u16 vid,
}

static inline int br_vlan_replay(struct net_device *br_dev,
struct net_device *dev,
struct notifier_block *nb,
struct net_device *dev, const void *ctx,
bool adding, struct notifier_block *nb,
struct netlink_ext_ack *extack)
{
return -EOPNOTSUPP;
Expand All @@ -164,9 +166,9 @@ struct net_device *br_fdb_find_port(const struct net_device *br_dev,
void br_fdb_clear_offload(const struct net_device *dev, u16 vid);
bool br_port_flag_is_set(const struct net_device *dev, unsigned long flag);
u8 br_port_get_stp_state(const struct net_device *dev);
clock_t br_get_ageing_time(struct net_device *br_dev);
int br_fdb_replay(struct net_device *br_dev, struct net_device *dev,
struct notifier_block *nb);
clock_t br_get_ageing_time(const struct net_device *br_dev);
int br_fdb_replay(const struct net_device *br_dev, const struct net_device *dev,
const void *ctx, bool adding, struct notifier_block *nb);
#else
static inline struct net_device *
br_fdb_find_port(const struct net_device *br_dev,
Expand All @@ -191,14 +193,14 @@ static inline u8 br_port_get_stp_state(const struct net_device *dev)
return BR_STATE_DISABLED;
}

static inline clock_t br_get_ageing_time(struct net_device *br_dev)
static inline clock_t br_get_ageing_time(const struct net_device *br_dev)
{
return 0;
}

static inline int br_fdb_replay(struct net_device *br_dev,
struct net_device *dev,
struct notifier_block *nb)
static inline int br_fdb_replay(const struct net_device *br_dev,
const struct net_device *dev, const void *ctx,
bool adding, struct notifier_block *nb)
{
return -EOPNOTSUPP;
}
Expand Down
13 changes: 7 additions & 6 deletions include/net/switchdev.h
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ enum switchdev_notifier_type {
struct switchdev_notifier_info {
struct net_device *dev;
struct netlink_ext_ack *extack;
const void *ctx;
};

struct switchdev_notifier_fdb_info {
Expand Down Expand Up @@ -268,19 +269,19 @@ void switchdev_port_fwd_mark_set(struct net_device *dev,
int switchdev_handle_port_obj_add(struct net_device *dev,
struct switchdev_notifier_port_obj_info *port_obj_info,
bool (*check_cb)(const struct net_device *dev),
int (*add_cb)(struct net_device *dev,
int (*add_cb)(struct net_device *dev, const void *ctx,
const struct switchdev_obj *obj,
struct netlink_ext_ack *extack));
int switchdev_handle_port_obj_del(struct net_device *dev,
struct switchdev_notifier_port_obj_info *port_obj_info,
bool (*check_cb)(const struct net_device *dev),
int (*del_cb)(struct net_device *dev,
int (*del_cb)(struct net_device *dev, const void *ctx,
const struct switchdev_obj *obj));

int switchdev_handle_port_attr_set(struct net_device *dev,
struct switchdev_notifier_port_attr_info *port_attr_info,
bool (*check_cb)(const struct net_device *dev),
int (*set_cb)(struct net_device *dev,
int (*set_cb)(struct net_device *dev, const void *ctx,
const struct switchdev_attr *attr,
struct netlink_ext_ack *extack));
#else
Expand Down Expand Up @@ -352,7 +353,7 @@ static inline int
switchdev_handle_port_obj_add(struct net_device *dev,
struct switchdev_notifier_port_obj_info *port_obj_info,
bool (*check_cb)(const struct net_device *dev),
int (*add_cb)(struct net_device *dev,
int (*add_cb)(struct net_device *dev, const void *ctx,
const struct switchdev_obj *obj,
struct netlink_ext_ack *extack))
{
Expand All @@ -363,7 +364,7 @@ static inline int
switchdev_handle_port_obj_del(struct net_device *dev,
struct switchdev_notifier_port_obj_info *port_obj_info,
bool (*check_cb)(const struct net_device *dev),
int (*del_cb)(struct net_device *dev,
int (*del_cb)(struct net_device *dev, const void *ctx,
const struct switchdev_obj *obj))
{
return 0;
Expand All @@ -373,7 +374,7 @@ static inline int
switchdev_handle_port_attr_set(struct net_device *dev,
struct switchdev_notifier_port_attr_info *port_attr_info,
bool (*check_cb)(const struct net_device *dev),
int (*set_cb)(struct net_device *dev,
int (*set_cb)(struct net_device *dev, const void *ctx,
const struct switchdev_attr *attr,
struct netlink_ext_ack *extack))
{
Expand Down
Loading

0 comments on commit 3095f51

Please sign in to comment.