Avoid collision between vrf and ovs bridges routing tables

There is a chance that the routing table associated to the ovs
bridge device collides with the one assigned for the VRF. If this
is the case there will be more routes than expected in the ovs
routing table and the traffic will be wrongly redirected to the
nic associated to the vrf instead of to the ovs bridge (e.g., br-ex)

Change-Id: Id723800050a6a4e367a3c13600fd2a7cdca17028
This commit is contained in:
Luis Tomas Bolivar 2023-03-03 11:48:38 +01:00
parent c631c7d084
commit 1b4c48c7c7
3 changed files with 12 additions and 8 deletions

View File

@ -177,7 +177,8 @@ class OVNBGPDriver(driver_api.AgentDriverBase):
if not extra_routes.get(bridge):
extra_routes[bridge] = (
linux_net.ensure_routing_table_for_bridge(
self.ovn_routing_tables, bridge))
self.ovn_routing_tables, bridge,
CONF.bgp_vrf_table_id))
vlan_tag = self.sb_idl.get_network_vlan_tag_by_network_name(
network)

View File

@ -133,8 +133,10 @@ class TestOVNBGPDriver(test_base.TestCase):
mock.call('bridge1', 2, 11)]
mock_ensure_arp.assert_has_calls(expected_calls)
expected_calls = [mock.call({'fake-bridge': 'fake-table'}, 'bridge0'),
mock.call({'fake-bridge': 'fake-table'}, 'bridge1')]
expected_calls = [mock.call({'fake-bridge': 'fake-table'}, 'bridge0',
CONF.bgp_vrf_table_id),
mock.call({'fake-bridge': 'fake-table'}, 'bridge1',
CONF.bgp_vrf_table_id)]
mock_routing_bridge.assert_has_calls(expected_calls)
expected_calls = [mock.call('bridge0', 10), mock.call('bridge1', 11)]

View File

@ -116,7 +116,7 @@ def ensure_arp_ndp_enabled_for_bridge(bridge, offset, vlan_tag=None):
enable_proxy_ndp(bridge)
def ensure_routing_table_for_bridge(ovn_routing_tables, bridge):
def ensure_routing_table_for_bridge(ovn_routing_tables, bridge, vrf_table):
# check a routing table with the bridge name exists on
# /etc/iproute2/rt_tables
regex = r'^[0-9]*[\s]*{}$'.format(bridge)
@ -139,8 +139,9 @@ def ensure_routing_table_for_bridge(ovn_routing_tables, bridge):
# pick a number between 1 and 252
try:
table_number = random.choice(list(
set([x for x in range(1, 253)]).difference(
set(existing_routes))))
set([x for x in range(1, 253)
if x != int(vrf_table)]).difference(
set(existing_routes))))
except IndexError:
LOG.error("No more routing tables available for bridge %s "
"at /etc/iproute2/rt_tables", bridge)
@ -471,10 +472,10 @@ def add_ips_to_dev(nic, ips, clear_local_route_at_table=False):
if clear_local_route_at_table:
for ip in ips:
if ip in already_added_ips:
continue
with pyroute2.NDB() as ndb:
oif = ndb.interfaces[nic]['index']
if ip in already_added_ips:
continue
route = {'table': clear_local_route_at_table,
'proto': 2,
'scope': 254,