Announce lrp ip if advertisement method is subnet

In the case of the subnet advertisement method, we do not
announce the route to the tenant subnet via BGP. While the routes
in br-ex are good, they do not fully expose the subnet.

This change exposes the router interface that connects the
tenant subnet.

Closes-Bug: 2068730
Change-Id: Id7dd902e5e2010ba41052cc9316db8518349c755
(cherry picked from commit bc1dc8ec9ea2438fe89ad0d9535dfddd05c463d9)
This commit is contained in:
jayjahns 2024-06-07 07:39:01 -05:00 committed by Luis Tomas Bolivar
parent 1920102b15
commit b71ce99ff6
2 changed files with 84 additions and 0 deletions
ovn_bgp_agent
drivers/openstack/utils
tests/unit/drivers/openstack/utils

@ -790,6 +790,18 @@ def _wire_lrp_port_underlay(routing_tables_routes, ip, bridge_device,
vlan=bridge_vlan,
mask=ip.split("/")[1],
via=cr_lrp_ip)
if (CONF.advertisement_method_tenant_networks ==
constants.ADVERTISEMENT_METHOD_SUBNET):
# NOTE(jayjahns): The route for the tenant subnet needs to be
# added to the bgp_nic in order to announce the network.
linux_net.add_ip_route(
routing_tables_routes,
ip.split("/")[0],
CONF.bgp_vrf_table_id,
CONF.bgp_nic,
mask=ip.split("/")[1],
via=cr_lrp_ip)
break
LOG.debug("Added IP Routes for network %s", ip)
return True
@ -854,6 +866,18 @@ def _unwire_lrp_port_underlay(routing_tables_routes, ip, bridge_device,
vlan=bridge_vlan,
mask=ip.split("/")[1],
via=cr_lrp_ip)
if (CONF.advertisement_method_tenant_networks ==
constants.ADVERTISEMENT_METHOD_SUBNET):
# NOTE(jayjahns): We need to delete the route to the
# tenant subnet from the bgp_nic interface.
linux_net.del_ip_route(
routing_tables_routes,
ip.split("/")[0],
CONF.bgp_vrf_table_id,
CONF.bgp_nic,
mask=ip.split("/")[1],
via=cr_lrp_ip)
LOG.debug("Deleted IP Routes for network %s", ip)
return True

@ -749,6 +749,36 @@ class TestWire(test_base.TestCase):
m_ip_rule.assert_called_once_with(ip, 5)
m_ip_version.assert_not_called()
@mock.patch.object(linux_net, 'add_ip_route')
@mock.patch.object(linux_net, 'get_ip_version')
@mock.patch.object(linux_net, 'add_ip_rule')
def test__wire_lrp_port_underlay_advertisement_subnet(
self, m_ip_rule, m_ip_version, m_ip_route):
CONF.set_override(
'advertisement_method_tenant_networks',
constants.ADVERTISEMENT_METHOD_SUBNET)
routing_tables_routes = {}
ip = '10.0.0.1/24'
bridge_device = 'fake-bridge'
bridge_vlan = None
routing_tables = {'fake-bridge': 5}
cr_lrp_ips = ['fake-crlrp-ip']
ret = wire._wire_lrp_port_underlay(
routing_tables_routes, ip, bridge_device,
bridge_vlan, routing_tables, cr_lrp_ips)
self.assertTrue(ret)
m_ip_rule.assert_called_once_with(ip, 5)
expected_ip_route_calls = [
mock.call(
routing_tables_routes, ip.split('/')[0],
routing_tables[bridge_device], bridge_device,
vlan=bridge_vlan, mask=ip.split('/')[1], via=cr_lrp_ips[0]),
mock.call(
routing_tables_routes, ip.split('/')[0],
CONF.bgp_vrf_table_id, CONF.bgp_nic,
mask=ip.split('/')[1], via=cr_lrp_ips[0])]
m_ip_route.assert_has_calls(expected_ip_route_calls)
@mock.patch.object(linux_net, 'del_ip_route')
@mock.patch.object(linux_net, 'get_ip_version')
@mock.patch.object(linux_net, 'del_ip_rule')
@ -805,3 +835,33 @@ class TestWire(test_base.TestCase):
self.assertFalse(ret)
m_ip_rule.assert_called_once_with(ip, 5)
m_ip_version.assert_not_called()
@mock.patch.object(linux_net, 'del_ip_route')
@mock.patch.object(linux_net, 'get_ip_version')
@mock.patch.object(linux_net, 'del_ip_rule')
def test__unwire_lrp_port_underlay_advertisement_subnet(
self, m_ip_rule, m_ip_version, m_ip_route):
CONF.set_override(
'advertisement_method_tenant_networks',
constants.ADVERTISEMENT_METHOD_SUBNET)
routing_tables_routes = {}
ip = '10.0.0.1/24'
bridge_device = 'fake-bridge'
bridge_vlan = None
routing_tables = {'fake-bridge': 5}
cr_lrp_ips = ['fake-crlrp-ip']
ret = wire._unwire_lrp_port_underlay(
routing_tables_routes, ip, bridge_device, bridge_vlan,
routing_tables, cr_lrp_ips)
self.assertTrue(ret)
m_ip_rule.assert_called_once_with(ip, 5)
expected_ip_route_calls = [
mock.call(
routing_tables_routes, ip.split('/')[0],
routing_tables[bridge_device], bridge_device,
vlan=bridge_vlan, mask=ip.split('/')[1], via=cr_lrp_ips[0]),
mock.call(
routing_tables_routes, ip.split('/')[0],
CONF.bgp_vrf_table_id, CONF.bgp_nic,
mask=ip.split('/')[1], via=cr_lrp_ips[0])]
m_ip_route.assert_has_calls(expected_ip_route_calls)