]> git.proxmox.com Git - mirror_ifupdown2.git/commitdiff
This commit adds the feature to change offloads for nics.
authorSven Auhagen <Sven.Auhagen@voleatech.de>
Tue, 30 Jul 2019 17:59:34 +0000 (19:59 +0200)
committerSven Auhagen <Sven.Auhagen@voleatech.de>
Tue, 30 Jul 2019 17:59:34 +0000 (19:59 +0200)
Currently GRO, LRO GSO, TSO, UFO, TX and RX Offload are supported.

One can read the current value with ethtool -k NICNAME.
Values are set with ethtool -K NICNAME gro on lro on gso on tso on ufo on tx on rx on

An example for the config file is:

iface eth0 static
gro-offload no

The default value will be kept in the statemanager. The default value might differ depending on the NIC and is saved upon the first change.

ifupdown2/addons/ethtool.py

index c4f9aa1772c13be7e5b85443d2014541c3f63c6b..4a20ef5d614bba73ac933f473f347259153e986c 100644 (file)
@@ -9,6 +9,7 @@ import os
 try:
     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
@@ -20,6 +21,7 @@ try:
 except ImportError:
     import ifupdown.ifupdownflags as ifupdownflags
     import ifupdown.policymanager as policymanager
+    import ifupdown.statemanager as statemanager
 
     from ifupdown.iface import *
     from ifupdown.utils import utils
@@ -61,7 +63,44 @@ class ethtool(moduleBase,utilsBase):
                             {'help': 'set forward error correction mode',
                              'example' : ['link-fec rs'],
                              'validvals' : ['rs', 'baser', 'auto', 'off'],
-                             'default' : 'varies by platform and port'}}}
+                             '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'},
+                    }
+                }
 
     def __init__(self, *args, **kargs):
         moduleBase.__init__(self, *args, **kargs)
@@ -70,6 +109,39 @@ class ethtool(moduleBase,utilsBase):
         self.ipcmd = None
         # keep a list of iface objects who have modified link attributes
         self.ifaceobjs_modified_configs = []
+        # Cache for features
+        self.feature_cache = None
+
+    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 = ''
@@ -226,6 +298,13 @@ class ethtool(moduleBase,utilsBase):
 
         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")
@@ -315,6 +394,21 @@ class ethtool(moduleBase,utilsBase):
 
         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
@@ -327,6 +421,41 @@ class ethtool(moduleBase,utilsBase):
                 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.read_file_oneline('/sys/class/net/%s/%s' % \
                                                       (ifaceobj.name, attr))