Allow the user to set the VRF settings

Allow the user to configure the VRF settings to e.g. run
multiple agents per host.

The constants OVN_BGP_NIC, OVN_BGP_VRF and OVN_BGP_VRF_TABLE
have been replaced by configurable config options:

- OVN_BGP_NIC renamed to bgp_nic (default: "bgp-nic")
- OVN_BGP_VRF renamed to bgp_vrf (default: "bgp-vrf")
- OVN_BGP_VRF_TABLE renamed to bgp_vrf_table_id (default: 10)

Change-Id: I863e7bb140cd85a4ecefe6ccaad8adc5eae0cbd9
This commit is contained in:
Luca Czesla 2022-10-18 12:12:22 +00:00
parent cf61dfeeab
commit 7f058d8c99
5 changed files with 68 additions and 58 deletions

View File

@ -258,9 +258,9 @@ To do that, when the agent starts, it ensures that:
- There is a VRF created (the one leaked in the previous step), by default
with name ``ovn-bgp-vrf``.
with name ``bgp_vrf``.
- There is a dummy interface type (by default named ``ovn``), associated to
- There is a dummy interface type (by default named ``bgp-nic``), associated to
the previously created VRF device.
- Ensure ARP/NDP is enabled at OVS provider bridges by adding an IP to it
@ -269,15 +269,15 @@ To do that, when the agent starts, it ensures that:
Then, to expose the VMs/LB IPs as they are created (or upon
initialization or re-sync), since the FRR configuration has the
``redistribute connected`` option enabled, the only action needed to expose it
(or withdraw it) is to add it (or remove it) from the ``ovn`` dummy interface.
(or withdraw it) is to add it (or remove it) from the ``bgp-nic`` dummy interface.
Then it relies on Zebra to do the BGP advertisemant, as Zebra detects the
addition/deletion of the IP on the local interface and advertises/withdraw
the route:
.. code-block:: ini
$ ip addr add IPv4/32 dev ovn
$ ip addr add IPv6/128 dev ovn
$ ip addr add IPv4/32 dev bgp-nic
$ ip addr add IPv6/128 dev bgp-nic
.. note::

View File

