• Vladimir Oltean's avatar
    net: switchdev: avoid infinite recursion from LAG to bridge with port object handler · acd8df58
    Vladimir Oltean authored
    The logic from switchdev_handle_port_obj_add_foreign() is directly
    adapted from switchdev_handle_fdb_event_to_device(), which already
    detects events on foreign interfaces and reoffloads them towards the
    switchdev neighbors.
    
    However, when we have a simple br0 <-> bond0 <-> swp0 topology and the
    switchdev_handle_port_obj_add_foreign() gets called on bond0, we get
    stuck into an infinite recursion:
    
    1. bond0 does not pass check_cb(), so we attempt to find switchdev
       neighbor interfaces. For that, we recursively call
       __switchdev_handle_port_obj_add() for bond0's bridge, br0.
    
    2. __switchdev_handle_port_obj_add() recurses through br0's lowers,
       essentially calling __switchdev_handle_port_obj_add() for bond0
    
    3. Go to step 1.
    
    This happens because switchdev_handle_fdb_event_to_device() and
    switchdev_handle_port_obj_add_foreign() are not exactly the same.
    The FDB event helper special-cases LAG interfaces with its lag_mod_cb(),
    so this is why we don't end up in an infinite loop - because it doesn't
    attempt to treat LAG interfaces as potentially foreign bridge ports.
    
    The problem is solved by looking ahead through the bridge's lowers to
    see whether there is any switchdev interface that is foreign to the @dev
    we are currently processing. This stops the recursion described above at
    step 1: __switchdev_handle_port_obj_add(bond0) will not create another
    call to __switchdev_handle_port_obj_add(br0). Going one step upper
    should only happen when we're starting from a bridge port that has been
    determined to be "foreign" to the switchdev driver that passes the
    foreign_dev_check_cb().
    
    Fixes: c4076cdd ("net: switchdev: introduce switchdev_handle_port_obj_{add,del} for foreign interfaces")
    Signed-off-by: default avatarVladimir Oltean <vladimir.oltean@nxp.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    acd8df58
switchdev.c 25.8 KB