Browse Source

Merge "Workaround for TCP checksum issue with ovs-dpdk and veth pair" into stable/rocky

changes/54/776454/3
Zuul 1 month ago
committed by Gerrit Code Review
parent
commit
62302fae77
5 changed files with 61 additions and 0 deletions
  1. +1
    -0
      etc/neutron/rootwrap.d/dhcp.filters
  2. +1
    -0
      etc/neutron/rootwrap.d/l3.filters
  3. +34
    -0
      neutron/agent/linux/ethtool.py
  4. +10
    -0
      neutron/agent/linux/interface.py
  5. +15
    -0
      neutron/tests/unit/agent/linux/test_interface.py

+ 1
- 0
etc/neutron/rootwrap.d/dhcp.filters View File

@ -10,6 +10,7 @@
# dhcp-agent
dnsmasq: CommandFilter, dnsmasq, root
ethtool: CommandFilter, ethtool, root
# dhcp-agent uses kill as well, that's handled by the generic KillFilter
# it looks like these are the only signals needed, per
# neutron/agent/linux/dhcp.py


+ 1
- 0
etc/neutron/rootwrap.d/l3.filters View File

@ -12,6 +12,7 @@
arping: CommandFilter, arping, root
# l3_agent
ethtool: CommandFilter, ethtool, root
sysctl: CommandFilter, sysctl, root
route: CommandFilter, route, root
radvd: CommandFilter, radvd, root


+ 34
- 0
neutron/agent/linux/ethtool.py View File

@ -0,0 +1,34 @@
# Copyright 2020 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from neutron.agent.linux import ip_lib
class Ethtool(object):
COMMAND = 'ethtool'
@staticmethod
def _cmd(cmd, namespace, **kwargs):
ip_wrapper = ip_lib.IPWrapper(namespace)
return ip_wrapper.netns.execute(cmd, run_as_root=True, **kwargs)
@classmethod
def offload(cls, device, rx, tx, namespace=None):
rx = 'on' if rx else 'off'
tx = 'on' if tx else 'off'
cmd = ['--offload', device, 'rx', rx, 'tx', tx]
cmd = [cls.COMMAND] + cmd
cls._cmd(cmd, namespace)

+ 10
- 0
neutron/agent/linux/interface.py View File

@ -22,9 +22,13 @@ from oslo_log import log as logging
import six
from neutron.agent.common import ovs_lib
from neutron.agent.linux import ethtool
from neutron.agent.linux import ip_lib
from neutron.common import constants as n_const
from neutron.common import exceptions
from neutron.conf.plugins.ml2.drivers import ovs_conf
from neutron.plugins.ml2.drivers.openvswitch.agent.common \
import constants as ovs_const
LOG = logging.getLogger(__name__)
@ -354,6 +358,7 @@ class OVSInterfaceDriver(LinuxInterfaceDriver):
def __init__(self, conf):
super(OVSInterfaceDriver, self).__init__(conf)
ovs_conf.register_ovs_agent_opts(self.conf)
if self.conf.ovs_use_veth:
self.DEV_NAME_PREFIX = 'ns-'
@ -434,6 +439,11 @@ class OVSInterfaceDriver(LinuxInterfaceDriver):
if link_up:
ns_dev.link.set_up()
if self.conf.ovs_use_veth:
# ovs-dpdk does not do checksum calculations for veth interface
# (bug 1832021)
if self.conf.OVS.datapath_type == ovs_const.OVS_DATAPATH_NETDEV:
ethtool.Ethtool.offload(ns_dev.name, rx=False, tx=False,
namespace=namespace)
root_dev.link.set_up()
def unplug(self, device_name, bridge=None, namespace=None, prefix=None):


+ 15
- 0
neutron/tests/unit/agent/linux/test_interface.py View File

@ -17,9 +17,13 @@ import mock
from neutron_lib import constants
from neutron.agent.common import ovs_lib
from neutron.agent.linux import ethtool
from neutron.agent.linux import interface
from neutron.agent.linux import ip_lib
from neutron.conf.agent import common as config
from neutron.conf.plugins.ml2.drivers import ovs_conf
from neutron.plugins.ml2.drivers.openvswitch.agent.common \
import constants as ovs_const
from neutron.tests import base
@ -69,6 +73,8 @@ class TestBase(base.BaseTestCase):
super(TestBase, self).setUp()
self.conf = config.setup_conf()
config.register_interface_opts(self.conf)
self.eth_tool_p = mock.patch.object(ethtool, 'Ethtool')
self.eth_tool = self.eth_tool_p.start()
self.ip_dev_p = mock.patch.object(ip_lib, 'IPDevice')
self.ip_dev = self.ip_dev_p.start()
self.ip_p = mock.patch.object(ip_lib, 'IPWrapper')
@ -482,7 +488,12 @@ class TestOVSInterfaceDriverWithVeth(TestOVSInterfaceDriver):
def setUp(self):
super(TestOVSInterfaceDriverWithVeth, self).setUp()
ovs_conf.register_ovs_agent_opts(self.conf)
self.conf.set_override('ovs_use_veth', True)
self.conf.set_override(
'datapath_type',
ovs_const.OVS_DATAPATH_NETDEV,
group='OVS')
def test_get_device_name(self):
br = interface.OVSInterfaceDriver(self.conf)
@ -513,6 +524,7 @@ class TestOVSInterfaceDriverWithVeth(TestOVSInterfaceDriver):
mock.patch.object(
interface, '_get_veth',
return_value=(root_dev, ns_dev)).start()
ns_dev.name = devname
expected = [mock.call(),
mock.call().add_veth('tap0', devname,
@ -543,6 +555,9 @@ class TestOVSInterfaceDriverWithVeth(TestOVSInterfaceDriver):
self.ip.assert_has_calls(expected)
root_dev.assert_has_calls([mock.call.link.set_up()])
ns_dev.assert_has_calls([mock.call.link.set_up()])
self.eth_tool.assert_has_calls([mock.call.offload(
devname, rx=False,
tx=False, namespace=namespace)])
def test_unplug(self, bridge=None):
if not bridge:


Loading…
Cancel
Save