Browse Source

Propagate mtu to all subnets

In networking-ovn we map subnets to OVN DHCP_Options
rows (where we store the MTU), but from neutron API perspective,
the MTU is applied per network. So we need update all subnets
thats belong to network to propagade correctly MTU for network.

Closes-Bug: #1816449
Change-Id: Ieddc16e607bccef84316f9ee908e884539c7ed39
(cherry picked from commit 1daffa9634)
changes/24/669624/1
Kamil Sambor 2 years ago
parent
commit
87ecdd8e0b
  1. 1
      networking_ovn/common/constants.py
  2. 39
      networking_ovn/common/ovn_client.py
  3. 45
      networking_ovn/tests/functional/test_mech_driver.py

1
networking_ovn/common/constants.py

@ -20,6 +20,7 @@ OVN_SG_EXT_ID_KEY = 'neutron:security_group_id'
OVN_SG_RULE_EXT_ID_KEY = 'neutron:security_group_rule_id'
OVN_ML2_MECH_DRIVER_NAME = 'ovn'
OVN_NETWORK_NAME_EXT_ID_KEY = 'neutron:network_name'
OVN_NETWORK_MTU_EXT_ID_KEY = 'neutron:mtu'
OVN_PORT_NAME_EXT_ID_KEY = 'neutron:port_name'
OVN_ROUTER_NAME_EXT_ID_KEY = 'neutron:router_name'
OVN_ROUTER_IS_EXT_GW = 'neutron:is_ext_gw'

39
networking_ovn/common/ovn_client.py

@ -1326,6 +1326,7 @@ class OVNClient(object):
def _gen_network_external_ids(self, network):
ext_ids = {
ovn_const.OVN_NETWORK_NAME_EXT_ID_KEY: network['name'],
ovn_const.OVN_NETWORK_MTU_EXT_ID_KEY: str(network['mtu']),
ovn_const.OVN_REV_NUM_EXT_ID_KEY: str(
utils.get_revision_number(network, ovn_const.TYPE_NETWORKS))}
@ -1418,7 +1419,19 @@ class OVNClient(object):
with self._nb_idl.transaction(check_error=True) as txn:
txn.add(check_rev_cmd)
ext_ids = self._gen_network_external_ids(network)
lswitch = self._nb_idl.get_lswitch(lswitch_name)
txn.add(self._nb_idl.set_lswitch_ext_ids(lswitch_name, ext_ids))
# Check if previous mtu is different than current one,
# checking will help reduce number of operations
if (not lswitch or
lswitch.external_ids.get(
ovn_const.OVN_NETWORK_MTU_EXT_ID_KEY) !=
str(network['mtu'])):
context = n_context.get_admin_context()
subnets = self._plugin.get_subnets_by_network(
context, network['id'])
for subnet in subnets:
self.update_subnet(subnet, network, txn)
if check_rev_cmd.result == ovn_const.TXN_COMMITTED:
if qos_update_required:
@ -1667,7 +1680,15 @@ class OVNClient(object):
self._add_subnet_dhcp_options(subnet, network)
db_rev.bump_revision(subnet, ovn_const.TYPE_SUBNETS)
def update_subnet(self, subnet, network):
def _modify_subnet_dhcp_options(self, subnet, ovn_subnet, network, txn):
if subnet['enable_dhcp'] and not ovn_subnet:
self._enable_subnet_dhcp_options(subnet, network, txn)
elif subnet['enable_dhcp'] and ovn_subnet:
self._update_subnet_dhcp_options(subnet, network, txn)
elif not subnet['enable_dhcp'] and ovn_subnet:
self._remove_subnet_dhcp_options(subnet['id'], txn)
def update_subnet(self, subnet, network, txn=None):
ovn_subnet = self._nb_idl.get_subnet_dhcp_options(
subnet['id'])['subnet']
@ -1677,15 +1698,13 @@ class OVNClient(object):
check_rev_cmd = self._nb_idl.check_revision_number(
subnet['id'], subnet, ovn_const.TYPE_SUBNETS)
with self._nb_idl.transaction(check_error=True) as txn:
txn.add(check_rev_cmd)
if subnet['enable_dhcp'] and not ovn_subnet:
self._enable_subnet_dhcp_options(subnet, network, txn)
elif not subnet['enable_dhcp'] and ovn_subnet:
self._remove_subnet_dhcp_options(subnet['id'], txn)
elif subnet['enable_dhcp'] and ovn_subnet:
self._update_subnet_dhcp_options(subnet, network, txn)
if not txn:
with self._nb_idl.transaction(check_error=True) as txn_n:
txn_n.add(check_rev_cmd)
self._modify_subnet_dhcp_options(subnet, ovn_subnet, network,
txn_n)
else:
self._modify_subnet_dhcp_options(subnet, ovn_subnet, network, txn)
if check_rev_cmd.result == ovn_const.TXN_COMMITTED:
db_rev.bump_revision(subnet, ovn_const.TYPE_SUBNETS)

45
networking_ovn/tests/functional/test_mech_driver.py

@ -13,6 +13,7 @@
# under the License.
from networking_ovn.common import utils
from networking_ovn.db import revision as db_rev
from networking_ovn.tests.functional import base
from oslo_config import cfg
from oslo_utils import uuidutils
@ -129,3 +130,47 @@ class TestPortBindingOverTcp(TestPortBinding):
class TestPortBindingOverSsl(TestPortBinding):
def get_ovsdb_server_protocol(self):
return 'ssl'
class TestNetworkMTUUpdate(base.TestOVNFunctionalBase):
def setUp(self):
super(TestNetworkMTUUpdate, self).setUp()
self._ovn_client = self.mech_driver._ovn_client
self.n1 = self._make_network(self.fmt, 'n1', True)
res = self._create_subnet(self.fmt, self.n1['network']['id'],
'10.0.0.0/24')
self.sub = self.deserialize(self.fmt, res)
def test_update_network_mtu(self):
mtu_value = self.n1['network']['mtu'] - 100
dhcp_options = (
self.mech_driver._ovn_client._nb_idl.get_subnet_dhcp_options(
self.sub['subnet']['id'])
)
self.assertNotEqual(
int(dhcp_options['subnet']['options']['mtu']),
mtu_value)
data = {'network': {'mtu': mtu_value}}
req = self.new_update_request(
'networks', data, self.n1['network']['id'], self.fmt)
req.get_response(self.api)
dhcp_options = (
self.mech_driver._ovn_client._nb_idl.get_subnet_dhcp_options(
self.sub['subnet']['id'])
)
self.assertEqual(
int(dhcp_options['subnet']['options']['mtu']),
mtu_value)
def test_no_update_network_mtu(self):
mtu_value = self.n1['network']['mtu']
base_revision = db_rev.get_revision_row(self.sub['subnet']['id'])
data = {'network': {'mtu': mtu_value}}
req = self.new_update_request(
'networks', data, self.n1['network']['id'], self.fmt)
req.get_response(self.api)
second_revision = db_rev.get_revision_row(self.sub['subnet']['id'])
self.assertEqual(
base_revision.updated_at,
second_revision.updated_at)
Loading…
Cancel
Save