diff --git a/ovn_bgp_agent/drivers/openstack/ovn_bgp_driver.py b/ovn_bgp_agent/drivers/openstack/ovn_bgp_driver.py index c329d4e8..3055212c 100644 --- a/ovn_bgp_agent/drivers/openstack/ovn_bgp_driver.py +++ b/ovn_bgp_agent/drivers/openstack/ovn_bgp_driver.py @@ -169,9 +169,12 @@ class OVNBGPDriver(driver_api.AgentDriverBase): linux_net.ensure_vlan_device_for_network(bridge, vlan_tag) + linux_net.ensure_arp_ndp_enabled_for_bridge(bridge, + bridge_index, + vlan_tag) + linux_net.ensure_arp_ndp_enabled_for_bridge(bridge, - bridge_index, - vlan_tags) + bridge_index) if self.ovs_flows.get(bridge): continue diff --git a/ovn_bgp_agent/drivers/openstack/utils/evpn.py b/ovn_bgp_agent/drivers/openstack/utils/evpn.py index 7ba06b9a..8efbf521 100644 --- a/ovn_bgp_agent/drivers/openstack/utils/evpn.py +++ b/ovn_bgp_agent/drivers/openstack/utils/evpn.py @@ -232,7 +232,7 @@ class VlanDev: # Add 169.254.x.x address to veth_vrf for ipv4 and ipv6 linux_net.ensure_arp_ndp_enabled_for_bridge( - self.veth_vrf, offset=int(self.vlan_tag), vlan_tag=self.vlan_tag + self.veth_vrf, offset=int(self.vlan_tag) ) # Configure mac on the veth interface to be the same on all hosts diff --git a/ovn_bgp_agent/drivers/openstack/utils/wire.py b/ovn_bgp_agent/drivers/openstack/utils/wire.py index 8c0724cc..76711a89 100644 --- a/ovn_bgp_agent/drivers/openstack/utils/wire.py +++ b/ovn_bgp_agent/drivers/openstack/utils/wire.py @@ -65,9 +65,13 @@ def _ensure_base_wiring_config_underlay(idl, ovs_idl, routing_tables): linux_net.ensure_vlan_device_for_network(bridge, vlan_tag) + linux_net.ensure_arp_ndp_enabled_for_bridge(bridge, + bridge_index, + vlan_tag) + linux_net.ensure_arp_ndp_enabled_for_bridge(bridge, - bridge_index, - vlan_tags) + bridge_index) + if not flows_info.get(bridge): mac = linux_net.get_interface_address(bridge) flows_info[bridge] = {'mac': mac, 'in_port': set()} diff --git a/ovn_bgp_agent/tests/unit/drivers/openstack/test_nb_ovn_bgp_driver.py b/ovn_bgp_agent/tests/unit/drivers/openstack/test_nb_ovn_bgp_driver.py index 88fec848..29b98d77 100644 --- a/ovn_bgp_agent/tests/unit/drivers/openstack/test_nb_ovn_bgp_driver.py +++ b/ovn_bgp_agent/tests/unit/drivers/openstack/test_nb_ovn_bgp_driver.py @@ -208,8 +208,10 @@ class TestNBOVNBGPDriver(test_base.TestCase): mock_ensure_br.assert_has_calls(expected_calls) expected_calls = [mock.call('bridge0', 10), mock.call('bridge1', 11)] mock_ensure_vlan_network.assert_has_calls(expected_calls) - expected_calls = [mock.call('bridge0', 1, [10]), - mock.call('bridge1', 2, [11])] + expected_calls = [mock.call('bridge0', 1, 10), + mock.call('bridge0', 1), + mock.call('bridge1', 2, 11), + mock.call('bridge1', 2)] mock_ensure_arp.assert_has_calls(expected_calls) expected_calls = [ mock.call('bridge0'), mock.call('bridge1')] diff --git a/ovn_bgp_agent/tests/unit/drivers/openstack/test_ovn_bgp_driver.py b/ovn_bgp_agent/tests/unit/drivers/openstack/test_ovn_bgp_driver.py index 6d739062..cdaef6e5 100644 --- a/ovn_bgp_agent/tests/unit/drivers/openstack/test_ovn_bgp_driver.py +++ b/ovn_bgp_agent/tests/unit/drivers/openstack/test_ovn_bgp_driver.py @@ -145,8 +145,10 @@ class TestOVNBGPDriver(test_base.TestCase): self.bgp_driver.sync() - expected_calls = [mock.call('bridge0', 1, [10]), - mock.call('bridge1', 2, [11])] + expected_calls = [mock.call('bridge0', 1, 10), + mock.call('bridge0', 1), + mock.call('bridge1', 2, 11), + mock.call('bridge1', 2)] mock_ensure_arp.assert_has_calls(expected_calls) expected_calls = [mock.call('bridge0'), mock.call('bridge1')] diff --git a/ovn_bgp_agent/tests/unit/drivers/openstack/utils/test_evpn.py b/ovn_bgp_agent/tests/unit/drivers/openstack/utils/test_evpn.py index 5df3d993..7d90d7b0 100644 --- a/ovn_bgp_agent/tests/unit/drivers/openstack/utils/test_evpn.py +++ b/ovn_bgp_agent/tests/unit/drivers/openstack/utils/test_evpn.py @@ -302,7 +302,7 @@ class TestEVPN(test_base.TestCase): linux_net.set_master_for_device.assert_called_once_with(self.veth_vrf, self.vrf_name) linux_net.ensure_arp_ndp_enabled_for_bridge.assert_called_once_with( - self.veth_vrf, offset=vlan_tag, vlan_tag=vlan_tag_str) + self.veth_vrf, offset=vlan_tag) linux_net.enable_routing_for_interfaces.assert_called_once_with( self.veth_vrf, 'br-100') diff --git a/ovn_bgp_agent/tests/unit/utils/test_linux_net.py b/ovn_bgp_agent/tests/unit/utils/test_linux_net.py index d9951988..1e31380e 100644 --- a/ovn_bgp_agent/tests/unit/utils/test_linux_net.py +++ b/ovn_bgp_agent/tests/unit/utils/test_linux_net.py @@ -160,8 +160,8 @@ class TestLinuxNet(test_base.TestCase): linux_net.ensure_arp_ndp_enabled_for_bridge('fake-bridge', 511) # NOTE(ltomasbo): hardoced starting ipv4 is 192.168.0.0, and ipv6 is # fd53:d91e:400:7f17::0 - ipv4 = '169.254.1.255' # base + 511 offset - ipv6 = 'fd53:d91e:400:7f17::1ff' # base + 5122 offset (to hex) + ipv4 = '169.254.255.255' # base + 511 offset + ipv6 = 'fd53:d91e:400:7f17::1ff:1ff' # base + 5122 offset (to hex) calls = [mock.call(ipv4, 'fake-bridge'), mock.call(ipv6, 'fake-bridge')] mock_add_ip_to_dev.assert_has_calls(calls) @@ -176,13 +176,13 @@ class TestLinuxNet(test_base.TestCase): linux_net.ensure_arp_ndp_enabled_for_bridge('fake-bridge', 511, 11) # NOTE(ltomasbo): hardoced starting ipv4 is 192.168.0.0, and ipv6 is # fd53:d91e:400:7f17::0 - ipv4 = '169.254.1.255' # base + 511 offset - ipv6 = 'fd53:d91e:400:7f17::1ff' # base + 5122 offset (to hex) - calls = [mock.call(ipv4, 'fake-bridge'), - mock.call(ipv6, 'fake-bridge')] + ipv4 = '169.254.255.11' # base + 511 offset + ipv6 = 'fd53:d91e:400:7f17::1ff:b' # base + 5122 offset (to hex) + calls = [mock.call(ipv4, 'fake-bridg.11'), + mock.call(ipv6, 'fake-bridg.11')] mock_add_ip_to_dev.assert_has_calls(calls) - mock_ndp.assert_called_once_with('fake-bridge') - mock_arp.assert_called_once_with('fake-bridge') + mock_ndp.assert_called_once_with('fake-bridg/11') + mock_arp.assert_called_once_with('fake-bridg/11') @mock.patch.object(linux_net, 'enable_proxy_arp') @mock.patch.object(linux_net, 'enable_proxy_ndp') diff --git a/ovn_bgp_agent/utils/linux_net.py b/ovn_bgp_agent/utils/linux_net.py index 0694b074..204eacb4 100644 --- a/ovn_bgp_agent/utils/linux_net.py +++ b/ovn_bgp_agent/utils/linux_net.py @@ -136,25 +136,37 @@ def delete_device(device): def ensure_arp_ndp_enabled_for_bridge(bridge, offset, vlan_tag=None): + + if vlan_tag: + device_name = '{}.{}'.format( + bridge[:constants.OVN_VLAN_DEVICE_MAX_LENGTH], + vlan_tag + ) + device_index = vlan_tag % constants.IPV4_OCTET_RANGE + + else: + device_name = bridge[:n_const.DEVICE_NAME_MAX_LEN] + device_index = offset + ipv4 = "%s%d.%s" % ( - constants.ARP_IPV4_PREFIX, offset / constants.IPV4_OCTET_RANGE, - offset % constants.IPV4_OCTET_RANGE) - ipv6 = "%s%x" % (constants.NDP_IPV6_PREFIX, offset) + constants.ARP_IPV4_PREFIX, offset % constants.IPV4_OCTET_RANGE, + device_index % constants.IPV4_OCTET_RANGE) + ipv6 = "%s%x:%x" % (constants.NDP_IPV6_PREFIX, offset, device_index) for ip in (ipv4, ipv6): try: - ovn_bgp_agent.privileged.linux_net.add_ip_to_dev(ip, bridge) + ovn_bgp_agent.privileged.linux_net.add_ip_to_dev(ip, device_name) except agent_exc.IpAddressAlreadyExists: - LOG.debug("IP %s already added on bridge %s", ip, bridge) + LOG.debug("IP %s already added on device %s", ip, device_name) except KeyError as e: if "object exists" not in str(e): - LOG.error("Unable to add IP on bridge %s to enable arp/ndp. " - "Exception: %s", bridge, e) + LOG.error("Unable to add IP on device %s to enable arp/ndp. " + "Exception: %s", device_name, e) raise - # also enable the arp/ndp on the bridge in case there are flat networks - enable_proxy_arp(bridge) - enable_proxy_ndp(bridge) + # also enable the arp/ndp on the device + enable_proxy_arp(device_name.replace('.', '/')) + enable_proxy_ndp(device_name.replace('.', '/')) def ensure_anycast_mac_for_interface(intf, offset): diff --git a/releasenotes/notes/enable_arp_ndp_for_vlans-6c306601aba68cb4.yaml b/releasenotes/notes/enable_arp_ndp_for_vlans-6c306601aba68cb4.yaml new file mode 100644 index 00000000..6ce04e3c --- /dev/null +++ b/releasenotes/notes/enable_arp_ndp_for_vlans-6c306601aba68cb4.yaml @@ -0,0 +1,10 @@ +--- +upgrade: + - | + Loopback IP addresses for provider bridge interfaces will be changed + with upgrade. This should have no impact on environments. +fixes: + - | + ARP/NDP are now will be enabled not only for the provider bridge itself, + but also for VLAN interfaces in case VLANs are being used as provider + networks instead of FLAT.