Skip to content

Commit b42a738

Browse files
committed
Merge branch 'dsa-fdb-isolation'
Vladimir Oltean says: ==================== DSA FDB isolation There are use cases which need FDB isolation between standalone ports and bridged ports, as well as isolation between ports of different bridges. Most of these use cases are a result of the fact that packets can now be partially forwarded by the software bridge, so one port might need to send a packet to the CPU but its FDB lookup will see that it can forward it directly to a bridge port where that packet was autonomously learned. So the source port will attempt to shortcircuit the CPU and forward autonomously, which it can't due to the forwarding isolation we have in place. So we will have packet drops instead of proper operation. Additionally, before DSA can implement IFF_UNICAST_FLT for standalone ports, we must have control over which database we install FDB entries corresponding to port MAC addresses in. We don't want to hinder the operation of the bridging layer. DSA does not have a driver API that encourages FDB isolation, so this needs to be created. The basis for this is a new struct dsa_db which annotates each FDB and MDB entry with the database it belongs to. The sja1105 and felix drivers are modified to observe the dsa_db argument, and therefore, enforce the FDB isolation. Compared to the previous RFC patch series from August: https://patchwork.kernel.org/project/netdevbpf/cover/[email protected]/ what is different is that I stopped trying to make SWITCHDEV_FDB_{ADD,DEL}_TO_DEVICE blocking, instead I'm making use of the fact that DSA waits for switchdev FDB work items to finish before a port leaves the bridge. This is possible since: https://patchwork.kernel.org/project/netdevbpf/patch/[email protected]/ Additionally, v2 is also rebased over the DSA LAG FDB work. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 1bb1c5b + 54c3198 commit b42a738

File tree

31 files changed

+925
-510
lines changed

31 files changed

+925
-510
lines changed

Documentation/networking/dsa/sja1105.rst

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,33 @@ of dropped frames, which is a sum of frames dropped due to timing violations,
293293
lack of destination ports and MTU enforcement checks). Byte-level counters are
294294
not available.
295295

296+
Limitations
297+
===========
298+
299+
The SJA1105 switch family always performs VLAN processing. When configured as
300+
VLAN-unaware, frames carry a different VLAN tag internally, depending on
301+
whether the port is standalone or under a VLAN-unaware bridge.
302+
303+
The virtual link keys are always fixed at {MAC DA, VLAN ID, VLAN PCP}, but the
304+
driver asks for the VLAN ID and VLAN PCP when the port is under a VLAN-aware
305+
bridge. Otherwise, it fills in the VLAN ID and PCP automatically, based on
306+
whether the port is standalone or in a VLAN-unaware bridge, and accepts only
307+
"VLAN-unaware" tc-flower keys (MAC DA).
308+
309+
The existing tc-flower keys that are offloaded using virtual links are no
310+
longer operational after one of the following happens:
311+
312+
- port was standalone and joins a bridge (VLAN-aware or VLAN-unaware)
313+
- port is part of a bridge whose VLAN awareness state changes
314+
- port was part of a bridge and becomes standalone
315+
- port was standalone, but another port joins a VLAN-aware bridge and this
316+
changes the global VLAN awareness state of the bridge
317+
318+
The driver cannot veto all these operations, and it cannot update/remove the
319+
existing tc-flower filters either. So for proper operation, the tc-flower
320+
filters should be installed only after the forwarding configuration of the port
321+
has been made, and removed by user space before making any changes to it.
322+
296323
Device Tree bindings and board design
297324
=====================================
298325

drivers/net/dsa/b53/b53_common.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1708,7 +1708,8 @@ static int b53_arl_op(struct b53_device *dev, int op, int port,
17081708
}
17091709

