summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/templates/sla/owamp-override.conf.j216
-rw-r--r--data/templates/sla/owamp-server.conf.j220
-rw-r--r--data/templates/sla/twamp-override.conf.j216
-rw-r--r--data/templates/sla/twamp-server.conf.j218
-rw-r--r--debian/control4
-rw-r--r--interface-definitions/service_sla.xml.in36
-rw-r--r--op-mode-definitions/force-wamp.xml.in25
-rwxr-xr-xsrc/conf_mode/service_sla.py113
8 files changed, 248 insertions, 0 deletions
diff --git a/data/templates/sla/owamp-override.conf.j2 b/data/templates/sla/owamp-override.conf.j2
new file mode 100644
index 000000000..b5ec161d4
--- /dev/null
+++ b/data/templates/sla/owamp-override.conf.j2
@@ -0,0 +1,16 @@
+[Unit]
+Description==OWAMP server
+After=vyos-router.service
+# Only start if there is a configuration file
+ConditionFileNotEmpty=/etc/owamp-server/owamp-server.conf
+
+[Service]
+KillMode=process
+Type=simple
+ExecStart=/usr/sbin/owampd -c /etc/owamp-server -R /var/run
+ExecReload=/bin/kill -HUP $MAINPID
+PIDFile=/run/owamp-server.pid
+LimitNOFILE=4096
+
+[Install]
+WantedBy=multi-user.target
diff --git a/data/templates/sla/owamp-server.conf.j2 b/data/templates/sla/owamp-server.conf.j2
new file mode 100644
index 000000000..6af963e57
--- /dev/null
+++ b/data/templates/sla/owamp-server.conf.j2
@@ -0,0 +1,20 @@
+### Autogenerated by service_twamp-server.py ###
+
+user owamp
+group owamp
+
+verbose
+vardir /var/run
+
+# location for "recv" session files.
+# The "catalog" subdirectory is completely cleaned and recreated each time
+datadir /var/lib/owamp
+
+srcnode :{{ port }}
+
+# This is used to limit testing to a specific port range. The valid values are:
+# 0 (twampd will let the system to pick the port number (ephemeral)
+# low-high (A range. high must be larger than low.)
+testports 8760-9960
+
+diskfudge 3.0
diff --git a/data/templates/sla/twamp-override.conf.j2 b/data/templates/sla/twamp-override.conf.j2
new file mode 100644
index 000000000..34bbd228b
--- /dev/null
+++ b/data/templates/sla/twamp-override.conf.j2
@@ -0,0 +1,16 @@
+[Unit]
+Description==TWAMP server
+After=vyos-router.service
+# Only start if there is a configuration file
+ConditionFileNotEmpty=/etc/twamp-server/twamp-server.conf
+
+[Service]
+KillMode=process
+Type=simple
+ExecStart=/usr/sbin/twampd -c /etc/twamp-server -R /var/run
+ExecReload=/bin/kill -HUP $MAINPID
+PIDFile=/run/twamp-server.pid
+LimitNOFILE=4096
+
+[Install]
+WantedBy=multi-user.target
diff --git a/data/templates/sla/twamp-server.conf.j2 b/data/templates/sla/twamp-server.conf.j2
new file mode 100644
index 000000000..ea5bbb54a
--- /dev/null
+++ b/data/templates/sla/twamp-server.conf.j2
@@ -0,0 +1,18 @@
+### Autogenerated by service_twamp-server.py ###
+
+user twamp
+group twamp
+
+verbose
+vardir /var/run
+
+# location for "recv" session files.
+# The "catalog" subdirectory is completely cleaned and recreated each time
+datadir /var/lib/twamp
+
+srcnode :{{ port }}
+
+# This is used to limit testing to a specific port range. The valid values are:
+# 0 (twampd will let the system to pick the port number (ephemeral)
+# low-high (A range. high must be larger than low.)
+testports 18760-19960
diff --git a/debian/control b/debian/control
index 437879764..6a6ccf602 100644
--- a/debian/control
+++ b/debian/control
@@ -108,6 +108,8 @@ Depends:
openvpn-auth-ldap,
openvpn-auth-radius,
openvpn-otp,
+ owamp-client,
+ owamp-server,
pciutils,
pdns-recursor,
pmacct (>= 1.6.0),
@@ -158,6 +160,8 @@ Depends:
tftpd-hpa,
traceroute,
tuned,
+ twamp-client,
+ twamp-server,
udp-broadcast-relay,
uidmap,
usb-modeswitch,
diff --git a/interface-definitions/service_sla.xml.in b/interface-definitions/service_sla.xml.in
new file mode 100644
index 000000000..0c4f8a591
--- /dev/null
+++ b/interface-definitions/service_sla.xml.in
@@ -0,0 +1,36 @@
+<?xml version="1.0"?>
+<interfaceDefinition>
+ <node name="service">
+ <children>
+ <node name="sla" owner="${vyos_conf_scripts_dir}/service_sla.py">
+ <properties>
+ <help>Service level agreement (SLA)</help>
+ </properties>
+ <children>
+ <node name="owamp-server">
+ <properties>
+ <help>One-way active measurement protocol (OWAMP) server</help>
+ </properties>
+ <children>
+ #include <include/port-number.xml.i>
+ <leafNode name="port">
+ <defaultValue>861</defaultValue>
+ </leafNode>
+ </children>
+ </node>
+ <node name="twamp-server">
+ <properties>
+ <help>Two-way active measurement protocol (TWAMP) server</help>
+ </properties>
+ <children>
+ #include <include/port-number.xml.i>
+ <leafNode name="port">
+ <defaultValue>862</defaultValue>
+ </leafNode>
+ </children>
+ </node>
+ </children>
+ </node>
+ </children>
+ </node>
+</interfaceDefinition>
diff --git a/op-mode-definitions/force-wamp.xml.in b/op-mode-definitions/force-wamp.xml.in
new file mode 100644
index 000000000..dbb205c6b
--- /dev/null
+++ b/op-mode-definitions/force-wamp.xml.in
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<interfaceDefinition>
+ <node name="force">
+ <children>
+ <tagNode name="owping">
+ <properties>
+ <help>IP address of the remote OWAMP server</help>
+ <completionHelp>
+ <list>&lt;x.x.x.x&gt; &lt;h:h:h:h:h:h:h:h&gt;</list>
+ </completionHelp>
+ </properties>
+ <command>owping $3</command>
+ </tagNode>
+ <tagNode name="twping">
+ <properties>
+ <help>IP address of the remote TWAMP server</help>
+ <completionHelp>
+ <list>&lt;x.x.x.x&gt; &lt;h:h:h:h:h:h:h:h&gt;</list>
+ </completionHelp>
+ </properties>
+ <command>twping $3</command>
+ </tagNode>
+ </children>
+ </node>
+</interfaceDefinition>
diff --git a/src/conf_mode/service_sla.py b/src/conf_mode/service_sla.py
new file mode 100755
index 000000000..e7c3ca59c
--- /dev/null
+++ b/src/conf_mode/service_sla.py
@@ -0,0 +1,113 @@
+#!/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/>.
+
+import os
+
+from sys import exit
+
+from vyos.config import Config
+from vyos.configdict import dict_merge
+from vyos.template import render
+from vyos.util import call
+from vyos.xml import defaults
+from vyos import ConfigError
+from vyos import airbag
+airbag.enable()
+
+
+owamp_config_dir = '/etc/owamp-server'
+owamp_config_file = f'{owamp_config_dir}/owamp-server.conf'
+systemd_override_owamp = r'/etc/systemd/system/owamp-server.d/20-override.conf'
+
+twamp_config_dir = '/etc/twamp-server'
+twamp_config_file = f'{twamp_config_dir}/twamp-server.conf'
+systemd_override_twamp = r'/etc/systemd/system/twamp-server.d/20-override.conf'
+
+
+def get_config(config=None):
+ if config:
+ conf = config
+ else:
+ conf = Config()
+ base = ['service', 'sla']
+ if not conf.exists(base):
+ return None
+
+ sla = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True)
+ # We have gathered the dict representation of the CLI, but there are default
+ # options which we need to update into the dictionary retrived.
+ default_values = defaults(base)
+ sla = dict_merge(default_values, sla)
+
+ # Ignore default XML values if config doesn't exists
+ # Delete key from dict
+ if not conf.exists(base + ['owamp-server']):
+ del sla['owamp_server']
+ if not conf.exists(base + ['twamp-server']):
+ del sla['twamp_server']
+
+ return sla
+
+def verify(sla):
+ if not sla:
+ return None
+
+def generate(sla):
+ if not sla:
+ return None
+
+ render(owamp_config_file, 'sla/owamp-server.conf.j2', sla)
+ render(systemd_override_owamp, 'sla/owamp-override.conf.j2', sla)
+
+ render(twamp_config_file, 'sla/twamp-server.conf.j2', sla)
+ render(systemd_override_twamp, 'sla/twamp-override.conf.j2', sla)
+
+ return None
+
+def apply(sla):
+ owamp_service = 'owamp-server.service'
+ twamp_service = 'twamp-server.service'
+
+ call('systemctl daemon-reload')
+
+ if not sla or 'owamp_server' not in sla:
+ call(f'systemctl stop {owamp_service}')
+
+ if os.path.exists(owamp_config_file):
+ os.unlink(owamp_config_file)
+
+ if not sla or 'twamp_server' not in sla:
+ call(f'systemctl stop {twamp_service}')
+ if os.path.exists(twamp_config_file):
+ os.unlink(twamp_config_file)
+
+ if sla and 'owamp_server' in sla:
+ call(f'systemctl reload-or-restart {owamp_service}')
+
+ if sla and 'twamp_server' in sla:
+ call(f'systemctl reload-or-restart {twamp_service}')
+
+ return None
+
+if __name__ == '__main__':
+ try:
+ c = get_config()
+ verify(c)
+ generate(c)
+ apply(c)
+ except ConfigError as e:
+ print(e)
+ exit(1)