1
0
mirror of https://github.com/CumulusNetworks/ifupdown2.git synced 2024-05-06 15:54:50 +00:00

Merge branch 'master-next' into python3

* master-next:
  argv: move --nldebug option to common_argparse to avoid exception in ifreload
  debian: changelog: new 2.0.1-1 entry
  argv: add new command line argument --nldebug
  This commit adds the feature to change offloads for nics. Currently GRO, LRO GSO, TSO, UFO, TX and RX Offload are supported.
This commit is contained in:
Julien Fortin
2020-01-02 15:50:51 +01:00
5 changed files with 158 additions and 9 deletions

9
debian/changelog vendored
View File

@@ -2,7 +2,14 @@ ifupdown2 (3.0.0-1) unstable; urgency=medium
* New. Enabled: python3 support
-- Julien Fortin <julien@cumulusnetworks.com> Tue, 01 Oct 2019 23:42:42 +0200
-- Julien Fortin <julien@cumulusnetworks.com> Tue, 31 Dec 2019 23:42:42 +0100
ifupdown2 (2.0.1-1) unstable; urgency=medium
* New argv option: --nldebug to print netlink debug message
* New: ethtool: nics (GRO, LRO GSO, TSO, UFO, TX and RX) offload attributes
-- Julien Fortin <julien@cumulusnetworks.com> Tue, 31 Dec 2019 15:21:06 +0100
ifupdown2 (2.0.0-1) unstable; urgency=medium

View File

