From 4e8839b6d78c7629cd2c1daee0438472c96365a4 Mon Sep 17 00:00:00 2001
From: Nicolas Fort <nicolasfort1988@gmail.com>
Date: Tue, 21 Nov 2023 17:36:20 +0000
Subject: T5419: firewall: backport firewall flowtable to Sagitta.

---
 python/vyos/ethtool.py           |  3 +++
 python/vyos/firewall.py          | 31 ++++++++++++++++++-------------
 python/vyos/ifconfig/ethernet.py | 26 ++++++++++++++++++++++++++
 3 files changed, 47 insertions(+), 13 deletions(-)

(limited to 'python')

diff --git a/python/vyos/ethtool.py b/python/vyos/ethtool.py
index ca3bcfc3d..f19632719 100644
--- a/python/vyos/ethtool.py
+++ b/python/vyos/ethtool.py
@@ -172,6 +172,9 @@ class Ethtool:
     def get_generic_segmentation_offload(self):
         return self._get_generic('generic-segmentation-offload')
 
+    def get_hw_tc_offload(self):
+        return self._get_generic('hw-tc-offload')
+
     def get_large_receive_offload(self):
         return self._get_generic('large-receive-offload')
 
diff --git a/python/vyos/firewall.py b/python/vyos/firewall.py
index 8ae269fed..4fc1abb15 100644
--- a/python/vyos/firewall.py
+++ b/python/vyos/firewall.py
@@ -421,19 +421,24 @@ def parse_rule(rule_conf, hook, fw_name, rule_id, ip_name):
     if 'action' in rule_conf:
         # Change action=return to action=action
         # #output.append(nft_action(rule_conf['action']))
-        output.append(f'{rule_conf["action"]}')
-        if 'jump' in rule_conf['action']:
-            target = rule_conf['jump_target']
-            output.append(f'NAME{def_suffix}_{target}')
-
-        if 'queue' in rule_conf['action']:
-            if 'queue' in rule_conf:
-                target = rule_conf['queue']
-                output.append(f'num {target}')
-
-            if 'queue_options' in rule_conf:
-                queue_opts = ','.join(rule_conf['queue_options'])
-                output.append(f'{queue_opts}')
+        if rule_conf['action'] == 'offload':
+            offload_target = rule_conf['offload_target']
+            output.append(f'flow add @VYOS_FLOWTABLE_{offload_target}')
+        else:
+            output.append(f'{rule_conf["action"]}')
+
+            if 'jump' in rule_conf['action']:
+                target = rule_conf['jump_target']
+                output.append(f'NAME{def_suffix}_{target}')
+
+            if 'queue' in rule_conf['action']:
+                if 'queue' in rule_conf:
+                    target = rule_conf['queue']
+                    output.append(f'num {target}')
+
+                if 'queue_options' in rule_conf:
+                    queue_opts = ','.join(rule_conf['queue_options'])
+                    output.append(f'{queue_opts}')
 
     else:
         output.append('return')
diff --git a/python/vyos/ifconfig/ethernet.py b/python/vyos/ifconfig/ethernet.py
index 96e5f513b..aa1e87744 100644
--- a/python/vyos/ifconfig/ethernet.py
+++ b/python/vyos/ifconfig/ethernet.py
@@ -57,6 +57,10 @@ class EthernetIf(Interface):
             'validate': lambda v: assert_list(v, ['on', 'off']),
             'possible': lambda i, v: EthernetIf.feature(i, 'gso', v),
         },
+        'hw-tc-offload': {
+            'validate': lambda v: assert_list(v, ['on', 'off']),
+            'possible': lambda i, v: EthernetIf.feature(i, 'hw-tc-offload', v),
+        },
         'lro': {
             'validate': lambda v: assert_list(v, ['on', 'off']),
             'possible': lambda i, v: EthernetIf.feature(i, 'lro', v),
@@ -256,6 +260,25 @@ class EthernetIf(Interface):
                 print('Adapter does not support changing generic-segmentation-offload settings!')
         return False
 
+    def set_hw_tc_offload(self, state):
+        """
+        Enable hardware TC flow offload. State can be either True or False.
+        Example:
+        >>> from vyos.ifconfig import EthernetIf
+        >>> i = EthernetIf('eth0')
+        >>> i.set_hw_tc_offload(True)
+        """
+        if not isinstance(state, bool):
+            raise ValueError('Value out of range')
+
+        enabled, fixed = self.ethtool.get_hw_tc_offload()
+        if enabled != state:
+            if not fixed:
+                return self.set_interface('hw-tc-offload', 'on' if state else 'off')
+            else:
+                print('Adapter does not support changing hw-tc-offload settings!')
+        return False
+
     def set_lro(self, state):
         """
         Enable Large Receive offload. State can be either True or False.
@@ -392,6 +415,9 @@ class EthernetIf(Interface):
         # GSO (generic segmentation offload)
         self.set_gso(dict_search('offload.gso', config) != None)
 
+        # GSO (generic segmentation offload)
+        self.set_hw_tc_offload(dict_search('offload.hw-tc-offload', config) != None)
+
         # LRO (large receive offload)
         self.set_lro(dict_search('offload.lro', config) != None)
 
-- 
cgit v1.2.3