Commit 0e9390eb authored by David S. Miller's avatar David S. Miller

Merge branch 'mlxsw-next'

Jiri Pirko says:

====================
mlxsw: Preparation for IPv4 router

Ido says:

This series prepares the driver for IPv4 router support. The router follow-up
patches are available at: https://github.com/jpirko/linux_mlxsw/tree/net-next_queue

Patches 1-9 simplify the netdevice notification block and also add several
checks during PRECHANGEUPPER events against topologies that aren't supported by
the device. This will ensure L3 interfaces are only configured on top of
valid netdevs.

Patches 10-13 contain trivial changes required for the introduction of a generic
FID struct - currently only used for vFIDs - in patch 14. Making the FID
struct generic will allow us to easily associate the underlying FIDs with
their L3-counterparts - Router interfaces (RIFs):

    FID Type        | Used by                         | RIF Type
    --------------------------------------------------------
    FID             | The VLAN-aware bridge           | VLAN
    vFID            | VLAN-unaware bridges            | FID
    rFID            | non-bridged netdevs (follow-up) | Sub-port

Obligatory ASCII art to visualize the above:

                   A.B.C.D
                      +
                      | FID RIF
                      +
                     br0                    E.F.G.H
                      +                        +
                      |                        | VLAN RIF
            +---------+---------+              +
            |                   |            br1.W
            | vFID              |              +
            |                   |              |
 vPort    +-+-+               +-+-+            +
swXpY.Z   |   |               |   |           br1
          +-+-+               +-+-+            +
            |                   |     FID=W    |
            |                   | +------------+------------+
            |                   | |                         |
        +---+---+           +---+-+-+                   +---+---+
        |       |           |       |                   |       |
        |       |           |       |                   |       |
        |       |           |       |                   |       |
        +-------+           +-------+                   +-------+
          swXpY

Patches 15-16 further generalize the struct by exploiting the fact that the
FID is a shared resource among ports. Each FID type is assigned a 'leave'
function that is invoked based on CHANGEUPPER events and takes care of the
necessary clean-up.

Patches 17-22 build upon the previous patches and use the FID struct for the
VLAN-aware bridge and take care of cleaning up FID resources in the 'leave'
functions. For now, these are only FDB records, but later on we'll have to
remove the RIFs associated with these FIDs, which will in turn take care of
routes and neighbours clean-up.

The last patch adds debug prints that proved very useful during the
development of this series.

