Skip to content

Commit 4aafc36

Browse files
idoschdavem330
authored andcommitted
mlxsw: spectrum: Set port's mode according to FID mappings
We currently transition the port to "Virtual mode" upon the creation of its first VLAN upper, as we need to classify incoming packets to a FID using {Port, VID} and not only the VID. However, it's more appropriate to transition the port to this mode when the {Port, VID} are actually mapped to a FID. Either during the enslavement of the VLAN upper to a VLAN-unaware bridge or the configuration of a router port. Do this change now in preparation for the introduction of the FID core, where this operation will be encapsulated. To prevent regressions, this patch also explicitly configures an OVS slave to "Virtual mode". Otherwise, a packet that didn't hit an ACL rule could be classified to an existing FID based on a global VID-to-FID mapping, thus not incurring a FID mis-classification, which would otherwise trap the packet to the CPU to be processed by the OVS daemon. Signed-off-by: Ido Schimmel <idosch@mellanox.com> Signed-off-by: Jiri Pirko <jiri@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 9341b98 commit 4aafc36

File tree

4 files changed

+63
-28
lines changed

4 files changed

+63
-28
lines changed

drivers/net/ethernet/mellanox/mlxsw/spectrum.c

Lines changed: 30 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1398,7 +1398,7 @@ int mlxsw_sp_port_vlan_set(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid_begin,
13981398
return 0;
13991399
}
14001400

1401-
static int mlxsw_sp_port_vp_mode_trans(struct mlxsw_sp_port *mlxsw_sp_port)
1401+
int mlxsw_sp_port_vp_mode_trans(struct mlxsw_sp_port *mlxsw_sp_port)
14021402
{
14031403
enum mlxsw_reg_svfa_mt mt = MLXSW_REG_SVFA_MT_PORT_VID_TO_FID;
14041404
u16 vid, last_visited_vid;
@@ -1428,7 +1428,7 @@ static int mlxsw_sp_port_vp_mode_trans(struct mlxsw_sp_port *mlxsw_sp_port)
14281428
return err;
14291429
}
14301430