@ -71,6 +71,19 @@ agent_opts = [
default=4789,
help='The UDP port used for EVPN VXLAN communication. By '
'default 4789 is being used.'),
cfg.StrOpt('bgp_nic',
default='bgp-nic',
help='The name of the interface used within the VRF '
'(bgp_vrf option) to expose the IPs and/or Networks.'),
cfg.StrOpt('bgp_vrf',
default='bgp-vrf',
help='The name of the VRF to be used to expose the IPs '
'and/or Networks through BGP.'),
cfg.IntOpt('bgp_vrf_table_id',
default=10,
help='The Routing Table ID that the VRF (bgp_vrf option) '
'should use. If it does not exist, this table will be '
'created.'),
]
root_helper_opts = [

View File

@ -22,9 +22,6 @@ OVN_LOCALNET_VIF_PORT_TYPE = "localnet"
OVN_CIDRS_EXT_ID_KEY = 'neutron:cidrs'
OVN_BGP_NIC = "ovn"
OVN_BGP_VRF = "ovn-bgp-vrf"
OVN_BGP_VRF_TABLE = 10
OVS_RULE_COOKIE = "999"
OVS_VRF_RULE_COOKIE = "998"

View File

@ -70,7 +70,7 @@ class OVNBGPDriver(driver_api.AgentDriverBase):
# Ensure FRR is configure to leak the routes
# NOTE: If we want to recheck this every X time, we should move it
# inside the sync function instead
frr.vrf_leak(constants.OVN_BGP_VRF, CONF.bgp_AS, CONF.bgp_router_id)
frr.vrf_leak(CONF.bgp_vrf, CONF.bgp_AS, CONF.bgp_router_id)
self.ovs_idl = ovs.OvsIdl()
self.ovs_idl.start(CONF.ovsdb_connection)
@ -127,11 +127,11 @@ class OVNBGPDriver(driver_api.AgentDriverBase):
LOG.debug("Ensuring VRF configuration for advertising routes")
# Create VRF
linux_net.ensure_vrf(constants.OVN_BGP_VRF,
constants.OVN_BGP_VRF_TABLE)
linux_net.ensure_vrf(CONF.bgp_vrf,
CONF.bgp_vrf_table_id)
# Create OVN dummy device
linux_net.ensure_ovn_device(constants.OVN_BGP_NIC,
constants.OVN_BGP_VRF)
linux_net.ensure_ovn_device(CONF.bgp_nic,
CONF.bgp_vrf)
LOG.debug("Configuring br-ex default rule and routing tables for "
"each provider network")
@ -174,7 +174,7 @@ class OVNBGPDriver(driver_api.AgentDriverBase):
ovs.remove_extra_ovs_flows(flows_info, constants.OVS_RULE_COOKIE)
LOG.debug("Syncing current routes.")
exposed_ips = linux_net.get_exposed_ips(constants.OVN_BGP_NIC)
exposed_ips = linux_net.get_exposed_ips(CONF.bgp_nic)
# get the rules pointing to ovn bridges
ovn_ip_rules = linux_net.get_ovn_ip_rules(
self.ovn_routing_tables.values())
@ -236,7 +236,7 @@ class OVNBGPDriver(driver_api.AgentDriverBase):
# remove extra routes/ips
# remove all the leftovers on the list of current ips on dev OVN
linux_net.delete_exposed_ips(exposed_ips, constants.OVN_BGP_NIC)
linux_net.delete_exposed_ips(exposed_ips, CONF.bgp_nic)
# remove all the leftovers on the list of current ip rules for ovn
# bridges
linux_net.delete_ip_rules(ovn_ip_rules)
@ -343,7 +343,7 @@ class OVNBGPDriver(driver_api.AgentDriverBase):
if ext_n_cidr:
ovn_lb_ip = ext_n_cidr.split(" ")[0].split("/")[0]
linux_net.add_ips_to_dev(
constants.OVN_BGP_NIC, [ovn_lb_ip])
CONF.bgp_nic, [ovn_lb_ip])
if ovn_lb_ip in exposed_ips:
exposed_ips.remove(ovn_lb_ip)
elif (not port.mac or
@ -366,7 +366,7 @@ class OVNBGPDriver(driver_api.AgentDriverBase):
port_ip_version = linux_net.get_ip_version(port_ip)
if port_ip_version == router_port_ip_version:
linux_net.add_ips_to_dev(
constants.OVN_BGP_NIC, [port_ip])
CONF.bgp_nic, [port_ip])
if port_ip in exposed_ips:
exposed_ips.remove(port_ip)
if router_port_ip_version == constants.IP_VERSION_6:
@ -415,9 +415,9 @@ class OVNBGPDriver(driver_api.AgentDriverBase):
# Check if there are VMs on the network
# and if so withdraw the routes
vms_on_net = linux_net.get_exposed_ips_on_network(
constants.OVN_BGP_NIC, net)
CONF.bgp_nic, net)
if vms_on_net:
linux_net.delete_exposed_ips(vms_on_net, constants.OVN_BGP_NIC)
linux_net.delete_exposed_ips(vms_on_net, CONF.bgp_nic)
def _get_bridge_for_datapath(self, datapath):
network_name, network_tag = self.sb_idl.get_network_name_and_tag(
@ -437,7 +437,7 @@ class OVNBGPDriver(driver_api.AgentDriverBase):
self.ovn_lb_vips.setdefault(ovn_lb, []).append(ip)
LOG.debug("Adding BGP route for loadbalancer VIP %s", ip)
linux_net.add_ips_to_dev(constants.OVN_BGP_NIC, [ip])
linux_net.add_ips_to_dev(CONF.bgp_nic, [ip])
rule_bridge, vlan_tag = self._get_bridge_for_datapath(provider_dp)
try:
@ -457,7 +457,7 @@ class OVNBGPDriver(driver_api.AgentDriverBase):
def withdraw_ovn_lb_on_provider(self, ovn_lb, provider_dp, cr_lrp):
for ip in self.ovn_lb_vips[ovn_lb].copy():
LOG.debug("Deleting BGP route for loadbalancer VIP %s", ip)
linux_net.del_ips_from_dev(constants.OVN_BGP_NIC, [ip])
linux_net.del_ips_from_dev(CONF.bgp_nic, [ip])
rule_bridge, vlan_tag = self._get_bridge_for_datapath(provider_dp)
@ -496,7 +496,7 @@ class OVNBGPDriver(driver_api.AgentDriverBase):
row.type == constants.OVN_VIRTUAL_VIF_PORT_TYPE) and
self.sb_idl.is_provider_network(row.datapath)):
LOG.debug("Adding BGP route for logical port with ip %s", ips)
linux_net.add_ips_to_dev(constants.OVN_BGP_NIC, ips)
linux_net.add_ips_to_dev(CONF.bgp_nic, ips)
rule_bridge, vlan_tag = self._get_bridge_for_datapath(row.datapath)
for ip in ips:
@ -521,7 +521,7 @@ class OVNBGPDriver(driver_api.AgentDriverBase):
row.logical_port)
if fip_address:
LOG.debug("Adding BGP route for FIP with ip %s", fip_address)
linux_net.add_ips_to_dev(constants.OVN_BGP_NIC,
linux_net.add_ips_to_dev(CONF.bgp_nic,
[fip_address])
rule_bridge, vlan_tag = self._get_bridge_for_datapath(
@ -550,7 +550,7 @@ class OVNBGPDriver(driver_api.AgentDriverBase):
if (associated_port and self.sb_idl.is_port_on_chassis(
associated_port, self.chassis)):
LOG.debug("Adding BGP route for FIP with ip %s", ips)
linux_net.add_ips_to_dev(constants.OVN_BGP_NIC, ips)
linux_net.add_ips_to_dev(CONF.bgp_nic, ips)
rule_bridge, vlan_tag = self._get_bridge_for_datapath(
row.datapath)
@ -589,7 +589,7 @@ class OVNBGPDriver(driver_api.AgentDriverBase):
'ovn_lbs': []
}
ips_without_mask = [ip.split("/")[0] for ip in ips]
linux_net.add_ips_to_dev(constants.OVN_BGP_NIC, ips_without_mask)
linux_net.add_ips_to_dev(CONF.bgp_nic, ips_without_mask)
rule_bridge, vlan_tag = self._get_bridge_for_datapath(
cr_lrp_datapath)
@ -669,7 +669,7 @@ class OVNBGPDriver(driver_api.AgentDriverBase):
row.type == constants.OVN_VIRTUAL_VIF_PORT_TYPE) and
self.sb_idl.is_provider_network(row.datapath)):
LOG.debug("Deleting BGP route for logical port with ip %s", ips)
linux_net.del_ips_from_dev(constants.OVN_BGP_NIC, ips)
linux_net.del_ips_from_dev(CONF.bgp_nic, ips)
rule_bridge, vlan_tag = self._get_bridge_for_datapath(row.datapath)
for ip in ips:
@ -692,7 +692,7 @@ class OVNBGPDriver(driver_api.AgentDriverBase):
return
LOG.debug("Delete BGP route for FIP with ip %s", fip_address)
linux_net.del_ips_from_dev(constants.OVN_BGP_NIC,
linux_net.del_ips_from_dev(CONF.bgp_nic,
[fip_address])
rule_bridge, vlan_tag = self._get_bridge_for_datapath(
@ -713,7 +713,7 @@ class OVNBGPDriver(driver_api.AgentDriverBase):
associated_port, self.chassis) or
self.sb_idl.is_port_deleted(associated_port))):
LOG.debug("Deleting BGP route for FIP with ip %s", ips)
linux_net.del_ips_from_dev(constants.OVN_BGP_NIC, ips)
linux_net.del_ips_from_dev(CONF.bgp_nic, ips)
rule_bridge, vlan_tag = self._get_bridge_for_datapath(
row.datapath)
@ -739,7 +739,7 @@ class OVNBGPDriver(driver_api.AgentDriverBase):
# Removing information about the associated network for
# tenant network advertisement
ips_without_mask = [ip.split("/")[0] for ip in ips]
linux_net.del_ips_from_dev(constants.OVN_BGP_NIC,
linux_net.del_ips_from_dev(CONF.bgp_nic,
ips_without_mask)
rule_bridge, vlan_tag = self._get_bridge_for_datapath(
@ -800,7 +800,7 @@ class OVNBGPDriver(driver_api.AgentDriverBase):
if port_lrp in self.ovn_local_lrps:
LOG.debug("Adding BGP route for tenant IP %s on chassis %s",
ips, self.chassis)
linux_net.add_ips_to_dev(constants.OVN_BGP_NIC, ips)
linux_net.add_ips_to_dev(CONF.bgp_nic, ips)
LOG.debug("Added BGP route for tenant IP %s on chassis %s",
ips, self.chassis)
@ -813,7 +813,7 @@ class OVNBGPDriver(driver_api.AgentDriverBase):
if port_lrp in self.ovn_local_lrps:
LOG.debug("Deleting BGP route for tenant IP %s on chassis %s",
ips, self.chassis)
linux_net.del_ips_from_dev(constants.OVN_BGP_NIC, ips)
linux_net.del_ips_from_dev(CONF.bgp_nic, ips)
LOG.debug("Deleted BGP route for tenant IP %s on chassis %s",
ips, self.chassis)
@ -893,7 +893,7 @@ class OVNBGPDriver(driver_api.AgentDriverBase):
# IP version
port_ip_version = linux_net.get_ip_version(port_ip)
if port_ip_version == ip_version:
linux_net.add_ips_to_dev(constants.OVN_BGP_NIC, [port_ip])
linux_net.add_ips_to_dev(CONF.bgp_nic, [port_ip])
@lockutils.synchronized('bgp')
def withdraw_subnet(self, ip, row):
@ -952,5 +952,5 @@ class OVNBGPDriver(driver_api.AgentDriverBase):
# Check if there are VMs on the network
# and if so withdraw the routes
vms_on_net = linux_net.get_exposed_ips_on_network(
constants.OVN_BGP_NIC, net)
linux_net.delete_exposed_ips(vms_on_net, constants.OVN_BGP_NIC)
CONF.bgp_nic, net)
linux_net.delete_exposed_ips(vms_on_net, CONF.bgp_nic)

View File

@ -75,7 +75,7 @@ class TestOVNBGPDriver(test_base.TestCase):
self.bgp_driver.start()
mock_vrf.assert_called_once_with(
constants.OVN_BGP_VRF, CONF.bgp_AS, CONF.bgp_router_id)
CONF.bgp_vrf, CONF.bgp_AS, CONF.bgp_router_id)
# Assert connections were started
self.mock_ovs_idl().start.assert_called_once_with(
CONF.ovsdb_connection)
@ -119,9 +119,9 @@ class TestOVNBGPDriver(test_base.TestCase):
self.bgp_driver.sync()
mock_ensure_vrf.assert_called_once_with(
constants.OVN_BGP_VRF, constants.OVN_BGP_VRF_TABLE)
CONF.bgp_vrf, CONF.bgp_vrf_table_id)
mock_ensure_ovn_dev.assert_called_once_with(
constants.OVN_BGP_NIC, constants.OVN_BGP_VRF)
CONF.bgp_nic, CONF.bgp_vrf)
expected_calls = [mock.call('bridge0', 1, 10),
mock.call('bridge1', 2, 11)]
@ -159,7 +159,7 @@ class TestOVNBGPDriver(test_base.TestCase):
mock_ensure_cr_port_exposed.assert_has_calls(expected_calls)
mock_del_exposed_ips.assert_called_once_with(
ips, constants.OVN_BGP_NIC)
ips, CONF.bgp_nic)
mock_del_ip_riles.assert_called_once_with(fake_ip_rules)
moock_del_ip_routes.assert_called_once_with(
{self.bridge: 'fake-table'}, mock.ANY,
@ -287,9 +287,9 @@ class TestOVNBGPDriver(test_base.TestCase):
mock_add_route.assert_called_once_with(
mock.ANY, self.ipv4, 'fake-table', self.bridge,
vlan=10, mask='32', via=self.fip)
expected_calls = [mock.call(constants.OVN_BGP_NIC, ['192.168.1.10']),
mock.call(constants.OVN_BGP_NIC, ['192.168.1.11']),
mock.call(constants.OVN_BGP_NIC, ['192.168.1.13'])]
expected_calls = [mock.call(CONF.bgp_nic, ['192.168.1.10']),
mock.call(CONF.bgp_nic, ['192.168.1.11']),
mock.call(CONF.bgp_nic, ['192.168.1.13'])]
mock_add_ips_dev.assert_has_calls(expected_calls)
@mock.patch.object(linux_net, 'add_ip_route')
@ -382,7 +382,7 @@ class TestOVNBGPDriver(test_base.TestCase):
# Assert that the add methods were called
mock_add_ip_dev.assert_called_once_with(
constants.OVN_BGP_NIC, [self.ipv4])
CONF.bgp_nic, [self.ipv4])
mock_add_rule.assert_called_once_with(
self.ipv4, 'fake-table', self.bridge)
mock_add_route.assert_called_once_with(
@ -405,7 +405,7 @@ class TestOVNBGPDriver(test_base.TestCase):
# Assert that the add methods were called
mock_add_ip_dev.assert_called_once_with(
constants.OVN_BGP_NIC, [self.ipv4])
CONF.bgp_nic, [self.ipv4])
mock_add_rule.assert_called_once_with(
self.ipv4, 'fake-table', self.bridge)
mock_add_route.assert_not_called()
@ -423,8 +423,8 @@ class TestOVNBGPDriver(test_base.TestCase):
self.loadbalancer, 'fake-provider-dp', self.cr_lrp0)
# Assert that the del methods were called
expected_calls = [mock.call(constants.OVN_BGP_NIC, [self.ipv4]),
mock.call(constants.OVN_BGP_NIC, [self.ipv6])]
expected_calls = [mock.call(CONF.bgp_nic, [self.ipv4]),
mock.call(CONF.bgp_nic, [self.ipv6])]
mock_del_ip_dev.assert_has_calls(expected_calls)
expected_calls = [mock.call(self.ipv4, 'fake-table', self.bridge),
@ -456,7 +456,7 @@ class TestOVNBGPDriver(test_base.TestCase):
# Assert that the add methods were called
mock_add_ip_dev.assert_called_once_with(
constants.OVN_BGP_NIC, ips)
CONF.bgp_nic, ips)
expected_calls = [mock.call(self.ipv4, 'fake-table', self.bridge),
mock.call(self.ipv6, 'fake-table', self.bridge)]
@ -490,7 +490,7 @@ class TestOVNBGPDriver(test_base.TestCase):
# Assert that the add methods were called
mock_add_ip_dev.assert_called_once_with(
constants.OVN_BGP_NIC, [self.fip])
CONF.bgp_nic, [self.fip])
mock_add_rule.assert_called_once_with(
self.fip, 'fake-table', self.bridge)
mock_add_route.assert_called_once_with(
@ -544,7 +544,7 @@ class TestOVNBGPDriver(test_base.TestCase):
# Assert that the add methods were called
mock_add_ip_dev.assert_called_once_with(
constants.OVN_BGP_NIC, ips)
CONF.bgp_nic, ips)
expected_calls = [mock.call(self.ipv4, 'fake-table', self.bridge),
mock.call(self.ipv6, 'fake-table', self.bridge)]
@ -615,7 +615,7 @@ class TestOVNBGPDriver(test_base.TestCase):
# Assert that the add methods were called
mock_add_ip_dev.assert_called_once_with(
constants.OVN_BGP_NIC, ips)
CONF.bgp_nic, ips)
expected_calls = [mock.call(self.ipv4, 'fake-table', self.bridge,
lladdr=self.mac),
@ -663,7 +663,7 @@ class TestOVNBGPDriver(test_base.TestCase):
# Assert that the del methods were called
mock_del_ip_dev.assert_called_once_with(
constants.OVN_BGP_NIC, ips)
CONF.bgp_nic, ips)
expected_calls = [mock.call(self.ipv4, 'fake-table', self.bridge),
mock.call(self.ipv6, 'fake-table', self.bridge)]
@ -697,7 +697,7 @@ class TestOVNBGPDriver(test_base.TestCase):
# Assert that the del methods were called
mock_del_ip_dev.assert_called_once_with(
constants.OVN_BGP_NIC, [self.fip])
CONF.bgp_nic, [self.fip])
mock_del_rule.assert_called_once_with(
self.fip, 'fake-table', self.bridge)
mock_del_route.assert_called_once_with(
@ -745,7 +745,7 @@ class TestOVNBGPDriver(test_base.TestCase):
# Assert that the del methods were called
mock_del_ip_dev.assert_called_once_with(
constants.OVN_BGP_NIC, ips)
CONF.bgp_nic, ips)
expected_calls = [mock.call(self.ipv4, 'fake-table', self.bridge),
mock.call(self.ipv6, 'fake-table', self.bridge)]
@ -799,7 +799,7 @@ class TestOVNBGPDriver(test_base.TestCase):
# Assert that the del methods were called
mock_del_ip_dev.assert_called_once_with(
constants.OVN_BGP_NIC, ips)
CONF.bgp_nic, ips)
expected_calls = [mock.call('{}/32'.format(self.ipv4), 'fake-table',
self.bridge, lladdr=self.mac),
@ -832,7 +832,7 @@ class TestOVNBGPDriver(test_base.TestCase):
ips = [self.ipv4, self.ipv6]
self.bgp_driver.expose_remote_ip(ips, row)
mock_add_ip_dev.assert_called_once_with(constants.OVN_BGP_NIC, ips)
mock_add_ip_dev.assert_called_once_with(CONF.bgp_nic, ips)
@mock.patch.object(linux_net, 'add_ips_to_dev')
def test_expose_remote_ip_is_provider_network(self, mock_add_ip_dev):
@ -871,7 +871,7 @@ class TestOVNBGPDriver(test_base.TestCase):
ips = [self.ipv4, self.ipv6]
self.bgp_driver.withdraw_remote_ip(ips, row)
mock_del_ip_dev.assert_called_once_with(constants.OVN_BGP_NIC, ips)
mock_del_ip_dev.assert_called_once_with(CONF.bgp_nic, ips)
@mock.patch.object(linux_net, 'del_ips_from_dev')
def test_withdraw_remote_ip_is_provider_network(self, mock_del_ip_dev):
@ -941,8 +941,8 @@ class TestOVNBGPDriver(test_base.TestCase):
mock_add_route.assert_called_once_with(
mock.ANY, self.ipv4, 'fake-table', self.bridge, vlan=10,
mask='32', via=self.fip)
expected_calls = [mock.call(constants.OVN_BGP_NIC, ['192.168.1.10']),
mock.call(constants.OVN_BGP_NIC, ['192.168.1.11'])]
expected_calls = [mock.call(CONF.bgp_nic, ['192.168.1.10']),
mock.call(CONF.bgp_nic, ['192.168.1.11'])]
mock_add_ip_dev.assert_has_calls(expected_calls)
@mock.patch.object(linux_net, 'get_exposed_ips_on_network')
@ -973,4 +973,4 @@ class TestOVNBGPDriver(test_base.TestCase):
mock.ANY, self.ipv4, 'fake-table', self.bridge, vlan=10,
mask='32', via=self.fip)
mock_del_exposed_ips.assert_called_once_with(
[self.ipv4], constants.OVN_BGP_NIC)
[self.ipv4], CONF.bgp_nic)