• Toshiaki Makita's avatar
    bridge: Fix the way to check if a local fdb entry can be deleted · 2b292fb4
    Toshiaki Makita authored
    We should take into account the followings when deleting a local fdb
    entry.
    
    - nbp_vlan_find() can be used only when vid != 0 to check if an entry is
      deletable, because a fdb entry with vid 0 can exist at any time while
      nbp_vlan_find() always return false with vid 0.
    
      Example of problematic case:
        ip link set eth0 address 12:34:56:78:90:ab
        ip link set eth1 address 12:34:56:78:90:ab
        brctl addif br0 eth0
        brctl addif br0 eth1
        ip link set eth0 address aa:bb:cc:dd:ee:ff
      Then, the fdb entry 12:34:56:78:90:ab will be deleted even though the
      bridge port eth1 still has that address.
    
    - The port to which the bridge device is attached might needs a local entry
      if its mac address is set manually.
    
      Example of problematic case:
        ip link set eth0 address 12:34:56:78:90:ab
        brctl addif br0 eth0
        ip link set br0 address 12:34:56:78:90:ab
        ip link set eth0 address aa:bb:cc:dd:ee:ff
      Then, the fdb still must have the entry 12:34:56:78:90:ab, but it will be
      deleted.
    
    We can use br->dev->addr_assign_type to check if the address is manually
    set or not, but I propose another approach.
    
    Since we delete and insert local entries whenever changing mac address
    of the bridge device, we can change dst of the entry to NULL regardless of
    addr_assign_type when deleting an entry associated with a certain port,
    and if it is found to be unnecessary later, then delete it.
    That is, if changing mac address of a port, the entry might be changed
    to its dst being NULL first, but is eventually deleted when recalculating
    and changing bridge id.
    
    This approach is especially useful when we want to share the code with
    deleting vlan in which the bridge device might want such an entry regardless
    of addr_assign_type, and makes things easy because we don't have to consider
    if mac address of the bridge device will be changed or not at the time we
    delete a local entry of a port, which means fdb code will not be bothered
    even if the bridge id calculating logic is changed in the future.
    
    Also, this change reduces inconsistent state, where frames whose dst is the
    mac address of the bridge, can't reach the bridge because of premature fdb
    entry deletion. This change reduces the possibility that the bridge device
    replies unreachable mac address to arp requests, which could occur during
    the short window between calling del_nbp() and br_stp_recalculate_bridge_id()
    in br_del_if(). This will effective after br_fdb_delete_by_port() starts to
    use the same code by following patch.
    Signed-off-by: default avatarToshiaki Makita <makita.toshiaki@lab.ntt.co.jp>
    Acked-by: default avatarVlad Yasevich <vyasevic@redhat.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    2b292fb4
br_fdb.c 20.3 KB