@@ -9,8 +9,10 @@ import os
try:
from ifupdown2.lib.addon import Addon
import ifupdown2.ifupdown.ifupdownflags as ifupdownflags
import ifupdown2.ifupdown.ifupdownflags as ifupdownflags
import ifupdown2.ifupdown.policymanager as policymanager
import ifupdown2.ifupdown.statemanager as statemanager
from ifupdown2.ifupdown.iface import *
from ifupdown2.ifupdown.utils import utils
@@ -23,6 +25,7 @@ except (ImportError, ModuleNotFoundError):
import ifupdown.ifupdownflags as ifupdownflags
import ifupdown.policymanager as policymanager
import ifupdown.statemanager as statemanager
from ifupdown.iface import *
from ifupdown.utils import utils
@@ -35,7 +38,7 @@ except (ImportError, ModuleNotFoundError):
class ethtool(Addon, moduleBase):
""" ifupdown2 addon module to configure ethtool attributes """
_modinfo = {
modinfo = {
"mhelp": "ethtool configuration module for interfaces",
"attrs": {
"link-speed": {
@@ -70,7 +73,49 @@ class ethtool(Addon, moduleBase):
"example": ["link-fec rs"],
"validvals": ["rs", "baser", "auto", "off"],
"default": "varies by platform and port"
}
},
'gro-offload': {
'help': 'Generic Receive Offload',
'example': ['gro-offload on'],
'validvals': ['on', 'off'],
'default': 'varies by interface'
},
'lro-offload': {
'help': 'Large Receive Offload',
'example': ['lro-offload on'],
'validvals': ['on', 'off'],
'default': 'varies by interface'
},
'gso-offload': {
'help': 'Generic Segmentation Offload',
'example': ['tso-offload on'],
'validvals': ['on', 'off'],
'default': 'varies by interface'
},
'tso-offload': {
'help': 'TCP Segmentation Offload',
'example': ['tso-offload on'],
'validvals': ['on', 'off'],
'default': 'varies by interface'
},
'ufo-offload': {
'help': 'UDP Fragmentation Offload',
'example': ['ufo-offload on'],
'validvals': ['on', 'off'],
'default': 'varies by interface'
},
'tx-offload': {
'help': 'TX Checksum Offload',
'example': ['tx-offload on'],
'validvals': ['on', 'off'],
'default': 'varies by interface'
},
'rx-offload': {
'help': 'RX Checksum Offload',
'example': ['rx-offload on'],
'validvals': ['on', 'off'],
'default': 'varies by interface'
},
}
}
@@ -81,12 +126,45 @@ class ethtool(Addon, moduleBase):
raise moduleNotSupported('module init failed: %s: not found' % utils.ethtool_cmd)
# keep a list of iface objects who have modified link attributes
self.ifaceobjs_modified_configs = []
# Cache for features
self.feature_cache = None
self.ethtool_ignore_errors = policymanager.policymanager_api.get_module_globals(
module_name=self.__class__.__name__,
attr='ethtool_ignore_errors'
)
def do_offload_settings(self, ifaceobj, attr_name, eth_name):
default = 'default_' + eth_name
config_val = ifaceobj.get_attr_value_first(attr_name)
# Default
default_val = None
saved_ifaceobjs = statemanager.statemanager_api.get_ifaceobjs(ifaceobj.name)
if saved_ifaceobjs:
default_val = saved_ifaceobjs[0].get_attr_value_first(default)
if config_val or default_val:
# get running value
running_val = str(self.get_running_attr(eth_name, ifaceobj)).lower()
# Save default value
# Load state data
if not default_val:
ifaceobj.config[default] = [running_val]
elif config_val:
# resave for state
ifaceobj.config[default] = [default_val]
if not config_val:
config_val = default_val
if config_val and config_val != running_val:
try:
cmd = ('%s -K %s %s %s' %
(utils.ethtool_cmd, ifaceobj.name, eth_name, config_val))
utils.exec_command(cmd)
except Exception, e:
self.log_error('%s: %s' %(ifaceobj.name, str(e)), ifaceobj)
def do_fec_settings(self, ifaceobj):
feccmd = ''
@@ -240,6 +318,13 @@ class ethtool(Addon, moduleBase):
self.do_speed_settings(ifaceobj)
self.do_fec_settings(ifaceobj)
self.do_offload_settings(ifaceobj, 'gro-offload', 'gro')
self.do_offload_settings(ifaceobj, 'lro-offload', 'lro')
self.do_offload_settings(ifaceobj, 'gso-offload', 'gso')
self.do_offload_settings(ifaceobj, 'tso-offload', 'tso')
self.do_offload_settings(ifaceobj, 'ufo-offload', 'ufo')
self.do_offload_settings(ifaceobj, 'tx-offload', 'tx')
self.do_offload_settings(ifaceobj, 'rx-offload', 'rx')
def _pre_down(self, ifaceobj):
pass #self._post_up(ifaceobj,operation="_pre_down")
@@ -329,6 +414,21 @@ class ethtool(Addon, moduleBase):
return(None)
def get_offload_setting(self, ethtool_output, setting):
value = None
for line in ethtool_output.splitlines():
if setting in line:
if 'on' in line:
value = 'on'
elif 'off' in line:
value = 'off'
break
return value
def get_running_attr(self,attr='',ifaceobj=None):
if not ifaceobj or not attr:
return
@@ -341,6 +441,41 @@ class ethtool(Addon, moduleBase):
output = utils.exec_command('%s --show-fec %s'%
(utils.ethtool_cmd, ifaceobj.name))
running_attr = self.get_fec_encoding(ethtool_output=output)
elif attr == 'gro':
if not self.feature_cache:
self.feature_cache = utils.exec_command('%s --show-features %s'%
(utils.ethtool_cmd, ifaceobj.name))
running_attr = self.get_offload_setting(ethtool_output=self.feature_cache, setting='generic-receive-offload')
elif attr == 'lro':
if not self.feature_cache:
self.feature_cache = utils.exec_command('%s --show-features %s'%
(utils.ethtool_cmd, ifaceobj.name))
running_attr = self.get_offload_setting(ethtool_output=self.feature_cache, setting='large-receive-offload')
elif attr == 'gso':
if not self.feature_cache:
self.feature_cache = utils.exec_command('%s --show-features %s'%
(utils.ethtool_cmd, ifaceobj.name))
running_attr = self.get_offload_setting(ethtool_output=self.feature_cache, setting='generic-segmentation-offload')
elif attr == 'tso':
if not self.feature_cache:
self.feature_cache = utils.exec_command('%s --show-features %s'%
(utils.ethtool_cmd, ifaceobj.name))
running_attr = self.get_offload_setting(ethtool_output=self.feature_cache, setting='tcp-segmentation-offload')
elif attr == 'ufo':
if not self.feature_cache:
self.feature_cache = utils.exec_command('%s --show-features %s'%
(utils.ethtool_cmd, ifaceobj.name))
running_attr = self.get_offload_setting(ethtool_output=self.feature_cache, setting='udp-fragmentation-offload')
elif attr == 'rx':
if not self.feature_cache:
self.feature_cache = utils.exec_command('%s --show-features %s'%
(utils.ethtool_cmd, ifaceobj.name))
running_attr = self.get_offload_setting(ethtool_output=self.feature_cache, setting='rx-checksumming')
elif attr == 'tx':
if not self.feature_cache:
self.feature_cache = utils.exec_command('%s --show-features %s'%
(utils.ethtool_cmd, ifaceobj.name))
running_attr = self.get_offload_setting(ethtool_output=self.feature_cache, setting='tx-checksumming')
else:
running_attr = self.io.read_file_oneline('/sys/class/net/%s/%s' % \
(ifaceobj.name, attr))