Tested with the existing L2 recipes:
https://github.com/jpirko/lnst/tree/master/recipes/switchdev
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 527f2273 22305378
......@@ -87,11 +87,12 @@ struct mlxsw_sp_upper {
unsigned int ref_count;
};
struct mlxsw_sp_vfid {
struct mlxsw_sp_fid {
void (*leave)(struct mlxsw_sp_port *mlxsw_sp_vport);
struct list_head list;
u16 nr_vports;
u16 vfid; /* Starting at 0 */
struct net_device *br_dev;
unsigned int ref_count;
struct net_device *dev;
u16 fid;
u16 vid;
};
......@@ -155,17 +156,17 @@ struct mlxsw_sp_sb {
struct mlxsw_sp {
struct {
struct list_head list;
unsigned long mapped[BITS_TO_LONGS(MLXSW_SP_VFID_PORT_MAX)];
DECLARE_BITMAP(mapped, MLXSW_SP_VFID_PORT_MAX);
} port_vfids;
struct {
struct list_head list;
unsigned long mapped[BITS_TO_LONGS(MLXSW_SP_VFID_BR_MAX)];
DECLARE_BITMAP(mapped, MLXSW_SP_VFID_BR_MAX);
} br_vfids;
struct {
struct list_head list;
unsigned long mapped[BITS_TO_LONGS(MLXSW_SP_MID_MAX)];
DECLARE_BITMAP(mapped, MLXSW_SP_MID_MAX);
} br_mids;
unsigned long active_fids[BITS_TO_LONGS(VLAN_N_VID)];
struct list_head fids; /* VLAN-aware bridge FIDs */
struct mlxsw_sp_port **ports;
struct mlxsw_core *core;
const struct mlxsw_bus_info *bus_info;
......@@ -217,7 +218,7 @@ struct mlxsw_sp_port {
u16 lag_id;
struct {
struct list_head list;
struct mlxsw_sp_vfid *vfid;
struct mlxsw_sp_fid *f;
u16 vid;
} vport;
struct {
......@@ -259,28 +260,38 @@ mlxsw_sp_port_lagged_get(struct mlxsw_sp *mlxsw_sp, u16 lag_id, u8 port_index)
return mlxsw_sp_port && mlxsw_sp_port->lagged ? mlxsw_sp_port : NULL;
}
static inline u16
mlxsw_sp_vport_vid_get(const struct mlxsw_sp_port *mlxsw_sp_vport)
{
return mlxsw_sp_vport->vport.vid;
}
static inline bool
mlxsw_sp_port_is_vport(const struct mlxsw_sp_port *mlxsw_sp_port)
{
return mlxsw_sp_port->vport.vfid;
u16 vid = mlxsw_sp_vport_vid_get(mlxsw_sp_port);
return vid != 0;
}
static inline struct net_device *
mlxsw_sp_vport_br_get(const struct mlxsw_sp_port *mlxsw_sp_vport)
static inline void mlxsw_sp_vport_fid_set(struct mlxsw_sp_port *mlxsw_sp_vport,
struct mlxsw_sp_fid *f)
{
return mlxsw_sp_vport->vport.vfid->br_dev;
mlxsw_sp_vport->vport.f = f;
}
static inline u16
mlxsw_sp_vport_vid_get(const struct mlxsw_sp_port *mlxsw_sp_vport)
static inline struct mlxsw_sp_fid *
mlxsw_sp_vport_fid_get(const struct mlxsw_sp_port *mlxsw_sp_vport)
{
return mlxsw_sp_vport->vport.vid;
return mlxsw_sp_vport->vport.f;
}
static inline u16
mlxsw_sp_vport_vfid_get(const struct mlxsw_sp_port *mlxsw_sp_vport)
static inline struct net_device *
mlxsw_sp_vport_br_get(const struct mlxsw_sp_port *mlxsw_sp_vport)
{
return mlxsw_sp_vport->vport.vfid->vfid;
struct mlxsw_sp_fid *f = mlxsw_sp_vport_fid_get(mlxsw_sp_vport);
return f ? f->dev : NULL;
}
static inline struct mlxsw_sp_port *
......@@ -298,14 +309,16 @@ mlxsw_sp_port_vport_find(const struct mlxsw_sp_port *mlxsw_sp_port, u16 vid)
}
static inline struct mlxsw_sp_port *
mlxsw_sp_port_vport_find_by_vfid(const struct mlxsw_sp_port *mlxsw_sp_port,
u16 vfid)
mlxsw_sp_port_vport_find_by_fid(const struct mlxsw_sp_port *mlxsw_sp_port,
u16 fid)
{
struct mlxsw_sp_port *mlxsw_sp_vport;
list_for_each_entry(mlxsw_sp_vport, &mlxsw_sp_port->vports_list,
vport.list) {
if (mlxsw_sp_vport_vfid_get(mlxsw_sp_vport) == vfid)
struct mlxsw_sp_fid *f = mlxsw_sp_vport_fid_get(mlxsw_sp_vport);
if (f && f->fid == fid)
return mlxsw_sp_vport;
}
......@@ -366,10 +379,11 @@ int mlxsw_sp_port_add_vid(struct net_device *dev, __be16 __always_unused proto,
u16 vid);
int mlxsw_sp_port_kill_vid(struct net_device *dev,
__be16 __always_unused proto, u16 vid);
int mlxsw_sp_vport_flood_set(struct mlxsw_sp_port *mlxsw_sp_vport, u16 vfid,
bool set, bool only_uc);
int mlxsw_sp_vport_flood_set(struct mlxsw_sp_port *mlxsw_sp_vport, u16 fid,
bool set);
void mlxsw_sp_port_active_vlans_del(struct mlxsw_sp_port *mlxsw_sp_port);
int mlxsw_sp_port_pvid_set(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid);
int mlxsw_sp_port_fdb_flush(struct mlxsw_sp_port *mlxsw_sp_port, u16 fid);
int mlxsw_sp_port_ets_set(struct mlxsw_sp_port *mlxsw_sp_port,
enum mlxsw_reg_qeec_hr hr, u8 index, u8 next_index,
bool dwrr, u8 dwrr_weight);
......
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