Page MenuHomeVyOS Platform

No OneTemporary

Size
9 KB
Referenced Files
None
Subscribers
None
diff --git a/data/templates/sflow/hsflowd.conf.j2 b/data/templates/sflow/hsflowd.conf.j2
index 94f5939be..5000956bd 100644
--- a/data/templates/sflow/hsflowd.conf.j2
+++ b/data/templates/sflow/hsflowd.conf.j2
@@ -1,31 +1,32 @@
# Genereated by /usr/libexec/vyos/conf_mode/system_sflow.py
# Parameters http://sflow.net/host-sflow-linux-config.php
sflow {
{% if polling is vyos_defined %}
polling={{ polling }}
{% endif %}
{% if sampling_rate is vyos_defined %}
sampling={{ sampling_rate }}
sampling.bps_ratio=0
{% endif %}
{% if agent_address is vyos_defined %}
agentIP={{ agent_address }}
{% endif %}
{% if agent_interface is vyos_defined %}
agent={{ agent_interface }}
{% endif %}
{% if server is vyos_defined %}
{% for server, server_config in server.items() %}
collector { ip = {{ server }} udpport = {{ server_config.port }} }
{% endfor %}
{% endif %}
{% if interface is vyos_defined %}
{% for iface in interface %}
pcap { dev={{ iface }} }
{% endfor %}
{% endif %}
{% if drop_monitor_limit is vyos_defined %}
dropmon { limit={{ drop_monitor_limit }} start=on sw=on hw=off }
{% endif %}
+ dbus { }
}
diff --git a/op-mode-definitions/sflow.xml.in b/op-mode-definitions/sflow.xml.in
new file mode 100644
index 000000000..9f02dacda
--- /dev/null
+++ b/op-mode-definitions/sflow.xml.in
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- sflow op mode commands -->
+<interfaceDefinition>
+ <node name="show">
+ <children>
+ <node name="sflow">
+ <properties>
+ <help>Show sFlow statistics</help>
+ </properties>
+ <!-- requires sudo, do not remove it -->
+ <command>sudo ${vyos_op_scripts_dir}/sflow.py show</command>
+ </node>
+ </children>
+ </node>
+</interfaceDefinition>
diff --git a/smoketest/scripts/cli/test_system_sflow.py b/smoketest/scripts/cli/test_system_sflow.py
index fef88b56a..1aec050a4 100755
--- a/smoketest/scripts/cli/test_system_sflow.py
+++ b/smoketest/scripts/cli/test_system_sflow.py
@@ -1,100 +1,101 @@
#!/usr/bin/env python3
#
# Copyright (C) 2023 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/>.
import unittest
from base_vyostest_shim import VyOSUnitTestSHIM
from vyos.configsession import ConfigSessionError
from vyos.ifconfig import Section
from vyos.util import cmd
from vyos.util import process_named_running
from vyos.util import read_file
PROCESS_NAME = 'hsflowd'
base_path = ['system', 'sflow']
hsflowd_conf = '/run/sflow/hsflowd.conf'
class TestSystemFlowAccounting(VyOSUnitTestSHIM.TestCase):
@classmethod
def setUpClass(cls):
super(TestSystemFlowAccounting, cls).setUpClass()
# ensure we can also run this test on a live system - so lets clean
# out the current configuration :)
cls.cli_delete(cls, base_path)
def tearDown(self):
# after service removal process must no longer run
self.assertTrue(process_named_running(PROCESS_NAME))
self.cli_delete(base_path)
self.cli_commit()
# after service removal process must no longer run
self.assertFalse(process_named_running(PROCESS_NAME))
def test_sflow(self):
agent_address = '192.0.2.5'
agent_interface = 'eth0'
polling = '24'
sampling_rate = '128'
server = '192.0.2.254'
local_server = '127.0.0.1'
port = '8192'
default_port = '6343'
mon_limit = '50'
self.cli_set(
['interfaces', 'dummy', 'dum0', 'address', f'{agent_address}/24'])
self.cli_set(base_path + ['agent-address', agent_address])
self.cli_set(base_path + ['agent-interface', agent_interface])
# You need to configure at least one interface for sflow
with self.assertRaises(ConfigSessionError):
self.cli_commit()
for interface in Section.interfaces('ethernet'):
self.cli_set(base_path + ['interface', interface])
self.cli_set(base_path + ['polling', polling])
self.cli_set(base_path + ['sampling-rate', sampling_rate])
self.cli_set(base_path + ['server', server, 'port', port])
self.cli_set(base_path + ['server', local_server])
self.cli_set(base_path + ['drop-monitor-limit', mon_limit])
# commit changes
self.cli_commit()
# verify configuration
hsflowd = read_file(hsflowd_conf)
self.assertIn(f'polling={polling}', hsflowd)
self.assertIn(f'sampling={sampling_rate}', hsflowd)
self.assertIn(f'agentIP={agent_address}', hsflowd)
self.assertIn(f'agent={agent_interface}', hsflowd)
self.assertIn(f'collector {{ ip = {server} udpport = {port} }}', hsflowd)
self.assertIn(f'collector {{ ip = {local_server} udpport = {default_port} }}', hsflowd)
self.assertIn(f'dropmon {{ limit={mon_limit} start=on sw=on hw=off }}', hsflowd)
+ self.assertIn('dbus { }', hsflowd)
for interface in Section.interfaces('ethernet'):
self.assertIn(f'pcap {{ dev={interface} }}', hsflowd)
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/src/op_mode/sflow.py b/src/op_mode/sflow.py
new file mode 100755
index 000000000..1ff006274
--- /dev/null
+++ b/src/op_mode/sflow.py
@@ -0,0 +1,102 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2023 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/>.
+
+import dbus
+import sys
+
+from tabulate import tabulate
+
+from vyos.configquery import ConfigTreeQuery
+from vyos.util import cmd
+
+import vyos.opmode
+
+
+def _get_raw_sflow():
+ bus = dbus.SystemBus()
+ config = ConfigTreeQuery()
+
+ interfaces = config.values('system sflow interface')
+ servers = config.list_nodes('system sflow server')
+
+ sflow = bus.get_object('net.sflow.hsflowd', '/net/sflow/hsflowd')
+ sflow_telemetry = dbus.Interface(
+ sflow, dbus_interface='net.sflow.hsflowd.telemetry')
+ agent_address = sflow_telemetry.GetAgent()
+ samples_dropped = int(sflow_telemetry.Get('dropped_samples'))
+ samples_packet_sent = int(sflow_telemetry.Get('flow_samples'))
+ samples_counter_sent = int(sflow_telemetry.Get('counter_samples'))
+ datagrams_sent = int(sflow_telemetry.Get('datagrams'))
+ rtmetric_samples = int(sflow_telemetry.Get('rtmetric_samples'))
+ samples_suppressed = int(sflow_telemetry.Get('flow_samples_suppressed'))
+ counter_samples_suppressed = int(
+ sflow_telemetry.Get("counter_samples_suppressed"))
+ version = sflow_telemetry.GetVersion()
+
+ sflow_dict = {
+ 'agent_address': agent_address,
+ 'sflow_interfaces': interfaces,
+ 'sflow_servers': servers,
+ 'counter_samples_sent': samples_counter_sent,
+ 'datagrams_sent': datagrams_sent,
+ 'packet_samples_dropped': samples_dropped,
+ 'packet_samples_sent': samples_packet_sent,
+ 'rtmetric_samples': rtmetric_samples,
+ 'flow_samples_suppressed': samples_suppressed,
+ 'counter_samples_suppressed': counter_samples_suppressed,
+ 'hsflowd_version': version
+ }
+ return sflow_dict
+
+
+def _get_formatted_sflow(data):
+ table = [
+ ['Agent address', f'{data.get("agent_address")}'],
+ ['sFlow interfaces', f'{data.get("sflow_interfaces", "n/a")}'],
+ ['sFlow servers', f'{data.get("sflow_servers", "n/a")}'],
+ ['Datagrams sent', f'{data.get("datagrams_sent")}'],
+ ['Packet samples sent', f'{data.get("packet_samples_sent")}'],
+ ['Packet samples dropped', f'{data.get("packet_samples_dropped")}'],
+ ['Counter samples sent', f'{data.get("counter_samples_sent")}'],
+ ['Flow samples suppressed', f'{data.get("flow_samples_suppressed")}'],
+ ['Counter samples suppressed', f'{data.get("counter_samples_suppressed")}']
+ ]
+
+ return tabulate(table)
+
+
+def show(raw: bool):
+
+ config = ConfigTreeQuery()
+ if not config.exists('system sflow'):
+ raise vyos.opmode.UnconfiguredSubsystem(
+ '"system sflow" is not configured!')
+
+ sflow_data = _get_raw_sflow()
+ if raw:
+ return sflow_data
+ else:
+ return _get_formatted_sflow(sflow_data)
+
+
+if __name__ == '__main__':
+ try:
+ res = vyos.opmode.run(sys.modules[__name__])
+ if res:
+ print(res)
+ except (ValueError, vyos.opmode.Error) as e:
+ print(e)
+ sys.exit(1)

File Metadata

Mime Type
text/x-diff
Expires
Fri, Nov 6, 8:56 AM (1 d, 2 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4652298
Default Alt Text
(9 KB)

Event Timeline