Skip to content

Commit 9f4c2cf

Browse files
committed
Merge branch 'mlxsw-Un-offload-FDB-on-NVE-detach-attach'
Ido Schimmel says: ==================== mlxsw: Un/offload FDB on NVE detach/attach Petr says: When a VXLAN device is attached to a bridge of a driver capable of offloading such, or upped, the FDB entries already present at the device need to be offloaded. Similarly when an offloaded VXLAN device ceases being interesting (it is downed, or detached, or a front-panel port netdevice is detached from the bridge that the VXLAN device is attached to), any offloaded FDB entries need to be unoffloaded and unmarked. This attach / detach processing is implemented in this patchset. In patch #1, a code pattern is extracted into a named function for easier reuse. In patch #2, vxlan_fdb_replay() is added to send SWITCHDEV_VXLAN_FDB_ADD_TO_DEVICE for each FDB entry with a given VNI. The intention is that the offloading driver will interpret these events like any other and thus offload the FDB entries that existed prior to VXLAN attach. In patches #3 and #4, the functions vxlan_fdb_clear_offload() resp. br_fdb_clear_offload() are added. These clear the offloaded flag at matching FDB entries. In patches #5-#9, we introduce FID-type-specific and NVE-type-specific ops necessary to properly abstract invocations of the replay/clear functions. Finally patch #10 implements the FDB management. In patch #11, the mlxsw-specific test case is extended to check that the management of offload marks under the newly-supported situations is correct. Patch #12, from Ido, exercises the new code paths in actual functional test. v2: - Patch #1: - Modify vxlan_fdb_switchdev_notifier_info() to initialize the structure through a passed-in pointer argument, instead of returning it as a value. - Patch #2: - Adapt to API change in vxlan_fdb_switchdev_notifier_info() ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 6b241e4 + 55939b2 commit 9f4c2cf

File tree

12 files changed

+495
-31
lines changed

12 files changed

+495
-31
lines changed

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

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@ enum mlxsw_sp_fid_type {
8181
MLXSW_SP_FID_TYPE_MAX,
8282
};
8383

