Browse Source

[OVN] Fix gateway_mtu option should not always be set

OVN Driver currently fixes gateway_mtu MTU to the provider MTU value
without considering if the private networks in the associated router
have greater MTU values than the provider. This is unnecesary and
adds extra actions for each packet. This patch fixes that, as now
gateway_mtu is only set in case the provider MTU is smaller than the
private MTU.

The changes in create_router_port and delete_router_port were necessary
as there could be a use case when the user first sets the gateway
router and later adds subnets from networks with greater MTU, so this
parameter needs to be checked after adding a subnet.

Closes-Bug: #1951559

Signed-off-by: Elvira García <egarciar@redhat.com>
(manually cherry-picked from commit 0725533a6fa6a42d361e518b027f69da8e1e1ec5)
Change-Id: I710723682e2b59c24d0ca1ef9f582c73c3c5af87
changes/55/819655/1
Elvira García 6 months ago
parent
commit
933c1ba7eb
  1. 26
      networking_ovn/common/ovn_client.py
  2. 18
      networking_ovn/tests/unit/l3/test_l3_ovn.py
  3. 7
      networking_ovn/tests/unit/ml2/test_mech_driver.py

26
networking_ovn/common/ovn_client.py

@ -1374,8 +1374,9 @@ class OVNClient(object):
def _gen_router_port_options(self, port, network=None):
options = {}
admin_context = n_context.get_admin_context()
if network is None:
network = self._plugin.get_network(n_context.get_admin_context(),
network = self._plugin.get_network(admin_context,
port['network_id'])
# For VLAN type networks we need to set the
# "reside-on-redirect-chassis" option so the routing for this
@ -1388,9 +1389,15 @@ class OVNClient(object):
is_gw_port = const.DEVICE_OWNER_ROUTER_GW == port.get(
'device_owner')
if is_gw_port and config.is_ovn_emit_need_to_frag_enabled():
options[ovn_const.OVN_ROUTER_PORT_GW_MTU_OPTION] = str(
network['mtu'])
network_ids = set([port['network_id'] for port in
self._get_router_ports(admin_context,
port['device_id'])])
for net in self._plugin.get_networks(admin_context,
filters={'id': network_ids}):
if net['mtu'] > network['mtu']:
options[ovn_const.OVN_ROUTER_PORT_GW_MTU_OPTION] = str(
network['mtu'])
break
return options
def _create_lrouter_port(self, router, port, txn=None):
@ -1463,6 +1470,11 @@ class OVNClient(object):
if subnet['ip_version'] == 4:
cidr = subnet['cidr']
if config.is_ovn_emit_need_to_frag_enabled():
provider_net = self._plugin.get_network(context,
router[l3.EXTERNAL_GW_INFO]['network_id'])
self.set_gateway_mtu(context, provider_net)
if utils.is_snat_enabled(router) and cidr:
self.update_nat_rules(router, networks=[cidr],
enable_snat=True, txn=txn)
@ -1560,6 +1572,12 @@ class OVNClient(object):
elif port:
subnet_ids = utils.get_port_subnet_ids(port)
if (config.is_ovn_emit_need_to_frag_enabled() and
router.get('gw_port_id')):
provider_net = self._plugin.get_network(context,
router[l3.EXTERNAL_GW_INFO]['network_id'])
self.set_gateway_mtu(context, provider_net, txn=txn)
cidr = None
for sid in subnet_ids:
try:

18
networking_ovn/tests/unit/l3/test_l3_ovn.py

@ -1492,27 +1492,33 @@ class OVNL3RouterPlugin(test_mech_driver.OVNMechanismDriverTestCase):
self.nb_idl().get_unhosted_gateways.assert_called_once_with(
{'foo-1': 'physnet1'}, mock.ANY, mock.ANY)
@mock.patch('neutron.db.db_base_plugin_v2.NeutronDbPluginV2.get_network')
@mock.patch('neutron.plugins.ml2.plugin.Ml2Plugin.get_network')
@mock.patch('neutron.plugins.ml2.plugin.Ml2Plugin.get_networks')
@mock.patch('neutron.db.db_base_plugin_v2.NeutronDbPluginV2.get_port')
@mock.patch('neutron.db.db_base_plugin_v2.NeutronDbPluginV2.get_subnet')
@mock.patch('networking_ovn.common.ovn_client.OVNClient._get_router_ports')
@mock.patch('neutron.db.l3_db.L3_NAT_dbonly_mixin.get_router')
@mock.patch('neutron.db.l3_db.L3_NAT_dbonly_mixin.add_router_interface')
def test_add_router_interface_need_to_frag_enabled(self, ari, gr, grps,
gs, gp, gn):
gs, gp, gns, gn):
config.cfg.CONF.set_override(
'ovn_emit_need_to_frag', True, group='ovn')
router_id = 'router-id'
interface_info = {'port_id': 'router-port-id'}
interface_info = {'port_id': 'router-port-id',
'network_id': 'priv_net'}
ari.return_value = self.fake_router_interface_info
gr.return_value = self.fake_router_with_ext_gw
gs.return_value = self.fake_subnet
gn.return_value = self.fake_network
network_attrs = {external_net.EXTERNAL: True, 'mtu': 1200}
prov_net = fakes.FakeNetwork.create_one_network(
attrs=network_attrs).info()
gn.return_value = prov_net
grps.return_value = [interface_info]
self.fake_router_port['device_owner'] = (
constants.DEVICE_OWNER_ROUTER_GW)
gp.return_value = self.fake_router_port
gns.return_value = [self.fake_network]
self.l3_inst.add_router_interface(self.context, router_id,
interface_info)
@ -1521,7 +1527,7 @@ class OVNL3RouterPlugin(test_mech_driver.OVNMechanismDriverTestCase):
fake_router_port_assert['gateway_chassis'] = mock.ANY
fake_router_port_assert['options'] = {
ovn_const.OVN_ROUTER_PORT_GW_MTU_OPTION:
str(self.fake_network['mtu'])}
str(prov_net['mtu'])}
self.l3_inst._ovn.add_lrouter_port.assert_called_once_with(
**fake_router_port_assert)

7
networking_ovn/tests/unit/ml2/test_mech_driver.py

@ -1798,7 +1798,8 @@ class TestOVNMechanismDriver(test_plugin.Ml2PluginV2TestCase):
def test__update_dnat_entry_if_needed_down(self):
self._test__update_dnat_entry_if_needed(up=False)
def _test_update_network_fragmentation(self, new_mtu, expected_opts):
@mock.patch.object(ovn_client.OVNClient, '_get_router_ports')
def _test_update_network_fragmentation(self, new_mtu, expected_opts, grps):
network_attrs = {external_net.EXTERNAL: True}
network = self._make_network(
self.fmt, 'net1', True, arg_list=(external_net.EXTERNAL,),
@ -1807,6 +1808,10 @@ class TestOVNMechanismDriver(test_plugin.Ml2PluginV2TestCase):
with self.subnet(network=network) as subnet:
with self.port(subnet=subnet,
device_owner=const.DEVICE_OWNER_ROUTER_GW) as port:
grps.return_value = [{'port_id': port['port']['id'],
'network_id':network['network']['id']}]
# Let's update the MTU to something different
network['network']['mtu'] = new_mtu
fake_ctx = mock.Mock(current=network['network'])

Loading…
Cancel
Save