Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
introduces MTU support for vhost-user
- This change introduces the ability
  to set the MTU for vhost-user interface
  if supported by ovs.
- This change leverages the mtu_request
  option added to the ovs interface in ovs 2.6.
- MTU support enable the use of jumbo frames
  with vhost-user interfaces.

Change-Id: Ide3435b74809605692fa6153c3be3294db80182f
  • Loading branch information
Sean Mooney committed Jan 9, 2017
1 parent 01da454 commit 9a14c18
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 14 deletions.
10 changes: 10 additions & 0 deletions releasenotes/notes/vhost-user-mtu-support-cbc7d02a6665fab1.yaml
@@ -0,0 +1,10 @@
---
features:
- In the ocata cycle support was added for setting
the MTU of vhost-user port with ovs.
- vhost-user MTU support enable jumbo frames to
be used with vhost-user interfaces.
other:
- vhost-user MTU support requires ovs 2.6 or newer.
On older versions of ovs, the MTU request will
not be made and jumbo frames are not supported.
38 changes: 29 additions & 9 deletions vif_plug_ovs/linux_net.py
Expand Up @@ -75,12 +75,12 @@ def create_ovs_vif_port(bridge, dev, iface_id, mac, instance_id,
_ovs_vsctl(_create_ovs_vif_cmd(bridge, dev, iface_id,
mac, instance_id, interface_type,
vhost_server_path), timeout=timeout)
_update_device_mtu(dev, mtu, interface_type)
_update_device_mtu(dev, mtu, interface_type, timeout=timeout)


@privsep.vif_plug.entrypoint
def update_ovs_vif_port(dev, mtu=None, interface_type=None):
_update_device_mtu(dev, mtu, interface_type)
def update_ovs_vif_port(dev, mtu=None, interface_type=None, timeout=None):
_update_device_mtu(dev, mtu, interface_type, timeout=timeout)


@privsep.vif_plug.entrypoint
Expand Down Expand Up @@ -168,21 +168,41 @@ def add_bridge_port(bridge, dev):
processutils.execute('brctl', 'addif', bridge, dev)


def _update_device_mtu(dev, mtu, interface_type=None):
# Note at present there is no support for setting the
# mtu for vhost-user type ports.
if mtu and interface_type not in [
constants.OVS_VHOSTUSER_INTERFACE_TYPE,
constants.OVS_VHOSTUSER_CLIENT_INTERFACE_TYPE]:
def _update_device_mtu(dev, mtu, interface_type=None, timeout=120):
if not mtu:
return
if interface_type not in [
constants.OVS_VHOSTUSER_INTERFACE_TYPE,
constants.OVS_VHOSTUSER_CLIENT_INTERFACE_TYPE]:
_set_device_mtu(dev, mtu)
elif _ovs_supports_mtu_requests(timeout=timeout):
_set_mtu_request(dev, mtu, timeout=timeout)
else:
LOG.debug("MTU not set on %(interface_name)s interface "
"of type %(interface_type)s.",
{'interface_name': dev,
'interface_type': interface_type})


@privsep.vif_plug.entrypoint
def _set_device_mtu(dev, mtu):
"""Set the device MTU."""
processutils.execute('ip', 'link', 'set', dev, 'mtu', mtu,
check_exit_code=[0, 2, 254])


@privsep.vif_plug.entrypoint
def _set_mtu_request(dev, mtu, timeout=None):
args = ['--', 'set', 'interface', dev,
'mtu_request=%s' % mtu]
_ovs_vsctl(args, timeout=timeout)


@privsep.vif_plug.entrypoint
def _ovs_supports_mtu_requests(timeout=None):
args = ['--columns=mtu_request', 'list', 'interface']
_, error = _ovs_vsctl(args, timeout=timeout)
if (error == 'ovs-vsctl: Interface does not contain' +
' a column whose name matches "mtu_request"'):
return False
return True
57 changes: 52 additions & 5 deletions vif_plug_ovs/tests/test_linux_net.py
Expand Up @@ -157,11 +157,14 @@ def test_create_ovs_bridge_cmd(self):
actual = linux_net._create_ovs_bridge_cmd(bridge, dp_type)
self.assertEqual(expected, actual)

@mock.patch.object(linux_net, '_ovs_supports_mtu_requests')
@mock.patch.object(linux_net, '_ovs_vsctl')
@mock.patch.object(linux_net, '_create_ovs_vif_cmd')
@mock.patch.object(linux_net, '_set_device_mtu')
def test_ovs_vif_port_with_type_vhostuser(self, mock_set_device_mtu,
mock_create_cmd, mock_vsctl):
mock_create_cmd, mock_vsctl,
mock_ovs_supports_mtu_requests):
mock_ovs_supports_mtu_requests.return_value = True
linux_net.create_ovs_vif_port(
'fake-bridge',
'fake-dev', 'fake-iface-id', 'fake-mac',
Expand All @@ -174,11 +177,14 @@ def test_ovs_vif_port_with_type_vhostuser(self, mock_set_device_mtu,
self.assertFalse(mock_set_device_mtu.called)
self.assertTrue(mock_vsctl.called)

@mock.patch.object(linux_net, '_ovs_supports_mtu_requests')
@mock.patch.object(linux_net, '_ovs_vsctl')
@mock.patch.object(linux_net, '_create_ovs_vif_cmd')
@mock.patch.object(linux_net, '_set_device_mtu')
def test_ovs_vif_port_with_type_vhostuserclient(self,
mock_set_device_mtu, mock_create_cmd, mock_vsctl):
mock_set_device_mtu, mock_create_cmd,
mock_vsctl, mock_ovs_supports_mtu_requests):
mock_ovs_supports_mtu_requests.return_value = True
linux_net.create_ovs_vif_port(
'fake-bridge',
'fake-dev', 'fake-iface-id', 'fake-mac',
Expand All @@ -193,11 +199,14 @@ def test_ovs_vif_port_with_type_vhostuserclient(self,
self.assertFalse(mock_set_device_mtu.called)
self.assertTrue(mock_vsctl.called)

@mock.patch.object(linux_net, '_ovs_supports_mtu_requests')
@mock.patch.object(linux_net, '_ovs_vsctl')
@mock.patch.object(linux_net, '_create_ovs_vif_cmd')
@mock.patch.object(linux_net, '_set_device_mtu')
def test_ovs_vif_port_with_no_mtu(self, mock_set_device_mtu,
mock_create_cmd, mock_vsctl):
mock_create_cmd, mock_vsctl,
mock_ovs_supports_mtu_requests):
mock_ovs_supports_mtu_requests.return_value = True
linux_net.create_ovs_vif_port(
'fake-bridge',
'fake-dev', 'fake-iface-id', 'fake-mac',
Expand All @@ -208,12 +217,18 @@ def test_ovs_vif_port_with_no_mtu(self, mock_set_device_mtu,
self.assertFalse(mock_set_device_mtu.called)
self.assertTrue(mock_vsctl.called)

@mock.patch.object(linux_net, '_ovs_supports_mtu_requests')
@mock.patch.object(linux_net, '_set_mtu_request')
@mock.patch.object(linux_net, '_ovs_vsctl')
@mock.patch.object(linux_net, '_create_ovs_vif_cmd',
return_value='ovs_command')
@mock.patch.object(linux_net, '_set_device_mtu')
def test_ovs_vif_port_with_timeout(self, mock_set_device_mtu,
mock_create_cmd, mock_vsctl):
mock_create_cmd, mock_vsctl,
mock_set_mtu_request,
mock_ovs_supports_mtu_requests):
mock_ovs_supports_mtu_requests.return_value = True

linux_net.create_ovs_vif_port(
'fake-bridge',
'fake-dev', 'fake-iface-id', 'fake-mac',
Expand All @@ -222,12 +237,17 @@ def test_ovs_vif_port_with_timeout(self, mock_set_device_mtu,
self.assertFalse(mock_set_device_mtu.called)
mock_vsctl.assert_called_with('ovs_command', timeout=42)

@mock.patch.object(linux_net, '_ovs_supports_mtu_requests')
@mock.patch.object(linux_net, '_set_mtu_request')
@mock.patch.object(linux_net, '_ovs_vsctl')
@mock.patch.object(linux_net, '_create_ovs_vif_cmd',
return_value='ovs_command')
@mock.patch.object(linux_net, '_set_device_mtu')
def test_ovs_vif_port_with_no_timeout(self, mock_set_device_mtu,
mock_create_cmd, mock_vsctl):
mock_create_cmd, mock_vsctl,
mock_set_mtu_request,
mock_ovs_supports_mtu_requests):
mock_ovs_supports_mtu_requests.return_value = True
linux_net.create_ovs_vif_port(
'fake-bridge',
'fake-dev', 'fake-iface-id', 'fake-mac',
Expand All @@ -246,3 +266,30 @@ def test_ovs_vsctl(self, mock_execute):
[mock.call('ovs-vsctl', *args),
mock.call('ovs-vsctl', '--timeout=%s' % timeout, *args)],
mock_execute.mock_calls)

@mock.patch.object(linux_net, '_ovs_vsctl')
def test_set_mtu_request(self, mock_vsctl):
dev = 'fake-dev'
mtu = 'fake-mtu'
timeout = 120
linux_net._set_mtu_request(dev, mtu, timeout=timeout)
args = ['--', 'set', 'interface', dev,
'mtu_request=%s' % mtu]
mock_vsctl.assert_called_with(args, timeout=timeout)

@mock.patch.object(linux_net, '_ovs_vsctl')
def test_ovs_supports_mtu_requests(self, mock_vsctl):
args = ['--columns=mtu_request', 'list', 'interface']
timeout = 120
msg = 'ovs-vsctl: Interface does not contain' + \
' a column whose name matches "mtu_request"'

mock_vsctl.return_value = (None, msg)
result = linux_net._ovs_supports_mtu_requests(timeout=timeout)
mock_vsctl.assert_called_with(args, timeout=timeout)
self.assertFalse(result)

mock_vsctl.return_value = (None, None)
result = linux_net._ovs_supports_mtu_requests(timeout=timeout)
mock_vsctl.assert_called_with(args, timeout=timeout)
self.assertTrue(result)

0 comments on commit 9a14c18

Please sign in to comment.