1
0
mirror of https://github.com/CumulusNetworks/ifupdown2.git synced 2024-05-06 15:54:50 +00:00

addons: address: remove stale fdb entry for svi (when hwaddress is used)

As seen in the example below we are seeing a corner case, first the user
/e/n/i is configured without 'hwaddress', then it is used to fix the svi
mac address. The current code only checks for the statemanager for old
'hwaddress' attribute but couldn't find any. Now we save the mac addr
before updating it, so we can later clear it from the fdb.

$ cat a
auto eth0
iface eth0 inet dhcp

auto bridge
iface bridge
        bridge-vlan-aware yes
        bridge-ports vx-1000
        bridge-stp on
        bridge-vids 1000 1002 1004 1006 1008
        bridge-pvid 1

auto vx-1000
iface vx-1000
        vxlan-id 1000
        bridge-access 1000
        vxlan-local-tunnelip 27.0.0.11
        bridge-learning off
        bridge-arp-nd-suppress on
        mstpctl-portbpdufilter yes
        mstpctl-bpduguard yes
        mtu 9152

auto vlan1000
iface vlan1000
        address 45.0.0.2/24
        vlan-id 1000
        vlan-raw-device bridge
        address-virtual 00:00:5e:00:01:01 45.0.0.1/24
        vrf vrf1

auto vrf1
iface vrf1
        vrf-table auto

$
$
$ cat b
auto eth0
iface eth0 inet dhcp

auto bridge
iface bridge
        bridge-vlan-aware yes
        bridge-ports vx-1000
        bridge-stp on
        bridge-vids 1000 1002 1004 1006 1008
        bridge-pvid 1

auto vx-1000
iface vx-1000
        vxlan-id 1000
        bridge-access 1000
        vxlan-local-tunnelip 27.0.0.11
        bridge-learning off
        bridge-arp-nd-suppress on
        mstpctl-portbpdufilter yes
        mstpctl-bpduguard yes
        mtu 9152

auto vlan1000
iface vlan1000
        address 45.0.0.2/24
        hwaddress 00:02:00:aa:aa:aa
        vlan-id 1000
        vlan-raw-device bridge
        address-virtual 00:00:5e:00:01:01 45.0.0.1/24
        vrf vrf1

auto vrf1
iface vrf1
        vrf-table auto

$
$
$ rm /etc/network/interfaces ; ln -s `pwd`/a /etc/network/interfaces ; ifreload -a ; rm /etc/network/interfaces ; ln -s `pwd`/b /etc/network/interfaces ; (ifreload -av |& grep vlan | grep 1000)
info: bridge: netlink: bridge vlan add vid 1000 dev bridge
info: vlan1000: netlink: ip link set dev vlan1000 down
info: vlan1000: netlink: ip link set dev vlan1000 address 00:02:00:aa:aa:aa
info: vlan1000: netlink: ip link set dev vlan1000 up
info: writing '1' to file /proc/sys/net/ipv4/conf/vlan1000/arp_accept
info: executing /sbin/bridge fdb del 4a:b3:1e:45:bf:bf dev bridge vlan 1000  self
info: executing /sbin/bridge fdb replace 00:02:00:aa:aa:aa dev bridge vlan 1000  self
info: executing /sbin/bridge fdb replace 00:00:5e:00:01:01 dev bridge vlan 1000  self
$

Signed-off-by: Julien Fortin <jfortin@nvidia.com>
This commit is contained in:
Julien Fortin
2021-06-29 01:07:48 +02:00
parent 20eab2b13e
commit 1db0cb7acc

View File

@@ -400,7 +400,7 @@ class address(AddonWithIpBlackList, moduleBase):
def _get_hwaddress(self, ifaceobj):
return utils.strip_hwaddress(ifaceobj.get_attr_value_first('hwaddress'))
def _process_bridge(self, ifaceobj, up):
def _process_bridge(self, ifaceobj, up, old_mac_addr=None):
hwaddress = self._get_hwaddress(ifaceobj)
addrs = ifaceobj.get_attr_value_first('address')
arp_accept = ifaceobj.get_attr_value_first('arp-accept')
@@ -425,13 +425,22 @@ class address(AddonWithIpBlackList, moduleBase):
else:
self.write_file('/proc/sys/net/ipv4/conf/%s/arp_accept' % ifaceobj.name, arp_accept)
if hwaddress and is_vlan_dev_on_vlan_aware_bridge:
if old_mac_addr:
# corner case, first the user's /e/n/i is configured without 'hwaddress', then it is used to fix the svi
# mac address. The current code only checks for the statemanager for old 'hwaddress' attribute but
# couldn't find any. Now we save the mac addr before updating it, so we can later clear it from the fdb.
try:
self.iproute2.bridge_fdb_del(bridgename, old_mac_addr, vlan)
except:
pass
if up:
# check statemanager to delete the old entry if necessary
try:
for old_obj in statemanager.statemanager_api.get_ifaceobjs(ifaceobj.name) or []:
old_hwaddress = old_obj.get_attr_value_first("hwaddress")
if old_hwaddress and utils.mac_str_to_int(old_hwaddress) != utils.mac_str_to_int(hwaddress):
self.iproute2.bridge_fdb_del(bridgename, old_hwaddress, vlan)
if old_hwaddress != old_mac_addr:
self.iproute2.bridge_fdb_del(bridgename, old_hwaddress, vlan)
break
except Exception:
pass
@@ -1034,10 +1043,8 @@ class address(AddonWithIpBlackList, moduleBase):
try:
self.process_hwaddress(ifaceobj)
# Handle special things on a bridge
self._process_bridge(ifaceobj, True)
self._process_bridge(ifaceobj, True, self.process_hwaddress(ifaceobj))
except Exception as e:
self.log_error('%s: %s' % (ifaceobj.name, str(e)), ifaceobj)
@@ -1069,6 +1076,8 @@ class address(AddonWithIpBlackList, moduleBase):
else:
running_hwaddress = None
old_mac_addr = None
if utils.mac_str_to_int(hwaddress) != utils.mac_str_to_int(running_hwaddress):
slave_down = False
if ifaceobj.link_kind & ifaceLinkKind.BOND:
@@ -1079,11 +1088,14 @@ class address(AddonWithIpBlackList, moduleBase):
slave_down = True
try:
self.netlink.link_set_address(ifaceobj.name, hwaddress)
old_mac_addr = running_hwaddress
finally:
if slave_down:
for l in ifaceobj.lowerifaces:
self.netlink.link_up(l)
return old_mac_addr
def _down(self, ifaceobj, ifaceobj_getfunc=None):
try:
if not self.cache.link_exists(ifaceobj.name):