Skip to content

Commit 4f2de74

Browse files
committed
[OVN][L3] Optimize FIP update operation
If the floating IP updates only the QoS policy, the method now skips the OVN NAT rules update and updates only the QoS policy. That avoids the OVN NAT rules deletion and creation and the ``FIPAddDeleteEvent`` event that deletes the MAC binding entries for an active floating IP, causing a disruption. Closes-Bug: #2025144 Conflicts: neutron/tests/unit/services/ovn_l3/test_plugin.py Change-Id: Ib9ec45d643c6162c526cd5a02db270094b575e34 (cherry picked from commit 7b85f9c)
1 parent 7972c1e commit 4f2de74

File tree

3 files changed

+47
-17
lines changed

3 files changed

+47
-17
lines changed

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

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
from neutron_lib.plugins import directory
3333
from neutron_lib.plugins import utils as p_utils
3434
from neutron_lib.services.logapi import constants as log_const
35+
from neutron_lib.services.qos import constants as qos_consts
3536
from neutron_lib.utils import helpers
3637
from neutron_lib.utils import net as n_net
3738
from oslo_config import cfg
@@ -1124,25 +1125,30 @@ def create_floatingip(self, context, floatingip):
11241125
n_context.get_admin_context(), floatingip['id'],
11251126
const.FLOATINGIP_STATUS_ACTIVE)
11261127

1127-
def update_floatingip(self, context, floatingip):
1128+
def update_floatingip(self, context, floatingip, fip_request=None):
11281129
fip_status = None
11291130
router_id = None
11301131
ovn_fip = self._nb_idl.get_floatingip(floatingip['id'])
1132+
fip_request = fip_request[l3.FLOATINGIP] if fip_request else {}
1133+
qos_update_only = (len(fip_request.keys()) == 1 and
1134+
qos_consts.QOS_POLICY_ID in fip_request)
11311135

11321136
check_rev_cmd = self._nb_idl.check_revision_number(
11331137
floatingip['id'], floatingip, ovn_const.TYPE_FLOATINGIPS)
11341138
with self._nb_idl.transaction(check_error=True) as txn:
11351139
txn.add(check_rev_cmd)
1136-
if ovn_fip:
1137-
lrouter = ovn_fip['external_ids'].get(
1138-
ovn_const.OVN_ROUTER_NAME_EXT_ID_KEY,
1139-
utils.ovn_name(router_id))
1140-
self._delete_floatingip(ovn_fip, lrouter, txn=txn)
1141-
fip_status = const.FLOATINGIP_STATUS_DOWN
1142-
1143-
if floatingip.get('port_id'):
1144-
self._create_or_update_floatingip(floatingip, txn=txn)
1145-
fip_status = const.FLOATINGIP_STATUS_ACTIVE
1140+
# If FIP updates the QoS policy only, skip the OVN NAT rules update
1141+
if not qos_update_only:
1142+
if ovn_fip:
1143+
lrouter = ovn_fip['external_ids'].get(
1144+
ovn_const.OVN_ROUTER_NAME_EXT_ID_KEY,
1145+
utils.ovn_name(router_id))
1146+
self._delete_floatingip(ovn_fip, lrouter, txn=txn)
1147+
fip_status = const.FLOATINGIP_STATUS_DOWN
1148+
1149+
if floatingip.get('port_id'):
1150+
self._create_or_update_floatingip(floatingip, txn=txn)
1151+
fip_status = const.FLOATINGIP_STATUS_ACTIVE
11461152

11471153
self._qos_driver.update_floatingip(txn, floatingip)
11481154

neutron/services/ovn_l3/plugin.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ def delete_floatingip(self, context, id):
285285
def update_floatingip(self, context, id, floatingip):
286286
fip = super(OVNL3RouterPlugin, self).update_floatingip(context, id,
287287
floatingip)
288-
self._ovn_client.update_floatingip(context, fip)
288+
self._ovn_client.update_floatingip(context, fip, floatingip)
289289
return fip
290290

291291
def update_floatingip_status(self, context, floatingip_id, status):

neutron/tests/unit/services/ovn_l3/test_plugin.py

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
from unittest import mock
1717

1818
from neutron_lib.api.definitions import external_net
19+
from neutron_lib.api.definitions import l3 as l3_def
1920
from neutron_lib.api.definitions import portbindings
2021
from neutron_lib.api.definitions import provider_net as pnet
2122
from neutron_lib.callbacks import events
@@ -26,12 +27,14 @@
2627
from neutron_lib.exceptions import l3 as l3_exc
2728
from neutron_lib.plugins import constants as plugin_constants
2829
from neutron_lib.plugins import directory
30+
from neutron_lib.services.qos import constants as qos_consts
2931
from oslo_config import cfg
3032
from oslo_utils import uuidutils
3133