1431-
static int mlxsw_sp_port_vlan_mode_trans(struct mlxsw_sp_port *mlxsw_sp_port)
1431+
int mlxsw_sp_port_vlan_mode_trans(struct mlxsw_sp_port *mlxsw_sp_port)
14321432
{
14331433
enum mlxsw_reg_svfa_mt mt = MLXSW_REG_SVFA_MT_PORT_VID_TO_FID;
14341434
u16 vid;
@@ -1501,26 +1501,13 @@ static int mlxsw_sp_port_add_vid(struct net_device *dev,
15011501
if (!mlxsw_sp_vport)
15021502
return -ENOMEM;
15031503

1504-
/* When adding the first VLAN interface on a bridged port we need to
1505-
* transition all the active 802.1Q bridge VLANs to use explicit
1506-
* {Port, VID} to FID mappings and set the port's mode to Virtual mode.
1507-
*/
1508-
if (list_is_singular(&mlxsw_sp_port->vports_list)) {
1509-
err = mlxsw_sp_port_vp_mode_trans(mlxsw_sp_port);
1510-
if (err)
1511-
goto err_port_vp_mode_trans;
1512-
}
1513-
15141504
err = mlxsw_sp_port_vlan_set(mlxsw_sp_vport, vid, vid, true, untagged);
15151505
if (err)
15161506
goto err_port_add_vid;
15171507

15181508
return 0;
15191509

15201510
err_port_add_vid:
1521-
if (list_is_singular(&mlxsw_sp_port->vports_list))
1522-
mlxsw_sp_port_vlan_mode_trans(mlxsw_sp_port);
1523-
err_port_vp_mode_trans:
15241511
mlxsw_sp_port_vport_destroy(mlxsw_sp_vport);
15251512
return err;
15261513
}
@@ -1551,13 +1538,6 @@ static int mlxsw_sp_port_kill_vid(struct net_device *dev,
15511538
if (f && !WARN_ON(!f->leave))
15521539
f->leave(mlxsw_sp_vport);
15531540

1554-
/* When removing the last VLAN interface on a bridged port we need to
1555-
* transition all active 802.1Q bridge VLANs to use VID to FID
1556-
* mappings and set port's mode to VLAN mode.
1557-
*/
1558-
if (list_is_singular(&mlxsw_sp_port->vports_list))
1559-
mlxsw_sp_port_vlan_mode_trans(mlxsw_sp_port);
1560-
15611541
mlxsw_sp_port_vport_destroy(mlxsw_sp_vport);
15621542

15631543
return 0;
@@ -4382,9 +4362,12 @@ static int mlxsw_sp_port_ovs_join(struct mlxsw_sp_port *mlxsw_sp_port)
43824362
{
43834363
int err;
43844364

4385-
err = mlxsw_sp_port_stp_set(mlxsw_sp_port, true);
4365+
err = mlxsw_sp_port_vp_mode_set(mlxsw_sp_port, true);
43864366
if (err)
43874367
return err;
4368+
err = mlxsw_sp_port_stp_set(mlxsw_sp_port, true);
4369+
if (err)
4370+
goto err_port_stp_set;
43884371
err = mlxsw_sp_port_vlan_set(mlxsw_sp_port, 2, VLAN_N_VID - 1,
43894372
true, false);
43904373
if (err)
@@ -4393,6 +4376,8 @@ static int mlxsw_sp_port_ovs_join(struct mlxsw_sp_port *mlxsw_sp_port)
43934376

43944377
err_port_vlan_set:
43954378
mlxsw_sp_port_stp_set(mlxsw_sp_port, false);
4379+
err_port_stp_set:
4380+
mlxsw_sp_port_vp_mode_set(mlxsw_sp_port, false);
43964381
return err;
43974382
}
43984383

@@ -4401,6 +4386,7 @@ static void mlxsw_sp_port_ovs_leave(struct mlxsw_sp_port *mlxsw_sp_port)
44014386
mlxsw_sp_port_vlan_set(mlxsw_sp_port, 2, VLAN_N_VID - 1,
44024387
false, false);
44034388
mlxsw_sp_port_stp_set(mlxsw_sp_port, false);
4389+
mlxsw_sp_port_vp_mode_set(mlxsw_sp_port, false);
44044390
}
44054391

44064392
static int mlxsw_sp_netdevice_port_upper_event(struct net_device *dev,
@@ -4695,6 +4681,7 @@ static int mlxsw_sp_vport_fid_map(struct mlxsw_sp_port *mlxsw_sp_vport, u16 fid,
46954681
static int mlxsw_sp_vport_vfid_join(struct mlxsw_sp_port *mlxsw_sp_vport,
46964682
struct net_device *br_dev)
46974683
{
4684+
struct mlxsw_sp_port *mlxsw_sp_port;
46984685
struct mlxsw_sp_fid *f;
46994686
int err;
47004687

@@ -4713,13 +4700,23 @@ static int mlxsw_sp_vport_vfid_join(struct mlxsw_sp_port *mlxsw_sp_vport,
47134700
if (err)
47144701
goto err_vport_fid_map;
47154702

4703+
mlxsw_sp_port = mlxsw_sp_vport_port(mlxsw_sp_vport);
4704+
if (mlxsw_sp_port->nr_port_vid_map++ == 0) {
4705+
err = mlxsw_sp_port_vp_mode_trans(mlxsw_sp_port);
4706+
if (err)
4707+
goto err_port_vp_mode_trans;
4708+
}
4709+
47164710
mlxsw_sp_vport_fid_set(mlxsw_sp_vport, f);
47174711
f->ref_count++;
47184712

47194713
netdev_dbg(mlxsw_sp_vport->dev, "Joined FID=%d\n", f->fid);
47204714

47214715
return 0;
47224716

4717+
err_port_vp_mode_trans:
4718+
mlxsw_sp_port->nr_port_vid_map--;
4719+
mlxsw_sp_vport_fid_map(mlxsw_sp_vport, f->fid, false);
47234720
err_vport_fid_map:
47244721
mlxsw_sp_vport_flood_set(mlxsw_sp_vport, f->fid, false);
47254722
err_vport_flood_set:
@@ -4731,17 +4728,25 @@ static int mlxsw_sp_vport_vfid_join(struct mlxsw_sp_port *mlxsw_sp_vport,
47314728
static void mlxsw_sp_vport_vfid_leave(struct mlxsw_sp_port *mlxsw_sp_vport)
47324729
{
47334730
struct mlxsw_sp_fid *f = mlxsw_sp_vport_fid_get(mlxsw_sp_vport);
4731+
struct mlxsw_sp_port *mlxsw_sp_port;
47344732

47354733
netdev_dbg(mlxsw_sp_vport->dev, "Left FID=%d\n", f->fid);
47364734

4735+
mlxsw_sp_vport_fid_set(mlxsw_sp_vport, NULL);
4736+
f->ref_count--;
4737+
4738+
mlxsw_sp_port = mlxsw_sp_vport_port(mlxsw_sp_vport);
4739+
if (mlxsw_sp_port->nr_port_vid_map == 1)
4740+
mlxsw_sp_port_vlan_mode_trans(mlxsw_sp_port);
4741+
mlxsw_sp_port->nr_port_vid_map--;
4742+
47374743
mlxsw_sp_vport_fid_map(mlxsw_sp_vport, f->fid, false);
47384744

47394745
mlxsw_sp_vport_flood_set(mlxsw_sp_vport, f->fid, false);
47404746

47414747
mlxsw_sp_port_fdb_flush(mlxsw_sp_vport, f->fid);
47424748

4743-
mlxsw_sp_vport_fid_set(mlxsw_sp_vport, NULL);
4744-
if (--f->ref_count == 0)
4749+
if (f->ref_count == 0)
47454750
mlxsw_sp_vfid_destroy(mlxsw_sp_vport->mlxsw_sp, f);
47464751
}
47474752

drivers/net/ethernet/mellanox/mlxsw/spectrum.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,7 @@ struct mlxsw_sp_port {
253253
struct delayed_work update_dw;
254254
} hw_stats;
255255
struct mlxsw_sp_port_sample *sample;
256+
unsigned int nr_port_vid_map; /* {Port, VID} => FID mappings */
256257
};
257258

258259
bool mlxsw_sp_port_dev_check(const struct net_device *dev);
@@ -343,6 +344,14 @@ mlxsw_sp_port_vport_find_by_fid(const struct mlxsw_sp_port *mlxsw_sp_port,
343344
return NULL;
344345
}
345346

347+
static inline struct mlxsw_sp_port *
348+
mlxsw_sp_vport_port(const struct mlxsw_sp_port *mlxsw_sp_vport)
349+
{
350+
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_vport->mlxsw_sp;
351+
352+
return mlxsw_sp->ports[mlxsw_sp_vport->local_port];
353+
}
354+
346355
static inline struct mlxsw_sp_fid *mlxsw_sp_fid_find(struct mlxsw_sp *mlxsw_sp,
347356
u16 fid)
348357
{
@@ -446,6 +455,8 @@ int mlxsw_sp_port_vid_stp_set(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid,
446455
int mlxsw_sp_port_vid_learning_set(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid,
447456
bool learn_enable);
448457
int mlxsw_sp_port_pvid_set(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid);
458+
int mlxsw_sp_port_vp_mode_trans(struct mlxsw_sp_port *mlxsw_sp_port);
459+
int mlxsw_sp_port_vlan_mode_trans(struct mlxsw_sp_port *mlxsw_sp_port);
449460

450461
#ifdef CONFIG_MLXSW_SPECTRUM_DCB
451462

drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3111,6 +3111,7 @@ static int mlxsw_sp_vport_rif_sp_join(struct mlxsw_sp_port *mlxsw_sp_vport,
31113111
{
31123112
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_vport->mlxsw_sp;
31133113
u16 vid = mlxsw_sp_vport_vid_get(mlxsw_sp_vport);
3114+
struct mlxsw_sp_port *mlxsw_sp_port;
31143115
struct mlxsw_sp_rif *rif;
31153116
int err;
31163117

@@ -3130,13 +3131,23 @@ static int mlxsw_sp_vport_rif_sp_join(struct mlxsw_sp_port *mlxsw_sp_vport,
31303131
if (err)
31313132
goto err_port_vid_stp_set;
31323133

3134+
mlxsw_sp_port = mlxsw_sp_vport_port(mlxsw_sp_vport);
3135+
if (mlxsw_sp_port->nr_port_vid_map++ == 0) {
3136+
err = mlxsw_sp_port_vp_mode_trans(mlxsw_sp_port);
3137+
if (err)
3138+
goto err_port_vp_mode_trans;
3139+
}
3140+
31333141
mlxsw_sp_vport_fid_set(mlxsw_sp_vport, rif->f);
31343142
rif->f->ref_count++;
31353143

31363144
netdev_dbg(mlxsw_sp_vport->dev, "Joined FID=%d\n", rif->f->fid);
31373145

31383146
return 0;
31393147

3148+
err_port_vp_mode_trans:
3149+
mlxsw_sp_port->nr_port_vid_map--;
3150+
mlxsw_sp_port_vid_stp_set(mlxsw_sp_vport, vid, BR_STATE_BLOCKING);
31403151
err_port_vid_stp_set:
31413152
mlxsw_sp_port_vid_learning_set(mlxsw_sp_vport, vid, true);
31423153
err_port_vid_learning_set:
@@ -3149,13 +3160,21 @@ static void mlxsw_sp_vport_rif_sp_leave(struct mlxsw_sp_port *mlxsw_sp_vport)
31493160
{
31503161
struct mlxsw_sp_fid *f = mlxsw_sp_vport_fid_get(mlxsw_sp_vport);
31513162
u16 vid = mlxsw_sp_vport_vid_get(mlxsw_sp_vport);
3163+
struct mlxsw_sp_port *mlxsw_sp_port;
31523164

31533165
netdev_dbg(mlxsw_sp_vport->dev, "Left FID=%d\n", f->fid);
31543166

3167+
f->ref_count--;
3168+
mlxsw_sp_vport_fid_set(mlxsw_sp_vport, NULL);
3169+
3170+
mlxsw_sp_port = mlxsw_sp_vport_port(mlxsw_sp_vport);
3171+
if (mlxsw_sp_port->nr_port_vid_map == 1)
3172+
mlxsw_sp_port_vlan_mode_trans(mlxsw_sp_port);
3173+
mlxsw_sp_port->nr_port_vid_map--;
31553174
mlxsw_sp_port_vid_stp_set(mlxsw_sp_vport, vid, BR_STATE_BLOCKING);
31563175
mlxsw_sp_port_vid_learning_set(mlxsw_sp_vport, vid, true);
3157-
mlxsw_sp_vport_fid_set(mlxsw_sp_vport, NULL);
3158-
if (--f->ref_count == 0)
3176+
3177+
if (f->ref_count == 0)
31593178
mlxsw_sp_vport_rif_sp_destroy(mlxsw_sp_vport, f->rif);
31603179
}
31613180

drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -617,7 +617,7 @@ static int mlxsw_sp_port_fid_map(struct mlxsw_sp_port *mlxsw_sp_port, u16 fid,
617617
/* If port doesn't have vPorts, then it can use the global
618618
* VID-to-FID mapping.
619619
*/
620-
if (list_empty(&mlxsw_sp_port->vports_list))
620+
if (mlxsw_sp_port->nr_port_vid_map == 0)
621621
return 0;
622622

623623
return mlxsw_sp_port_vid_to_fid_set(mlxsw_sp_port, mt, valid, fid, fid);

0 commit comments

Comments
 (0)