1. 03 10月, 2015 4 次提交
  2. 30 9月, 2015 2 次提交
    • V
      net: switchdev: abstract object in add/del ops · ab069002
      Vivien Didelot 提交于
      Similar to the notifier_call callback of a notifier_block, change the
      function signature of switchdev add and del operations to:
      
          int switchdev_port_obj_add/del(struct net_device *dev,
                                         enum switchdev_obj_id id, void *obj);
      
      This allows the caller to pass a specific switchdev_obj_* structure
      instead of the generic switchdev_obj one.
      
      Drivers implementation of these operations and switchdev have been
      changed accordingly.
      Signed-off-by: NVivien Didelot <vivien.didelot@savoirfairelinux.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      ab069002
    • N
      bridge: vlan: add per-vlan struct and move to rhashtables · 2594e906
      Nikolay Aleksandrov 提交于
      This patch changes the bridge vlan implementation to use rhashtables
      instead of bitmaps. The main motivation behind this change is that we
      need extensible per-vlan structures (both per-port and global) so more
      advanced features can be introduced and the vlan support can be
      extended. I've tried to break this up but the moment net_port_vlans is
      changed and the whole API goes away, thus this is a larger patch.
      A few short goals of this patch are:
      - Extensible per-vlan structs stored in rhashtables and a sorted list
      - Keep user-visible behaviour (compressed vlans etc)
      - Keep fastpath ingress/egress logic the same (optimizations to come
        later)
      
      Here's a brief list of some of the new features we'd like to introduce:
      - per-vlan counters
      - vlan ingress/egress mapping
      - per-vlan igmp configuration
      - vlan priorities
      - avoid fdb entries replication (e.g. local fdb scaling issues)
      
      The structure is kept single for both global and per-port entries so to
      avoid code duplication where possible and also because we'll soon introduce
      "port0 / aka bridge as port" which should simplify things further
      (thanks to Vlad for the suggestion!).
      
      Now we have per-vlan global rhashtable (bridge-wide) and per-vlan port
      rhashtable, if an entry is added to a port it'll get a pointer to its
      global context so it can be quickly accessed later. There's also a
      sorted vlan list which is used for stable walks and some user-visible
      behaviour such as the vlan ranges, also for error paths.
      VLANs are stored in a "vlan group" which currently contains the
      rhashtable, sorted vlan list and the number of "real" vlan entries.
      A good side-effect of this change is that it resembles how hw keeps
      per-vlan data.
      One important note after this change is that if a VLAN is being looked up
      in the bridge's rhashtable for filtering purposes (or to check if it's an
      existing usable entry, not just a global context) then the new helper
      br_vlan_should_use() needs to be used if the vlan is found. In case the
      lookup is done only with a port's vlan group, then this check can be
      skipped.
      
      Things tested so far:
      - basic vlan ingress/egress
      - pvids
      - untagged vlans
      - undef CONFIG_BRIDGE_VLAN_FILTERING
      - adding/deleting vlans in different scenarios (with/without global ctx,
        while transmitting traffic, in ranges etc)
      - loading/removing the module while having/adding/deleting vlans
      - extracting bridge vlan information (user ABI), compressed requests
      - adding/deleting fdbs on vlans
      - bridge mac change, promisc mode
      - default pvid change
      - kmemleak ON during the whole time
      Signed-off-by: NNikolay Aleksandrov <nikolay@cumulusnetworks.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      2594e906
  3. 24 9月, 2015 1 次提交
  4. 12 8月, 2015 1 次提交
  5. 10 8月, 2015 1 次提交
  6. 24 6月, 2015 1 次提交
  7. 16 6月, 2015 1 次提交
    • S
      bridge: del external_learned fdbs from device on flush or ageout · b4ad7baa
      Scott Feldman 提交于
      We need to delete from offload the device externally learnded fdbs when any
      one of these events happen:
      
      1) Bridge ages out fdb.  (When bridge is doing ageing vs. device doing
      ageing.  If device is doing ageing, it would send SWITCHDEV_FDB_DEL
      directly).
      
      2) STP state change flushes fdbs on port.
      
      3) User uses sysfs interface to flush fdbs from bridge or bridge port:
      
      	echo 1 >/sys/class/net/BR_DEV/bridge/flush
      	echo 1 >/sys/class/net/BR_PORT/brport/flush
      
      4) Offload driver send event SWITCHDEV_FDB_DEL to delete fdb entry.
      
      For rocker, we can now get called to delete fdb entry in wait and nowait
      contexts, so set NOWAIT flag when deleting fdb entry.
      Signed-off-by: NScott Feldman <sfeldma@gmail.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      b4ad7baa
  8. 11 6月, 2015 1 次提交
  9. 08 6月, 2015 3 次提交
  10. 26 5月, 2015 1 次提交
  11. 10 2月, 2015 1 次提交
    • T
      bridge: Fix inability to add non-vlan fdb entry · 25d3b493
      Toshiaki Makita 提交于
      Bridge's default_pvid adds a vid by default, by which we cannot add a
      non-vlan fdb entry by default, because br_fdb_add() adds fdb entries for
      all vlans instead of a non-vlan one when any vlan is configured.
      
       # ip link add br0 type bridge
       # ip link set eth0 master br0
       # bridge fdb add 12:34:56:78:90:ab dev eth0 master temp
       # bridge fdb show brport eth0 | grep 12:34:56:78:90:ab
       12:34:56:78:90:ab dev eth0 vlan 1 static
      
      We expect a non-vlan fdb entry as well as vlan 1:
       12:34:56:78:90:ab dev eth0 static
      
      To fix this, we need to insert a non-vlan fdb entry if vlan is not
      specified, even when any vlan is configured.
      
      Fixes: 5be5a2df ("bridge: Add filtering support for default_pvid")
      Signed-off-by: NToshiaki Makita <makita.toshiaki@lab.ntt.co.jp>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      25d3b493
  12. 05 2月, 2015 2 次提交
  13. 18 1月, 2015 2 次提交
    • J
      netlink: make nlmsg_end() and genlmsg_end() void · 053c095a
      Johannes Berg 提交于
      Contrary to common expectations for an "int" return, these functions
      return only a positive value -- if used correctly they cannot even
      return 0 because the message header will necessarily be in the skb.
      
      This makes the very common pattern of
      
        if (genlmsg_end(...) < 0) { ... }
      
      be a whole bunch of dead code. Many places also simply do
      
        return nlmsg_end(...);
      
      and the caller is expected to deal with it.
      
      This also commonly (at least for me) causes errors, because it is very
      common to write
      
        if (my_function(...))
          /* error condition */
      
      and if my_function() does "return nlmsg_end()" this is of course wrong.
      
      Additionally, there's not a single place in the kernel that actually
      needs the message length returned, and if anyone needs it later then
      it'll be very easy to just use skb->len there.
      
      Remove this, and make the functions void. This removes a bunch of dead
      code as described above. The patch adds lines because I did
      
      -	return nlmsg_end(...);
      +	nlmsg_end(...);
      +	return 0;
      
      I could have preserved all the function's return values by returning
      skb->len, but instead I've audited all the places calling the affected
      functions and found that none cared. A few places actually compared
      the return value with <= 0 in dump functionality, but that could just
      be changed to < 0 with no change in behaviour, so I opted for the more
      efficient version.
      
      One instance of the error I've made numerous times now is also present
      in net/phonet/pn_netlink.c in the route_dumpit() function - it didn't
      check for <0 or <=0 and thus broke out of the loop every single time.
      I've preserved this since it will (I think) have caused the messages to
      userspace to be formatted differently with just a single message for
      every SKB returned to userspace. It's possible that this isn't needed
      for the tools that actually use this, but I don't even know what they
      are so couldn't test that changing this behaviour would be acceptable.
      Signed-off-by: NJohannes Berg <johannes.berg@intel.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      053c095a
    • J
      net: replace br_fdb_external_learn_* calls with switchdev notifier events · 3aeb6617
      Jiri Pirko 提交于
      This patch benefits from newly introduced switchdev notifier and uses it
      to propagate fdb learn events from rocker driver to bridge. That avoids
      direct function calls and possible use by other listeners (ovs).
      Suggested-by: NThomas Graf <tgraf@suug.ch>
      Signed-off-by: NJiri Pirko <jiri@resnulli.us>
      Signed-off-by: NScott Feldman <sfeldma@gmail.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      3aeb6617
  14. 06 1月, 2015 1 次提交
    • H
      net: Do not call ndo_dflt_fdb_dump if ndo_fdb_dump is defined · 6cb69742
      Hubert Sokolowski 提交于
      Add checking whether the call to ndo_dflt_fdb_dump is needed.
      It is not expected to call ndo_dflt_fdb_dump unconditionally
      by some drivers (i.e. qlcnic or macvlan) that defines
      own ndo_fdb_dump. Other drivers define own ndo_fdb_dump
      and don't want ndo_dflt_fdb_dump to be called at all.
      At the same time it is desirable to call the default dump
      function on a bridge device.
      Fix attributes that are passed to dev->netdev_ops->ndo_fdb_dump.
      Add extra checking in br_fdb_dump to avoid duplicate entries
      as now filter_dev can be NULL.
      
      Following tests for filtering have been performed before
      the change and after the patch was applied to make sure
      they are the same and it doesn't break the filtering algorithm.
      
      [root@localhost ~]# cd /root/iproute2-3.18.0/bridge
      [root@localhost bridge]# modprobe dummy
      [root@localhost bridge]# ./bridge fdb add f1:f2:f3:f4:f5:f6 dev dummy0
      [root@localhost bridge]# brctl addbr br0
      [root@localhost bridge]# brctl addif  br0 dummy0
      [root@localhost bridge]# ip link set dev br0 address 02:00:00:12:01:04
      [root@localhost bridge]# # show all
      [root@localhost bridge]# ./bridge fdb show
      33:33:00:00:00:01 dev p2p1 self permanent
      01:00:5e:00:00:01 dev p2p1 self permanent
      33:33:ff:ac:ce:32 dev p2p1 self permanent
      33:33:00:00:02:02 dev p2p1 self permanent
      01:00:5e:00:00:fb dev p2p1 self permanent
      33:33:00:00:00:01 dev p7p1 self permanent
      01:00:5e:00:00:01 dev p7p1 self permanent
      33:33:ff:79:50:53 dev p7p1 self permanent
      33:33:00:00:02:02 dev p7p1 self permanent
      01:00:5e:00:00:fb dev p7p1 self permanent
      f2:46:50:85:6d:d9 dev dummy0 master br0 permanent
      f2:46:50:85:6d:d9 dev dummy0 vlan 1 master br0 permanent
      33:33:00:00:00:01 dev dummy0 self permanent
      f1:f2:f3:f4:f5:f6 dev dummy0 self permanent
      33:33:00:00:00:01 dev br0 self permanent
      02:00:00:12:01:04 dev br0 vlan 1 master br0 permanent
      02:00:00:12:01:04 dev br0 master br0 permanent
      [root@localhost bridge]# # filter by bridge
      [root@localhost bridge]# ./bridge fdb show br br0
      f2:46:50:85:6d:d9 dev dummy0 master br0 permanent
      f2:46:50:85:6d:d9 dev dummy0 vlan 1 master br0 permanent
      33:33:00:00:00:01 dev dummy0 self permanent
      f1:f2:f3:f4:f5:f6 dev dummy0 self permanent
      33:33:00:00:00:01 dev br0 self permanent
      02:00:00:12:01:04 dev br0 vlan 1 master br0 permanent
      02:00:00:12:01:04 dev br0 master br0 permanent
      [root@localhost bridge]# # filter by port
      [root@localhost bridge]# ./bridge fdb show brport dummy0
      f2:46:50:85:6d:d9 master br0 permanent
      f2:46:50:85:6d:d9 vlan 1 master br0 permanent
      33:33:00:00:00:01 self permanent
      f1:f2:f3:f4:f5:f6 self permanent
      [root@localhost bridge]# # filter by port + bridge
      [root@localhost bridge]# ./bridge fdb show br br0 brport dummy0
      f2:46:50:85:6d:d9 master br0 permanent
      f2:46:50:85:6d:d9 vlan 1 master br0 permanent
      33:33:00:00:00:01 self permanent
      f1:f2:f3:f4:f5:f6 self permanent
      [root@localhost bridge]#
      Signed-off-by: NHubert Sokolowski <hubert.sokolowski@intel.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      6cb69742
  15. 03 12月, 2014 3 次提交
  16. 01 8月, 2014 1 次提交
  17. 11 7月, 2014 2 次提交
    • J
      bridge: netlink dump interface at par with brctl · 5e6d2435
      Jamal Hadi Salim 提交于
      Actually better than brctl showmacs because we can filter by bridge
      port in the kernel.
      The current bridge netlink interface doesnt scale when you have many
      bridges each with large fdbs or even bridges with many bridge ports
      
      And now for the science non-fiction novel you have all been
      waiting for..
      
      //lets see what bridge ports we have
      root@moja-1:/configs/may30-iprt/bridge# ./bridge link show
      8: eth1 state DOWN : <BROADCAST,MULTICAST> mtu 1500 master br0 state
      disabled priority 32 cost 19
      17: sw1-p1 state DOWN : <BROADCAST,NOARP> mtu 1500 master br0 state
      disabled priority 32 cost 100
      
      // show all..
      root@moja-1:/configs/may30-iprt/bridge# ./bridge fdb show
      33:33:00:00:00:01 dev bond0 self permanent
      33:33:00:00:00:01 dev dummy0 self permanent
      33:33:00:00:00:01 dev ifb0 self permanent
      33:33:00:00:00:01 dev ifb1 self permanent
      33:33:00:00:00:01 dev eth0 self permanent
      01:00:5e:00:00:01 dev eth0 self permanent
      33:33:ff:22:01:01 dev eth0 self permanent
      02:00:00:12:01:02 dev eth1 vlan 0 master br0 permanent
      00:17:42:8a:b4:05 dev eth1 vlan 0 master br0 permanent
      00:17:42:8a:b4:07 dev eth1 self permanent
      33:33:00:00:00:01 dev eth1 self permanent
      33:33:00:00:00:01 dev gretap0 self permanent
      da:ac:46:27:d9:53 dev sw1-p1 vlan 0 master br0 permanent
      33:33:00:00:00:01 dev sw1-p1 self permanent
      
      //filter by bridge
      root@moja-1:/configs/may30-iprt/bridge# ./bridge fdb show br br0
      02:00:00:12:01:02 dev eth1 vlan 0 master br0 permanent
      00:17:42:8a:b4:05 dev eth1 vlan 0 master br0 permanent
      00:17:42:8a:b4:07 dev eth1 self permanent
      33:33:00:00:00:01 dev eth1 self permanent
      da:ac:46:27:d9:53 dev sw1-p1 vlan 0 master br0 permanent
      33:33:00:00:00:01 dev sw1-p1 self permanent
      
      // bridge sw1 has no ports attached..
      root@moja-1:/configs/may30-iprt/bridge# ./bridge fdb show br sw1
      
      //filter by port
      root@moja-1:/configs/may30-iprt/bridge# ./bridge fdb show brport eth1
      02:00:00:12:01:02 vlan 0 master br0 permanent
      00:17:42:8a:b4:05 vlan 0 master br0 permanent
      00:17:42:8a:b4:07 self permanent
      33:33:00:00:00:01 self permanent
      
      // filter by port + bridge
      root@moja-1:/configs/may30-iprt/bridge# ./bridge fdb show br br0 brport
      sw1-p1
      da:ac:46:27:d9:53 vlan 0 master br0 permanent
      33:33:00:00:00:01 self permanent
      
      // for shits and giggles (as they say in New Brunswick), lets
      // change the mac that br0 uses
      // Note: a magical fdb entry with no brport is added ...
      root@moja-1:/configs/may30-iprt/bridge# ip link set dev br0 address
      02:00:00:12:01:04
      
      // lets see if we can see the unicorn ..
      root@moja-1:/configs/may30-iprt/bridge# ./bridge fdb show
      33:33:00:00:00:01 dev bond0 self permanent
      33:33:00:00:00:01 dev dummy0 self permanent
      33:33:00:00:00:01 dev ifb0 self permanent
      33:33:00:00:00:01 dev ifb1 self permanent
      33:33:00:00:00:01 dev eth0 self permanent
      01:00:5e:00:00:01 dev eth0 self permanent
      33:33:ff:22:01:01 dev eth0 self permanent
      02:00:00:12:01:02 dev eth1 vlan 0 master br0 permanent
      00:17:42:8a:b4:05 dev eth1 vlan 0 master br0 permanent
      00:17:42:8a:b4:07 dev eth1 self permanent
      33:33:00:00:00:01 dev eth1 self permanent
      33:33:00:00:00:01 dev gretap0 self permanent
      02:00:00:12:01:04 dev br0 vlan 0 master br0 permanent <=== there it is
      da:ac:46:27:d9:53 dev sw1-p1 vlan 0 master br0 permanent
      33:33:00:00:00:01 dev sw1-p1 self permanent
      
      //can we see it if we filter by bridge?
      root@moja-1:/configs/may30-iprt/bridge# ./bridge fdb show br br0
      02:00:00:12:01:02 dev eth1 vlan 0 master br0 permanent
      00:17:42:8a:b4:05 dev eth1 vlan 0 master br0 permanent
      00:17:42:8a:b4:07 dev eth1 self permanent
      33:33:00:00:00:01 dev eth1 self permanent
      02:00:00:12:01:04 dev br0 vlan 0 master br0 permanent <=== there it is
      da:ac:46:27:d9:53 dev sw1-p1 vlan 0 master br0 permanent
      33:33:00:00:00:01 dev sw1-p1 self permanent
      Signed-off-by: NJamal Hadi Salim <jhs@mojatatu.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      5e6d2435
    • J
      bridge: fdb dumping takes a filter device · 5d5eacb3
      Jamal Hadi Salim 提交于
      Dumping a bridge fdb dumps every fdb entry
      held. With this change we are going to filter
      on selected bridge port.
      Signed-off-by: NJamal Hadi Salim <jhs@mojatatu.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      5d5eacb3
  18. 22 6月, 2014 1 次提交
  19. 03 6月, 2014 1 次提交
    • R
      bridge: Add bridge ifindex to bridge fdb notify msgs · 41c389d7
      Roopa Prabhu 提交于
      (This patch was previously posted as RFC at
      http://patchwork.ozlabs.org/patch/352677/)
      
      This patch adds NDA_MASTER attribute to neighbour attributes enum for
      bridge/master ifindex. And adds NDA_MASTER to bridge fdb notify msgs.
      
      Today bridge fdb notifications dont contain bridge information.
      Userspace can derive it from the port information in the fdb
      notification. However this is tricky in some scenarious.
      
      Example, bridge port delete notification comes before bridge fdb
      delete notifications. And we have seen problems in userspace
      when using libnl where, the bridge fdb delete notification handling code
      does not understand which bridge this fdb entry is part of because
      the bridge and port association has already been deleted.
      And these notifications (port membership and fdb) are generated on
      separate rtnl groups.
      
      Fixing the order of notifications could possibly solve the problem
      for some cases (I can submit a separate patch for that).
      
      This patch chooses to add NDA_MASTER to bridge fdb notify msgs
      because it not only solves the problem described above, but also helps
      userspace avoid another lookup into link msgs to derive the master index.
      Signed-off-by: NRoopa Prabhu <roopa@cumulusnetworks.com>
      Acked-by: NJamal Hadi Salim <jhs@mojatatu.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      41c389d7
  20. 02 6月, 2014 1 次提交
  21. 17 5月, 2014 2 次提交
  22. 11 2月, 2014 7 次提交
    • T
      bridge: Prevent possible race condition in br_fdb_change_mac_address · ac4c8868
      Toshiaki Makita 提交于
      br_fdb_change_mac_address() calls fdb_insert()/fdb_delete() without
      br->hash_lock.
      
      These hash list updates are racy with br_fdb_update()/br_fdb_cleanup().
      Signed-off-by: NToshiaki Makita <makita.toshiaki@lab.ntt.co.jp>
      Acked-by: NVlad Yasevich <vyasevic@redhat.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      ac4c8868
    • T
      bridge: Properly check if local fdb entry can be deleted when deleting vlan · 424bb9c9
      Toshiaki Makita 提交于
      Vlan codes unconditionally delete local fdb entries.
      We should consider the possibility that other ports have the same
      address and vlan.
      
      Example of problematic case:
        ip link set eth0 address 12:34:56:78:90:ab
        ip link set eth1 address aa:bb:cc:dd:ee:ff
        brctl addif br0 eth0
        brctl addif br0 eth1 # br0 will have mac address 12:34:56:78:90:ab
        bridge vlan add dev eth0 vid 10
        bridge vlan add dev eth1 vid 10
        bridge vlan add dev br0 vid 10 self
      We will have fdb entry such that f->dst == eth0, f->vlan_id == 10 and
      f->addr == 12:34:56:78:90:ab at this time.
      Next, delete eth0 vlan 10.
        bridge vlan del dev eth0 vid 10
      In this case, we still need the entry for br0, but it will be deleted.
      
      Note that br0 needs the entry even though its mac address is not set
      manually. To delete the entry with proper condition checking,
      fdb_delete_local() is suitable to use.
      Signed-off-by: NToshiaki Makita <makita.toshiaki@lab.ntt.co.jp>
      Acked-by: NVlad Yasevich <vyasevic@redhat.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      424bb9c9
    • T
      bridge: Properly check if local fdb entry can be deleted in br_fdb_delete_by_port · a778e6d1
      Toshiaki Makita 提交于
      br_fdb_delete_by_port() doesn't care about vlan and mac address of the
      bridge device.
      
      As the check is almost the same as mac address changing, slightly modify
      fdb_delete_local() and use it.
      
      Note that we can always set added_by_user to 0 in fdb_delete_local() because
      - br_fdb_delete_by_port() calls fdb_delete_local() for local entries
        regardless of its added_by_user. In this case, we have to check if another
        port has the same address and vlan, and if found, we have to create the
        entry (by changing dst). This is kernel-added entry, not user-added.
      - br_fdb_changeaddr() doesn't call fdb_delete_local() for user-added entry.
      Signed-off-by: NToshiaki Makita <makita.toshiaki@lab.ntt.co.jp>
      Acked-by: NVlad Yasevich <vyasevic@redhat.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      a778e6d1
    • T
      bridge: Properly check if local fdb entry can be deleted in br_fdb_change_mac_address · 960b589f
      Toshiaki Makita 提交于
      br_fdb_change_mac_address() doesn't check if the local entry has the
      same address as any of bridge ports.
      Although I'm not sure when it is beneficial, current implementation allow
      the bridge device to receive any mac address of its ports.
      To preserve this behavior, we have to check if the mac address of the
      entry being deleted is identical to that of any port.
      
      As this check is almost the same as that in br_fdb_changeaddr(), create
      a common function fdb_delete_local() and call it from
      br_fdb_changeadddr() and br_fdb_change_mac_address().
      Signed-off-by: NToshiaki Makita <makita.toshiaki@lab.ntt.co.jp>
      Acked-by: NVlad Yasevich <vyasevic@redhat.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      960b589f
    • T
      bridge: Fix the way to check if a local fdb entry can be deleted · 2b292fb4
      Toshiaki Makita 提交于
      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: NToshiaki Makita <makita.toshiaki@lab.ntt.co.jp>
      Acked-by: NVlad Yasevich <vyasevic@redhat.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      2b292fb4
    • T
      bridge: Fix the way to insert new local fdb entries in br_fdb_changeaddr · 2836882f
      Toshiaki Makita 提交于
      Since commit bc9a25d2 ("bridge: Add vlan support for local fdb entries"),
      br_fdb_changeaddr() has inserted a new local fdb entry only if it can
      find old one. But if we have two ports where they have the same address
      or user has deleted a local entry, there will be no entry for one of the
      ports.
      
      Example of problematic case:
        ip link set eth0 address aa:bb:cc:dd:ee:ff
        ip link set eth1 address aa:bb:cc:dd:ee:ff
        brctl addif br0 eth0
        brctl addif br0 eth1 # eth1 will not have a local entry due to dup.
        ip link set eth1 address 12:34:56:78:90:ab
      Then, the new entry for the address 12:34:56:78:90:ab will not be
      created, and the bridge device will not be able to communicate.
      
      Insert new entries regardless of whether we can find old entries or not.
      Signed-off-by: NToshiaki Makita <makita.toshiaki@lab.ntt.co.jp>
      Acked-by: NVlad Yasevich <vyasevic@redhat.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      2836882f
    • T
      bridge: Fix the way to find old local fdb entries in br_fdb_changeaddr · a5642ab4
      Toshiaki Makita 提交于
      br_fdb_changeaddr() assumes that there is at most one local entry per port
      per vlan. It used to be true, but since commit 36fd2b63 ("bridge: allow
      creating/deleting fdb entries via netlink"), it has not been so.
      Therefore, the function might fail to search a correct previous address
      to be deleted and delete an arbitrary local entry if user has added local
      entries manually.
      
      Example of problematic case:
        ip link set eth0 address ee:ff:12:34:56:78
        brctl addif br0 eth0
        bridge fdb add 12:34:56:78:90:ab dev eth0 master
        ip link set eth0 address aa:bb:cc:dd:ee:ff
      Then, the address 12:34:56:78:90:ab might be deleted instead of
      ee:ff:12:34:56:78, the original mac address of eth0.
      
      Address this issue by introducing a new flag, added_by_user, to struct
      net_bridge_fdb_entry.
      
      Note that br_fdb_delete_by_port() has to set added_by_user to 0 in cases
      like:
        ip link set eth0 address 12:34:56:78:90:ab
        ip link set eth1 address aa:bb:cc:dd:ee:ff
        brctl addif br0 eth0
        bridge fdb add aa:bb:cc:dd:ee:ff dev eth0 master
        brctl addif br0 eth1
        brctl delif br0 eth0
      In this case, kernel should delete the user-added entry aa:bb:cc:dd:ee:ff,
      but it also should have been added by "brctl addif br0 eth1" originally,
      so we don't delete it and treat it a new kernel-created entry.
      Signed-off-by: NToshiaki Makita <makita.toshiaki@lab.ntt.co.jp>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      a5642ab4