| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- From 90dc8fd36078a536671adae884d0b929cce6480a Mon Sep 17 00:00:00 2001
- From: Vladimir Oltean <[email protected]>
- Date: Wed, 6 Jan 2021 11:51:30 +0200
- Subject: [PATCH] net: bridge: notify switchdev of disappearance of old FDB
- entry upon migration
- Currently the bridge emits atomic switchdev notifications for
- dynamically learnt FDB entries. Monitoring these notifications works
- wonders for switchdev drivers that want to keep their hardware FDB in
- sync with the bridge's FDB.
- For example station A wants to talk to station B in the diagram below,
- and we are concerned with the behavior of the bridge on the DUT device:
- DUT
- +-------------------------------------+
- | br0 |
- | +------+ +------+ +------+ +------+ |
- | | | | | | | | | |
- | | swp0 | | swp1 | | swp2 | | eth0 | |
- +-------------------------------------+
- | | |
- Station A | |
- | |
- +--+------+--+ +--+------+--+
- | | | | | | | |
- | | swp0 | | | | swp0 | |
- Another | +------+ | | +------+ | Another
- switch | br0 | | br0 | switch
- | +------+ | | +------+ |
- | | | | | | | |
- | | swp1 | | | | swp1 | |
- +--+------+--+ +--+------+--+
- |
- Station B
- Interfaces swp0, swp1, swp2 are handled by a switchdev driver that has
- the following property: frames injected from its control interface bypass
- the internal address analyzer logic, and therefore, this hardware does
- not learn from the source address of packets transmitted by the network
- stack through it. So, since bridging between eth0 (where Station B is
- attached) and swp0 (where Station A is attached) is done in software,
- the switchdev hardware will never learn the source address of Station B.
- So the traffic towards that destination will be treated as unknown, i.e.
- flooded.
- This is where the bridge notifications come in handy. When br0 on the
- DUT sees frames with Station B's MAC address on eth0, the switchdev
- driver gets these notifications and can install a rule to send frames
- towards Station B's address that are incoming from swp0, swp1, swp2,
- only towards the control interface. This is all switchdev driver private
- business, which the notification makes possible.
- All is fine until someone unplugs Station B's cable and moves it to the
- other switch:
- DUT
- +-------------------------------------+
- | br0 |
- | +------+ +------+ +------+ +------+ |
- | | | | | | | | | |
- | | swp0 | | swp1 | | swp2 | | eth0 | |
- +-------------------------------------+
- | | |
- Station A | |
- | |
- +--+------+--+ +--+------+--+
- | | | | | | | |
- | | swp0 | | | | swp0 | |
- Another | +------+ | | +------+ | Another
- switch | br0 | | br0 | switch
- | +------+ | | +------+ |
- | | | | | | | |
- | | swp1 | | | | swp1 | |
- +--+------+--+ +--+------+--+
- |
- Station B
- Luckily for the use cases we care about, Station B is noisy enough that
- the DUT hears it (on swp1 this time). swp1 receives the frames and
- delivers them to the bridge, who enters the unlikely path in br_fdb_update
- of updating an existing entry. It moves the entry in the software bridge
- to swp1 and emits an addition notification towards that.
- As far as the switchdev driver is concerned, all that it needs to ensure
- is that traffic between Station A and Station B is not forever broken.
- If it does nothing, then the stale rule to send frames for Station B
- towards the control interface remains in place. But Station B is no
- longer reachable via the control interface, but via a port that can
- offload the bridge port learning attribute. It's just that the port is
- prevented from learning this address, since the rule overrides FDB
- updates. So the rule needs to go. The question is via what mechanism.
- It sure would be possible for this switchdev driver to keep track of all
- addresses which are sent to the control interface, and then also listen
- for bridge notifier events on its own ports, searching for the ones that
- have a MAC address which was previously sent to the control interface.
- But this is cumbersome and inefficient. Instead, with one small change,
- the bridge could notify of the address deletion from the old port, in a
- symmetrical manner with how it did for the insertion. Then the switchdev
- driver would not be required to monitor learn/forget events for its own
- ports. It could just delete the rule towards the control interface upon
- bridge entry migration. This would make hardware address learning be
- possible again. Then it would take a few more packets until the hardware
- and software FDB would be in sync again.
- Signed-off-by: Vladimir Oltean <[email protected]>
- Acked-by: Nikolay Aleksandrov <[email protected]>
- Reviewed-by: Ido Schimmel <[email protected]>
- Reviewed-by: Andrew Lunn <[email protected]>
- Reviewed-by: Florian Fainelli <[email protected]>
- Signed-off-by: Jakub Kicinski <[email protected]>
- ---
- net/bridge/br_fdb.c | 1 +
- 1 file changed, 1 insertion(+)
- --- a/net/bridge/br_fdb.c
- +++ b/net/bridge/br_fdb.c
- @@ -581,6 +581,7 @@ void br_fdb_update(struct net_bridge *br
-
- /* fastpath: update of existing entry */
- if (unlikely(source != fdb->dst && !fdb->is_sticky)) {
- + br_switchdev_fdb_notify(fdb, RTM_DELNEIGH);
- fdb->dst = source;
- fdb_modified = true;
- /* Take over HW learned entry */
|