Skip to content

Commit b5a3c70

Browse files
Zuulopenstack-gerrit
authored andcommitted
Merge "[OVN] ovn-db-sync check for router port differences" into stable/yoga
2 parents c569db7 + b288a12 commit b5a3c70

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
@@ -446,6 +446,36 @@ def _delete_floatingip_pfs(self, context, fip_id, txn):
446446
self.l3_plugin.port_forwarding.db_sync_delete(
447447
context, fip_id, txn)
448448

449+
def _is_router_port_changed(self, db_router_port, lrport_nets):
450+
"""Check if the router port needs to be updated.
451+
452+
This method checks for networks and ipv6_ra_configs (if supported)
453+
changes on a given router port.
454+
"""
455+
db_lrport_nets = db_router_port['networks']
456+
if db_lrport_nets != lrport_nets:
457+
return True
458+
459+
# Check for ipv6_ra_configs changes
460+
db_lrport_ra = db_router_port['ipv6_ra_configs']
461+
lrport_ra = {}
462+
ipv6_ra_supported = self.ovn_api.is_col_present(
463+
'Logical_Router_Port', 'ipv6_ra_configs')
464+
if ipv6_ra_supported:
465+
lrp_name = utils.ovn_lrouter_port_name(db_router_port['id'])
466+
try:
467+
ovn_lrport = self.ovn_api.lrp_get(
468+
lrp_name).execute(check_error=True)
469+
except idlutils.RowNotFound:
470+
# If the port is not found in the OVN database the
471+
# ovn-db-sync script will recreate this port later
472+
# and it will have the latest information. No need
473+
# to update it.
474+
return False
475+
lrport_ra = ovn_lrport.ipv6_ra_configs
476+
477+
return db_lrport_ra != lrport_ra
478+
449479
def sync_routers_and_rports(self, ctx):
450480
"""Sync Routers between neutron and NB.
451481
@@ -525,6 +555,12 @@ def sync_routers_and_rports(self, ctx):
525555
constants.DEVICE_OWNER_HA_REPLICATED_INT])
526556
for interface in interfaces:
527557
db_router_ports[interface['id']] = interface
558+
networks, ipv6_ra_configs = (
559+
self._ovn_client._get_nets_and_ipv6_ra_confs_for_router_port(
560+
ctx, interface))
561+
db_router_ports[interface['id']]['networks'] = networks
562+
db_router_ports[interface['id']][
563+
'ipv6_ra_configs'] = ipv6_ra_configs
528564

529565
lrouters = self.ovn_api.get_all_logical_routers_with_rports()
530566

@@ -541,11 +577,9 @@ def sync_routers_and_rports(self, ctx):
541577
if lrouter['name'] in db_routers:
542578
for lrport, lrport_nets in lrouter['ports'].items():
543579
if lrport in db_router_ports:
544-
# We dont have to check for the networks and
545-
# ipv6_ra_configs values. Lets add it to the
546-
# update_lrport_list. If they are in sync, then
547-
# update_router_port will be a no-op.
548-
update_lrport_list.append(db_router_ports[lrport])
580+
if self._is_router_port_changed(
581+
db_router_ports[lrport], lrport_nets):
582+
update_lrport_list.append(db_router_ports[lrport])
549583
del db_router_ports[lrport]
550584
else:
551585
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
@@ -159,6 +159,7 @@ def __init__(self, **kwargs):
159159
self.ha_chassis_group_del = mock.Mock()
160160
self.ha_chassis_group_add_chassis = mock.Mock()
161161
self.ha_chassis_group_del_chassis = mock.Mock()
162+
self.lrp_get = mock.Mock()
162163

163164

164165
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)