3234
from neutron.common.ovn import constants as ovn_const
3335
from neutron.common.ovn import utils
3436
from neutron.conf.plugins.ml2.drivers.ovn import ovn_conf as config
37+
from neutron.db import extraroute_db
3538
from neutron.services.revisions import revision_plugin
3639
from neutron.tests.unit.api import test_extensions
3740
from neutron.tests.unit.extensions import test_extraroute
@@ -1216,7 +1219,8 @@ def test_update_floatingip(self, uf):
12161219
uf.return_value = self.fake_floating_ip_new
12171220
nb_ovn.get_floatingip.return_value = (
12181221
self.fake_ovn_nat_rule)
1219-
self.l3_inst.update_floatingip(self.context, 'id', 'floatingip')
1222+
fip = {l3_def.FLOATINGIP: {'port_id': 'port1'}}
1223+
self.l3_inst.update_floatingip(self.context, 'id', fip)
12201224
nb_ovn.delete_nat_rule_in_lrouter.assert_called_once_with(
12211225
'neutron-router-id',
12221226
type='dnat_and_snat',
@@ -1240,13 +1244,30 @@ def test_update_floatingip(self, uf):
12401244
logical_port='new-port_id',
12411245
external_ids=expected_ext_ids)
12421246

1247+
@mock.patch.object(extraroute_db.ExtraRoute_dbonly_mixin,
1248+
'update_floatingip')
1249+
def test_update_floatingip_qos(self, uf):
1250+
nb_ovn = self.l3_inst._nb_ovn
1251+
nb_ovn.is_col_present.return_value = True
1252+
uf.return_value = self.fake_floating_ip_new
1253+
nb_ovn.get_floatingip.return_value = (
1254+
self.fake_ovn_nat_rule)
1255+
fip = {l3_def.FLOATINGIP: {qos_consts.QOS_POLICY_ID: 'qos_id_1'}}
1256+
with mock.patch.object(self.l3_inst._ovn_client._qos_driver,
1257+
'update_floatingip') as ufip:
1258+
self.l3_inst.update_floatingip(self.context, 'id', fip)
1259+
nb_ovn.delete_nat_rule_in_lrouter.assert_not_called()
1260+
nb_ovn.add_nat_rule_in_lrouter.assert_not_called()
1261+
ufip.assert_called_once_with(mock.ANY, self.fake_floating_ip_new)
1262+
12431263
@mock.patch('neutron.db.extraroute_db.ExtraRoute_dbonly_mixin.'
12441264
'update_floatingip')
12451265
def test_update_floatingip_associate(self, uf):
12461266
self.l3_inst._nb_ovn.is_col_present.return_value = True
12471267
self.fake_floating_ip.update({'fixed_port_id': None})
12481268
uf.return_value = self.fake_floating_ip_new
1249-
self.l3_inst.update_floatingip(self.context, 'id', 'floatingip')
1269+
fip = {l3_def.FLOATINGIP: {'port_id': 'port1'}}
1270+
self.l3_inst.update_floatingip(self.context, 'id', fip)
12501271
self.l3_inst._nb_ovn.delete_nat_rule_in_lrouter.assert_not_called()
12511272
expected_ext_ids = {
12521273
ovn_const.OVN_FIP_EXT_ID_KEY: self.fake_floating_ip_new['id'],
@@ -1282,7 +1303,8 @@ def test_update_floatingip_associate_distributed(self, uf, gn):
12821303

12831304
config.cfg.CONF.set_override(
12841305
'enable_distributed_floating_ip', True, group='ovn')
1285-
self.l3_inst.update_floatingip(self.context, 'id', 'floatingip')
1306+
fip = {l3_def.FLOATINGIP: {'port_id': 'port1'}}
1307+
self.l3_inst.update_floatingip(self.context, 'id', fip)
12861308
self.l3_inst._nb_ovn.delete_nat_rule_in_lrouter.assert_not_called()
12871309
expected_ext_ids = {
12881310
ovn_const.OVN_FIP_EXT_ID_KEY: self.fake_floating_ip_new['id'],
@@ -1310,7 +1332,8 @@ def test_update_floatingip_association_empty_update(self, uf):
13101332
self.fake_floating_ip.update({'fixed_port_id': 'foo'})
13111333
self.fake_floating_ip_new.update({'port_id': 'foo'})
13121334
uf.return_value = self.fake_floating_ip_new
1313-
self.l3_inst.update_floatingip(self.context, 'id', 'floatingip')
1335+
fip = {l3_def.FLOATINGIP: {'port_id': 'port1'}}
1336+
self.l3_inst.update_floatingip(self.context, 'id', fip)
13141337
nb_ovn.delete_nat_rule_in_lrouter.assert_called_once_with(
13151338
'neutron-router-id',
13161339
type='dnat_and_snat',
@@ -1345,7 +1368,8 @@ def test_update_floatingip_reassociate_to_same_port_diff_fixed_ip(
13451368
self.fake_floating_ip_new.update({'port_id': 'port_id',
13461369
'fixed_port_id': 'port_id'})
13471370
uf.return_value = self.fake_floating_ip_new
1348-
self.l3_inst.update_floatingip(self.context, 'id', 'floatingip')
1371+
fip = {l3_def.FLOATINGIP: {'port_id': 'port1'}}
1372+
self.l3_inst.update_floatingip(self.context, 'id', fip)
13491373

13501374
nb_ovn.delete_nat_rule_in_lrouter.assert_called_once_with(
13511375
'neutron-router-id',

0 commit comments

Comments
 (0)