From 983ee0c4f31413904b2f1c2b3a655a32cba70401 Mon Sep 17 00:00:00 2001 From: Fernando Royo Date: Tue, 19 Sep 2023 17:56:23 +0200 Subject: [PATCH] Check multiple address of a LRP plugged to LS When LB or member is created, driver looks for the Logical Router which is plugged to the Logical Switch. As there can be more than one address on the port, we should iterate over them to be compared with the gateway IP. This patch modifies code to do not crash if more than one address is found in neutron:cidrs external_ids field. Closes-Bug: 2036620 Change-Id: I17b2c2577a4d99455c30ca1e10632a7004d7c084 --- ovn_octavia_provider/helper.py | 10 ++- .../tests/unit/test_helper.py | 80 +++++++++++++++++++ 2 files changed, 86 insertions(+), 4 deletions(-) diff --git a/ovn_octavia_provider/helper.py b/ovn_octavia_provider/helper.py index 4197ef6a..e5286d71 100644 --- a/ovn_octavia_provider/helper.py +++ b/ovn_octavia_provider/helper.py @@ -801,10 +801,12 @@ class OvnProviderHelper(): ovn_const.OVN_DEVICE_OWNER_EXT_ID_KEY) == n_const.DEVICE_OWNER_ROUTER_INTF): if subnet_gateway_ip: - port_cidr = netaddr.IPNetwork( - port.external_ids[ - ovn_const.OVN_PORT_CIDR_EXT_ID_KEY]).ip - if netaddr.IPAddress(subnet_gateway_ip) != port_cidr: + for port_cidr in port.external_ids[ + ovn_const.OVN_PORT_CIDR_EXT_ID_KEY].split(): + port_ip = netaddr.IPNetwork(port_cidr).ip + if netaddr.IPAddress(subnet_gateway_ip) == port_ip: + break + else: continue lsp_router_port = port break diff --git a/ovn_octavia_provider/tests/unit/test_helper.py b/ovn_octavia_provider/tests/unit/test_helper.py index c55c63b9..397df30d 100644 --- a/ovn_octavia_provider/tests/unit/test_helper.py +++ b/ovn_octavia_provider/tests/unit/test_helper.py @@ -2598,6 +2598,70 @@ class TestOvnProviderHelper(ovn_base.TestOvnOctaviaBase): returned_lr = self.helper._find_lr_of_ls(ls, '10.10.10.1') self.assertEqual(lr, returned_lr) + def test__find_lr_of_ls_multiple_address_ipv4(self): + lsp = fakes.FakeOvsdbRow.create_one_ovsdb_row( + attrs={ + 'external_ids': { + ovn_const.OVN_ROUTER_NAME_EXT_ID_KEY: 'router1', + 'neutron:cidrs': ( + '10.10.10.1/24 10.10.20.1/24' + ), + ovn_const.OVN_DEVICE_OWNER_EXT_ID_KEY: + n_const.DEVICE_OWNER_ROUTER_INTF}, + 'type': 'router', + 'options': { + 'router-port': 'lrp-foo-name'}, + }) + lrp = fakes.FakeOvsdbRow.create_one_ovsdb_row( + attrs={ + 'name': 'lrp-foo-name', + }) + lr = fakes.FakeOVNRouter.create_one_router( + attrs={ + 'name': 'router1', + 'ports': [lrp]}) + + ls = fakes.FakeOvsdbRow.create_one_ovsdb_row( + attrs={'ports': [lsp]}) + + (self.helper.ovn_nbdb_api.get_lrs.return_value. + execute.return_value) = [lr] + returned_lr = self.helper._find_lr_of_ls(ls, '10.10.20.1') + self.assertEqual(lr, returned_lr) + + def test__find_lr_of_ls_multiple_address_ipv6(self): + lsp = fakes.FakeOvsdbRow.create_one_ovsdb_row( + attrs={ + 'external_ids': { + ovn_const.OVN_ROUTER_NAME_EXT_ID_KEY: 'router1', + 'neutron:cidrs': ( + 'fd61:5fe4:978c:a334:0:3eff:24ab:f816/64 ' + 'fd8b:8a01:ab1d:0:f816:3eff:fe3d:24ab/64' + ), + ovn_const.OVN_DEVICE_OWNER_EXT_ID_KEY: + n_const.DEVICE_OWNER_ROUTER_INTF}, + 'type': 'router', + 'options': { + 'router-port': 'lrp-foo-name'}, + }) + lrp = fakes.FakeOvsdbRow.create_one_ovsdb_row( + attrs={ + 'name': 'lrp-foo-name', + }) + lr = fakes.FakeOVNRouter.create_one_router( + attrs={ + 'name': 'router1', + 'ports': [lrp]}) + + ls = fakes.FakeOvsdbRow.create_one_ovsdb_row( + attrs={'ports': [lsp]}) + + (self.helper.ovn_nbdb_api.get_lrs.return_value. + execute.return_value) = [lr] + returned_lr = self.helper._find_lr_of_ls( + ls, 'fd61:5fe4:978c:a334:0:3eff:24ab:f816') + self.assertEqual(lr, returned_lr) + def test__find_lr_of_ls_no_lrs(self): lsp = fakes.FakeOvsdbRow.create_one_ovsdb_row( attrs={ @@ -2669,6 +2733,22 @@ class TestOvnProviderHelper(ovn_base.TestOvnOctaviaBase): returned_lr = self.helper._find_lr_of_ls(ls) self.assertIsNone(returned_lr) + def test__find_lr_of_ls_no_router_type_port(self): + lsp = fakes.FakeOvsdbRow.create_one_ovsdb_row( + attrs={ + 'external_ids': { + ovn_const.OVN_ROUTER_NAME_EXT_ID_KEY: 'router1', + ovn_const.OVN_DEVICE_OWNER_EXT_ID_KEY: + n_const.DEVICE_OWNER_ROUTER_INTF}, + 'type': 'foo', + 'options': { + 'router-port': None} + }) + ls = fakes.FakeOvsdbRow.create_one_ovsdb_row( + attrs={'ports': [lsp]}) + returned_lr = self.helper._find_lr_of_ls(ls) + self.assertIsNone(returned_lr) + def test__find_lr_of_ls_no_lrp(self): ls = fakes.FakeOvsdbRow.create_one_ovsdb_row( attrs={'ports': []})