17101710
int b53_fdb_add(struct dsa_switch *ds, int port,
1711-
const unsigned char *addr, u16 vid)
1711+
const unsigned char *addr, u16 vid,
1712+
struct dsa_db db)
17121713
{
17131714
struct b53_device *priv = ds->priv;
17141715
int ret;
@@ -1728,7 +1729,8 @@ int b53_fdb_add(struct dsa_switch *ds, int port,
17281729
EXPORT_SYMBOL(b53_fdb_add);
17291730

17301731
int b53_fdb_del(struct dsa_switch *ds, int port,
1731-
const unsigned char *addr, u16 vid)
1732+
const unsigned char *addr, u16 vid,
1733+
struct dsa_db db)
17321734
{
17331735
struct b53_device *priv = ds->priv;
17341736
int ret;
@@ -1829,7 +1831,8 @@ int b53_fdb_dump(struct dsa_switch *ds, int port,
18291831
EXPORT_SYMBOL(b53_fdb_dump);
18301832

18311833
int b53_mdb_add(struct dsa_switch *ds, int port,
1832-
const struct switchdev_obj_port_mdb *mdb)
1834+
const struct switchdev_obj_port_mdb *mdb,
1835+
struct dsa_db db)
18331836
{
18341837
struct b53_device *priv = ds->priv;
18351838
int ret;
@@ -1849,7 +1852,8 @@ int b53_mdb_add(struct dsa_switch *ds, int port,
18491852
EXPORT_SYMBOL(b53_mdb_add);
18501853

18511854
int b53_mdb_del(struct dsa_switch *ds, int port,
1852-
const struct switchdev_obj_port_mdb *mdb)
1855+
const struct switchdev_obj_port_mdb *mdb,
1856+
struct dsa_db db)
18531857
{
18541858
struct b53_device *priv = ds->priv;
18551859
int ret;
@@ -1865,7 +1869,7 @@ int b53_mdb_del(struct dsa_switch *ds, int port,
18651869
EXPORT_SYMBOL(b53_mdb_del);
18661870

18671871
int b53_br_join(struct dsa_switch *ds, int port, struct dsa_bridge bridge,
1868-
bool *tx_fwd_offload)
1872+
bool *tx_fwd_offload, struct netlink_ext_ack *extack)
18691873
{
18701874
struct b53_device *dev = ds->priv;
18711875
s8 cpu_port = dsa_to_port(ds, port)->cpu_dp->index;

drivers/net/dsa/b53/b53_priv.h

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ void b53_get_ethtool_stats(struct dsa_switch *ds, int port, uint64_t *data);
324324
int b53_get_sset_count(struct dsa_switch *ds, int port, int sset);
325325
void b53_get_ethtool_phy_stats(struct dsa_switch *ds, int port, uint64_t *data);
326326
int b53_br_join(struct dsa_switch *ds, int port, struct dsa_bridge bridge,
327-
bool *tx_fwd_offload);
327+
bool *tx_fwd_offload, struct netlink_ext_ack *extack);
328328
void b53_br_leave(struct dsa_switch *ds, int port, struct dsa_bridge bridge);
329329
void b53_br_set_stp_state(struct dsa_switch *ds, int port, u8 state);
330330
void b53_br_fast_age(struct dsa_switch *ds, int port);
@@ -359,15 +359,19 @@ int b53_vlan_add(struct dsa_switch *ds, int port,
359359
int b53_vlan_del(struct dsa_switch *ds, int port,
360360
const struct switchdev_obj_port_vlan *vlan);
361361
int b53_fdb_add(struct dsa_switch *ds, int port,
362-
const unsigned char *addr, u16 vid);
362+
const unsigned char *addr, u16 vid,
363+
struct dsa_db db);
363364
int b53_fdb_del(struct dsa_switch *ds, int port,
364-
const unsigned char *addr, u16 vid);
365+
const unsigned char *addr, u16 vid,
366+
struct dsa_db db);
365367
int b53_fdb_dump(struct dsa_switch *ds, int port,
366368
dsa_fdb_dump_cb_t *cb, void *data);
367369
int b53_mdb_add(struct dsa_switch *ds, int port,
368-
const struct switchdev_obj_port_mdb *mdb);
370+
const struct switchdev_obj_port_mdb *mdb,
371+
struct dsa_db db);
369372
int b53_mdb_del(struct dsa_switch *ds, int port,
370-
const struct switchdev_obj_port_mdb *mdb);
373+
const struct switchdev_obj_port_mdb *mdb,
374+
struct dsa_db db);
371375
int b53_mirror_add(struct dsa_switch *ds, int port,
372376
struct dsa_mall_mirror_tc_entry *mirror, bool ingress);
373377
enum dsa_tag_protocol b53_get_tag_protocol(struct dsa_switch *ds, int port,

drivers/net/dsa/dsa_loop.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,8 @@ static int dsa_loop_phy_write(struct dsa_switch *ds, int port,
168168

169169
static int dsa_loop_port_bridge_join(struct dsa_switch *ds, int port,
170170
struct dsa_bridge bridge,
171-
bool *tx_fwd_offload)
171+
bool *tx_fwd_offload,
172+
struct netlink_ext_ack *extack)
172173
{
173174
dev_dbg(ds->dev, "%s: port: %d, bridge: %s\n",
174175
__func__, port, bridge.dev->name);

drivers/net/dsa/hirschmann/hellcreek.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -675,7 +675,8 @@ static int hellcreek_bridge_flags(struct dsa_switch *ds, int port,
675675

676676
static int hellcreek_port_bridge_join(struct dsa_switch *ds, int port,
677677
struct dsa_bridge bridge,
678-
bool *tx_fwd_offload)
678+
bool *tx_fwd_offload,
679+
struct netlink_ext_ack *extack)
679680
{
680681
struct hellcreek *hellcreek = ds->priv;
681682

@@ -827,7 +828,8 @@ static int hellcreek_fdb_get(struct hellcreek *hellcreek,
827828
}
828829

829830
static int hellcreek_fdb_add(struct dsa_switch *ds, int port,
830-
const unsigned char *addr, u16 vid)
831+
const unsigned char *addr, u16 vid,
832+
struct dsa_db db)
831833
{
832834
struct hellcreek_fdb_entry entry = { 0 };
833835
struct hellcreek *hellcreek = ds->priv;
@@ -872,7 +874,8 @@ static int hellcreek_fdb_add(struct dsa_switch *ds, int port,
872874
}
873875

874876
static int hellcreek_fdb_del(struct dsa_switch *ds, int port,
875-
const unsigned char *addr, u16 vid)
877+
const unsigned char *addr, u16 vid,
878+
struct dsa_db db)
876879
{
877880
struct hellcreek_fdb_entry entry = { 0 };
878881
struct hellcreek *hellcreek = ds->priv;

drivers/net/dsa/lan9303-core.c

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1111,7 +1111,8 @@ static void lan9303_port_disable(struct dsa_switch *ds, int port)
11111111

11121112
static int lan9303_port_bridge_join(struct dsa_switch *ds, int port,
11131113
struct dsa_bridge bridge,
1114-
bool *tx_fwd_offload)
1114+
bool *tx_fwd_offload,
1115+
struct netlink_ext_ack *extack)
11151116
{
11161117
struct lan9303 *chip = ds->priv;
11171118

@@ -1188,7 +1189,8 @@ static void lan9303_port_fast_age(struct dsa_switch *ds, int port)
11881189
}
11891190

11901191
static int lan9303_port_fdb_add(struct dsa_switch *ds, int port,
1191-
const unsigned char *addr, u16 vid)
1192+
const unsigned char *addr, u16 vid,
1193+
struct dsa_db db)
11921194
{
11931195
struct lan9303 *chip = ds->priv;
11941196

@@ -1200,8 +1202,8 @@ static int lan9303_port_fdb_add(struct dsa_switch *ds, int port,
12001202
}
12011203

12021204
static int lan9303_port_fdb_del(struct dsa_switch *ds, int port,
1203-
const unsigned char *addr, u16 vid)
1204-
1205+
const unsigned char *addr, u16 vid,
1206+
struct dsa_db db)
12051207
{
12061208
struct lan9303 *chip = ds->priv;
12071209

@@ -1245,7 +1247,8 @@ static int lan9303_port_mdb_prepare(struct dsa_switch *ds, int port,
12451247
}
12461248

12471249
static int lan9303_port_mdb_add(struct dsa_switch *ds, int port,
1248-
const struct switchdev_obj_port_mdb *mdb)
1250+
const struct switchdev_obj_port_mdb *mdb,
1251+
struct dsa_db db)
12491252
{
12501253
struct lan9303 *chip = ds->priv;
12511254
int err;
@@ -1260,7 +1263,8 @@ static int lan9303_port_mdb_add(struct dsa_switch *ds, int port,
12601263
}
12611264

12621265
static int lan9303_port_mdb_del(struct dsa_switch *ds, int port,
1263-
const struct switchdev_obj_port_mdb *mdb)
1266+
const struct switchdev_obj_port_mdb *mdb,
1267+
struct dsa_db db)
12641268
{
12651269
struct lan9303 *chip = ds->priv;
12661270

drivers/net/dsa/lantiq_gswip.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1152,7 +1152,8 @@ static int gswip_vlan_remove(struct gswip_priv *priv,
11521152

11531153
static int gswip_port_bridge_join(struct dsa_switch *ds, int port,
11541154
struct dsa_bridge bridge,
1155-
bool *tx_fwd_offload)
1155+
bool *tx_fwd_offload,
1156+
struct netlink_ext_ack *extack)
11561157
{
11571158
struct net_device *br = bridge.dev;
11581159
struct gswip_priv *priv = ds->priv;
@@ -1389,13 +1390,15 @@ static int gswip_port_fdb(struct dsa_switch *ds, int port,
13891390
}
13901391

13911392
static int gswip_port_fdb_add(struct dsa_switch *ds, int port,
1392-
const unsigned char *addr, u16 vid)
1393+
const unsigned char *addr, u16 vid,
1394+
struct dsa_db db)
13931395
{
13941396
return gswip_port_fdb(ds, port, addr, vid, true);
13951397
}
13961398

13971399
static int gswip_port_fdb_del(struct dsa_switch *ds, int port,
1398-
const unsigned char *addr, u16 vid)
1400+
const unsigned char *addr, u16 vid,
1401+
struct dsa_db db)
13991402
{
14001403
return gswip_port_fdb(ds, port, addr, vid, false);
14011404
}

drivers/net/dsa/microchip/ksz9477.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -640,7 +640,8 @@ static int ksz9477_port_vlan_del(struct dsa_switch *ds, int port,
640640
}
641641

642642
static int ksz9477_port_fdb_add(struct dsa_switch *ds, int port,
643-
const unsigned char *addr, u16 vid)
643+
const unsigned char *addr, u16 vid,
644+
struct dsa_db db)
644645
{
645646
struct ksz_device *dev = ds->priv;
646647
u32 alu_table[4];
@@ -697,7 +698,8 @@ static int ksz9477_port_fdb_add(struct dsa_switch *ds, int port,
697698
}
698699

699700
static int ksz9477_port_fdb_del(struct dsa_switch *ds, int port,
700-
const unsigned char *addr, u16 vid)
701+
const unsigned char *addr, u16 vid,
702+
struct dsa_db db)
701703
{
702704
struct ksz_device *dev = ds->priv;
703705
u32 alu_table[4];
@@ -839,7 +841,8 @@ static int ksz9477_port_fdb_dump(struct dsa_switch *ds, int port,
839841
}
840842

841843
static int ksz9477_port_mdb_add(struct dsa_switch *ds, int port,
842-
const struct switchdev_obj_port_mdb *mdb)
844+
const struct switchdev_obj_port_mdb *mdb,
845+
struct dsa_db db)
843846
{
844847
struct ksz_device *dev = ds->priv;
845848
u32 static_table[4];
@@ -914,7 +917,8 @@ static int ksz9477_port_mdb_add(struct dsa_switch *ds, int port,
914917
}
915918

916919
static int ksz9477_port_mdb_del(struct dsa_switch *ds, int port,
917-
const struct switchdev_obj_port_mdb *mdb)
920+
const struct switchdev_obj_port_mdb *mdb,
921+
struct dsa_db db)
918922
{
919923
struct ksz_device *dev = ds->priv;
920924
u32 static_table[4];

drivers/net/dsa/microchip/ksz_common.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,8 @@ EXPORT_SYMBOL_GPL(ksz_get_ethtool_stats);
217217

218218
int ksz_port_bridge_join(struct dsa_switch *ds, int port,
219219
struct dsa_bridge bridge,
220-
bool *tx_fwd_offload)
220+
bool *tx_fwd_offload,
221+
struct netlink_ext_ack *extack)
221222
{
222223
/* port_stp_state_set() will be called after to put the port in
223224
* appropriate state so there is no need to do anything.
@@ -276,7 +277,8 @@ int ksz_port_fdb_dump(struct dsa_switch *ds, int port, dsa_fdb_dump_cb_t *cb,
276277
EXPORT_SYMBOL_GPL(ksz_port_fdb_dump);
277278

278279
int ksz_port_mdb_add(struct dsa_switch *ds, int port,
279-
const struct switchdev_obj_port_mdb *mdb)
280+
const struct switchdev_obj_port_mdb *mdb,
281+
struct dsa_db db)
280282
{
281283
struct ksz_device *dev = ds->priv;
282284
struct alu_struct alu;
@@ -321,7 +323,8 @@ int ksz_port_mdb_add(struct dsa_switch *ds, int port,
321323
EXPORT_SYMBOL_GPL(ksz_port_mdb_add);
322324

323325
int ksz_port_mdb_del(struct dsa_switch *ds, int port,
324-
const struct switchdev_obj_port_mdb *mdb)
326+
const struct switchdev_obj_port_mdb *mdb,
327+
struct dsa_db db)
325328
{
326329
struct ksz_device *dev = ds->priv;
327330
struct alu_struct alu;

drivers/net/dsa/microchip/ksz_common.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -159,16 +159,19 @@ void ksz_mac_link_down(struct dsa_switch *ds, int port, unsigned int mode,
159159
int ksz_sset_count(struct dsa_switch *ds, int port, int sset);
160160
void ksz_get_ethtool_stats(struct dsa_switch *ds, int port, uint64_t *buf);
161161
int ksz_port_bridge_join(struct dsa_switch *ds, int port,
162-
struct dsa_bridge bridge, bool *tx_fwd_offload);
162+
struct dsa_bridge bridge, bool *tx_fwd_offload,
163+
struct netlink_ext_ack *extack);
163164
void ksz_port_bridge_leave(struct dsa_switch *ds, int port,
164165
struct dsa_bridge bridge);
165166
void ksz_port_fast_age(struct dsa_switch *ds, int port);
166167
int ksz_port_fdb_dump(struct dsa_switch *ds, int port, dsa_fdb_dump_cb_t *cb,
167168
void *data);
168169
int ksz_port_mdb_add(struct dsa_switch *ds, int port,
169-
const struct switchdev_obj_port_mdb *mdb);
170+
const struct switchdev_obj_port_mdb *mdb,
171+
struct dsa_db db);
170172
int ksz_port_mdb_del(struct dsa_switch *ds, int port,
171-
const struct switchdev_obj_port_mdb *mdb);
173+
const struct switchdev_obj_port_mdb *mdb,
174+
struct dsa_db db);
172175
int ksz_enable_port(struct dsa_switch *ds, int port, struct phy_device *phy);
173176

174177
/* Common register access functions */

drivers/net/dsa/mt7530.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1186,7 +1186,8 @@ mt7530_port_bridge_flags(struct dsa_switch *ds, int port,
11861186

11871187
static int
11881188
mt7530_port_bridge_join(struct dsa_switch *ds, int port,
1189-
struct dsa_bridge bridge, bool *tx_fwd_offload)
1189+
struct dsa_bridge bridge, bool *tx_fwd_offload,
1190+
struct netlink_ext_ack *extack)
11901191
{
11911192
struct dsa_port *dp = dsa_to_port(ds, port), *other_dp;
11921193
u32 port_bitmap = BIT(MT7530_CPU_PORT);
@@ -1349,7 +1350,8 @@ mt7530_port_bridge_leave(struct dsa_switch *ds, int port,
13491350

13501351
static int
13511352
mt7530_port_fdb_add(struct dsa_switch *ds, int port,
1352-
const unsigned char *addr, u16 vid)
1353+
const unsigned char *addr, u16 vid,
1354+
struct dsa_db db)
13531355
{
13541356
struct mt7530_priv *priv = ds->priv;
13551357
int ret;
@@ -1365,7 +1367,8 @@ mt7530_port_fdb_add(struct dsa_switch *ds, int port,
13651367

13661368
static int
13671369
mt7530_port_fdb_del(struct dsa_switch *ds, int port,
1368-
const unsigned char *addr, u16 vid)
1370+
const unsigned char *addr, u16 vid,
1371+
struct dsa_db db)
13691372
{
13701373
struct mt7530_priv *priv = ds->priv;
13711374
int ret;
@@ -1416,7 +1419,8 @@ mt7530_port_fdb_dump(struct dsa_switch *ds, int port,
14161419

14171420
static int
14181421
mt7530_port_mdb_add(struct dsa_switch *ds, int port,
1419-
const struct switchdev_obj_port_mdb *mdb)
1422+
const struct switchdev_obj_port_mdb *mdb,
1423+
struct dsa_db db)
14201424
{
14211425
struct mt7530_priv *priv = ds->priv;
14221426
const u8 *addr = mdb->addr;
@@ -1442,7 +1446,8 @@ mt7530_port_mdb_add(struct dsa_switch *ds, int port,
14421446

14431447
static int
14441448
mt7530_port_mdb_del(struct dsa_switch *ds, int port,
1445-
const struct switchdev_obj_port_mdb *mdb)
1449+
const struct switchdev_obj_port_mdb *mdb,
1450+
struct dsa_db db)
14461451
{
14471452
struct mt7530_priv *priv = ds->priv;
14481453
const u8 *addr = mdb->addr;

0 commit comments

Comments
 (0)