diff --git a/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/ovn_client.py b/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/ovn_client.py index b66d06f2879..64f71ea963a 100644 --- a/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/ovn_client.py +++ b/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/ovn_client.py @@ -1684,13 +1684,13 @@ class OVNClient: for net in networks) else 'false' return reside_redir_ch - def _gen_router_port_options(self, port): + def _gen_router_port_options(self, port, network_mtu=None): options = {} admin_context = n_context.get_admin_context() ls_name = utils.ovn_name(port['network_id']) ls = self._nb_idl.ls_get(ls_name).execute(check_error=True) network_type = ls.external_ids[ovn_const.OVN_NETTYPE_EXT_ID_KEY] - network_mtu = int( + network_mtu = network_mtu or int( ls.external_ids[ovn_const.OVN_NETWORK_MTU_EXT_ID_KEY]) # For provider networks (VLAN, FLAT types) we need to set the # "reside-on-redirect-chassis" option so the routing for this @@ -2131,7 +2131,8 @@ class OVNClient: commands = [] for port in ports: lrp_name = utils.ovn_lrouter_port_name(port['id']) - options = self._gen_router_port_options(port) + options = self._gen_router_port_options( + port, network_mtu=prov_net['mtu']) # Do not fail for cases where logical router port get deleted commands.append(self._nb_idl.lrp_set_options(lrp_name, if_exists=True, diff --git a/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovn_client.py b/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovn_client.py index 997b79ca845..94eca8ef13b 100644 --- a/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovn_client.py +++ b/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovn_client.py @@ -13,6 +13,7 @@ # under the License. from neutron_lib.api.definitions import external_net +from neutron_lib.api.definitions import network_mtu as mtu_def from neutron_lib.api.definitions import provider_net from neutron_lib import constants from oslo_config import cfg @@ -221,3 +222,49 @@ class TestOVNClient(base.TestOVNFunctionalBase, # Delete the address group ovn_client.delete_address_group(self.context, ag['id']) self.assertEqual((None, None), _find_address_set_for_ag()) + + def test_update_network_lrp_mtu_updated(self): + def check_gw_lrp_mtu(router_id, mtu): + # Find gateway LRP and check the MTU value. + lr = self.nb_api.lookup('Logical_Router', + ovn_utils.ovn_name(router_id)) + for lrp in lr.ports: + if strutils.bool_from_string( + lrp.external_ids[ + ovn_const.OVN_ROUTER_IS_EXT_GW]): + self.assertEqual(mtu, int(lrp.options['gateway_mtu'])) + return + + self.fail('Gateway Logical_Router_Port not found for ' + 'router %s' % router_id) + + self.add_fake_chassis('host1', enable_chassis_as_gw=True, azs=[]) + net_ext_args = {provider_net.NETWORK_TYPE: 'geneve', + external_net.EXTERNAL: True, + mtu_def.MTU: 1300} + net_int_args = {provider_net.NETWORK_TYPE: 'geneve', + mtu_def.MTU: 1400} + with self.network( + 'test-ext-net', as_admin=True, + arg_list=tuple(net_ext_args.keys()), **net_ext_args) as \ + net_ext, self.network( + 'test-int-net', as_admin=True, + arg_list=tuple(net_int_args.keys()), **net_int_args) as \ + net_int: + with self.subnet(net_ext, cidr='10.1.0.0/24'), \ + self.subnet(net_int, cidr='10.2.0.0/24') as snet_int: + ext_gw = {'network_id': net_ext['network']['id']} + with self.router(external_gateway_info=ext_gw) as router: + router_id = router['router']['id'] + self._router_interface_action( + 'add', router_id, snet_int['subnet']['id'], + None) + + check_gw_lrp_mtu(router_id, 1300) + + # Update external network MTU. + net_ext_args = {'network': {mtu_def.MTU: 1350}} + req = self.new_update_request('networks', net_ext_args, + net_ext['network']['id']) + req.get_response(self.api) + check_gw_lrp_mtu(router_id, 1350)