Skip to content

Commit 052c389

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) (cherry picked from commit 4f2de74)
1 parent 226e29a commit 052c389

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
@@ -1125,25 +1126,30 @@ def create_floatingip(self, context, floatingip):
11251126
n_context.get_admin_context(), floatingip['id'],
11261127
const.FLOATINGIP_STATUS_ACTIVE)
11271128

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

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

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

neutron/services/ovn_l3/plugin.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ def delete_floatingip(self, context, id):
278278
def update_floatingip(self, context, id, floatingip):
279279
fip = super(OVNL3RouterPlugin, self).update_floatingip(context, id,
280280
floatingip)
281-
self._ovn_client.update_floatingip(context, fip)
281+
self._ovn_client.update_floatingip(context, fip, floatingip)
282282
return fip
283283

284284
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
@@ -1210,7 +1213,8 @@ def test_update_floatingip(self, uf):
12101213
uf.return_value = self.fake_floating_ip_new
12111214
nb_ovn.get_floatingip.return_value = (
12121215
self.fake_ovn_nat_rule)
1213-
self.l3_inst.update_floatingip(self.context, 'id', 'floatingip')
1216+
fip = {l3_def.FLOATINGIP: {'port_id': 'port1'}}
1217+
self.l3_inst.update_floatingip(self.context, 'id', fip)
12141218
nb_ovn.delete_nat_rule_in_lrouter.assert_called_once_with(
12151219
'neutron-router-id',
12161220
type='dnat_and_snat',
@@ -1234,13 +1238,30 @@ def test_update_floatingip(self, uf):
12341238
logical_port='new-port_id',
12351239
external_ids=expected_ext_ids)
12361240

1241+
@mock.patch.object(extraroute_db.ExtraRoute_dbonly_mixin,
1242+
'update_floatingip')
1243+
def test_update_floatingip_qos(self, uf):
1244+
nb_ovn = self.l3_inst._nb_ovn
1245+
nb_ovn.is_col_present.return_value = True
1246+
uf.return_value = self.fake_floating_ip_new
1247+
nb_ovn.get_floatingip.return_value = (
1248+
self.fake_ovn_nat_rule)
1249+
fip = {l3_def.FLOATINGIP: {qos_consts.QOS_POLICY_ID: 'qos_id_1'}}
1250+
with mock.patch.object(self.l3_inst._ovn_client._qos_driver,
1251+
'update_floatingip') as ufip:
1252+
self.l3_inst.update_floatingip(self.context, 'id', fip)
1253+
nb_ovn.delete_nat_rule_in_lrouter.assert_not_called()
1254+
nb_ovn.add_nat_rule_in_lrouter.assert_not_called()
1255+
ufip.assert_called_once_with(mock.ANY, self.fake_floating_ip_new)
1256+
12371257
@mock.patch('neutron.db.extraroute_db.ExtraRoute_dbonly_mixin.'
12381258
'update_floatingip')
12391259
def test_update_floatingip_associate(self, uf):
12401260
self.l3_inst._nb_ovn.is_col_present.return_value = True
12411261
self.fake_floating_ip.update({'fixed_port_id': None})
12421262
uf.return_value = self.fake_floating_ip_new
1243-
self.l3_inst.update_floatingip(self.context, 'id', 'floatingip')
1263+
fip = {l3_def.FLOATINGIP: {'port_id': 'port1'}}
1264+
self.l3_inst.update_floatingip(self.context, 'id', fip)
12441265
self.l3_inst._nb_ovn.delete_nat_rule_in_lrouter.assert_not_called()
12451266
expected_ext_ids = {
12461267
ovn_const.OVN_FIP_EXT_ID_KEY: self.fake_floating_ip_new['id'],
@@ -1276,7 +1297,8 @@ def test_update_floatingip_associate_distributed(self, uf, gn):
12761297

12771298
config.cfg.CONF.set_override(
12781299
'enable_distributed_floating_ip', True, group='ovn')
1279-
self.l3_inst.update_floatingip(self.context, 'id', 'floatingip')
1300+
fip = {l3_def.FLOATINGIP: {'port_id': 'port1'}}
1301+
self.l3_inst.update_floatingip(self.context, 'id', fip)
12801302
self.l3_inst._nb_ovn.delete_nat_rule_in_lrouter.assert_not_called()
12811303
expected_ext_ids = {
12821304
ovn_const.OVN_FIP_EXT_ID_KEY: self.fake_floating_ip_new['id'],
@@ -1304,7 +1326,8 @@ def test_update_floatingip_association_empty_update(self, uf):
13041326
self.fake_floating_ip.update({'fixed_port_id': 'foo'})
13051327
self.fake_floating_ip_new.update({'port_id': 'foo'})
13061328
uf.return_value = self.fake_floating_ip_new
1307-
self.l3_inst.update_floatingip(self.context, 'id', 'floatingip')
1329+
fip = {l3_def.FLOATINGIP: {'port_id': 'port1'}}
1330+
self.l3_inst.update_floatingip(self.context, 'id', fip)
13081331
nb_ovn.delete_nat_rule_in_lrouter.assert_called_once_with(
13091332
'neutron-router-id',
13101333
type='dnat_and_snat',
@@ -1339,7 +1362,8 @@ def test_update_floatingip_reassociate_to_same_port_diff_fixed_ip(
13391362
self.fake_floating_ip_new.update({'port_id': 'port_id',
13401363
'fixed_port_id': 'port_id'})
13411364
uf.return_value = self.fake_floating_ip_new
1342-
self.l3_inst.update_floatingip(self.context, 'id', 'floatingip')
1365+
fip = {l3_def.FLOATINGIP: {'port_id': 'port1'}}
1366+
self.l3_inst.update_floatingip(self.context, 'id', fip)
13431367

13441368
nb_ovn.delete_nat_rule_in_lrouter.assert_called_once_with(
13451369
'neutron-router-id',

0 commit comments

Comments
 (0)