Merge "Make agent interface plugging utilize network MTU"
This commit is contained in:
commit
855aaee40d
|
@ -117,4 +117,5 @@ class DvrEdgeHaRouter(DvrEdgeRouter, HaRouter):
|
|||
self.driver.plug(port['network_id'], port['id'],
|
||||
interface_name, port['mac_address'],
|
||||
namespace=self.snat_namespace.name,
|
||||
prefix=dvr_snat_ns.SNAT_INT_DEV_PREFIX)
|
||||
prefix=dvr_snat_ns.SNAT_INT_DEV_PREFIX,
|
||||
mtu=port.get('mtu'))
|
||||
|
|
|
@ -104,7 +104,8 @@ class DvrEdgeRouter(dvr_local_router.DvrLocalRouter):
|
|||
sn_port['fixed_ips'],
|
||||
sn_port['mac_address'],
|
||||
interface_name,
|
||||
dvr_snat_ns.SNAT_INT_DEV_PREFIX)
|
||||
dvr_snat_ns.SNAT_INT_DEV_PREFIX,
|
||||
mtu=sn_port.get('mtu'))
|
||||
|
||||
def _dvr_internal_network_removed(self, port):
|
||||
super(DvrEdgeRouter, self)._dvr_internal_network_removed(port)
|
||||
|
@ -132,7 +133,8 @@ class DvrEdgeRouter(dvr_local_router.DvrLocalRouter):
|
|||
self.snat_namespace.name, port['network_id'],
|
||||
port['id'], port['fixed_ips'],
|
||||
port['mac_address'], interface_name,
|
||||
dvr_snat_ns.SNAT_INT_DEV_PREFIX)
|
||||
dvr_snat_ns.SNAT_INT_DEV_PREFIX,
|
||||
mtu=port.get('mtu'))
|
||||
|
||||
def _create_dvr_gateway(self, ex_gw_port, gw_interface_name):
|
||||
"""Create SNAT namespace."""
|
||||
|
|
|
@ -106,7 +106,8 @@ class FipNamespace(namespaces.Namespace):
|
|||
ex_gw_port['mac_address'],
|
||||
bridge=self.agent_conf.external_network_bridge,
|
||||
namespace=ns_name,
|
||||
prefix=FIP_EXT_DEV_PREFIX)
|
||||
prefix=FIP_EXT_DEV_PREFIX,
|
||||
mtu=ex_gw_port.get('mtu'))
|
||||
|
||||
ip_cidrs = common_utils.fixed_ip_cidrs(ex_gw_port['fixed_ips'])
|
||||
self.driver.init_l3(interface_name, ip_cidrs, namespace=ns_name,
|
||||
|
@ -257,9 +258,11 @@ class FipNamespace(namespaces.Namespace):
|
|||
self._internal_ns_interface_added(str(fip_2_rtr),
|
||||
fip_2_rtr_name,
|
||||
fip_ns_name)
|
||||
if self.agent_conf.network_device_mtu:
|
||||
int_dev[0].link.set_mtu(self.agent_conf.network_device_mtu)
|
||||
int_dev[1].link.set_mtu(self.agent_conf.network_device_mtu)
|
||||
mtu = (self.agent_conf.network_device_mtu or
|
||||
ri.get_ex_gw_port().get('mtu'))
|
||||
if mtu:
|
||||
int_dev[0].link.set_mtu(mtu)
|
||||
int_dev[1].link.set_mtu(mtu)
|
||||
int_dev[0].link.set_up()
|
||||
int_dev[1].link.set_up()
|
||||
|
||||
|
|
|
@ -144,7 +144,8 @@ class HaRouter(router.RouterInfo):
|
|||
interface_name,
|
||||
self.ha_port['mac_address'],
|
||||
namespace=self.ha_namespace,
|
||||
prefix=HA_DEV_PREFIX)
|
||||
prefix=HA_DEV_PREFIX,
|
||||
mtu=self.ha_port.get('mtu'))
|
||||
ip_cidrs = common_utils.fixed_ip_cidrs(self.ha_port['fixed_ips'])
|
||||
self.driver.init_l3(interface_name, ip_cidrs,
|
||||
namespace=self.ha_namespace,
|
||||
|
@ -268,13 +269,13 @@ class HaRouter(router.RouterInfo):
|
|||
def _plug_ha_router_port(self, port, name_getter, prefix):
|
||||
port_id = port['id']
|
||||
interface_name = name_getter(port_id)
|
||||
|
||||
self.driver.plug(port['network_id'],
|
||||
port_id,
|
||||
interface_name,
|
||||
port['mac_address'],
|
||||
namespace=self.ha_namespace,
|
||||
prefix=prefix)
|
||||
prefix=prefix,
|
||||
mtu=port.get('mtu'))
|
||||
|
||||
self._disable_ipv6_addressing_on_interface(interface_name)
|
||||
self._add_vips(port, interface_name)
|
||||
|
|
|
@ -361,12 +361,12 @@ class RouterInfo(object):
|
|||
|
||||
def _internal_network_added(self, ns_name, network_id, port_id,
|
||||
fixed_ips, mac_address,
|
||||
interface_name, prefix):
|
||||
interface_name, prefix, mtu=None):
|
||||
LOG.debug("adding internal network: prefix(%s), port(%s)",
|
||||
prefix, port_id)
|
||||
self.driver.plug(network_id, port_id, interface_name, mac_address,
|
||||
namespace=ns_name,
|
||||
prefix=prefix)
|
||||
prefix=prefix, mtu=mtu)
|
||||
|
||||
ip_cidrs = common_utils.fixed_ip_cidrs(fixed_ips)
|
||||
self.driver.init_router_port(
|
||||
|
@ -391,7 +391,8 @@ class RouterInfo(object):
|
|||
fixed_ips,
|
||||
mac_address,
|
||||
interface_name,
|
||||
INTERNAL_DEV_PREFIX)
|
||||
INTERNAL_DEV_PREFIX,
|
||||
mtu=port.get('mtu'))
|
||||
|
||||
def internal_network_removed(self, port):
|
||||
interface_name = self.get_internal_device_name(port['id'])
|
||||
|
@ -557,7 +558,8 @@ class RouterInfo(object):
|
|||
ex_gw_port['mac_address'],
|
||||
bridge=self.agent_conf.external_network_bridge,
|
||||
namespace=ns_name,
|
||||
prefix=EXTERNAL_DEV_PREFIX)
|
||||
prefix=EXTERNAL_DEV_PREFIX,
|
||||
mtu=ex_gw_port.get('mtu'))
|
||||
|
||||
def _get_external_gw_ips(self, ex_gw_port):
|
||||
gateway_ips = []
|
||||
|
|
|
@ -1230,7 +1230,8 @@ class DeviceManager(object):
|
|||
port.id,
|
||||
interface_name,
|
||||
port.mac_address,
|
||||
namespace=network.namespace)
|
||||
namespace=network.namespace,
|
||||
mtu=network.get('mtu'))
|
||||
except Exception:
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.exception(_LE('Unable to plug DHCP port for '
|
||||
|
|
|
@ -20,7 +20,7 @@ from oslo_config import cfg
|
|||
from oslo_log import log as logging
|
||||
import six
|
||||
|
||||
from neutron._i18n import _, _LE, _LI
|
||||
from neutron._i18n import _, _LE, _LI, _LW
|
||||
from neutron.agent.common import ovs_lib
|
||||
from neutron.agent.linux import ip_lib
|
||||
from neutron.agent.linux import utils
|
||||
|
@ -237,15 +237,15 @@ class LinuxInterfaceDriver(object):
|
|||
|
||||
@abc.abstractmethod
|
||||
def plug_new(self, network_id, port_id, device_name, mac_address,
|
||||
bridge=None, namespace=None, prefix=None):
|
||||
bridge=None, namespace=None, prefix=None, mtu=None):
|
||||
"""Plug in the interface only for new devices that don't exist yet."""
|
||||
|
||||
def plug(self, network_id, port_id, device_name, mac_address,
|
||||
bridge=None, namespace=None, prefix=None):
|
||||
bridge=None, namespace=None, prefix=None, mtu=None):
|
||||
if not ip_lib.device_exists(device_name,
|
||||
namespace=namespace):
|
||||
self.plug_new(network_id, port_id, device_name, mac_address,
|
||||
bridge, namespace, prefix)
|
||||
bridge, namespace, prefix, mtu)
|
||||
else:
|
||||
LOG.info(_LI("Device %s already exists"), device_name)
|
||||
|
||||
|
@ -273,7 +273,7 @@ class LinuxInterfaceDriver(object):
|
|||
|
||||
class NullDriver(LinuxInterfaceDriver):
|
||||
def plug_new(self, network_id, port_id, device_name, mac_address,
|
||||
bridge=None, namespace=None, prefix=None):
|
||||
bridge=None, namespace=None, prefix=None, mtu=None):
|
||||
pass
|
||||
|
||||
def unplug(self, device_name, bridge=None, namespace=None, prefix=None):
|
||||
|
@ -308,7 +308,7 @@ class OVSInterfaceDriver(LinuxInterfaceDriver):
|
|||
ovs.replace_port(device_name, *attrs)
|
||||
|
||||
def plug_new(self, network_id, port_id, device_name, mac_address,
|
||||
bridge=None, namespace=None, prefix=None):
|
||||
bridge=None, namespace=None, prefix=None, mtu=None):
|
||||
"""Plug in the interface."""
|
||||
if not bridge:
|
||||
bridge = self.conf.ovs_integration_bridge
|
||||
|
@ -333,11 +333,13 @@ class OVSInterfaceDriver(LinuxInterfaceDriver):
|
|||
|
||||
ns_dev.link.set_address(mac_address)
|
||||
|
||||
if self.conf.network_device_mtu:
|
||||
ns_dev.link.set_mtu(self.conf.network_device_mtu)
|
||||
mtu = self.conf.network_device_mtu or mtu
|
||||
if mtu:
|
||||
ns_dev.link.set_mtu(mtu)
|
||||
if self.conf.ovs_use_veth:
|
||||
root_dev.link.set_mtu(self.conf.network_device_mtu)
|
||||
|
||||
root_dev.link.set_mtu(mtu)
|
||||
else:
|
||||
LOG.warning(_LW("No MTU configured for port %s"), port_id)
|
||||
# Add an interface created by ovs to the namespace.
|
||||
if not self.conf.ovs_use_veth and namespace:
|
||||
namespace_obj = ip.ensure_namespace(namespace)
|
||||
|
@ -386,7 +388,7 @@ class IVSInterfaceDriver(LinuxInterfaceDriver):
|
|||
utils.execute(cmd, run_as_root=True)
|
||||
|
||||
def plug_new(self, network_id, port_id, device_name, mac_address,
|
||||
bridge=None, namespace=None, prefix=None):
|
||||
bridge=None, namespace=None, prefix=None, mtu=None):
|
||||
"""Plug in the interface."""
|
||||
ip = ip_lib.IPWrapper()
|
||||
tap_name = self._get_tap_name(device_name, prefix)
|
||||
|
@ -399,9 +401,12 @@ class IVSInterfaceDriver(LinuxInterfaceDriver):
|
|||
ns_dev = ip.device(device_name)
|
||||
ns_dev.link.set_address(mac_address)
|
||||
|
||||
if self.conf.network_device_mtu:
|
||||
ns_dev.link.set_mtu(self.conf.network_device_mtu)
|
||||
root_dev.link.set_mtu(self.conf.network_device_mtu)
|
||||
mtu = self.conf.network_device_mtu or mtu
|
||||
if mtu:
|
||||
ns_dev.link.set_mtu(mtu)
|
||||
root_dev.link.set_mtu(mtu)
|
||||
else:
|
||||
LOG.warning(_LW("No MTU configured for port %s"), port_id)
|
||||
|
||||
if namespace:
|
||||
namespace_obj = ip.ensure_namespace(namespace)
|
||||
|
@ -430,7 +435,7 @@ class BridgeInterfaceDriver(LinuxInterfaceDriver):
|
|||
DEV_NAME_PREFIX = 'ns-'
|
||||
|
||||
def plug_new(self, network_id, port_id, device_name, mac_address,
|
||||
bridge=None, namespace=None, prefix=None):
|
||||
bridge=None, namespace=None, prefix=None, mtu=None):
|
||||
"""Plugin the interface."""
|
||||
ip = ip_lib.IPWrapper()
|
||||
|
||||
|
@ -443,9 +448,12 @@ class BridgeInterfaceDriver(LinuxInterfaceDriver):
|
|||
root_veth.disable_ipv6()
|
||||
ns_veth.link.set_address(mac_address)
|
||||
|
||||
if self.conf.network_device_mtu:
|
||||
root_veth.link.set_mtu(self.conf.network_device_mtu)
|
||||
ns_veth.link.set_mtu(self.conf.network_device_mtu)
|
||||
mtu = self.conf.network_device_mtu or mtu
|
||||
if mtu:
|
||||
root_veth.link.set_mtu(mtu)
|
||||
ns_veth.link.set_mtu(mtu)
|
||||
else:
|
||||
LOG.warning(_LW("No MTU configured for port %s"), port_id)
|
||||
|
||||
root_veth.link.set_up()
|
||||
ns_veth.link.set_up()
|
||||
|
|
|
@ -50,6 +50,10 @@ class TestDvrRouter(framework.L3AgentTestFramework):
|
|||
self.agent.conf.agent_mode = 'dvr'
|
||||
self._test_update_floatingip_statuses(self.generate_dvr_router_info())
|
||||
|
||||
def test_dvr_router_lifecycle_ha_with_snat_with_fips_nmtu(self):
|
||||
self._dvr_router_lifecycle(enable_ha=True, enable_snat=True,
|
||||
use_port_mtu=True)
|
||||
|
||||
def test_dvr_router_lifecycle_without_ha_without_snat_with_fips(self):
|
||||
self._dvr_router_lifecycle(enable_ha=False, enable_snat=False)
|
||||
|
||||
|
@ -100,7 +104,7 @@ class TestDvrRouter(framework.L3AgentTestFramework):
|
|||
self._validate_fips_for_external_network(router2, fip2_ns)
|
||||
|
||||
def _dvr_router_lifecycle(self, enable_ha=False, enable_snat=False,
|
||||
custom_mtu=2000,
|
||||
custom_mtu=2000, use_port_mtu=False,
|
||||
ip_version=4,
|
||||
dual_stack=False):
|
||||
'''Test dvr router lifecycle
|
||||
|
@ -114,11 +118,19 @@ class TestDvrRouter(framework.L3AgentTestFramework):
|
|||
# Since by definition this is a dvr (distributed = true)
|
||||
# only dvr and dvr_snat are applicable
|
||||
self.agent.conf.agent_mode = 'dvr_snat' if enable_snat else 'dvr'
|
||||
self.agent.conf.network_device_mtu = custom_mtu
|
||||
|
||||
# We get the router info particular to a dvr router
|
||||
router_info = self.generate_dvr_router_info(
|
||||
enable_ha, enable_snat, extra_routes=True)
|
||||
if use_port_mtu:
|
||||
for key in ('_interfaces', '_snat_router_interfaces',
|
||||
'_floatingip_agent_interfaces'):
|
||||
for port in router_info[key]:
|
||||
port['mtu'] = custom_mtu
|
||||
router_info['gw_port']['mtu'] = custom_mtu
|
||||
router_info['_ha_interface']['mtu'] = custom_mtu
|
||||
else:
|
||||
self.agent.conf.network_device_mtu = custom_mtu
|
||||
|
||||
# We need to mock the get_agent_gateway_port return value
|
||||
# because the whole L3PluginApi is mocked and we need the port
|
||||
|
@ -155,6 +167,9 @@ class TestDvrRouter(framework.L3AgentTestFramework):
|
|||
router.get_internal_device_name,
|
||||
router.ns_name)
|
||||
utils.wait_until_true(device_exists)
|
||||
name = router.get_internal_device_name(device['id'])
|
||||
self.assertEqual(custom_mtu,
|
||||
ip_lib.IPDevice(name, router.ns_name).link.mtu)
|
||||
|
||||
ext_gateway_port = router_info['gw_port']
|
||||
self.assertTrue(self._namespace_exists(router.ns_name))
|
||||
|
|
|
@ -253,6 +253,15 @@ class DHCPAgentOVSTestCase(DHCPAgentOVSTestFramework):
|
|||
dhcp_enabled=dhcp_enabled)
|
||||
self.assert_dhcp_resources(network, dhcp_enabled)
|
||||
|
||||
def test_agent_mtu_set_on_interface_driver(self):
|
||||
network = self.network_dict_for_dhcp()
|
||||
network["mtu"] = 789
|
||||
self.configure_dhcp_for_network(network=network)
|
||||
port = network.ports[0]
|
||||
iface_name = self.get_interface_name(network, port)
|
||||
dev = ip_lib.IPDevice(iface_name, network.namespace)
|
||||
self.assertEqual(789, dev.link.mtu)
|
||||
|
||||
def test_good_address_allocation(self):
|
||||
network, port = self._get_network_port_for_allocation_test()
|
||||
network.ports.append(port)
|
||||
|
|
|
@ -1309,7 +1309,8 @@ class TestDeviceManager(base.BaseTestCase):
|
|||
port.id,
|
||||
'tap12345678-12',
|
||||
'aa:bb:cc:dd:ee:ff',
|
||||
namespace=net.namespace))
|
||||
namespace=net.namespace,
|
||||
mtu=None))
|
||||
self.mock_driver.assert_has_calls(expected)
|
||||
|
||||
dh._set_default_route.assert_called_once_with(net, 'tap12345678-12')
|
||||
|
|
|
@ -390,7 +390,8 @@ class TestBasicRouterOperations(BasicRouterOperationsFramework):
|
|||
sn_port['fixed_ips'],
|
||||
sn_port['mac_address'],
|
||||
ri._get_snat_int_device_name(sn_port['id']),
|
||||
dvr_snat_ns.SNAT_INT_DEV_PREFIX)
|
||||
dvr_snat_ns.SNAT_INT_DEV_PREFIX,
|
||||
mtu=None)
|
||||
elif action == 'remove':
|
||||
self.device_exists.return_value = False
|
||||
ri.get_snat_port_for_internal_port = mock.Mock(
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
---
|
||||
features:
|
||||
- Use the value of the network 'mtu' attribute for the MTU
|
||||
of virtual network interfaces such as veth pairs, patch
|
||||
ports, and tap devices involving a particular network.
|
||||
- Enable end-to-end support for arbitrary MTUs including
|
||||
jumbo frames between instances and provider networks by
|
||||
moving MTU disparities between flat or VLAN networks and
|
||||
overlay networks from layer-2 devices to layer-3 devices
|
||||
that support path MTU discovery (PMTUD).
|
||||
upgrade:
|
||||
- Does not change MTU for existing virtual network interfaces.
|
||||
- Actions that create virtual network interfaces on an existing
|
||||
network with the 'mtu' attribute containing a value greater
|
||||
than zero could cause issues for network traffic traversing
|
||||
existing and new virtual network interfaces.
|
||||
fixes:
|
||||
- Explicitly configure MTU of virtual network interfaces
|
||||
rather than using default values or incorrect values that
|
||||
do not account for overlay protocol overhead.
|
Loading…
Reference in New Issue