84+
enum mlxsw_sp_nve_type {
85+
MLXSW_SP_NVE_TYPE_VXLAN,
86+
};
87+
8488
struct mlxsw_sp_mid {
8589
struct list_head list;
8690
unsigned char addr[ETH_ALEN];
@@ -383,6 +387,7 @@ int mlxsw_sp_bridge_vxlan_join(struct mlxsw_sp *mlxsw_sp,
383387
struct netlink_ext_ack *extack);
384388
void mlxsw_sp_bridge_vxlan_leave(struct mlxsw_sp *mlxsw_sp,
385389
const struct net_device *vxlan_dev);
390+
extern struct notifier_block mlxsw_sp_switchdev_notifier;
386391

387392
/* spectrum.c */
388393
int mlxsw_sp_port_ets_set(struct mlxsw_sp_port *mlxsw_sp_port,
@@ -745,16 +750,21 @@ bool mlxsw_sp_fid_lag_vid_valid(const struct mlxsw_sp_fid *fid);
745750
struct mlxsw_sp_fid *mlxsw_sp_fid_lookup_by_index(struct mlxsw_sp *mlxsw_sp,
746751
u16 fid_index);
747752
int mlxsw_sp_fid_nve_ifindex(const struct mlxsw_sp_fid *fid, int *nve_ifindex);
753+
int mlxsw_sp_fid_nve_type(const struct mlxsw_sp_fid *fid,
754+
enum mlxsw_sp_nve_type *p_type);
748755
struct mlxsw_sp_fid *mlxsw_sp_fid_lookup_by_vni(struct mlxsw_sp *mlxsw_sp,
749756
__be32 vni);
750757
int mlxsw_sp_fid_vni(const struct mlxsw_sp_fid *fid, __be32 *vni);
751758
int mlxsw_sp_fid_nve_flood_index_set(struct mlxsw_sp_fid *fid,
752759
u32 nve_flood_index);
753760
void mlxsw_sp_fid_nve_flood_index_clear(struct mlxsw_sp_fid *fid);
754761
bool mlxsw_sp_fid_nve_flood_index_is_set(const struct mlxsw_sp_fid *fid);
755-
int mlxsw_sp_fid_vni_set(struct mlxsw_sp_fid *fid, __be32 vni, int nve_ifindex);
762+
int mlxsw_sp_fid_vni_set(struct mlxsw_sp_fid *fid, enum mlxsw_sp_nve_type type,
763+
__be32 vni, int nve_ifindex);
756764
void mlxsw_sp_fid_vni_clear(struct mlxsw_sp_fid *fid);
757765
bool mlxsw_sp_fid_vni_is_set(const struct mlxsw_sp_fid *fid);
766+
void mlxsw_sp_fid_fdb_clear_offload(const struct mlxsw_sp_fid *fid,
767+
const struct net_device *nve_dev);
758768
int mlxsw_sp_fid_flood_set(struct mlxsw_sp_fid *fid,
759769
enum mlxsw_sp_flood_type packet_type, u8 local_port,
760770
bool member);
@@ -823,10 +833,6 @@ extern const struct mlxsw_sp_mr_tcam_ops mlxsw_sp1_mr_tcam_ops;
823833
extern const struct mlxsw_sp_mr_tcam_ops mlxsw_sp2_mr_tcam_ops;
824834

825835
/* spectrum_nve.c */
826-
enum mlxsw_sp_nve_type {
827-
MLXSW_SP_NVE_TYPE_VXLAN,
828-
};
829-
830836
struct mlxsw_sp_nve_params {
831837
enum mlxsw_sp_nve_type type;
832838
__be32 vni;

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

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ struct mlxsw_sp_fid {
3030
struct rhash_head ht_node;
3131

3232
struct rhash_head vni_ht_node;
33+
enum mlxsw_sp_nve_type nve_type;
3334
__be32 vni;
3435
u32 nve_flood_index;
3536
int nve_ifindex;
@@ -84,6 +85,8 @@ struct mlxsw_sp_fid_ops {
8485
int (*nve_flood_index_set)(struct mlxsw_sp_fid *fid,
8586
u32 nve_flood_index);
8687
void (*nve_flood_index_clear)(struct mlxsw_sp_fid *fid);
88+
void (*fdb_clear_offload)(const struct mlxsw_sp_fid *fid,
89+
const struct net_device *nve_dev);
8790
};
8891

8992
struct mlxsw_sp_fid_family {
@@ -151,6 +154,17 @@ int mlxsw_sp_fid_nve_ifindex(const struct mlxsw_sp_fid *fid, int *nve_ifindex)
151154
return 0;
152155
}
153156

157+
int mlxsw_sp_fid_nve_type(const struct mlxsw_sp_fid *fid,
158+
enum mlxsw_sp_nve_type *p_type)
159+
{
160+
if (!fid->vni_valid)
161+
return -EINVAL;
162+
163+
*p_type = fid->nve_type;
164+
165+
return 0;
166+
}
167+
154168
struct mlxsw_sp_fid *mlxsw_sp_fid_lookup_by_vni(struct mlxsw_sp *mlxsw_sp,
155169
__be32 vni)
156170
{
@@ -211,7 +225,8 @@ bool mlxsw_sp_fid_nve_flood_index_is_set(const struct mlxsw_sp_fid *fid)
211225
return fid->nve_flood_index_valid;
212226
}
213227

214-
int mlxsw_sp_fid_vni_set(struct mlxsw_sp_fid *fid, __be32 vni, int nve_ifindex)
228+
int mlxsw_sp_fid_vni_set(struct mlxsw_sp_fid *fid, enum mlxsw_sp_nve_type type,
229+
__be32 vni, int nve_ifindex)
215230
{
216231
struct mlxsw_sp_fid_family *fid_family = fid->fid_family;
217232
const struct mlxsw_sp_fid_ops *ops = fid_family->ops;
@@ -221,6 +236,7 @@ int mlxsw_sp_fid_vni_set(struct mlxsw_sp_fid *fid, __be32 vni, int nve_ifindex)
221236
if (WARN_ON(!ops->vni_set || fid->vni_valid))
222237
return -EINVAL;
223238

239+
fid->nve_type = type;
224240
fid->nve_ifindex = nve_ifindex;
225241
fid->vni = vni;
226242
err = rhashtable_lookup_insert_fast(&mlxsw_sp->fid_core->vni_ht,
@@ -263,6 +279,16 @@ bool mlxsw_sp_fid_vni_is_set(const struct mlxsw_sp_fid *fid)
263279
return fid->vni_valid;
264280
}
265281

282+
void mlxsw_sp_fid_fdb_clear_offload(const struct mlxsw_sp_fid *fid,
283+
const struct net_device *nve_dev)
284+
{
285+
struct mlxsw_sp_fid_family *fid_family = fid->fid_family;
286+
const struct mlxsw_sp_fid_ops *ops = fid_family->ops;
287+
288+
if (ops->fdb_clear_offload)
289+
ops->fdb_clear_offload(fid, nve_dev);
290+
}
291+
266292
static const struct mlxsw_sp_flood_table *
267293
mlxsw_sp_fid_flood_table_lookup(const struct mlxsw_sp_fid *fid,
268294
enum mlxsw_sp_flood_type packet_type)
@@ -752,6 +778,13 @@ static void mlxsw_sp_fid_8021d_nve_flood_index_clear(struct mlxsw_sp_fid *fid)
752778
fid->vni_valid, 0, false);
753779
}
754780

781+
static void
782+
mlxsw_sp_fid_8021d_fdb_clear_offload(const struct mlxsw_sp_fid *fid,
783+
const struct net_device *nve_dev)
784+
{
785+
br_fdb_clear_offload(nve_dev, 0);
786+
}
787+
755788
static const struct mlxsw_sp_fid_ops mlxsw_sp_fid_8021d_ops = {
756789
.setup = mlxsw_sp_fid_8021d_setup,
757790
.configure = mlxsw_sp_fid_8021d_configure,
@@ -765,6 +798,7 @@ static const struct mlxsw_sp_fid_ops mlxsw_sp_fid_8021d_ops = {
765798
.vni_clear = mlxsw_sp_fid_8021d_vni_clear,
766799
.nve_flood_index_set = mlxsw_sp_fid_8021d_nve_flood_index_set,
767800
.nve_flood_index_clear = mlxsw_sp_fid_8021d_nve_flood_index_clear,
801+
.fdb_clear_offload = mlxsw_sp_fid_8021d_fdb_clear_offload,
768802
};
769803

770804
static const struct mlxsw_sp_flood_table mlxsw_sp_fid_8021d_flood_tables[] = {
@@ -801,6 +835,13 @@ static const struct mlxsw_sp_fid_family mlxsw_sp_fid_8021d_family = {
801835
.lag_vid_valid = 1,
802836
};
803837

838+
static void
839+
mlxsw_sp_fid_8021q_fdb_clear_offload(const struct mlxsw_sp_fid *fid,
840+
const struct net_device *nve_dev)
841+
{
842+
br_fdb_clear_offload(nve_dev, mlxsw_sp_fid_8021q_vid(fid));
843+
}
844+
804845
static const struct mlxsw_sp_fid_ops mlxsw_sp_fid_8021q_emu_ops = {
805846
.setup = mlxsw_sp_fid_8021q_setup,
806847
.configure = mlxsw_sp_fid_8021d_configure,
@@ -814,6 +855,7 @@ static const struct mlxsw_sp_fid_ops mlxsw_sp_fid_8021q_emu_ops = {
814855
.vni_clear = mlxsw_sp_fid_8021d_vni_clear,
815856
.nve_flood_index_set = mlxsw_sp_fid_8021d_nve_flood_index_set,
816857
.nve_flood_index_clear = mlxsw_sp_fid_8021d_nve_flood_index_clear,
858+
.fdb_clear_offload = mlxsw_sp_fid_8021q_fdb_clear_offload,
817859
};
818860

819861
/* There are 4K-2 emulated 802.1Q FIDs, starting right after the 802.1D FIDs */

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

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -789,6 +789,21 @@ static void mlxsw_sp_nve_fdb_flush_by_fid(struct mlxsw_sp *mlxsw_sp,
789789
mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sfdf), sfdf_pl);
790790
}
791791

792+
static void mlxsw_sp_nve_fdb_clear_offload(struct mlxsw_sp *mlxsw_sp,
793+
const struct mlxsw_sp_fid *fid,
794+
const struct net_device *nve_dev,
795+
__be32 vni)
796+
{
797+
const struct mlxsw_sp_nve_ops *ops;
798+
enum mlxsw_sp_nve_type type;
799+
800+
if (WARN_ON(mlxsw_sp_fid_nve_type(fid, &type)))
801+
return;
802+
803+
ops = mlxsw_sp->nve->nve_ops_arr[type];
804+
ops->fdb_clear_offload(nve_dev, vni);
805+
}
806+
792807
int mlxsw_sp_nve_fid_enable(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_fid *fid,
793808
struct mlxsw_sp_nve_params *params,
794809
struct netlink_ext_ack *extack)
@@ -817,16 +832,25 @@ int mlxsw_sp_nve_fid_enable(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_fid *fid,
817832
return err;
818833
}
819834

820-
err = mlxsw_sp_fid_vni_set(fid, params->vni, params->dev->ifindex);
835+
err = mlxsw_sp_fid_vni_set(fid, params->type, params->vni,
836+
params->dev->ifindex);
821837
if (err) {
822838
NL_SET_ERR_MSG_MOD(extack, "Failed to set VNI on FID");
823839
goto err_fid_vni_set;
824840
}
825841

826842
nve->config = config;
827843

844+
err = ops->fdb_replay(params->dev, params->vni);
845+
if (err) {
846+
NL_SET_ERR_MSG_MOD(extack, "Failed to offload the FDB");
847+
goto err_fdb_replay;
848+
}
849+
828850
return 0;
829851

852+
err_fdb_replay:
853+
mlxsw_sp_fid_vni_clear(fid);
830854
err_fid_vni_set:
831855
mlxsw_sp_nve_tunnel_fini(mlxsw_sp);
832856
return err;
@@ -836,9 +860,27 @@ void mlxsw_sp_nve_fid_disable(struct mlxsw_sp *mlxsw_sp,
836860
struct mlxsw_sp_fid *fid)
837861
{
838862
u16 fid_index = mlxsw_sp_fid_index(fid);
863+
struct net_device *nve_dev;
864+
int nve_ifindex;
865+
__be32 vni;
839866

840867
mlxsw_sp_nve_flood_ip_flush(mlxsw_sp, fid);
841868
mlxsw_sp_nve_fdb_flush_by_fid(mlxsw_sp, fid_index);
869+
870+
if (WARN_ON(mlxsw_sp_fid_nve_ifindex(fid, &nve_ifindex) ||
871+
mlxsw_sp_fid_vni(fid, &vni)))
872+
goto out;
873+
874+
nve_dev = dev_get_by_index(&init_net, nve_ifindex);
875+
if (!nve_dev)
876+
goto out;
877+
878+
mlxsw_sp_nve_fdb_clear_offload(mlxsw_sp, fid, nve_dev, vni);
879+
mlxsw_sp_fid_fdb_clear_offload(fid, nve_dev);
880+
881+
dev_put(nve_dev);
882+
883+
out:
842884
mlxsw_sp_fid_vni_clear(fid);
843885
mlxsw_sp_nve_tunnel_fini(mlxsw_sp);
844886
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ struct mlxsw_sp_nve_ops {
4141
int (*init)(struct mlxsw_sp_nve *nve,
4242
const struct mlxsw_sp_nve_config *config);
4343
void (*fini)(struct mlxsw_sp_nve *nve);
44+
int (*fdb_replay)(const struct net_device *nve_dev, __be32 vni);
45+
void (*fdb_clear_offload)(const struct net_device *nve_dev, __be32 vni);
4446
};
4547

4648
extern const struct mlxsw_sp_nve_ops mlxsw_sp1_nve_vxlan_ops;

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,12 +211,30 @@ static void mlxsw_sp1_nve_vxlan_fini(struct mlxsw_sp_nve *nve)
211211
config->udp_dport);
212212
}
213213

214+
static int
215+
mlxsw_sp_nve_vxlan_fdb_replay(const struct net_device *nve_dev, __be32 vni)
216+
{
217+
if (WARN_ON(!netif_is_vxlan(nve_dev)))
218+
return -EINVAL;
219+
return vxlan_fdb_replay(nve_dev, vni, &mlxsw_sp_switchdev_notifier);
220+
}
221+
222+
static void
223+
mlxsw_sp_nve_vxlan_clear_offload(const struct net_device *nve_dev, __be32 vni)
224+
{
225+
if (WARN_ON(!netif_is_vxlan(nve_dev)))
226+
return;
227+
vxlan_fdb_clear_offload(nve_dev, vni);
228+
}
229+
214230
const struct mlxsw_sp_nve_ops mlxsw_sp1_nve_vxlan_ops = {
215231
.type = MLXSW_SP_NVE_TYPE_VXLAN,
216232
.can_offload = mlxsw_sp1_nve_vxlan_can_offload,
217233
.nve_config = mlxsw_sp_nve_vxlan_config,
218234
.init = mlxsw_sp1_nve_vxlan_init,
219235
.fini = mlxsw_sp1_nve_vxlan_fini,
236+
.fdb_replay = mlxsw_sp_nve_vxlan_fdb_replay,
237+
.fdb_clear_offload = mlxsw_sp_nve_vxlan_clear_offload,
220238
};
221239

222240
static bool mlxsw_sp2_nve_vxlan_can_offload(const struct mlxsw_sp_nve *nve,
@@ -242,4 +260,6 @@ const struct mlxsw_sp_nve_ops mlxsw_sp2_nve_vxlan_ops = {
242260
.nve_config = mlxsw_sp_nve_vxlan_config,
243261
.init = mlxsw_sp2_nve_vxlan_init,
244262
.fini = mlxsw_sp2_nve_vxlan_fini,
263+
.fdb_replay = mlxsw_sp_nve_vxlan_fdb_replay,
264+
.fdb_clear_offload = mlxsw_sp_nve_vxlan_clear_offload,
245265
};

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3186,7 +3186,7 @@ static int mlxsw_sp_switchdev_event(struct notifier_block *unused,
31863186
return NOTIFY_BAD;
31873187
}
31883188

3189-
static struct notifier_block mlxsw_sp_switchdev_notifier = {
3189+
struct notifier_block mlxsw_sp_switchdev_notifier = {
31903190
.notifier_call = mlxsw_sp_switchdev_event,
31913191
};
31923192

0 commit comments

Comments
 (0)