Skip to content

Commit b117e1e

Browse files
vladimirolteandavem330
authored andcommitted
net: dsa: delete dsa_legacy_fdb_add and dsa_legacy_fdb_del
We want to add reference counting for FDB entries in cross-chip topologies, and in order for that to have any chance of working and not be unbalanced (leading to entries which are never deleted), we need to ensure that higher layers are sane, because if they aren't, it's garbage in, garbage out. For example, if we add a bridge FDB entry twice, the bridge properly errors out: $ bridge fdb add dev swp0 00:01:02:03:04:07 master static $ bridge fdb add dev swp0 00:01:02:03:04:07 master static RTNETLINK answers: File exists However, the same thing cannot be said about the bridge bypass operations: $ bridge fdb add dev swp0 00:01:02:03:04:07 $ bridge fdb add dev swp0 00:01:02:03:04:07 $ bridge fdb add dev swp0 00:01:02:03:04:07 $ bridge fdb add dev swp0 00:01:02:03:04:07 $ echo $? 0 But one 'bridge fdb del' is enough to remove the entry, no matter how many times it was added. The bridge bypass operations are impossible to maintain in these circumstances and lack of support for reference counting the cross-chip notifiers is holding us back from making further progress, so just drop support for them. The only way left for users to install static bridge FDB entries is the proper one, using the "master static" flags. With this change, rtnl_fdb_add() falls back to calling ndo_dflt_fdb_add() which uses the duplicate-exclusive variant of dev_uc_add(): dev_uc_add_excl(). Because DSA does not (yet) declare IFF_UNICAST_FLT, this results in us going to promiscuous mode: $ bridge fdb add dev swp0 00:01:02:03:04:05 [ 28.206743] device swp0 entered promiscuous mode $ bridge fdb add dev swp0 00:01:02:03:04:05 RTNETLINK answers: File exists So even if it does not completely fail, there is at least some indication that it is behaving differently from before, and closer to user space expectations, I would argue (the lack of a "local|static" specifier defaults to "local", or "host-only", so dev_uc_add() is a reasonable default implementation). If the generic implementation of .ndo_fdb_add provided by Vlad Yasevich is a proof of anything, it only proves that the implementation provided by DSA was always wrong, by not looking at "ndm->ndm_state & NUD_NOARP" (the "static" flag which means that the FDB entry points outwards) and "ndm->ndm_state & NUD_PERMANENT" (the "local" flag which means that the FDB entry points towards the host). It all used to mean the same thing to DSA. Update the documentation so that the users are not confused about what's going on. Signed-off-by: Vladimir Oltean <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent f851a72 commit b117e1e

File tree

2 files changed

+68
-23
lines changed

2 files changed

+68
-23
lines changed

