Browse Source

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

tags/14.3.0
Zuul 1 month ago
committed by Gerrit Code Review
parent
commit
d042897ab7
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

@@ -24,9 +24,13 @@ from oslo_utils import excutils
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 utils
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__)

@@ -346,6 +350,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-'

@@ -435,6 +440,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

@@ -19,10 +19,14 @@ from neutron_lib import exceptions
from oslo_utils import excutils

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.common import utils
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


@@ -72,6 +76,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')
@@ -516,7 +522,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)
@@ -547,6 +558,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,
@@ -577,6 +589,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_plug_new(self, bridge=None, namespace=None):
# The purpose of test_plug_new in parent class(TestOVSInterfaceDriver)


Loading…
Cancel
Save