bisdn / basebox

A tiny OpenFlow controller for OF-DPA switches.
Mozilla Public License 2.0
45 stars 9 forks source link

Termination MAC entries not being removed after changing SVI MAC address #362

Closed rubensfig closed 2 years ago

rubensfig commented 2 years ago

Expected Behavior

Following a routed vlan bridge setup, I considered the following setup.

Where swbridge.10: 10.0.1.1/24 and MAC address AA:BB:CC:DD:EE:FF.

Flowtable 20 will have the following entry

--  inPort:mask = 0:0x0 etherType = 0x0800 destMac:mask = AABB.CCDD.EEFF:ffff.ffff.ffff vlanId:mask = 0x100a:0x1fff (VLAN 10) | GoTo = 30 (Unicast Routing) outPort = 0 (Physical)  | priority = 2 hard_time = 0 idle_time = 0 cookie = 30
--  inPort:mask = 0:0x0 etherType = 0x86dd destMac:mask = AABB.CCDD.EEFF:ffff.ffff.ffff vlanId:mask = 0x100a:0x1fff (VLAN 10) | GoTo = 30 (Unicast Routing) outPort = 0 (Physical)  | priority = 2 hard_time = 0 idle_time = 0 cookie = 31

After changing the MAC address to 02:00:00:00:00:01, we see the following entries in the same table

--  inPort:mask = 0:0x0 etherType = 0x0800 destMac:mask = 0200.0000.0001:ffff.ffff.ffff vlanId:mask = 0x100a:0x1fff (VLAN 10) | GoTo = 30 (Unicast Routing) outPort = 0 (Physical)  | priority = 2 hard_time = 0 idle_time = 0 cookie = 30
--  inPort:mask = 0:0x0 etherType = 0x86dd destMac:mask = 0200.0000.0001:ffff.ffff.ffff vlanId:mask = 0x100a:0x1fff (VLAN 10) | GoTo = 30 (Unicast Routing) outPort = 0 (Physical)  | priority = 2 hard_time = 0 idle_time = 0 cookie = 31

Deleting the IP address should remove the IPv4 entry thus showing

--  inPort:mask = 0:0x0 etherType = 0x86dd destMac:mask = 0200.0000.0001:ffff.ffff.ffff vlanId:mask = 0x100a:0x1fff (VLAN 10) | GoTo = 30 (Unicast Routing) outPort = 0 (Physical)  | priority = 2 hard_time = 0 idle_time = 0 cookie = 31

Deleting the Ipv6 link local address should not show any entry wrt to this VLAN

Actual Behavior

The following entries are seen post MAC address change and deletion, meaning the entries are being mantained.

--  inPort:mask = 0:0x0 etherType = 0x0800 destMac:mask = 0200.0000.0001:ffff.ffff.ffff vlanId:mask = 0x100a:0x1fff (VLAN 10) | GoTo = 30 (Unicast Routing) outPort = 0 (Physical)  | priority = 2 hard_time = 0 idle_time = 0 cookie = 30
--  inPort:mask = 0:0x0 etherType = 0x86dd destMac:mask = 0200.0000.0001:ffff.ffff.ffff vlanId:mask = 0x100a:0x1fff (VLAN 10) | GoTo = 30 (Unicast Routing) outPort = 0 (Physical)  | priority = 2 hard_time = 0 idle_time = 0 cookie = 31

Before and after the deletion on the IP address. This leads me to think that there is a broken interaction between this code path and https://github.com/bisdn/basebox/blob/5805132c1fbcfccdda67e7f45dd1a3ebe46b6945/src/netlink/nl_l3.cc#L1225

Similarly, flushing the IPv6 link local address does not remove the entry on the table.

Steps to Reproduce the Problem

Specifications

rubensfig commented 2 years ago

Further investigation shows the following result.

when changing the MAC address of the interface, the following log is observed. This log is working as expected.

nl_l3.cc:1313] update_l3_termination: updated Termination MAC for port_id=1 old mac address=<caddress_ll a2:0a:c2:f6:80:10 >
                                                              new mac address=<caddress_ll 02:00:00:01:02:01 >
                                                             AF=2
nl_l3.cc:1372] update_l3_egress: no mapping found, no egress entry to be updated

When deleting the IP address from the interface, the following is observed.

nl_l3.cc:1221] del_l3_termination: trying to delete for port_id=1, vid=1, mac=<caddress_ll a2:0a:c2:f6:80:10 >
                                                      , af=2
nl_l3.cc:1245] del_l3_termination: tried to delete a non existing termination mac for port_id=1, vid=1, mac=<caddress_ll a2:0a:c2:f6:80:10 >
                                                       , af=2

The line del_l3_termination: trying to delete for port_id=1, vid=1, mac=<caddress_ll a2:0a:c2:f6:80:10 > points to the fact that the deletion of the termination MAC entry is being triggered with the previous IP address, and not with the current one. The function del_l3_termination is triggered after the following code block. https://github.com/bisdn/basebox/blob/master/src/netlink/nl_l3.cc#L480

  struct rtnl_link *link = rtnl_addr_get_link(a);
...
  int port_id = nl->get_port_id(link);

  addr = rtnl_link_get_addr(link);
  rofl::caddress_ll mac = libnl_lladdr_2_rofl(addr);

First impressions point to a failed update of the address cache, in that the link object is not updated with the correct MAC address from the interface.

KanjiMonster commented 2 years ago

Yeah, looks like something would need to trigger an update for the address for it to update the link.

So maybe something like this might work?

  struct rtnl_link *link = nl->get_link(rtnl_addr_get_ifindex(a), AF_UNSPEC);