Documentation/networking/dsa/configuration.rst

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,3 +292,71 @@ configuration.
292292
293293
# bring up the bridge devices
294294
ip link set br0 up
295+
296+
Forwarding database (FDB) management
297+
------------------------------------
298+
299+
The existing DSA switches do not have the necessary hardware support to keep
300+
the software FDB of the bridge in sync with the hardware tables, so the two
301+
tables are managed separately (``bridge fdb show`` queries both, and depending
302+
on whether the ``self`` or ``master`` flags are being used, a ``bridge fdb
303+
add`` or ``bridge fdb del`` command acts upon entries from one or both tables).
304+
305+
Up until kernel v4.14, DSA only supported user space management of bridge FDB
306+
entries using the bridge bypass operations (which do not update the software
307+
FDB, just the hardware one) using the ``self`` flag (which is optional and can
308+
be omitted).
309+
310+
.. code-block:: sh
311+
312+
bridge fdb add dev swp0 00:01:02:03:04:05 self static
313+
# or shorthand
314+
bridge fdb add dev swp0 00:01:02:03:04:05 static
315+
316+
Due to a bug, the bridge bypass FDB implementation provided by DSA did not
317+
distinguish between ``static`` and ``local`` FDB entries (``static`` are meant
318+
to be forwarded, while ``local`` are meant to be locally terminated, i.e. sent
319+
to the host port). Instead, all FDB entries with the ``self`` flag (implicit or
320+
explicit) are treated by DSA as ``static`` even if they are ``local``.
321+
322+
.. code-block:: sh
323+
324+
# This command:
325+
bridge fdb add dev swp0 00:01:02:03:04:05 static
326+
# behaves the same for DSA as this command:
327+
bridge fdb add dev swp0 00:01:02:03:04:05 local
328+
# or shorthand, because the 'local' flag is implicit if 'static' is not
329+
# specified, it also behaves the same as:
330+
bridge fdb add dev swp0 00:01:02:03:04:05
331+
332+
The last command is an incorrect way of adding a static bridge FDB entry to a
333+
DSA switch using the bridge bypass operations, and works by mistake. Other
334+
drivers will treat an FDB entry added by the same command as ``local`` and as
335+
such, will not forward it, as opposed to DSA.
336+
337+
Between kernel v4.14 and v5.14, DSA has supported in parallel two modes of
338+
adding a bridge FDB entry to the switch: the bridge bypass discussed above, as
339+
well as a new mode using the ``master`` flag which installs FDB entries in the
340+
software bridge too.
341+
342+
.. code-block:: sh
343+
344+
bridge fdb add dev swp0 00:01:02:03:04:05 master static
345+
346+
Since kernel v5.14, DSA has gained stronger integration with the bridge's
347+
software FDB, and the support for its bridge bypass FDB implementation (using
348+
the ``self`` flag) has been removed. This results in the following changes:
349+
350+
.. code-block:: sh
351+
352+
# This is the only valid way of adding an FDB entry that is supported,
353+
# compatible with v4.14 kernels and later:
354+
bridge fdb add dev swp0 00:01:02:03:04:05 master static
355+
# This command is no longer buggy and the entry is properly treated as
356+
# 'local' instead of being forwarded:
357+
bridge fdb add dev swp0 00:01:02:03:04:05
358+
# This command no longer installs a static FDB entry to hardware:
359+
bridge fdb add dev swp0 00:01:02:03:04:05 static
360+
361+
Script writers are therefore encouraged to use the ``master static`` set of
362+
flags when working with bridge FDB entries on DSA switch interfaces.

net/dsa/slave.c

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1651,27 +1651,6 @@ static const struct ethtool_ops dsa_slave_ethtool_ops = {
16511651
.self_test = dsa_slave_net_selftest,
16521652
};
16531653

1654-
/* legacy way, bypassing the bridge *****************************************/
1655-
static int dsa_legacy_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
1656-
struct net_device *dev,
1657-
const unsigned char *addr, u16 vid,
1658-
u16 flags,
1659-
struct netlink_ext_ack *extack)
1660-
{
1661-
struct dsa_port *dp = dsa_slave_to_port(dev);
1662-
1663-
return dsa_port_fdb_add(dp, addr, vid);
1664-
}
1665-
1666-
static int dsa_legacy_fdb_del(struct ndmsg *ndm, struct nlattr *tb[],
1667-
struct net_device *dev,
1668-
const unsigned char *addr, u16 vid)
1669-
{
1670-
struct dsa_port *dp = dsa_slave_to_port(dev);
1671-
1672-
return dsa_port_fdb_del(dp, addr, vid);
1673-
}
1674-
16751654
static struct devlink_port *dsa_slave_get_devlink_port(struct net_device *dev)
16761655
{
16771656
struct dsa_port *dp = dsa_slave_to_port(dev);
@@ -1713,8 +1692,6 @@ static const struct net_device_ops dsa_slave_netdev_ops = {
17131692
.ndo_change_rx_flags = dsa_slave_change_rx_flags,
17141693
.ndo_set_rx_mode = dsa_slave_set_rx_mode,
17151694
.ndo_set_mac_address = dsa_slave_set_mac_address,
1716-
.ndo_fdb_add = dsa_legacy_fdb_add,
1717-
.ndo_fdb_del = dsa_legacy_fdb_del,
17181695
.ndo_fdb_dump = dsa_slave_fdb_dump,
17191696
.ndo_do_ioctl = dsa_slave_ioctl,
17201697
.ndo_get_iflink = dsa_slave_get_iflink,

0 commit comments

Comments
 (0)