View File

@@ -241,3 +241,10 @@ class Parse:
''' general parsing rules '''
argparser.add_argument('-V', '--version', action=VersionAction, nargs=0)
argparser.add_argument(
"--nldebug",
dest="nldebug",
action="store_true",
default=False,
help="print netlink debug messages"
)

View File

@@ -219,7 +219,7 @@ class ifupdownMain:
def link_exists(self, ifacename):
return os.path.exists('/sys/class/net/%s' %ifacename)
def __init__(self, config={},
def __init__(self, config={}, args=None,
daemon=False, force=False, dryrun=False, nowait=False,
perfmode=False, withdepends=False, njobs=1,
cache=False, addons_enable=True, statemanager_enable=True,
@@ -247,7 +247,7 @@ class ifupdownMain:
self.reset_ifupdown2()
else:
# init nlcache with appropriate log level
nlcache.NetlinkListenerWithCache.init(logging.root.level)
nlcache.NetlinkListenerWithCache.init(logging.DEBUG if args.nldebug else logging.WARNING)
# start netlink listener and cache link/addr/netconf dumps
nlcache.NetlinkListenerWithCache.get_instance().start()

View File

@@ -161,7 +161,7 @@ class Ifupdown2:
log.debug('creating ifupdown object ..')
cachearg = (False if (iflist or args.nocache or args.noact)
else True)
ifupdown_handle = ifupdownMain(daemon=self.daemon,
ifupdown_handle = ifupdownMain(daemon=self.daemon, args=args,
config=configmap_g,
force=args.force,
withdepends=args.withdepends,
@@ -195,7 +195,7 @@ class Ifupdown2:
try:
iflist = args.iflist
log.debug('creating ifupdown object ..')
ifupdown_handle = ifupdownMain(daemon=self.daemon,
ifupdown_handle = ifupdownMain(daemon=self.daemon, args=args,
config=configmap_g, force=args.force,
withdepends=args.withdepends,
perfmode=args.perfmode,
@@ -241,7 +241,7 @@ class Ifupdown2:
iflist = [i for i in os.listdir('/sys/class/net/')
if os.path.isdir('/sys/class/net/%s' % i)]
log.debug('creating ifupdown object ..')
ifupdown_handle = ifupdownMain(daemon=self.daemon,
ifupdown_handle = ifupdownMain(daemon=self.daemon, args=args,
config=configmap_g,
withdepends=args.withdepends,
perfmode=args.perfmode,
@@ -265,7 +265,7 @@ class Ifupdown2:
try:
log.debug('creating ifupdown object ..')
ifupdown_handle = ifupdownMain(daemon=self.daemon,
ifupdown_handle = ifupdownMain(daemon=self.daemon, args=args,
config=configmap_g,
interfacesfile=self.interfaces_filename,
withdepends=args.withdepends,