summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/templates/ids/fastnetmon.j264
-rw-r--r--interface-definitions/include/ids/threshold.xml.i38
-rw-r--r--interface-definitions/include/version/ids-version.xml.i3
-rw-r--r--interface-definitions/service-ids-ddos-protection.xml.in56
-rw-r--r--python/vyos/ifconfig/ethernet.py9
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_ethernet.py4
-rwxr-xr-xsmoketest/scripts/cli/test_service_ids.py6
-rw-r--r--src/etc/sysctl.d/30-vyos-router.conf4
-rwxr-xr-xsrc/migration-scripts/ids/0-to-156
9 files changed, 188 insertions, 52 deletions
diff --git a/data/templates/ids/fastnetmon.j2 b/data/templates/ids/fastnetmon.j2
index b9f77a257..0340d3c92 100644
--- a/data/templates/ids/fastnetmon.j2
+++ b/data/templates/ids/fastnetmon.j2
@@ -37,18 +37,70 @@ process_incoming_traffic = {{ 'on' if direction is vyos_defined and 'in' in dire
process_outgoing_traffic = {{ 'on' if direction is vyos_defined and 'out' in direction else 'off' }}
{% if threshold is vyos_defined %}
-{% for thr, thr_value in threshold.items() %}
-{% if thr is vyos_defined('fps') %}
+{% if threshold.general is vyos_defined %}
+# General threshold
+{% for thr, thr_value in threshold.general.items() %}
+{% if thr is vyos_defined('fps') %}
ban_for_flows = on
threshold_flows = {{ thr_value }}
-{% elif thr is vyos_defined('mbps') %}
+{% elif thr is vyos_defined('mbps') %}
ban_for_bandwidth = on
threshold_mbps = {{ thr_value }}
-{% elif thr is vyos_defined('pps') %}
+{% elif thr is vyos_defined('pps') %}
ban_for_pps = on
threshold_pps = {{ thr_value }}
-{% endif %}
-{% endfor %}
+{% endif %}
+{% endfor %}
+{% endif %}
+
+{% if threshold.tcp is vyos_defined %}
+# TCP threshold
+{% for thr, thr_value in threshold.tcp.items() %}
+{% if thr is vyos_defined('fps') %}
+ban_for_tcp_flows = on
+threshold_tcp_flows = {{ thr_value }}
+{% elif thr is vyos_defined('mbps') %}
+ban_for_tcp_bandwidth = on
+threshold_tcp_mbps = {{ thr_value }}
+{% elif thr is vyos_defined('pps') %}
+ban_for_tcp_pps = on
+threshold_tcp_pps = {{ thr_value }}
+{% endif %}
+{% endfor %}
+{% endif %}
+
+{% if threshold.udp is vyos_defined %}
+# UDP threshold
+{% for thr, thr_value in threshold.udp.items() %}
+{% if thr is vyos_defined('fps') %}
+ban_for_udp_flows = on
+threshold_udp_flows = {{ thr_value }}
+{% elif thr is vyos_defined('mbps') %}
+ban_for_udp_bandwidth = on
+threshold_udp_mbps = {{ thr_value }}
+{% elif thr is vyos_defined('pps') %}
+ban_for_udp_pps = on
+threshold_udp_pps = {{ thr_value }}
+{% endif %}
+{% endfor %}
+{% endif %}
+
+{% if threshold.icmp is vyos_defined %}
+# ICMP threshold
+{% for thr, thr_value in threshold.icmp.items() %}
+{% if thr is vyos_defined('fps') %}
+ban_for_icmp_flows = on
+threshold_icmp_flows = {{ thr_value }}
+{% elif thr is vyos_defined('mbps') %}
+ban_for_icmp_bandwidth = on
+threshold_icmp_mbps = {{ thr_value }}
+{% elif thr is vyos_defined('pps') %}
+ban_for_icmp_pps = on
+threshold_icmp_pps = {{ thr_value }}
+{% endif %}
+{% endfor %}
+{% endif %}
+
{% endif %}
{% if listen_interface is vyos_defined %}
diff --git a/interface-definitions/include/ids/threshold.xml.i b/interface-definitions/include/ids/threshold.xml.i
new file mode 100644
index 000000000..e21e3a005
--- /dev/null
+++ b/interface-definitions/include/ids/threshold.xml.i
@@ -0,0 +1,38 @@
+<!-- include start from ids/threshold.xml.i -->
+<leafNode name="fps">
+ <properties>
+ <help>Flows per second</help>
+ <valueHelp>
+ <format>u32:0-4294967294</format>
+ <description>Flows per second</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-4294967294"/>
+ </constraint>
+ </properties>
+</leafNode>
+<leafNode name="mbps">
+ <properties>
+ <help>Megabits per second</help>
+ <valueHelp>
+ <format>u32:0-4294967294</format>
+ <description>Megabits per second</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-4294967294"/>
+ </constraint>
+ </properties>
+</leafNode>
+<leafNode name="pps">
+ <properties>
+ <help>Packets per second</help>
+ <valueHelp>
+ <format>u32:0-4294967294</format>
+ <description>Packets per second</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-4294967294"/>
+ </constraint>
+ </properties>
+</leafNode>
+<!-- include end -->
diff --git a/interface-definitions/include/version/ids-version.xml.i b/interface-definitions/include/version/ids-version.xml.i
new file mode 100644
index 000000000..9133be02b
--- /dev/null
+++ b/interface-definitions/include/version/ids-version.xml.i
@@ -0,0 +1,3 @@
+<!-- include start from include/version/ids-version.xml.i -->
+<syntaxVersion component='ids' version='1'></syntaxVersion>
+<!-- include end -->
diff --git a/interface-definitions/service-ids-ddos-protection.xml.in b/interface-definitions/service-ids-ddos-protection.xml.in
index 86fc4dffa..a661b845d 100644
--- a/interface-definitions/service-ids-ddos-protection.xml.in
+++ b/interface-definitions/service-ids-ddos-protection.xml.in
@@ -107,42 +107,38 @@
<help>Attack limits thresholds</help>
</properties>
<children>
- <leafNode name="fps">
+ <node name="general">
<properties>
- <help>Flows per second</help>
- <valueHelp>
- <format>u32:0-4294967294</format>
- <description>Flows per second</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 0-4294967294"/>
- </constraint>
+ <help>General threshold</help>
</properties>
- </leafNode>
- <leafNode name="mbps">
+ <children>
+ #include <include/ids/threshold.xml.i>
+ </children>
+ </node>
+ <node name="tcp">
<properties>
- <help>Megabits per second</help>
- <valueHelp>
- <format>u32:0-4294967294</format>
- <description>Megabits per second</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 0-4294967294"/>
- </constraint>
+ <help>TCP threshold</help>
</properties>
- </leafNode>
- <leafNode name="pps">
+ <children>
+ #include <include/ids/threshold.xml.i>
+ </children>
+ </node>
+ <node name="udp">
<properties>
- <help>Packets per second</help>
- <valueHelp>
- <format>u32:0-4294967294</format>
- <description>Packets per second</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 0-4294967294"/>
- </constraint>
+ <help>UDP threshold</help>
</properties>
- </leafNode>
+ <children>
+ #include <include/ids/threshold.xml.i>
+ </children>
+ </node>
+ <node name="icmp">
+ <properties>
+ <help>ICMP threshold</help>
+ </properties>
+ <children>
+ #include <include/ids/threshold.xml.i>
+ </children>
+ </node>
</children>
</node>
</children>
diff --git a/python/vyos/ifconfig/ethernet.py b/python/vyos/ifconfig/ethernet.py
index b260a00ef..519cfc58c 100644
--- a/python/vyos/ifconfig/ethernet.py
+++ b/python/vyos/ifconfig/ethernet.py
@@ -70,13 +70,6 @@ class EthernetIf(Interface):
},
}}
- _sysfs_set = {**Interface._sysfs_set, **{
- 'rfs': {
- 'convert': lambda num: num if num else '0',
- 'location': '/proc/sys/net/core/rps_sock_flow_entries',
- },
- }}
-
def __init__(self, ifname, **kargs):
super().__init__(ifname, **kargs)
self.ethtool = Ethtool(ifname)
@@ -265,13 +258,11 @@ class EthernetIf(Interface):
def set_rfs(self, state):
rfs_flow = 0
- global_rfs_flow = 0
queues = len(glob(f'/sys/class/net/{self.ifname}/queues/rx-*'))
if state:
global_rfs_flow = 32768
rfs_flow = int(global_rfs_flow/queues)
- self.set_interface('rfs', global_rfs_flow)
for i in range(0, queues):
self._write_sysfs(f'/sys/class/net/{self.ifname}/queues/rx-{i}/rps_flow_cnt', rfs_flow)
diff --git a/smoketest/scripts/cli/test_interfaces_ethernet.py b/smoketest/scripts/cli/test_interfaces_ethernet.py
index 5049bd5b0..feb2c0268 100755
--- a/smoketest/scripts/cli/test_interfaces_ethernet.py
+++ b/smoketest/scripts/cli/test_interfaces_ethernet.py
@@ -205,7 +205,6 @@ class EthernetInterfaceTest(BasicInterfaceTest.TestCase):
tmp = read_file(f'/proc/sys/net/core/rps_sock_flow_entries')
self.assertEqual(int(tmp), global_rfs_flow)
-
# delete configuration of RFS and check all values returned to default "0"
for interface in self._interfaces:
self.cli_delete(self._base_path + [interface, 'offload', 'rfs'])
@@ -219,9 +218,6 @@ class EthernetInterfaceTest(BasicInterfaceTest.TestCase):
tmp = read_file(f'/sys/class/net/{interface}/queues/rx-{i}/rps_flow_cnt')
self.assertEqual(int(tmp), 0)
- tmp = read_file(f'/proc/sys/net/core/rps_sock_flow_entries')
- self.assertEqual(int(tmp), 0)
-
def test_non_existing_interface(self):
unknonw_interface = self._base_path + ['eth667']
diff --git a/smoketest/scripts/cli/test_service_ids.py b/smoketest/scripts/cli/test_service_ids.py
index d471eeaed..dcf2bcefe 100755
--- a/smoketest/scripts/cli/test_service_ids.py
+++ b/smoketest/scripts/cli/test_service_ids.py
@@ -77,9 +77,9 @@ class TestServiceIDS(VyOSUnitTestSHIM.TestCase):
self.cli_set(base_path + ['listen-interface', tmp])
self.cli_set(base_path + ['direction', 'in'])
- self.cli_set(base_path + ['threshold', 'fps', fps])
- self.cli_set(base_path + ['threshold', 'pps', pps])
- self.cli_set(base_path + ['threshold', 'mbps', mbps])
+ self.cli_set(base_path + ['threshold', 'general', 'fps', fps])
+ self.cli_set(base_path + ['threshold', 'general', 'pps', pps])
+ self.cli_set(base_path + ['threshold', 'general', 'mbps', mbps])
# commit changes
self.cli_commit()
diff --git a/src/etc/sysctl.d/30-vyos-router.conf b/src/etc/sysctl.d/30-vyos-router.conf
index 4feb7e09a..411429510 100644
--- a/src/etc/sysctl.d/30-vyos-router.conf
+++ b/src/etc/sysctl.d/30-vyos-router.conf
@@ -109,3 +109,7 @@ net.ipv4.neigh.default.gc_thresh3 = 8192
net.ipv6.neigh.default.gc_thresh1 = 1024
net.ipv6.neigh.default.gc_thresh2 = 4096
net.ipv6.neigh.default.gc_thresh3 = 8192
+
+# Enable global RFS (Receive Flow Steering) configuration. RFS is inactive
+# until explicitly configured at the interface level
+net.core.rps_sock_flow_entries = 32768
diff --git a/src/migration-scripts/ids/0-to-1 b/src/migration-scripts/ids/0-to-1
new file mode 100755
index 000000000..9f08f7dc7
--- /dev/null
+++ b/src/migration-scripts/ids/0-to-1
@@ -0,0 +1,56 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2022 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+from sys import argv
+from sys import exit
+
+from vyos.configtree import ConfigTree
+
+if (len(argv) < 1):
+ print("Must specify file name!")
+ exit(1)
+
+file_name = argv[1]
+
+with open(file_name, 'r') as f:
+ config_file = f.read()
+
+base = ['service', 'ids', 'ddos-protection']
+config = ConfigTree(config_file)
+
+if not config.exists(base + ['threshold']):
+ # Nothing to do
+ exit(0)
+else:
+ if config.exists(base + ['threshold', 'fps']):
+ tmp = config.return_value(base + ['threshold', 'fps'])
+ config.delete(base + ['threshold', 'fps'])
+ config.set(base + ['threshold', 'general', 'fps'], value=tmp)
+ if config.exists(base + ['threshold', 'mbps']):
+ tmp = config.return_value(base + ['threshold', 'mbps'])
+ config.delete(base + ['threshold', 'mbps'])
+ config.set(base + ['threshold', 'general', 'mbps'], value=tmp)
+ if config.exists(base + ['threshold', 'pps']):
+ tmp = config.return_value(base + ['threshold', 'pps'])
+ config.delete(base + ['threshold', 'pps'])
+ config.set(base + ['threshold', 'general', 'pps'], value=tmp)
+
+try:
+ with open(file_name, 'w') as f:
+ f.write(config.to_string())
+except OSError as e:
+ print(f'Failed to save the modified config: {e}')
+ exit(1)