diff --git a/etc/neutron/plugins/openvswitch/ovs_neutron_plugin.ini b/etc/neutron/plugins/openvswitch/ovs_neutron_plugin.ini index e20f606fca8..48442db5213 100644 --- a/etc/neutron/plugins/openvswitch/ovs_neutron_plugin.ini +++ b/etc/neutron/plugins/openvswitch/ovs_neutron_plugin.ini @@ -107,6 +107,12 @@ # vxlan_udp_port = # Example: vxlan_udp_port = 8472 +# (IntOpt) This is the MTU size of veth interfaces. +# Do not change unless you have a good reason to. +# The default MTU size of veth interfaces is 1500. +# veth_mtu = +# Example: veth_mtu = 1504 + [securitygroup] # Firewall driver for realizing neutron security group function. # firewall_driver = neutron.agent.firewall.NoopFirewallDriver diff --git a/neutron/plugins/openvswitch/agent/ovs_neutron_agent.py b/neutron/plugins/openvswitch/agent/ovs_neutron_agent.py index 4c2d31da369..72bb80153ad 100644 --- a/neutron/plugins/openvswitch/agent/ovs_neutron_agent.py +++ b/neutron/plugins/openvswitch/agent/ovs_neutron_agent.py @@ -150,7 +150,8 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin): def __init__(self, integ_br, tun_br, local_ip, bridge_mappings, root_helper, - polling_interval, tunnel_types=None): + polling_interval, tunnel_types=None, + veth_mtu=None): '''Constructor. :param integ_br: name of the integration bridge. @@ -162,7 +163,9 @@ def __init__(self, integ_br, tun_br, local_ip, :param tunnel_types: A list of tunnel types to enable support for in the agent. If set, will automatically set enable_tunneling to True. + :param veth_mtu: MTU size for veth interfaces. ''' + self.veth_mtu = veth_mtu self.root_helper = root_helper self.available_local_vlans = set(xrange(q_const.MIN_VLAN_TAG, q_const.MAX_VLAN_TAG)) @@ -615,6 +618,11 @@ def setup_physical_bridges(self, bridge_mappings): int_veth.link.set_up() phys_veth.link.set_up() + if self.veth_mtu: + # set up mtu size for veth interfaces + int_veth.link.set_mtu(self.veth_mtu) + phys_veth.link.set_mtu(self.veth_mtu) + def update_ports(self, registered_ports): ports = self.int_br.get_vif_port_set() if ports == registered_ports: @@ -825,6 +833,7 @@ def create_agent_config_map(config): root_helper=config.AGENT.root_helper, polling_interval=config.AGENT.polling_interval, tunnel_types=config.AGENT.tunnel_types, + veth_mtu=config.AGENT.veth_mtu, ) # If enable_tunneling is TRUE, set tunnel_type to default to GRE diff --git a/neutron/plugins/openvswitch/common/config.py b/neutron/plugins/openvswitch/common/config.py index 69a7a7f412c..76e522f4fba 100644 --- a/neutron/plugins/openvswitch/common/config.py +++ b/neutron/plugins/openvswitch/common/config.py @@ -67,6 +67,8 @@ "(gre and/or vxlan)")), cfg.IntOpt('vxlan_udp_port', default=constants.VXLAN_UDP_PORT, help=_("The UDP port to use for VXLAN tunnels.")), + cfg.IntOpt('veth_mtu', default=None, + help=_("MTU size of veth interfaces")), ] diff --git a/neutron/tests/unit/openvswitch/test_ovs_neutron_agent.py b/neutron/tests/unit/openvswitch/test_ovs_neutron_agent.py index 33ad6b26b7c..f90cea843aa 100644 --- a/neutron/tests/unit/openvswitch/test_ovs_neutron_agent.py +++ b/neutron/tests/unit/openvswitch/test_ovs_neutron_agent.py @@ -311,10 +311,11 @@ def test_setup_physical_bridges(self): mock.patch.object(self.agent.int_br, "delete_port"), mock.patch.object(ip_lib.IPWrapper, "add_veth"), mock.patch.object(ip_lib.IpLinkCommand, "delete"), - mock.patch.object(ip_lib.IpLinkCommand, "set_up") + mock.patch.object(ip_lib.IpLinkCommand, "set_up"), + mock.patch.object(ip_lib.IpLinkCommand, "set_mtu") ) as (devex_fn, sysexit_fn, remflows_fn, ovs_addfl_fn, ovs_addport_fn, ovs_delport_fn, br_addport_fn, - br_delport_fn, addveth_fn, linkdel_fn, linkset_fn): + br_delport_fn, addveth_fn, linkdel_fn, linkset_fn, linkmtu_fn): devex_fn.return_value = True addveth_fn.return_value = (ip_lib.IPDevice("int-br-eth1"), ip_lib.IPDevice("phy-br-eth1")) diff --git a/neutron/tests/unit/openvswitch/test_ovs_tunnel.py b/neutron/tests/unit/openvswitch/test_ovs_tunnel.py index b1186e3301b..bf3ed41bfe8 100644 --- a/neutron/tests/unit/openvswitch/test_ovs_tunnel.py +++ b/neutron/tests/unit/openvswitch/test_ovs_tunnel.py @@ -74,6 +74,7 @@ def setUp(self): self.INT_OFPORT = 11111 self.TUN_OFPORT = 22222 self.MAP_TUN_OFPORT = 33333 + self.VETH_MTU = None self.inta = self.mox.CreateMock(ip_lib.IPDevice) self.intb = self.mox.CreateMock(ip_lib.IPDevice) self.inta.link = self.mox.CreateMock(ip_lib.IpLinkCommand) @@ -129,7 +130,8 @@ def testConstruct(self): ovs_neutron_agent.OVSNeutronAgent(self.INT_BRIDGE, self.TUN_BRIDGE, '10.0.0.1', self.NET_MAPPING, - 'sudo', 2, ['gre']) + 'sudo', 2, ['gre'], + self.VETH_MTU) self.mox.VerifyAll() def testConstructVXLAN(self): @@ -141,7 +143,8 @@ def testConstructVXLAN(self): ovs_neutron_agent.OVSNeutronAgent(self.INT_BRIDGE, self.TUN_BRIDGE, '10.0.0.1', self.NET_MAPPING, - 'sudo', 2, ['vxlan']) + 'sudo', 2, ['vxlan'], + self.VETH_MTU) self.mox.VerifyAll() def testProvisionLocalVlan(self): @@ -158,7 +161,8 @@ def testProvisionLocalVlan(self): a = ovs_neutron_agent.OVSNeutronAgent(self.INT_BRIDGE, self.TUN_BRIDGE, '10.0.0.1', self.NET_MAPPING, - 'sudo', 2, ['gre']) + 'sudo', 2, ['gre'], + self.VETH_MTU) a.available_local_vlans = set([LV_ID]) a.provision_local_vlan(NET_UUID, constants.TYPE_GRE, None, LS_ID) self.mox.VerifyAll() @@ -178,7 +182,8 @@ def testProvisionLocalVlanFlat(self): a = ovs_neutron_agent.OVSNeutronAgent(self.INT_BRIDGE, self.TUN_BRIDGE, '10.0.0.1', self.NET_MAPPING, - 'sudo', 2, ['gre']) + 'sudo', 2, ['gre'], + self.VETH_MTU) a.available_local_vlans = set([LV_ID]) a.phys_brs['net1'] = self.mock_map_tun_bridge a.phys_ofports['net1'] = self.MAP_TUN_OFPORT @@ -191,7 +196,8 @@ def testProvisionLocalVlanFlatFail(self): a = ovs_neutron_agent.OVSNeutronAgent(self.INT_BRIDGE, self.TUN_BRIDGE, '10.0.0.1', self.NET_MAPPING, - 'sudo', 2, ['gre']) + 'sudo', 2, ['gre'], + self.VETH_MTU) a.provision_local_vlan(NET_UUID, constants.TYPE_FLAT, 'net2', LS_ID) self.mox.VerifyAll() @@ -209,7 +215,8 @@ def testProvisionLocalVlanVlan(self): a = ovs_neutron_agent.OVSNeutronAgent(self.INT_BRIDGE, self.TUN_BRIDGE, '10.0.0.1', self.NET_MAPPING, - 'sudo', 2, ['gre']) + 'sudo', 2, ['gre'], + self.VETH_MTU) a.available_local_vlans = set([LV_ID]) a.phys_brs['net1'] = self.mock_map_tun_bridge a.phys_ofports['net1'] = self.MAP_TUN_OFPORT @@ -222,7 +229,8 @@ def testProvisionLocalVlanVlanFail(self): a = ovs_neutron_agent.OVSNeutronAgent(self.INT_BRIDGE, self.TUN_BRIDGE, '10.0.0.1', self.NET_MAPPING, - 'sudo', 2, ['gre']) + 'sudo', 2, ['gre'], + self.VETH_MTU) a.provision_local_vlan(NET_UUID, constants.TYPE_VLAN, 'net2', LS_ID) self.mox.VerifyAll() @@ -235,7 +243,8 @@ def testReclaimLocalVlan(self): a = ovs_neutron_agent.OVSNeutronAgent(self.INT_BRIDGE, self.TUN_BRIDGE, '10.0.0.1', self.NET_MAPPING, - 'sudo', 2, ['gre']) + 'sudo', 2, ['gre'], + self.VETH_MTU) a.available_local_vlans = set() a.local_vlan_map[NET_UUID] = LVM a.reclaim_local_vlan(NET_UUID, LVM) @@ -253,7 +262,8 @@ def testReclaimLocalVlanFlat(self): a = ovs_neutron_agent.OVSNeutronAgent(self.INT_BRIDGE, self.TUN_BRIDGE, '10.0.0.1', self.NET_MAPPING, - 'sudo', 2, ['gre']) + 'sudo', 2, ['gre'], + self.VETH_MTU) a.phys_brs['net1'] = self.mock_map_tun_bridge a.phys_ofports['net1'] = self.MAP_TUN_OFPORT a.int_ofports['net1'] = self.INT_OFPORT @@ -275,7 +285,8 @@ def testReclaimLocalVlanVLAN(self): a = ovs_neutron_agent.OVSNeutronAgent(self.INT_BRIDGE, self.TUN_BRIDGE, '10.0.0.1', self.NET_MAPPING, - 'sudo', 2, ['gre']) + 'sudo', 2, ['gre'], + self.VETH_MTU) a.phys_brs['net1'] = self.mock_map_tun_bridge a.phys_ofports['net1'] = self.MAP_TUN_OFPORT a.int_ofports['net1'] = self.INT_OFPORT @@ -300,7 +311,8 @@ def testPortBound(self): a = ovs_neutron_agent.OVSNeutronAgent(self.INT_BRIDGE, self.TUN_BRIDGE, '10.0.0.1', self.NET_MAPPING, - 'sudo', 2, ['gre']) + 'sudo', 2, ['gre'], + self.VETH_MTU) a.local_vlan_map[NET_UUID] = LVM a.port_bound(VIF_PORT, NET_UUID, 'gre', None, LS_ID) self.mox.VerifyAll() @@ -320,7 +332,8 @@ def testPortUnbound(self): a = ovs_neutron_agent.OVSNeutronAgent(self.INT_BRIDGE, self.TUN_BRIDGE, '10.0.0.1', self.NET_MAPPING, - 'sudo', 2, ['gre']) + 'sudo', 2, ['gre'], + self.VETH_MTU) a.local_vlan_map[NET_UUID] = LVM a.port_bound(VIF_PORT, NET_UUID, 'gre', None, LS_ID) a.available_local_vlans = set([LV_ID]) @@ -339,7 +352,8 @@ def testPortDead(self): a = ovs_neutron_agent.OVSNeutronAgent(self.INT_BRIDGE, self.TUN_BRIDGE, '10.0.0.1', self.NET_MAPPING, - 'sudo', 2, ['gre']) + 'sudo', 2, ['gre'], + self.VETH_MTU) a.available_local_vlans = set([LV_ID]) a.local_vlan_map[NET_UUID] = LVM a.port_dead(VIF_PORT) @@ -352,7 +366,8 @@ def testTunnelUpdate(self): a = ovs_neutron_agent.OVSNeutronAgent(self.INT_BRIDGE, self.TUN_BRIDGE, '10.0.0.1', self.NET_MAPPING, - 'sudo', 2, ['gre']) + 'sudo', 2, ['gre'], + self.VETH_MTU) a.tunnel_update( mox.MockAnything, tunnel_id='1', tunnel_ip='10.0.10.1', tunnel_type=constants.TYPE_GRE) @@ -363,7 +378,8 @@ def testTunnelUpdateSelf(self): a = ovs_neutron_agent.OVSNeutronAgent(self.INT_BRIDGE, self.TUN_BRIDGE, '10.0.0.1', self.NET_MAPPING, - 'sudo', 2, ['gre']) + 'sudo', 2, ['gre'], + self.VETH_MTU) a.tunnel_update( mox.MockAnything, tunnel_id='1', tunnel_ip='10.0.0.1') self.mox.VerifyAll() @@ -403,7 +419,8 @@ def testDaemonLoop(self): self.TUN_BRIDGE, '10.0.0.1', self.NET_MAPPING, - 'sudo', 2, ['gre']) + 'sudo', 2, ['gre'], + self.VETH_MTU) # Hack to test loop # We start method and expect it will raise after 2nd loop @@ -414,3 +431,12 @@ def testDaemonLoop(self): pass self.mox.VerifyAll() + + +class TunnelTestWithMTU(TunnelTest): + + def setUp(self): + super(TunnelTestWithMTU, self).setUp() + self.VETH_MTU = 1500 + self.inta.link.set_mtu(self.VETH_MTU) + self.intb.link.set_mtu(self.VETH_MTU)