summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/templates/openvpn/server.conf.tmpl9
-rw-r--r--op-mode-definitions/restart-frr.xml.in6
-rw-r--r--python/vyos/config.py57
-rw-r--r--smoketest/configs/qos-basic205
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_bonding.py22
-rw-r--r--src/etc/dhcp/dhclient-enter-hooks.d/03-vyos-ipwrapper2
-rwxr-xr-xsrc/op_mode/restart_frr.py2
7 files changed, 285 insertions, 18 deletions
diff --git a/data/templates/openvpn/server.conf.tmpl b/data/templates/openvpn/server.conf.tmpl
index 75aae2981..627068b3e 100644
--- a/data/templates/openvpn/server.conf.tmpl
+++ b/data/templates/openvpn/server.conf.tmpl
@@ -82,15 +82,18 @@ push "route-ipv6 {{ route }}"
{% endif %}
{% endfor %}
{% endif %}
+
+{% if server.client_ip_pool is not defined %}
{# OpenVPN assigns the first IP address to its local interface so the pool used #}
{# in net30 topology - where each client receives a /30 must start from the second subnet #}
{% if server.topology is defined and server.topology == 'net30' %}
-ifconfig-pool {{ subnet | inc_ip('4') }} {{ subnet | last_host_address | dec_ip('1') }} {{ subnet | netmask_from_cidr if device_type == 'tap' else '' }}
+ifconfig-pool {{ subnet | inc_ip('4') }} {{ subnet | last_host_address | dec_ip('1') }} {% if device_type == 'tap' %} {{ subnet | netmask_from_cidr }} {% endif %}
{% else %}
{# OpenVPN assigns the first IP address to its local interface so the pool must #}
{# start from the second address and end on the last address #}
-ifconfig-pool {{ subnet | first_host_address | inc_ip('1') }} {{ subnet | last_host_address | dec_ip('1') }} {{ subnet | netmask_from_cidr if device_type == 'tun' else '' }}
+ifconfig-pool {{ subnet | first_host_address | inc_ip('1') }} {{ subnet | last_host_address | dec_ip('1') }} {% if device_type == 'tap' %} {{ subnet | netmask_from_cidr }} {% endif %}
{% endif %}
+{% endif %}
{% elif subnet | is_ipv6 %}
server-ipv6 {{ subnet }}
{% endif %}
@@ -98,7 +101,7 @@ server-ipv6 {{ subnet }}
{% endif %}
{% if server.client_ip_pool is defined and server.client_ip_pool is not none and server.client_ip_pool.disable is not defined %}
-ifconfig-pool {{ server.client_ip_pool.start }} {{ server.client_ip_pool.stop }}{{ server.client_ip_pool.subnet_mask if server.client_ip_pool.subnet_mask is defined and server.client_ip_pool.subnet_mask is not none }}
+ifconfig-pool {{ server.client_ip_pool.start }} {{ server.client_ip_pool.stop }} {{ server.client_ip_pool.subnet_mask if server.client_ip_pool.subnet_mask is defined and server.client_ip_pool.subnet_mask is not none and device_type == 'tap' }}
{% endif %}
{% if server.max_connections is defined and server.max_connections is not none %}
max-clients {{ server.max_connections }}
diff --git a/op-mode-definitions/restart-frr.xml.in b/op-mode-definitions/restart-frr.xml.in
index 475bd1ee8..4e2be1bf2 100644
--- a/op-mode-definitions/restart-frr.xml.in
+++ b/op-mode-definitions/restart-frr.xml.in
@@ -26,6 +26,12 @@
</properties>
<command>sudo ${vyos_op_scripts_dir}/restart_frr.py --action restart --daemon isisd</command>
</leafNode>
+ <leafNode name="ldp">
+ <properties>
+ <help>Restart the Label Distribution Protocol (LDP) daemon</help>
+ </properties>
+ <command>sudo ${vyos_op_scripts_dir}/restart_frr.py --action restart --daemon ldpd</command>
+ </leafNode>
<leafNode name="ospf">
<properties>
<help>Restart Open Shortest Path First (OSPF) routing daemon</help>
diff --git a/python/vyos/config.py b/python/vyos/config.py
index a5c1ad122..287fd2ed1 100644
--- a/python/vyos/config.py
+++ b/python/vyos/config.py
@@ -142,31 +142,41 @@ class Config(object):
def exists(self, path):
"""
- Checks if a node with given path exists in the running or proposed config
+ Checks if a node or value with given path exists in the proposed config.
+
+ Args:
+ path (str): Configuration tree path
Returns:
- True if node exists, False otherwise
+ True if node or value exists in the proposed config, False otherwise
Note:
- This function cannot be used outside a configuration sessions.
+ This function should not be used outside of configuration sessions.
In operational mode scripts, use ``exists_effective``.
"""
- if not self._session_config:
+ if self._session_config is None:
return False
+
+ # Assume the path is a node path first
if self._session_config.exists(self._make_path(path)):
return True
else:
+ # If that check fails, it may mean the path has a value at the end.
# libvyosconfig exists() works only for _nodes_, not _values_
- # libvyattacfg one also worked for values, so we emulate that case here
+ # libvyattacfg also worked for values, so we emulate that case here
if isinstance(path, str):
path = re.split(r'\s+', path)
path_without_value = path[:-1]
- path_str = " ".join(path_without_value)
try:
- value = self._session_config.return_value(self._make_path(path_str))
- return (value == path[-1])
+ # return_values() is safe to use with single-value nodes,
+ # it simply returns a single-item list in that case.
+ values = self._session_config.return_values(self._make_path(path_without_value))
+
+ # If we got this far, the node does exist and has values,
+ # so we need to check if it has the value in question among its values.
+ return (path[-1] in values)
except vyos.configtree.ConfigTreeError:
- # node doesn't exist at all
+ # Even the parent node doesn't exist at all
return False
def session_changed(self):
@@ -380,7 +390,7 @@ class Config(object):
def exists_effective(self, path):
"""
- Check if a node exists in the running (effective) config
+ Checks if a node or value exists in the running (effective) config.
Args:
path (str): Configuration tree path
@@ -392,10 +402,31 @@ class Config(object):
This function is safe to use in operational mode. In configuration mode,
it ignores uncommited changes.
"""
- if self._running_config:
- return(self._running_config.exists(self._make_path(path)))
+ if self._running_config is None:
+ return False
+
+ # Assume the path is a node path first
+ if self._running_config.exists(self._make_path(path)):
+ return True
+ else:
+ # If that check fails, it may mean the path has a value at the end.
+ # libvyosconfig exists() works only for _nodes_, not _values_
+ # libvyattacfg also worked for values, so we emulate that case here
+ if isinstance(path, str):
+ path = re.split(r'\s+', path)
+ path_without_value = path[:-1]
+ try:
+ # return_values() is safe to use with single-value nodes,
+ # it simply returns a single-item list in that case.
+ values = self._running_config.return_values(self._make_path(path_without_value))
+
+ # If we got this far, the node does exist and has values,
+ # so we need to check if it has the value in question among its values.
+ return (path[-1] in values)
+ except vyos.configtree.ConfigTreeError:
+ # Even the parent node doesn't exist at all
+ return False
- return False
def return_effective_value(self, path, default=None):
"""
diff --git a/smoketest/configs/qos-basic b/smoketest/configs/qos-basic
new file mode 100644
index 000000000..f94a5650d
--- /dev/null
+++ b/smoketest/configs/qos-basic
@@ -0,0 +1,205 @@
+interfaces {
+ ethernet eth0 {
+ address 10.1.1.100/24
+ traffic-policy {
+ out FS
+ }
+ }
+ ethernet eth1 {
+ address 10.2.1.1/24
+ traffic-policy {
+ out M2
+ }
+ }
+ ethernet eth2 {
+ address 10.9.9.1/24
+ traffic-policy {
+ out MY-HTB
+ }
+ }
+ loopback lo {
+ }
+}
+protocols {
+ static {
+ route 0.0.0.0/0 {
+ next-hop 10.9.9.2 {
+ }
+ next-hop 10.1.1.1 {
+ }
+ }
+ }
+}
+system {
+ config-management {
+ commit-revisions 10
+ }
+ conntrack {
+ modules {
+ ftp
+ h323
+ nfs
+ pptp
+ sip
+ sqlnet
+ tftp
+ }
+ }
+ console {
+ device ttyS0 {
+ speed 115200
+ }
+ }
+ host-name vyos
+ login {
+ user vyos {
+ authentication {
+ encrypted-password $6$r/Yw/07NXNY$/ZB.Rjf9jxEV.BYoDyLdH.kH14rU52pOBtrX.4S34qlPt77chflCHvpTCq9a6huLzwaMR50rEICzA5GoIRZlM0
+ plaintext-password ""
+ }
+ }
+ }
+ ntp {
+ server time1.vyos.net {
+ }
+ server time2.vyos.net {
+ }
+ server time3.vyos.net {
+ }
+ }
+ syslog {
+ global {
+ facility all {
+ level info
+ }
+ facility protocols {
+ level debug
+ }
+ }
+ }
+}
+traffic-policy {
+ shaper M2 {
+ bandwidth auto
+ class 10 {
+ bandwidth 100%
+ burst 15k
+ match ADDRESS10 {
+ ip {
+ dscp CS4
+ }
+ }
+ queue-type fair-queue
+ set-dscp CS5
+ }
+ default {
+ bandwidth 10mbit
+ burst 15k
+ queue-type fair-queue
+ }
+ }
+ shaper MY-HTB {
+ bandwidth 10mbit
+ class 30 {
+ bandwidth 10%
+ burst 15k
+ ceiling 50%
+ match ADDRESS30 {
+ ip {
+ source {
+ address 10.1.1.0/24
+ }
+ }
+ }
+ priority 5
+ queue-type fair-queue
+ }
+ class 40 {
+ bandwidth 90%
+ burst 15k
+ ceiling 100%
+ match ADDRESS40 {
+ ip {
+ dscp CS4
+ source {
+ address 10.2.1.0/24
+ }
+ }
+ }
+ priority 5
+ queue-type fair-queue
+ }
+ class 50 {
+ bandwidth 100%
+ burst 15k
+ match ADDRESS50 {
+ ip {
+ dscp CS5
+ }
+ }
+ queue-type fair-queue
+ set-dscp CS7
+ }
+ default {
+ bandwidth 10%
+ burst 15k
+ ceiling 100%
+ priority 7
+ queue-type fair-queue
+ set-dscp CS1
+ }
+ }
+ shaper FS {
+ bandwidth auto
+ class 10 {
+ bandwidth 100%
+ burst 15k
+ match ADDRESS10 {
+ ip {
+ source {
+ address 172.17.1.2/32
+ }
+ }
+ }
+ queue-type fair-queue
+ set-dscp CS4
+ }
+ class 20 {
+ bandwidth 100%
+ burst 15k
+ match ADDRESS20 {
+ ip {
+ source {
+ address 172.17.1.3/32
+ }
+ }
+ }
+ queue-type fair-queue
+ set-dscp CS5
+ }
+ class 30 {
+ bandwidth 100%
+ burst 15k
+ match ADDRESS30 {
+ ip {
+ source {
+ address 172.17.1.4/32
+ }
+ }
+ }
+ queue-type fair-queue
+ set-dscp CS6
+ }
+ default {
+ bandwidth 10%
+ burst 15k
+ ceiling 100%
+ priority 7
+ queue-type fair-queue
+ }
+ }
+}
+// Warning: Do not remove the following line.
+// vyos-config-version: "broadcast-relay@1:cluster@1:config-management@1:conntrack@3:conntrack-sync@2:dhcp-relay@2:dhcp-server@6:dhcpv6-server@1:dns-forwarding@3:firewall@5:https@2:interfaces@22:ipoe-server@1:ipsec@5:isis@1:l2tp@3:lldp@1:mdns@1:nat@5:ntp@1:pppoe-server@5:pptp@2:qos@1:quagga@8:rpki@1:salt@1:snmp@2:ssh@2:sstp@3:system@21:vrrp@2:vyos-accel-ppp@2:wanloadbalance@3:webproxy@2:zone-policy@1"
+// Release version: 1.3.1
+
diff --git a/smoketest/scripts/cli/test_interfaces_bonding.py b/smoketest/scripts/cli/test_interfaces_bonding.py
index 4f2fe979a..9bb561275 100755
--- a/smoketest/scripts/cli/test_interfaces_bonding.py
+++ b/smoketest/scripts/cli/test_interfaces_bonding.py
@@ -165,5 +165,27 @@ class BondingInterfaceTest(BasicInterfaceTest.TestCase):
self.cli_commit()
+ def test_bonding_uniq_member_description(self):
+ ethernet_path = ['interfaces', 'ethernet']
+ for interface in self._interfaces:
+ for option in self._options.get(interface, []):
+ self.cli_set(self._base_path + [interface] + option.split())
+
+ self.cli_commit()
+
+ # Add any changes on bonding members
+ # For example add description on separate ethX interfaces
+ for interface in self._interfaces:
+ for member in self._members:
+ self.cli_set(ethernet_path + [member, 'description', member + '_interface'])
+
+ self.cli_commit()
+
+ # verify config
+ for interface in self._interfaces:
+ slaves = read_file(f'/sys/class/net/{interface}/bonding/slaves').split()
+ for member in self._members:
+ self.assertIn(member, slaves)
+
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/src/etc/dhcp/dhclient-enter-hooks.d/03-vyos-ipwrapper b/src/etc/dhcp/dhclient-enter-hooks.d/03-vyos-ipwrapper
index fc035766b..2bd2d1d22 100644
--- a/src/etc/dhcp/dhclient-enter-hooks.d/03-vyos-ipwrapper
+++ b/src/etc/dhcp/dhclient-enter-hooks.d/03-vyos-ipwrapper
@@ -23,7 +23,7 @@ function iptovtysh () {
local VTYSH_GATEWAY=""
local VTYSH_DEV=""
local VTYSH_TAG="210"
- local VTYSH_DISTANCE=""
+ local VTYSH_DISTANCE=$IF_METRIC
# convert default route to 0.0.0.0/0
if [ "$4" == "default" ] ; then
VTYSH_NETADDR="0.0.0.0/0"
diff --git a/src/op_mode/restart_frr.py b/src/op_mode/restart_frr.py
index 109c8dd7b..e5014452f 100755
--- a/src/op_mode/restart_frr.py
+++ b/src/op_mode/restart_frr.py
@@ -138,7 +138,7 @@ def _reload_config(daemon):
# define program arguments
cmd_args_parser = argparse.ArgumentParser(description='restart frr daemons')
cmd_args_parser.add_argument('--action', choices=['restart'], required=True, help='action to frr daemons')
-cmd_args_parser.add_argument('--daemon', choices=['bfdd', 'bgpd', 'ospfd', 'ospf6d', 'isisd', 'ripd', 'ripngd', 'staticd', 'zebra'], required=False, nargs='*', help='select single or multiple daemons')
+cmd_args_parser.add_argument('--daemon', choices=['bfdd', 'bgpd', 'ldpd', 'ospfd', 'ospf6d', 'isisd', 'ripd', 'ripngd', 'staticd', 'zebra'], required=False, nargs='*', help='select single or multiple daemons')
# parse arguments
cmd_args = cmd_args_parser.parse_args()