Skip to content

Commit 0110c31

Browse files
Zuulopenstack-gerrit
authored andcommitted
Merge "[OVN] ovn-db-sync check for router port differences" into stable/2023.1
2 parents 36f78ee + 04541b0 commit 0110c31

File tree

3 files changed

+82
-5
lines changed

3 files changed

+82
-5
lines changed

neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/ovn_db_sync.py

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,36 @@ def _delete_floatingip_pfs(self, context, fip_id, txn):
455455
self.l3_plugin.port_forwarding.db_sync_delete(
456456
context, fip_id, txn)
457457

458+
def _is_router_port_changed(self, db_router_port, lrport_nets):
459+
"""Check if the router port needs to be updated.
460+
461+
This method checks for networks and ipv6_ra_configs (if supported)
462+
changes on a given router port.
463+
"""
464+
db_lrport_nets = db_router_port['networks']
465+
if db_lrport_nets != lrport_nets:
466+
return True
467+
468+
# Check for ipv6_ra_configs changes
469+
db_lrport_ra = db_router_port['ipv6_ra_configs']
470+
lrport_ra = {}
471+
ipv6_ra_supported = self.ovn_api.is_col_present(
472+
'Logical_Router_Port', 'ipv6_ra_configs')
473+
if ipv6_ra_supported:
474+
lrp_name = utils.ovn_lrouter_port_name(db_router_port['id'])
475+
try:
476+
ovn_lrport = self.ovn_api.lrp_get(
477+
lrp_name).execute(check_error=True)
478+
except idlutils.RowNotFound:
479+
# If the port is not found in the OVN database the
480+
# ovn-db-sync script will recreate this port later
481+
# and it will have the latest information. No need
482+
# to update it.
483+
return False
484+
lrport_ra = ovn_lrport.ipv6_ra_configs
485+
486+
return db_lrport_ra != lrport_ra
487+
458488
def sync_routers_and_rports(self, ctx):
459489
"""Sync Routers between neutron and NB.
460490
@@ -534,6 +564,12 @@ def sync_routers_and_rports(self, ctx):
534564
constants.DEVICE_OWNER_HA_REPLICATED_INT])
535565
for interface in interfaces:
536566
db_router_ports[interface['id']] = interface
567+
networks, ipv6_ra_configs = (
568+
self._ovn_client._get_nets_and_ipv6_ra_confs_for_router_port(
569+
ctx, interface))
570+
db_router_ports[interface['id']]['networks'] = networks
571+
db_router_ports[interface['id']][
572+
'ipv6_ra_configs'] = ipv6_ra_configs
537573

538574
lrouters = self.ovn_api.get_all_logical_routers_with_rports()
539575

@@ -550,11 +586,9 @@ def sync_routers_and_rports(self, ctx):
550586
if lrouter['name'] in db_routers:
551587
for lrport, lrport_nets in lrouter['ports'].items():
552588
if lrport in db_router_ports:
553-
# We dont have to check for the networks and
554-
# ipv6_ra_configs values. Lets add it to the
555-
# update_lrport_list. If they are in sync, then
556-
# update_router_port will be a no-op.
557-
update_lrport_list.append(db_router_ports[lrport])
589+
if self._is_router_port_changed(
590+
db_router_ports[lrport], lrport_nets):
591+
update_lrport_list.append(db_router_ports[lrport])
558592
del db_router_ports[lrport]
559593
else:
560594
del_lrouter_ports_list.append(

neutron/tests/unit/fake_resources.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ def __init__(self, **kwargs):
163163
self.ha_chassis_group_del = mock.Mock()
164164
self.ha_chassis_group_add_chassis = mock.Mock()
165165
self.ha_chassis_group_del_chassis = mock.Mock()
166+
self.lrp_get = mock.Mock()
166167

167168

168169
class FakeOvsdbSbOvnIdl(object):

neutron/tests/unit/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovn_db_sync.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
from neutron.plugins.ml2.drivers.ovn.mech_driver.ovsdb import ovn_client
2424
from neutron.plugins.ml2.drivers.ovn.mech_driver.ovsdb import ovn_db_sync
2525
from neutron.services.ovn_l3 import plugin as ovn_plugin
26+
from neutron.tests.unit import fake_resources as fakes
2627
from neutron.tests.unit.plugins.ml2.drivers.ovn.mech_driver import \
2728
test_mech_driver
2829

@@ -1109,6 +1110,47 @@ def test_ovn_nb_sync_calculate_routes_add_remove_keep_two_routes(self):
11091110
expected_deleted)
11101111

11111112

1113+
class TestIsRouterPortChanged(test_mech_driver.OVNMechanismDriverTestCase):
1114+
1115+
def setUp(self):
1116+
super(TestIsRouterPortChanged, self).setUp()
1117+
self.ovn_nb_synchronizer = ovn_db_sync.OvnNbSynchronizer(
1118+
self.plugin, self.mech_driver.nb_ovn, self.mech_driver.sb_ovn,
1119+
'log', self.mech_driver)
1120+
1121+
self.db_router_port = {
1122+
'id': 'aa076509-915d-4b1c-8d9d-3db53d9c5faf',
1123+
'networks': ['fdf9:ad62:3a04::1/64'],
1124+
'ipv6_ra_configs': {'address_mode': 'slaac',
1125+
'send_periodic': 'true',
1126+
'mtu': '1442'}
1127+
}
1128+
self.lrport_nets = ['fdf9:ad62:3a04::1/64']
1129+
self.ovn_lrport = fakes.FakeOvsdbRow.create_one_ovsdb_row(
1130+
attrs={'ipv6_ra_configs': {'address_mode': 'slaac',
1131+
'send_periodic': 'true',
1132+
'mtu': '1442'}})
1133+
1134+
self.ovn_nb_synchronizer.ovn_api.is_col_present.return_value = True
1135+
self.ovn_nb_synchronizer.ovn_api.lrp_get().execute.return_value = (
1136+
self.ovn_lrport)
1137+
1138+
def test__is_router_port_changed_not_changed(self):
1139+
self.assertFalse(self.ovn_nb_synchronizer._is_router_port_changed(
1140+
self.db_router_port, self.lrport_nets))
1141+
1142+
def test__is_router_port_changed_network_changed(self):
1143+
self.db_router_port['networks'] = ['172.24.4.26/24',
1144+
'2001:db8::206/64']
1145+
self.assertTrue(self.ovn_nb_synchronizer._is_router_port_changed(
1146+
self.db_router_port, self.lrport_nets))
1147+
1148+
def test__is_router_port_changed_ipv6_ra_configs_changed(self):
1149+
self.db_router_port['ipv6_ra_configs']['mtu'] = '1500'
1150+
self.assertTrue(self.ovn_nb_synchronizer._is_router_port_changed(
1151+
self.db_router_port, self.lrport_nets))
1152+
1153+
11121154
class TestOvnSbSyncML2(test_mech_driver.OVNMechanismDriverTestCase):
11131155

11141156
def test_ovn_sb_sync(self):

0 commit comments

Comments
 (0)