Skip to content

Commit fdba20b

Browse files
Zuulopenstack-gerrit
authored andcommitted
Merge "[OVN] ovn-db-sync check for router port differences" into stable/zed
2 parents 7364c55 + bc71377 commit fdba20b

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
@@ -453,6 +453,36 @@ def _delete_floatingip_pfs(self, context, fip_id, txn):
453453
self.l3_plugin.port_forwarding.db_sync_delete(
454454
context, fip_id, txn)
455455

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

536572
lrouters = self.ovn_api.get_all_logical_routers_with_rports()
537573

@@ -548,11 +584,9 @@ def sync_routers_and_rports(self, ctx):
548584
if lrouter['name'] in db_routers:
549585
for lrport, lrport_nets in lrouter['ports'].items():
550586
if lrport in db_router_ports:
551-
# We dont have to check for the networks and
552-
# ipv6_ra_configs values. Lets add it to the
553-
# update_lrport_list. If they are in sync, then
554-
# update_router_port will be a no-op.
555-
update_lrport_list.append(db_router_ports[lrport])
587+
if self._is_router_port_changed(
588+
db_router_ports[lrport], lrport_nets):
589+
update_lrport_list.append(db_router_ports[lrport])
556590
del db_router_ports[lrport]
557591
else:
558592
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)