summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--interface-definitions/interfaces-ethernet.xml.in6
-rw-r--r--python/vyos/ifconfig/ethernet.py24
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_ethernet.py19
3 files changed, 49 insertions, 0 deletions
diff --git a/interface-definitions/interfaces-ethernet.xml.in b/interface-definitions/interfaces-ethernet.xml.in
index ab65a93f3..77f130e1c 100644
--- a/interface-definitions/interfaces-ethernet.xml.in
+++ b/interface-definitions/interfaces-ethernet.xml.in
@@ -93,6 +93,12 @@
<valueless/>
</properties>
</leafNode>
+ <leafNode name="rfs">
+ <properties>
+ <help>Enable Receive Flow Steering</help>
+ <valueless/>
+ </properties>
+ </leafNode>
<leafNode name="sg">
<properties>
<help>Enable Scatter-Gather</help>
diff --git a/python/vyos/ifconfig/ethernet.py b/python/vyos/ifconfig/ethernet.py
index b8deb3311..eac72ab8c 100644
--- a/python/vyos/ifconfig/ethernet.py
+++ b/python/vyos/ifconfig/ethernet.py
@@ -16,6 +16,7 @@
import os
import re
+from glob import glob
from vyos.ethtool import Ethtool
from vyos.ifconfig.interface import Interface
from vyos.util import run
@@ -74,6 +75,10 @@ class EthernetIf(Interface):
'convert': lambda cpus: cpus if cpus else '0',
'location': '/sys/class/net/{ifname}/queues/rx-0/rps_cpus',
},
+ 'rfs': {
+ 'convert': lambda num: num if num else '0',
+ 'location': '/proc/sys/net/core/rps_sock_flow_entries',
+ },
}}
def __init__(self, ifname, **kargs):
@@ -258,6 +263,22 @@ class EthernetIf(Interface):
# send bitmask representation as hex string without leading '0x'
return self.set_interface('rps', rps_cpus)
+ def set_rfs(self, state):
+ rfs_flow = 0
+ global_rfs_flow = 0
+ ifname = self.config['ifname']
+ queues = glob(f'/sys/class/net/{ifname}/queues/rx-*')
+ if state:
+ global_rfs_flow = 32768
+ rfs_flow = global_rfs_flow/len(queues)
+
+ self.set_interface('rfs', str(int(global_rfs_flow)))
+
+ for i in range(0,len(queues)):
+ self._write_sysfs(f'/sys/class/net/{ifname}/queues/rx-{i}/rps_flow_cnt',str(int(rfs_flow)))
+
+ return state
+
def set_sg(self, state):
"""
Enable Scatter-Gather support. State can be either True or False.
@@ -342,6 +363,9 @@ class EthernetIf(Interface):
# RPS - Receive Packet Steering
self.set_rps(dict_search('offload.rps', config) != None)
+ # RFS - Receive Flow Steering
+ self.set_rfs(dict_search('offload.rfs', config) != None)
+
# scatter-gather option
self.set_sg(dict_search('offload.sg', config) != None)
diff --git a/smoketest/scripts/cli/test_interfaces_ethernet.py b/smoketest/scripts/cli/test_interfaces_ethernet.py
index 05d2ae5f5..529655f6a 100755
--- a/smoketest/scripts/cli/test_interfaces_ethernet.py
+++ b/smoketest/scripts/cli/test_interfaces_ethernet.py
@@ -17,6 +17,7 @@
import os
import re
import unittest
+from glob import glob
from netifaces import AF_INET
from netifaces import AF_INET6
@@ -185,6 +186,24 @@ class EthernetInterfaceTest(BasicInterfaceTest.TestCase):
self.assertEqual(f'{cpus:x}', f'{rps_cpus:x}')
+ def test_offloading_rfs(self):
+ global_rfs_flow = 32768
+ rfs_flow = global_rfs_flow
+
+ for interface in self._interfaces:
+ self.cli_set(self._base_path + [interface, 'offload', 'rfs'])
+ self.cli_commit()
+
+ for interface in self._interfaces:
+ queues = glob(f'/sys/class/net/{interface}/queues/rx-*')
+ rfs_flow = global_rfs_flow/len(queues)
+ for i in range(0,len(queues)):
+ flows = read_file(f'/sys/class/net/{interface}/queues/rx-{i}/rps_flow_cnt')
+ self.assertEqual(int(flows), int(rfs_flow))
+
+ global_flows = read_file(f'/proc/sys/net/core/rps_sock_flow_entries')
+ self.assertEqual(int(global_flows), int(global_rfs_flow))
+
def test_non_existing_interface(self):
unknonw_interface = self._base_path + ['eth667']
self.cli_set(unknonw_interface)