summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile3
-rw-r--r--data/templates/accel-ppp/ipoe.config.tmpl28
-rw-r--r--data/templates/bcast-relay/udp-broadcast-relay.tmpl6
-rw-r--r--data/templates/conntrack/nftables-ct.tmpl32
-rw-r--r--data/templates/conntrack/sysctl.conf.tmpl2
-rw-r--r--data/templates/containers/registry.tmpl2
-rw-r--r--data/templates/dhcp-client/daemon-options.tmpl2
-rw-r--r--data/templates/dhcp-client/ipv4.tmpl8
-rw-r--r--data/templates/dhcp-client/ipv6.tmpl34
-rw-r--r--data/templates/dhcp-relay/dhcrelay.conf.tmpl2
-rw-r--r--data/templates/dhcp-relay/dhcrelay6.conf.tmpl10
-rw-r--r--data/templates/dhcp-server/dhcpd.conf.tmpl109
-rw-r--r--data/templates/dhcp-server/dhcpdv6.conf.tmpl70
-rw-r--r--data/templates/dns-forwarding/recursor.conf.tmpl3
-rw-r--r--data/templates/frr/bfdd.frr.tmpl26
-rw-r--r--data/templates/frr/bgpd.frr.tmpl440
-rw-r--r--data/templates/frr/isisd.frr.tmpl175
-rw-r--r--data/templates/frr/ldpd.frr.tmpl253
-rw-r--r--data/templates/frr/ospf6d.frr.tmpl74
-rw-r--r--data/templates/frr/ospfd.frr.tmpl154
-rw-r--r--data/templates/frr/policy.frr.tmpl196
-rw-r--r--data/templates/frr/rip_ripng.frr.j218
-rw-r--r--data/templates/frr/ripd.frr.tmpl62
-rw-r--r--data/templates/frr/ripngd.frr.tmpl46
-rw-r--r--data/templates/frr/rpki.frr.tmpl6
-rw-r--r--data/templates/frr/static_routes_macro.j222
-rw-r--r--data/templates/frr/staticd.frr.tmpl20
-rw-r--r--data/templates/frr/vrf-vni.frr.tmpl4
-rw-r--r--data/templates/frr/vrf.route-map.frr.tmpl4
-rw-r--r--data/templates/https/nginx.default.tmpl13
-rw-r--r--debian/vyos-1x.install1
-rw-r--r--interface-definitions/dhcp-server.xml.in5
-rw-r--r--interface-definitions/dns-forwarding.xml.in13
-rw-r--r--interface-definitions/include/accel-ppp/client-ip-pool-subnet-single.xml.i15
-rw-r--r--interface-definitions/include/firewall/common-rule.xml.i6
-rw-r--r--interface-definitions/include/interface/traffic-policy.xml.i43
-rw-r--r--interface-definitions/include/interface/vif-s.xml.i4
-rw-r--r--interface-definitions/include/interface/vif.xml.i2
-rw-r--r--interface-definitions/include/isis/high-low-label-value.xml.i26
-rw-r--r--interface-definitions/include/isis/password.xml.i20
-rw-r--r--interface-definitions/include/isis/protocol-common-config.xml.i110
-rw-r--r--interface-definitions/include/version/system-version.xml.i2
-rw-r--r--interface-definitions/interfaces-bonding.xml.in1
-rw-r--r--interface-definitions/interfaces-bridge.xml.in1
-rw-r--r--interface-definitions/interfaces-dummy.xml.in2
-rw-r--r--interface-definitions/interfaces-ethernet.xml.in1
-rw-r--r--interface-definitions/interfaces-geneve.xml.in2
-rw-r--r--interface-definitions/interfaces-input.xml.in1
-rw-r--r--interface-definitions/interfaces-l2tpv3.xml.in2
-rw-r--r--interface-definitions/interfaces-loopback.xml.in2
-rw-r--r--interface-definitions/interfaces-macsec.xml.in2
-rw-r--r--interface-definitions/interfaces-openvpn.xml.in2
-rw-r--r--interface-definitions/interfaces-pppoe.xml.in2
-rw-r--r--interface-definitions/interfaces-pseudo-ethernet.xml.in2
-rw-r--r--interface-definitions/interfaces-tunnel.xml.in2
-rw-r--r--interface-definitions/interfaces-vti.xml.in2
-rw-r--r--interface-definitions/interfaces-vxlan.xml.in2
-rw-r--r--interface-definitions/interfaces-wireguard.xml.in2
-rw-r--r--interface-definitions/interfaces-wireless.xml.in5
-rw-r--r--interface-definitions/interfaces-wwan.xml.in4
-rw-r--r--interface-definitions/policy.xml.in2
-rw-r--r--interface-definitions/qos.xml.in1148
-rw-r--r--interface-definitions/service_ipoe-server.xml.in16
-rw-r--r--interface-definitions/system-ipv6.xml.in6
-rw-r--r--op-mode-definitions/include/ospf-common.xml.i9
-rw-r--r--op-mode-definitions/monitor-log.xml.in73
-rw-r--r--op-mode-definitions/show-log.xml.in22
-rw-r--r--python/vyos/base.py6
-rw-r--r--python/vyos/configverify.py57
-rw-r--r--python/vyos/firewall.py2
-rwxr-xr-xpython/vyos/ifconfig/interface.py190
-rw-r--r--python/vyos/ifconfig/loopback.py12
-rw-r--r--python/vyos/template.py77
-rw-r--r--python/vyos/util.py9
-rw-r--r--smoketest/configs/dialup-router-complex3
-rw-r--r--smoketest/configs/ipv6-disable83
-rwxr-xr-xsmoketest/scripts/cli/test_firewall.py5
-rwxr-xr-xsmoketest/scripts/cli/test_policy.py34
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_bgp.py197
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_isis.py35
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_ospf.py6
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_ospfv3.py32
-rwxr-xr-xsmoketest/scripts/cli/test_service_https.py78
-rwxr-xr-xsmoketest/scripts/cli/test_service_ssh.py72
-rwxr-xr-xsmoketest/scripts/cli/test_system_ipv6.py36
-rwxr-xr-xsmoketest/scripts/cli/test_system_login.py8
-rwxr-xr-xsmoketest/scripts/cli/test_vrf.py83
-rwxr-xr-xsrc/conf_mode/dhcp_server.py4
-rwxr-xr-xsrc/conf_mode/dhcpv6_server.py4
-rwxr-xr-xsrc/conf_mode/dns_forwarding.py25
-rwxr-xr-xsrc/conf_mode/firewall.py6
-rwxr-xr-xsrc/conf_mode/interfaces-bonding.py6
-rwxr-xr-xsrc/conf_mode/interfaces-bridge.py6
-rwxr-xr-xsrc/conf_mode/interfaces-dummy.py4
-rwxr-xr-xsrc/conf_mode/interfaces-ethernet.py6
-rwxr-xr-xsrc/conf_mode/interfaces-geneve.py4
-rwxr-xr-xsrc/conf_mode/interfaces-l2tpv3.py4
-rwxr-xr-xsrc/conf_mode/interfaces-loopback.py4
-rwxr-xr-xsrc/conf_mode/interfaces-macsec.py4
-rwxr-xr-xsrc/conf_mode/interfaces-openvpn.py2
-rwxr-xr-xsrc/conf_mode/interfaces-pppoe.py4
-rwxr-xr-xsrc/conf_mode/interfaces-pseudo-ethernet.py4
-rwxr-xr-xsrc/conf_mode/interfaces-tunnel.py4
-rwxr-xr-xsrc/conf_mode/interfaces-vti.py4
-rwxr-xr-xsrc/conf_mode/interfaces-vxlan.py4
-rwxr-xr-xsrc/conf_mode/interfaces-wireguard.py4
-rwxr-xr-xsrc/conf_mode/interfaces-wireless.py4
-rwxr-xr-xsrc/conf_mode/interfaces-wwan.py99
-rwxr-xr-xsrc/conf_mode/policy.py9
-rwxr-xr-xsrc/conf_mode/protocols_bgp.py7
-rwxr-xr-xsrc/conf_mode/protocols_isis.py44
-rwxr-xr-xsrc/conf_mode/qos.py47
-rwxr-xr-xsrc/conf_mode/service_ipoe-server.py23
-rwxr-xr-xsrc/conf_mode/system-ipv6.py14
-rwxr-xr-xsrc/conf_mode/system-login.py21
-rwxr-xr-xsrc/conf_mode/vrf.py4
-rw-r--r--src/etc/cron.d/check-wwan1
-rwxr-xr-xsrc/migration-scripts/system/22-to-2350
-rwxr-xr-xsrc/services/vyos-http-api-server2
-rw-r--r--src/tests/test_util.py10
120 files changed, 2646 insertions, 2201 deletions
diff --git a/Makefile b/Makefile
index 54f3892ba..dc1301100 100644
--- a/Makefile
+++ b/Makefile
@@ -31,9 +31,8 @@ interface_definitions: $(config_xml_obj)
rm -rf $(TMPL_DIR)/vpn/ipsec/remote-access/radius/source-address
# T4284 neq QoS implementation is not yet live
- find $(TMPL_DIR)/interfaces -name traffic-policy -type d -exec rm -rf {} \;
find $(TMPL_DIR)/interfaces -name redirect -type d -exec rm -rf {} \;
- rm -rf $(TMPL_DIR)/traffic-policy
+ rm -rf $(TMPL_DIR)/qos
rm -rf $(TMPL_DIR)/interfaces/input
# XXX: test if there are empty node.def files - this is not allowed as these
diff --git a/data/templates/accel-ppp/ipoe.config.tmpl b/data/templates/accel-ppp/ipoe.config.tmpl
index 1cf2ab0be..92c2d5715 100644
--- a/data/templates/accel-ppp/ipoe.config.tmpl
+++ b/data/templates/accel-ppp/ipoe.config.tmpl
@@ -25,11 +25,21 @@ level=5
verbose=1
{% for interface in interfaces %}
{% if interface.vlan_mon %}
-interface=re:{{ interface.name }}\.\d+,{% else %}interface={{ interface.name }},{% endif %}shared={{ interface.shared }},mode={{ interface.mode }},ifcfg={{ interface.ifcfg }},range={{ interface.range }},start={{ interface.sess_start }},ipv6=1
+interface=re:{{ interface.name }}\.\d+,{% else %}interface={{ interface.name }},{% endif %}shared={{ interface.shared }},mode={{ interface.mode }},ifcfg={{ interface.ifcfg }}{{ ',range=' + interface.range if interface.range is defined and interface.range is not none }},start={{ interface.sess_start }},ipv6=1
{% endfor %}
-{% if auth_mode == 'noauth' %}
+{% if auth_mode == 'noauth' %}
noauth=1
-{% elif auth_mode == 'local' %}
+{% if client_named_ip_pool %}
+{% for pool in client_named_ip_pool %}
+{% if pool.subnet is defined %}
+ip-pool={{ pool.name }}
+{% endif %}
+{% if pool.gateway_address is defined %}
+gw-ip-address={{ pool.gateway_address }}/{{ pool.subnet.split('/')[1] }}
+{% endif %}
+{% endfor%}
+{% endif %}
+{% elif auth_mode == 'local' %}
username=ifname
password=csid
{% endif %}
@@ -61,6 +71,18 @@ verbose=1
[ipv6-dhcp]
verbose=1
+{% if client_named_ip_pool %}
+[ip-pool]
+{% for pool in client_named_ip_pool %}
+{% if pool.subnet is defined %}
+{{ pool.subnet }},name={{ pool.name }}
+{% endif %}
+{% if pool.gateway_address is defined %}
+gw-ip-address={{ pool.gateway_address }}/{{ pool.subnet.split('/')[1] }}
+{% endif %}
+{% endfor%}
+{% endif %}
+
{% if client_ipv6_pool %}
[ipv6-pool]
{% for p in client_ipv6_pool %}
diff --git a/data/templates/bcast-relay/udp-broadcast-relay.tmpl b/data/templates/bcast-relay/udp-broadcast-relay.tmpl
index 73e9acad4..7b2b9b1a2 100644
--- a/data/templates/bcast-relay/udp-broadcast-relay.tmpl
+++ b/data/templates/bcast-relay/udp-broadcast-relay.tmpl
@@ -1,7 +1,5 @@
### Autogenerated by bcast_relay.py ###
# UDP broadcast relay configuration for instance {{ id }}
-{% if description %}
-# Comment: {{ description }}
-{% endif %}
-DAEMON_ARGS="{{ '-s ' + address if address is defined }} {{ instance }} {{ port }} {{ interface | join(' ') }}"
+{{ '# ' ~ description if description is vyos_defined }}
+DAEMON_ARGS="{{ '-s ' ~ address if address is defined }} {{ instance }} {{ port }} {{ interface | join(' ') }}"
diff --git a/data/templates/conntrack/nftables-ct.tmpl b/data/templates/conntrack/nftables-ct.tmpl
index c0fe5297d..cebc1a54e 100644
--- a/data/templates/conntrack/nftables-ct.tmpl
+++ b/data/templates/conntrack/nftables-ct.tmpl
@@ -10,31 +10,27 @@ flush chain raw {{ nft_ct_timeout_name }}
table raw {
chain {{ nft_ct_ignore_name }} {
-{% if ignore is defined and ignore.rule is defined and ignore.rule is not none %}
+{% if ignore.rule is vyos_defined %}
{% for rule, rule_config in ignore.rule.items() %}
# rule-{{ rule }} {{ '- ' ~ rule_config.description if rule_config.description is defined and rule_config.description is not none }}
{% set nft_command = '' %}
-{% if rule_config.inbound_interface is defined and rule_config.inbound_interface is not none %}
+{% if rule_config.inbound_interface is vyos_defined %}
{% set nft_command = nft_command ~ ' iifname ' ~ rule_config.inbound_interface %}
{% endif %}
-{% if rule_config.protocol is defined and rule_config.protocol is not none %}
+{% if rule_config.protocol is vyos_defined %}
{% set nft_command = nft_command ~ ' ip protocol ' ~ rule_config.protocol %}
{% endif %}
-{% if rule_config.destination is defined and rule_config.destination is not none %}
-{% if rule_config.destination.address is defined and rule_config.destination.address is not none %}
-{% set nft_command = nft_command ~ ' ip daddr ' ~ rule_config.destination.address %}
-{% endif %}
-{% if rule_config.destination.port is defined and rule_config.destination.port is not none %}
-{% set nft_command = nft_command ~ ' ' ~ rule_config.protocol ~ ' dport { ' ~ rule_config.destination.port ~ ' }' %}
-{% endif %}
+{% if rule_config.destination.address is vyos_defined %}
+{% set nft_command = nft_command ~ ' ip daddr ' ~ rule_config.destination.address %}
{% endif %}
-{% if rule_config.source is defined and rule_config.source is not none %}
-{% if rule_config.source.address is defined and rule_config.source.address is not none %}
-{% set nft_command = nft_command ~ ' ip saddr ' ~ rule_config.source.address %}
-{% endif %}
-{% if rule_config.source.port is defined and rule_config.source.port is not none %}
-{% set nft_command = nft_command ~ ' ' ~ rule_config.protocol ~ ' sport { ' ~ rule_config.source.port ~ ' }' %}
-{% endif %}
+{% if rule_config.destination.port is vyos_defined %}
+{% set nft_command = nft_command ~ ' ' ~ rule_config.protocol ~ ' dport { ' ~ rule_config.destination.port ~ ' }' %}
+{% endif %}
+{% if rule_config.source.address is vyos_defined %}
+{% set nft_command = nft_command ~ ' ip saddr ' ~ rule_config.source.address %}
+{% endif %}
+{% if rule_config.source.port is vyos_defined %}
+{% set nft_command = nft_command ~ ' ' ~ rule_config.protocol ~ ' sport { ' ~ rule_config.source.port ~ ' }' %}
{% endif %}
{{ nft_command }} counter notrack comment ignore-{{ rule }}
{% endfor %}
@@ -42,7 +38,7 @@ table raw {
return
}
chain {{ nft_ct_timeout_name }} {
-{% if timeout is defined and timeout.custom is defined and timeout.custom.rule is defined and timeout.custom.rule is not none %}
+{% if timeout.custom.rule is vyos_defined %}
{% for rule, rule_config in timeout.custom.rule.items() %}
# rule-{{ rule }} {{ '- ' ~ rule_config.description if rule_config.description is defined and rule_config.description is not none }}
{% endfor %}
diff --git a/data/templates/conntrack/sysctl.conf.tmpl b/data/templates/conntrack/sysctl.conf.tmpl
index 9e97c3286..075402c04 100644
--- a/data/templates/conntrack/sysctl.conf.tmpl
+++ b/data/templates/conntrack/sysctl.conf.tmpl
@@ -6,7 +6,7 @@ net.netfilter.nf_conntrack_max = {{ table_size }}
net.ipv4.tcp_max_syn_backlog = {{ tcp.half_open_connections }}
-net.netfilter.nf_conntrack_tcp_loose = {{ '1' if tcp.loose == 'enable' else '0' }}
+net.netfilter.nf_conntrack_tcp_loose = {{ '1' if tcp.loose is vyos_defined('enable') else '0' }}
net.netfilter.nf_conntrack_tcp_max_retrans = {{ tcp.max_retrans }}
net.netfilter.nf_conntrack_icmp_timeout = {{ timeout.icmp }}
diff --git a/data/templates/containers/registry.tmpl b/data/templates/containers/registry.tmpl
index 0347de673..0cbd9ecc2 100644
--- a/data/templates/containers/registry.tmpl
+++ b/data/templates/containers/registry.tmpl
@@ -1,5 +1,5 @@
### Autogenerated by /usr/libexec/vyos/conf_mode/containers.py ###
-{% if registry is defined and registry is not none %}
+{% if registry is vyos_defined %}
unqualified-search-registries = {{ registry }}
{% endif %}
diff --git a/data/templates/dhcp-client/daemon-options.tmpl b/data/templates/dhcp-client/daemon-options.tmpl
index 40629dca1..5b3bff73f 100644
--- a/data/templates/dhcp-client/daemon-options.tmpl
+++ b/data/templates/dhcp-client/daemon-options.tmpl
@@ -1,4 +1,4 @@
### Autogenerated by interface.py ###
-DHCLIENT_OPTS="-nw -cf /var/lib/dhcp/dhclient_{{ifname}}.conf -pf /var/lib/dhcp/dhclient_{{ifname}}.pid -lf /var/lib/dhcp/dhclient_{{ifname}}.leases{{" -e IF_METRIC=" ~ dhcp_options.default_route_distance if dhcp_options.default_route_distance is defined and dhcp_options.default_route_distance is not none}} {{ifname}}"
+DHCLIENT_OPTS="-nw -cf /var/lib/dhcp/dhclient_{{ ifname }}.conf -pf /var/lib/dhcp/dhclient_{{ ifname }}.pid -lf /var/lib/dhcp/dhclient_{{ ifname }}.leases{{" -e IF_METRIC=" ~ dhcp_options.default_route_distance if dhcp_options.default_route_distance is vyos_defined }} {{ ifname }}"
diff --git a/data/templates/dhcp-client/ipv4.tmpl b/data/templates/dhcp-client/ipv4.tmpl
index b3e74c22b..83fb93dc1 100644
--- a/data/templates/dhcp-client/ipv4.tmpl
+++ b/data/templates/dhcp-client/ipv4.tmpl
@@ -7,7 +7,7 @@ initial-interval 2;
interface "{{ ifname }}" {
send host-name "{{ dhcp_options.host_name }}";
-{% if dhcp_options.client_id is defined and dhcp_options.client_id is not none %}
+{% if dhcp_options.client_id is vyos_defined %}
{% set client_id = dhcp_options.client_id %}
{# Use HEX representation of client-id as it is send in MAC-address style using hex characters. If not HEX, use double quotes ASCII format #}
{% if not dhcp_options.client_id.split(':') | length >= 5 %}
@@ -15,18 +15,18 @@ interface "{{ ifname }}" {
{% endif %}
send dhcp-client-identifier {{ client_id }};
{% endif %}
-{% if dhcp_options.vendor_class_id is defined and dhcp_options.vendor_class_id is not none %}
+{% if dhcp_options.vendor_class_id is vyos_defined %}
send vendor-class-identifier "{{ dhcp_options.vendor_class_id }}";
{% endif %}
# The request statement causes the client to request that any server responding to the
# client send the client its values for the specified options.
- request subnet-mask, broadcast-address,{{ " routers," if dhcp_options.no_default_route is not defined }} domain-name-servers,
+ request subnet-mask, broadcast-address,{{ " routers," if dhcp_options.no_default_route is not vyos_defined }} domain-name-servers,
rfc3442-classless-static-routes, domain-name, interface-mtu;
# The require statement lists options that must be sent in order for an offer to be
# accepted. Offers that do not contain all the listed options will be ignored!
require subnet-mask;
-{% if dhcp_options.reject is defined and dhcp_options.reject is not none %}
+{% if dhcp_options.reject is vyos_defined %}
# Block addresses coming from theses dhcp servers if configured.
reject {{ dhcp_options.reject | join(', ') }};
{% endif %}
diff --git a/data/templates/dhcp-client/ipv6.tmpl b/data/templates/dhcp-client/ipv6.tmpl
index c292664e9..085cfe5a9 100644
--- a/data/templates/dhcp-client/ipv6.tmpl
+++ b/data/templates/dhcp-client/ipv6.tmpl
@@ -2,54 +2,54 @@
# man https://www.unix.com/man-page/debian/5/dhcp6c.conf/
interface {{ ifname }} {
-{% if dhcpv6_options is defined and dhcpv6_options.duid is defined and dhcpv6_options.duid is not none %}
+{% if dhcpv6_options.duid is vyos_defined %}
send client-id {{ dhcpv6_options.duid }};
{% endif %}
-{% if address is defined and 'dhcpv6' in address %}
+{% if address is vyos_defined and 'dhcpv6' in address %}
request domain-name-servers;
request domain-name;
-{% if dhcpv6_options is defined and dhcpv6_options.parameters_only is defined %}
+{% if dhcpv6_options.parameters_only is vyos_defined %}
information-only;
{% endif %}
-{% if dhcpv6_options is not defined or dhcpv6_options.temporary is not defined %}
+{% if dhcpv6_options.temporary is not vyos_defined %}
send ia-na 0; # non-temporary address
{% endif %}
-{% if dhcpv6_options is defined and dhcpv6_options.rapid_commit is defined %}
+{% if dhcpv6_options.rapid_commit is vyos_defined %}
send rapid-commit; # wait for immediate reply instead of advertisements
{% endif %}
{% endif %}
-{% if dhcpv6_options is defined and dhcpv6_options.pd is defined %}
+{% if dhcpv6_options.pd is vyos_defined %}
{% for pd in dhcpv6_options.pd %}
send ia-pd {{ pd }}; # prefix delegation #{{ pd }}
{% endfor %}
{% endif %}
};
-{% if address is defined and 'dhcpv6' in address %}
-{% if dhcpv6_options is not defined or dhcpv6_options.temporary is not defined %}
+{% if address is vyos_defined and 'dhcpv6' in address %}
+{% if dhcpv6_options.temporary is not vyos_defined %}
id-assoc na 0 {
# Identity association for non temporary address
};
{% endif %}
{% endif %}
-{% if dhcpv6_options is defined and dhcpv6_options.pd is defined %}
-{% for pd in dhcpv6_options.pd %}
+{% if dhcpv6_options.pd is vyos_defined %}
+{% for pd, pd_config in dhcpv6_options.pd.items() %}
id-assoc pd {{ pd }} {
{# length got a default value #}
- prefix ::/{{ dhcpv6_options.pd[pd].length }} infinity;
-{% set sla_len = 64 - dhcpv6_options.pd[pd].length|int %}
+ prefix ::/{{ pd_config.length }} infinity;
+{% set sla_len = 64 - pd_config.length|int %}
{% set count = namespace(value=0) %}
-{% for interface in dhcpv6_options.pd[pd].interface if dhcpv6_options.pd[pd].interface is defined %}
+{% for interface, interface_config in pd_config.interface.items() if pd_config.interface is vyos_defined %}
prefix-interface {{ interface }} {
sla-len {{ sla_len }};
-{% if dhcpv6_options.pd[pd].interface[interface].sla_id is defined and dhcpv6_options.pd[pd].interface[interface].sla_id is not none %}
- sla-id {{ dhcpv6_options.pd[pd].interface[interface].sla_id }};
+{% if interface_config.sla_id is vyos_defined %}
+ sla-id {{ interface_config.sla_id }};
{% else %}
sla-id {{ count.value }};
{% endif %}
-{% if dhcpv6_options.pd[pd].interface[interface].address is defined and dhcpv6_options.pd[pd].interface[interface].address is not none %}
- ifid {{ dhcpv6_options.pd[pd].interface[interface].address }};
+{% if interface_config.address is vyos_defined %}
+ ifid {{ interface_config.address }};
{% endif %}
};
{% set count.value = count.value + 1 %}
diff --git a/data/templates/dhcp-relay/dhcrelay.conf.tmpl b/data/templates/dhcp-relay/dhcrelay.conf.tmpl
index a9d17ed9a..11710bd8e 100644
--- a/data/templates/dhcp-relay/dhcrelay.conf.tmpl
+++ b/data/templates/dhcp-relay/dhcrelay.conf.tmpl
@@ -1,6 +1,6 @@
### Autogenerated by dhcp_relay.py ###
-{% set max_size = '-A ' + relay_options.max_size if relay_options.max_size is defined and relay_options.max_size is not none %}
+{% set max_size = '-A ' ~ relay_options.max_size if relay_options.max_size is vyos_defined %}
{# hop_count and relay_agents_packets is a default option, thus it is always present #}
OPTIONS="-c {{ relay_options.hop_count }} -a -m {{ relay_options.relay_agents_packets }} {{ max_size }} -i {{ interface | join(' -i ') }} {{ server | join(' ') }}"
diff --git a/data/templates/dhcp-relay/dhcrelay6.conf.tmpl b/data/templates/dhcp-relay/dhcrelay6.conf.tmpl
index 58c216b7c..1fd5de18c 100644
--- a/data/templates/dhcp-relay/dhcrelay6.conf.tmpl
+++ b/data/templates/dhcp-relay/dhcrelay6.conf.tmpl
@@ -4,18 +4,18 @@
{% set upstream = namespace(value='') %}
{% for interface, config in upstream_interface.items() %}
{% for address in config.address %}
-{% set upstream.value = upstream.value + '-u ' + address + '%' + interface + ' ' %}
+{% set upstream.value = upstream.value ~ '-u ' ~ address ~ '%' ~ interface ~ ' ' %}
{% endfor %}
{% endfor %}
{# listen_interface is mandatory so it's always present #}
{% set listen = namespace(value='') %}
{% for interface, config in listen_interface.items() %}
-{% if config.address is defined and config.address is not none %}
-{% set listen.value = listen.value + '-l ' + config.address + '%' + interface + ' ' %}
+{% if config.address is vyos_defined %}
+{% set listen.value = listen.value ~ '-l ' ~ config.address ~ '%' ~ interface ~ ' ' %}
{% else %}
-{% set listen.value = listen.value + '-l ' + interface + ' ' %}
+{% set listen.value = listen.value ~ '-l ' ~ interface ~ ' ' %}
{% endif %}
{% endfor %}
-OPTIONS="{{ listen.value }} {{ upstream.value }} -c {{ max_hop_count }} {{ '-I' if use_interface_id_option is defined }}"
+OPTIONS="{{ listen.value }} {{ upstream.value }} -c {{ max_hop_count }} {{ '-I' if use_interface_id_option is vyos_defined }}"
diff --git a/data/templates/dhcp-server/dhcpd.conf.tmpl b/data/templates/dhcp-server/dhcpd.conf.tmpl
index dbd864b5e..00f6eba8e 100644
--- a/data/templates/dhcp-server/dhcpd.conf.tmpl
+++ b/data/templates/dhcp-server/dhcpd.conf.tmpl
@@ -4,7 +4,7 @@
# https://www.isc.org/wp-content/uploads/2017/08/dhcp43options.html
#
# log-facility local7;
-{% if hostfile_update is defined %}
+{% if hostfile_update is vyos_defined %}
on release {
set ClientName = pick-first-value(host-decl-name, option fqdn.hostname, option host-name);
set ClientIp = binary-to-ascii(10, 8, ".",leased-address);
@@ -17,13 +17,13 @@ on expiry {
}
{% endif %}
-{{ 'use-host-decl-names on;' if host_decl_name is defined }}
-ddns-update-style {{ 'interim' if dynamic_dns_update is defined else 'none' }};
+{{ 'use-host-decl-names on;' if host_decl_name is vyos_defined }}
+ddns-update-style {{ 'interim' if dynamic_dns_update is vyos_defined else 'none' }};
option rfc3442-static-route code 121 = array of integer 8;
option windows-static-route code 249 = array of integer 8;
option wpad-url code 252 = text;
-{% if global_parameters is defined and global_parameters is not none %}
+{% if global_parameters is vyos_defined %}
# The following {{ global_parameters | length }} line(s) have been added as
# global-parameters in the CLI and have not been validated !!!
{% for parameter in global_parameters %}
@@ -31,7 +31,7 @@ option wpad-url code 252 = text;
{% endfor %}
{% endif %}
-{% if failover is defined and failover is not none %}
+{% if failover is vyos_defined %}
# DHCP failover configuration
failover peer "{{ failover.name }}" {
{% if failover.status == 'primary' %}
@@ -50,7 +50,7 @@ failover peer "{{ failover.name }}" {
load balance max seconds 3;
}
{% endif %}
-{% if listen_address is defined and listen_address is not none %}
+{% if listen_address is vyos_defined %}
# DHCP server serving relay subnet, we need a connector to the real world
{% for address in listen_address %}
@@ -60,70 +60,70 @@ subnet {{ address | network_from_ipv4 }} netmask {{ address | netmask_from_ipv4
{% endif %}
# Shared network configration(s)
-{% if shared_network_name is defined and shared_network_name is not none %}
-{% for network, network_config in shared_network_name.items() if network_config.disable is not defined %}
-shared-network {{ network | replace('_','-') }} {
-{% if network_config.authoritative is defined %}
+{% if shared_network_name is vyos_defined %}
+{% for network, network_config in shared_network_name.items() if network_config.disable is not vyos_defined %}
+shared-network {{ network }} {
+{% if network_config.authoritative is vyos_defined %}
authoritative;
{% endif %}
-{% if network_config.name_server is defined and network_config.name_server is not none %}
+{% if network_config.name_server is vyos_defined %}
option domain-name-servers {{ network_config.name_server | join(', ') }};
{% endif %}
-{% if network_config.domain_name is defined and network_config.domain_name is not none %}
+{% if network_config.domain_name is vyos_defined %}
option domain-name "{{ network_config.domain_name }}";
{% endif %}
-{% if network_config.domain_search is defined and network_config.domain_search is not none %}
+{% if network_config.domain_search is vyos_defined %}
option domain-search "{{ network_config.domain_search | join('", "') }}";
{% endif %}
-{% if network_config.ntp_server is defined and network_config.ntp_server is not none %}
+{% if network_config.ntp_server is vyos_defined %}
option ntp-servers {{ network_config.ntp_server | join(', ') }};
{% endif %}
-{% if network_config.ping_check is defined %}
+{% if network_config.ping_check is vyos_defined %}
ping-check true;
{% endif %}
-{% if network_config.shared_network_parameters is defined and network_config.shared_network_parameters is not none %}
+{% if network_config.shared_network_parameters is vyos_defined %}
# The following {{ network_config.shared_network_parameters | length }} line(s)
# were added as shared-network-parameters in the CLI and have not been validated
{% for parameter in network_config.shared_network_parameters %}
{{ parameter }}
{% endfor %}
{% endif %}
-{% if network_config.subnet is defined and network_config.subnet is not none %}
+{% if network_config.subnet is vyos_defined %}
{% for subnet, subnet_config in network_config.subnet.items() %}
-{% if subnet_config.description is defined and subnet_config.description is not none %}
+{% if subnet_config.description is vyos_defined %}
# {{ subnet_config.description }}
{% endif %}
subnet {{ subnet | address_from_cidr }} netmask {{ subnet | netmask_from_cidr }} {
-{% if subnet_config.name_server is defined and subnet_config.name_server is not none %}
+{% if subnet_config.name_server is vyos_defined %}
option domain-name-servers {{ subnet_config.name_server | join(', ') }};
{% endif %}
-{% if subnet_config.domain_name is defined and subnet_config.domain_name is not none %}
+{% if subnet_config.domain_name is vyos_defined %}
option domain-name "{{ subnet_config.domain_name }}";
{% endif %}
-{% if subnet_config.domain_search is defined and subnet_config.domain_search is not none %}
+{% if subnet_config.domain_search is vyos_defined %}
option domain-search "{{ subnet_config.domain_search | join('", "') }}";
{% endif %}
-{% if subnet_config.ntp_server is defined and subnet_config.ntp_server is not none %}
+{% if subnet_config.ntp_server is vyos_defined %}
option ntp-servers {{ subnet_config.ntp_server | join(', ') }};
{% endif %}
-{% if subnet_config.pop_server is defined and subnet_config.pop_server is not none %}
+{% if subnet_config.pop_server is vyos_defined %}
option pop-server {{ subnet_config.pop_server | join(', ') }};
{% endif %}
-{% if subnet_config.smtp_server is defined and subnet_config.smtp_server is not none %}
+{% if subnet_config.smtp_server is vyos_defined %}
option smtp-server {{ subnet_config.smtp_server | join(', ') }};
{% endif %}
-{% if subnet_config.time_server is defined and subnet_config.time_server is not none %}
+{% if subnet_config.time_server is vyos_defined %}
option time-servers {{ subnet_config.time_server | join(', ') }};
{% endif %}
-{% if subnet_config.wins_server is defined and subnet_config.wins_server is not none %}
+{% if subnet_config.wins_server is vyos_defined %}
option netbios-name-servers {{ subnet_config.wins_server | join(', ') }};
{% endif %}
-{% if subnet_config.static_route is defined and subnet_config.static_route is not none %}
+{% if subnet_config.static_route is vyos_defined %}
{% set static_default_route = '' %}
-{% if subnet_config.default_router and subnet_config.default_router is not none %}
-{% set static_default_route = ', ' + '0.0.0.0/0' | isc_static_route(subnet_config.default_router) %}
+{% if subnet_config.default_router is vyos_defined %}
+{% set static_default_route = ', ' ~ '0.0.0.0/0' | isc_static_route(subnet_config.default_router) %}
{% endif %}
-{% if subnet_config.static_route is defined and subnet_config.static_route is not none %}
+{% if subnet_config.static_route is vyos_defined %}
{% set rfc3442_routes = [] %}
{% for route, route_options in subnet_config.static_route.items() %}
{% set rfc3442_routes = rfc3442_routes.append(route | isc_static_route(route_options.next_hop)) %}
@@ -132,56 +132,59 @@ shared-network {{ network | replace('_','-') }} {
option windows-static-route {{ rfc3442_routes | join(', ') }};
{% endif %}
{% endif %}
-{% if subnet_config.ip_forwarding is defined %}
+{% if subnet_config.ip_forwarding is vyos_defined %}
option ip-forwarding true;
{% endif %}
-{% if subnet_config.default_router and subnet_config.default_router is not none %}
+{% if subnet_config.default_router is vyos_defined %}
option routers {{ subnet_config.default_router }};
{% endif %}
-{% if subnet_config.server_identifier is defined and subnet_config.server_identifier is not none %}
+{% if subnet_config.server_identifier is vyos_defined %}
option dhcp-server-identifier {{ subnet_config.server_identifier }};
{% endif %}
-{% if subnet_config.subnet_parameters is defined and subnet_config.subnet_parameters is not none %}
+{% if subnet_config.subnet_parameters is vyos_defined %}
# The following {{ subnet_config.subnet_parameters | length }} line(s) were added as
# subnet-parameters in the CLI and have not been validated!!!
{% for parameter in subnet_config.subnet_parameters %}
{{ parameter }}
{% endfor %}
{% endif %}
-{% if subnet_config.tftp_server_name is defined and subnet_config.tftp_server_name is not none %}
+{% if subnet_config.tftp_server_name is vyos_defined %}
option tftp-server-name "{{ subnet_config.tftp_server_name }}";
{% endif %}
-{% if subnet_config.bootfile_name is defined and subnet_config.bootfile_name is not none %}
+{% if subnet_config.bootfile_name is vyos_defined %}
option bootfile-name "{{ subnet_config.bootfile_name }}";
filename "{{ subnet_config.bootfile_name }}";
{% endif %}
-{% if subnet_config.bootfile_server is defined and subnet_config.bootfile_server is not none %}
+{% if subnet_config.bootfile_server is vyos_defined %}
next-server {{ subnet_config.bootfile_server }};
{% endif %}
-{% if subnet_config.time_offset is defined and subnet_config.time_offset is not none %}
+{% if subnet_config.bootfile_size is defined and subnet_config.bootfile_size is not none %}
+ option boot-size {{ subnet_config.bootfile_size }};
+{% endif %}
+{% if subnet_config.time_offset is vyos_defined %}
option time-offset {{ subnet_config.time_offset }};
{% endif %}
-{% if subnet_config.wpad_url is defined and subnet_config.wpad_url is not none %}
+{% if subnet_config.wpad_url is vyos_defined %}
option wpad-url "{{ subnet_config.wpad_url }}";
{% endif %}
-{% if subnet_config.client_prefix_length is defined and subnet_config.client_prefix_length is not none %}
+{% if subnet_config.client_prefix_length is vyos_defined %}
option subnet-mask {{ ('0.0.0.0/' ~ subnet_config.client_prefix_length) | netmask_from_cidr }};
{% endif %}
-{% if subnet_config.lease is defined and subnet_config.lease is not none %}
+{% if subnet_config.lease is vyos_defined %}
default-lease-time {{ subnet_config.lease }};
max-lease-time {{ subnet_config.lease }};
{% endif %}
-{% if network_config.ping_check is not defined and subnet_config.ping_check is defined %}
+{% if network_config.ping_check is not vyos_defined and subnet_config.ping_check is vyos_defined %}
ping-check true;
{% endif %}
-{% if subnet_config.static_mapping is defined and subnet_config.static_mapping is not none %}
-{% for host, host_config in subnet_config.static_mapping.items() if host_config.disable is not defined %}
- host {{ host | replace('_','-') if host_decl_name is defined else network | replace('_','-') + '_' + host | replace('_','-') }} {
-{% if host_config.ip_address is defined and host_config.ip_address is not none %}
+{% if subnet_config.static_mapping is vyos_defined %}
+{% for host, host_config in subnet_config.static_mapping.items() if host_config.disable is not vyos_defined %}
+ host {{ host | replace('_','-') if host_decl_name is vyos_defined else network | replace('_','-') ~ '_' ~ host | replace('_','-') }} {
+{% if host_config.ip_address is vyos_defined %}
fixed-address {{ host_config.ip_address }};
{% endif %}
hardware ethernet {{ host_config.mac_address }};
-{% if host_config.static_mapping_parameters is defined and host_config.static_mapping_parameters is not none %}
+{% if host_config.static_mapping_parameters is vyos_defined %}
# The following {{ host_config.static_mapping_parameters | length }} line(s) were added
# as static-mapping-parameters in the CLI and have not been validated
{% for parameter in host_config.static_mapping_parameters %}
@@ -191,20 +194,20 @@ shared-network {{ network | replace('_','-') }} {
}
{% endfor %}
{% endif %}
-{% if subnet_config.range is defined and subnet_config.range is not none %}
+{% if subnet_config.range is vyos_defined %}
{# pool configuration can only be used if there follows a range option #}
pool {
{% endif %}
-{% if subnet_config.enable_failover is defined %}
+{% if subnet_config.enable_failover is vyos_defined %}
failover peer "{{ failover.name }}";
deny dynamic bootp clients;
{% endif %}
-{% if subnet_config.range is defined and subnet_config.range is not none %}
+{% if subnet_config.range is vyos_defined %}
{% for range, range_options in subnet_config.range.items() %}
range {{ range_options.start }} {{ range_options.stop }};
{% endfor %}
{% endif %}
-{% if subnet_config.range is defined and subnet_config.range is not none %}
+{% if subnet_config.range is vyos_defined %}
{# pool configuration can only be used if there follows a range option #}
}
{% endif %}
@@ -212,8 +215,8 @@ shared-network {{ network | replace('_','-') }} {
{% endfor %}
{% endif %}
on commit {
- set shared-networkname = "{{ network | replace('_','-') }}";
-{% if hostfile_update is defined %}
+ set shared-networkname = "{{ network }}";
+{% if hostfile_update is vyos_defined %}
set ClientIp = binary-to-ascii(10, 8, ".", leased-address);
set ClientMac = binary-to-ascii(16, 8, ":", substring(hardware, 1, 6));
set ClientName = pick-first-value(host-decl-name, option fqdn.hostname, option host-name, "empty_hostname");
diff --git a/data/templates/dhcp-server/dhcpdv6.conf.tmpl b/data/templates/dhcp-server/dhcpdv6.conf.tmpl
index 45d629928..1a55668e1 100644
--- a/data/templates/dhcp-server/dhcpdv6.conf.tmpl
+++ b/data/templates/dhcp-server/dhcpdv6.conf.tmpl
@@ -4,74 +4,74 @@
# https://www.isc.org/wp-content/uploads/2017/08/dhcp43options.html
log-facility local7;
-{% if preference is defined and preference is not none %}
+{% if preference is vyos_defined %}
option dhcp6.preference {{ preference }};
{% endif %}
-{% if global_parameters is defined and global_parameters.name_server is defined and global_parameters.name_server is not none %}
+{% if global_parameters.name_server is vyos_defined %}
option dhcp6.name-servers {{ global_parameters.name_server | join(', ') }};
{% endif %}
# Shared network configration(s)
-{% if shared_network_name is defined and shared_network_name is not none %}
-{% for network, network_config in shared_network_name.items() if network_config.disable is not defined %}
-shared-network {{ network | replace('_','-') }} {
-{% if network_config.common_options is defined and network_config.common_options is not none %}
-{% if network_config.common_options.info_refresh_time is defined and network_config.common_options.info_refresh_time is not none %}
+{% if shared_network_name is vyos_defined %}
+{% for network, network_config in shared_network_name.items() if network_config.disable is not vyos_defined %}
+shared-network {{ network }} {
+{% if network_config.common_options is vyos_defined %}
+{% if network_config.common_options.info_refresh_time is vyos_defined %}
option dhcp6.info-refresh-time {{ network_config.common_options.info_refresh_time }};
{% endif %}
-{% if network_config.common_options.domain_search is defined and network_config.common_options.domain_search is not none %}
+{% if network_config.common_options.domain_search is vyos_defined %}
option dhcp6.domain-search "{{ network_config.common_options.domain_search | join('", "') }}";
{% endif %}
-{% if network_config.common_options.name_server is defined and network_config.common_options.name_server is not none %}
+{% if network_config.common_options.name_server is vyos_defined %}
option dhcp6.name-servers {{ network_config.common_options.name_server | join(', ') }};
{% endif %}
{% endif %}
-{% if network_config.subnet is defined and network_config.subnet is not none %}
+{% if network_config.subnet is vyos_defined %}
{% for subnet, subnet_config in network_config.subnet.items() %}
subnet6 {{ subnet }} {
-{% if subnet_config.address_range is defined and subnet_config.address_range is not none %}
-{% if subnet_config.address_range.prefix is defined and subnet_config.address_range.prefix is not none %}
+{% if subnet_config.address_range is vyos_defined %}
+{% if subnet_config.address_range.prefix is vyos_defined %}
{% for prefix, prefix_config in subnet_config.address_range.prefix.items() %}
- range6 {{ prefix }} {{ "temporary" if prefix_config.temporary is defined }};
+ range6 {{ prefix }} {{ "temporary" if prefix_config.temporary is vyos_defined }};
{% endfor %}
{% endif %}
-{% if subnet_config.address_range.start is defined and subnet_config.address_range.start is not none %}
+{% if subnet_config.address_range.start is vyos_defined %}
{% for address, address_config in subnet_config.address_range.start.items() %}
range6 {{ address }} {{ address_config.stop }};
{% endfor %}
{% endif %}
{% endif %}
-{% if subnet_config.domain_search is defined and subnet_config.domain_search is not none %}
+{% if subnet_config.domain_search is vyos_defined %}
option dhcp6.domain-search "{{ subnet_config.domain_search | join('", "') }}";
{% endif %}
-{% if subnet_config.lease_time is defined and subnet_config.lease_time is not none %}
-{% if subnet_config.lease_time.default is defined and subnet_config.lease_time.default is not none %}
+{% if subnet_config.lease_time is vyos_defined %}
+{% if subnet_config.lease_time.default is vyos_defined %}
default-lease-time {{ subnet_config.lease_time.default }};
{% endif %}
-{% if subnet_config.lease_time.maximum is defined and subnet_config.lease_time.maximum is not none %}
+{% if subnet_config.lease_time.maximum is vyos_defined %}
max-lease-time {{ subnet_config.lease_time.maximum }};
{% endif %}
-{% if subnet_config.lease_time.minimum is defined and subnet_config.lease_time.minimum is not none %}
+{% if subnet_config.lease_time.minimum is vyos_defined %}
min-lease-time {{ subnet_config.lease_time.minimum }};
{% endif %}
{% endif %}
-{% if subnet_config.name_server is defined and subnet_config.name_server is not none %}
+{% if subnet_config.name_server is vyos_defined %}
option dhcp6.name-servers {{ subnet_config.name_server | join(', ') }};
{% endif %}
-{% if subnet_config.nis_domain is defined and subnet_config.nis_domain is not none %}
+{% if subnet_config.nis_domain is vyos_defined %}
option dhcp6.nis-domain-name "{{ subnet_config.nis_domain }}";
{% endif %}
-{% if subnet_config.nis_server is defined and subnet_config.nis_server is not none %}
+{% if subnet_config.nis_server is vyos_defined %}
option dhcp6.nis-servers {{ subnet_config.nis_server | join(', ') }};
{% endif %}
-{% if subnet_config.nisplus_domain is defined and subnet_config.nisplus_domain is not none %}
+{% if subnet_config.nisplus_domain is vyos_defined %}
option dhcp6.nisp-domain-name "{{ subnet_config.nisplus_domain }}";
{% endif %}
-{% if subnet_config.nisplus_server is defined and subnet_config.nisplus_server is not none %}
+{% if subnet_config.nisplus_server is vyos_defined %}
option dhcp6.nisp-servers {{ subnet_config.nisplus_server | join(', ') }};
{% endif %}
-{% if subnet_config.sip_server is defined and subnet_config.sip_server is not none %}
+{% if subnet_config.sip_server is vyos_defined %}
{% set server_ip = [] %}
{% set server_fqdn = [] %}
{% for address in subnet_config.sip_server %}
@@ -81,33 +81,33 @@ shared-network {{ network | replace('_','-') }} {
{% set server_fqdn = server_fqdn.append(address) %}
{% endif %}
{% endfor %}
-{% if server_ip is defined and server_ip | length > 0 %}
+{% if server_ip is vyos_defined and server_ip | length > 0 %}
option dhcp6.sip-servers-addresses {{ server_ip | join(', ') }};
{% endif %}
-{% if server_fqdn is defined and server_fqdn | length > 0 %}
+{% if server_fqdn is vyos_defined and server_fqdn | length > 0 %}
option dhcp6.sip-servers-names "{{ server_fqdn | join('", "') }}";
{% endif %}
{% endif %}
-{% if subnet_config.sntp_server is defined and subnet_config.sntp_server is not none %}
+{% if subnet_config.sntp_server is vyos_defined %}
option dhcp6.sntp-servers {{ subnet_config.sntp_server | join(', ') }};
{% endif %}
-{% if subnet_config.prefix_delegation is defined and subnet_config.prefix_delegation.start is defined and subnet_config.prefix_delegation.start is not none %}
+{% if subnet_config.prefix_delegation.start is vyos_defined %}
{% for prefix, prefix_config in subnet_config.prefix_delegation.start.items() %}
prefix6 {{ prefix }} {{ prefix_config.stop }} /{{ prefix_config.prefix_length }};
{% endfor %}
{% endif %}
-{% if subnet_config.static_mapping is defined and subnet_config.static_mapping is not none %}
+{% if subnet_config.static_mapping is vyos_defined %}
# begin configuration of static client mappings
-{% for host, host_config in subnet_config.static_mapping.items() if host_config.disable is not defined %}
+{% for host, host_config in subnet_config.static_mapping.items() if host_config.disable is not vyos_defined %}
host {{ network | replace('_','-') }}_{{ host | replace('_','-') }} {
-{% if host_config.identifier is defined and host_config.identifier is not none %}
+{% if host_config.identifier is vyos_defined %}
host-identifier option dhcp6.client-id {{ host_config.identifier }};
{% endif %}
-{% if host_config.ipv6_address is defined and host_config.ipv6_address is not none %}
+{% if host_config.ipv6_address is vyos_defined %}
fixed-address6 {{ host_config.ipv6_address }};
{% endif %}
-{% if host_config.ipv6_prefix is defined and host_config.ipv6_prefix is not none %}
+{% if host_config.ipv6_prefix is vyos_defined %}
fixed-prefix6 {{ host_config.ipv6_prefix }};
{% endif %}
}
@@ -117,7 +117,7 @@ shared-network {{ network | replace('_','-') }} {
{% endfor %}
{% endif %}
on commit {
- set shared-networkname = "{{ network | replace('_','-') }}";
+ set shared-networkname = "{{ network }}";
}
}
{% endfor %}
diff --git a/data/templates/dns-forwarding/recursor.conf.tmpl b/data/templates/dns-forwarding/recursor.conf.tmpl
index 02efe903b..d4ec80a3a 100644
--- a/data/templates/dns-forwarding/recursor.conf.tmpl
+++ b/data/templates/dns-forwarding/recursor.conf.tmpl
@@ -19,6 +19,9 @@ max-cache-entries={{ cache_size }}
# negative TTL for NXDOMAIN
max-negative-ttl={{ negative_ttl }}
+# timeout
+network-timeout={{ timeout }}
+
# ignore-hosts-file
export-etc-hosts={{ 'no' if ignore_hosts_file is defined else 'yes' }}
diff --git a/data/templates/frr/bfdd.frr.tmpl b/data/templates/frr/bfdd.frr.tmpl
index 439f79d67..ac55d4634 100644
--- a/data/templates/frr/bfdd.frr.tmpl
+++ b/data/templates/frr/bfdd.frr.tmpl
@@ -1,22 +1,22 @@
-{% if profile is defined or peer is defined %}
+{% if profile is vyos_defined or peer is vyos_defined %}
bfd
-{% if profile is defined and profile is not none %}
+{% if profile is vyos_defined %}
{% for profile_name, profile_config in profile.items() %}
profile {{ profile_name }}
detect-multiplier {{ profile_config.interval.multiplier }}
receive-interval {{ profile_config.interval.receive }}
transmit-interval {{ profile_config.interval.transmit }}
-{% if profile_config.interval.echo_interval is defined and profile_config.interval.echo_interval is not none %}
+{% if profile_config.interval.echo_interval is vyos_defined %}
echo transmit-interval {{ profile_config.interval.echo_interval }}
echo receive-interval {{ profile_config.interval.echo_interval }}
{% endif %}
-{% if profile_config.echo_mode is defined %}
+{% if profile_config.echo_mode is vyos_defined %}
echo-mode
{% endif %}
-{% if profile_config.passive is defined %}
+{% if profile_config.passive is vyos_defined %}
passive-mode
{% endif %}
-{% if profile_config.shutdown is defined %}
+{% if profile_config.shutdown is vyos_defined %}
shutdown
{% else %}
no shutdown
@@ -25,26 +25,26 @@ bfd
!
{% endfor %}
{% endif %}
-{% if peer is defined and peer is not none %}
+{% if peer is vyos_defined %}
{% for peer_name, peer_config in peer.items() %}
- peer {{ peer_name }}{{ ' multihop' if peer_config.multihop is defined }}{{ ' local-address ' + peer_config.source.address if peer_config.source is defined and peer_config.source.address is defined }}{{ ' interface ' + peer_config.source.interface if peer_config.source is defined and peer_config.source.interface is defined }} {{ ' vrf ' + peer_config.vrf if peer_config.vrf is defined and peer_config.vrf is not none }}
+ peer {{ peer_name }}{{ ' multihop' if peer_config.multihop is vyos_defined }}{{ ' local-address ' + peer_config.source.address if peer_config.source.address is vyos_defined }}{{ ' interface ' + peer_config.source.interface if peer_config.source.interface is vyos_defined }} {{ ' vrf ' + peer_config.vrf if peer_config.vrf is vyos_defined }}
detect-multiplier {{ peer_config.interval.multiplier }}
receive-interval {{ peer_config.interval.receive }}
transmit-interval {{ peer_config.interval.transmit }}
-{% if peer_config.interval.echo_interval is defined and peer_config.interval.echo_interval is not none %}
+{% if peer_config.interval.echo_interval is vyos_defined %}
echo transmit-interval {{ peer_config.interval.echo_interval }}
echo receive-interval {{ peer_config.interval.echo_interval }}
{% endif %}
-{% if peer_config.echo_mode is defined %}
+{% if peer_config.echo_mode is vyos_defined %}
echo-mode
{% endif %}
-{% if peer_config.passive is defined %}
+{% if peer_config.passive is vyos_defined %}
passive-mode
{% endif %}
-{% if peer_config.profile is defined and peer_config.profile is not none %}
+{% if peer_config.profile is vyos_defined %}
profile {{ peer_config.profile }}
{% endif %}
-{% if peer_config.shutdown is defined %}
+{% if peer_config.shutdown is vyos_defined %}
shutdown
{% else %}
no shutdown
diff --git a/data/templates/frr/bgpd.frr.tmpl b/data/templates/frr/bgpd.frr.tmpl
index 0bc0fd36e..8baa128a7 100644
--- a/data/templates/frr/bgpd.frr.tmpl
+++ b/data/templates/frr/bgpd.frr.tmpl
@@ -3,113 +3,113 @@
{% macro bgp_neighbor(neighbor, config, peer_group=false) %}
{% if peer_group == true %}
neighbor {{ neighbor }} peer-group
-{% elif config.peer_group is defined and config.peer_group is not none %}
+{% elif config.peer_group is vyos_defined %}
neighbor {{ neighbor }} peer-group {{ config.peer_group }}
{% endif %}
-{% if config.remote_as is defined and config.remote_as is not none %}
+{% if config.remote_as is vyos_defined %}
neighbor {{ neighbor }} remote-as {{ config.remote_as }}
{% endif %}
-{% if config.interface is defined and config.interface.remote_as is defined and config.interface.remote_as is not none %}
+{% if config.interface.remote_as is vyos_defined %}
neighbor {{ neighbor }} interface remote-as {{ config.interface.remote_as }}
{% endif %}
-{% if config.advertisement_interval is defined and config.advertisement_interval is not none %}
+{% if config.advertisement_interval is vyos_defined %}
neighbor {{ neighbor }} advertisement-interval {{ config.advertisement_interval }}
{% endif %}
-{% if config.bfd is defined %}
+{% if config.bfd is vyos_defined %}
neighbor {{ neighbor }} bfd
-{% if config.bfd.check_control_plane_failure is defined %}
+{% if config.bfd.check_control_plane_failure is vyos_defined %}
neighbor {{ neighbor }} bfd check-control-plane-failure
{% endif %}
-{% if config.bfd.profile is defined and config.bfd.profile is not none %}
+{% if config.bfd.profile is vyos_defined %}
neighbor {{ neighbor }} bfd profile {{ config.bfd.profile }}
{% endif %}
{% endif %}
-{% if config.capability is defined and config.capability is not none %}
-{% if config.capability.dynamic is defined %}
+{% if config.capability is vyos_defined %}
+{% if config.capability.dynamic is vyos_defined %}
neighbor {{ neighbor }} capability dynamic
{% endif %}
-{% if config.capability.extended_nexthop is defined %}
+{% if config.capability.extended_nexthop is vyos_defined %}
neighbor {{ neighbor }} capability extended-nexthop
{% endif %}
{% endif %}
-{% if config.description is defined and config.description is not none %}
+{% if config.description is vyos_defined %}
neighbor {{ neighbor }} description {{ config.description }}
{% endif %}
-{% if config.disable_capability_negotiation is defined %}
+{% if config.disable_capability_negotiation is vyos_defined %}
neighbor {{ neighbor }} dont-capability-negotiate
{% endif %}
-{% if config.ebgp_multihop is defined and config.ebgp_multihop is not none %}
+{% if config.ebgp_multihop is vyos_defined %}
neighbor {{ neighbor }} ebgp-multihop {{ config.ebgp_multihop }}
{% endif %}
-{% if config.graceful_restart is defined and config.graceful_restart is not none %}
-{% if config.graceful_restart == 'enable' %}
+{% if config.graceful_restart is vyos_defined %}
+{% if config.graceful_restart is vyos_defined('enable') %}
{% set graceful_restart = 'graceful-restart' %}
-{% elif config.graceful_restart == 'disable' %}
+{% elif config.graceful_restart is vyos_defined('disable') %}
{% set graceful_restart = 'graceful-restart-disable' %}
-{% elif config.graceful_restart == 'restart-helper' %}
+{% elif config.graceful_restart is vyos_defined('restart-helper') %}
{% set graceful_restart = 'graceful-restart-helper' %}
{% endif %}
neighbor {{ neighbor }} {{ graceful_restart }}
{% endif %}
-{% if config.local_as is defined and config.local_as is not none %}
+{% if config.local_as is vyos_defined %}
{% for local_as, local_as_config in config.local_as.items() %}
{# There can be only one local-as value, this is checked in the Python code #}
- neighbor {{ neighbor }} local-as {{ local_as }} {{ 'no-prepend' if local_as_config.no_prepend is defined }} {{ 'replace-as' if local_as_config.no_prepend is defined and local_as_config.no_prepend.replace_as is defined }}
+ neighbor {{ neighbor }} local-as {{ local_as }} {{ 'no-prepend' if local_as_config.no_prepend is vyos_defined }} {{ 'replace-as' if local_as_config.no_prepend is vyos_defined and local_as_config.no_prepend.replace_as is vyos_defined }}
{% endfor %}
{% endif %}
-{% if config.override_capability is defined %}
+{% if config.override_capability is vyos_defined %}
neighbor {{ neighbor }} override-capability
{% endif %}
-{% if config.passive is defined %}
+{% if config.passive is vyos_defined %}
neighbor {{ neighbor }} passive
{% endif %}
-{% if config.password is defined and config.password is not none %}
+{% if config.password is vyos_defined %}
neighbor {{ neighbor }} password {{ config.password }}
{% endif %}
-{% if config.port is defined and config.port is not none %}
+{% if config.port is vyos_defined %}
neighbor {{ neighbor }} port {{ config.port }}
{% endif %}
-{% if config.shutdown is defined %}
+{% if config.shutdown is vyos_defined %}
neighbor {{ neighbor }} shutdown
{% endif %}
-{% if config.solo is defined %}
+{% if config.solo is vyos_defined %}
neighbor {{ neighbor }} solo
{% endif %}
-{% if config.strict_capability_match is defined %}
+{% if config.strict_capability_match is vyos_defined %}
neighbor {{ neighbor }} strict-capability-match
{% endif %}
-{% if config.ttl_security is defined and config.ttl_security.hops is defined and config.ttl_security.hops is not none %}
+{% if config.ttl_security.hops is vyos_defined %}
neighbor {{ neighbor }} ttl-security hops {{ config.ttl_security.hops }}
{% endif %}
-{% if config.timers is defined %}
-{% if config.timers.connect is defined and config.timers.connect is not none %}
+{% if config.timers is vyos_defined %}
+{% if config.timers.connect is vyos_defined %}
neighbor {{ neighbor }} timers connect {{ config.timers.connect }}
{% endif %}
-{% if config.timers.holdtime is defined and config.timers.keepalive is defined and config.timers.holdtime is not none and config.timers.keepalive is not none %}
+{% if config.timers.keepalive is vyos_defined and config.timers.holdtime is vyos_defined %}
neighbor {{ neighbor }} timers {{ config.timers.keepalive }} {{ config.timers.holdtime }}
{% endif %}
{% endif %}
-{% if config.update_source is defined and config.update_source is not none %}
+{% if config.update_source is vyos_defined %}
neighbor {{ neighbor }} update-source {{ config.update_source }}
{% endif %}
-{% if config.interface is defined and config.interface is not none %}
-{% if config.interface.peer_group is defined and config.interface.peer_group is not none %}
+{% if config.interface is vyos_defined %}
+{% if config.interface.peer_group is vyos_defined %}
neighbor {{ neighbor }} interface peer-group {{ config.interface.peer_group }}
{% endif %}
-{% if config.interface.source_interface is defined and config.interface.source_interface is not none %}
+{% if config.interface.source_interface is vyos_defined %}
neighbor {{ neighbor }} interface {{ config.interface.source_interface }}
{% endif %}
-{% if config.interface.v6only is defined and config.interface.v6only is not none %}
-{% if config.interface.v6only.peer_group is defined and config.interface.v6only.peer_group is not none %}
+{% if config.interface.v6only is vyos_defined %}
+{% if config.interface.v6only.peer_group is vyos_defined %}
neighbor {{ neighbor }} interface v6only peer-group {{ config.interface.v6only.peer_group }}
{% endif %}
-{% if config.interface.v6only.remote_as is defined and config.interface.v6only.remote_as is not none %}
+{% if config.interface.v6only.remote_as is vyos_defined %}
neighbor {{ neighbor }} interface v6only remote-as {{ config.interface.v6only.remote_as }}
{% endif %}
{% endif %}
{% endif %}
!
-{% if config.address_family is defined and config.address_family is not none %}
+{% if config.address_family is vyos_defined %}
{% for afi, afi_config in config.address_family.items() %}
{% if afi == 'ipv4_unicast' %}
address-family ipv4 unicast
@@ -134,104 +134,96 @@
{% elif afi == 'l2vpn_evpn' %}
address-family l2vpn evpn
{% endif %}
-{% if afi_config.addpath_tx_all is defined %}
+{% if afi_config.addpath_tx_all is vyos_defined %}
neighbor {{ neighbor }} addpath-tx-all-paths
{% endif %}
-{% if afi_config.addpath_tx_per_as is defined %}
+{% if afi_config.addpath_tx_per_as is vyos_defined %}
neighbor {{ neighbor }} addpath-tx-bestpath-per-AS
{% endif %}
-{% if afi_config.allowas_in is defined and afi_config.allowas_in is not none %}
- neighbor {{ neighbor }} allowas-in {{ afi_config.allowas_in.number if afi_config.allowas_in.number is defined }}
+{% if afi_config.allowas_in is vyos_defined %}
+ neighbor {{ neighbor }} allowas-in {{ afi_config.allowas_in.number if afi_config.allowas_in.number is vyos_defined }}
{% endif %}
-{% if afi_config.as_override is defined %}
+{% if afi_config.as_override is vyos_defined %}
neighbor {{ neighbor }} as-override
{% endif %}
-{% if afi_config.conditionally_advertise is defined and afi_config.conditionally_advertise is not none %}
-{% if afi_config.conditionally_advertise.advertise_map is defined and afi_config.conditionally_advertise.advertise_map is not none %}
+{% if afi_config.conditionally_advertise is vyos_defined %}
+{% if afi_config.conditionally_advertise.advertise_map is vyos_defined %}
{% set exist_non_exist_map = 'exist-map' %}
-{% if afi_config.conditionally_advertise.exist_map is defined and afi_config.conditionally_advertise.exist_map is not none %}
+{% if afi_config.conditionally_advertise.exist_map is vyos_defined %}
{% set exist_non_exist_map = 'exist-map ' ~ afi_config.conditionally_advertise.exist_map %}
-{% elif afi_config.conditionally_advertise.non_exist_map is defined and afi_config.conditionally_advertise.non_exist_map is not none %}
+{% elif afi_config.conditionally_advertise.non_exist_map is vyos_defined %}
{% set exist_non_exist_map = 'non-exist-map ' ~ afi_config.conditionally_advertise.non_exist_map %}
{% endif %}
neighbor {{ neighbor }} advertise-map {{ afi_config.conditionally_advertise.advertise_map }} {{ exist_non_exist_map }}
{% endif %}
{% endif %}
-{% if afi_config.remove_private_as is defined %}
+{% if afi_config.remove_private_as is vyos_defined %}
neighbor {{ neighbor }} remove-private-AS
{% endif %}
-{% if afi_config.route_reflector_client is defined %}
+{% if afi_config.route_reflector_client is vyos_defined %}
neighbor {{ neighbor }} route-reflector-client
{% endif %}
-{% if afi_config.weight is defined and afi_config.weight is not none %}
+{% if afi_config.weight is vyos_defined %}
neighbor {{ neighbor }} weight {{ afi_config.weight }}
{% endif %}
-{% if afi_config.attribute_unchanged is defined and afi_config.attribute_unchanged is not none %}
- neighbor {{ neighbor }} attribute-unchanged {{ 'as-path ' if afi_config.attribute_unchanged.as_path is defined }}{{ 'med ' if afi_config.attribute_unchanged.med is defined }}{{ 'next-hop ' if afi_config.attribute_unchanged.next_hop is defined }}
+{% if afi_config.attribute_unchanged is vyos_defined %}
+ neighbor {{ neighbor }} attribute-unchanged {{ 'as-path ' if afi_config.attribute_unchanged.as_path is vyos_defined }}{{ 'med ' if afi_config.attribute_unchanged.med is vyos_defined }}{{ 'next-hop ' if afi_config.attribute_unchanged.next_hop is vyos_defined }}
{% endif %}
-{% if afi_config.capability is defined and afi_config.capability.orf is defined and afi_config.capability.orf.prefix_list is defined and afi_config.capability.orf.prefix_list.send is defined %}
+{% if afi_config.capability.orf.prefix_list.send is vyos_defined %}
neighbor {{ neighbor }} capability orf prefix-list send
{% endif %}
-{% if afi_config.capability is defined and afi_config.capability.orf is defined and afi_config.capability.orf.prefix_list is defined and afi_config.capability.orf.prefix_list.receive is defined %}
+{% if afi_config.capability.orf.prefix_list.receive is vyos_defined %}
neighbor {{ neighbor }} capability orf prefix-list receive
{% endif %}
-{% if afi_config.default_originate is defined %}
- neighbor {{ neighbor }} default-originate {{ 'route-map ' ~ afi_config.default_originate.route_map if afi_config.default_originate.route_map is defined }}
+{% if afi_config.default_originate is vyos_defined %}
+ neighbor {{ neighbor }} default-originate {{ 'route-map ' ~ afi_config.default_originate.route_map if afi_config.default_originate.route_map is vyos_defined }}
{% endif %}
-{% if afi_config.distribute_list is defined and afi_config.distribute_list is not none %}
-{% if afi_config.distribute_list.export is defined and afi_config.distribute_list.export is not none %}
+{% if afi_config.distribute_list.export is vyos_defined %}
neighbor {{ neighbor }} distribute-list {{ afi_config.distribute_list.export }} out
-{% endif %}
-{% if afi_config.distribute_list.import is defined and afi_config.distribute_list.import is not none %}
+{% endif %}
+{% if afi_config.distribute_list.import is vyos_defined %}
neighbor {{ neighbor }} distribute-list {{ afi_config.distribute_list.import }} in
-{% endif %}
{% endif %}
-{% if afi_config.filter_list is defined and afi_config.filter_list is not none %}
-{% if afi_config.filter_list.export is defined and afi_config.filter_list.export is not none %}
+{% if afi_config.filter_list.export is vyos_defined %}
neighbor {{ neighbor }} filter-list {{ afi_config.filter_list.export }} out
-{% endif %}
-{% if afi_config.filter_list.import is defined and afi_config.filter_list.import is not none %}
+{% endif %}
+{% if afi_config.filter_list.import is vyos_defined %}
neighbor {{ neighbor }} filter-list {{ afi_config.filter_list.import }} in
-{% endif %}
{% endif %}
-{% if afi_config.maximum_prefix is defined and afi_config.maximum_prefix is not none %}
+{% if afi_config.maximum_prefix is vyos_defined %}
neighbor {{ neighbor }} maximum-prefix {{ afi_config.maximum_prefix }}
{% endif %}
-{% if afi_config.maximum_prefix_out is defined and afi_config.maximum_prefix_out is not none %}
+{% if afi_config.maximum_prefix_out is vyos_defined %}
neighbor {{ neighbor }} maximum-prefix-out {{ afi_config.maximum_prefix_out }}
{% endif %}
-{% if afi_config.nexthop_self is defined %}
- neighbor {{ neighbor }} next-hop-self {{ 'force' if afi_config.nexthop_self.force is defined }}
+{% if afi_config.nexthop_self is vyos_defined %}
+ neighbor {{ neighbor }} next-hop-self {{ 'force' if afi_config.nexthop_self.force is vyos_defined }}
{% endif %}
-{% if afi_config.route_server_client is defined %}
+{% if afi_config.route_server_client is vyos_defined %}
neighbor {{ neighbor }} route-server-client
{% endif %}
-{% if afi_config.route_map is defined and afi_config.route_map is not none %}
-{% if afi_config.route_map.export is defined and afi_config.route_map.export is not none %}
+{% if afi_config.route_map.export is vyos_defined %}
neighbor {{ neighbor }} route-map {{ afi_config.route_map.export }} out
-{% endif %}
-{% if afi_config.route_map.import is defined and afi_config.route_map.import is not none %}
+{% endif %}
+{% if afi_config.route_map.import is vyos_defined %}
neighbor {{ neighbor }} route-map {{ afi_config.route_map.import }} in
-{% endif %}
{% endif %}
-{% if afi_config.prefix_list is defined and afi_config.prefix_list is not none %}
-{% if afi_config.prefix_list.export is defined and afi_config.prefix_list.export is not none %}
+{% if afi_config.prefix_list.export is vyos_defined %}
neighbor {{ neighbor }} prefix-list {{ afi_config.prefix_list.export }} out
-{% endif %}
-{% if afi_config.prefix_list.import is defined and afi_config.prefix_list.import is not none %}
+{% endif %}
+{% if afi_config.prefix_list.import is vyos_defined %}
neighbor {{ neighbor }} prefix-list {{ afi_config.prefix_list.import }} in
-{% endif %}
{% endif %}
-{% if afi_config.soft_reconfiguration is defined and afi_config.soft_reconfiguration.inbound is defined %}
+{% if afi_config.soft_reconfiguration.inbound is vyos_defined %}
neighbor {{ neighbor }} soft-reconfiguration inbound
{% endif %}
-{% if afi_config.unsuppress_map is defined and afi_config.unsuppress_map is not none %}
+{% if afi_config.unsuppress_map is vyos_defined %}
neighbor {{ neighbor }} unsuppress-map {{ afi_config.unsuppress_map }}
{% endif %}
-{% if afi_config.disable_send_community is defined and afi_config.disable_send_community.extended is defined %}
+{% if afi_config.disable_send_community.extended is vyos_defined %}
no neighbor {{ neighbor }} send-community extended
{% endif %}
-{% if afi_config.disable_send_community is defined and afi_config.disable_send_community.standard is defined %}
+{% if afi_config.disable_send_community.standard is vyos_defined %}
no neighbor {{ neighbor }} send-community standard
{% endif %}
neighbor {{ neighbor }} activate
@@ -241,8 +233,8 @@
{% endif %}
{% endmacro %}
!
-router bgp {{ local_as }} {{ 'vrf ' ~ vrf if vrf is defined and vrf is not none }}
-{% if parameters is defined and parameters.ebgp_requires_policy is defined %}
+router bgp {{ local_as }} {{ 'vrf ' ~ vrf if vrf is vyos_defined }}
+{% if parameters.ebgp_requires_policy is vyos_defined %}
bgp ebgp-requires-policy
{% else %}
no bgp ebgp-requires-policy
@@ -251,7 +243,7 @@ router bgp {{ local_as }} {{ 'vrf ' ~ vrf if vrf is defined and vrf is not none
no bgp default ipv4-unicast
{# Workaround for T2100 until we have decided about a migration script #}
no bgp network import-check
-{% if address_family is defined and address_family is not none %}
+{% if address_family is vyos_defined %}
{% for afi, afi_config in address_family.items() %}
!
{% if afi == 'ipv4_unicast' %}
@@ -276,25 +268,25 @@ router bgp {{ local_as }} {{ 'vrf ' ~ vrf if vrf is defined and vrf is not none
address-family ipv6 flowspec
{% elif afi == 'l2vpn_evpn' %}
address-family l2vpn evpn
-{% if afi_config.rd is defined and afi_config.rd is not none %}
+{% if afi_config.rd is vyos_defined %}
rd {{ afi_config.rd }}
{% endif %}
{% endif %}
-{% if afi_config.aggregate_address is defined and afi_config.aggregate_address is not none %}
+{% if afi_config.aggregate_address is vyos_defined %}
{% for aggregate, aggregate_config in afi_config.aggregate_address.items() %}
- aggregate-address {{ aggregate }}{{ ' as-set' if aggregate_config.as_set is defined }}{{ ' summary-only' if aggregate_config.summary_only is defined }}
-{% if aggregate_config.route_map is defined and aggregate_config.route_map is not none %}
+ aggregate-address {{ aggregate }}{{ ' as-set' if aggregate_config.as_set is vyos_defined }}{{ ' summary-only' if aggregate_config.summary_only is vyos_defined }}
+{% if aggregate_config.route_map is vyos_defined %}
aggregate-address {{ aggregate }} route-map {{ aggregate_config.route_map }}
{% endif %}
{% endfor %}
{% endif %}
-{% if afi_config.maximum_paths is defined and afi_config.maximum_paths.ebgp is defined and afi_config.maximum_paths.ebgp is not none %}
+{% if afi_config.maximum_paths.ebgp is vyos_defined %}
maximum-paths {{ afi_config.maximum_paths.ebgp }}
{% endif %}
-{% if afi_config.maximum_paths is defined and afi_config.maximum_paths.ibgp is defined and afi_config.maximum_paths.ibgp is not none %}
+{% if afi_config.maximum_paths.ibgp is vyos_defined %}
maximum-paths ibgp {{ afi_config.maximum_paths.ibgp }}
{% endif %}
-{% if afi_config.redistribute is defined and afi_config.redistribute is not none %}
+{% if afi_config.redistribute is vyos_defined %}
{% for protocol in afi_config.redistribute %}
{% if protocol == 'table' %}
redistribute table {{ afi_config.redistribute[protocol].table }}
@@ -303,135 +295,123 @@ router bgp {{ local_as }} {{ 'vrf ' ~ vrf if vrf is defined and vrf is not none
{% if protocol == 'ospfv3' %}
{% set redistribution_protocol = 'ospf6' %}
{% endif %}
- redistribute {{ redistribution_protocol }}{% if afi_config.redistribute[protocol].metric is defined %} metric {{ afi_config.redistribute[protocol].metric }}{% endif %}{% if afi_config.redistribute[protocol].route_map is defined %} route-map {{ afi_config.redistribute[protocol].route_map }}{% endif %}
+ redistribute {{ redistribution_protocol }}{% if afi_config.redistribute[protocol].metric is vyos_defined %} metric {{ afi_config.redistribute[protocol].metric }}{% endif %}{% if afi_config.redistribute[protocol].route_map is vyos_defined %} route-map {{ afi_config.redistribute[protocol].route_map }}{% endif %}
{####### we need this blank line!! #######}
{% endif %}
{% endfor %}
{% endif %}
-{% if afi_config.network is defined and afi_config.network is not none %}
+{% if afi_config.network is vyos_defined %}
{% for network in afi_config.network %}
- network {{ network }}{% if afi_config.network[network].route_map is defined %} route-map {{ afi_config.network[network].route_map }}{% endif %}{% if afi_config.network[network].backdoor is defined %} backdoor{% endif %}{% if afi_config.network[network].rd is defined and afi_config.network[network].label is defined%} rd {{ afi_config.network[network].rd }} label {{ afi_config.network[network].label }}{% endif %}
+ network {{ network }}{% if afi_config.network[network].route_map is vyos_defined %} route-map {{ afi_config.network[network].route_map }}{% endif %}{% if afi_config.network[network].backdoor is vyos_defined %} backdoor{% endif %}{% if afi_config.network[network].rd is vyos_defined and afi_config.network[network].label is vyos_defined %} rd {{ afi_config.network[network].rd }} label {{ afi_config.network[network].label }}{% endif %}
{####### we need this blank line!! #######}
{% endfor %}
{% endif %}
-{% if afi_config.advertise is defined and afi_config.advertise is not none %}
+{% if afi_config.advertise is vyos_defined %}
{% for adv_afi, adv_afi_config in afi_config.advertise.items() %}
-{% if adv_afi_config.unicast is defined and adv_afi_config.unicast is not none %}
- advertise {{ adv_afi }} unicast {{ 'route-map ' ~ adv_afi_config.unicast.route_map if adv_afi_config.unicast.route_map is defined }}
+{% if adv_afi_config.unicast is vyos_defined %}
+ advertise {{ adv_afi }} unicast {{ 'route-map ' ~ adv_afi_config.unicast.route_map if adv_afi_config.unicast.route_map is vyos_defined }}
{% endif %}
{% endfor %}
{% endif %}
-{% if afi_config.distance is defined and afi_config.distance is not none %}
-{% if afi_config.distance is defined and afi_config.distance.external is defined and afi_config.distance.internal is defined and afi_config.distance.local is defined %}
+{% if afi_config.distance.external is vyos_defined and afi_config.distance.internal is vyos_defined and afi_config.distance.local is vyos_defined %}
distance bgp {{ afi_config.distance.external }} {{ afi_config.distance.internal }} {{ afi_config.distance.local }}
-{% endif %}
-{% if afi_config.distance.prefix is defined and afi_config.distance.prefix is not none %}
-{% for prefix in afi_config.distance.prefix %}
+{% endif %}
+{% if afi_config.distance.prefix is vyos_defined %}
+{% for prefix in afi_config.distance.prefix %}
distance {{ afi_config.distance.prefix[prefix].distance }} {{ prefix }}
-{% endfor %}
-{% endif %}
+{% endfor %}
{% endif %}
-{% if afi_config.export is defined and afi_config.export.vpn is defined %}
+{% if afi_config.export.vpn is vyos_defined %}
export vpn
{% endif %}
-{% if afi_config.import is defined and afi_config.import is not none %}
-{% if afi_config.import.vpn is defined %}
+{% if afi_config.import.vpn is vyos_defined %}
import vpn
-{% endif %}
-{% if afi_config.import.vrf is defined and afi_config.import.vrf is not none %}
-{% for vrf in afi_config.import.vrf %}
+{% endif %}
+{% if afi_config.import.vrf is vyos_defined %}
+{% for vrf in afi_config.import.vrf %}
import vrf {{ vrf }}
-{% endfor %}
-{% endif %}
+{% endfor %}
{% endif %}
-{% if afi_config.label is defined and afi_config.label.vpn is defined and afi_config.label.vpn.export is defined and afi_config.label.vpn.export is not none %}
+{% if afi_config.label.vpn.export is vyos_defined %}
label vpn export {{ afi_config.label.vpn.export }}
{% endif %}
-{% if afi_config.local_install is defined and afi_config.local_install is not none %}
+{% if afi_config.local_install is vyos_defined %}
{% for interface in afi_config.local_install.interface %}
local-install {{ interface }}
{% endfor %}
{% endif %}
-{% if afi_config.advertise_all_vni is defined %}
+{% if afi_config.advertise_all_vni is vyos_defined %}
advertise-all-vni
{% endif %}
-{% if afi_config.advertise_default_gw is defined %}
+{% if afi_config.advertise_default_gw is vyos_defined %}
advertise-default-gw
{% endif %}
-{% if afi_config.advertise_pip is defined and afi_config.advertise_pip is not none %}
+{% if afi_config.advertise_pip is vyos_defined %}
advertise-pip ip {{ afi_config.advertise_pip }}
{% endif %}
-{% if afi_config.advertise_svi_ip is defined %}
+{% if afi_config.advertise_svi_ip is vyos_defined %}
advertise-svi-ip
{% endif %}
-{% if afi_config.rt_auto_derive is defined %}
+{% if afi_config.rt_auto_derive is vyos_defined %}
autort rfc8365-compatible
{% endif %}
-{% if afi_config.flooding is defined and afi_config.flooding.disable is defined %}
+{% if afi_config.flooding.disable is vyos_defined %}
flooding disable
{% endif %}
-{% if afi_config.flooding is defined and afi_config.flooding.head_end_replication is defined %}
+{% if afi_config.flooding.head_end_replication is vyos_defined %}
flooding head-end-replication
{% endif %}
-{% if afi_config.rd is defined and afi_config.rd.vpn is defined and afi_config.rd.vpn.export is defined %}
+{% if afi_config.rd.vpn.export is vyos_defined %}
rd vpn export {{ afi_config.rd.vpn.export }}
{% endif %}
-{% if afi_config.route_target is defined and afi_config.route_target is not none %}
-{% if afi_config.route_target.vpn is defined and afi_config.route_target.vpn is not none %}
-{% if afi_config.route_target.vpn.both is defined and afi_config.route_target.vpn.both is not none %}
+{% if afi_config.route_target.vpn.both is vyos_defined %}
route-target vpn both {{ afi_config.route_target.vpn.both }}
-{% else %}
-{% if afi_config.route_target.vpn.export is defined and afi_config.route_target.vpn.export is not none %}
+{% else %}
+{% if afi_config.route_target.vpn.export is vyos_defined %}
route-target vpn export {{ afi_config.route_target.vpn.export }}
-{% endif %}
-{% if afi_config.route_target.vpn.import is defined and afi_config.route_target.vpn.import is not none %}
+{% endif %}
+{% if afi_config.route_target.vpn.import is vyos_defined %}
route-target vpn import {{ afi_config.route_target.vpn.import }}
-{% endif %}
-{% endif %}
{% endif %}
-{% if afi_config.route_target.both is defined and afi_config.route_target.both is not none %}
+{% endif %}
+{% if afi_config.route_target.both is vyos_defined %}
route-target both {{ afi_config.route_target.both }}
-{% else %}
-{% if afi_config.route_target.export is defined and afi_config.route_target.export is not none %}
+{% else %}
+{% if afi_config.route_target.export is vyos_defined %}
route-target export {{ afi_config.route_target.export }}
-{% endif %}
-{% if afi_config.route_target.import is defined and afi_config.route_target.import is not none %}
+{% endif %}
+{% if afi_config.route_target.import is vyos_defined %}
route-target import {{ afi_config.route_target.import }}
-{% endif %}
{% endif %}
{% endif %}
-{% if afi_config.route_map is defined and afi_config.route_map.vpn is defined and afi_config.route_map.vpn is not none %}
-{% if afi_config.route_map.vpn.export is defined and afi_config.route_map.vpn.export is not none %}
+{% if afi_config.route_map.vpn.export is vyos_defined %}
route-map vpn export {{ afi_config.route_map.vpn.export }}
-{% endif %}
-{% if afi_config.route_map.vpn.import is defined and afi_config.route_map.vpn.import is not none %}
+{% endif %}
+{% if afi_config.route_map.vpn.import is vyos_defined %}
route-map vpn import {{ afi_config.route_map.vpn.import }}
-{% endif %}
{% endif %}
-{% if afi_config.vni is defined and afi_config.vni is not none %}
+{% if afi_config.vni is vyos_defined %}
{% for vni, vni_config in afi_config.vni.items() %}
vni {{ vni }}
-{% if vni_config.advertise_default_gw is defined %}
+{% if vni_config.advertise_default_gw is vyos_defined %}
advertise-default-gw
{% endif %}
-{% if vni_config.advertise_svi_ip is defined %}
+{% if vni_config.advertise_svi_ip is vyos_defined %}
advertise-svi-ip
{% endif %}
-{% if vni_config.rd is defined and vni_config.rd is not none %}
+{% if vni_config.rd is vyos_defined %}
rd {{ vni_config.rd }}
{% endif %}
-{% if vni_config.route_target is defined and vni_config.route_target is not none %}
-{% if vni_config.route_target.both is defined and vni_config.route_target.both is not none %}
+{% if vni_config.route_target.both is vyos_defined %}
route-target both {{ vni_config.route_target.both }}
-{% endif %}
-{% if vni_config.route_target.export is defined and vni_config.route_target.export is not none %}
+{% endif %}
+{% if vni_config.route_target.export is vyos_defined %}
route-target export {{ vni_config.route_target.export }}
-{% endif %}
-{% if vni_config.route_target.import is defined and vni_config.route_target.import is not none %}
+{% endif %}
+{% if vni_config.route_target.import is vyos_defined %}
route-target import {{ vni_config.route_target.import }}
-{% endif %}
{% endif %}
exit-vni
{% endfor %}
@@ -440,128 +420,116 @@ router bgp {{ local_as }} {{ 'vrf ' ~ vrf if vrf is defined and vrf is not none
{% endfor %}
{% endif %}
!
-{% if peer_group is defined and peer_group is not none %}
+{% if peer_group is vyos_defined %}
{% for peer, config in peer_group.items() %}
{{ bgp_neighbor(peer, config, true) }}
{% endfor %}
{% endif %}
!
-{% if neighbor is defined and neighbor is not none %}
+{% if neighbor is vyos_defined %}
{% for peer, config in neighbor.items() %}
{{ bgp_neighbor(peer, config) }}
{% endfor %}
{% endif %}
!
-{% if listen is defined %}
-{% if listen.limit is defined and listen.limit is not none %}
+{% if listen.limit is vyos_defined %}
bgp listen limit {{ listen.limit }}
-{% endif %}
+{% endif %}
+{% if listen.range is vyos_defined %}
{% for prefix, options in listen.range.items() %}
-{% if options.peer_group is defined and options.peer_group is not none %}
+{% if options.peer_group is vyos_defined %}
bgp listen range {{ prefix }} peer-group {{ options.peer_group }}
{% endif %}
{% endfor %}
{% endif %}
-{% if parameters is defined %}
-{% if parameters.always_compare_med is defined %}
+{% if parameters.always_compare_med is vyos_defined %}
bgp always-compare-med
-{% endif %}
-{% if parameters.bestpath is defined and parameters.bestpath is not none %}
-{% if parameters.bestpath.as_path is defined and parameters.bestpath.as_path is not none %}
-{% for option in parameters.bestpath.as_path %}
+{% endif %}
+{% if parameters.bestpath.as_path is vyos_defined %}
+{% for option in parameters.bestpath.as_path %}
{# replace is required for multipath-relax option #}
bgp bestpath as-path {{ option|replace('_', '-') }}
-{% endfor %}
-{% endif %}
-{% if parameters.bestpath.bandwidth is defined and parameters.bestpath.bandwidth is not none %}
+{% endfor %}
+{% endif %}
+{% if parameters.bestpath.bandwidth is vyos_defined %}
bgp bestpath bandwidth {{ parameters.bestpath.bandwidth }}
-{% endif %}
-{% if parameters.bestpath.compare_routerid is defined %}
+{% endif %}
+{% if parameters.bestpath.compare_routerid is vyos_defined %}
bgp bestpath compare-routerid
-{% endif %}
-{% if parameters.bestpath.med is defined and parameters.bestpath.med is not none %}
- bgp bestpath med {{ 'confed' if parameters.bestpath.med.confed is defined }} {{ 'missing-as-worst' if parameters.bestpath.med.missing_as_worst is defined }}
-{% endif %}
-{% endif %}
-{% if parameters.cluster_id is defined and parameters.cluster_id is not none %}
+{% endif %}
+{% if parameters.bestpath.med is vyos_defined %}
+ bgp bestpath med {{ 'confed' if parameters.bestpath.med.confed is vyos_defined }} {{ 'missing-as-worst' if parameters.bestpath.med.missing_as_worst is vyos_defined }}
+{% endif %}
+{% if parameters.cluster_id is vyos_defined %}
bgp cluster-id {{ parameters.cluster_id }}
-{% endif %}
-{% if parameters.conditional_advertisement is defined and parameters.conditional_advertisement is not none %}
-{% if parameters.conditional_advertisement.timer is defined and parameters.conditional_advertisement.timer is not none %}
+{% endif %}
+{% if parameters.conditional_advertisement.timer is vyos_defined %}
bgp conditional-advertisement timer {{ parameters.conditional_advertisement.timer }}
-{% endif %}
-{% endif %}
-{% if parameters.confederation is defined and parameters.confederation is not none %}
-{% if parameters.confederation.identifier is defined and parameters.confederation.identifier is not none %}
+{% endif %}
+{% if parameters.confederation.identifier is vyos_defined %}
bgp confederation identifier {{ parameters.confederation.identifier }}
-{% endif %}
-{% if parameters.confederation.peers is defined and parameters.confederation.peers is not none %}
+{% endif %}
+{% if parameters.confederation.peers is vyos_defined %}
bgp confederation peers {{ parameters.confederation.peers | join(' ') }}
-{% endif %}
-{% endif %}
-{% if parameters.dampening is defined and parameters.dampening is defined and parameters.dampening.half_life is defined and parameters.dampening.half_life is not none %}
+{% endif %}
+{% if parameters.dampening.half_life is vyos_defined %}
{# Doesn't work in current FRR configuration; vtysh (bgp dampening 16 751 2001 61) #}
- bgp dampening {{ parameters.dampening.half_life }} {{ parameters.dampening.re_use if parameters.dampening.re_use is defined }} {{ parameters.dampening.start_suppress_time if parameters.dampening.start_suppress_time is defined }} {{ parameters.dampening.max_suppress_time if parameters.dampening.max_suppress_time is defined }}
-{% endif %}
-{% if parameters.default is defined and parameters.default is not none %}
-{% if parameters.default.local_pref is defined and parameters.default.local_pref is not none %}
+ bgp dampening {{ parameters.dampening.half_life }} {{ parameters.dampening.re_use if parameters.dampening.re_use is vyos_defined }} {{ parameters.dampening.start_suppress_time if parameters.dampening.start_suppress_time is vyos_defined }} {{ parameters.dampening.max_suppress_time if parameters.dampening.max_suppress_time is vyos_defined }}
+{% endif %}
+{% if parameters.default.local_pref is vyos_defined %}
bgp default local-preference {{ parameters.default.local_pref }}
-{% endif %}
-{% endif %}
-{% if parameters.deterministic_med is defined %}
+{% endif %}
+{% if parameters.deterministic_med is vyos_defined %}
bgp deterministic-med
-{% endif %}
-{% if parameters.distance is defined and parameters.distance is not none %}
-{% if parameters.distance.global is defined and parameters.distance.global.external is defined and parameters.distance.global.internal is defined and parameters.distance.global.local is defined %}
+{% endif %}
+{% if parameters.distance.global.external is vyos_defined and parameters.distance.global.internal is vyos_defined and parameters.distance.global.local is vyos_defined %}
distance bgp {{ parameters.distance.global.external }} {{ parameters.distance.global.internal }} {{ parameters.distance.global.local }}
-{% endif %}
-{% if parameters.distance.prefix is defined and parameters.distance.prefix is not none %}
-{% for prefix in parameters.distance.prefix %}
+{% endif %}
+{% if parameters.distance.prefix is vyos_defined %}
+{% for prefix in parameters.distance.prefix %}
distance {{ parameters.distance.prefix[prefix].distance }} {{ prefix }}
-{% endfor %}
-{% endif %}
-{% endif %}
-{% if parameters.fast_convergence is defined %}
+{% endfor %}
+{% endif %}
+{% if parameters.fast_convergence is vyos_defined %}
bgp fast-convergence
-{% endif %}
-{% if parameters.graceful_restart is defined %}
- bgp graceful-restart {{ 'stalepath-time ' ~ parameters.graceful_restart.stalepath_time if parameters.graceful_restart.stalepath_time is defined }}
-{% endif %}
-{% if parameters.graceful_shutdown is defined %}
+{% endif %}
+{% if parameters.graceful_restart is vyos_defined %}
+ bgp graceful-restart {{ 'stalepath-time ' ~ parameters.graceful_restart.stalepath_time if parameters.graceful_restart.stalepath_time is vyos_defined }}
+{% endif %}
+{% if parameters.graceful_shutdown is vyos_defined %}
bgp graceful-shutdown
-{% endif %}
-{% if parameters.log_neighbor_changes is defined %}
+{% endif %}
+{% if parameters.log_neighbor_changes is vyos_defined %}
bgp log-neighbor-changes
-{% endif %}
-{% if parameters.minimum_holdtime is defined and parameters.minimum_holdtime is not none %}
+{% endif %}
+{% if parameters.minimum_holdtime is vyos_defined %}
bgp minimum-holdtime {{ parameters.minimum_holdtime }}
-{% endif %}
-{% if parameters.network_import_check is defined %}
+{% endif %}
+{% if parameters.network_import_check is vyos_defined %}
bgp network import-check
-{% endif %}
-{% if parameters.no_client_to_client_reflection is defined %}
+{% endif %}
+{% if parameters.no_client_to_client_reflection is vyos_defined %}
no bgp client-to-client reflection
-{% endif %}
-{% if parameters.no_fast_external_failover is defined %}
+{% endif %}
+{% if parameters.no_fast_external_failover is vyos_defined %}
no bgp fast-external-failover
-{% endif %}
-{% if parameters.no_suppress_duplicates is defined %}
+{% endif %}
+{% if parameters.no_suppress_duplicates is vyos_defined %}
no bgp suppress-duplicates
-{% endif %}
-{% if parameters.reject_as_sets is defined %}
+{% endif %}
+{% if parameters.reject_as_sets is vyos_defined %}
bgp reject-as-sets
-{% endif %}
-{% if parameters.router_id is defined and parameters.router_id is not none %}
+{% endif %}
+{% if parameters.router_id is vyos_defined and parameters.router_id is not none %}
bgp router-id {{ parameters.router_id }}
-{% endif %}
-{% if parameters.shutdown is defined %}
+{% endif %}
+{% if parameters.shutdown is vyos_defined %}
bgp shutdown
-{% endif %}
-{% if parameters.suppress_fib_pending is defined %}
+{% endif %}
+{% if parameters.suppress_fib_pending is vyos_defined %}
bgp suppress-fib-pending
-{% endif %}
{% endif %}
-{% if timers is defined and timers.keepalive is defined and timers.holdtime is defined %}
+{% if timers.keepalive is vyos_defined and timers.holdtime is vyos_defined %}
timers bgp {{ timers.keepalive }} {{ timers.holdtime }}
{% endif %}
exit
diff --git a/data/templates/frr/isisd.frr.tmpl b/data/templates/frr/isisd.frr.tmpl
index c68dda443..238541903 100644
--- a/data/templates/frr/isisd.frr.tmpl
+++ b/data/templates/frr/isisd.frr.tmpl
@@ -1,46 +1,48 @@
!
-{% if interface is defined and interface is not none %}
+{% if interface is vyos_defined %}
{% for iface, iface_config in interface.items() %}
interface {{ iface }}
ip router isis VyOS
ipv6 router isis VyOS
-{% if iface_config.bfd is defined %}
+{% if iface_config.bfd is vyos_defined %}
isis bfd
-{% if iface_config.bfd.profile is defined and iface_config.bfd.profile is not none %}
+{% if iface_config.bfd.profile is vyos_defined %}
isis bfd profile {{ iface_config.bfd.profile }}
{% endif %}
{% endif %}
-{% if iface_config.network is defined and iface_config.network.point_to_point is defined %}
+{% if iface_config.network.point_to_point is vyos_defined %}
isis network point-to-point
{% endif %}
-{% if iface_config.circuit_type is defined %}
+{% if iface_config.circuit_type is vyos_defined %}
isis circuit-type {{ iface_config.circuit_type }}
{% endif %}
-{% if iface_config.hello_interval is defined and iface_config.hello_interval is not none %}
+{% if iface_config.hello_interval is vyos_defined %}
isis hello-interval {{ iface_config.hello_interval }}
{% endif %}
-{% if iface_config.hello_multiplier is defined and iface_config.hello_multiplier is not none %}
+{% if iface_config.hello_multiplier is vyos_defined %}
isis hello-multiplier {{ iface_config.hello_multiplier }}
{% endif %}
-{% if iface_config.hello_padding is defined %}
+{% if iface_config.hello_padding is vyos_defined %}
isis hello padding
{% endif %}
-{% if iface_config.metric is defined and iface_config.metric is not none %}
+{% if iface_config.metric is vyos_defined %}
isis metric {{ iface_config.metric }}
{% endif %}
-{% if iface_config.passive is defined %}
+{% if iface_config.passive is vyos_defined %}
isis passive
{% endif %}
-{% if iface_config.password is defined and iface_config.password.plaintext_password is defined and iface_config.password.plaintext_password is not none %}
+{% if iface_config.password.md5 is vyos_defined %}
+ isis password md5 {{ iface_config.password.md5 }}
+{% elif iface_config.password.plaintext_password is vyos_defined %}
isis password clear {{ iface_config.password.plaintext_password }}
{% endif %}
-{% if iface_config.priority is defined and iface_config.priority is not none %}
+{% if iface_config.priority is vyos_defined %}
isis priority {{ iface_config.priority }}
{% endif %}
-{% if iface_config.psnp_interval is defined and iface_config.psnp_interval is not none %}
+{% if iface_config.psnp_interval is vyos_defined %}
isis psnp-interval {{ iface_config.psnp_interval }}
{% endif %}
-{% if iface_config.no_three_way_handshake is defined %}
+{% if iface_config.no_three_way_handshake is vyos_defined %}
no isis three-way-handshake
{% endif %}
exit
@@ -48,98 +50,95 @@ exit
{% endfor %}
{% endif %}
!
-router isis VyOS {{ 'vrf ' + vrf if vrf is defined and vrf is not none }}
+router isis VyOS {{ 'vrf ' + vrf if vrf is vyos_defined }}
net {{ net }}
-{% if dynamic_hostname is defined %}
+{% if dynamic_hostname is vyos_defined %}
hostname dynamic
{% endif %}
-{% if purge_originator is defined %}
+{% if purge_originator is vyos_defined %}
purge-originator
{% endif %}
-{% if set_attached_bit is defined %}
+{% if set_attached_bit is vyos_defined %}
set-attached-bit
{% endif %}
-{% if set_overload_bit is defined %}
+{% if set_overload_bit is vyos_defined %}
set-overload-bit
{% endif %}
-{% if domain_password is defined and domain_password is not none %}
-{% if domain_password.md5 is defined and domain_password.md5 is not none %}
+{% if domain_password.md5 is vyos_defined %}
domain-password md5 {{ domain_password.plaintext_password }}
-{% elif domain_password.plaintext_password is defined and domain_password.plaintext_password is not none %}
+{% elif domain_password.plaintext_password is vyos_defined %}
domain-password clear {{ domain_password.plaintext_password }}
-{% endif %}
{% endif %}
-{% if log_adjacency_changes is defined %}
+{% if log_adjacency_changes is vyos_defined %}
log-adjacency-changes
{% endif %}
-{% if lsp_gen_interval is defined and lsp_gen_interval is not none %}
+{% if lsp_gen_interval is vyos_defined %}
lsp-gen-interval {{ lsp_gen_interval }}
{% endif %}
-{% if lsp_mtu is defined and lsp_mtu is not none %}
+{% if lsp_mtu is vyos_defined %}
lsp-mtu {{ lsp_mtu }}
{% endif %}
-{% if lsp_refresh_interval is defined and lsp_refresh_interval is not none %}
+{% if lsp_refresh_interval is vyos_defined %}
lsp-refresh-interval {{ lsp_refresh_interval }}
{% endif %}
-{% if max_lsp_lifetime is defined and max_lsp_lifetime is not none %}
+{% if max_lsp_lifetime is vyos_defined %}
max-lsp-lifetime {{ max_lsp_lifetime }}
{% endif %}
-{% if spf_interval is defined and spf_interval is not none %}
+{% if spf_interval is vyos_defined %}
spf-interval {{ spf_interval }}
{% endif %}
-{% if traffic_engineering is defined and traffic_engineering is not none %}
-{% if traffic_engineering.enable is defined %}
+{% if traffic_engineering.enable is vyos_defined %}
mpls-te on
-{% endif %}
-{% if traffic_engineering.address is defined %}
+{% endif %}
+{% if traffic_engineering.address is vyos_defined %}
mpls-te router-address {{ traffic_engineering.address }}
+{% endif %}
+{% if traffic_engineering.inter_as is vyos_defined %}
+{% set level = '' %}
+{% if traffic_engineering.inter_as.level_1 is vyos_defined %}
+{% set level = ' level-1' %}
{% endif %}
-{% if traffic_engineering.inter_as is defined %}
-{% if traffic_engineering.inter_as.level_1 is defined %}
- mpls-te inter-as level-1
-{% endif %}
-{% if traffic_engineering.inter_as.level_1_2 is defined %}
- mpls-te inter-as level-1-2
-{% endif %}
-{% if traffic_engineering.inter_as.level_2 is defined %}
- mpls-te inter-as level-2-only
-{% endif %}
-{% else %}
- mpls-te inter-as
+{% if traffic_engineering.inter_as.level_1_2 is vyos_defined %}
+{% set level = ' level-1-2' %}
+{% endif %}
+{% if traffic_engineering.inter_as.level_2 is vyos_defined %}
+{% set level = ' level-2-only' %}
{% endif %}
+ mpls-te inter-as{{ level }}
{% endif %}
-{% if segment_routing is defined %}
-{% if segment_routing.enable is defined %}
+{% if segment_routing is vyos_defined %}
+{% if segment_routing.enable is vyos_defined %}
segment-routing on
{% endif %}
-{% if segment_routing.maximum_label_depth is defined %}
+{% if segment_routing.maximum_label_depth is vyos_defined %}
segment-routing node-msd {{ segment_routing.maximum_label_depth }}
{% endif %}
-{% if segment_routing.global_block is defined %}
+{% if segment_routing.global_block is vyos_defined %}
+{% if segment_routing.local_block is vyos_defined %}
+ segment-routing global-block {{ segment_routing.global_block.low_label_value }} {{ segment_routing.global_block.high_label_value }} local-block {{ segment_routing.local_block.low_label_value }} {{ segment_routing.local_block.high_label_value }}
+{% else %}
segment-routing global-block {{ segment_routing.global_block.low_label_value }} {{ segment_routing.global_block.high_label_value }}
+{% endif %}
{% endif %}
-{% if segment_routing.local_block is defined %}
- segment-routing local-block {{ segment_routing.global_block.low_label_value }} {{ segment_routing.local_block.high_label_value }}
-{% endif %}
-{% if segment_routing.prefix is defined %}
+{% if segment_routing.prefix is vyos_defined %}
{% for prefixes in segment_routing.prefix %}
-{% if segment_routing.prefix[prefixes].absolute is defined %}
-{% if segment_routing.prefix[prefixes].absolute.value is defined %}
+{% if segment_routing.prefix[prefixes].absolute is vyos_defined %}
+{% if segment_routing.prefix[prefixes].absolute.value is vyos_defined %}
segment-routing prefix {{ prefixes }} absolute {{ segment_routing.prefix[prefixes].absolute.value }}
-{% if segment_routing.prefix[prefixes].absolute.explicit_null is defined %}
+{% if segment_routing.prefix[prefixes].absolute.explicit_null is vyos_defined %}
segment-routing prefix {{ prefixes }} absolute {{ segment_routing.prefix[prefixes].absolute.value }} explicit-null
{% endif %}
-{% if segment_routing.prefix[prefixes].absolute.no_php_flag is defined %}
+{% if segment_routing.prefix[prefixes].absolute.no_php_flag is vyos_defined %}
segment-routing prefix {{ prefixes }} absolute {{ segment_routing.prefix[prefixes].absolute.value }} no-php-flag
{% endif %}
{% endif %}
-{% if segment_routing.prefix[prefixes].index is defined %}
-{% if segment_routing.prefix[prefixes].index.value is defined %}
+{% if segment_routing.prefix[prefixes].index is vyos_defined %}
+{% if segment_routing.prefix[prefixes].index.value is vyos_defined %}
segment-routing prefix {{ prefixes }} index {{ segment_routing.prefix[prefixes].index.value }}
-{% if segment_routing.prefix[prefixes].index.explicit_null is defined %}
+{% if segment_routing.prefix[prefixes].index.explicit_null is vyos_defined %}
segment-routing prefix {{ prefixes }} index {{ segment_routing.prefix[prefixes].index.value }} explicit-null
{% endif %}
-{% if segment_routing.prefix[prefixes].index.no_php_flag is defined %}
+{% if segment_routing.prefix[prefixes].index.no_php_flag is vyos_defined %}
segment-routing prefix {{ prefixes }} index {{ segment_routing.prefix[prefixes].index.value }} no-php-flag
{% endif %}
{% endif %}
@@ -148,57 +147,51 @@ router isis VyOS {{ 'vrf ' + vrf if vrf is defined and vrf is not none }}
{% endfor %}
{% endif %}
{% endif %}
-{% if spf_delay_ietf is defined and spf_delay_ietf.init_delay is defined and spf_delay_ietf.init_delay is not none %}
+{% if spf_delay_ietf.init_delay is vyos_defined %}
spf-delay-ietf init-delay {{ spf_delay_ietf.init_delay }} short-delay {{ spf_delay_ietf.short_delay }} long-delay {{ spf_delay_ietf.long_delay }} holddown {{ spf_delay_ietf.holddown }} time-to-learn {{ spf_delay_ietf.time_to_learn }}
{% endif %}
-{% if area_password is defined and area_password is not none %}
-{% if area_password.md5 is defined and area_password.md5 is not none %}
+{% if area_password.md5 is vyos_defined %}
area-password md5 {{ area_password.md5 }}
-{% elif area_password.plaintext_password is defined and area_password.plaintext_password is not none %}
+{% elif area_password.plaintext_password is vyos_defined %}
area-password clear {{ area_password.plaintext_password }}
-{% endif %}
{% endif %}
-{% if default_information is defined and default_information.originate is defined and default_information.originate is not none %}
+{% if default_information.originate is vyos_defined %}
{% for afi, afi_config in default_information.originate.items() %}
{% for level, level_config in afi_config.items() %}
- default-information originate {{ afi }} {{ level | replace('_', '-') }} {{ 'always' if level_config.always is defined }} {{ 'route-map ' ~ level_config.route_map if level_config.route_map is defined }} {{ 'metric ' ~ level_config.metric if level_config.metric is defined }}
+ default-information originate {{ afi }} {{ level | replace('_', '-') }} {{ 'always' if level_config.always is vyos_defined }} {{ 'route-map ' ~ level_config.route_map if level_config.route_map is vyos_defined }} {{ 'metric ' ~ level_config.metric if level_config.metric is vyos_defined }}
{% endfor %}
{% endfor %}
{% endif %}
-{% if redistribute is defined %}
-{% if redistribute.ipv4 is defined and redistribute.ipv4 is not none %}
-{% for protocol, protocol_options in redistribute.ipv4.items() %}
-{% for level, level_config in protocol_options.items() %}
-{% if level_config.metric is defined and level_config.metric is not none %}
+{% if redistribute.ipv4 is vyos_defined %}
+{% for protocol, protocol_options in redistribute.ipv4.items() %}
+{% for level, level_config in protocol_options.items() %}
+{% if level_config.metric is vyos_defined %}
redistribute ipv4 {{ protocol }} {{ level | replace('_', '-') }} metric {{ level_config.metric }}
-{% elif level_config.route_map is defined and level_config.route_map is not none %}
+{% elif level_config.route_map is vyos_defined %}
redistribute ipv4 {{ protocol }} {{ level | replace('_', '-') }} route-map {{ level_config.route_map }}
-{% else %}
+{% else %}
redistribute ipv4 {{ protocol }} {{ level | replace('_', '-') }}
-{% endif %}
-{% endfor %}
+{% endif %}
{% endfor %}
-{% endif %}
-{% if redistribute.ipv6 is defined and redistribute.ipv6 is not none %}
-{% for protocol, protocol_options in redistribute.ipv6.items() %}
-{% for level, level_config in protocol_options.items() %}
-{% if level_config.metric is defined and level_config.metric is not none %}
+{% endfor %}
+{% endif %}
+{% if redistribute.ipv6 is vyos_defined %}
+{% for protocol, protocol_options in redistribute.ipv6.items() %}
+{% for level, level_config in protocol_options.items() %}
+{% if level_config.metric is vyos_defined %}
redistribute ipv6 {{ protocol }} {{ level | replace('_', '-') }} metric {{ level_config.metric }}
-{% elif level_config.route_map is defined and level_config.route_map is not none %}
+{% elif level_config.route_map is vyos_defined %}
redistribute ipv6 {{ protocol }} {{ level | replace('_', '-') }} route-map {{ level_config.route_map }}
-{% else %}
+{% else %}
redistribute ipv6 {{ protocol }} {{ level | replace('_', '-') }}
-{% endif %}
-{% endfor %}
+{% endif %}
{% endfor %}
-{% endif %}
+{% endfor %}
{% endif %}
-{% if level is defined and level is not none %}
-{% if level == 'level-2' %}
+{% if level is vyos_defined('level-2') %}
is-type level-2-only
-{% else %}
+{% elif level is vyos_defined %}
is-type {{ level }}
-{% endif %}
{% endif %}
exit
! \ No newline at end of file
diff --git a/data/templates/frr/ldpd.frr.tmpl b/data/templates/frr/ldpd.frr.tmpl
index 537ea4025..5a67b5cdf 100644
--- a/data/templates/frr/ldpd.frr.tmpl
+++ b/data/templates/frr/ldpd.frr.tmpl
@@ -1,190 +1,157 @@
!
-{% if ldp is defined %}
+{% if ldp is vyos_defined %}
mpls ldp
-{% if ldp.router_id is defined %}
+{% if ldp.router_id is vyos_defined %}
router-id {{ ldp.router_id }}
-{% endif %}
-{% if ldp.parameters is defined %}
-{% if ldp.parameters.cisco_interop_tlv is defined %}
+{% endif %}
+{% if ldp.parameters.cisco_interop_tlv is vyos_defined %}
dual-stack cisco-interop
-{% endif %}
-{% if ldp.parameters.transport_prefer_ipv4 is defined%}
+{% endif %}
+{% if ldp.parameters.transport_prefer_ipv4 is vyos_defined %}
dual-stack transport-connection prefer ipv4
-{% endif %}
-{% if ldp.parameters.ordered_control is defined%}
+{% endif %}
+{% if ldp.parameters.ordered_control is vyos_defined %}
ordered-control
-{% endif %}
-{% endif %}
-{% if ldp.neighbor is defined %}
-{% for neighbors in ldp.neighbor %}
-{% if ldp.neighbor[neighbors].password is defined %}
- neighbor {{ neighbors }} password {{ ldp.neighbor[neighbors].password }}
-{% endif %}
-{% if ldp.neighbor[neighbors].ttl_security is defined %}
-{% if 'disable' in ldp.neighbor[neighbors].ttl_security %}
+{% endif %}
+{% if ldp.neighbor is vyos_defined %}
+{% for neighbor, neighbor_config in ldp.neighbor %}
+{% if neighbor_config.password is vyos_defined %}
+ neighbor {{ neighbors }} password {{ neighbor_config.password }}
+{% endif %}
+{% if neighbor_config.ttl_security is vyos_defined %}
+{% if neighbor_config.ttl_security.disable is vyos_defined%}
neighbor {{ neighbors }} ttl-security disable
-{% else %}
- neighbor {{ neighbors }} ttl-security hops {{ ldp.neighbor[neighbors].ttl_security }}
-{% endif %}
-{% endif %}
-{% if ldp.neighbor[neighbors].session_holdtime is defined %}
- neighbor {{ neighbors }} session holdtime {{ ldp.neighbor[neighbors].session_holdtime }}
-{% endif %}
-{% endfor %}
-{% endif %}
+{% else %}
+ neighbor {{ neighbors }} ttl-security hops {{ neighbor_config.ttl_security }}
+{% endif %}
+{% endif %}
+{% if neighbor_config.session_holdtime is vyos_defined %}
+ neighbor {{ neighbors }} session holdtime {{ neighbor_config.session_holdtime }}
+{% endif %}
+{% endfor %}
+{% endif %}
!
-{% if ldp.discovery is defined %}
-{% if ldp.discovery.transport_ipv4_address is defined %}
+{% if ldp.discovery.transport_ipv4_address is vyos_defined %}
address-family ipv4
-{% if ldp.allocation is defined %}
-{% if ldp.allocation.ipv4 is defined %}
-{% if ldp.allocation.ipv4.access_list is defined %}
+{% if ldp.allocation.ipv4.access_list is vyos_defined %}
label local allocate for {{ ldp.allocation.ipv4.access_list }}
-{% endif %}
-{% endif %}
-{% else %}
+{% else %}
label local allocate host-routes
-{% endif %}
-{% if ldp.discovery.transport_ipv4_address is defined %}
+{% endif %}
+{% if ldp.discovery.transport_ipv4_address is vyos_defined %}
discovery transport-address {{ ldp.discovery.transport_ipv4_address }}
-{% endif %}
-{% if ldp.discovery.hello_ipv4_holdtime is defined %}
+{% endif %}
+{% if ldp.discovery.hello_ipv4_holdtime is vyos_defined %}
discovery hello holdtime {{ ldp.discovery.hello_ipv4_holdtime }}
-{% endif %}
-{% if ldp.discovery.hello_ipv4_interval is defined %}
+{% endif %}
+{% if ldp.discovery.hello_ipv4_interval is vyos_defined %}
discovery hello interval {{ ldp.discovery.hello_ipv4_interval }}
-{% endif %}
-{% if ldp.discovery.session_ipv4_holdtime is defined %}
+{% endif %}
+{% if ldp.discovery.session_ipv4_holdtime is vyos_defined %}
session holdtime {{ ldp.discovery.session_ipv4_holdtime }}
-{% endif %}
-{% if ldp.import is defined %}
-{% if ldp.import.ipv4 is defined %}
-{% if ldp.import.ipv4.import_filter is defined %}
-{% if ldp.import.ipv4.import_filter.filter_access_list is defined %}
-{% if ldp.import.ipv4.import_filter.neighbor_access_list is defined %}
+{% endif %}
+{% if ldp.import.ipv4.import_filter.filter_access_list is vyos_defined %}
+{% if ldp.import.ipv4.import_filter.neighbor_access_list is vyos_defined %}
label remote accept for {{ ldp.import.ipv4.import_filter.filter_access_list }} from {{ ldp.import.ipv4.import_filter.neighbor_access_list }}
-{% else %}
+{% else %}
label remote accept for {{ ldp.import.ipv4.import_filter.filter_access_list }}
-{% endif %}
-{% endif %}
-{% endif %}
-{% endif %}
-{% endif %}
-{% if ldp.export is defined %}
-{% if ldp.export.ipv4 is defined %}
-{% if ldp.export.ipv4.explicit_null is defined %}
+{% endif %}
+{% endif %}
+{% if ldp.export.ipv4.explicit_null is vyos_defined %}
label local advertise explicit-null
-{% endif %}
-{% if ldp.export.ipv4.export_filter is defined %}
-{% if ldp.export.ipv4.export_filter.filter_access_list is defined %}
-{% if ldp.export.ipv4.export_filter.neighbor_access_list is defined %}
+{% endif %}
+{% if ldp.export.ipv4.export_filter.filter_access_list is vyos_defined %}
+{% if ldp.export.ipv4.export_filter.neighbor_access_list is vyos_defined %}
label local advertise for {{ ldp.export.ipv4.export_filter.filter_access_list }} to {{ ldp.export.ipv4.export_filter.neighbor_access_list }}
-{% else %}
+{% else %}
label local advertise for {{ ldp.export.ipv4.export_filter.filter_access_list }}
-{% endif %}
-{% endif %}
-{% endif %}
-{% endif %}
-{% endif %}
-{% if ldp.targeted_neighbor is defined %}
-{% if ldp.targeted_neighbor.ipv4.enable is defined %}
+{% endif %}
+{% endif %}
+{% if ldp.targeted_neighbor is vyos_defined %}
+{% if ldp.targeted_neighbor.ipv4.enable is vyos_defined %}
discovery targeted-hello accept
-{% endif %}
-{% if ldp.targeted_neighbor.ipv4.hello_holdtime is defined %}
+{% endif %}
+{% if ldp.targeted_neighbor.ipv4.hello_holdtime is vyos_defined %}
discovery targeted-hello holdtime {{ ldp.targeted_neighbor.ipv4.hello_holdtime }}
-{% endif %}
-{% if ldp.targeted_neighbor.ipv4.hello_interval is defined %}
+{% endif %}
+{% if ldp.targeted_neighbor.ipv4.hello_interval is vyos_defined %}
discovery targeted-hello interval {{ ldp.targeted_neighbor.ipv4.hello_interval }}
-{% endif %}
-{% for addresses in ldp.targeted_neighbor.ipv4.address %}
- neighbor {{addresses}} targeted
-{% endfor %}
-{% endif %}
-{% for interfaces in ldp.interface %}
- interface {{interfaces}}
-{% endfor %}
+{% endif %}
+{% for addresses in ldp.targeted_neighbor.ipv4.address %}
+ neighbor {{ addresses }} targeted
+{% endfor %}
+{% endif %}
+{% if ldp.interface is vyos_defined %}
+{% for interface in ldp.interface %}
+ interface {{ interface }}
+ exit
+{% endfor %}
+{% endif %}
exit-address-family
-{% else %}
+{% else %}
no address-family ipv4
-{% endif %}
-{% endif %}
+{% endif %}
!
-{% if ldp.discovery is defined %}
-{% if ldp.discovery.transport_ipv6_address is defined %}
+{% if ldp.discovery.transport_ipv6_address is vyos_defined %}
address-family ipv6
-{% if ldp.allocation is defined %}
-{% if ldp.allocation.ipv6 is defined %}
-{% if ldp.allocation.ipv6.access_list6 is defined %}
+{% if ldp.allocation.ipv6.access_list6 is vyos_defined %}
label local allocate for {{ ldp.allocation.ipv6.access_list6 }}
-{% endif %}
-{% endif %}
-{% else %}
+{% else %}
label local allocate host-routes
-{% endif %}
-{% if ldp.discovery.transport_ipv6_address is defined %}
+{% endif %}
+{% if ldp.discovery.transport_ipv6_address is vyos_defined %}
discovery transport-address {{ ldp.discovery.transport_ipv6_address }}
-{% endif %}
-{% if ldp.discovery.hello_ipv6_holdtime is defined %}
+{% endif %}
+{% if ldp.discovery.hello_ipv6_holdtime is vyos_defined %}
discovery hello holdtime {{ ldp.discovery.hello_ipv6_holdtime }}
-{% endif %}
-{% if ldp.discovery.hello_ipv6_interval is defined %}
+{% endif %}
+{% if ldp.discovery.hello_ipv6_interval is vyos_defined %}
discovery hello interval {{ ldp.discovery.hello_ipv6_interval }}
-{% endif %}
-{% if ldp.discovery.session_ipv6_holdtime is defined %}
+{% endif %}
+{% if ldp.discovery.session_ipv6_holdtime is vyos_defined %}
session holdtime {{ ldp.discovery.session_ipv6_holdtime }}
-{% endif %}
-{% if ldp.import is defined %}
-{% if ldp.import.ipv6 is defined %}
-{% if ldp.import.ipv6.import_filter is defined %}
-{% if ldp.import.ipv6.import_filter.filter_access_list6 is defined %}
-{% if ldp.import.ipv6.import_filter.neighbor_access_list6 is defined %}
+{% endif %}
+{% if ldp.import.ipv6.import_filter.filter_access_list6 is vyos_defined %}
+{% if ldp.import.ipv6.import_filter.neighbor_access_list6 is vyos_defined %}
label remote accept for {{ ldp.import.ipv6.import_filter.filter_access_list6 }} from {{ ldp.import.ipv6.import_filter.neighbor_access_list6 }}
-{% else %}
+{% else %}
label remote accept for {{ ldp.import.ipv6.import_filter.filter_access_list6 }}
-{% endif %}
-{% endif %}
-{% endif %}
-{% endif %}
-{% endif %}
-{% if ldp.export is defined %}
-{% if ldp.export.ipv6 is defined %}
-{% if ldp.export.ipv6.explicit_null is defined %}
+{% endif %}
+{% endif %}
+{% if ldp.export.ipv6.explicit_null is vyos_defined %}
label local advertise explicit-null
-{% endif %}
-{% if ldp.export.ipv6.export_filter is defined %}
-{% if ldp.export.ipv6.export_filter.filter_access_list6 is defined %}
-{% if ldp.export.ipv6.export_filter.neighbor_access_list6 is defined %}
+{% endif %}
+{% if ldp.export.ipv6.export_filter.filter_access_list6 is vyos_defined %}
+{% if ldp.export.ipv6.export_filter.neighbor_access_list6 is vyos_defined %}
label local advertise for {{ ldp.export.ipv6.export_filter.filter_access_list6 }} to {{ ldp.export.ipv6.export_filter.neighbor_access_list6 }}
-{% else %}
+{% else %}
label local advertise for {{ ldp.export.ipv6.export_filter.filter_access_list6 }}
-{% endif %}
-{% endif %}
-{% endif %}
-{% endif %}
-{% endif %}
-{% if ldp.targeted_neighbor is defined %}
-{% if ldp.targeted_neighbor.ipv6.enable is defined %}
+{% endif %}
+{% endif %}
+{% if ldp.targeted_neighbor is vyos_defined %}
+{% if ldp.targeted_neighbor.ipv6.enable is vyos_defined %}
discovery targeted-hello accept
-{% endif %}
-{% if ldp.targeted_neighbor.ipv6.hello_holdtime is defined %}
+{% endif %}
+{% if ldp.targeted_neighbor.ipv6.hello_holdtime is vyos_defined %}
discovery targeted-hello holdtime {{ ldp.targeted_neighbor.ipv6.hello_holdtime }}
-{% endif %}
-{% if ldp.targeted_neighbor.ipv6.hello_interval is defined %}
+{% endif %}
+{% if ldp.targeted_neighbor.ipv6.hello_interval is vyos_defined %}
discovery targeted-hello interval {{ ldp.targeted_neighbor.ipv6.hello_interval }}
-{% endif %}
-{% for addresses in ldp.targeted_neighbor.ipv6.address %}
- neighbor {{addresses}} targeted
-{% endfor %}
-{% endif %}
-{% for interfaces in ldp.interface %}
- interface {{interfaces}}
-{% endfor %}
+{% endif %}
+{% for addresses in ldp.targeted_neighbor.ipv6.address %}
+ neighbor {{ addresses }} targeted
+{% endfor %}
+{% endif %}
+{% if ldp.interface is vyos_defined %}
+{% for interface in ldp.interface %}
+ interface {{ interface }}
+{% endfor %}
+{% endif %}
exit-address-family
-{% else %}
+{% else %}
no address-family ipv6
-{% endif %}
+{% endif %}
!
-{% endif %}
exit
{% endif %}
!
diff --git a/data/templates/frr/ospf6d.frr.tmpl b/data/templates/frr/ospf6d.frr.tmpl
index a73c6cac3..325f05213 100644
--- a/data/templates/frr/ospf6d.frr.tmpl
+++ b/data/templates/frr/ospf6d.frr.tmpl
@@ -1,47 +1,47 @@
!
-{% if interface is defined and interface is not none %}
+{% if interface is vyos_defined %}
{% for iface, iface_config in interface.items() %}
interface {{ iface }}
-{% if iface_config.area is defined and iface_config.area is not none %}
+{% if iface_config.area is vyos_defined %}
ipv6 ospf6 area {{ iface_config.area }}
{% endif %}
-{% if iface_config.cost is defined and iface_config.cost is not none %}
+{% if iface_config.cost is vyos_defined %}
ipv6 ospf6 cost {{ iface_config.cost }}
{% endif %}
-{% if iface_config.priority is defined and iface_config.priority is not none %}
+{% if iface_config.priority is vyos_defined %}
ipv6 ospf6 priority {{ iface_config.priority }}
{% endif %}
-{% if iface_config.hello_interval is defined and iface_config.hello_interval is not none %}
+{% if iface_config.hello_interval is vyos_defined %}
ipv6 ospf6 hello-interval {{ iface_config.hello_interval }}
{% endif %}
-{% if iface_config.retransmit_interval is defined and iface_config.retransmit_interval is not none %}
+{% if iface_config.retransmit_interval is vyos_defined %}
ipv6 ospf6 retransmit-interval {{ iface_config.retransmit_interval }}
{% endif %}
-{% if iface_config.transmit_delay is defined and iface_config.transmit_delay is not none %}
+{% if iface_config.transmit_delay is vyos_defined %}
ipv6 ospf6 transmit-delay {{ iface_config.transmit_delay }}
{% endif %}
-{% if iface_config.dead_interval is defined and iface_config.dead_interval is not none %}
+{% if iface_config.dead_interval is vyos_defined %}
ipv6 ospf6 dead-interval {{ iface_config.dead_interval }}
{% endif %}
-{% if iface_config.bfd is defined %}
+{% if iface_config.bfd is vyos_defined %}
ipv6 ospf6 bfd
-{% if iface_config.bfd.profile is defined and iface_config.bfd.profile is not none %}
+{% endif %}
+{% if iface_config.bfd.profile is vyos_defined %}
ipv6 ospf6 bfd profile {{ iface_config.bfd.profile }}
-{% endif %}
{% endif %}
-{% if iface_config.mtu_ignore is defined %}
+{% if iface_config.mtu_ignore is vyos_defined %}
ipv6 ospf6 mtu-ignore
{% endif %}
-{% if iface_config.ifmtu is defined and iface_config.ifmtu is not none %}
+{% if iface_config.ifmtu is vyos_defined %}
ipv6 ospf6 ifmtu {{ iface_config.ifmtu }}
{% endif %}
-{% if iface_config.network is defined and iface_config.network is not none %}
+{% if iface_config.network is vyos_defined %}
ipv6 ospf6 network {{ iface_config.network }}
{% endif %}
-{% if iface_config.instance_id is defined and iface_config.instance_id is not none %}
+{% if iface_config.instance_id is vyos_defined %}
ipv6 ospf6 instance-id {{ iface_config.instance_id }}
{% endif %}
-{% if iface_config.passive is defined %}
+{% if iface_config.passive is vyos_defined %}
ipv6 ospf6 passive
{% endif %}
exit
@@ -49,50 +49,46 @@ exit
{% endfor %}
{% endif %}
!
-router ospf6 {{ 'vrf ' + vrf if vrf is defined and vrf is not none }}
-{% if area is defined and area is not none %}
+router ospf6 {{ 'vrf ' ~ vrf if vrf is vyos_defined }}
+{% if area is vyos_defined %}
{% for area_id, area_config in area.items() %}
-{% if area_config.area_type is defined and area_config.area_type is not none %}
+{% if area_config.area_type is vyos_defined %}
{% for type, type_config in area_config.area_type.items() %}
- area {{ area_id }} {{ type }} {{ 'default-information-originate' if type_config.default_information_originate is defined }} {{ 'no-summary' if type_config.no_summary is defined }}
+ area {{ area_id }} {{ type }} {{ 'default-information-originate' if type_config.default_information_originate is vyos_defined }} {{ 'no-summary' if type_config.no_summary is vyos_defined }}
{% endfor %}
{% endif %}
-{% if area_config.range is defined and area_config.range is not none %}
+{% if area_config.range is vyos_defined %}
{% for prefix, prefix_config in area_config.range.items() %}
- area {{ area_id }} range {{ prefix }} {{ 'advertise' if prefix_config.advertise is defined }} {{ 'not-advertise' if prefix_config.not_advertise is defined }}
+ area {{ area_id }} range {{ prefix }} {{ 'advertise' if prefix_config.advertise is vyos_defined }} {{ 'not-advertise' if prefix_config.not_advertise is vyos_defined }}
{% endfor %}
{% endif %}
-{% if area_config.export_list is defined and area_config.export_list is not none %}
+{% if area_config.export_list is vyos_defined %}
area {{ area_id }} export-list {{ area_config.export_list }}
{% endif %}
-{% if area_config.import_list is defined and area_config.import_list is not none %}
+{% if area_config.import_list is vyos_defined %}
area {{ area_id }} import-list {{ area_config.import_list }}
{% endif %}
{% endfor %}
{% endif %}
auto-cost reference-bandwidth {{ auto_cost.reference_bandwidth }}
-{% if default_information is defined and default_information.originate is defined and default_information.originate is not none %}
- default-information originate {{ 'always' if default_information.originate.always is defined }} {{ 'metric ' + default_information.originate.metric if default_information.originate.metric is defined }} {{ 'metric-type ' + default_information.originate.metric_type if default_information.originate.metric_type is defined }} {{ 'route-map ' + default_information.originate.route_map if default_information.originate.route_map is defined }}
+{% if default_information.originate is vyos_defined %}
+ default-information originate {{ 'always' if default_information.originate.always is vyos_defined }} {{ 'metric ' + default_information.originate.metric if default_information.originate.metric is vyos_defined }} {{ 'metric-type ' + default_information.originate.metric_type if default_information.originate.metric_type is vyos_defined }} {{ 'route-map ' + default_information.originate.route_map if default_information.originate.route_map is vyos_defined }}
{% endif %}
-{% if distance is defined and distance is not none %}
-{% if distance.global is defined and distance.global is not none %}
+{% if distance.global is vyos_defined %}
distance {{ distance.global }}
-{% endif %}
-{% if distance.ospfv3 is defined and distance.ospfv3 is not none %}
- distance ospf6 {{ 'intra-area ' + distance.ospfv3.intra_area if distance.ospfv3.intra_area is defined }} {{ 'inter-area ' + distance.ospfv3.inter_area if distance.ospfv3.inter_area is defined }} {{ 'external ' + distance.ospfv3.external if distance.ospfv3.external is defined }}
-{% endif %}
{% endif %}
-{% if log_adjacency_changes is defined %}
- log-adjacency-changes {{ "detail" if log_adjacency_changes.detail is defined }}
+{% if distance.ospfv3 is vyos_defined %}
+ distance ospf6 {{ 'intra-area ' + distance.ospfv3.intra_area if distance.ospfv3.intra_area is vyos_defined }} {{ 'inter-area ' + distance.ospfv3.inter_area if distance.ospfv3.inter_area is vyos_defined }} {{ 'external ' + distance.ospfv3.external if distance.ospfv3.external is vyos_defined }}
+{% endif %}
+{% if log_adjacency_changes is vyos_defined %}
+ log-adjacency-changes {{ "detail" if log_adjacency_changes.detail is vyos_defined }}
{% endif %}
-{% if parameters is defined and parameters is not none %}
-{% if parameters.router_id is defined and parameters.router_id is not none %}
+{% if parameters.router_id is vyos_defined %}
ospf6 router-id {{ parameters.router_id }}
-{% endif %}
{% endif %}
-{% if redistribute is defined and redistribute is not none %}
+{% if redistribute is vyos_defined %}
{% for protocol, options in redistribute.items() %}
- redistribute {{ protocol }} {{ 'route-map ' + options.route_map if options.route_map is defined }}
+ redistribute {{ protocol }} {{ 'route-map ' + options.route_map if options.route_map is vyos_defined }}
{% endfor %}
{% endif %}
exit
diff --git a/data/templates/frr/ospfd.frr.tmpl b/data/templates/frr/ospfd.frr.tmpl
index 59d936b55..7c6738181 100644
--- a/data/templates/frr/ospfd.frr.tmpl
+++ b/data/templates/frr/ospfd.frr.tmpl
@@ -1,121 +1,117 @@
!
-{% if interface is defined and interface is not none %}
+{% if interface is vyos_defined %}
{% for iface, iface_config in interface.items() %}
interface {{ iface }}
-{% if iface_config.authentication is defined and iface_config.authentication is not none %}
-{% if iface_config.authentication.plaintext_password is defined and iface_config.authentication.plaintext_password is not none %}
+{% if iface_config.authentication.plaintext_password is vyos_defined %}
ip ospf authentication-key {{ iface_config.authentication.plaintext_password }}
-{% elif iface_config.authentication.md5 is defined %}
+{% elif iface_config.authentication.md5 is vyos_defined %}
ip ospf authentication message-digest
-{% if iface_config.authentication.md5.key_id is defined and iface_config.authentication.md5.key_id is not none %}
-{% for key, key_config in iface_config.authentication.md5.key_id.items() %}
+{% if iface_config.authentication.md5.key_id is vyos_defined %}
+{% for key, key_config in iface_config.authentication.md5.key_id.items() %}
ip ospf message-digest-key {{ key }} md5 {{ key_config.md5_key }}
-{% endfor %}
-{% endif %}
+{% endfor %}
{% endif %}
{% endif %}
-{% if iface_config.area is defined and iface_config.area is not none %}
+{% if iface_config.area is vyos_defined %}
ip ospf area {{ iface_config.area }}
{% endif %}
-{% if iface_config.bandwidth is defined and iface_config.bandwidth is not none %}
+{% if iface_config.bandwidth is vyos_defined %}
bandwidth {{ iface_config.bandwidth }}
{% endif %}
-{% if iface_config.cost is defined and iface_config.cost is not none %}
+{% if iface_config.cost is vyos_defined %}
ip ospf cost {{ iface_config.cost }}
{% endif %}
-{% if iface_config.priority is defined and iface_config.priority is not none %}
+{% if iface_config.priority is vyos_defined %}
ip ospf priority {{ iface_config.priority }}
{% endif %}
-{% if iface_config.hello_interval is defined and iface_config.hello_interval is not none %}
+{% if iface_config.hello_interval is vyos_defined %}
ip ospf hello-interval {{ iface_config.hello_interval }}
{% endif %}
-{% if iface_config.retransmit_interval is defined and iface_config.retransmit_interval is not none %}
+{% if iface_config.retransmit_interval is vyos_defined %}
ip ospf retransmit-interval {{ iface_config.retransmit_interval }}
{% endif %}
-{% if iface_config.transmit_delay is defined and iface_config.transmit_delay is not none %}
+{% if iface_config.transmit_delay is vyos_defined %}
ip ospf transmit-delay {{ iface_config.transmit_delay }}
{% endif %}
-{% if iface_config.dead_interval is defined and iface_config.dead_interval is not none %}
+{% if iface_config.dead_interval is vyos_defined %}
ip ospf dead-interval {{ iface_config.dead_interval }}
-{% elif iface_config.hello_multiplier is defined and iface_config.hello_multiplier is not none %}
+{% elif iface_config.hello_multiplier is vyos_defined %}
ip ospf dead-interval minimal hello-multiplier {{ iface_config.hello_multiplier }}
{% endif %}
-{% if iface_config.bfd is defined %}
+{% if iface_config.bfd is vyos_defined %}
ip ospf bfd
-{% if iface_config.bfd.profile is defined and iface_config.bfd.profile is not none %}
+{% endif %}
+{% if iface_config.bfd.profile is vyos_defined %}
ip ospf bfd profile {{ iface_config.bfd.profile }}
-{% endif %}
{% endif %}
-{% if iface_config.mtu_ignore is defined %}
+{% if iface_config.mtu_ignore is vyos_defined %}
ip ospf mtu-ignore
{% endif %}
-{% if iface_config.network is defined and iface_config.network is not none %}
+{% if iface_config.network is vyos_defined %}
ip ospf network {{ iface_config.network }}
{% endif %}
-{% if iface_config.passive is defined %}
- {{ 'no ' if iface_config.passive.disable is defined }}ip ospf passive
+{% if iface_config.passive is vyos_defined %}
+ {{ 'no ' if iface_config.passive.disable is vyos_defined }}ip ospf passive
{% endif %}
exit
!
{% endfor %}
{% endif %}
!
-router ospf {{ 'vrf ' + vrf if vrf is defined and vrf is not none }}
-{% if access_list is defined and access_list is not none %}
+router ospf {{ 'vrf ' ~ vrf if vrf is vyos_defined }}
+{% if access_list is vyos_defined %}
{% for acl, acl_config in access_list.items() %}
-{% for protocol in acl_config.export if acl_config.export is defined %}
+{% for protocol in acl_config.export if acl_config.export is vyos_defined %}
distribute-list {{ acl }} out {{ protocol }}
{% endfor %}
{% endfor %}
{% endif %}
-{% if area is defined and area is not none %}
+{% if area is vyos_defined %}
{% for area_id, area_config in area.items() %}
-{% if area_config.area_type is defined and area_config.area_type is not none %}
+{% if area_config.area_type is vyos_defined %}
{% for type, type_config in area_config.area_type.items() if type != 'normal' %}
- area {{ area_id }} {{ type }} {{ 'no-summary' if type_config.no_summary is defined }}
-{% if type_config.default_cost is defined and type_config.default_cost is not none %}
+ area {{ area_id }} {{ type }} {{ 'no-summary' if type_config.no_summary is vyos_defined }}
+{% if type_config.default_cost is vyos_defined %}
area {{ area_id }} default-cost {{ type_config.default_cost }}
{% endif %}
{% endfor %}
{% endif %}
-{% if area_config.authentication is defined and area_config.authentication is not none %}
- area {{ area_id }} authentication {{ 'message-digest' if area_config.authentication == 'md5' }}
+{% if area_config.authentication is vyos_defined %}
+ area {{ area_id }} authentication {{ 'message-digest' if area_config.authentication is vyos_defined('md5') }}
{% endif %}
-{% for network in area_config.network if area_config.network is defined %}
+{% for network in area_config.network if area_config.network is vyos_defined %}
network {{ network }} area {{ area_id }}
{% endfor %}
-{% if area_config.range is defined and area_config.range is not none %}
+{% if area_config.range is vyos_defined %}
{% for range, range_config in area_config.range.items() %}
-{% if range_config.cost is defined and range_config.cost is not none %}
+{% if range_config.cost is vyos_defined %}
area {{ area_id }} range {{ range }} cost {{ range_config.cost }}
{% endif %}
-{% if range_config.not_advertise is defined %}
+{% if range_config.not_advertise is vyos_defined %}
area {{ area_id }} range {{ range }} not-advertise
{% endif %}
-{% if range_config.substitute is defined and range_config.substitute is not none %}
+{% if range_config.substitute is vyos_defined %}
area {{ area_id }} range {{ range }} substitute {{ range_config.substitute }}
{% endif %}
{% endfor %}
{% endif %}
-{% if area_config.export_list is defined and area_config.export_list is not none %}
+{% if area_config.export_list is vyos_defined %}
area {{ area_id }} export-list {{ area_config.export_list }}
{% endif %}
-{% if area_config.import_list is defined and area_config.import_list is not none %}
+{% if area_config.import_list is vyos_defined %}
area {{ area_id }} import-list {{ area_config.import_list }}
{% endif %}
-{% if area_config.shortcut is defined and area_config.shortcut is not none %}
+{% if area_config.shortcut is vyos_defined %}
area {{ area_id }} shortcut {{ area_config.shortcut }}
{% endif %}
-{% if area_config.virtual_link is defined and area_config.virtual_link is not none %}
+{% if area_config.virtual_link is vyos_defined %}
{% for link, link_config in area_config.virtual_link.items() %}
-{% if link_config.authentication is defined and link_config.authentication is not none %}
-{% if link_config.authentication.plaintext_password is defined and link_config.authentication.plaintext_password is not none %}
+{% if link_config.authentication.plaintext_password is vyos_defined %}
area {{ area_id }} virtual-link {{ link }} authentication-key {{ link_config.authentication.plaintext_password }}
-{% elif link_config.authentication.md5 is defined and link_config.authentication.md5.key_id is defined and link_config.authentication.md5.key_id is not none %}
-{% for key, key_config in link_config.authentication.md5.key_id.items() %}
+{% elif link_config.authentication.md5.key_id is vyos_defined %}
+{% for key, key_config in link_config.authentication.md5.key_id.items() %}
area {{ area_id }} virtual-link {{ link }} message-digest-key {{ key }} md5 {{ key_config.md5_key }}
-{% endfor %}
-{% endif %}
+{% endfor %}
{% endif %}
{# The following values are default values #}
area {{ area_id }} virtual-link {{ link }} hello-interval {{ link_config.hello_interval }} retransmit-interval {{ link_config.retransmit_interval }} transmit-delay {{ link_config.transmit_delay }} dead-interval {{ link_config.dead_interval }}
@@ -123,75 +119,69 @@ router ospf {{ 'vrf ' + vrf if vrf is defined and vrf is not none }}
{% endif %}
{% endfor %}
{% endif %}
-{% if auto_cost is defined and auto_cost.reference_bandwidth is defined and auto_cost.reference_bandwidth is not none %}
+{% if auto_cost.reference_bandwidth is vyos_defined %}
auto-cost reference-bandwidth {{ auto_cost.reference_bandwidth }}
{% endif %}
-{% if default_information is defined and default_information.originate is defined and default_information.originate is not none %}
- default-information originate {{ 'always' if default_information.originate.always is defined }} {{ 'metric ' + default_information.originate.metric if default_information.originate.metric is defined }} {{ 'metric-type ' + default_information.originate.metric_type if default_information.originate.metric_type is defined }} {{ 'route-map ' + default_information.originate.route_map if default_information.originate.route_map is defined }}
+{% if default_information.originate is vyos_defined %}
+ default-information originate {{ 'always' if default_information.originate.always is vyos_defined }} {{ 'metric ' + default_information.originate.metric if default_information.originate.metric is vyos_defined }} {{ 'metric-type ' + default_information.originate.metric_type if default_information.originate.metric_type is vyos_defined }} {{ 'route-map ' + default_information.originate.route_map if default_information.originate.route_map is vyos_defined }}
{% endif %}
-{% if default_metric is defined and default_metric is not none %}
+{% if default_metric is vyos_defined %}
default-metric {{ default_metric }}
{% endif %}
-{% if maximum_paths is defined and maximum_paths is not none %}
+{% if maximum_paths is vyos_defined %}
maximum-paths {{ maximum_paths }}
{% endif %}
-{% if distance is defined and distance is not none %}
-{% if distance.global is defined and distance.global is not none %}
+{% if distance.global is vyos_defined %}
distance {{ distance.global }}
-{% endif %}
-{% if distance.ospf is defined and distance.ospf is not none %}
- distance ospf {{ 'intra-area ' + distance.ospf.intra_area if distance.ospf.intra_area is defined }} {{ 'inter-area ' + distance.ospf.inter_area if distance.ospf.inter_area is defined }} {{ 'external ' + distance.ospf.external if distance.ospf.external is defined }}
-{% endif %}
{% endif %}
-{% if log_adjacency_changes is defined %}
- log-adjacency-changes {{ "detail" if log_adjacency_changes.detail is defined }}
+{% if distance.ospf is vyos_defined %}
+ distance ospf {{ 'intra-area ' + distance.ospf.intra_area if distance.ospf.intra_area is vyos_defined }} {{ 'inter-area ' + distance.ospf.inter_area if distance.ospf.inter_area is vyos_defined }} {{ 'external ' + distance.ospf.external if distance.ospf.external is vyos_defined }}
{% endif %}
-{% if max_metric is defined and max_metric.router_lsa is defined and max_metric.router_lsa is not none %}
-{% if max_metric.router_lsa.administrative is defined %}
+{% if log_adjacency_changes is vyos_defined %}
+ log-adjacency-changes {{ "detail" if log_adjacency_changes.detail is vyos_defined }}
+{% endif %}
+{% if max_metric.router_lsa.administrative is vyos_defined %}
max-metric router-lsa administrative
-{% endif %}
-{% if max_metric.router_lsa.on_shutdown is defined and max_metric.router_lsa.on_shutdown is not none %}
+{% endif %}
+{% if max_metric.router_lsa.on_shutdown is vyos_defined %}
max-metric router-lsa on-shutdown {{ max_metric.router_lsa.on_shutdown }}
-{% endif %}
-{% if max_metric.router_lsa.on_startup is defined and max_metric.router_lsa.on_startup is not none %}
+{% endif %}
+{% if max_metric.router_lsa.on_startup is vyos_defined %}
max-metric router-lsa on-startup {{ max_metric.router_lsa.on_startup }}
-{% endif %}
{% endif %}
-{% if mpls_te is defined and mpls_te.enable is defined %}
+{% if mpls_te.enable is vyos_defined %}
mpls-te on
mpls-te router-address {{ mpls_te.router_address }}
{% endif %}
-{% if neighbor is defined and neighbor is not none%}
+{% if neighbor is vyos_defined %}
{% for address, address_config in neighbor.items() %}
- neighbor {{ address }} {{ 'priority ' + address_config.priority if address_config.priority is defined }} {{ 'poll-interval ' + address_config.poll_interval if address_config.poll_interval is defined }}
+ neighbor {{ address }} {{ 'priority ' + address_config.priority if address_config.priority is vyos_defined }} {{ 'poll-interval ' + address_config.poll_interval if address_config.poll_interval is vyos_defined }}
{% endfor %}
{% endif %}
-{% if parameters is defined and parameters is not none %}
-{% if parameters.abr_type is defined and parameters.abr_type is not none %}
+{% if parameters.abr_type is vyos_defined %}
ospf abr-type {{ parameters.abr_type }}
-{% endif %}
-{% if parameters.router_id is defined and parameters.router_id is not none %}
+{% endif %}
+{% if parameters.router_id is vyos_defined %}
ospf router-id {{ parameters.router_id }}
-{% endif %}
{% endif %}
-{% if passive_interface is defined and passive_interface.default is defined %}
+{% if passive_interface.default is vyos_defined %}
passive-interface default
{% endif %}
-{% if redistribute is defined and redistribute is not none %}
+{% if redistribute is vyos_defined %}
{% for protocol, protocols_options in redistribute.items() %}
{% if protocol == 'table' %}
{% for table, table_options in protocols_options.items() %}
- redistribute {{ protocol }} {{ table }} {{ 'metric ' + table_options.metric if table_options.metric is defined }} {{ 'metric-type ' + table_options.metric_type if table_options.metric_type is defined }} {{ 'route-map ' + table_options.route_map if table_options.route_map is defined }}
+ redistribute {{ protocol }} {{ table }} {{ 'metric ' + table_options.metric if table_options.metric is vyos_defined }} {{ 'metric-type ' + table_options.metric_type if table_options.metric_type is vyos_defined }} {{ 'route-map ' + table_options.route_map if table_options.route_map is vyos_defined }}
{% endfor %}
{% else %}
- redistribute {{ protocol }} {{ 'metric ' + protocols_options.metric if protocols_options.metric is defined }} {{ 'metric-type ' + protocols_options.metric_type if protocols_options.metric_type is defined }} {{ 'route-map ' + protocols_options.route_map if protocols_options.route_map is defined }}
+ redistribute {{ protocol }} {{ 'metric ' + protocols_options.metric if protocols_options.metric is vyos_defined }} {{ 'metric-type ' + protocols_options.metric_type if protocols_options.metric_type is vyos_defined }} {{ 'route-map ' + protocols_options.route_map if protocols_options.route_map is vyos_defined }}
{% endif %}
{% endfor %}
{% endif %}
-{% if refresh is defined and refresh.timers is defined and refresh.timers is not none %}
+{% if refresh.timers is vyos_defined %}
refresh timer {{ refresh.timers }}
{% endif %}
-{% if timers is defined and timers.throttle is defined and timers.throttle.spf is defined and timers.throttle.spf is not none %}
+{% if timers.throttle.spf.delay is vyos_defined and timers.throttle.spf.initial_holdtime is vyos_defined and timers.throttle.spf.max_holdtime is vyos_defined %}
{# Timer values have default values #}
timers throttle spf {{ timers.throttle.spf.delay }} {{ timers.throttle.spf.initial_holdtime }} {{ timers.throttle.spf.max_holdtime }}
{% endif %}
diff --git a/data/templates/frr/policy.frr.tmpl b/data/templates/frr/policy.frr.tmpl
index 60e15f4fd..814dbf761 100644
--- a/data/templates/frr/policy.frr.tmpl
+++ b/data/templates/frr/policy.frr.tmpl
@@ -1,18 +1,18 @@
-{% if access_list is defined and access_list is not none %}
+{% if access_list is vyos_defined %}
{% for acl, acl_config in access_list.items() | natural_sort %}
-{% if acl_config.description is defined and acl_config.description is not none %}
+{% if acl_config.description is vyos_defined %}
access-list {{ acl }} remark {{ acl_config.description }}
{% endif %}
-{% if acl_config.rule is defined and acl_config.rule is not none %}
+{% if acl_config.rule is vyos_defined %}
{% for rule, rule_config in acl_config.rule.items() | natural_sort %}
{% set ip = '' %}
{% set src = '' %}
{% set src_mask = '' %}
-{% if rule_config.source is defined and rule_config.source.any is defined %}
+{% if rule_config.source.any is vyos_defined %}
{% set src = 'any' %}
-{% elif rule_config.source is defined and rule_config.source.host is defined and rule_config.source.host is not none %}
-{% set src = 'host ' + rule_config.source.host %}
-{% elif rule_config.source is defined and rule_config.source.network is defined and rule_config.source.network is not none %}
+{% elif rule_config.source.host is vyos_defined %}
+{% set src = 'host ' ~ rule_config.source.host %}
+{% elif rule_config.source.network is vyos_defined %}
{% set src = rule_config.source.network %}
{% set src_mask = rule_config.source.inverse_mask %}
{% endif %}
@@ -21,11 +21,11 @@ access-list {{ acl }} remark {{ acl_config.description }}
{% if (acl|int >= 100 and acl|int <= 199) or (acl|int >= 2000 and acl|int <= 2699) %}
{% set ip = 'ip' %}
{% set dst = 'any' %}
-{% if rule_config.destination is defined and rule_config.destination.any is defined %}
+{% if rule_config.destination.any is vyos_defined %}
{% set dst = 'any' %}
-{% elif rule_config.destination is defined and rule_config.destination.host is defined and rule_config.destination.host is not none %}
-{% set dst = 'host ' + rule_config.destination.host %}
-{% elif rule_config.destination is defined and rule_config.destination.network is defined and rule_config.destination.network is not none %}
+{% elif rule_config.destination.host is vyos_defined %}
+{% set dst = 'host ' ~ rule_config.destination.host %}
+{% elif rule_config.destination.network is vyos_defined %}
{% set dst = rule_config.destination.network %}
{% set dst_mask = rule_config.destination.inverse_mask %}
{% endif %}
@@ -36,28 +36,28 @@ access-list {{ acl }} seq {{ rule }} {{ rule_config.action }} {{ ip }} {{ src }}
{% endfor %}
{% endif %}
!
-{% if access_list6 is defined and access_list6 is not none %}
+{% if access_list6 is vyos_defined %}
{% for acl, acl_config in access_list6.items() | natural_sort %}
-{% if acl_config.description is defined and acl_config.description is not none %}
+{% if acl_config.description is vyos_defined %}
ipv6 access-list {{ acl }} remark {{ acl_config.description }}
{% endif %}
-{% if acl_config.rule is defined and acl_config.rule is not none %}
+{% if acl_config.rule is vyos_defined %}
{% for rule, rule_config in acl_config.rule.items() | natural_sort %}
{% set src = '' %}
-{% if rule_config.source is defined and rule_config.source.any is defined %}
+{% if rule_config.source.any is vyos_defined %}
{% set src = 'any' %}
-{% elif rule_config.source is defined and rule_config.source.network is defined and rule_config.source.network is not none %}
+{% elif rule_config.source.network is vyos_defined %}
{% set src = rule_config.source.network %}
{% endif %}
-ipv6 access-list {{ acl }} seq {{ rule }} {{ rule_config.action }} {{ src }} {{ 'exact-match' if rule_config.source.exact_match is defined }}
+ipv6 access-list {{ acl }} seq {{ rule }} {{ rule_config.action }} {{ src }} {{ 'exact-match' if rule_config.source.exact_match is vyos_defined }}
{% endfor %}
{% endif %}
{% endfor %}
{% endif %}
!
-{% if as_path_list is defined and as_path_list is not none %}
+{% if as_path_list is vyos_defined %}
{% for acl, acl_config in as_path_list.items() | natural_sort %}
-{% if acl_config.rule is defined and acl_config.rule is not none %}
+{% if acl_config.rule is vyos_defined %}
{% for rule, rule_config in acl_config.rule.items() | natural_sort %}
bgp as-path access-list {{ acl }} seq {{ rule }} {{ rule_config.action }} {{ rule_config.regex }}
{% endfor %}
@@ -65,9 +65,9 @@ bgp as-path access-list {{ acl }} seq {{ rule }} {{ rule_config.action }} {{ rul
{% endfor %}
{% endif %}
!
-{% if community_list is defined and community_list is not none %}
+{% if community_list is vyos_defined %}
{% for list, list_config in community_list.items() | natural_sort %}
-{% if list_config.rule is defined and list_config.rule is not none %}
+{% if list_config.rule is vyos_defined %}
{% for rule, rule_config in list_config.rule.items() | natural_sort %}
{# by default, if casting to int fails it returns 0 #}
{% if list|int != 0 %}
@@ -80,9 +80,9 @@ bgp community-list expanded {{ list }} seq {{ rule }} {{ rule_config.action }} {
{% endfor %}
{% endif %}
!
-{% if extcommunity_list is defined and extcommunity_list is not none %}
+{% if extcommunity_list is vyos_defined %}
{% for list, list_config in extcommunity_list.items() | natural_sort %}
-{% if list_config.rule is defined and list_config.rule is not none %}
+{% if list_config.rule is vyos_defined %}
{% for rule, rule_config in list_config.rule.items() | natural_sort %}
{# by default, if casting to int fails it returns 0 #}
{% if list|int != 0 %}
@@ -95,9 +95,9 @@ bgp extcommunity-list expanded {{ list }} seq {{ rule }} {{ rule_config.action }
{% endfor %}
{% endif %}
!
-{% if large_community_list is defined and large_community_list is not none %}
+{% if large_community_list is vyos_defined %}
{% for list, list_config in large_community_list.items() | natural_sort %}
-{% if list_config.rule is defined and list_config.rule is not none %}
+{% if list_config.rule is vyos_defined %}
{% for rule, rule_config in list_config.rule.items() | natural_sort %}
{# by default, if casting to int fails it returns 0 #}
{% if list|int != 0 %}
@@ -110,209 +110,207 @@ bgp large-community-list expanded {{ list }} seq {{ rule }} {{ rule_config.actio
{% endfor %}
{% endif %}
!
-{% if prefix_list is defined and prefix_list is not none %}
+{% if prefix_list is vyos_defined %}
{% for prefix_list, prefix_list_config in prefix_list.items() | natural_sort %}
-{% if prefix_list_config.description is defined and prefix_list_config.description is not none %}
+{% if prefix_list_config.description is vyos_defined %}
ip prefix-list {{ prefix_list }} description {{ prefix_list_config.description }}
{% endif %}
-{% if prefix_list_config.rule is defined and prefix_list_config.rule is not none %}
+{% if prefix_list_config.rule is vyos_defined %}
{% for rule, rule_config in prefix_list_config.rule.items() | natural_sort %}
-{% if rule_config.prefix is defined and rule_config.prefix is not none %}
-ip prefix-list {{ prefix_list }} seq {{ rule }} {{ rule_config.action }} {{ rule_config.prefix }} {{ 'ge ' + rule_config.ge if rule_config.ge is defined }} {{ 'le ' + rule_config.le if rule_config.le is defined }}
+{% if rule_config.prefix is vyos_defined %}
+ip prefix-list {{ prefix_list }} seq {{ rule }} {{ rule_config.action }} {{ rule_config.prefix }} {{ 'ge ' ~ rule_config.ge if rule_config.ge is vyos_defined }} {{ 'le ' ~ rule_config.le if rule_config.le is vyos_defined }}
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}
{% endif %}
!
-{% if prefix_list6 is defined and prefix_list6 is not none %}
+{% if prefix_list6 is vyos_defined %}
{% for prefix_list, prefix_list_config in prefix_list6.items() | natural_sort %}
-{% if prefix_list_config.description is defined and prefix_list_config.description is not none %}
+{% if prefix_list_config.description is vyos_defined %}
ipv6 prefix-list {{ prefix_list }} description {{ prefix_list_config.description }}
{% endif %}
-{% if prefix_list_config.rule is defined and prefix_list_config.rule is not none %}
+{% if prefix_list_config.rule is vyos_defined %}
{% for rule, rule_config in prefix_list_config.rule.items() | natural_sort %}
-{% if rule_config.prefix is defined and rule_config.prefix is not none %}
-ipv6 prefix-list {{ prefix_list }} seq {{ rule }} {{ rule_config.action }} {{ rule_config.prefix }} {{ 'ge ' + rule_config.ge if rule_config.ge is defined }} {{ 'le ' + rule_config.le if rule_config.le is defined }}
+{% if rule_config.prefix is vyos_defined %}
+ipv6 prefix-list {{ prefix_list }} seq {{ rule }} {{ rule_config.action }} {{ rule_config.prefix }} {{ 'ge ' ~ rule_config.ge if rule_config.ge is vyos_defined }} {{ 'le ' ~ rule_config.le if rule_config.le is vyos_defined }}
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}
{% endif %}
!
-{% if route_map is defined and route_map is not none %}
+{% if route_map is vyos_defined %}
{% for route_map, route_map_config in route_map.items() | natural_sort %}
-{% if route_map_config.rule is defined and route_map_config.rule is not none %}
+{% if route_map_config.rule is vyos_defined %}
{% for rule, rule_config in route_map_config.rule.items() | natural_sort %}
route-map {{ route_map }} {{ rule_config.action }} {{ rule }}
-{% if rule_config.call is defined and rule_config.call is not none %}
+{% if rule_config.call is vyos_defined %}
call {{ rule_config.call }}
{% endif %}
-{% if rule_config.continue is defined and rule_config.continue is not none %}
+{% if rule_config.continue is vyos_defined %}
on-match goto {{ rule_config.continue }}
{% endif %}
-{% if rule_config.description is defined and rule_config.description is not none %}
+{% if rule_config.description is vyos_defined %}
description {{ rule_config.description }}
{% endif %}
-{% if rule_config.match is defined and rule_config.match is not none %}
-{% if rule_config.match.as_path is defined and rule_config.match.as_path is not none %}
+{% if rule_config.match is vyos_defined %}
+{% if rule_config.match.as_path is vyos_defined %}
match as-path {{ rule_config.match.as_path }}
{% endif %}
-{% if rule_config.match.community is defined and rule_config.match.community.community_list is defined and rule_config.match.community.community_list is not none %}
- match community {{ rule_config.match.community.community_list }} {{ 'exact-match' if rule_config.match.community.exact_match is defined }}
+{% if rule_config.match.community.community_list is vyos_defined %}
+ match community {{ rule_config.match.community.community_list }} {{ 'exact-match' if rule_config.match.community.exact_match is vyos_defined }}
{% endif %}
-{% if rule_config.match.extcommunity is defined and rule_config.match.extcommunity is not none %}
+{% if rule_config.match.extcommunity is vyos_defined %}
match extcommunity {{ rule_config.match.extcommunity }}
{% endif %}
-{% if rule_config.match.evpn is defined and rule_config.match.evpn.default_route is defined %}
+{% if rule_config.match.evpn.default_route is vyos_defined %}
match evpn default-route
{% endif %}
-{% if rule_config.match.evpn is defined and rule_config.match.evpn.rd is defined and rule_config.match.evpn.rd is not none %}
+{% if rule_config.match.evpn.rd is vyos_defined %}
match evpn rd {{ rule_config.match.evpn.rd }}
{% endif %}
-{% if rule_config.match.evpn is defined and rule_config.match.evpn.route_type is defined and rule_config.match.evpn.route_type is not none %}
+{% if rule_config.match.evpn.route_type is vyos_defined %}
match evpn route-type {{ rule_config.match.evpn.route_type }}
{% endif %}
-{% if rule_config.match.evpn is defined and rule_config.match.evpn.vni is defined and rule_config.match.evpn.vni is not none %}
+{% if rule_config.match.evpn.vni is vyos_defined %}
match evpn vni {{ rule_config.match.evpn.vni }}
{% endif %}
-{% if rule_config.match.interface is defined and rule_config.match.interface is not none %}
+{% if rule_config.match.interface is vyos_defined %}
match interface {{ rule_config.match.interface }}
{% endif %}
-{% if rule_config.match.ip is defined and rule_config.match.ip.address is defined and rule_config.match.ip.address.access_list is defined and rule_config.match.ip.address.access_list is not none %}
+{% if rule_config.match.ip.address.access_list is vyos_defined %}
match ip address {{ rule_config.match.ip.address.access_list }}
{% endif %}
-{% if rule_config.match.ip is defined and rule_config.match.ip.address is defined and rule_config.match.ip.address.prefix_list is defined and rule_config.match.ip.address.prefix_list is not none %}
+{% if rule_config.match.ip.address.prefix_list is vyos_defined %}
match ip address prefix-list {{ rule_config.match.ip.address.prefix_list }}
{% endif %}
-{% if rule_config.match.ip is defined and rule_config.match.ip.nexthop is defined and rule_config.match.ip.nexthop.access_list is defined and rule_config.match.ip.nexthop.access_list is not none %}
+{% if rule_config.match.ip.nexthop.access_list is vyos_defined %}
match ip next-hop {{ rule_config.match.ip.nexthop.access_list }}
{% endif %}
-{% if rule_config.match.ip is defined and rule_config.match.ip.nexthop is defined and rule_config.match.ip.nexthop.prefix_list is defined and rule_config.match.ip.nexthop.prefix_list is not none %}
+{% if rule_config.match.ip.nexthop.prefix_list is vyos_defined %}
match ip next-hop prefix-list {{ rule_config.match.ip.nexthop.prefix_list }}
{% endif %}
-{% if rule_config.match.ip is defined and rule_config.match.ip.route_source is defined and rule_config.match.ip.route_source.access_list is defined and rule_config.match.ip.route_source.access_list is not none %}
+{% if rule_config.match.ip.route_source.access_list is vyos_defined %}
match ip route-source {{ rule_config.match.ip.route_source.access_list }}
{% endif %}
-{% if rule_config.match.ip is defined and rule_config.match.ip.route_source is defined and rule_config.match.ip.route_source.prefix_list is defined and rule_config.match.ip.route_source.prefix_list is not none %}
+{% if rule_config.match.ip.route_source.prefix_list is vyos_defined %}
match ip route-source prefix-list {{ rule_config.match.ip.route_source.prefix_list }}
{% endif %}
-{% if rule_config.match.ipv6 is defined and rule_config.match.ipv6.address is defined and rule_config.match.ipv6.address.access_list is defined and rule_config.match.ipv6.address.access_list is not none %}
+{% if rule_config.match.ipv6.address.access_list is vyos_defined %}
match ipv6 address {{ rule_config.match.ipv6.address.access_list }}
{% endif %}
-{% if rule_config.match.ipv6 is defined and rule_config.match.ipv6.address is defined and rule_config.match.ipv6.address.prefix_list is defined and rule_config.match.ipv6.address.prefix_list is not none %}
+{% if rule_config.match.ipv6.address.prefix_list is vyos_defined %}
match ipv6 address prefix-list {{ rule_config.match.ipv6.address.prefix_list }}
{% endif %}
-{% if rule_config.match.ipv6 is defined and rule_config.match.ipv6.nexthop is defined and rule_config.match.ipv6.nexthop is not none %}
+{% if rule_config.match.ipv6.nexthop is vyos_defined %}
match ipv6 next-hop address {{ rule_config.match.ipv6.nexthop }}
{% endif %}
-{% if rule_config.match.large_community is defined and rule_config.match.large_community.large_community_list is defined and rule_config.match.large_community.large_community_list is not none %}
+{% if rule_config.match.large_community.large_community_list is vyos_defined %}
match large-community {{ rule_config.match.large_community.large_community_list }}
{% endif %}
-{% if rule_config.match.local_preference is defined and rule_config.match.local_preference is not none %}
+{% if rule_config.match.local_preference is vyos_defined %}
match local-preference {{ rule_config.match.local_preference }}
{% endif %}
-{% if rule_config.match.metric is defined and rule_config.match.metric is not none %}
+{% if rule_config.match.metric is vyos_defined %}
match metric {{ rule_config.match.metric }}
{% endif %}
-{% if rule_config.match.origin is defined and rule_config.match.origin is not none %}
+{% if rule_config.match.origin is vyos_defined %}
match origin {{ rule_config.match.origin }}
{% endif %}
-{% if rule_config.match.peer is defined and rule_config.match.peer is not none %}
+{% if rule_config.match.peer is vyos_defined %}
match peer {{ rule_config.match.peer }}
{% endif %}
-{% if rule_config.match.rpki is defined and rule_config.match.rpki is not none %}
+{% if rule_config.match.rpki is vyos_defined %}
match rpki {{ rule_config.match.rpki }}
{% endif %}
-{% if rule_config.match.tag is defined and rule_config.match.tag is not none %}
+{% if rule_config.match.tag is vyos_defined %}
match tag {{ rule_config.match.tag }}
{% endif %}
{% endif %}
-{% if rule_config.on_match is defined and rule_config.on_match is not none %}
-{% if rule_config.on_match.next is defined %}
+{% if rule_config.on_match.next is vyos_defined %}
on-match next
-{% endif %}
-{% if rule_config.on_match.goto is defined and rule_config.on_match.goto is not none %}
+{% endif %}
+{% if rule_config.on_match.goto is vyos_defined %}
on-match goto {{ rule_config.on_match.goto }}
-{% endif %}
{% endif %}
-{% if rule_config.set is defined and rule_config.set is not none %}
-{% if rule_config.set.aggregator is defined and rule_config.set.aggregator.as is defined and rule_config.set.aggregator.ip is defined %}
+{% if rule_config.set is vyos_defined %}
+{% if rule_config.set.aggregator.as is vyos_defined and rule_config.set.aggregator.ip is vyos_defined %}
set aggregator as {{ rule_config.set.aggregator.as }} {{ rule_config.set.aggregator.ip }}
{% endif %}
-{% if rule_config.set.as_path_exclude is defined and rule_config.set.as_path_exclude is not none %}
+{% if rule_config.set.as_path_exclude is vyos_defined %}
set as-path exclude {{ rule_config.set.as_path_exclude }}
{% endif %}
-{% if rule_config.set.as_path_prepend is defined and rule_config.set.as_path_prepend is not none %}
+{% if rule_config.set.as_path_prepend is vyos_defined %}
set as-path prepend {{ rule_config.set.as_path_prepend }}
{% endif %}
-{% if rule_config.set.atomic_aggregate is defined %}
+{% if rule_config.set.atomic_aggregate is vyos_defined %}
set atomic-aggregate
{% endif %}
-{% if rule_config.set.comm_list is defined and rule_config.set.comm_list.comm_list is defined and rule_config.set.comm_list.comm_list is not none %}
- set comm-list {{ rule_config.set.comm_list.comm_list }} {{ 'delete' if rule_config.set.comm_list.delete is defined }}
+{% if rule_config.set.comm_list.comm_list is vyos_defined %}
+ set comm-list {{ rule_config.set.comm_list.comm_list }} {{ 'delete' if rule_config.set.comm_list.delete is vyos_defined }}
{% endif %}
-{% if rule_config.set.community is defined and rule_config.set.community is not none %}
+{% if rule_config.set.community is vyos_defined %}
set community {{ rule_config.set.community }}
{% endif %}
-{% if rule_config.set.distance is defined and rule_config.set.distance is not none %}
+{% if rule_config.set.distance is vyos_defined %}
set distance {{ rule_config.set.distance }}
{% endif %}
-{% if rule_config.set.extcommunity is defined and rule_config.set.extcommunity.bandwidth is defined and rule_config.set.extcommunity.bandwidth is not none %}
+{% if rule_config.set.extcommunity.bandwidth is vyos_defined %}
set extcommunity bandwidth {{ rule_config.set.extcommunity.bandwidth }}
{% endif %}
-{% if rule_config.set.extcommunity is defined and rule_config.set.extcommunity.rt is defined and rule_config.set.extcommunity.rt is not none %}
+{% if rule_config.set.extcommunity.rt is vyos_defined %}
set extcommunity rt {{ rule_config.set.extcommunity.rt }}
{% endif %}
-{% if rule_config.set.extcommunity is defined and rule_config.set.extcommunity.soo is defined and rule_config.set.extcommunity.soo is not none %}
+{% if rule_config.set.extcommunity.soo is vyos_defined %}
set extcommunity soo {{ rule_config.set.extcommunity.soo }}
{% endif %}
-{% if rule_config.set.ip_next_hop is defined and rule_config.set.ip_next_hop is not none %}
+{% if rule_config.set.ip_next_hop is vyos_defined %}
set ip next-hop {{ rule_config.set.ip_next_hop }}
{% endif %}
-{% if rule_config.set.ipv6_next_hop is defined and rule_config.set.ipv6_next_hop.global is defined and rule_config.set.ipv6_next_hop.global is not none %}
+{% if rule_config.set.ipv6_next_hop.global is vyos_defined %}
set ipv6 next-hop global {{ rule_config.set.ipv6_next_hop.global }}
{% endif %}
-{% if rule_config.set.ipv6_next_hop is defined and rule_config.set.ipv6_next_hop.local is defined and rule_config.set.ipv6_next_hop.local is not none %}
+{% if rule_config.set.ipv6_next_hop.local is vyos_defined %}
set ipv6 next-hop local {{ rule_config.set.ipv6_next_hop.local }}
{% endif %}
-{% if rule_config.set.ipv6_next_hop is defined and rule_config.set.ipv6_next_hop.peer_address is defined %}
+{% if rule_config.set.ipv6_next_hop.peer_address is vyos_defined %}
set ipv6 next-hop peer-address
{% endif %}
-{% if rule_config.set.ipv6_next_hop is defined and rule_config.set.ipv6_next_hop.prefer_global is defined %}
+{% if rule_config.set.ipv6_next_hop.prefer_global is vyos_defined %}
set ipv6 next-hop prefer-global
{% endif %}
-{% if rule_config.set.large_community is defined and rule_config.set.large_community is not none %}
+{% if rule_config.set.large_community is vyos_defined %}
set large-community {{ rule_config.set.large_community }}
{% endif %}
-{% if rule_config.set.large_comm_list_delete is defined and rule_config.set.large_comm_list_delete is not none %}
+{% if rule_config.set.large_comm_list_delete is vyos_defined %}
set large-comm-list {{ rule_config.set.large_comm_list_delete }} delete
{% endif %}
-{% if rule_config.set.local_preference is defined and rule_config.set.local_preference is not none %}
+{% if rule_config.set.local_preference is vyos_defined %}
set local-preference {{ rule_config.set.local_preference }}
{% endif %}
-{% if rule_config.set.metric is defined and rule_config.set.metric is not none %}
+{% if rule_config.set.metric is vyos_defined %}
set metric {{ rule_config.set.metric }}
{% endif %}
-{% if rule_config.set.metric_type is defined and rule_config.set.metric_type is not none %}
+{% if rule_config.set.metric_type is vyos_defined %}
set metric-type {{ rule_config.set.metric_type }}
{% endif %}
-{% if rule_config.set.origin is defined and rule_config.set.origin is not none %}
+{% if rule_config.set.origin is vyos_defined %}
set origin {{ rule_config.set.origin }}
{% endif %}
-{% if rule_config.set.originator_id is defined and rule_config.set.originator_id is not none %}
+{% if rule_config.set.originator_id is vyos_defined %}
set originator-id {{ rule_config.set.originator_id }}
{% endif %}
-{% if rule_config.set.src is defined and rule_config.set.src is not none %}
+{% if rule_config.set.src is vyos_defined %}
set src {{ rule_config.set.src }}
{% endif %}
-{% if rule_config.set.table is defined and rule_config.set.table is not none %}
+{% if rule_config.set.table is vyos_defined %}
set table {{ rule_config.set.table }}
{% endif %}
-{% if rule_config.set.tag is defined and rule_config.set.tag is not none %}
+{% if rule_config.set.tag is vyos_defined %}
set tag {{ rule_config.set.tag }}
{% endif %}
-{% if rule_config.set.weight is defined and rule_config.set.weight is not none %}
+{% if rule_config.set.weight is vyos_defined %}
set weight {{ rule_config.set.weight }}
{% endif %}
{% endif %}
diff --git a/data/templates/frr/rip_ripng.frr.j2 b/data/templates/frr/rip_ripng.frr.j2
index de180ee6b..3732371b2 100644
--- a/data/templates/frr/rip_ripng.frr.j2
+++ b/data/templates/frr/rip_ripng.frr.j2
@@ -1,36 +1,36 @@
-{% if default_information is defined and default_information.originate is defined %}
+{% if default_information is vyos_defined %}
default-information originate
{% endif %}
-{% if default_metric is defined and default_metric is not none %}
+{% if default_metric is vyos_defined %}
default-metric {{ default_metric }}
{% endif %}
-{% if passive_interface is defined and passive_interface is not none %}
+{% if passive_interface is vyos_defined %}
{% for interface in passive_interface %}
passive-interface {{ interface }}
{% endfor %}
{% endif %}
-{% if network is defined and network is not none %}
+{% if network is vyos_defined %}
{% for prefix in network %}
network {{ prefix }}
{% endfor %}
{% endif %}
-{% if interface is defined and interface is not none %}
+{% if interface is vyos_defined %}
{% for ifname in interface %}
network {{ ifname }}
{% endfor %}
{% endif %}
-{% if route is defined and route is not none %}
+{% if route is vyos_defined %}
{% for prefix in route %}
route {{ prefix }}
{% endfor %}
{% endif %}
{# timers have default values #}
timers basic {{ timers['update'] }} {{ timers.timeout }} {{ timers.garbage_collection }}
-{% if redistribute is defined and redistribute is not none %}
+{% if redistribute is vyos_defined %}
{% for protocol, protocol_config in redistribute.items() %}
-{% if protocol == 'ospfv3' %}
+{% if protocol is vyos_defined('ospfv3') %}
{% set protocol = 'ospf6' %}
{% endif %}
- redistribute {{ protocol }} {{ 'metric ' + protocol_config.metric if protocol_config.metric is defined }} {{ 'route-map ' + protocol_config.route_map if protocol_config.route_map is defined }}
+ redistribute {{ protocol }} {{ 'metric ' ~ protocol_config.metric if protocol_config.metric is vyos_defined }} {{ 'route-map ' ~ protocol_config.route_map if protocol_config.route_map is vyos_defined }}
{% endfor %}
{% endif %}
diff --git a/data/templates/frr/ripd.frr.tmpl b/data/templates/frr/ripd.frr.tmpl
index c44bb6d27..2dbb93052 100644
--- a/data/templates/frr/ripd.frr.tmpl
+++ b/data/templates/frr/ripd.frr.tmpl
@@ -1,11 +1,11 @@
{# RIP key-chain definition #}
-{% if interface is defined and interface is not none %}
+{% if interface is vyos_defined %}
{% for iface, iface_config in interface.items() %}
-{% if iface_config.authentication is defined and iface_config.authentication.md5 is defined and iface_config.authentication.md5 is not none %}
+{% if iface_config.authentication.md5 is vyos_defined %}
key chain {{ iface }}-rip
{% for key_id, key_options in iface_config.authentication.md5.items() %}
key {{ key_id }}
-{% if key_options.password is defined and key_options.password is not none %}
+{% if key_options.password is vyos_defined %}
key-string {{ key_options.password }}
{% endif %}
exit
@@ -16,20 +16,20 @@ exit
{% endif %}
!
{# Interface specific configuration #}
-{% if interface is defined and interface is not none %}
+{% if interface is vyos_defined %}
{% for iface, iface_config in interface.items() %}
interface {{ iface }}
-{% if iface_config.authentication is defined and iface_config.authentication.plaintext_password is defined and iface_config.authentication.plaintext_password is not none %}
+{% if iface_config.authentication.plaintext_password is vyos_defined %}
ip rip authentication mode text
ip rip authentication string {{ iface_config.authentication.plaintext_password }}
-{% elif iface_config.authentication is defined and iface_config.authentication.md5 is defined and iface_config.authentication.md5 is not none %}
+{% elif iface_config.authentication.md5 is vyos_defined %}
ip rip authentication key-chain {{ iface }}-rip
ip rip authentication mode md5
{% endif %}
-{% if iface_config.split_horizon is defined and iface_config.split_horizon.disable is defined %}
+{% if iface_config.split_horizon.disable is vyos_defined %}
no ip rip split-horizon
{% endif %}
-{% if iface_config.split_horizon is defined and iface_config.split_horizon.poison_reverse is defined %}
+{% if iface_config.split_horizon.poison_reverse is vyos_defined %}
ip rip split-horizon poisoned-reverse
{% endif %}
exit
@@ -38,63 +38,55 @@ exit
{% endif %}
!
router rip
-{% if default_distance is defined and default_distance is not none %}
+{% if default_distance is vyos_defined %}
distance {{ default_distance }}
{% endif %}
-{% if network_distance is defined and network_distance is not none %}
+{% if network_distance is vyos_defined %}
{% for network, network_config in network_distance.items() %}
-{% if network_config.distance is defined and network_config.distance is not none %}
+{% if network_config.distance is vyos_defined %}
distance {{ network_config.distance }} {{ network }}
{% endif %}
{% endfor %}
{% endif %}
-{% if neighbor is defined and neighbor is not none %}
+{% if neighbor is vyos_defined %}
{% for address in neighbor %}
neighbor {{ address }}
{% endfor %}
{% endif %}
-{% if distribute_list is defined and distribute_list is not none %}
-{% if distribute_list.access_list is defined and distribute_list.access_list is not none %}
-{% if distribute_list.access_list.in is defined and distribute_list.access_list.in is not none %}
+{% if distribute_list is vyos_defined %}
+{% if distribute_list.access_list.in is vyos_defined %}
distribute-list {{ distribute_list.access_list.in }} in
-{% endif %}
-{% if distribute_list.access_list.out is defined and distribute_list.access_list.out is not none %}
+{% endif %}
+{% if distribute_list.access_list.out is vyos_defined %}
distribute-list {{ distribute_list.access_list.out }} out
-{% endif %}
{% endif %}
-{% if distribute_list.interface is defined and distribute_list.interface is not none %}
+{% if distribute_list.interface is vyos_defined %}
{% for interface, interface_config in distribute_list.interface.items() %}
-{% if interface_config.access_list is defined and interface_config.access_list is not none %}
-{% if interface_config.access_list.in is defined and interface_config.access_list.in is not none %}
+{% if interface_config.access_list.in is vyos_defined %}
distribute-list {{ interface_config.access_list.in }} in {{ interface }}
-{% endif %}
-{% if interface_config.access_list.out is defined and interface_config.access_list.out is not none %}
+{% endif %}
+{% if interface_config.access_list.out is vyos_defined %}
distribute-list {{ interface_config.access_list.out }} out {{ interface }}
-{% endif %}
{% endif %}
-{% if interface_config.prefix_list is defined and interface_config.prefix_list is not none %}
-{% if interface_config.prefix_list.in is defined and interface_config.prefix_list.in is not none %}
+{% if interface_config.prefix_list.in is vyos_defined %}
distribute-list prefix {{ interface_config.prefix_list.in }} in {{ interface }}
-{% endif %}
-{% if interface_config.prefix_list.out is defined and interface_config.prefix_list.out is not none %}
+{% endif %}
+{% if interface_config.prefix_list.out is vyos_defined %}
distribute-list prefix {{ interface_config.prefix_list.out }} out {{ interface }}
-{% endif %}
{% endif %}
{% endfor %}
{% endif %}
-{% if distribute_list.prefix_list is defined and distribute_list.prefix_list is not none %}
-{% if distribute_list.prefix_list.in is defined and distribute_list.prefix_list.in is not none %}
+{% if distribute_list.prefix_list.in is vyos_defined %}
distribute-list prefix {{ distribute_list.prefix_list.in }} in
-{% endif %}
-{% if distribute_list.prefix_list.out is defined and distribute_list.prefix_list.out is not none %}
+{% endif %}
+{% if distribute_list.prefix_list.out is vyos_defined %}
distribute-list prefix {{ distribute_list.prefix_list.out }} out
-{% endif %}
{% endif %}
{% endif %}
{% include 'frr/rip_ripng.frr.j2' %}
exit
!
-{% if route_map is defined and route_map is not none %}
+{% if route_map is vyos_defined %}
ip protocol rip route-map {{ route_map }}
{% endif %}
!
diff --git a/data/templates/frr/ripngd.frr.tmpl b/data/templates/frr/ripngd.frr.tmpl
index ca7b9b5fb..06c61dd48 100644
--- a/data/templates/frr/ripngd.frr.tmpl
+++ b/data/templates/frr/ripngd.frr.tmpl
@@ -1,11 +1,11 @@
{# Interface specific configuration #}
-{% if interface is defined and interface is not none %}
+{% if interface is vyos_defined %}
{% for iface, iface_config in interface.items() %}
interface {{ iface }}
-{% if iface_config.split_horizon is defined and iface_config.split_horizon.disable is defined %}
+{% if iface_config.split_horizon.disable is vyos_defined %}
no ipv6 rip split-horizon
{% endif %}
-{% if iface_config.split_horizon is defined and iface_config.split_horizon.poison_reverse is defined %}
+{% if iface_config.split_horizon.poison_reverse is vyos_defined %}
ipv6 rip split-horizon poisoned-reverse
{% endif %}
exit
@@ -13,53 +13,45 @@ exit
{% endif %}
!
router ripng
-{% if aggregate_address is defined and aggregate_address is not none %}
+{% if aggregate_address is vyos_defined %}
{% for prefix in aggregate_address %}
aggregate-address {{ prefix }}
{% endfor %}
{% endif %}
-{% if distribute_list is defined and distribute_list is not none %}
-{% if distribute_list.access_list is defined and distribute_list.access_list is not none %}
-{% if distribute_list.access_list.in is defined and distribute_list.access_list.in is not none %}
+{% if distribute_list is vyos_defined %}
+{% if distribute_list.access_list.in is vyos_defined %}
ipv6 distribute-list {{ distribute_list.access_list.in }} in
-{% endif %}
-{% if distribute_list.access_list.out is defined and distribute_list.access_list.out is not none %}
+{% endif %}
+{% if distribute_list.access_list.out is vyos_defined %}
ipv6 distribute-list {{ distribute_list.access_list.out }} out
-{% endif %}
{% endif %}
-{% if distribute_list.interface is defined and distribute_list.interface is not none %}
+{% if distribute_list.interface is vyos_defined %}
{% for interface, interface_config in distribute_list.interface.items() %}
-{% if interface_config.access_list is defined and interface_config.access_list is not none %}
-{% if interface_config.access_list.in is defined and interface_config.access_list.in is not none %}
+{% if interface_config.access_list.in is vyos_defined %}
ipv6 distribute-list {{ interface_config.access_list.in }} in {{ interface }}
-{% endif %}
-{% if interface_config.access_list.out is defined and interface_config.access_list.out is not none %}
+{% endif %}
+{% if interface_config.access_list.out is vyos_defined %}
ipv6 distribute-list {{ interface_config.access_list.out }} out {{ interface }}
-{% endif %}
{% endif %}
-{% if interface_config.prefix_list is defined and interface_config.prefix_list is not none %}
-{% if interface_config.prefix_list.in is defined and interface_config.prefix_list.in is not none %}
+{% if interface_config.prefix_list.in is vyos_defined %}
ipv6 distribute-list prefix {{ interface_config.prefix_list.in }} in {{ interface }}
-{% endif %}
-{% if interface_config.prefix_list.out is defined and interface_config.prefix_list.out is not none %}
+{% endif %}
+{% if interface_config.prefix_list.out is vyos_defined %}
ipv6 distribute-list prefix {{ interface_config.prefix_list.out }} out {{ interface }}
-{% endif %}
{% endif %}
{% endfor %}
{% endif %}
-{% if distribute_list.prefix_list is defined and distribute_list.prefix_list is not none %}
-{% if distribute_list.prefix_list.in is defined and distribute_list.prefix_list.in is not none %}
+{% if distribute_list.prefix_list.in is vyos_defined %}
ipv6 distribute-list prefix {{ distribute_list.prefix_list.in }} in
-{% endif %}
-{% if distribute_list.prefix_list.out is defined and distribute_list.prefix_list.out is not none %}
+{% endif %}
+{% if distribute_list.prefix_list.out is vyos_defined %}
ipv6 distribute-list prefix {{ distribute_list.prefix_list.out }} out
-{% endif %}
{% endif %}
{% endif %}
{% include 'frr/rip_ripng.frr.j2' %}
exit
!
-{% if route_map is defined and route_map is not none %}
+{% if route_map is vyos_defined %}
ipv6 protocol ripng route-map {{ route_map }}
{% endif %}
!
diff --git a/data/templates/frr/rpki.frr.tmpl b/data/templates/frr/rpki.frr.tmpl
index 7f9823f6b..3f4fd3236 100644
--- a/data/templates/frr/rpki.frr.tmpl
+++ b/data/templates/frr/rpki.frr.tmpl
@@ -1,17 +1,17 @@
!
{# as FRR does not support deleting the entire rpki section we leave it in place even when it's empty #}
rpki
-{% if cache is defined and cache is not none %}
+{% if cache is vyos_defined %}
{% for peer, peer_config in cache.items() %}
{# port is mandatory and preference uses a default value #}
-{% if peer_config.ssh is defined and peer_config.ssh.username is defined and peer_config.ssh.username is not none %}
+{% if peer_config.ssh.username is vyos_defined %}
rpki cache {{ peer | replace('_', '-') }} {{ peer_config.port }} {{ peer_config.ssh.username }} {{ peer_config.ssh.private_key_file }} {{ peer_config.ssh.public_key_file }} {{ peer_config.ssh.known_hosts_file }} preference {{ peer_config.preference }}
{% else %}
rpki cache {{ peer | replace('_', '-') }} {{ peer_config.port }} preference {{ peer_config.preference }}
{% endif %}
{% endfor %}
{% endif %}
-{% if polling_period is defined and polling_period is not none %}
+{% if polling_period is vyos_defined %}
rpki polling_period {{ polling_period }}
{% endif %}
exit
diff --git a/data/templates/frr/static_routes_macro.j2 b/data/templates/frr/static_routes_macro.j2
index 8359357b7..0b242a868 100644
--- a/data/templates/frr/static_routes_macro.j2
+++ b/data/templates/frr/static_routes_macro.j2
@@ -1,24 +1,24 @@
{% macro static_routes(ip_ipv6, prefix, prefix_config, table=None) %}
-{% if prefix_config.blackhole is defined %}
-{{ ip_ipv6 }} route {{ prefix }} blackhole {{ prefix_config.blackhole.distance if prefix_config.blackhole.distance is defined }} {{ 'tag ' + prefix_config.blackhole.tag if prefix_config.blackhole.tag is defined }} {{ 'table ' + table if table is defined and table is not none }}
+{% if prefix_config.blackhole is vyos_defined %}
+{{ ip_ipv6 }} route {{ prefix }} blackhole {{ prefix_config.blackhole.distance if prefix_config.blackhole.distance is vyos_defined }} {{ 'tag ' ~ prefix_config.blackhole.tag if prefix_config.blackhole.tag is vyos_defined }} {{ 'table ' ~ table if table is vyos_defined and table is not none }}
{% endif %}
-{% if prefix_config.reject is defined %}
-{{ ip_ipv6 }} route {{ prefix }} reject {{ prefix_config.reject.distance if prefix_config.reject.distance is defined }} {{ 'tag ' + prefix_config.reject.tag if prefix_config.reject.tag is defined }} {{ 'table ' + table if table is defined and table is not none }}
+{% if prefix_config.reject is vyos_defined %}
+{{ ip_ipv6 }} route {{ prefix }} reject {{ prefix_config.reject.distance if prefix_config.reject.distance is vyos_defined }} {{ 'tag ' ~ prefix_config.reject.tag if prefix_config.reject.tag is vyos_defined }} {{ 'table ' ~ table if table is vyos_defined }}
{% endif %}
-{% if prefix_config.dhcp_interface is defined and prefix_config.dhcp_interface is not none %}
+{% if prefix_config.dhcp_interface is vyos_defined %}
{% set next_hop = prefix_config.dhcp_interface | get_dhcp_router %}
-{% if next_hop is defined and next_hop is not none %}
-{{ ip_ipv6 }} route {{ prefix }} {{ next_hop }} {{ prefix_config.dhcp_interface }} {{ 'table ' + table if table is defined and table is not none }}
+{% if next_hop is vyos_defined %}
+{{ ip_ipv6 }} route {{ prefix }} {{ next_hop }} {{ prefix_config.dhcp_interface }} {{ 'table ' ~ table if table is vyos_defined }}
{% endif %}
{% endif %}
-{% if prefix_config.interface is defined and prefix_config.interface is not none %}
+{% if prefix_config.interface is vyos_defined %}
{% for interface, interface_config in prefix_config.interface.items() if interface_config.disable is not defined %}
-{{ ip_ipv6 }} route {{ prefix }} {{ interface }} {{ interface_config.distance if interface_config.distance is defined }} {{ 'nexthop-vrf ' + interface_config.vrf if interface_config.vrf is defined }} {{ 'table ' + table if table is defined and table is not none }}
+{{ ip_ipv6 }} route {{ prefix }} {{ interface }} {{ interface_config.distance if interface_config.distance is vyos_defined }} {{ 'nexthop-vrf ' ~ interface_config.vrf if interface_config.vrf is vyos_defined }} {{ 'table ' ~ table if table is vyos_defined }}
{% endfor %}
{% endif %}
-{% if prefix_config.next_hop is defined and prefix_config.next_hop is not none %}
+{% if prefix_config.next_hop is vyos_defined and prefix_config.next_hop is not none %}
{% for next_hop, next_hop_config in prefix_config.next_hop.items() if next_hop_config.disable is not defined %}
-{{ ip_ipv6 }} route {{ prefix }} {{ next_hop }} {{ next_hop_config.interface if next_hop_config.interface is defined }} {{ next_hop_config.distance if next_hop_config.distance is defined }} {{ 'nexthop-vrf ' + next_hop_config.vrf if next_hop_config.vrf is defined }} {{ 'table ' + table if table is defined and table is not none }}
+{{ ip_ipv6 }} route {{ prefix }} {{ next_hop }} {{ next_hop_config.interface if next_hop_config.interface is vyos_defined }} {{ next_hop_config.distance if next_hop_config.distance is vyos_defined }} {{ 'nexthop-vrf ' ~ next_hop_config.vrf if next_hop_config.vrf is vyos_defined }} {{ 'table ' ~ table if table is vyos_defined}}
{% endfor %}
{% endif %}
{% endmacro %}
diff --git a/data/templates/frr/staticd.frr.tmpl b/data/templates/frr/staticd.frr.tmpl
index 5d833228a..c7138b12b 100644
--- a/data/templates/frr/staticd.frr.tmpl
+++ b/data/templates/frr/staticd.frr.tmpl
@@ -2,7 +2,7 @@
!
{% set ip_prefix = 'ip' %}
{% set ipv6_prefix = 'ipv6' %}
-{% if vrf is defined and vrf is not none %}
+{% if vrf is vyos_defined %}
{# We need to add an additional whitespace in front of the prefix #}
{# when VRFs are in use, thus we use a variable for prefix handling #}
{% set ip_prefix = ' ip' %}
@@ -10,40 +10,40 @@
vrf {{ vrf }}
{% endif %}
{# IPv4 routing #}
-{% if route is defined and route is not none %}
+{% if route is vyos_defined %}
{% for prefix, prefix_config in route.items() %}
{{ static_routes(ip_prefix, prefix, prefix_config) }}
{%- endfor -%}
{% endif %}
{# IPv4 default routes from DHCP interfaces #}
-{% if dhcp is defined and dhcp is not none %}
+{% if dhcp is vyos_defined %}
{% for interface, interface_config in dhcp.items() %}
{% set next_hop = interface | get_dhcp_router %}
-{% if next_hop is defined and next_hop is not none %}
+{% if next_hop is vyos_defined %}
{{ ip_prefix }} route 0.0.0.0/0 {{ next_hop }} {{ interface }} tag 210 {{ interface_config.distance }}
{% endif %}
{% endfor %}
{% endif %}
{# IPv6 routing #}
-{% if route6 is defined and route6 is not none %}
+{% if route6 is vyos_defined %}
{% for prefix, prefix_config in route6.items() %}
{{ static_routes(ipv6_prefix, prefix, prefix_config) }}
{%- endfor -%}
{% endif %}
-{% if vrf is defined and vrf is not none %}
+{% if vrf is vyos_defined %}
exit-vrf
{% endif %}
!
{# Policy route tables #}
-{% if table is defined and table is not none %}
+{% if table is vyos_defined %}
{% for table_id, table_config in table.items() %}
-{% if table_config.route is defined and table_config.route is not none %}
+{% if table_config.route is vyos_defined %}
{% for prefix, prefix_config in table_config.route.items() %}
{{ static_routes('ip', prefix, prefix_config, table_id) }}
{%- endfor -%}
{% endif %}
!
-{% if table_config.route6 is defined and table_config.route6 is not none %}
+{% if table_config.route6 is vyos_defined %}
{% for prefix, prefix_config in table_config.route6.items() %}
{{ static_routes('ipv6', prefix, prefix_config, table_id) }}
{%- endfor -%}
@@ -52,7 +52,7 @@ vrf {{ vrf }}
{% endfor %}
{% endif %}
!
-{% if route_map is defined and route_map is not none %}
+{% if route_map is vyos_defined %}
ip protocol static route-map {{ route_map }}
!
{% endif %}
diff --git a/data/templates/frr/vrf-vni.frr.tmpl b/data/templates/frr/vrf-vni.frr.tmpl
index 299c9719e..916b5d05d 100644
--- a/data/templates/frr/vrf-vni.frr.tmpl
+++ b/data/templates/frr/vrf-vni.frr.tmpl
@@ -1,7 +1,7 @@
-{% if name is defined and name is not none %}
+{% if name is vyos_defined %}
{% for vrf, vrf_config in name.items() %}
vrf {{ vrf }}
-{% if vrf_config.vni is defined and vrf_config.vni is not none %}
+{% if vrf_config.vni is vyos_defined %}
vni {{ vrf_config.vni }}
{% endif %}
exit-vrf
diff --git a/data/templates/frr/vrf.route-map.frr.tmpl b/data/templates/frr/vrf.route-map.frr.tmpl
index cb0e07616..5e0c56a7b 100644
--- a/data/templates/frr/vrf.route-map.frr.tmpl
+++ b/data/templates/frr/vrf.route-map.frr.tmpl
@@ -1,10 +1,10 @@
!
-{% if vrf is defined and vrf is not none and route_map is defined and route_map is not none %}
+{% if vrf is vyos_defined and route_map is vyos_defined %}
vrf {{ vrf }}
ip protocol {{ protocol }} route-map {{ route_map }}
exit-vrf
!
-{% elif route_map is defined and route_map is not none %}
+{% elif route_map is vyos_defined %}
ip protocol {{ protocol }} route-map {{ route_map }}
{% endif %}
!
diff --git a/data/templates/https/nginx.default.tmpl b/data/templates/https/nginx.default.tmpl
index e8511bd62..a51505270 100644
--- a/data/templates/https/nginx.default.tmpl
+++ b/data/templates/https/nginx.default.tmpl
@@ -53,19 +53,6 @@ server {
}
error_page 497 =301 https://$host:{{ server.port }}$request_uri;
- error_page 501 502 503 =200 @50*_json;
-
-{% if api_set %}
- location @50*_json {
- default_type application/json;
- return 200 '{"error": "service https api unavailable at this proxy address: set service https api-restrict virtual-host"}';
- }
-{% else %}
- location @50*_json {
- default_type application/json;
- return 200 '{"error": "Start service in configuration mode: set service https api"}';
- }
-{% endif %}
}
diff --git a/debian/vyos-1x.install b/debian/vyos-1x.install
index 63dff43a5..493c896eb 100644
--- a/debian/vyos-1x.install
+++ b/debian/vyos-1x.install
@@ -1,4 +1,3 @@
-etc/cron.d
etc/cron.hourly
etc/dhcp
etc/ipsec.d
diff --git a/interface-definitions/dhcp-server.xml.in b/interface-definitions/dhcp-server.xml.in
index 312dcd2a0..4ea2d471d 100644
--- a/interface-definitions/dhcp-server.xml.in
+++ b/interface-definitions/dhcp-server.xml.in
@@ -142,6 +142,11 @@
boot file is to be loaded</help>
</properties>
</leafNode>
+ <leafNode name="bootfile-size">
+ <properties>
+ <help>Bootstrap file size in 512 byte blocks</help>
+ </properties>
+ </leafNode>
<leafNode name="client-prefix-length">
<properties>
<help>Specifies the clients subnet mask as per RFC 950. If unset, subnet declaration is used.</help>
diff --git a/interface-definitions/dns-forwarding.xml.in b/interface-definitions/dns-forwarding.xml.in
index a2e809da8..08501a4b5 100644
--- a/interface-definitions/dns-forwarding.xml.in
+++ b/interface-definitions/dns-forwarding.xml.in
@@ -598,6 +598,19 @@
</properties>
<defaultValue>3600</defaultValue>
</leafNode>
+ <leafNode name="timeout">
+ <properties>
+ <help>Number of milliseconds to wait for a remote authoritative server to respond</help>
+ <valueHelp>
+ <format>u32:10-60000</format>
+ <description>Network timeout in milliseconds</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 10-60000"/>
+ </constraint>
+ </properties>
+ <defaultValue>1500</defaultValue>
+ </leafNode>
#include <include/name-server-ipv4-ipv6.xml.i>
<leafNode name="source-address">
<properties>
diff --git a/interface-definitions/include/accel-ppp/client-ip-pool-subnet-single.xml.i b/interface-definitions/include/accel-ppp/client-ip-pool-subnet-single.xml.i
new file mode 100644
index 000000000..e5918b765
--- /dev/null
+++ b/interface-definitions/include/accel-ppp/client-ip-pool-subnet-single.xml.i
@@ -0,0 +1,15 @@
+<!-- include start from accel-ppp/client-ip-pool-subnet-single.xml.i -->
+<leafNode name="subnet">
+ <properties>
+ <help>Client IP subnet (CIDR notation)</help>
+ <valueHelp>
+ <format>ipv4net</format>
+ <description>IPv4 address and prefix length</description>
+ </valueHelp>
+ <constraint>
+ <validator name="ipv4-prefix"/>
+ </constraint>
+ <constraintErrorMessage>Not a valid CIDR formatted prefix</constraintErrorMessage>
+ </properties>
+</leafNode>
+<!-- include end -->
diff --git a/interface-definitions/include/firewall/common-rule.xml.i b/interface-definitions/include/firewall/common-rule.xml.i
index 353804990..cd80b7e28 100644
--- a/interface-definitions/include/firewall/common-rule.xml.i
+++ b/interface-definitions/include/firewall/common-rule.xml.i
@@ -66,11 +66,11 @@
<properties>
<help>Maximum average matching rate</help>
<valueHelp>
- <format>u32:0-4294967295</format>
- <description>Maximum average matching rate</description>
+ <format>txt</format>
+ <description>integer/unit (Example: 5/minute)</description>
</valueHelp>
<constraint>
- <validator name="numeric" argument="--range 0-4294967295"/>
+ <regex>^\d+/(second|minute|hour|day)$</regex>
</constraint>
</properties>
</leafNode>
diff --git a/interface-definitions/include/interface/traffic-policy.xml.i b/interface-definitions/include/interface/traffic-policy.xml.i
deleted file mode 100644
index cd60b62a5..000000000
--- a/interface-definitions/include/interface/traffic-policy.xml.i
+++ /dev/null
@@ -1,43 +0,0 @@
-<!-- include start from interface/traffic-policy.xml.i -->
-<node name="traffic-policy">
- <properties>
- <help>Traffic-policy for interface</help>
- </properties>
- <children>
- <leafNode name="in">
- <properties>
- <help>Ingress traffic policy for interface</help>
- <completionHelp>
- <path>traffic-policy drop-tail</path>
- <path>traffic-policy fair-queue</path>
- <path>traffic-policy fq-codel</path>
- <path>traffic-policy limiter</path>
- <path>traffic-policy network-emulator</path>
- <path>traffic-policy priority-queue</path>
- <path>traffic-policy random-detect</path>
- <path>traffic-policy rate-control</path>
- <path>traffic-policy round-robin</path>
- <path>traffic-policy shaper</path>
- <path>traffic-policy shaper-hfsc</path>
- </completionHelp>
- <valueHelp>
- <format>txt</format>
- <description>Policy name</description>
- </valueHelp>
- </properties>
- </leafNode>
- <leafNode name="out">
- <properties>
- <help>Egress traffic policy for interface</help>
- <completionHelp>
- <path>traffic-policy</path>
- </completionHelp>
- <valueHelp>
- <format>txt</format>
- <description>Policy name</description>
- </valueHelp>
- </properties>
- </leafNode>
- </children>
-</node>
-<!-- include end --> \ No newline at end of file
diff --git a/interface-definitions/include/interface/vif-s.xml.i b/interface-definitions/include/interface/vif-s.xml.i
index 59a47b5ff..3b305618e 100644
--- a/interface-definitions/include/interface/vif-s.xml.i
+++ b/interface-definitions/include/interface/vif-s.xml.i
@@ -44,6 +44,7 @@
#include <include/interface/ipv4-options.xml.i>
#include <include/interface/ipv6-options.xml.i>
#include <include/interface/mac.xml.i>
+ #include <include/interface/mirror.xml.i>
#include <include/interface/mtu-68-16000.xml.i>
<tagNode name="vif-c">
<properties>
@@ -63,16 +64,15 @@
#include <include/interface/ipv4-options.xml.i>
#include <include/interface/ipv6-options.xml.i>
#include <include/interface/mac.xml.i>
+ #include <include/interface/mirror.xml.i>
#include <include/interface/mtu-68-16000.xml.i>
#include <include/interface/redirect.xml.i>
- #include <include/interface/traffic-policy.xml.i>
#include <include/interface/vrf.xml.i>
#include <include/interface/interface-firewall-vif-c.xml.i>
#include <include/interface/interface-policy-vif-c.xml.i>
</children>
</tagNode>
#include <include/interface/redirect.xml.i>
- #include <include/interface/traffic-policy.xml.i>
#include <include/interface/vrf.xml.i>
</children>
</tagNode>
diff --git a/interface-definitions/include/interface/vif.xml.i b/interface-definitions/include/interface/vif.xml.i
index 8a1475711..4e7f9b3c2 100644
--- a/interface-definitions/include/interface/vif.xml.i
+++ b/interface-definitions/include/interface/vif.xml.i
@@ -49,9 +49,9 @@
#include <include/interface/ipv4-options.xml.i>
#include <include/interface/ipv6-options.xml.i>
#include <include/interface/mac.xml.i>
+ #include <include/interface/mirror.xml.i>
#include <include/interface/mtu-68-16000.xml.i>
#include <include/interface/redirect.xml.i>
- #include <include/interface/traffic-policy.xml.i>
#include <include/interface/vrf.xml.i>
</children>
</tagNode>
diff --git a/interface-definitions/include/isis/high-low-label-value.xml.i b/interface-definitions/include/isis/high-low-label-value.xml.i
new file mode 100644
index 000000000..adc28417d
--- /dev/null
+++ b/interface-definitions/include/isis/high-low-label-value.xml.i
@@ -0,0 +1,26 @@
+<!-- include start from isis/high-low-label-value.xml.i -->
+<leafNode name="low-label-value">
+ <properties>
+ <help>MPLS label lower bound</help>
+ <valueHelp>
+ <format>u32:16-1048575</format>
+ <description>Label value</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 16-1048575"/>
+ </constraint>
+ </properties>
+</leafNode>
+<leafNode name="high-label-value">
+ <properties>
+ <help>MPLS label upper bound</help>
+ <valueHelp>
+ <format>u32:16-1048575</format>
+ <description>Label value</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 16-1048575"/>
+ </constraint>
+ </properties>
+</leafNode>
+<!-- include end -->
diff --git a/interface-definitions/include/isis/password.xml.i b/interface-definitions/include/isis/password.xml.i
new file mode 100644
index 000000000..27c3b0fa0
--- /dev/null
+++ b/interface-definitions/include/isis/password.xml.i
@@ -0,0 +1,20 @@
+<!-- include start from isis/password.xml.i -->
+<leafNode name="plaintext-password">
+ <properties>
+ <help>Plain-text authentication type</help>
+ <valueHelp>
+ <format>txt</format>
+ <description>Circuit password</description>
+ </valueHelp>
+ </properties>
+</leafNode>
+<leafNode name="md5">
+ <properties>
+ <help>MD5 authentication type</help>
+ <valueHelp>
+ <format>txt</format>
+ <description>Level-wide password</description>
+ </valueHelp>
+ </properties>
+</leafNode>
+<!-- include end -->
diff --git a/interface-definitions/include/isis/protocol-common-config.xml.i b/interface-definitions/include/isis/protocol-common-config.xml.i
index 8ffa14a19..75a0355d4 100644
--- a/interface-definitions/include/isis/protocol-common-config.xml.i
+++ b/interface-definitions/include/isis/protocol-common-config.xml.i
@@ -4,24 +4,7 @@
<help>Configure the authentication password for an area</help>
</properties>
<children>
- <leafNode name="plaintext-password">
- <properties>
- <help>Plain-text authentication type</help>
- <valueHelp>
- <format>txt</format>
- <description>Level-wide password</description>
- </valueHelp>
- </properties>
- </leafNode>
- <leafNode name="md5">
- <properties>
- <help>MD5 authentication type</help>
- <valueHelp>
- <format>txt</format>
- <description>Level-wide password</description>
- </valueHelp>
- </properties>
- </leafNode>
+ #include <include/isis/password.xml.i>
</children>
</node>
<node name="default-information">
@@ -59,24 +42,7 @@
<help>Set the authentication password for a routing domain</help>
</properties>
<children>
- <leafNode name="plaintext-password">
- <properties>
- <help>Plain-text authentication type</help>
- <valueHelp>
- <format>txt</format>
- <description>Level-wide password</description>
- </valueHelp>
- </properties>
- </leafNode>
- <leafNode name="md5">
- <properties>
- <help>MD5 authentication type</help>
- <valueHelp>
- <format>txt</format>
- <description>Level-wide password</description>
- </valueHelp>
- </properties>
- </leafNode>
+ #include <include/isis/password.xml.i>
</children>
</node>
<leafNode name="dynamic-hostname">
@@ -104,7 +70,7 @@
<description>Act as an area router</description>
</valueHelp>
<constraint>
- <regex>^(level-1|level-1-2|level-2)$</regex>
+ <regex>(level-1|level-1-2|level-2)</regex>
</constraint>
</properties>
</leafNode>
@@ -182,7 +148,7 @@
<description>Use new style of TLVs to carry wider metric</description>
</valueHelp>
<constraint>
- <regex>^(narrow|transition|wide)$</regex>
+ <regex>(narrow|transition|wide)</regex>
</constraint>
</properties>
</leafNode>
@@ -275,68 +241,20 @@
</leafNode>
<node name="global-block">
<properties>
- <help>Global block label range</help>
+ <help>Segment Routing Global Block label range</help>
</properties>
<children>
- <leafNode name="low-label-value">
- <properties>
- <help>The lower bound of the global block</help>
- <valueHelp>
- <format>u32:16-1048575</format>
- <description>MPLS label value</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 16-1048575"/>
- </constraint>
- </properties>
- </leafNode>
- <leafNode name="high-label-value">
- <properties>
- <help>The upper bound of the global block</help>
- <valueHelp>
- <format>u32:16-1048575</format>
- <description>MPLS label value</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 16-1048575"/>
- </constraint>
- </properties>
- </leafNode>
+ #include <include/isis/high-low-label-value.xml.i>
</children>
</node>
-<!--
<node name="local-block">
<properties>
- <help>Local Block label range</help>
+ <help>Segment Routing Local Block label range</help>
</properties>
<children>
- <leafNode name="low-label-value">
- <properties>
- <help>The lower bound of the local block</help>
- <valueHelp>
- <format>u32:16-1048575</format>
- <description>MPLS label value</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument=" range 16-1048575"/>
- </constraint>
- </properties>
- </leafNode>
- <leafNode name="high-label-value">
- <properties>
- <help>The upper bound of the local block</help>
- <valueHelp>
- <format>u32:16-1048575</format>
- <description>MPLS label value</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument=" range 16-1048575"/>
- </constraint>
- </properties>
- </leafNode>
+ #include <include/isis/high-low-label-value.xml.i>
</children>
</node>
--->
<leafNode name="maximum-label-depth">
<properties>
<help>Maximum MPLS labels allowed for this router</help>
@@ -668,7 +586,7 @@
<description>Level-2 only adjacencies are formed</description>
</valueHelp>
<constraint>
- <regex>^(level-1|level-1-2|level-2-only)$</regex>
+ <regex>(level-1|level-1-2|level-2-only)</regex>
</constraint>
</properties>
</leafNode>
@@ -722,15 +640,7 @@
<help>Configure the authentication password for a circuit</help>
</properties>
<children>
- <leafNode name="plaintext-password">
- <properties>
- <help>Plain-text authentication type</help>
- <valueHelp>
- <format>txt</format>
- <description>Circuit password</description>
- </valueHelp>
- </properties>
- </leafNode>
+ #include <include/isis/password.xml.i>
</children>
</node>
<leafNode name="priority">
diff --git a/interface-definitions/include/version/system-version.xml.i b/interface-definitions/include/version/system-version.xml.i
index fb4629bf1..19591256d 100644
--- a/interface-definitions/include/version/system-version.xml.i
+++ b/interface-definitions/include/version/system-version.xml.i
@@ -1,3 +1,3 @@
<!-- include start from include/version/system-version.xml.i -->
-<syntaxVersion component='system' version='22'></syntaxVersion>
+<syntaxVersion component='system' version='23'></syntaxVersion>
<!-- include end -->
diff --git a/interface-definitions/interfaces-bonding.xml.in b/interface-definitions/interfaces-bonding.xml.in
index 20ece5137..5ae67a672 100644
--- a/interface-definitions/interfaces-bonding.xml.in
+++ b/interface-definitions/interfaces-bonding.xml.in
@@ -208,7 +208,6 @@
</properties>
</leafNode>
#include <include/interface/redirect.xml.i>
- #include <include/interface/traffic-policy.xml.i>
#include <include/interface/vif-s.xml.i>
#include <include/interface/vif.xml.i>
#include <include/interface/xdp.xml.i>
diff --git a/interface-definitions/interfaces-bridge.xml.in b/interface-definitions/interfaces-bridge.xml.in
index 6957067cd..be4c92583 100644
--- a/interface-definitions/interfaces-bridge.xml.in
+++ b/interface-definitions/interfaces-bridge.xml.in
@@ -211,7 +211,6 @@
</properties>
</leafNode>
#include <include/interface/redirect.xml.i>
- #include <include/interface/traffic-policy.xml.i>
#include <include/interface/vif.xml.i>
</children>
</tagNode>
diff --git a/interface-definitions/interfaces-dummy.xml.in b/interface-definitions/interfaces-dummy.xml.in
index 109ed1b50..7f9ae90e5 100644
--- a/interface-definitions/interfaces-dummy.xml.in
+++ b/interface-definitions/interfaces-dummy.xml.in
@@ -29,9 +29,9 @@
#include <include/interface/source-validation.xml.i>
</children>
</node>
+ #include <include/interface/mirror.xml.i>
#include <include/interface/netns.xml.i>
#include <include/interface/redirect.xml.i>
- #include <include/interface/traffic-policy.xml.i>
#include <include/interface/vrf.xml.i>
</children>
</tagNode>
diff --git a/interface-definitions/interfaces-ethernet.xml.in b/interface-definitions/interfaces-ethernet.xml.in
index 7d28912c0..7fa07e9ec 100644
--- a/interface-definitions/interfaces-ethernet.xml.in
+++ b/interface-definitions/interfaces-ethernet.xml.in
@@ -197,7 +197,6 @@
</children>
</node>
#include <include/interface/redirect.xml.i>
- #include <include/interface/traffic-policy.xml.i>
#include <include/interface/vif-s.xml.i>
#include <include/interface/vif.xml.i>
#include <include/interface/vrf.xml.i>
diff --git a/interface-definitions/interfaces-geneve.xml.in b/interface-definitions/interfaces-geneve.xml.in
index aa5809e60..fa5a78be5 100644
--- a/interface-definitions/interfaces-geneve.xml.in
+++ b/interface-definitions/interfaces-geneve.xml.in
@@ -50,8 +50,8 @@
</node>
</children>
</node>
+ #include <include/interface/mirror.xml.i>
#include <include/interface/redirect.xml.i>
- #include <include/interface/traffic-policy.xml.i>
#include <include/interface/tunnel-remote.xml.i>
#include <include/vni.xml.i>
</children>
diff --git a/interface-definitions/interfaces-input.xml.in b/interface-definitions/interfaces-input.xml.in
index f2eb01c58..2164bfa4e 100644
--- a/interface-definitions/interfaces-input.xml.in
+++ b/interface-definitions/interfaces-input.xml.in
@@ -22,7 +22,6 @@
#include <include/interface/interface-firewall.xml.i>
#include <include/interface/interface-policy.xml.i>
#include <include/interface/redirect.xml.i>
- #include <include/interface/traffic-policy.xml.i>
</children>
</tagNode>
</children>
diff --git a/interface-definitions/interfaces-l2tpv3.xml.in b/interface-definitions/interfaces-l2tpv3.xml.in
index 680170b0f..1f23a89a5 100644
--- a/interface-definitions/interfaces-l2tpv3.xml.in
+++ b/interface-definitions/interfaces-l2tpv3.xml.in
@@ -58,6 +58,7 @@
#include <include/interface/ipv4-options.xml.i>
#include <include/interface/ipv6-options.xml.i>
#include <include/source-address-ipv4-ipv6.xml.i>
+ #include <include/interface/mirror.xml.i>
#include <include/interface/mtu-68-16000.xml.i>
<leafNode name="mtu">
<defaultValue>1488</defaultValue>
@@ -124,7 +125,6 @@
</constraint>
</properties>
</leafNode>
- #include <include/interface/traffic-policy.xml.i>
#include <include/interface/vrf.xml.i>
</children>
</tagNode>
diff --git a/interface-definitions/interfaces-loopback.xml.in b/interface-definitions/interfaces-loopback.xml.in
index ffffc0220..7ac0545c6 100644
--- a/interface-definitions/interfaces-loopback.xml.in
+++ b/interface-definitions/interfaces-loopback.xml.in
@@ -26,8 +26,8 @@
#include <include/interface/source-validation.xml.i>
</children>
</node>
+ #include <include/interface/mirror.xml.i>
#include <include/interface/redirect.xml.i>
- #include <include/interface/traffic-policy.xml.i>
</children>
</tagNode>
</children>
diff --git a/interface-definitions/interfaces-macsec.xml.in b/interface-definitions/interfaces-macsec.xml.in
index 311e95c2f..cb3c489aa 100644
--- a/interface-definitions/interfaces-macsec.xml.in
+++ b/interface-definitions/interfaces-macsec.xml.in
@@ -23,6 +23,7 @@
#include <include/interface/ipv6-options.xml.i>
#include <include/interface/interface-firewall.xml.i>
#include <include/interface/interface-policy.xml.i>
+ #include <include/interface/mirror.xml.i>
<node name="security">
<properties>
<help>Security/Encryption Settings</help>
@@ -123,7 +124,6 @@
</leafNode>
#include <include/source-interface-ethernet.xml.i>
#include <include/interface/redirect.xml.i>
- #include <include/interface/traffic-policy.xml.i>
#include <include/interface/vrf.xml.i>
</children>
</tagNode>
diff --git a/interface-definitions/interfaces-openvpn.xml.in b/interface-definitions/interfaces-openvpn.xml.in
index 73e30e590..c917b9312 100644
--- a/interface-definitions/interfaces-openvpn.xml.in
+++ b/interface-definitions/interfaces-openvpn.xml.in
@@ -168,6 +168,7 @@
</children>
</node>
#include <include/interface/ipv6-options.xml.i>
+ #include <include/interface/mirror.xml.i>
<leafNode name="hash">
<properties>
<help>Hashing Algorithm</help>
@@ -817,7 +818,6 @@
</properties>
</leafNode>
#include <include/interface/redirect.xml.i>
- #include <include/interface/traffic-policy.xml.i>
#include <include/interface/vrf.xml.i>
</children>
</tagNode>
diff --git a/interface-definitions/interfaces-pppoe.xml.in b/interface-definitions/interfaces-pppoe.xml.in
index 1d888236e..3a0b7a40c 100644
--- a/interface-definitions/interfaces-pppoe.xml.in
+++ b/interface-definitions/interfaces-pppoe.xml.in
@@ -102,6 +102,7 @@
</constraint>
</properties>
</leafNode>
+ #include <include/interface/mirror.xml.i>
#include <include/interface/mtu-68-1500.xml.i>
<leafNode name="mtu">
<defaultValue>1492</defaultValue>
@@ -134,7 +135,6 @@
</properties>
</leafNode>
#include <include/interface/redirect.xml.i>
- #include <include/interface/traffic-policy.xml.i>
#include <include/interface/vrf.xml.i>
</children>
</tagNode>
diff --git a/interface-definitions/interfaces-pseudo-ethernet.xml.in b/interface-definitions/interfaces-pseudo-ethernet.xml.in
index 7baeac537..5f5e9fdef 100644
--- a/interface-definitions/interfaces-pseudo-ethernet.xml.in
+++ b/interface-definitions/interfaces-pseudo-ethernet.xml.in
@@ -27,6 +27,7 @@
#include <include/interface/ipv6-options.xml.i>
#include <include/source-interface-ethernet.xml.i>
#include <include/interface/mac.xml.i>
+ #include <include/interface/mirror.xml.i>
#include <include/interface/interface-firewall.xml.i>
#include <include/interface/interface-policy.xml.i>
<leafNode name="mode">
@@ -60,7 +61,6 @@
</leafNode>
#include <include/interface/mtu-68-16000.xml.i>
#include <include/interface/redirect.xml.i>
- #include <include/interface/traffic-policy.xml.i>
#include <include/interface/vif-s.xml.i>
#include <include/interface/vif.xml.i>
</children>
diff --git a/interface-definitions/interfaces-tunnel.xml.in b/interface-definitions/interfaces-tunnel.xml.in
index bc9297c86..42ec62775 100644
--- a/interface-definitions/interfaces-tunnel.xml.in
+++ b/interface-definitions/interfaces-tunnel.xml.in
@@ -107,6 +107,7 @@
<constraintErrorMessage>Invalid encapsulation, must be one of: erspan, gre, gretap, ip6erspan, ip6gre, ip6gretap, ipip, sit, ipip6 or ip6ip6</constraintErrorMessage>
</properties>
</leafNode>
+ #include <include/interface/mirror.xml.i>
<leafNode name="multicast">
<properties>
<help>Multicast operation over tunnel</help>
@@ -289,7 +290,6 @@
</node>
#include <include/interface/vrf.xml.i>
#include <include/interface/redirect.xml.i>
- #include <include/interface/traffic-policy.xml.i>
</children>
</tagNode>
</children>
diff --git a/interface-definitions/interfaces-vti.xml.in b/interface-definitions/interfaces-vti.xml.in
index 538194c2b..5893e4c4c 100644
--- a/interface-definitions/interfaces-vti.xml.in
+++ b/interface-definitions/interfaces-vti.xml.in
@@ -34,8 +34,8 @@
#include <include/interface/ipv4-options.xml.i>
#include <include/interface/ipv6-options.xml.i>
#include <include/interface/mtu-68-16000.xml.i>
+ #include <include/interface/mirror.xml.i>
#include <include/interface/redirect.xml.i>
- #include <include/interface/traffic-policy.xml.i>
#include <include/interface/vrf.xml.i>
#include <include/interface/interface-firewall.xml.i>
#include <include/interface/interface-policy.xml.i>
diff --git a/interface-definitions/interfaces-vxlan.xml.in b/interface-definitions/interfaces-vxlan.xml.in
index 18abf9f20..9747b1816 100644
--- a/interface-definitions/interfaces-vxlan.xml.in
+++ b/interface-definitions/interfaces-vxlan.xml.in
@@ -53,6 +53,7 @@
#include <include/interface/ipv6-options.xml.i>
#include <include/interface/mac.xml.i>
#include <include/interface/mtu-1200-16000.xml.i>
+ #include <include/interface/mirror.xml.i>
#include <include/interface/interface-firewall.xml.i>
#include <include/interface/interface-policy.xml.i>
<leafNode name="mtu">
@@ -100,7 +101,6 @@
#include <include/source-interface.xml.i>
#include <include/interface/tunnel-remote-multi.xml.i>
#include <include/interface/redirect.xml.i>
- #include <include/interface/traffic-policy.xml.i>
#include <include/interface/vrf.xml.i>
#include <include/vni.xml.i>
</children>
diff --git a/interface-definitions/interfaces-wireguard.xml.in b/interface-definitions/interfaces-wireguard.xml.in
index 2f130c6f2..eb0892f07 100644
--- a/interface-definitions/interfaces-wireguard.xml.in
+++ b/interface-definitions/interfaces-wireguard.xml.in
@@ -23,6 +23,7 @@
#include <include/interface/mtu-68-16000.xml.i>
#include <include/interface/interface-firewall.xml.i>
#include <include/interface/interface-policy.xml.i>
+ #include <include/interface/mirror.xml.i>
<leafNode name="mtu">
<defaultValue>1420</defaultValue>
</leafNode>
@@ -120,7 +121,6 @@
</children>
</tagNode>
#include <include/interface/redirect.xml.i>
- #include <include/interface/traffic-policy.xml.i>
#include <include/interface/vrf.xml.i>
</children>
</tagNode>
diff --git a/interface-definitions/interfaces-wireless.xml.in b/interface-definitions/interfaces-wireless.xml.in
index eebe8f841..db01657eb 100644
--- a/interface-definitions/interfaces-wireless.xml.in
+++ b/interface-definitions/interfaces-wireless.xml.in
@@ -6,6 +6,9 @@
<properties>
<help>Wireless (WiFi/WLAN) Network Interface</help>
<priority>318</priority>
+ <completionHelp>
+ <script>cd /sys/class/net; if compgen -G "wlan*" > /dev/null; then ls -d wlan*; fi</script>
+ </completionHelp>
<constraint>
<regex>^wlan[0-9]+$</regex>
</constraint>
@@ -563,6 +566,7 @@
</properties>
<defaultValue>g</defaultValue>
</leafNode>
+ #include <include/interface/mirror.xml.i>
<leafNode name="physical-device">
<properties>
<help>Wireless physical device</help>
@@ -779,7 +783,6 @@
<defaultValue>monitor</defaultValue>
</leafNode>
#include <include/interface/redirect.xml.i>
- #include <include/interface/traffic-policy.xml.i>
#include <include/interface/vif.xml.i>
#include <include/interface/vif-s.xml.i>
</children>
diff --git a/interface-definitions/interfaces-wwan.xml.in b/interface-definitions/interfaces-wwan.xml.in
index 7007a67ae..3cb1645c4 100644
--- a/interface-definitions/interfaces-wwan.xml.in
+++ b/interface-definitions/interfaces-wwan.xml.in
@@ -7,7 +7,7 @@
<help>Wireless Modem (WWAN) Interface</help>
<priority>350</priority>
<completionHelp>
- <script>cd /sys/class/net; ls -d wwan*</script>
+ <script>cd /sys/class/net; if compgen -G "wwan*" > /dev/null; then ls -d wwan*; fi</script>
</completionHelp>
<constraint>
<regex>^wwan[0-9]+$</regex>
@@ -31,6 +31,7 @@
#include <include/interface/description.xml.i>
#include <include/interface/disable.xml.i>
#include <include/interface/disable-link-detect.xml.i>
+ #include <include/interface/mirror.xml.i>
#include <include/interface/mtu-68-1500.xml.i>
<leafNode name="mtu">
<defaultValue>1430</defaultValue>
@@ -41,7 +42,6 @@
#include <include/interface/interface-firewall.xml.i>
#include <include/interface/interface-policy.xml.i>
#include <include/interface/redirect.xml.i>
- #include <include/interface/traffic-policy.xml.i>
#include <include/interface/vrf.xml.i>
</children>
</tagNode>
diff --git a/interface-definitions/policy.xml.in b/interface-definitions/policy.xml.in
index 5e037b558..1a4781397 100644
--- a/interface-definitions/policy.xml.in
+++ b/interface-definitions/policy.xml.in
@@ -1086,7 +1086,7 @@
<description>Based on a router-id IP address</description>
</valueHelp>
<constraint>
- <regex>^((?:[0-9]{1,3}\.){3}[0-9]{1,3}|\d+):\d+$</regex>
+ <regex>^(((\b(?:(?:2(?:[0-4][0-9]|5[0-5])|[0-1]?[0-9]?[0-9])\.){3}(?:(?:2([0-4][0-9]|5[0-5])|[0-1]?[0-9]?[0-9]))\b)|(\d+)):(\d+) ?)+$</regex>
</constraint>
<constraintErrorMessage>Should be in form: ASN:NN or IPADDR:NN where ASN is autonomous system number</constraintErrorMessage>
</properties>
diff --git a/interface-definitions/qos.xml.in b/interface-definitions/qos.xml.in
index d4468543c..e8f575a1e 100644
--- a/interface-definitions/qos.xml.in
+++ b/interface-definitions/qos.xml.in
@@ -1,721 +1,789 @@
<?xml version="1.0"?>
<interfaceDefinition>
- <node name="traffic-policy" owner="${vyos_conf_scripts_dir}/qos.py">
+ <node name="qos" owner="${vyos_conf_scripts_dir}/qos.py">
<properties>
- <help>Quality of Service (QOS) policy type</help>
- <priority>900</priority>
+ <help>Quality of Service (QoS)</help>
</properties>
<children>
- <tagNode name="drop-tail">
+ <tagNode name="interface">
<properties>
- <help>Packet limited First In, First Out queue</help>
+ <help>Interface to apply QoS policy</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_interfaces.py</script>
+ </completionHelp>
<valueHelp>
<format>txt</format>
- <description>Policy name</description>
+ <description>Interface name</description>
</valueHelp>
<constraint>
- <regex>[[:alnum:]][-_[:alnum:]]*</regex>
+ <validator name="interface-name"/>
</constraint>
- <constraintErrorMessage>Only alpha-numeric policy name allowed</constraintErrorMessage>
</properties>
<children>
- #include <include/generic-description.xml.i>
- #include <include/qos/queue-limit-1-4294967295.xml.i>
- </children>
- </tagNode>
- <tagNode name="fair-queue">
- <properties>
- <help>Stochastic Fairness Queueing</help>
- <valueHelp>
- <format>txt</format>
- <description>Policy name</description>
- </valueHelp>
- <constraint>
- <regex>[[:alnum:]][-_[:alnum:]]*</regex>
- </constraint>
- <constraintErrorMessage>Only alpha-numeric policy name allowed</constraintErrorMessage>
- </properties>
- <children>
- #include <include/generic-description.xml.i>
- <leafNode name="hash-interval">
+ <leafNode name="ingress">
<properties>
- <help>Interval in seconds for queue algorithm perturbation</help>
- <valueHelp>
- <format>u32:0</format>
- <description>No perturbation</description>
- </valueHelp>
+ <help>Interface ingress traffic policy</help>
+ <completionHelp>
+ <path>traffic-policy drop-tail</path>
+ <path>traffic-policy fair-queue</path>
+ <path>traffic-policy fq-codel</path>
+ <path>traffic-policy limiter</path>
+ <path>traffic-policy network-emulator</path>
+ <path>traffic-policy priority-queue</path>
+ <path>traffic-policy random-detect</path>
+ <path>traffic-policy rate-control</path>
+ <path>traffic-policy round-robin</path>
+ <path>traffic-policy shaper</path>
+ <path>traffic-policy shaper-hfsc</path>
+ </completionHelp>
<valueHelp>
- <format>u32:1-127</format>
- <description>Interval in seconds for queue algorithm perturbation (advised: 10)</description>
+ <format>txt</format>
+ <description>QoS Policy name</description>
</valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 0-127"/>
- </constraint>
- <constraintErrorMessage>Interval must be in range 0 to 127</constraintErrorMessage>
</properties>
- <defaultValue>0</defaultValue>
</leafNode>
- <leafNode name="queue-limit">
+ <leafNode name="egress">
<properties>
- <help>Upper limit of the SFQ</help>
+ <help>Interface egress traffic policy</help>
+ <completionHelp>
+ <path>traffic-policy drop-tail</path>
+ <path>traffic-policy fair-queue</path>
+ <path>traffic-policy fq-codel</path>
+ <path>traffic-policy limiter</path>
+ <path>traffic-policy network-emulator</path>
+ <path>traffic-policy priority-queue</path>
+ <path>traffic-policy random-detect</path>
+ <path>traffic-policy rate-control</path>
+ <path>traffic-policy round-robin</path>
+ <path>traffic-policy shaper</path>
+ <path>traffic-policy shaper-hfsc</path>
+ </completionHelp>
<valueHelp>
- <format>u32:2-127</format>
- <description>Queue size in packets</description>
+ <format>txt</format>
+ <description>QoS Policy name</description>
</valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 2-127"/>
- </constraint>
- <constraintErrorMessage>Queue limit must greater than 1 and less than 128</constraintErrorMessage>
</properties>
- <defaultValue>127</defaultValue>
</leafNode>
</children>
</tagNode>
- <tagNode name="fq-codel">
+ <node name="policy" owner="${vyos_conf_scripts_dir}/qos.py">
<properties>
- <help>Fair Queuing Controlled Delay</help>
- <valueHelp>
- <format>txt</format>
- <description>Policy name</description>
- </valueHelp>
- <constraint>
- <regex>[[:alnum:]][-_[:alnum:]]*</regex>
- </constraint>
- <constraintErrorMessage>Only alpha-numeric policy name allowed</constraintErrorMessage>
+ <help>Service Policy definitions</help>
+ <priority>900</priority>
</properties>
<children>
- #include <include/generic-description.xml.i>
- #include <include/qos/codel-quantum.xml.i>
- #include <include/qos/flows.xml.i>
- #include <include/qos/interval.xml.i>
- #include <include/qos/queue-limit-2-10999.xml.i>
- #include <include/qos/target.xml.i>
- </children>
- </tagNode>
- <tagNode name="limiter">
- <properties>
- <help>Traffic input limiting policy</help>
- <valueHelp>
- <format>txt</format>
- <description>Policy name</description>
- </valueHelp>
- <constraint>
- <regex>[[:alnum:]][-_[:alnum:]]*</regex>
- </constraint>
- <constraintErrorMessage>Only alpha-numeric policy name allowed</constraintErrorMessage>
- </properties>
- <children>
- <tagNode name="class">
+ <tagNode name="drop-tail">
<properties>
- <help>Class ID</help>
+ <help>Packet limited First In, First Out queue</help>
<valueHelp>
- <format>u32:1-4090</format>
- <description>Class Identifier</description>
+ <format>txt</format>
+ <description>Policy name</description>
</valueHelp>
<constraint>
- <validator name="numeric" argument="--range 1-4090"/>
+ <regex>[[:alnum:]][-_[:alnum:]]*</regex>
</constraint>
- <constraintErrorMessage>Class identifier must be between 1 and 4090</constraintErrorMessage>
+ <constraintErrorMessage>Only alpha-numeric policy name allowed</constraintErrorMessage>
+ </properties>
+ <children>
+ #include <include/generic-description.xml.i>
+ #include <include/qos/queue-limit-1-4294967295.xml.i>
+ </children>
+ </tagNode>
+ <tagNode name="fair-queue">
+ <properties>
+ <help>Stochastic Fairness Queueing</help>
+ <valueHelp>
+ <format>txt</format>
+ <description>Policy name</description>
+ </valueHelp>
+ <constraint>
+ <regex>[[:alnum:]][-_[:alnum:]]*</regex>
+ </constraint>
+ <constraintErrorMessage>Only alpha-numeric policy name allowed</constraintErrorMessage>
</properties>
<children>
- #include <include/qos/bandwidth.xml.i>
- #include <include/qos/burst.xml.i>
#include <include/generic-description.xml.i>
- #include <include/qos/match.xml.i>
- <leafNode name="priority">
+ <leafNode name="hash-interval">
+ <properties>
+ <help>Interval in seconds for queue algorithm perturbation</help>
+ <valueHelp>
+ <format>u32:0</format>
+ <description>No perturbation</description>
+ </valueHelp>
+ <valueHelp>
+ <format>u32:1-127</format>
+ <description>Interval in seconds for queue algorithm perturbation (advised: 10)</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-127"/>
+ </constraint>
+ <constraintErrorMessage>Interval must be in range 0 to 127</constraintErrorMessage>
+ </properties>
+ <defaultValue>0</defaultValue>
+ </leafNode>
+ <leafNode name="queue-limit">
<properties>
- <help>Priority for rule evaluation</help>
+ <help>Upper limit of the SFQ</help>
<valueHelp>
- <format>u32:0-20</format>
- <description>Priority for match rule evaluation</description>
+ <format>u32:2-127</format>
+ <description>Queue size in packets</description>
</valueHelp>
<constraint>
- <validator name="numeric" argument="--range 0-20"/>
+ <validator name="numeric" argument="--range 2-127"/>
</constraint>
- <constraintErrorMessage>Priority must be between 0 and 20</constraintErrorMessage>
+ <constraintErrorMessage>Queue limit must greater than 1 and less than 128</constraintErrorMessage>
</properties>
- <defaultValue>20</defaultValue>
+ <defaultValue>127</defaultValue>
</leafNode>
</children>
</tagNode>
- <node name="default">
- <properties>
- <help>Default policy</help>
- </properties>
- <children>
- #include <include/qos/bandwidth.xml.i>
- #include <include/qos/burst.xml.i>
- </children>
- </node>
- #include <include/generic-description.xml.i>
- </children>
- </tagNode>
- <tagNode name="network-emulator">
- <properties>
- <help>Network emulator policy</help>
- <valueHelp>
- <format>txt</format>
- <description>Policy name</description>
- </valueHelp>
- <constraint>
- <regex>[[:alnum:]][-_[:alnum:]]*</regex>
- </constraint>
- <constraintErrorMessage>Only alpha-numeric policy name allowed</constraintErrorMessage>
- </properties>
- <children>
- #include <include/qos/bandwidth.xml.i>
- #include <include/qos/burst.xml.i>
- #include <include/generic-description.xml.i>
- <leafNode name="network-delay">
- <properties>
- <help>Adds delay to packets outgoing to chosen network interface</help>
- <valueHelp>
- <format>&lt;number&gt;</format>
- <description>Time in milliseconds</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 0-65535"/>
- </constraint>
- <constraintErrorMessage>Priority must be between 0 and 65535</constraintErrorMessage>
- </properties>
- </leafNode>
- <leafNode name="packet-corruption">
- <properties>
- <help>Introducing error in a random position for chosen percent of packets</help>
- <valueHelp>
- <format>&lt;number&gt;</format>
- <description>Percentage of packets affected</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 0-100"/>
- </constraint>
- <constraintErrorMessage>Priority must be between 0 and 100</constraintErrorMessage>
- </properties>
- </leafNode>
- <leafNode name="packet-loss">
- <properties>
- <help>Add independent loss probability to the packets outgoing to chosen network interface</help>
- <valueHelp>
- <format>&lt;number&gt;</format>
- <description>Percentage of packets affected</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 0-100"/>
- </constraint>
- <constraintErrorMessage>Must be between 0 and 100</constraintErrorMessage>
- </properties>
- </leafNode>
- <leafNode name="packet-loss">
+ <tagNode name="fq-codel">
<properties>
- <help>Add independent loss probability to the packets outgoing to chosen network interface</help>
+ <help>Fair Queuing Controlled Delay</help>
<valueHelp>
- <format>&lt;number&gt;</format>
- <description>Percentage of packets affected</description>
+ <format>txt</format>
+ <description>Policy name</description>
</valueHelp>
<constraint>
- <validator name="numeric" argument="--range 0-100"/>
+ <regex>[[:alnum:]][-_[:alnum:]]*</regex>
</constraint>
- <constraintErrorMessage>Must be between 0 and 100</constraintErrorMessage>
- </properties>
- </leafNode>
- <leafNode name="packet-loss">
- <properties>
- <help>Packet reordering percentage</help>
- <valueHelp>
- <format>&lt;number&gt;</format>
- <description>Percentage of packets affected</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 0-100"/>
- </constraint>
- <constraintErrorMessage>Must be between 0 and 100</constraintErrorMessage>
- </properties>
- </leafNode>
- #include <include/qos/queue-limit-1-4294967295.xml.i>
- </children>
- </tagNode>
- <tagNode name="priority-queue">
- <properties>
- <help>Priority queuing based policy</help>
- <valueHelp>
- <format>txt</format>
- <description>Policy name</description>
- </valueHelp>
- <constraint>
- <regex>[[:alnum:]][-_[:alnum:]]*</regex>
- </constraint>
- <constraintErrorMessage>Only alpha-numeric policy name allowed</constraintErrorMessage>
- </properties>
- <children>
- <tagNode name="class">
- <properties>
- <help>Class Handle</help>
- <valueHelp>
- <format>u32:1-7</format>
- <description>Priority</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 1-7"/>
- </constraint>
- <constraintErrorMessage>Class handle must be between 1 and 7</constraintErrorMessage>
+ <constraintErrorMessage>Only alpha-numeric policy name allowed</constraintErrorMessage>
</properties>
<children>
#include <include/generic-description.xml.i>
#include <include/qos/codel-quantum.xml.i>
#include <include/qos/flows.xml.i>
#include <include/qos/interval.xml.i>
- #include <include/qos/match.xml.i>
#include <include/qos/queue-limit-2-10999.xml.i>
#include <include/qos/target.xml.i>
- #include <include/qos/queue-type.xml.i>
</children>
</tagNode>
- <node name="default">
+ <tagNode name="limiter">
<properties>
- <help>Default policy</help>
+ <help>Traffic input limiting policy</help>
+ <valueHelp>
+ <format>txt</format>
+ <description>Policy name</description>
+ </valueHelp>
+ <constraint>
+ <regex>[[:alnum:]][-_[:alnum:]]*</regex>
+ </constraint>
+ <constraintErrorMessage>Only alpha-numeric policy name allowed</constraintErrorMessage>
</properties>
<children>
+ <tagNode name="class">
+ <properties>
+ <help>Class ID</help>
+ <valueHelp>
+ <format>u32:1-4090</format>
+ <description>Class Identifier</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-4090"/>
+ </constraint>
+ <constraintErrorMessage>Class identifier must be between 1 and 4090</constraintErrorMessage>
+ </properties>
+ <children>
+ #include <include/qos/bandwidth.xml.i>
+ #include <include/qos/burst.xml.i>
+ #include <include/generic-description.xml.i>
+ #include <include/qos/match.xml.i>
+ <leafNode name="priority">
+ <properties>
+ <help>Priority for rule evaluation</help>
+ <valueHelp>
+ <format>u32:0-20</format>
+ <description>Priority for match rule evaluation</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-20"/>
+ </constraint>
+ <constraintErrorMessage>Priority must be between 0 and 20</constraintErrorMessage>
+ </properties>
+ <defaultValue>20</defaultValue>
+ </leafNode>
+ </children>
+ </tagNode>
+ <node name="default">
+ <properties>
+ <help>Default policy</help>
+ </properties>
+ <children>
+ #include <include/qos/bandwidth.xml.i>
+ #include <include/qos/burst.xml.i>
+ </children>
+ </node>
#include <include/generic-description.xml.i>
- #include <include/qos/codel-quantum.xml.i>
- #include <include/qos/flows.xml.i>
- #include <include/qos/interval.xml.i>
- #include <include/qos/queue-limit-2-10999.xml.i>
- #include <include/qos/target.xml.i>
- #include <include/qos/queue-type.xml.i>
</children>
- </node>
- #include <include/generic-description.xml.i>
- </children>
- </tagNode>
- <tagNode name="random-detect">
- <properties>
- <help>Priority queuing based policy</help>
- <valueHelp>
- <format>txt</format>
- <description>Policy name</description>
- </valueHelp>
- <constraint>
- <regex>[[:alnum:]][-_[:alnum:]]*</regex>
- </constraint>
- <constraintErrorMessage>Only alpha-numeric policy name allowed</constraintErrorMessage>
- </properties>
- <children>
- #include <include/qos/bandwidth.xml.i>
- <leafNode name="bandwidth">
- <defaultValue>auto</defaultValue>
- </leafNode>
- #include <include/generic-description.xml.i>
- <tagNode name="precedence">
+ </tagNode>
+ <tagNode name="network-emulator">
<properties>
- <help>IP precedence</help>
+ <help>Network emulator policy</help>
<valueHelp>
- <format>u32:0-7</format>
- <description>IP precedence value</description>
+ <format>txt</format>
+ <description>Policy name</description>
</valueHelp>
<constraint>
- <validator name="numeric" argument="--range 0-7"/>
+ <regex>[[:alnum:]][-_[:alnum:]]*</regex>
</constraint>
- <constraintErrorMessage>IP precedence value must be between 0 and 7</constraintErrorMessage>
+ <constraintErrorMessage>Only alpha-numeric policy name allowed</constraintErrorMessage>
</properties>
<children>
- #include <include/qos/queue-limit-1-4294967295.xml.i>
- <leafNode name="average-packet">
+ #include <include/qos/bandwidth.xml.i>
+ #include <include/qos/burst.xml.i>
+ #include <include/generic-description.xml.i>
+ <leafNode name="network-delay">
<properties>
- <help>Average packet size (bytes)</help>
+ <help>Adds delay to packets outgoing to chosen network interface</help>
<valueHelp>
- <format>u32:16-10240</format>
- <description>Average packet size in bytes</description>
+ <format>&lt;number&gt;</format>
+ <description>Time in milliseconds</description>
</valueHelp>
<constraint>
- <validator name="numeric" argument="--range 0-100"/>
+ <validator name="numeric" argument="--range 0-65535"/>
</constraint>
- <constraintErrorMessage>Average packet size must be between 16 and 10240</constraintErrorMessage>
+ <constraintErrorMessage>Priority must be between 0 and 65535</constraintErrorMessage>
</properties>
- <defaultValue>1024</defaultValue>
</leafNode>
- <leafNode name="mark-probability">
+ <leafNode name="packet-corruption">
<properties>
- <help>Mark probability for this precedence</help>
+ <help>Introducing error in a random position for chosen percent of packets</help>
<valueHelp>
<format>&lt;number&gt;</format>
- <description>Numeric value (1/N)</description>
+ <description>Percentage of packets affected</description>
</valueHelp>
<constraint>
- <validator name="numeric" argument="--positive"/>
+ <validator name="numeric" argument="--range 0-100"/>
</constraint>
- <constraintErrorMessage>Mark probability must be greater than 0</constraintErrorMessage>
+ <constraintErrorMessage>Priority must be between 0 and 100</constraintErrorMessage>
</properties>
</leafNode>
- <leafNode name="maximum-threshold">
+ <leafNode name="packet-loss">
<properties>
- <help>Maximum threshold for random detection</help>
+ <help>Add independent loss probability to the packets outgoing to chosen network interface</help>
<valueHelp>
- <format>u32:0-4096</format>
- <description>Maximum Threshold in packets</description>
+ <format>&lt;number&gt;</format>
+ <description>Percentage of packets affected</description>
</valueHelp>
<constraint>
- <validator name="numeric" argument="--range 0-4096"/>
+ <validator name="numeric" argument="--range 0-100"/>
</constraint>
- <constraintErrorMessage>Threshold must be between 0 and 4096</constraintErrorMessage>
+ <constraintErrorMessage>Must be between 0 and 100</constraintErrorMessage>
</properties>
</leafNode>
- <leafNode name="minimum-threshold">
+ <leafNode name="packet-loss">
<properties>
- <help>Minimum threshold for random detection</help>
+ <help>Add independent loss probability to the packets outgoing to chosen network interface</help>
<valueHelp>
- <format>u32:0-4096</format>
- <description>Maximum Threshold in packets</description>
+ <format>&lt;number&gt;</format>
+ <description>Percentage of packets affected</description>
</valueHelp>
<constraint>
- <validator name="numeric" argument="--range 0-4096"/>
+ <validator name="numeric" argument="--range 0-100"/>
</constraint>
- <constraintErrorMessage>Threshold must be between 0 and 4096</constraintErrorMessage>
+ <constraintErrorMessage>Must be between 0 and 100</constraintErrorMessage>
</properties>
</leafNode>
- </children>
- </tagNode>
- </children>
- </tagNode>
- <tagNode name="rate-control">
- <properties>
- <help>Rate limiting policy (Token Bucket Filter)</help>
- <valueHelp>
- <format>txt</format>
- <description>Policy name</description>
- </valueHelp>
- <constraint>
- <regex>[[:alnum:]][-_[:alnum:]]*</regex>
- </constraint>
- <constraintErrorMessage>Only alpha-numeric policy name allowed</constraintErrorMessage>
- </properties>
- <children>
- #include <include/qos/bandwidth.xml.i>
- #include <include/generic-description.xml.i>
- #include <include/qos/burst.xml.i>
- <leafNode name="latency">
- <properties>
- <help>Maximum latency</help>
- <valueHelp>
- <format>&lt;number&gt;</format>
- <description>Time in milliseconds</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 0-4096"/>
- </constraint>
- <constraintErrorMessage>Threshold must be between 0 and 4096</constraintErrorMessage>
- </properties>
- <defaultValue>50</defaultValue>
- </leafNode>
- </children>
- </tagNode>
- <tagNode name="round-robin">
- <properties>
- <help>Round-Robin based policy</help>
- <valueHelp>
- <format>txt</format>
- <description>Policy name</description>
- </valueHelp>
- <constraint>
- <regex>[[:alnum:]][-_[:alnum:]]*</regex>
- </constraint>
- <constraintErrorMessage>Only alpha-numeric policy name allowed</constraintErrorMessage>
- </properties>
- <children>
- #include <include/generic-description.xml.i>
- <tagNode name="class">
- <properties>
- <help>Class ID</help>
- <valueHelp>
- <format>u32:1-4095</format>
- <description>Class Identifier</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 1-4095"/>
- </constraint>
- <constraintErrorMessage>Class identifier must be between 1 and 4095</constraintErrorMessage>
- </properties>
- <children>
- #include <include/qos/codel-quantum.xml.i>
- #include <include/generic-description.xml.i>
- #include <include/qos/flows.xml.i>
- #include <include/qos/interval.xml.i>
- #include <include/qos/match.xml.i>
- <leafNode name="quantum">
+ <leafNode name="packet-loss">
<properties>
- <help>Packet scheduling quantum</help>
+ <help>Packet reordering percentage</help>
<valueHelp>
- <format>u32:1-4294967295</format>
- <description>Packet scheduling quantum (bytes)</description>
+ <format>&lt;number&gt;</format>
+ <description>Percentage of packets affected</description>
</valueHelp>
<constraint>
- <validator name="numeric" argument="--range 1-4294967295"/>
+ <validator name="numeric" argument="--range 0-100"/>
</constraint>
- <constraintErrorMessage>Quantum must be in range 1 to 4294967295</constraintErrorMessage>
+ <constraintErrorMessage>Must be between 0 and 100</constraintErrorMessage>
</properties>
</leafNode>
#include <include/qos/queue-limit-1-4294967295.xml.i>
- #include <include/qos/queue-type.xml.i>
- #include <include/qos/target.xml.i>
</children>
</tagNode>
- </children>
- </tagNode>
- <tagNode name="shaper-hfsc">
- <properties>
- <help>Hierarchical Fair Service Curve's policy</help>
- <valueHelp>
- <format>txt</format>
- <description>Policy name</description>
- </valueHelp>
- <constraint>
- <regex>[[:alnum:]][-_[:alnum:]]*</regex>
- </constraint>
- <constraintErrorMessage>Only alpha-numeric policy name allowed</constraintErrorMessage>
- </properties>
- <children>
- #include <include/qos/bandwidth.xml.i>
- <leafNode name="bandwidth">
- <defaultValue>auto</defaultValue>
- </leafNode>
- #include <include/generic-description.xml.i>
- <tagNode name="class">
+ <tagNode name="priority-queue">
<properties>
- <help>Class ID</help>
+ <help>Priority queuing based policy</help>
<valueHelp>
- <format>u32:1-4095</format>
- <description>Class Identifier</description>
+ <format>txt</format>
+ <description>Policy name</description>
</valueHelp>
<constraint>
- <validator name="numeric" argument="--range 1-4095"/>
+ <regex>[[:alnum:]][-_[:alnum:]]*</regex>
</constraint>
- <constraintErrorMessage>Class identifier must be between 1 and 4095</constraintErrorMessage>
+ <constraintErrorMessage>Only alpha-numeric policy name allowed</constraintErrorMessage>
</properties>
<children>
- #include <include/generic-description.xml.i>
- <node name="linkshare">
+ <tagNode name="class">
<properties>
- <help>Linkshare class settings</help>
- </properties>
- <children>
- #include <include/qos/hfsc-d.xml.i>
- #include <include/qos/hfsc-m1.xml.i>
- #include <include/qos/hfsc-m2.xml.i>
- </children>
- </node>
- #include <include/qos/match.xml.i>
- <node name="realtime">
- <properties>
- <help>Realtime class settings</help>
+ <help>Class Handle</help>
+ <valueHelp>
+ <format>u32:1-7</format>
+ <description>Priority</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-7"/>
+ </constraint>
+ <constraintErrorMessage>Class handle must be between 1 and 7</constraintErrorMessage>
</properties>
<children>
- #include <include/qos/hfsc-d.xml.i>
- #include <include/qos/hfsc-m1.xml.i>
- #include <include/qos/hfsc-m2.xml.i>
+ #include <include/generic-description.xml.i>
+ #include <include/qos/codel-quantum.xml.i>
+ #include <include/qos/flows.xml.i>
+ #include <include/qos/interval.xml.i>
+ #include <include/qos/match.xml.i>
+ #include <include/qos/queue-limit-2-10999.xml.i>
+ #include <include/qos/target.xml.i>
+ #include <include/qos/queue-type.xml.i>
</children>
- </node>
- <node name="upperlimit">
+ </tagNode>
+ <node name="default">
<properties>
- <help>Upperlimit class settings</help>
+ <help>Default policy</help>
</properties>
<children>
- #include <include/qos/hfsc-d.xml.i>
- #include <include/qos/hfsc-m1.xml.i>
- #include <include/qos/hfsc-m2.xml.i>
+ #include <include/generic-description.xml.i>
+ #include <include/qos/codel-quantum.xml.i>
+ #include <include/qos/flows.xml.i>
+ #include <include/qos/interval.xml.i>
+ #include <include/qos/queue-limit-2-10999.xml.i>
+ #include <include/qos/target.xml.i>
+ #include <include/qos/queue-type.xml.i>
</children>
</node>
+ #include <include/generic-description.xml.i>
</children>
</tagNode>
- <node name="default">
+ <tagNode name="random-detect">
<properties>
- <help>Default policy</help>
+ <help>Priority queuing based policy</help>
+ <valueHelp>
+ <format>txt</format>
+ <description>Policy name</description>
+ </valueHelp>
+ <constraint>
+ <regex>[[:alnum:]][-_[:alnum:]]*</regex>
+ </constraint>
+ <constraintErrorMessage>Only alpha-numeric policy name allowed</constraintErrorMessage>
</properties>
<children>
- <node name="linkshare">
- <properties>
- <help>Linkshare class settings</help>
- </properties>
- <children>
- #include <include/qos/hfsc-d.xml.i>
- #include <include/qos/hfsc-m1.xml.i>
- #include <include/qos/hfsc-m2.xml.i>
- </children>
- </node>
- <node name="realtime">
- <properties>
- <help>Realtime class settings</help>
- </properties>
- <children>
- #include <include/qos/hfsc-d.xml.i>
- #include <include/qos/hfsc-m1.xml.i>
- #include <include/qos/hfsc-m2.xml.i>
- </children>
- </node>
- <node name="upperlimit">
+ #include <include/qos/bandwidth.xml.i>
+ <leafNode name="bandwidth">
+ <defaultValue>auto</defaultValue>
+ </leafNode>
+ #include <include/generic-description.xml.i>
+ <tagNode name="precedence">
<properties>
- <help>Upperlimit class settings</help>
+ <help>IP precedence</help>
+ <valueHelp>
+ <format>u32:0-7</format>
+ <description>IP precedence value</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-7"/>
+ </constraint>
+ <constraintErrorMessage>IP precedence value must be between 0 and 7</constraintErrorMessage>
</properties>
<children>
- #include <include/qos/hfsc-d.xml.i>
- #include <include/qos/hfsc-m1.xml.i>
- #include <include/qos/hfsc-m2.xml.i>
+ #include <include/qos/queue-limit-1-4294967295.xml.i>
+ <leafNode name="average-packet">
+ <properties>
+ <help>Average packet size (bytes)</help>
+ <valueHelp>
+ <format>u32:16-10240</format>
+ <description>Average packet size in bytes</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-100"/>
+ </constraint>
+ <constraintErrorMessage>Average packet size must be between 16 and 10240</constraintErrorMessage>
+ </properties>
+ <defaultValue>1024</defaultValue>
+ </leafNode>
+ <leafNode name="mark-probability">
+ <properties>
+ <help>Mark probability for this precedence</help>
+ <valueHelp>
+ <format>&lt;number&gt;</format>
+ <description>Numeric value (1/N)</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--positive"/>
+ </constraint>
+ <constraintErrorMessage>Mark probability must be greater than 0</constraintErrorMessage>
+ </properties>
+ </leafNode>
+ <leafNode name="maximum-threshold">
+ <properties>
+ <help>Maximum threshold for random detection</help>
+ <valueHelp>
+ <format>u32:0-4096</format>
+ <description>Maximum Threshold in packets</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-4096"/>
+ </constraint>
+ <constraintErrorMessage>Threshold must be between 0 and 4096</constraintErrorMessage>
+ </properties>
+ </leafNode>
+ <leafNode name="minimum-threshold">
+ <properties>
+ <help>Minimum threshold for random detection</help>
+ <valueHelp>
+ <format>u32:0-4096</format>
+ <description>Maximum Threshold in packets</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-4096"/>
+ </constraint>
+ <constraintErrorMessage>Threshold must be between 0 and 4096</constraintErrorMessage>
+ </properties>
+ </leafNode>
</children>
- </node>
+ </tagNode>
</children>
- </node>
- </children>
- </tagNode>
- <tagNode name="shaper">
- <properties>
- <help>Traffic shaping based policy (Hierarchy Token Bucket)</help>
- <valueHelp>
- <format>txt</format>
- <description>Policy name</description>
- </valueHelp>
- <constraint>
- <regex>[[:alnum:]][-_[:alnum:]]*</regex>
- </constraint>
- <constraintErrorMessage>Only alpha-numeric policy name allowed</constraintErrorMessage>
- </properties>
- <children>
- #include <include/qos/bandwidth.xml.i>
- <leafNode name="bandwidth">
- <defaultValue>auto</defaultValue>
- </leafNode>
- <tagNode name="class">
+ </tagNode>
+ <tagNode name="rate-control">
<properties>
- <help>Class ID</help>
+ <help>Rate limiting policy (Token Bucket Filter)</help>
<valueHelp>
- <format>u32:2-4095</format>
- <description>Class Identifier</description>
+ <format>txt</format>
+ <description>Policy name</description>
</valueHelp>
<constraint>
- <validator name="numeric" argument="--range 2-4095"/>
+ <regex>[[:alnum:]][-_[:alnum:]]*</regex>
</constraint>
- <constraintErrorMessage>Class identifier must be between 2 and 4095</constraintErrorMessage>
+ <constraintErrorMessage>Only alpha-numeric policy name allowed</constraintErrorMessage>
</properties>
<children>
#include <include/qos/bandwidth.xml.i>
- <leafNode name="bandwidth">
- <defaultValue>100%</defaultValue>
- </leafNode>
+ #include <include/generic-description.xml.i>
#include <include/qos/burst.xml.i>
- <leafNode name="ceiling">
+ <leafNode name="latency">
<properties>
- <help>Bandwidth limit for this class</help>
+ <help>Maximum latency</help>
<valueHelp>
<format>&lt;number&gt;</format>
- <description>Rate in kbit (kilobit per second)</description>
- </valueHelp>
- <valueHelp>
- <format>&lt;number&gt;%%</format>
- <description>Percentage of overall rate</description>
- </valueHelp>
- <valueHelp>
- <format>&lt;number&gt;bit</format>
- <description>bit(1), kbit(10^3), mbit(10^6), gbit, tbit</description>
- </valueHelp>
- <valueHelp>
- <format>&lt;number&gt;ibit</format>
- <description>kibit(1024), mibit(1024^2), gibit(1024^3), tbit(1024^4)</description>
- </valueHelp>
- <valueHelp>
- <format>&lt;number&gt;ibps</format>
- <description>kibps(1024*8), mibps(1024^2*8), gibps, tibps - Byte/sec</description>
- </valueHelp>
- <valueHelp>
- <format>&lt;number&gt;bps</format>
- <description>bps(8),kbps(8*10^3),mbps(8*10^6), gbps, tbps - Byte/sec</description>
+ <description>Time in milliseconds</description>
</valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-4096"/>
+ </constraint>
+ <constraintErrorMessage>Threshold must be between 0 and 4096</constraintErrorMessage>
</properties>
+ <defaultValue>50</defaultValue>
</leafNode>
- #include <include/qos/codel-quantum.xml.i>
+ </children>
+ </tagNode>
+ <tagNode name="round-robin">
+ <properties>
+ <help>Round-Robin based policy</help>
+ <valueHelp>
+ <format>txt</format>
+ <description>Policy name</description>
+ </valueHelp>
+ <constraint>
+ <regex>[[:alnum:]][-_[:alnum:]]*</regex>
+ </constraint>
+ <constraintErrorMessage>Only alpha-numeric policy name allowed</constraintErrorMessage>
+ </properties>
+ <children>
#include <include/generic-description.xml.i>
- #include <include/qos/flows.xml.i>
- #include <include/qos/interval.xml.i>
- #include <include/qos/match.xml.i>
- <leafNode name="priority">
+ <tagNode name="class">
<properties>
- <help>Priority for usage of excess bandwidth</help>
+ <help>Class ID</help>
<valueHelp>
- <format>u32:0-7</format>
- <description>Priority order for bandwidth pool</description>
+ <format>u32:1-4095</format>
+ <description>Class Identifier</description>
</valueHelp>
<constraint>
- <validator name="numeric" argument="--range 0-7"/>
+ <validator name="numeric" argument="--range 1-4095"/>
</constraint>
- <constraintErrorMessage>Priority must be between 0 and 7</constraintErrorMessage>
+ <constraintErrorMessage>Class identifier must be between 1 and 4095</constraintErrorMessage>
</properties>
- <defaultValue>20</defaultValue>
- </leafNode>
- #include <include/qos/queue-limit-1-4294967295.xml.i>
- #include <include/qos/queue-type.xml.i>
- #include <include/qos/set-dscp.xml.i>
- #include <include/qos/target.xml.i>
+ <children>
+ #include <include/qos/codel-quantum.xml.i>
+ #include <include/generic-description.xml.i>
+ #include <include/qos/flows.xml.i>
+ #include <include/qos/interval.xml.i>
+ #include <include/qos/match.xml.i>
+ <leafNode name="quantum">
+ <properties>
+ <help>Packet scheduling quantum</help>
+ <valueHelp>
+ <format>u32:1-4294967295</format>
+ <description>Packet scheduling quantum (bytes)</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-4294967295"/>
+ </constraint>
+ <constraintErrorMessage>Quantum must be in range 1 to 4294967295</constraintErrorMessage>
+ </properties>
+ </leafNode>
+ #include <include/qos/queue-limit-1-4294967295.xml.i>
+ #include <include/qos/queue-type.xml.i>
+ #include <include/qos/target.xml.i>
+ </children>
+ </tagNode>
</children>
</tagNode>
- #include <include/generic-description.xml.i>
- <node name="default">
+ <tagNode name="shaper-hfsc">
<properties>
- <help>Default policy</help>
+ <help>Hierarchical Fair Service Curve's policy</help>
+ <valueHelp>
+ <format>txt</format>
+ <description>Policy name</description>
+ </valueHelp>
+ <constraint>
+ <regex>[[:alnum:]][-_[:alnum:]]*</regex>
+ </constraint>
+ <constraintErrorMessage>Only alpha-numeric policy name allowed</constraintErrorMessage>
</properties>
<children>
#include <include/qos/bandwidth.xml.i>
- #include <include/qos/burst.xml.i>
- <leafNode name="ceiling">
+ <leafNode name="bandwidth">
+ <defaultValue>auto</defaultValue>
+ </leafNode>
+ #include <include/generic-description.xml.i>
+ <tagNode name="class">
<properties>
- <help>Bandwidth limit for this class</help>
- <valueHelp>
- <format>&lt;number&gt;</format>
- <description>Rate in kbit (kilobit per second)</description>
- </valueHelp>
- <valueHelp>
- <format>&lt;number&gt;%%</format>
- <description>Percentage of overall rate</description>
- </valueHelp>
+ <help>Class ID</help>
<valueHelp>
- <format>&lt;number&gt;bit</format>
- <description>bit(1), kbit(10^3), mbit(10^6), gbit, tbit</description>
- </valueHelp>
- <valueHelp>
- <format>&lt;number&gt;ibit</format>
- <description>kibit(1024), mibit(1024^2), gibit(1024^3), tbit(1024^4)</description>
- </valueHelp>
- <valueHelp>
- <format>&lt;number&gt;ibps</format>
- <description>kibps(1024*8), mibps(1024^2*8), gibps, tibps - Byte/sec</description>
- </valueHelp>
- <valueHelp>
- <format>&lt;number&gt;bps</format>
- <description>bps(8),kbps(8*10^3),mbps(8*10^6), gbps, tbps - Byte/sec</description>
+ <format>u32:1-4095</format>
+ <description>Class Identifier</description>
</valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-4095"/>
+ </constraint>
+ <constraintErrorMessage>Class identifier must be between 1 and 4095</constraintErrorMessage>
+ </properties>
+ <children>
+ #include <include/generic-description.xml.i>
+ <node name="linkshare">
+ <properties>
+ <help>Linkshare class settings</help>
+ </properties>
+ <children>
+ #include <include/qos/hfsc-d.xml.i>
+ #include <include/qos/hfsc-m1.xml.i>
+ #include <include/qos/hfsc-m2.xml.i>
+ </children>
+ </node>
+ #include <include/qos/match.xml.i>
+ <node name="realtime">
+ <properties>
+ <help>Realtime class settings</help>
+ </properties>
+ <children>
+ #include <include/qos/hfsc-d.xml.i>
+ #include <include/qos/hfsc-m1.xml.i>
+ #include <include/qos/hfsc-m2.xml.i>
+ </children>
+ </node>
+ <node name="upperlimit">
+ <properties>
+ <help>Upperlimit class settings</help>
+ </properties>
+ <children>
+ #include <include/qos/hfsc-d.xml.i>
+ #include <include/qos/hfsc-m1.xml.i>
+ #include <include/qos/hfsc-m2.xml.i>
+ </children>
+ </node>
+ </children>
+ </tagNode>
+ <node name="default">
+ <properties>
+ <help>Default policy</help>
</properties>
+ <children>
+ <node name="linkshare">
+ <properties>
+ <help>Linkshare class settings</help>
+ </properties>
+ <children>
+ #include <include/qos/hfsc-d.xml.i>
+ #include <include/qos/hfsc-m1.xml.i>
+ #include <include/qos/hfsc-m2.xml.i>
+ </children>
+ </node>
+ <node name="realtime">
+ <properties>
+ <help>Realtime class settings</help>
+ </properties>
+ <children>
+ #include <include/qos/hfsc-d.xml.i>
+ #include <include/qos/hfsc-m1.xml.i>
+ #include <include/qos/hfsc-m2.xml.i>
+ </children>
+ </node>
+ <node name="upperlimit">
+ <properties>
+ <help>Upperlimit class settings</help>
+ </properties>
+ <children>
+ #include <include/qos/hfsc-d.xml.i>
+ #include <include/qos/hfsc-m1.xml.i>
+ #include <include/qos/hfsc-m2.xml.i>
+ </children>
+ </node>
+ </children>
+ </node>
+ </children>
+ </tagNode>
+ <tagNode name="shaper">
+ <properties>
+ <help>Traffic shaping based policy (Hierarchy Token Bucket)</help>
+ <valueHelp>
+ <format>txt</format>
+ <description>Policy name</description>
+ </valueHelp>
+ <constraint>
+ <regex>[[:alnum:]][-_[:alnum:]]*</regex>
+ </constraint>
+ <constraintErrorMessage>Only alpha-numeric policy name allowed</constraintErrorMessage>
+ </properties>
+ <children>
+ #include <include/qos/bandwidth.xml.i>
+ <leafNode name="bandwidth">
+ <defaultValue>auto</defaultValue>
</leafNode>
- #include <include/qos/codel-quantum.xml.i>
- #include <include/generic-description.xml.i>
- #include <include/qos/flows.xml.i>
- #include <include/qos/interval.xml.i>
- <leafNode name="priority">
+ <tagNode name="class">
<properties>
- <help>Priority for usage of excess bandwidth</help>
+ <help>Class ID</help>
<valueHelp>
- <format>u32:0-7</format>
- <description>Priority order for bandwidth pool</description>
+ <format>u32:2-4095</format>
+ <description>Class Identifier</description>
</valueHelp>
<constraint>
- <validator name="numeric" argument="--range 0-7"/>
+ <validator name="numeric" argument="--range 2-4095"/>
</constraint>
- <constraintErrorMessage>Priority must be between 0 and 7</constraintErrorMessage>
+ <constraintErrorMessage>Class identifier must be between 2 and 4095</constraintErrorMessage>
</properties>
- <defaultValue>20</defaultValue>
- </leafNode>
- #include <include/qos/queue-limit-1-4294967295.xml.i>
- #include <include/qos/queue-type.xml.i>
- #include <include/qos/set-dscp.xml.i>
- #include <include/qos/target.xml.i>
+ <children>
+ #include <include/qos/bandwidth.xml.i>
+ <leafNode name="bandwidth">
+ <defaultValue>100%</defaultValue>
+ </leafNode>
+ #include <include/qos/burst.xml.i>
+ <leafNode name="ceiling">
+ <properties>
+ <help>Bandwidth limit for this class</help>
+ <valueHelp>
+ <format>&lt;number&gt;</format>
+ <description>Rate in kbit (kilobit per second)</description>
+ </valueHelp>
+ <valueHelp>
+ <format>&lt;number&gt;%%</format>
+ <description>Percentage of overall rate</description>
+ </valueHelp>
+ <valueHelp>
+ <format>&lt;number&gt;bit</format>
+ <description>bit(1), kbit(10^3), mbit(10^6), gbit, tbit</description>
+ </valueHelp>
+ <valueHelp>
+ <format>&lt;number&gt;ibit</format>
+ <description>kibit(1024), mibit(1024^2), gibit(1024^3), tbit(1024^4)</description>
+ </valueHelp>
+ <valueHelp>
+ <format>&lt;number&gt;ibps</format>
+ <description>kibps(1024*8), mibps(1024^2*8), gibps, tibps - Byte/sec</description>
+ </valueHelp>
+ <valueHelp>
+ <format>&lt;number&gt;bps</format>
+ <description>bps(8),kbps(8*10^3),mbps(8*10^6), gbps, tbps - Byte/sec</description>
+ </valueHelp>
+ </properties>
+ </leafNode>
+ #include <include/qos/codel-quantum.xml.i>
+ #include <include/generic-description.xml.i>
+ #include <include/qos/flows.xml.i>
+ #include <include/qos/interval.xml.i>
+ #include <include/qos/match.xml.i>
+ <leafNode name="priority">
+ <properties>
+ <help>Priority for usage of excess bandwidth</help>
+ <valueHelp>
+ <format>u32:0-7</format>
+ <description>Priority order for bandwidth pool</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-7"/>
+ </constraint>
+ <constraintErrorMessage>Priority must be between 0 and 7</constraintErrorMessage>
+ </properties>
+ <defaultValue>20</defaultValue>
+ </leafNode>
+ #include <include/qos/queue-limit-1-4294967295.xml.i>
+ #include <include/qos/queue-type.xml.i>
+ #include <include/qos/set-dscp.xml.i>
+ #include <include/qos/target.xml.i>
+ </children>
+ </tagNode>
+ #include <include/generic-description.xml.i>
+ <node name="default">
+ <properties>
+ <help>Default policy</help>
+ </properties>
+ <children>
+ #include <include/qos/bandwidth.xml.i>
+ #include <include/qos/burst.xml.i>
+ <leafNode name="ceiling">
+ <properties>
+ <help>Bandwidth limit for this class</help>
+ <valueHelp>
+ <format>&lt;number&gt;</format>
+ <description>Rate in kbit (kilobit per second)</description>
+ </valueHelp>
+ <valueHelp>
+ <format>&lt;number&gt;%%</format>
+ <description>Percentage of overall rate</description>
+ </valueHelp>
+ <valueHelp>
+ <format>&lt;number&gt;bit</format>
+ <description>bit(1), kbit(10^3), mbit(10^6), gbit, tbit</description>
+ </valueHelp>
+ <valueHelp>
+ <format>&lt;number&gt;ibit</format>
+ <description>kibit(1024), mibit(1024^2), gibit(1024^3), tbit(1024^4)</description>
+ </valueHelp>
+ <valueHelp>
+ <format>&lt;number&gt;ibps</format>
+ <description>kibps(1024*8), mibps(1024^2*8), gibps, tibps - Byte/sec</description>
+ </valueHelp>
+ <valueHelp>
+ <format>&lt;number&gt;bps</format>
+ <description>bps(8),kbps(8*10^3),mbps(8*10^6), gbps, tbps - Byte/sec</description>
+ </valueHelp>
+ </properties>
+ </leafNode>
+ #include <include/qos/codel-quantum.xml.i>
+ #include <include/generic-description.xml.i>
+ #include <include/qos/flows.xml.i>
+ #include <include/qos/interval.xml.i>
+ <leafNode name="priority">
+ <properties>
+ <help>Priority for usage of excess bandwidth</help>
+ <valueHelp>
+ <format>u32:0-7</format>
+ <description>Priority order for bandwidth pool</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-7"/>
+ </constraint>
+ <constraintErrorMessage>Priority must be between 0 and 7</constraintErrorMessage>
+ </properties>
+ <defaultValue>20</defaultValue>
+ </leafNode>
+ #include <include/qos/queue-limit-1-4294967295.xml.i>
+ #include <include/qos/queue-type.xml.i>
+ #include <include/qos/set-dscp.xml.i>
+ #include <include/qos/target.xml.i>
+ </children>
+ </node>
</children>
- </node>
+ </tagNode>
</children>
- </tagNode>
+ </node>
</children>
</node>
</interfaceDefinition>
diff --git a/interface-definitions/service_ipoe-server.xml.in b/interface-definitions/service_ipoe-server.xml.in
index b19acab56..1325ba10d 100644
--- a/interface-definitions/service_ipoe-server.xml.in
+++ b/interface-definitions/service_ipoe-server.xml.in
@@ -112,6 +112,22 @@
</children>
</tagNode>
#include <include/name-server-ipv4-ipv6.xml.i>
+ <node name="client-ip-pool">
+ <properties>
+ <help>Client IP pools and gateway setting</help>
+ </properties>
+ <children>
+ <tagNode name="name">
+ <properties>
+ <help>Pool name</help>
+ </properties>
+ <children>
+ #include <include/accel-ppp/gateway-address.xml.i>
+ #include <include/accel-ppp/client-ip-pool-subnet-single.xml.i>
+ </children>
+ </tagNode>
+ </children>
+ </node>
#include <include/accel-ppp/client-ipv6-pool.xml.i>
<node name="authentication">
<properties>
diff --git a/interface-definitions/system-ipv6.xml.in b/interface-definitions/system-ipv6.xml.in
index af4dcdb0f..63260d00c 100644
--- a/interface-definitions/system-ipv6.xml.in
+++ b/interface-definitions/system-ipv6.xml.in
@@ -15,12 +15,6 @@
<valueless/>
</properties>
</leafNode>
- <leafNode name="disable">
- <properties>
- <help>Disable assignment of IPv6 addresses on all interfaces</help>
- <valueless/>
- </properties>
- </leafNode>
<node name="multipath">
<properties>
<help>IPv6 multipath settings</help>
diff --git a/op-mode-definitions/include/ospf-common.xml.i b/op-mode-definitions/include/ospf-common.xml.i
index 0edc3c37f..23769c8ba 100644
--- a/op-mode-definitions/include/ospf-common.xml.i
+++ b/op-mode-definitions/include/ospf-common.xml.i
@@ -523,15 +523,6 @@
</properties>
<command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
<children>
- <tagNode name="address">
- <properties>
- <help>Show IPv4 OSPF neighbor information for specified IP address</help>
- <completionHelp>
- <list>&lt;x.x.x.x&gt;</list>
- </completionHelp>
- </properties>
- <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
- </tagNode>
<node name="detail">
<properties>
<help>Show detailed IPv4 OSPF neighbor information</help>
diff --git a/op-mode-definitions/monitor-log.xml.in b/op-mode-definitions/monitor-log.xml.in
index 352c84ff1..cbdf76fc3 100644
--- a/op-mode-definitions/monitor-log.xml.in
+++ b/op-mode-definitions/monitor-log.xml.in
@@ -14,6 +14,79 @@
</properties>
<command>grc tail --follow=name /var/log/messages</command>
</node>
+ <node name="protocol">
+ <properties>
+ <help>Monitor log for Routing Protocols</help>
+ </properties>
+ <children>
+ <leafNode name="ospf">
+ <properties>
+ <help>Monitor log for OSPF</help>
+ </properties>
+ <command>journalctl --follow --boot /usr/lib/frr/ospfd</command>
+ </leafNode>
+ <leafNode name="ospfv3">
+ <properties>
+ <help>Monitor log for OSPF for IPv6</help>
+ </properties>
+ <command>journalctl --follow --boot /usr/lib/frr/ospf6d</command>
+ </leafNode>
+ <leafNode name="bgp">
+ <properties>
+ <help>Monitor log for BGP</help>
+ </properties>
+ <command>journalctl --follow --boot /usr/lib/frr/bgpd</command>
+ </leafNode>
+ <leafNode name="rip">
+ <properties>
+ <help>Monitor log for RIP</help>
+ </properties>
+ <command>journalctl --follow --boot /usr/lib/frr/ripd</command>
+ </leafNode>
+ <leafNode name="ripng">
+ <properties>
+ <help>Monitor log for RIPng</help>
+ </properties>
+ <command>journalctl --follow --boot /usr/lib/frr/ripngd</command>
+ </leafNode>
+ <leafNode name="static">
+ <properties>
+ <help>Monitor log for static route</help>
+ </properties>
+ <command>journalctl --follow --boot /usr/lib/frr/staticd</command>
+ </leafNode>
+ <leafNode name="multicast">
+ <properties>
+ <help>Monitor log for Multicast protocol</help>
+ </properties>
+ <command>journalctl --follow --boot /usr/lib/frr/pimd</command>
+ </leafNode>
+ <leafNode name="isis">
+ <properties>
+ <help>Monitor log for ISIS</help>
+ </properties>
+ <command>journalctl --follow --boot /usr/lib/frr/isisd</command>
+ </leafNode>
+ <leafNode name="nhrp">
+ <properties>
+ <help>Monitor log for NHRP</help>
+ </properties>
+ <command>journalctl --follow --boot /usr/lib/frr/nhrpd</command>
+ </leafNode>
+ <leafNode name="bfd">
+ <properties>
+ <help>Monitor log for BFD</help>
+ </properties>
+ <command>journalctl --follow --boot /usr/lib/frr/bfdd</command>
+ </leafNode>
+ <leafNode name="mpls">
+ <properties>
+ <help>Monitor log for MPLS</help>
+ </properties>
+ <command>journalctl --follow --boot /usr/lib/frr/ldpd</command>
+ </leafNode>
+ </children>
+ </node>
</children>
</node>
</children>
diff --git a/op-mode-definitions/show-log.xml.in b/op-mode-definitions/show-log.xml.in
index 2d75f119d..15bbc7f42 100644
--- a/op-mode-definitions/show-log.xml.in
+++ b/op-mode-definitions/show-log.xml.in
@@ -221,67 +221,67 @@
<properties>
<help>Show log for OSPF</help>
</properties>
- <command>journalctl -b /usr/lib/frr/ospfd</command>
+ <command>journalctl --boot /usr/lib/frr/ospfd</command>
</leafNode>
<leafNode name="ospfv3">
<properties>
<help>Show log for OSPF for IPv6</help>
</properties>
- <command>journalctl -b /usr/lib/frr/ospf6d</command>
+ <command>journalctl --boot /usr/lib/frr/ospf6d</command>
</leafNode>
<leafNode name="bgp">
<properties>
<help>Show log for BGP</help>
</properties>
- <command>journalctl -b /usr/lib/frr/bgpd</command>
+ <command>journalctl --boot /usr/lib/frr/bgpd</command>
</leafNode>
<leafNode name="rip">
<properties>
<help>Show log for RIP</help>
</properties>
- <command>journalctl -b /usr/lib/frr/ripd</command>
+ <command>journalctl --boot /usr/lib/frr/ripd</command>
</leafNode>
<leafNode name="ripng">
<properties>
<help>Show log for RIPng</help>
</properties>
- <command>journalctl -b /usr/lib/frr/ripngd</command>
+ <command>journalctl --boot /usr/lib/frr/ripngd</command>
</leafNode>
<leafNode name="static">
<properties>
<help>Show log for static route</help>
</properties>
- <command>journalctl -b /usr/lib/frr/staticd</command>
+ <command>journalctl --boot /usr/lib/frr/staticd</command>
</leafNode>
<leafNode name="multicast">
<properties>
<help>Show log for Multicast protocol</help>
</properties>
- <command>journalctl -b /usr/lib/frr/pimd</command>
+ <command>journalctl --boot /usr/lib/frr/pimd</command>
</leafNode>
<leafNode name="isis">
<properties>
<help>Show log for ISIS</help>
</properties>
- <command>journalctl -b /usr/lib/frr/isisd</command>
+ <command>journalctl --boot /usr/lib/frr/isisd</command>
</leafNode>
<leafNode name="nhrp">
<properties>
<help>Show log for NHRP</help>
</properties>
- <command>journalctl -b /usr/lib/frr/nhrpd</command>
+ <command>journalctl --boot /usr/lib/frr/nhrpd</command>
</leafNode>
<leafNode name="bfd">
<properties>
<help>Show log for BFD</help>
</properties>
- <command>journalctl -b /usr/lib/frr/bfdd</command>
+ <command>journalctl --boot /usr/lib/frr/bfdd</command>
</leafNode>
<leafNode name="mpls">
<properties>
<help>Show log for MPLS</help>
</properties>
- <command>journalctl -b /usr/lib/frr/ldpd</command>
+ <command>journalctl --boot /usr/lib/frr/ldpd</command>
</leafNode>
</children>
</node>
diff --git a/python/vyos/base.py b/python/vyos/base.py
index c78045548..fd22eaccd 100644
--- a/python/vyos/base.py
+++ b/python/vyos/base.py
@@ -15,6 +15,12 @@
from textwrap import fill
+class DeprecationWarning():
+ def __init__(self, message):
+ # Reformat the message and trim it to 72 characters in length
+ message = fill(message, width=72)
+ print(f'\nDEPRECATION WARNING: {message}\n')
+
class ConfigError(Exception):
def __init__(self, message):
# Reformat the message and trim it to 72 characters in length
diff --git a/python/vyos/configverify.py b/python/vyos/configverify.py
index 7f1258575..1062d51ee 100644
--- a/python/vyos/configverify.py
+++ b/python/vyos/configverify.py
@@ -178,31 +178,37 @@ def verify_eapol(config):
if 'certificate' not in ca_cert:
raise ConfigError('Invalid CA certificate specified for EAPoL')
-def verify_mirror(config):
+def verify_mirror_redirect(config):
"""
Common helper function used by interface implementations to perform
- recurring validation of mirror interface configuration.
+ recurring validation of mirror and redirect interface configuration via tc(8)
It makes no sense to mirror traffic back at yourself!
"""
+ import os
+ if {'mirror', 'redirect'} <= set(config):
+ raise ConfigError('Mirror and redirect can not be enabled at the same time!')
+
if 'mirror' in config:
for direction, mirror_interface in config['mirror'].items():
+ if not os.path.exists(f'/sys/class/net/{mirror_interface}'):
+ raise ConfigError(f'Requested mirror interface "{mirror_interface}" '\
+ 'does not exist!')
+
if mirror_interface == config['ifname']:
- raise ConfigError(f'Can not mirror "{direction}" traffic back ' \
+ raise ConfigError(f'Can not mirror "{direction}" traffic back '\
'the originating interface!')
-def verify_redirect(config):
- """
- Common helper function used by interface implementations to perform
- recurring validation of the redirect interface configuration.
-
- It makes no sense to mirror and redirect traffic at the same time!
- """
- if {'mirror', 'redirect'} <= set(config):
- raise ConfigError('Can not do both redirect and mirror')
+ if 'redirect' in config:
+ redirect_ifname = config['redirect']
+ if not os.path.exists(f'/sys/class/net/{redirect_ifname}'):
+ raise ConfigError(f'Requested redirect interface "{redirect_ifname}" '\
+ 'does not exist!')
if dict_search('traffic_policy.in', config) != None:
- raise ConfigError('Can not use ingress policy and redirect')
+ # XXX: support combination of limiting and redirect/mirror - this is an
+ # artificial limitation
+ raise ConfigError('Can not use ingress policy tigether with mirror or redirect!')
def verify_authentication(config):
"""
@@ -322,30 +328,37 @@ def verify_vlan_config(config):
if duplicate:
raise ConfigError(f'Duplicate VLAN id "{duplicate[0]}" used for vif and vif-s interfaces!')
+ parent_ifname = config['ifname']
# 802.1q VLANs
- for vlan in config.get('vif', {}):
- vlan = config['vif'][vlan]
+ for vlan_id in config.get('vif', {}):
+ vlan = config['vif'][vlan_id]
+ vlan['ifname'] = f'{parent_ifname}.{vlan_id}'
+
verify_dhcpv6(vlan)
verify_address(vlan)
verify_vrf(vlan)
- verify_redirect(vlan)
+ verify_mirror_redirect(vlan)
verify_mtu_parent(vlan, config)
# 802.1ad (Q-in-Q) VLANs
- for s_vlan in config.get('vif_s', {}):
- s_vlan = config['vif_s'][s_vlan]
+ for s_vlan_id in config.get('vif_s', {}):
+ s_vlan = config['vif_s'][s_vlan_id]
+ s_vlan['ifname'] = f'{parent_ifname}.{s_vlan_id}'
+
verify_dhcpv6(s_vlan)
verify_address(s_vlan)
verify_vrf(s_vlan)
- verify_redirect(s_vlan)
+ verify_mirror_redirect(s_vlan)
verify_mtu_parent(s_vlan, config)
- for c_vlan in s_vlan.get('vif_c', {}):
- c_vlan = s_vlan['vif_c'][c_vlan]
+ for c_vlan_id in s_vlan.get('vif_c', {}):
+ c_vlan = s_vlan['vif_c'][c_vlan_id]
+ c_vlan['ifname'] = f'{parent_ifname}.{s_vlan_id}.{c_vlan_id}'
+
verify_dhcpv6(c_vlan)
verify_address(c_vlan)
verify_vrf(c_vlan)
- verify_redirect(c_vlan)
+ verify_mirror_redirect(c_vlan)
verify_mtu_parent(c_vlan, config)
verify_mtu_parent(c_vlan, s_vlan)
diff --git a/python/vyos/firewall.py b/python/vyos/firewall.py
index 55ce318e7..ff8623592 100644
--- a/python/vyos/firewall.py
+++ b/python/vyos/firewall.py
@@ -174,7 +174,7 @@ def parse_rule(rule_conf, fw_name, rule_id, ip_name):
if 'limit' in rule_conf:
if 'rate' in rule_conf['limit']:
- output.append(f'limit rate {rule_conf["limit"]["rate"]}/second')
+ output.append(f'limit rate {rule_conf["limit"]["rate"]}')
if 'burst' in rule_conf['limit']:
output.append(f'burst {rule_conf["limit"]["burst"]} packets')
diff --git a/python/vyos/ifconfig/interface.py b/python/vyos/ifconfig/interface.py
index f39da90e4..6b0f08fd4 100755
--- a/python/vyos/ifconfig/interface.py
+++ b/python/vyos/ifconfig/interface.py
@@ -13,7 +13,6 @@
# You should have received a copy of the GNU Lesser General Public
# License along with this library. If not, see <http://www.gnu.org/licenses/>.
-from netifaces import interfaces
import os
import re
import json
@@ -39,7 +38,6 @@ from vyos.util import read_file
from vyos.util import get_interface_config
from vyos.util import get_interface_namespace
from vyos.util import is_systemd_service_active
-from vyos.util import is_ipv6_enabled
from vyos.template import is_ipv4
from vyos.template import is_ipv6
from vyos.validate import is_intf_addr_assigned
@@ -1081,12 +1079,6 @@ class Interface(Control):
if addr in self._addr:
return False
- addr_is_v4 = is_ipv4(addr)
-
- # Failsave - do not add IPv6 address if IPv6 is disabled
- if is_ipv6(addr) and not is_ipv6_enabled():
- return False
-
# add to interface
if addr == 'dhcp':
self.set_dhcp(True)
@@ -1294,48 +1286,57 @@ class Interface(Control):
if os.path.isfile(config_file):
os.remove(config_file)
- def set_mirror(self):
+ def set_mirror_redirect(self):
# Please refer to the document for details
# - https://man7.org/linux/man-pages/man8/tc.8.html
# - https://man7.org/linux/man-pages/man8/tc-mirred.8.html
# Depening if we are the source or the target interface of the port
# mirror we need to setup some variables.
source_if = self._config['ifname']
- config = self._config.get('mirror', None)
+ mirror_config = None
+ if 'mirror' in self._config:
+ mirror_config = self._config['mirror']
if 'is_mirror_intf' in self._config:
source_if = next(iter(self._config['is_mirror_intf']))
- config = self._config['is_mirror_intf'][source_if].get('mirror', None)
-
- # Check configuration stored by old perl code before delete T3782/T4056
- if not 'redirect' in self._config and not 'traffic_policy' in self._config:
- # Please do not clear the 'set $? = 0 '. It's meant to force a return of 0
- # Remove existing mirroring rules
- delete_tc_cmd = f'tc qdisc del dev {source_if} handle ffff: ingress 2> /dev/null;'
- delete_tc_cmd += f'tc qdisc del dev {source_if} handle 1: root prio 2> /dev/null;'
- delete_tc_cmd += 'set $?=0'
- self._popen(delete_tc_cmd)
-
- # Bail out early if nothing needs to be configured
- if not config:
- return
-
- for direction, mirror_if in config.items():
- if mirror_if not in interfaces():
- continue
-
- if direction == 'ingress':
- handle = 'ffff: ingress'
- parent = 'ffff:'
- elif direction == 'egress':
- handle = '1: root prio'
- parent = '1:'
-
- # Mirror egress traffic
- mirror_cmd = f'tc qdisc add dev {source_if} handle {handle}; '
- # Export the mirrored traffic to the interface
- mirror_cmd += f'tc filter add dev {source_if} parent {parent} protocol all prio 10 u32 match u32 0 0 flowid 1:1 action mirred egress mirror dev {mirror_if}'
- self._popen(mirror_cmd)
+ mirror_config = self._config['is_mirror_intf'][source_if].get('mirror', None)
+
+ redirect_config = None
+
+ # clear existing ingess - ignore errors (e.g. "Error: Cannot find specified
+ # qdisc on specified device") - we simply cleanup all stuff here
+ self._popen(f'tc qdisc del dev {source_if} parent ffff: 2>/dev/null');
+ self._popen(f'tc qdisc del dev {source_if} parent 1: 2>/dev/null');
+
+ # Apply interface mirror policy
+ if mirror_config:
+ for direction, target_if in mirror_config.items():
+ if direction == 'ingress':
+ handle = 'ffff: ingress'
+ parent = 'ffff:'
+ elif direction == 'egress':
+ handle = '1: root prio'
+ parent = '1:'
+
+ # Mirror egress traffic
+ mirror_cmd = f'tc qdisc add dev {source_if} handle {handle}; '
+ # Export the mirrored traffic to the interface
+ mirror_cmd += f'tc filter add dev {source_if} parent {parent} protocol '\
+ f'all prio 10 u32 match u32 0 0 flowid 1:1 action mirred '\
+ f'egress mirror dev {target_if}'
+ _, err = self._popen(mirror_cmd)
+ if err: print('tc qdisc(filter for mirror port failed')
+
+ # Apply interface traffic redirection policy
+ elif 'redirect' in self._config:
+ _, err = self._popen(f'tc qdisc add dev {source_if} handle ffff: ingress')
+ if err: print(f'tc qdisc add for redirect failed!')
+
+ target_if = self._config['redirect']
+ _, err = self._popen(f'tc filter add dev {source_if} parent ffff: protocol '\
+ f'all prio 10 u32 match u32 0 0 flowid 1:1 action mirred '\
+ f'egress redirect dev {target_if}')
+ if err: print('tc filter add for redirect failed')
def set_xdp(self, state):
"""
@@ -1434,9 +1435,6 @@ class Interface(Control):
else:
self.del_addr(addr)
- for addr in new_addr:
- self.add_addr(addr)
-
# start DHCPv6 client when only PD was configured
if dhcpv6pd:
self.set_dhcpv6(True)
@@ -1451,6 +1449,10 @@ class Interface(Control):
# checked before
self.set_vrf(config.get('vrf', ''))
+ # Add this section after vrf T4331
+ for addr in new_addr:
+ self.add_addr(addr)
+
# Configure MSS value for IPv4 TCP connections
tmp = dict_search('ip.adjust_mss', config)
value = tmp if (tmp != None) else '0'
@@ -1501,55 +1503,56 @@ class Interface(Control):
value = tmp if (tmp != None) else '0'
self.set_ipv4_source_validation(value)
- # Only change IPv6 parameters if IPv6 was not explicitly disabled
- if is_ipv6_enabled():
- # Configure MSS value for IPv6 TCP connections
- tmp = dict_search('ipv6.adjust_mss', config)
- value = tmp if (tmp != None) else '0'
- self.set_tcp_ipv6_mss(value)
-
- # IPv6 forwarding
- tmp = dict_search('ipv6.disable_forwarding', config)
- value = '0' if (tmp != None) else '1'
- self.set_ipv6_forwarding(value)
-
- # IPv6 router advertisements
- tmp = dict_search('ipv6.address.autoconf', config)
- value = '2' if (tmp != None) else '1'
- if 'dhcpv6' in new_addr:
- value = '2'
- self.set_ipv6_accept_ra(value)
-
- # IPv6 address autoconfiguration
- tmp = dict_search('ipv6.address.autoconf', config)
- value = '1' if (tmp != None) else '0'
- self.set_ipv6_autoconf(value)
-
- # IPv6 Duplicate Address Detection (DAD) tries
- tmp = dict_search('ipv6.dup_addr_detect_transmits', config)
- value = tmp if (tmp != None) else '1'
- self.set_ipv6_dad_messages(value)
-
- # Delete old IPv6 EUI64 addresses before changing MAC
- for addr in (dict_search('ipv6.address.eui64_old', config) or []):
- self.del_ipv6_eui64_address(addr)
-
- # Manage IPv6 link-local addresses
- if dict_search('ipv6.address.no_default_link_local', config) != None:
- self.del_ipv6_eui64_address('fe80::/64')
- else:
- self.add_ipv6_eui64_address('fe80::/64')
-
- # Add IPv6 EUI-based addresses
- tmp = dict_search('ipv6.address.eui64', config)
- if tmp:
- for addr in tmp:
- self.add_ipv6_eui64_address(addr)
-
- # MTU - Maximum Transfer Unit
+ # MTU - Maximum Transfer Unit has a default value. It must ALWAYS be set
+ # before mangling any IPv6 option. If MTU is less then 1280 IPv6 will be
+ # automatically disabled by the kernel. Also MTU must be increased before
+ # configuring any IPv6 address on the interface.
if 'mtu' in config:
self.set_mtu(config.get('mtu'))
+ # Configure MSS value for IPv6 TCP connections
+ tmp = dict_search('ipv6.adjust_mss', config)
+ value = tmp if (tmp != None) else '0'
+ self.set_tcp_ipv6_mss(value)
+
+ # IPv6 forwarding
+ tmp = dict_search('ipv6.disable_forwarding', config)
+ value = '0' if (tmp != None) else '1'
+ self.set_ipv6_forwarding(value)
+
+ # IPv6 router advertisements
+ tmp = dict_search('ipv6.address.autoconf', config)
+ value = '2' if (tmp != None) else '1'
+ if 'dhcpv6' in new_addr:
+ value = '2'
+ self.set_ipv6_accept_ra(value)
+
+ # IPv6 address autoconfiguration
+ tmp = dict_search('ipv6.address.autoconf', config)
+ value = '1' if (tmp != None) else '0'
+ self.set_ipv6_autoconf(value)
+
+ # IPv6 Duplicate Address Detection (DAD) tries
+ tmp = dict_search('ipv6.dup_addr_detect_transmits', config)
+ value = tmp if (tmp != None) else '1'
+ self.set_ipv6_dad_messages(value)
+
+ # Delete old IPv6 EUI64 addresses before changing MAC
+ for addr in (dict_search('ipv6.address.eui64_old', config) or []):
+ self.del_ipv6_eui64_address(addr)
+
+ # Manage IPv6 link-local addresses
+ if dict_search('ipv6.address.no_default_link_local', config) != None:
+ self.del_ipv6_eui64_address('fe80::/64')
+ else:
+ self.add_ipv6_eui64_address('fe80::/64')
+
+ # Add IPv6 EUI-based addresses
+ tmp = dict_search('ipv6.address.eui64', config)
+ if tmp:
+ for addr in tmp:
+ self.add_ipv6_eui64_address(addr)
+
# re-add ourselves to any bridge we might have fallen out of
if 'is_bridge_member' in config:
bridge_dict = config.get('is_bridge_member')
@@ -1558,8 +1561,8 @@ class Interface(Control):
# eXpress Data Path - highly experimental
self.set_xdp('xdp' in config)
- # configure port mirror
- self.set_mirror()
+ # configure interface mirror or redirection target
+ self.set_mirror_redirect()
# Enable/Disable of an interface must always be done at the end of the
# derived class to make use of the ref-counting set_admin_state()
@@ -1718,6 +1721,3 @@ class VLANIf(Interface):
return None
return super().set_admin_state(state)
-
- def set_mirror(self):
- return
diff --git a/python/vyos/ifconfig/loopback.py b/python/vyos/ifconfig/loopback.py
index 30c890fdf..b3babfadc 100644
--- a/python/vyos/ifconfig/loopback.py
+++ b/python/vyos/ifconfig/loopback.py
@@ -14,7 +14,6 @@
# License along with this library. If not, see <http://www.gnu.org/licenses/>.
from vyos.ifconfig.interface import Interface
-from vyos.util import is_ipv6_enabled
@Interface.register
class LoopbackIf(Interface):
@@ -58,15 +57,14 @@ class LoopbackIf(Interface):
interface setup code and provide a single point of entry when workin
on any interface. """
- addr = config.get('address', [])
-
+ address = config.get('address', [])
# We must ensure that the loopback addresses are never deleted from the system
- addr.append('127.0.0.1/8')
- if is_ipv6_enabled():
- addr.append('::1/128')
+ for tmp in self._persistent_addresses:
+ if tmp not in address:
+ address.append(tmp)
# Update IP address entry in our dictionary
- config.update({'address' : addr})
+ config.update({'address' : address})
# call base class
super().update(config)
diff --git a/python/vyos/template.py b/python/vyos/template.py
index dabf53692..132f5ddde 100644
--- a/python/vyos/template.py
+++ b/python/vyos/template.py
@@ -18,7 +18,7 @@ import os
from jinja2 import Environment
from jinja2 import FileSystemLoader
-
+from jinja2 import ChainableUndefined
from vyos.defaults import directories
from vyos.util import chmod
from vyos.util import chown
@@ -27,6 +27,7 @@ from vyos.util import makedir
# Holds template filters registered via register_filter()
_FILTERS = {}
+_TESTS = {}
# reuse Environments with identical settings to improve performance
@functools.lru_cache(maxsize=2)
@@ -42,8 +43,10 @@ def _get_environment(location=None):
cache_size=100,
loader=loc_loader,
trim_blocks=True,
+ undefined=ChainableUndefined,
)
env.filters.update(_FILTERS)
+ env.tests.update(_TESTS)
return env
@@ -67,6 +70,26 @@ def register_filter(name, func=None):
_FILTERS[name] = func
return func
+def register_test(name, func=None):
+ """Register a function to be available as test in templates under given name.
+
+ It can also be used as a decorator, see below in this module for examples.
+
+ :raise RuntimeError:
+ when trying to register a test after a template has been rendered already
+ :raise ValueError: when trying to register a name which was taken already
+ """
+ if func is None:
+ return functools.partial(register_test, name)
+ if _get_environment.cache_info().currsize:
+ raise RuntimeError(
+ "Tests can only be registered before rendering the first template"
+ )
+ if name in _TESTS:
+ raise ValueError(f"A test with name {name!r} was registered already")
+ _TESTS[name] = func
+ return func
+
def render_to_string(template, content, formater=None, location=None):
"""Render a template from the template directory, raise on any errors.
@@ -566,3 +589,55 @@ def nft_intra_zone_action(zone_conf, ipv6=False):
name = dict_search_args(intra_zone, 'firewall', fw_name)
return f'jump {name_prefix}{name}'
return 'return'
+
+@register_test('vyos_defined')
+def vyos_defined(value, test_value=None, var_type=None):
+ """
+ Jinja2 plugin to test if a variable is defined and not none - vyos_defined
+ will test value if defined and is not none and return true or false.
+
+ If test_value is supplied, the value must also pass == test_value to return true.
+ If var_type is supplied, the value must also be of the specified class/type
+
+ Examples:
+ 1. Test if var is defined and not none:
+ {% if foo is vyos_defined %}
+ ...
+ {% endif %}
+
+ 2. Test if variable is defined, not none and has value "something"
+ {% if bar is vyos_defined("something") %}
+ ...
+ {% endif %}
+
+ Parameters
+ ----------
+ value : any
+ Value to test from ansible
+ test_value : any, optional
+ Value to test in addition of defined and not none, by default None
+ var_type : ['float', 'int', 'str', 'list', 'dict', 'tuple', 'bool'], optional
+ Type or Class to test for
+
+ Returns
+ -------
+ boolean
+ True if variable matches criteria, False in other cases.
+
+ Implementation inspired and re-used from https://github.com/aristanetworks/ansible-avd/
+ """
+
+ from jinja2 import Undefined
+
+ if isinstance(value, Undefined) or value is None:
+ # Invalid value - return false
+ return False
+ elif test_value is not None and value != test_value:
+ # Valid value but not matching the optional argument
+ return False
+ elif str(var_type).lower() in ['float', 'int', 'str', 'list', 'dict', 'tuple', 'bool'] and str(var_type).lower() != type(value).__name__:
+ # Invalid class - return false
+ return False
+ else:
+ # Valid value and is matching optional argument if provided - return true
+ return True
diff --git a/python/vyos/util.py b/python/vyos/util.py
index f3f323c34..de55e108b 100644
--- a/python/vyos/util.py
+++ b/python/vyos/util.py
@@ -989,6 +989,11 @@ def is_wwan_connected(interface):
if not interface.startswith('wwan'):
raise ValueError(f'Specified interface "{interface}" is not a WWAN interface')
+ # ModemManager is required for connection(s) - if service is not running,
+ # there won't be any connection at all!
+ if not is_systemd_service_active('ModemManager.service'):
+ return False
+
modem = interface.lstrip('wwan')
tmp = cmd(f'mmcli --modem {modem} --output-json')
@@ -1019,7 +1024,3 @@ def sysctl_write(name, value):
call(f'sysctl -wq {name}={value}')
return True
return False
-
-def is_ipv6_enabled() -> bool:
- """ Check if IPv6 support on the system is enabled or not """
- return (sysctl_read('net.ipv6.conf.all.disable_ipv6') == '0')
diff --git a/smoketest/configs/dialup-router-complex b/smoketest/configs/dialup-router-complex
index 1b62deb5c..ac5ff5e99 100644
--- a/smoketest/configs/dialup-router-complex
+++ b/smoketest/configs/dialup-router-complex
@@ -498,6 +498,9 @@ firewall {
destination {
port 110,995
}
+ limit {
+ rate "10/minute"
+ }
protocol tcp
}
rule 123 {
diff --git a/smoketest/configs/ipv6-disable b/smoketest/configs/ipv6-disable
new file mode 100644
index 000000000..da41e9020
--- /dev/null
+++ b/smoketest/configs/ipv6-disable
@@ -0,0 +1,83 @@
+interfaces {
+ ethernet eth0 {
+ duplex auto
+ smp-affinity auto
+ speed auto
+ vif 201 {
+ address 172.18.201.10/24
+ }
+ vif 202 {
+ address 172.18.202.10/24
+ }
+ vif 203 {
+ address 172.18.203.10/24
+ }
+ vif 204 {
+ address 172.18.204.10/24
+ }
+ }
+}
+protocols {
+ static {
+ route 0.0.0.0/0 {
+ next-hop 172.18.201.254 {
+ distance 10
+ }
+ next-hop 172.18.202.254 {
+ distance 20
+ }
+ next-hop 172.18.203.254 {
+ distance 30
+ }
+ next-hop 172.18.204.254 {
+ distance 40
+ }
+ }
+ }
+}
+system {
+ config-management {
+ commit-revisions 200
+ }
+ console {
+ device ttyS0 {
+ speed 115200
+ }
+ }
+ domain-name vyos.net
+ host-name vyos
+ ipv6 {
+ disable
+ }
+ login {
+ user vyos {
+ authentication {
+ encrypted-password $6$2Ta6TWHd/U$NmrX0x9kexCimeOcYK1MfhMpITF9ELxHcaBU/znBq.X2ukQOj61fVI2UYP/xBzP4QtiTcdkgs7WOQMHWsRymO/
+ plaintext-password ""
+ }
+ level admin
+ }
+ }
+ name-server 172.16.254.20
+ name-server 172.16.254.30
+ ntp {
+ server 172.16.254.20 {
+ }
+ server 172.16.254.30 {
+ }
+ }
+ syslog {
+ global {
+ facility all {
+ level info
+ }
+ facility protocols {
+ level debug
+ }
+ }
+ }
+}
+
+/* Warning: Do not remove the following line. */
+/* === vyatta-config-version: "broadcast-relay@1:cluster@1:config-management@1:conntrack-sync@1:conntrack@1:dhcp-relay@2:dhcp-server@5:dns-forwarding@1:firewall@5:ipsec@5:l2tp@1:mdns@1:nat@4:ntp@1:pptp@1:qos@1:quagga@6:snmp@1:ssh@1:system@9:vrrp@2:wanloadbalance@3:webgui@1:webproxy@1:webproxy@2:zone-policy@1" === */
+/* Release version: 1.2.6 */
diff --git a/smoketest/scripts/cli/test_firewall.py b/smoketest/scripts/cli/test_firewall.py
index ecc0c29a0..16b020e07 100755
--- a/smoketest/scripts/cli/test_firewall.py
+++ b/smoketest/scripts/cli/test_firewall.py
@@ -88,6 +88,10 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase):
self.cli_set(['firewall', 'name', 'smoketest', 'rule', '2', 'destination', 'port', '8888'])
self.cli_set(['firewall', 'name', 'smoketest', 'rule', '2', 'tcp', 'flags', 'syn'])
self.cli_set(['firewall', 'name', 'smoketest', 'rule', '2', 'tcp', 'flags', 'not', 'ack'])
+ self.cli_set(['firewall', 'name', 'smoketest', 'rule', '3', 'action', 'accept'])
+ self.cli_set(['firewall', 'name', 'smoketest', 'rule', '3', 'protocol', 'tcp'])
+ self.cli_set(['firewall', 'name', 'smoketest', 'rule', '3', 'destination', 'port', '22'])
+ self.cli_set(['firewall', 'name', 'smoketest', 'rule', '3', 'limit', 'rate', '5/minute'])
self.cli_set(['interfaces', 'ethernet', 'eth0', 'firewall', 'in', 'name', 'smoketest'])
@@ -97,6 +101,7 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase):
['iifname "eth0"', 'jump NAME_smoketest'],
['saddr 172.16.20.10', 'daddr 172.16.10.10', 'return'],
['tcp flags & (syn | ack) == syn', 'tcp dport { 8888 }', 'reject'],
+ ['tcp dport { 22 }', 'limit rate 5/minute', 'return'],
['smoketest default-action', 'drop']
]
diff --git a/smoketest/scripts/cli/test_policy.py b/smoketest/scripts/cli/test_policy.py
index 0acd41903..b232a2241 100755
--- a/smoketest/scripts/cli/test_policy.py
+++ b/smoketest/scripts/cli/test_policy.py
@@ -665,6 +665,40 @@ class TestPolicy(VyOSUnitTestSHIM.TestCase):
self.assertIn(tmp, config)
+ def test_prefix_list_duplicates(self):
+ # FRR does not allow to specify the same profix list rule multiple times
+ #
+ # vyos(config)# ip prefix-list foo seq 10 permit 192.0.2.0/24
+ # vyos(config)# ip prefix-list foo seq 20 permit 192.0.2.0/24
+ # % Configuration failed.
+ # Error type: validation
+ # Error description: duplicated prefix list value: 192.0.2.0/24
+
+ # There is also a VyOS verify() function to test this
+
+ prefix = '100.64.0.0/10'
+ prefix_list = 'duplicates'
+ test_range = range(20, 25)
+ path = base_path + ['prefix-list', prefix_list]
+
+ for rule in test_range:
+ self.cli_set(path + ['rule', str(rule), 'action', 'permit'])
+ self.cli_set(path + ['rule', str(rule), 'prefix', prefix])
+
+ # Duplicate prefixes
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+
+ for rule in test_range:
+ self.cli_set(path + ['rule', str(rule), 'le', str(rule)])
+
+ self.cli_commit()
+
+ config = self.getFRRconfig('ip prefix-list', end='')
+ for rule in test_range:
+ tmp = f'ip prefix-list {prefix_list} seq {rule} permit {prefix} le {rule}'
+ self.assertIn(tmp, config)
+
def test_route_map(self):
access_list = '50'
as_path_list = '100'
diff --git a/smoketest/scripts/cli/test_protocols_bgp.py b/smoketest/scripts/cli/test_protocols_bgp.py
index db1587ba7..f1db5350a 100755
--- a/smoketest/scripts/cli/test_protocols_bgp.py
+++ b/smoketest/scripts/cli/test_protocols_bgp.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021 VyOS maintainers and contributors
+# Copyright (C) 2021-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
@@ -36,112 +36,118 @@ bfd_profile = 'foo-bar-baz'
neighbor_config = {
'192.0.2.1' : {
- 'bfd' : '',
- 'cap_dynamic' : '',
- 'cap_ext_next' : '',
- 'remote_as' : '100',
- 'adv_interv' : '400',
- 'passive' : '',
- 'password' : 'VyOS-Secure123',
- 'shutdown' : '',
- 'cap_over' : '',
- 'ttl_security' : '5',
- 'local_as' : '300',
- 'route_map_in' : route_map_in,
- 'route_map_out': route_map_out,
+ 'bfd' : '',
+ 'cap_dynamic' : '',
+ 'cap_ext_next' : '',
+ 'remote_as' : '100',
+ 'adv_interv' : '400',
+ 'passive' : '',
+ 'password' : 'VyOS-Secure123',
+ 'shutdown' : '',
+ 'cap_over' : '',
+ 'ttl_security' : '5',
+ 'local_as' : '300',
+ 'route_map_in' : route_map_in,
+ 'route_map_out' : route_map_out,
'no_send_comm_ext' : '',
- 'addpath_all' : '',
+ 'addpath_all' : '',
},
'192.0.2.2' : {
- 'bfd_profile' : bfd_profile,
- 'remote_as' : '200',
- 'shutdown' : '',
- 'no_cap_nego' : '',
- 'port' : '667',
- 'cap_strict' : '',
- 'advertise_map': route_map_in,
- 'non_exist_map': route_map_out,
- 'pfx_list_in' : prefix_list_in,
- 'pfx_list_out' : prefix_list_out,
+ 'bfd_profile' : bfd_profile,
+ 'remote_as' : '200',
+ 'shutdown' : '',
+ 'no_cap_nego' : '',
+ 'port' : '667',
+ 'cap_strict' : '',
+ 'advertise_map' : route_map_in,
+ 'non_exist_map' : route_map_out,
+ 'pfx_list_in' : prefix_list_in,
+ 'pfx_list_out' : prefix_list_out,
'no_send_comm_std' : '',
},
'192.0.2.3' : {
- 'advertise_map': route_map_in,
- 'description' : 'foo bar baz',
- 'remote_as' : '200',
- 'passive' : '',
- 'multi_hop' : '5',
- 'update_src' : 'lo',
- 'peer_group' : 'foo',
+ 'advertise_map' : route_map_in,
+ 'description' : 'foo bar baz',
+ 'remote_as' : '200',
+ 'passive' : '',
+ 'multi_hop' : '5',
+ 'update_src' : 'lo',
+ 'peer_group' : 'foo',
+ 'graceful_rst' : '',
},
'2001:db8::1' : {
- 'advertise_map': route_map_in,
- 'exist_map' : route_map_out,
- 'cap_dynamic' : '',
- 'cap_ext_next' : '',
- 'remote_as' : '123',
- 'adv_interv' : '400',
- 'passive' : '',
- 'password' : 'VyOS-Secure123',
- 'shutdown' : '',
- 'cap_over' : '',
- 'ttl_security' : '5',
- 'local_as' : '300',
- 'solo' : '',
- 'route_map_in' : route_map_in,
- 'route_map_out': route_map_out,
+ 'advertise_map' : route_map_in,
+ 'exist_map' : route_map_out,
+ 'cap_dynamic' : '',
+ 'cap_ext_next' : '',
+ 'remote_as' : '123',
+ 'adv_interv' : '400',
+ 'passive' : '',
+ 'password' : 'VyOS-Secure123',
+ 'shutdown' : '',
+ 'cap_over' : '',
+ 'ttl_security' : '5',
+ 'local_as' : '300',
+ 'solo' : '',
+ 'route_map_in' : route_map_in,
+ 'route_map_out' : route_map_out,
'no_send_comm_std' : '',
'addpath_per_as' : '',
- 'peer_group' : 'foo-bar',
+ 'peer_group' : 'foo-bar',
},
'2001:db8::2' : {
- 'remote_as' : '456',
- 'shutdown' : '',
- 'no_cap_nego' : '',
- 'port' : '667',
- 'cap_strict' : '',
- 'pfx_list_in' : prefix_list_in6,
- 'pfx_list_out' : prefix_list_out6,
+ 'remote_as' : '456',
+ 'shutdown' : '',
+ 'no_cap_nego' : '',
+ 'port' : '667',
+ 'cap_strict' : '',
+ 'pfx_list_in' : prefix_list_in6,
+ 'pfx_list_out' : prefix_list_out6,
'no_send_comm_ext' : '',
- 'peer_group' : 'foo-bar_baz',
+ 'peer_group' : 'foo-bar_baz',
+ 'graceful_rst_hlp' : ''
},
}
peer_group_config = {
'foo' : {
- 'advertise_map': route_map_in,
- 'exist_map' : route_map_out,
- 'bfd' : '',
- 'remote_as' : '100',
- 'passive' : '',
- 'password' : 'VyOS-Secure123',
- 'shutdown' : '',
- 'cap_over' : '',
- 'ttl_security': '5',
+ 'advertise_map' : route_map_in,
+ 'exist_map' : route_map_out,
+ 'bfd' : '',
+ 'remote_as' : '100',
+ 'passive' : '',
+ 'password' : 'VyOS-Secure123',
+ 'shutdown' : '',
+ 'cap_over' : '',
+ 'ttl_security' : '5',
+ },
+ 'bar' : {
+ 'remote_as' : '111',
+ 'graceful_rst_no' : ''
},
'foo-bar' : {
- 'advertise_map': route_map_in,
- 'description' : 'foo peer bar group',
- 'remote_as' : '200',
- 'shutdown' : '',
- 'no_cap_nego' : '',
- 'local_as' : '300',
- 'pfx_list_in' : prefix_list_in,
- 'pfx_list_out' : prefix_list_out,
+ 'advertise_map' : route_map_in,
+ 'description' : 'foo peer bar group',
+ 'remote_as' : '200',
+ 'shutdown' : '',
+ 'no_cap_nego' : '',
+ 'local_as' : '300',
+ 'pfx_list_in' : prefix_list_in,
+ 'pfx_list_out' : prefix_list_out,
'no_send_comm_ext' : '',
},
'foo-bar_baz' : {
- 'advertise_map': route_map_in,
- 'non_exist_map': route_map_out,
- 'bfd_profile' : bfd_profile,
- 'cap_dynamic' : '',
- 'cap_ext_next' : '',
- 'remote_as' : '200',
- 'passive' : '',
- 'multi_hop' : '5',
- 'update_src' : 'lo',
- 'route_map_in' : route_map_in,
- 'route_map_out': route_map_out,
+ 'advertise_map' : route_map_in,
+ 'non_exist_map' : route_map_out,
+ 'bfd_profile' : bfd_profile,
+ 'cap_dynamic' : '',
+ 'cap_ext_next' : '',
+ 'remote_as' : '200',
+ 'passive' : '',
+ 'multi_hop' : '5',
+ 'update_src' : 'lo',
+ 'route_map_in' : route_map_in,
+ 'route_map_out' : route_map_out,
},
}
@@ -239,6 +245,12 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase):
if 'non_exist_map' in peer_config:
base = f'{base} non-exist-map {peer_config["non_exist_map"]}'
self.assertIn(base, frrconfig)
+ if 'graceful_rst' in peer_config:
+ self.assertIn(f' neighbor {peer} graceful-restart', frrconfig)
+ if 'graceful_rst_no' in peer_config:
+ self.assertIn(f' neighbor {peer} graceful-restart-disable', frrconfig)
+ if 'graceful_rst_hlp' in peer_config:
+ self.assertIn(f' neighbor {peer} graceful-restart-helper', frrconfig)
def test_bgp_01_simple(self):
router_id = '127.0.0.1'
@@ -320,6 +332,8 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase):
def test_bgp_02_neighbors(self):
# Test out individual neighbor configuration items, not all of them are
# also available to a peer-group!
+ self.cli_set(base_path + ['parameters', 'deterministic-med'])
+
for peer, peer_config in neighbor_config.items():
afi = 'ipv4-unicast'
if is_ipv6(peer):
@@ -380,6 +394,12 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase):
self.cli_set(base_path + ['neighbor', peer, 'address-family', afi, 'addpath-tx-all'])
if 'addpath_per_as' in peer_config:
self.cli_set(base_path + ['neighbor', peer, 'address-family', afi, 'addpath-tx-per-as'])
+ if 'graceful_rst' in peer_config:
+ self.cli_set(base_path + ['neighbor', peer, 'graceful-restart', 'enable'])
+ if 'graceful_rst_no' in peer_config:
+ self.cli_set(base_path + ['neighbor', peer, 'graceful-restart', 'disable'])
+ if 'graceful_rst_hlp' in peer_config:
+ self.cli_set(base_path + ['neighbor', peer, 'graceful-restart', 'restart-helper'])
# Conditional advertisement
if 'advertise_map' in peer_config:
@@ -462,6 +482,12 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase):
self.cli_set(base_path + ['peer-group', peer_group, 'address-family', 'ipv4-unicast', 'addpath-tx-all'])
if 'addpath_per_as' in config:
self.cli_set(base_path + ['peer-group', peer_group, 'address-family', 'ipv4-unicast', 'addpath-tx-per-as'])
+ if 'graceful_rst' in config:
+ self.cli_set(base_path + ['peer-group', peer_group, 'graceful-restart', 'enable'])
+ if 'graceful_rst_no' in config:
+ self.cli_set(base_path + ['peer-group', peer_group, 'graceful-restart', 'disable'])
+ if 'graceful_rst_hlp' in config:
+ self.cli_set(base_path + ['peer-group', peer_group, 'graceful-restart', 'restart-helper'])
# Conditional advertisement
if 'advertise_map' in config:
@@ -481,6 +507,7 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase):
if 'peer_group' in peer_config:
self.cli_set(base_path + ['neighbor', peer, 'peer-group', peer_config['peer_group']])
+
# commit changes
self.cli_commit()
@@ -856,4 +883,4 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase):
self.assertIn(f' exit-address-family', afi_config)
if __name__ == '__main__':
- unittest.main(verbosity=2)
+ unittest.main(verbosity=2, failfast=True)
diff --git a/smoketest/scripts/cli/test_protocols_isis.py b/smoketest/scripts/cli/test_protocols_isis.py
index 7f51c7178..11c765793 100755
--- a/smoketest/scripts/cli/test_protocols_isis.py
+++ b/smoketest/scripts/cli/test_protocols_isis.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021 VyOS maintainers and contributors
+# Copyright (C) 2021-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
@@ -35,6 +35,10 @@ class TestProtocolsISIS(VyOSUnitTestSHIM.TestCase):
# call base-classes classmethod
super(cls, 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):
self.cli_delete(base_path)
self.cli_commit()
@@ -71,13 +75,13 @@ class TestProtocolsISIS(VyOSUnitTestSHIM.TestCase):
self.cli_commit()
# Verify all changes
- tmp = self.getFRRconfig(f'router isis {domain}')
+ tmp = self.getFRRconfig(f'router isis {domain}', daemon='isisd')
self.assertIn(f' net {net}', tmp)
self.assertIn(f' log-adjacency-changes', tmp)
self.assertIn(f' redistribute ipv4 connected level-2 route-map {route_map}', tmp)
for interface in self._interfaces:
- tmp = self.getFRRconfig(f'interface {interface}')
+ tmp = self.getFRRconfig(f'interface {interface}', daemon='isisd')
self.assertIn(f' ip router isis {domain}', tmp)
self.assertIn(f' ipv6 router isis {domain}', tmp)
@@ -104,11 +108,11 @@ class TestProtocolsISIS(VyOSUnitTestSHIM.TestCase):
self.cli_commit()
# Verify FRR isisd configuration
- tmp = self.getFRRconfig(f'router isis {domain}')
+ tmp = self.getFRRconfig(f'router isis {domain}', daemon='isisd')
self.assertIn(f'router isis {domain}', tmp)
self.assertIn(f' net {net}', tmp)
- tmp = self.getFRRconfig(f'router isis {domain} vrf {vrf}')
+ tmp = self.getFRRconfig(f'router isis {domain} vrf {vrf}', daemon='isisd')
self.assertIn(f'router isis {domain} vrf {vrf}', tmp)
self.assertIn(f' net {net}', tmp)
@@ -124,22 +128,26 @@ class TestProtocolsISIS(VyOSUnitTestSHIM.TestCase):
self.isis_base_config()
self.cli_set(base_path + ['redistribute', 'ipv4', 'connected', 'level-2', 'route-map', route_map])
self.cli_set(base_path + ['route-map', route_map])
+ self.cli_set(base_path + ['level', 'level-2'])
# commit changes
self.cli_commit()
# Verify FRR configuration
zebra_route_map = f'ip protocol isis route-map {route_map}'
- frrconfig = self.getFRRconfig(zebra_route_map)
+ frrconfig = self.getFRRconfig(zebra_route_map, daemon='zebra')
self.assertIn(zebra_route_map, frrconfig)
+ tmp = self.getFRRconfig(f'router isis {domain}', daemon='isisd')
+ self.assertIn(' is-type level-2-only', tmp)
+
# Remove the route-map again
self.cli_delete(base_path + ['route-map'])
# commit changes
self.cli_commit()
# Verify FRR configuration
- frrconfig = self.getFRRconfig(zebra_route_map)
+ frrconfig = self.getFRRconfig(zebra_route_map, daemon='zebra')
self.assertNotIn(zebra_route_map, frrconfig)
self.cli_delete(['policy', 'route-map', route_map])
@@ -159,7 +167,7 @@ class TestProtocolsISIS(VyOSUnitTestSHIM.TestCase):
self.cli_commit()
# Verify all changes
- tmp = self.getFRRconfig(f'router isis {domain}')
+ tmp = self.getFRRconfig(f'router isis {domain}', daemon='isisd')
self.assertIn(f' net {net}', tmp)
for afi in ['ipv4', 'ipv6']:
@@ -172,6 +180,8 @@ class TestProtocolsISIS(VyOSUnitTestSHIM.TestCase):
password = 'foo'
self.isis_base_config()
+ for interface in self._interfaces:
+ self.cli_set(base_path + ['interface', interface, 'password', 'plaintext-password', f'{password}-{interface}'])
self.cli_set(base_path + ['area-password', 'plaintext-password', password])
self.cli_set(base_path + ['area-password', 'md5', password])
@@ -192,11 +202,14 @@ class TestProtocolsISIS(VyOSUnitTestSHIM.TestCase):
self.cli_commit()
# Verify all changes
- tmp = self.getFRRconfig(f'router isis {domain}')
+ tmp = self.getFRRconfig(f'router isis {domain}', daemon='isisd')
self.assertIn(f' net {net}', tmp)
self.assertIn(f' domain-password clear {password}', tmp)
self.assertIn(f' area-password clear {password}', tmp)
+ for interface in self._interfaces:
+ tmp = self.getFRRconfig(f'interface {interface}', daemon='isisd')
+ self.assertIn(f' isis password clear {password}-{interface}', tmp)
def test_isis_06_spf_delay_bfd(self):
network = 'point-to-point'
@@ -237,12 +250,12 @@ class TestProtocolsISIS(VyOSUnitTestSHIM.TestCase):
self.cli_commit()
# Verify all changes
- tmp = self.getFRRconfig(f'router isis {domain}')
+ tmp = self.getFRRconfig(f'router isis {domain}', daemon='isisd')
self.assertIn(f' net {net}', tmp)
self.assertIn(f' spf-delay-ietf init-delay {init_delay} short-delay {short_delay} long-delay {long_delay} holddown {holddown} time-to-learn {time_to_learn}', tmp)
for interface in self._interfaces:
- tmp = self.getFRRconfig(f'interface {interface}')
+ tmp = self.getFRRconfig(f'interface {interface}', daemon='isisd')
self.assertIn(f' ip router isis {domain}', tmp)
self.assertIn(f' ipv6 router isis {domain}', tmp)
self.assertIn(f' isis network {network}', tmp)
diff --git a/smoketest/scripts/cli/test_protocols_ospf.py b/smoketest/scripts/cli/test_protocols_ospf.py
index 5d8e9cff2..e433d06d0 100755
--- a/smoketest/scripts/cli/test_protocols_ospf.py
+++ b/smoketest/scripts/cli/test_protocols_ospf.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021 VyOS maintainers and contributors
+# Copyright (C) 2021-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
@@ -40,6 +40,10 @@ class TestProtocolsOSPF(VyOSUnitTestSHIM.TestCase):
cls.cli_set(cls, ['policy', 'route-map', route_map, 'rule', '10', 'action', 'permit'])
cls.cli_set(cls, ['policy', 'route-map', route_map, 'rule', '20', 'action', 'permit'])
+ # ensure we can also run this test on a live system - so lets clean
+ # out the current configuration :)
+ cls.cli_delete(cls, base_path)
+
@classmethod
def tearDownClass(cls):
cls.cli_delete(cls, ['policy', 'route-map', route_map])
diff --git a/smoketest/scripts/cli/test_protocols_ospfv3.py b/smoketest/scripts/cli/test_protocols_ospfv3.py
index 2fc694fd7..944190089 100755
--- a/smoketest/scripts/cli/test_protocols_ospfv3.py
+++ b/smoketest/scripts/cli/test_protocols_ospfv3.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021 VyOS maintainers and contributors
+# Copyright (C) 2021-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
@@ -38,6 +38,10 @@ class TestProtocolsOSPFv3(VyOSUnitTestSHIM.TestCase):
cls.cli_set(cls, ['policy', 'route-map', route_map, 'rule', '10', 'action', 'permit'])
cls.cli_set(cls, ['policy', 'route-map', route_map, 'rule', '20', 'action', 'permit'])
+ # ensure we can also run this test on a live system - so lets clean
+ # out the current configuration :)
+ cls.cli_delete(cls, base_path)
+
@classmethod
def tearDownClass(cls):
cls.cli_delete(cls, ['policy', 'route-map', route_map])
@@ -70,7 +74,7 @@ class TestProtocolsOSPFv3(VyOSUnitTestSHIM.TestCase):
self.cli_commit()
# Verify FRR ospfd configuration
- frrconfig = self.getFRRconfig('router ospf6')
+ frrconfig = self.getFRRconfig('router ospf6', daemon='ospf6d')
self.assertIn(f'router ospf6', frrconfig)
self.assertIn(f' area {default_area} range {prefix}', frrconfig)
self.assertIn(f' ospf6 router-id {router_id}', frrconfig)
@@ -78,7 +82,7 @@ class TestProtocolsOSPFv3(VyOSUnitTestSHIM.TestCase):
self.assertIn(f' area {default_area} export-list {acl_name}', frrconfig)
for interface in interfaces:
- if_config = self.getFRRconfig(f'interface {interface}')
+ if_config = self.getFRRconfig(f'interface {interface}', daemon='ospf6d')
self.assertIn(f'ipv6 ospf6 area {default_area}', if_config)
self.cli_delete(['policy', 'access-list6', acl_name])
@@ -99,7 +103,7 @@ class TestProtocolsOSPFv3(VyOSUnitTestSHIM.TestCase):
self.cli_commit()
# Verify FRR ospfd configuration
- frrconfig = self.getFRRconfig('router ospf6')
+ frrconfig = self.getFRRconfig('router ospf6', daemon='ospf6d')
self.assertIn(f'router ospf6', frrconfig)
self.assertIn(f' distance {dist_global}', frrconfig)
self.assertIn(f' distance ospf6 intra-area {dist_intra_area} inter-area {dist_inter_area} external {dist_external}', frrconfig)
@@ -119,7 +123,7 @@ class TestProtocolsOSPFv3(VyOSUnitTestSHIM.TestCase):
self.cli_commit()
# Verify FRR ospfd configuration
- frrconfig = self.getFRRconfig('router ospf6')
+ frrconfig = self.getFRRconfig('router ospf6', daemon='ospf6d')
self.assertIn(f'router ospf6', frrconfig)
for protocol in redistribute:
self.assertIn(f' redistribute {protocol} route-map {route_map}', frrconfig)
@@ -150,13 +154,13 @@ class TestProtocolsOSPFv3(VyOSUnitTestSHIM.TestCase):
self.cli_commit()
# Verify FRR ospfd configuration
- frrconfig = self.getFRRconfig('router ospf6')
+ frrconfig = self.getFRRconfig('router ospf6', daemon='ospf6d')
self.assertIn(f'router ospf6', frrconfig)
cost = '100'
priority = '10'
for interface in interfaces:
- if_config = self.getFRRconfig(f'interface {interface}')
+ if_config = self.getFRRconfig(f'interface {interface}', daemon='ospf6d')
self.assertIn(f'interface {interface}', if_config)
self.assertIn(f' ipv6 ospf6 bfd', if_config)
self.assertIn(f' ipv6 ospf6 bfd profile {bfd_profile}', if_config)
@@ -180,7 +184,7 @@ class TestProtocolsOSPFv3(VyOSUnitTestSHIM.TestCase):
self.cli_commit()
# Verify FRR ospfd configuration
- frrconfig = self.getFRRconfig('router ospf6')
+ frrconfig = self.getFRRconfig('router ospf6', daemon='ospf6d')
self.assertIn(f'router ospf6', frrconfig)
self.assertIn(f' area {area_stub} stub', frrconfig)
self.assertIn(f' area {area_stub_nosum} stub no-summary', frrconfig)
@@ -206,7 +210,7 @@ class TestProtocolsOSPFv3(VyOSUnitTestSHIM.TestCase):
self.cli_commit()
# Verify FRR ospfd configuration
- frrconfig = self.getFRRconfig('router ospf6')
+ frrconfig = self.getFRRconfig('router ospf6', daemon='ospf6d')
self.assertIn(f'router ospf6', frrconfig)
self.assertIn(f' area {area_nssa} nssa', frrconfig)
self.assertIn(f' area {area_nssa_nosum} nssa default-information-originate no-summary', frrconfig)
@@ -226,7 +230,7 @@ class TestProtocolsOSPFv3(VyOSUnitTestSHIM.TestCase):
self.cli_commit()
# Verify FRR ospfd configuration
- frrconfig = self.getFRRconfig('router ospf6')
+ frrconfig = self.getFRRconfig('router ospf6', daemon='ospf6d')
self.assertIn(f'router ospf6', frrconfig)
self.assertIn(f' default-information originate metric {metric} metric-type {metric_type} route-map {route_map}', frrconfig)
@@ -235,7 +239,7 @@ class TestProtocolsOSPFv3(VyOSUnitTestSHIM.TestCase):
self.cli_commit()
# Verify FRR ospfd configuration
- frrconfig = self.getFRRconfig('router ospf6')
+ frrconfig = self.getFRRconfig('router ospf6', daemon='ospf6d')
self.assertIn(f' default-information originate always metric {metric} metric-type {metric_type} route-map {route_map}', frrconfig)
@@ -261,15 +265,15 @@ class TestProtocolsOSPFv3(VyOSUnitTestSHIM.TestCase):
self.cli_commit()
# Verify FRR ospfd configuration
- frrconfig = self.getFRRconfig('router ospf6')
+ frrconfig = self.getFRRconfig('router ospf6', daemon='ospf6d')
self.assertIn(f'router ospf6', frrconfig)
self.assertIn(f' ospf6 router-id {router_id}', frrconfig)
- frrconfig = self.getFRRconfig(f'interface {vrf_iface}')
+ frrconfig = self.getFRRconfig(f'interface {vrf_iface}', daemon='ospf6d')
self.assertIn(f'interface {vrf_iface}', frrconfig)
self.assertIn(f' ipv6 ospf6 bfd', frrconfig)
- frrconfig = self.getFRRconfig(f'router ospf6 vrf {vrf}')
+ frrconfig = self.getFRRconfig(f'router ospf6 vrf {vrf}', daemon='ospf6d')
self.assertIn(f'router ospf6 vrf {vrf}', frrconfig)
self.assertIn(f' ospf6 router-id {router_id_vrf}', frrconfig)
diff --git a/smoketest/scripts/cli/test_service_https.py b/smoketest/scripts/cli/test_service_https.py
index 8e69efd9c..9413d22d1 100755
--- a/smoketest/scripts/cli/test_service_https.py
+++ b/smoketest/scripts/cli/test_service_https.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2020 VyOS maintainers and contributors
+# Copyright (C) 2019-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
@@ -15,15 +15,39 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import unittest
+import urllib3
+
+from requests import request
from base_vyostest_shim import VyOSUnitTestSHIM
+from vyos.util import read_file
from vyos.util import run
-base_path = ['service', 'https']
+urllib3.disable_warnings()
+base_path = ['service', 'https']
pki_base = ['pki']
-cert_data = 'MIICFDCCAbugAwIBAgIUfMbIsB/ozMXijYgUYG80T1ry+mcwCgYIKoZIzj0EAwIwWTELMAkGA1UEBhMCR0IxEzARBgNVBAgMClNvbWUtU3RhdGUxEjAQBgNVBAcMCVNvbWUtQ2l0eTENMAsGA1UECgwEVnlPUzESMBAGA1UEAwwJVnlPUyBUZXN0MB4XDTIxMDcyMDEyNDUxMloXDTI2MDcxOTEyNDUxMlowWTELMAkGA1UEBhMCR0IxEzARBgNVBAgMClNvbWUtU3RhdGUxEjAQBgNVBAcMCVNvbWUtQ2l0eTENMAsGA1UECgwEVnlPUzESMBAGA1UEAwwJVnlPUyBUZXN0MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE01HrLcNttqq4/PtoMua8rMWEkOdBu7vP94xzDO7A8C92ls1v86eePy4QllKCzIw3QxBIoCuH2peGRfWgPRdFsKNhMF8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMB0GA1UdDgQWBBSu+JnU5ZC4mkuEpqg2+Mk4K79oeDAKBggqhkjOPQQDAgNHADBEAiBEFdzQ/Bc3LftzngrY605UhA6UprHhAogKgROv7iR4QgIgEFUxTtW3xXJcnUPWhhUFhyZoqfn8dE93+dm/LDnp7C0='
-key_data = 'MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgPLpD0Ohhoq0g4nhx2KMIuze7ucKUt/lBEB2wc03IxXyhRANCAATTUestw222qrj8+2gy5rysxYSQ50G7u8/3jHMM7sDwL3aWzW/zp54/LhCWUoLMjDdDEEigK4fal4ZF9aA9F0Ww'
+
+cert_data = """
+MIICFDCCAbugAwIBAgIUfMbIsB/ozMXijYgUYG80T1ry+mcwCgYIKoZIzj0EAwIw
+WTELMAkGA1UEBhMCR0IxEzARBgNVBAgMClNvbWUtU3RhdGUxEjAQBgNVBAcMCVNv
+bWUtQ2l0eTENMAsGA1UECgwEVnlPUzESMBAGA1UEAwwJVnlPUyBUZXN0MB4XDTIx
+MDcyMDEyNDUxMloXDTI2MDcxOTEyNDUxMlowWTELMAkGA1UEBhMCR0IxEzARBgNV
+BAgMClNvbWUtU3RhdGUxEjAQBgNVBAcMCVNvbWUtQ2l0eTENMAsGA1UECgwEVnlP
+UzESMBAGA1UEAwwJVnlPUyBUZXN0MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE
+01HrLcNttqq4/PtoMua8rMWEkOdBu7vP94xzDO7A8C92ls1v86eePy4QllKCzIw3
+QxBIoCuH2peGRfWgPRdFsKNhMF8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E
+BAMCAYYwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMB0GA1UdDgQWBBSu
++JnU5ZC4mkuEpqg2+Mk4K79oeDAKBggqhkjOPQQDAgNHADBEAiBEFdzQ/Bc3Lftz
+ngrY605UhA6UprHhAogKgROv7iR4QgIgEFUxTtW3xXJcnUPWhhUFhyZoqfn8dE93
++dm/LDnp7C0=
+"""
+
+key_data = """
+MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgPLpD0Ohhoq0g4nhx
+2KMIuze7ucKUt/lBEB2wc03IxXyhRANCAATTUestw222qrj8+2gy5rysxYSQ50G7
+u8/3jHMM7sDwL3aWzW/zp54/LhCWUoLMjDdDEEigK4fal4ZF9aA9F0Ww
+"""
class TestHTTPSService(VyOSUnitTestSHIM.TestCase):
def setUp(self):
@@ -61,9 +85,13 @@ class TestHTTPSService(VyOSUnitTestSHIM.TestCase):
ret = run('sudo /usr/sbin/nginx -t')
self.assertEqual(ret, 0)
+ nginx_config = read_file('/etc/nginx/sites-enabled/default')
+ self.assertIn(f'listen {address}:{port} ssl;', nginx_config)
+ self.assertIn(f'ssl_protocols TLSv1.2 TLSv1.3;', nginx_config)
+
def test_certificate(self):
- self.cli_set(pki_base + ['certificate', 'test_https', 'certificate', cert_data])
- self.cli_set(pki_base + ['certificate', 'test_https', 'private', 'key', key_data])
+ self.cli_set(pki_base + ['certificate', 'test_https', 'certificate', cert_data.replace('\n','')])
+ self.cli_set(pki_base + ['certificate', 'test_https', 'private', 'key', key_data.replace('\n','')])
self.cli_set(base_path + ['certificates', 'certificate', 'test_https'])
@@ -72,5 +100,43 @@ class TestHTTPSService(VyOSUnitTestSHIM.TestCase):
ret = run('sudo /usr/sbin/nginx -t')
self.assertEqual(ret, 0)
+ def test_api_auth(self):
+ vhost_id = 'example'
+ address = '127.0.0.1'
+ port = '443'
+ name = 'localhost'
+
+ self.cli_set(base_path + ['api', 'socket'])
+ key = 'MySuperSecretVyOS'
+ self.cli_set(base_path + ['api', 'keys', 'id', 'key-01', 'key', key])
+
+ test_path = base_path + ['virtual-host', vhost_id]
+ self.cli_set(test_path + ['listen-address', address])
+ self.cli_set(test_path + ['listen-port', port])
+ self.cli_set(test_path + ['server-name', name])
+
+ self.cli_commit()
+
+ nginx_config = read_file('/etc/nginx/sites-enabled/default')
+ self.assertIn(f'listen {address}:{port} ssl;', nginx_config)
+ self.assertIn(f'ssl_protocols TLSv1.2 TLSv1.3;', nginx_config)
+
+ url = f'https://{address}/retrieve'
+ payload = {'data': '{"op": "showConfig", "path": []}', 'key': f'{key}'}
+ headers = {}
+ r = request('POST', url, verify=False, headers=headers, data=payload)
+ # Must get HTTP code 200 on success
+ self.assertEqual(r.status_code, 200)
+
+ payload_invalid = {'data': '{"op": "showConfig", "path": []}', 'key': 'invalid'}
+ r = request('POST', url, verify=False, headers=headers, data=payload_invalid)
+ # Must get HTTP code 401 on invalid key (Unauthorized)
+ self.assertEqual(r.status_code, 401)
+
+ payload_no_key = {'data': '{"op": "showConfig", "path": []}'}
+ r = request('POST', url, verify=False, headers=headers, data=payload_no_key)
+ # Must get HTTP code 401 on missing key (Unauthorized)
+ self.assertEqual(r.status_code, 401)
+
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_service_ssh.py b/smoketest/scripts/cli/test_service_ssh.py
index a54c03919..9ed263655 100755
--- a/smoketest/scripts/cli/test_service_ssh.py
+++ b/smoketest/scripts/cli/test_service_ssh.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2020 VyOS maintainers and contributors
+# Copyright (C) 2019-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
@@ -15,13 +15,17 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
+import paramiko
import re
import unittest
+from pwd import getpwall
+
from base_vyostest_shim import VyOSUnitTestSHIM
from vyos.configsession import ConfigSessionError
from vyos.util import cmd
+from vyos.util import is_systemd_service_running
from vyos.util import process_named_running
from vyos.util import read_file
@@ -49,6 +53,9 @@ class TestServiceSSH(VyOSUnitTestSHIM.TestCase):
cls.cli_delete(cls, base_path)
def tearDown(self):
+ # Check for running process
+ self.assertTrue(process_named_running(PROCESS_NAME))
+
# delete testing SSH config
self.cli_delete(base_path)
self.cli_commit()
@@ -57,6 +64,11 @@ class TestServiceSSH(VyOSUnitTestSHIM.TestCase):
self.assertTrue(os.path.isfile(key_dsa))
self.assertTrue(os.path.isfile(key_ed25519))
+ # Established SSH connections remains running after service is stopped.
+ # We can not use process_named_running here - we rather need to check
+ # that the systemd service is no longer running
+ self.assertFalse(is_systemd_service_running(PROCESS_NAME))
+
def test_ssh_default(self):
# Check if SSH service runs with default settings - used for checking
# behavior of <defaultValue> in XML definition
@@ -69,9 +81,6 @@ class TestServiceSSH(VyOSUnitTestSHIM.TestCase):
port = get_config_value('Port')[0]
self.assertEqual('22', port)
- # Check for running process
- self.assertTrue(process_named_running(PROCESS_NAME))
-
def test_ssh_single_listen_address(self):
# Check if SSH service can be configured and runs
self.cli_set(base_path + ['port', '1234'])
@@ -108,9 +117,6 @@ class TestServiceSSH(VyOSUnitTestSHIM.TestCase):
keepalive = get_config_value('ClientAliveInterval')[0]
self.assertTrue("100" in keepalive)
- # Check for running process
- self.assertTrue(process_named_running(PROCESS_NAME))
-
def test_ssh_multiple_listen_addresses(self):
# Check if SSH service can be configured and runs with multiple
# listen ports and listen-addresses
@@ -135,9 +141,6 @@ class TestServiceSSH(VyOSUnitTestSHIM.TestCase):
for address in addresses:
self.assertIn(address, tmp)
- # Check for running process
- self.assertTrue(process_named_running(PROCESS_NAME))
-
def test_ssh_vrf(self):
# Check if SSH service can be bound to given VRF
port = '22'
@@ -157,9 +160,6 @@ class TestServiceSSH(VyOSUnitTestSHIM.TestCase):
tmp = get_config_value('Port')
self.assertIn(port, tmp)
- # Check for running process
- self.assertTrue(process_named_running(PROCESS_NAME))
-
# Check for process in VRF
tmp = cmd(f'ip vrf pids {vrf}')
self.assertIn(PROCESS_NAME, tmp)
@@ -167,5 +167,51 @@ class TestServiceSSH(VyOSUnitTestSHIM.TestCase):
# delete VRF
self.cli_delete(['vrf', 'name', vrf])
+ def test_ssh_login(self):
+ # Perform SSH login and command execution with a predefined user. The
+ # result (output of uname -a) must match the output if the command is
+ # run natively.
+ #
+ # We also try to login as an invalid user - this is not allowed to work.
+
+ def ssh_send_cmd(command, username, password, host='localhost'):
+ """ SSH command execution helper """
+ # Try to login via SSH
+ ssh_client = paramiko.SSHClient()
+ ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
+ ssh_client.connect(hostname='localhost', username=username, password=password)
+ _, stdout, stderr = ssh_client.exec_command(command)
+ output = stdout.read().decode().strip()
+ error = stderr.read().decode().strip()
+ ssh_client.close()
+ return output, error
+
+ test_user = 'ssh_test'
+ test_pass = 'v2i57DZs8idUwMN3VC92'
+ test_command = 'uname -a'
+
+ self.cli_set(base_path)
+ self.cli_set(['system', 'login', 'user', test_user, 'authentication', 'plaintext-password', test_pass])
+
+ # commit changes
+ self.cli_commit()
+
+ # Login with proper credentials
+ output, error = ssh_send_cmd(test_command, test_user, test_pass)
+ # verify login
+ self.assertFalse(error)
+ self.assertEqual(output, cmd(test_command))
+
+ # Login with invalid credentials
+ with self.assertRaises(paramiko.ssh_exception.AuthenticationException):
+ output, error = ssh_send_cmd(test_command, 'invalid_user', 'invalid_password')
+
+ self.cli_delete(['system', 'login', 'user', test_user])
+ self.cli_commit()
+
+ # After deletion the test user is not allowed to remain in /etc/passwd
+ usernames = [x[0] for x in getpwall()]
+ self.assertNotIn(test_user, usernames)
+
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_system_ipv6.py b/smoketest/scripts/cli/test_system_ipv6.py
index 837d1dc12..c8aea9100 100755
--- a/smoketest/scripts/cli/test_system_ipv6.py
+++ b/smoketest/scripts/cli/test_system_ipv6.py
@@ -20,7 +20,6 @@ from base_vyostest_shim import VyOSUnitTestSHIM
from vyos.template import is_ipv4
from vyos.util import read_file
-from vyos.util import is_ipv6_enabled
from vyos.util import get_interface_config
from vyos.validate import is_intf_addr_assigned
@@ -46,41 +45,6 @@ class TestSystemIPv6(VyOSUnitTestSHIM.TestCase):
self.assertEqual(read_file(file_forwarding), '0')
- def test_system_ipv6_disable(self):
- # Verify previous "enable" state
- self.assertEqual(read_file(file_disable), '0')
- self.assertTrue(is_ipv6_enabled())
-
- loopbacks = ['127.0.0.1', '::1']
- for addr in loopbacks:
- self.assertTrue(is_intf_addr_assigned('lo', addr))
-
- # Do not assign any IPv6 address on interfaces, this requires a reboot
- # which can not be tested, but we can read the config file :)
- self.cli_set(base_path + ['disable'])
- self.cli_commit()
-
- # Verify configuration file
- self.assertEqual(read_file(file_disable), '1')
- self.assertFalse(is_ipv6_enabled())
-
- for addr in loopbacks:
- if is_ipv4(addr):
- self.assertTrue(is_intf_addr_assigned('lo', addr))
- else:
- self.assertFalse(is_intf_addr_assigned('lo', addr))
-
- # T4330: Verify MTU can be changed with IPv6 disabled
- mtu = '1600'
- eth_if = 'eth0'
- self.cli_set(['interfaces', 'ethernet', eth_if, 'mtu', mtu])
- self.cli_commit()
-
- tmp = get_interface_config(eth_if)
- self.assertEqual(tmp['mtu'], int(mtu))
-
- self.cli_delete(['interfaces', 'ethernet', eth_if, 'mtu'])
-
def test_system_ipv6_strict_dad(self):
# This defaults to 1
self.assertEqual(read_file(file_dad), '1')
diff --git a/smoketest/scripts/cli/test_system_login.py b/smoketest/scripts/cli/test_system_login.py
index 095300de3..1131b6f93 100755
--- a/smoketest/scripts/cli/test_system_login.py
+++ b/smoketest/scripts/cli/test_system_login.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2020 VyOS maintainers and contributors
+# Copyright (C) 2019-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
@@ -23,6 +23,7 @@ from base_vyostest_shim import VyOSUnitTestSHIM
from distutils.version import LooseVersion
from platform import release as kernel_version
from subprocess import Popen, PIPE
+from pwd import getpwall
from vyos.configsession import ConfigSessionError
from vyos.util import cmd
@@ -52,6 +53,11 @@ class TestSystemLogin(VyOSUnitTestSHIM.TestCase):
self.cli_commit()
+ # After deletion, a user is not allowed to remain in /etc/passwd
+ usernames = [x[0] for x in getpwall()]
+ for user in users:
+ self.assertNotIn(user, usernames)
+
def test_add_linux_system_user(self):
# We are not allowed to re-use a username already taken by the Linux
# base system
diff --git a/smoketest/scripts/cli/test_vrf.py b/smoketest/scripts/cli/test_vrf.py
index 5daea589c..c591d6cf5 100755
--- a/smoketest/scripts/cli/test_vrf.py
+++ b/smoketest/scripts/cli/test_vrf.py
@@ -131,41 +131,6 @@ class VRFTest(VyOSUnitTestSHIM.TestCase):
for addr in loopbacks:
self.assertTrue(is_intf_addr_assigned(vrf, addr))
- def test_vrf_loopbacks_no_ipv6(self):
- table = '2002'
- for vrf in vrfs:
- base = base_path + ['name', vrf]
- self.cli_set(base + ['table', str(table)])
- table = str(int(table) + 1)
-
- # Globally disable IPv6 - this will remove all IPv6 interface addresses
- self.cli_set(['system', 'ipv6', 'disable'])
-
- # commit changes
- self.cli_commit()
-
- # Verify VRF configuration
- table = '2002'
- loopbacks = ['127.0.0.1', '::1']
- for vrf in vrfs:
- # Ensure VRF was created
- self.assertIn(vrf, interfaces())
-
- # Verify VRF table ID
- tmp = get_interface_config(vrf)
- self.assertEqual(int(table), tmp['linkinfo']['info_data']['table'])
-
- # Test for proper loopback IP assignment
- for addr in loopbacks:
- if is_ipv4(addr):
- self.assertTrue(is_intf_addr_assigned(vrf, addr))
- else:
- self.assertFalse(is_intf_addr_assigned(vrf, addr))
-
- table = str(int(table) + 1)
-
- self.cli_delete(['system', 'ipv6'])
-
def test_vrf_bind_all(self):
table = '2000'
for vrf in vrfs:
@@ -216,11 +181,11 @@ class VRFTest(VyOSUnitTestSHIM.TestCase):
# commit changes
self.cli_commit()
- # Verify & cleanup
+ # Verify VRF assignmant
for interface in self._interfaces:
- # os.readlink resolves to: '../../../../../virtual/net/foovrf'
- tmp = os.readlink(f'/sys/class/net/{interface}/master').split('/')[-1]
- self.assertEqual(tmp, vrf)
+ tmp = get_interface_config(interface)
+ self.assertEqual(vrf, tmp['master'])
+
# cleanup
section = Section.section(interface)
self.cli_delete(['interfaces', section, interface, 'vrf'])
@@ -262,5 +227,45 @@ class VRFTest(VyOSUnitTestSHIM.TestCase):
# Increment table ID for the next run
table = str(int(table) + 1)
+ def test_vrf_link_local_ip_addresses(self):
+ # Testcase for issue T4331
+ table = '100'
+ vrf = 'orange'
+ interface = 'dum9998'
+ addresses = ['192.0.2.1/26', '2001:db8:9998::1/64', 'fe80::1/64']
+
+ for address in addresses:
+ self.cli_set(['interfaces', 'dummy', interface, 'address', address])
+
+ # Create dummy interfaces
+ self.cli_commit()
+
+ # ... and verify IP addresses got assigned
+ for address in addresses:
+ self.assertTrue(is_intf_addr_assigned(interface, address))
+
+ # Move interface to VRF
+ self.cli_set(base_path + ['name', vrf, 'table', table])
+ self.cli_set(['interfaces', 'dummy', interface, 'vrf', vrf])
+
+ # Apply VRF config
+ self.cli_commit()
+ # Ensure VRF got created
+ self.assertIn(vrf, interfaces())
+ # ... and IP addresses are still assigned
+ for address in addresses:
+ self.assertTrue(is_intf_addr_assigned(interface, address))
+ # Verify VRF table ID
+ tmp = get_interface_config(vrf)
+ self.assertEqual(int(table), tmp['linkinfo']['info_data']['table'])
+
+ # Verify interface is assigned to VRF
+ tmp = get_interface_config(interface)
+ self.assertEqual(vrf, tmp['master'])
+
+ # Delete Interface
+ self.cli_delete(['interfaces', 'dummy', interface])
+ self.cli_commit()
+
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/src/conf_mode/dhcp_server.py b/src/conf_mode/dhcp_server.py
index a8cef5ebf..d27f8d995 100755
--- a/src/conf_mode/dhcp_server.py
+++ b/src/conf_mode/dhcp_server.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2021 VyOS maintainers and contributors
+# Copyright (C) 2018-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
@@ -109,7 +109,7 @@ def get_config(config=None):
if not conf.exists(base):
return None
- dhcp = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True)
+ dhcp = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True, no_tag_node_value_mangle=True)
# T2665: defaults include lease time per TAG node which need to be added to
# individual subnet definitions
default_values = defaults(base + ['shared-network-name', 'subnet'])
diff --git a/src/conf_mode/dhcpv6_server.py b/src/conf_mode/dhcpv6_server.py
index e6a2e4486..be1e6db1e 100755
--- a/src/conf_mode/dhcpv6_server.py
+++ b/src/conf_mode/dhcpv6_server.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2020 VyOS maintainers and contributors
+# Copyright (C) 2018-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
@@ -41,7 +41,7 @@ def get_config(config=None):
if not conf.exists(base):
return None
- dhcpv6 = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True)
+ dhcpv6 = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True, no_tag_node_value_mangle=True)
return dhcpv6
def verify(dhcpv6):
diff --git a/src/conf_mode/dns_forwarding.py b/src/conf_mode/dns_forwarding.py
index 23a16df63..fa9b21f20 100755
--- a/src/conf_mode/dns_forwarding.py
+++ b/src/conf_mode/dns_forwarding.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2020 VyOS maintainers and contributors
+# Copyright (C) 2018-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
@@ -16,6 +16,7 @@
import os
+from netifaces import interfaces
from sys import exit
from glob import glob
@@ -65,10 +66,6 @@ def get_config(config=None):
if conf.exists(base_nameservers):
dns.update({'system_name_server': conf.return_values(base_nameservers)})
- base_nameservers_dhcp = ['system', 'name-servers-dhcp']
- if conf.exists(base_nameservers_dhcp):
- dns.update({'system_name_server_dhcp': conf.return_values(base_nameservers_dhcp)})
-
if 'authoritative_domain' in dns:
dns['authoritative_zones'] = []
dns['authoritative_zone_errors'] = []
@@ -272,9 +269,8 @@ def verify(dns):
raise ConfigError('Invalid authoritative records have been defined')
if 'system' in dns:
- if not ('system_name_server' in dns or 'system_name_server_dhcp' in dns):
- print("Warning: No 'system name-server' or 'system " \
- "name-servers-dhcp' configured")
+ if not 'system_name_server' in dns:
+ print('Warning: No "system name-server" configured')
return None
@@ -339,10 +335,15 @@ def apply(dns):
hc.delete_name_server_tags_recursor(['system'])
# add dhcp nameserver tags for configured interfaces
- if 'system_name_server_dhcp' in dns:
- for interface in dns['system_name_server_dhcp']:
- hc.add_name_server_tags_recursor(['dhcp-' + interface,
- 'dhcpv6-' + interface ])
+ if 'system_name_server' in dns:
+ for interface in dns['system_name_server']:
+ # system_name_server key contains both IP addresses and interface
+ # names (DHCP) to use DNS servers. We need to check if the
+ # value is an interface name - only if this is the case, add the
+ # interface based DNS forwarder.
+ if interface in interfaces():
+ hc.add_name_server_tags_recursor(['dhcp-' + interface,
+ 'dhcpv6-' + interface ])
# hostsd will generate the forward-zones file
# the list and keys() are required as get returns a dict, not list
diff --git a/src/conf_mode/firewall.py b/src/conf_mode/firewall.py
index 41df1b84a..f33198a49 100755
--- a/src/conf_mode/firewall.py
+++ b/src/conf_mode/firewall.py
@@ -171,6 +171,12 @@ def verify_rule(firewall, rule_conf, ipv6):
if {'match_frag', 'match_non_frag'} <= set(rule_conf['fragment']):
raise ConfigError('Cannot specify both "match-frag" and "match-non-frag"')
+ if 'limit' in rule_conf:
+ if 'rate' in rule_conf['limit']:
+ rate_int = re.sub(r'\D', '', rule_conf['limit']['rate'])
+ if int(rate_int) < 1:
+ raise ConfigError('Limit rate integer cannot be less than 1')
+
if 'ipsec' in rule_conf:
if {'match_ipsec', 'match_non_ipsec'} <= set(rule_conf['ipsec']):
raise ConfigError('Cannot specify both "match-ipsec" and "match-non-ipsec"')
diff --git a/src/conf_mode/interfaces-bonding.py b/src/conf_mode/interfaces-bonding.py
index 661dc2298..ad5a0f499 100755
--- a/src/conf_mode/interfaces-bonding.py
+++ b/src/conf_mode/interfaces-bonding.py
@@ -27,9 +27,8 @@ from vyos.configdict import is_source_interface
from vyos.configverify import verify_address
from vyos.configverify import verify_bridge_delete
from vyos.configverify import verify_dhcpv6
-from vyos.configverify import verify_mirror
+from vyos.configverify import verify_mirror_redirect
from vyos.configverify import verify_mtu_ipv6
-from vyos.configverify import verify_redirect
from vyos.configverify import verify_source_interface
from vyos.configverify import verify_vlan_config
from vyos.configverify import verify_vrf
@@ -151,8 +150,7 @@ def verify(bond):
verify_address(bond)
verify_dhcpv6(bond)
verify_vrf(bond)
- verify_mirror(bond)
- verify_redirect(bond)
+ verify_mirror_redirect(bond)
# use common function to verify VLAN configuration
verify_vlan_config(bond)
diff --git a/src/conf_mode/interfaces-bridge.py b/src/conf_mode/interfaces-bridge.py
index e16c0e9f4..b1f7e6d7c 100755
--- a/src/conf_mode/interfaces-bridge.py
+++ b/src/conf_mode/interfaces-bridge.py
@@ -27,8 +27,7 @@ from vyos.configdict import is_source_interface
from vyos.configdict import has_vlan_subinterface_configured
from vyos.configdict import dict_merge
from vyos.configverify import verify_dhcpv6
-from vyos.configverify import verify_mirror
-from vyos.configverify import verify_redirect
+from vyos.configverify import verify_mirror_redirect
from vyos.configverify import verify_vrf
from vyos.ifconfig import BridgeIf
from vyos.validate import has_address_configured
@@ -107,8 +106,7 @@ def verify(bridge):
verify_dhcpv6(bridge)
verify_vrf(bridge)
- verify_mirror(bridge)
- verify_redirect(bridge)
+ verify_mirror_redirect(bridge)
ifname = bridge['ifname']
diff --git a/src/conf_mode/interfaces-dummy.py b/src/conf_mode/interfaces-dummy.py
index 4072c4452..4a1eb7b93 100755
--- a/src/conf_mode/interfaces-dummy.py
+++ b/src/conf_mode/interfaces-dummy.py
@@ -21,7 +21,7 @@ from vyos.configdict import get_interface_dict
from vyos.configverify import verify_vrf
from vyos.configverify import verify_address
from vyos.configverify import verify_bridge_delete
-from vyos.configverify import verify_redirect
+from vyos.configverify import verify_mirror_redirect
from vyos.ifconfig import DummyIf
from vyos import ConfigError
from vyos import airbag
@@ -47,7 +47,7 @@ def verify(dummy):
verify_vrf(dummy)
verify_address(dummy)
- verify_redirect(dummy)
+ verify_mirror_redirect(dummy)
return None
diff --git a/src/conf_mode/interfaces-ethernet.py b/src/conf_mode/interfaces-ethernet.py
index 3eeddf190..6aea7a80e 100755
--- a/src/conf_mode/interfaces-ethernet.py
+++ b/src/conf_mode/interfaces-ethernet.py
@@ -25,10 +25,9 @@ from vyos.configverify import verify_address
from vyos.configverify import verify_dhcpv6
from vyos.configverify import verify_eapol
from vyos.configverify import verify_interface_exists
-from vyos.configverify import verify_mirror
+from vyos.configverify import verify_mirror_redirect
from vyos.configverify import verify_mtu
from vyos.configverify import verify_mtu_ipv6
-from vyos.configverify import verify_redirect
from vyos.configverify import verify_vlan_config
from vyos.configverify import verify_vrf
from vyos.ethtool import Ethtool
@@ -84,8 +83,7 @@ def verify(ethernet):
verify_address(ethernet)
verify_vrf(ethernet)
verify_eapol(ethernet)
- verify_mirror(ethernet)
- verify_redirect(ethernet)
+ verify_mirror_redirect(ethernet)
ethtool = Ethtool(ifname)
# No need to check speed and duplex keys as both have default values.
diff --git a/src/conf_mode/interfaces-geneve.py b/src/conf_mode/interfaces-geneve.py
index a94b5e1f7..3a668226b 100755
--- a/src/conf_mode/interfaces-geneve.py
+++ b/src/conf_mode/interfaces-geneve.py
@@ -24,7 +24,7 @@ from vyos.configdict import get_interface_dict
from vyos.configverify import verify_address
from vyos.configverify import verify_mtu_ipv6
from vyos.configverify import verify_bridge_delete
-from vyos.configverify import verify_redirect
+from vyos.configverify import verify_mirror_redirect
from vyos.ifconfig import GeneveIf
from vyos import ConfigError
@@ -51,7 +51,7 @@ def verify(geneve):
verify_mtu_ipv6(geneve)
verify_address(geneve)
- verify_redirect(geneve)
+ verify_mirror_redirect(geneve)
if 'remote' not in geneve:
raise ConfigError('Remote side must be configured')
diff --git a/src/conf_mode/interfaces-l2tpv3.py b/src/conf_mode/interfaces-l2tpv3.py
index 5ea7159dc..22256bf4f 100755
--- a/src/conf_mode/interfaces-l2tpv3.py
+++ b/src/conf_mode/interfaces-l2tpv3.py
@@ -25,7 +25,7 @@ from vyos.configdict import leaf_node_changed
from vyos.configverify import verify_address
from vyos.configverify import verify_bridge_delete
from vyos.configverify import verify_mtu_ipv6
-from vyos.configverify import verify_redirect
+from vyos.configverify import verify_mirror_redirect
from vyos.ifconfig import L2TPv3If
from vyos.util import check_kmod
from vyos.validate import is_addr_assigned
@@ -77,7 +77,7 @@ def verify(l2tpv3):
verify_mtu_ipv6(l2tpv3)
verify_address(l2tpv3)
- verify_redirect(l2tpv3)
+ verify_mirror_redirect(l2tpv3)
return None
def generate(l2tpv3):
diff --git a/src/conf_mode/interfaces-loopback.py b/src/conf_mode/interfaces-loopback.py
index e6a851113..e4bc15bb5 100755
--- a/src/conf_mode/interfaces-loopback.py
+++ b/src/conf_mode/interfaces-loopback.py
@@ -20,7 +20,7 @@ from sys import exit
from vyos.config import Config
from vyos.configdict import get_interface_dict
-from vyos.configverify import verify_redirect
+from vyos.configverify import verify_mirror_redirect
from vyos.ifconfig import LoopbackIf
from vyos import ConfigError
from vyos import airbag
@@ -40,7 +40,7 @@ def get_config(config=None):
return loopback
def verify(loopback):
- verify_redirect(loopback)
+ verify_mirror_redirect(loopback)
return None
def generate(loopback):
diff --git a/src/conf_mode/interfaces-macsec.py b/src/conf_mode/interfaces-macsec.py
index 6a29fdb11..96fc1c41c 100755
--- a/src/conf_mode/interfaces-macsec.py
+++ b/src/conf_mode/interfaces-macsec.py
@@ -29,7 +29,7 @@ from vyos.configverify import verify_vrf
from vyos.configverify import verify_address
from vyos.configverify import verify_bridge_delete
from vyos.configverify import verify_mtu_ipv6
-from vyos.configverify import verify_redirect
+from vyos.configverify import verify_mirror_redirect
from vyos.configverify import verify_source_interface
from vyos import ConfigError
from vyos import airbag
@@ -67,7 +67,7 @@ def verify(macsec):
verify_vrf(macsec)
verify_mtu_ipv6(macsec)
verify_address(macsec)
- verify_redirect(macsec)
+ verify_mirror_redirect(macsec)
if not (('security' in macsec) and
('cipher' in macsec['security'])):
diff --git a/src/conf_mode/interfaces-openvpn.py b/src/conf_mode/interfaces-openvpn.py
index 8f9c0b3f1..83d1c6d9b 100755
--- a/src/conf_mode/interfaces-openvpn.py
+++ b/src/conf_mode/interfaces-openvpn.py
@@ -35,6 +35,7 @@ from vyos.configdict import get_interface_dict
from vyos.configdict import leaf_node_changed
from vyos.configverify import verify_vrf
from vyos.configverify import verify_bridge_delete
+from vyos.configverify import verify_mirror_redirect
from vyos.ifconfig import VTunIf
from vyos.pki import load_dh_parameters
from vyos.pki import load_private_key
@@ -495,6 +496,7 @@ def verify(openvpn):
raise ConfigError('Username for authentication is missing')
verify_vrf(openvpn)
+ verify_mirror_redirect(openvpn)
return None
diff --git a/src/conf_mode/interfaces-pppoe.py b/src/conf_mode/interfaces-pppoe.py
index 9962e0a08..bfb1fadd5 100755
--- a/src/conf_mode/interfaces-pppoe.py
+++ b/src/conf_mode/interfaces-pppoe.py
@@ -28,7 +28,7 @@ from vyos.configverify import verify_source_interface
from vyos.configverify import verify_interface_exists
from vyos.configverify import verify_vrf
from vyos.configverify import verify_mtu_ipv6
-from vyos.configverify import verify_redirect
+from vyos.configverify import verify_mirror_redirect
from vyos.ifconfig import PPPoEIf
from vyos.template import render
from vyos.util import call
@@ -86,7 +86,7 @@ def verify(pppoe):
verify_authentication(pppoe)
verify_vrf(pppoe)
verify_mtu_ipv6(pppoe)
- verify_redirect(pppoe)
+ verify_mirror_redirect(pppoe)
if {'connect_on_demand', 'vrf'} <= set(pppoe):
raise ConfigError('On-demand dialing and VRF can not be used at the same time')
diff --git a/src/conf_mode/interfaces-pseudo-ethernet.py b/src/conf_mode/interfaces-pseudo-ethernet.py
index f57e41cc4..f2c85554f 100755
--- a/src/conf_mode/interfaces-pseudo-ethernet.py
+++ b/src/conf_mode/interfaces-pseudo-ethernet.py
@@ -25,7 +25,7 @@ from vyos.configverify import verify_bridge_delete
from vyos.configverify import verify_source_interface
from vyos.configverify import verify_vlan_config
from vyos.configverify import verify_mtu_parent
-from vyos.configverify import verify_redirect
+from vyos.configverify import verify_mirror_redirect
from vyos.ifconfig import MACVLANIf
from vyos import ConfigError
@@ -61,7 +61,7 @@ def verify(peth):
verify_vrf(peth)
verify_address(peth)
verify_mtu_parent(peth, peth['parent'])
- verify_redirect(peth)
+ verify_mirror_redirect(peth)
# use common function to verify VLAN configuration
verify_vlan_config(peth)
diff --git a/src/conf_mode/interfaces-tunnel.py b/src/conf_mode/interfaces-tunnel.py
index 005fae5eb..f4668d976 100755
--- a/src/conf_mode/interfaces-tunnel.py
+++ b/src/conf_mode/interfaces-tunnel.py
@@ -26,7 +26,7 @@ from vyos.configverify import verify_address
from vyos.configverify import verify_bridge_delete
from vyos.configverify import verify_interface_exists
from vyos.configverify import verify_mtu_ipv6
-from vyos.configverify import verify_redirect
+from vyos.configverify import verify_mirror_redirect
from vyos.configverify import verify_vrf
from vyos.configverify import verify_tunnel
from vyos.ifconfig import Interface
@@ -158,7 +158,7 @@ def verify(tunnel):
verify_mtu_ipv6(tunnel)
verify_address(tunnel)
verify_vrf(tunnel)
- verify_redirect(tunnel)
+ verify_mirror_redirect(tunnel)
if 'source_interface' in tunnel:
verify_interface_exists(tunnel['source_interface'])
diff --git a/src/conf_mode/interfaces-vti.py b/src/conf_mode/interfaces-vti.py
index 30e13536f..f06fdff1b 100755
--- a/src/conf_mode/interfaces-vti.py
+++ b/src/conf_mode/interfaces-vti.py
@@ -19,7 +19,7 @@ from sys import exit
from vyos.config import Config
from vyos.configdict import get_interface_dict
-from vyos.configverify import verify_redirect
+from vyos.configverify import verify_mirror_redirect
from vyos.ifconfig import VTIIf
from vyos.util import dict_search
from vyos import ConfigError
@@ -40,7 +40,7 @@ def get_config(config=None):
return vti
def verify(vti):
- verify_redirect(vti)
+ verify_mirror_redirect(vti)
return None
def generate(vti):
diff --git a/src/conf_mode/interfaces-vxlan.py b/src/conf_mode/interfaces-vxlan.py
index a29836efd..0a9b51cac 100755
--- a/src/conf_mode/interfaces-vxlan.py
+++ b/src/conf_mode/interfaces-vxlan.py
@@ -25,7 +25,7 @@ from vyos.configdict import leaf_node_changed
from vyos.configverify import verify_address
from vyos.configverify import verify_bridge_delete
from vyos.configverify import verify_mtu_ipv6
-from vyos.configverify import verify_redirect
+from vyos.configverify import verify_mirror_redirect
from vyos.configverify import verify_source_interface
from vyos.ifconfig import Interface
from vyos.ifconfig import VXLANIf
@@ -141,7 +141,7 @@ def verify(vxlan):
verify_mtu_ipv6(vxlan)
verify_address(vxlan)
- verify_redirect(vxlan)
+ verify_mirror_redirect(vxlan)
return None
def generate(vxlan):
diff --git a/src/conf_mode/interfaces-wireguard.py b/src/conf_mode/interfaces-wireguard.py
index dc0fe7b9c..b404375d6 100755
--- a/src/conf_mode/interfaces-wireguard.py
+++ b/src/conf_mode/interfaces-wireguard.py
@@ -28,7 +28,7 @@ from vyos.configverify import verify_vrf
from vyos.configverify import verify_address
from vyos.configverify import verify_bridge_delete
from vyos.configverify import verify_mtu_ipv6
-from vyos.configverify import verify_redirect
+from vyos.configverify import verify_mirror_redirect
from vyos.ifconfig import WireGuardIf
from vyos.util import check_kmod
from vyos.util import check_port_availability
@@ -71,7 +71,7 @@ def verify(wireguard):
verify_mtu_ipv6(wireguard)
verify_address(wireguard)
verify_vrf(wireguard)
- verify_redirect(wireguard)
+ verify_mirror_redirect(wireguard)
if 'private_key' not in wireguard:
raise ConfigError('Wireguard private-key not defined')
diff --git a/src/conf_mode/interfaces-wireless.py b/src/conf_mode/interfaces-wireless.py
index fdf9e3988..500952df1 100755
--- a/src/conf_mode/interfaces-wireless.py
+++ b/src/conf_mode/interfaces-wireless.py
@@ -27,7 +27,7 @@ from vyos.configverify import verify_address
from vyos.configverify import verify_bridge_delete
from vyos.configverify import verify_dhcpv6
from vyos.configverify import verify_source_interface
-from vyos.configverify import verify_redirect
+from vyos.configverify import verify_mirror_redirect
from vyos.configverify import verify_vlan_config
from vyos.configverify import verify_vrf
from vyos.ifconfig import WiFiIf
@@ -190,7 +190,7 @@ def verify(wifi):
verify_address(wifi)
verify_vrf(wifi)
- verify_redirect(wifi)
+ verify_mirror_redirect(wifi)
# use common function to verify VLAN configuration
verify_vlan_config(wifi)
diff --git a/src/conf_mode/interfaces-wwan.py b/src/conf_mode/interfaces-wwan.py
index 367a50e82..9a33039a3 100755
--- a/src/conf_mode/interfaces-wwan.py
+++ b/src/conf_mode/interfaces-wwan.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2021 VyOS maintainers and contributors
+# Copyright (C) 2020-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
@@ -21,9 +21,10 @@ from time import sleep
from vyos.config import Config
from vyos.configdict import get_interface_dict
+from vyos.configdict import leaf_node_changed
from vyos.configverify import verify_authentication
from vyos.configverify import verify_interface_exists
-from vyos.configverify import verify_redirect
+from vyos.configverify import verify_mirror_redirect
from vyos.configverify import verify_vrf
from vyos.ifconfig import WWANIf
from vyos.util import cmd
@@ -37,7 +38,7 @@ from vyos import airbag
airbag.enable()
service_name = 'ModemManager.service'
-cron_script = '/etc/cron.d/wwan'
+cron_script = '/etc/cron.d/vyos-wwan'
def get_config(config=None):
"""
@@ -51,6 +52,32 @@ def get_config(config=None):
base = ['interfaces', 'wwan']
wwan = get_interface_dict(conf, base)
+ # We should only terminate the WWAN session if critical parameters change.
+ # All parameters that can be changed on-the-fly (like interface description)
+ # should not lead to a reconnect!
+ tmp = leaf_node_changed(conf, ['address'])
+ if tmp: wwan.update({'shutdown_required': {}})
+
+ tmp = leaf_node_changed(conf, ['apn'])
+ if tmp: wwan.update({'shutdown_required': {}})
+
+ tmp = leaf_node_changed(conf, ['disable'])
+ if tmp: wwan.update({'shutdown_required': {}})
+
+ tmp = leaf_node_changed(conf, ['vrf'])
+ # leaf_node_changed() returns a list, as VRF is a non-multi node, there
+ # will be only one list element
+ if tmp: wwan.update({'vrf_old': tmp[0]})
+
+ tmp = leaf_node_changed(conf, ['authentication', 'user'])
+ if tmp: wwan.update({'shutdown_required': {}})
+
+ tmp = leaf_node_changed(conf, ['authentication', 'password'])
+ if tmp: wwan.update({'shutdown_required': {}})
+
+ tmp = leaf_node_changed(conf, ['ipv6', 'address', 'autoconf'])
+ if tmp: wwan.update({'shutdown_required': {}})
+
# We need to know the amount of other WWAN interfaces as ModemManager needs
# to be started or stopped.
conf.set_level(base)
@@ -58,8 +85,8 @@ def get_config(config=None):
get_first_key=True,
no_tag_node_value_mangle=True)
- # This if-clause is just to be sure - it will always evaluate to true
ifname = wwan['ifname']
+ # This if-clause is just to be sure - it will always evaluate to true
if ifname in wwan['other_interfaces']:
del wwan['other_interfaces'][ifname]
if len(wwan['other_interfaces']) == 0:
@@ -78,19 +105,31 @@ def verify(wwan):
verify_interface_exists(ifname)
verify_authentication(wwan)
verify_vrf(wwan)
- verify_redirect(wwan)
+ verify_mirror_redirect(wwan)
return None
def generate(wwan):
if 'deleted' in wwan:
+ # We are the last WWAN interface - there are no other ones remaining
+ # thus the cronjob needs to go away, too
+ if 'other_interfaces' not in wwan:
+ if os.path.exists(cron_script):
+ os.unlink(cron_script)
return None
+ # Install cron triggered helper script to re-dial WWAN interfaces on
+ # disconnect - e.g. happens during RF signal loss. The script watches every
+ # WWAN interface - so there is only one instance.
if not os.path.exists(cron_script):
write_file(cron_script, '*/5 * * * * root /usr/libexec/vyos/vyos-check-wwan.py')
+
return None
def apply(wwan):
+ # ModemManager is required to dial WWAN connections - one instance is
+ # required to serve all modems. Activate ModemManager on first invocation
+ # of any WWAN interface.
if not is_systemd_service_active(service_name):
cmd(f'systemctl start {service_name}')
@@ -103,17 +142,19 @@ def apply(wwan):
break
sleep(0.250)
- # we only need the modem number. wwan0 -> 0, wwan1 -> 1
- modem = wwan['ifname'].lstrip('wwan')
- base_cmd = f'mmcli --modem {modem}'
- # Number of bearers is limited - always disconnect first
- cmd(f'{base_cmd} --simple-disconnect')
+ if 'shutdown_required' in wwan:
+ # we only need the modem number. wwan0 -> 0, wwan1 -> 1
+ modem = wwan['ifname'].lstrip('wwan')
+ base_cmd = f'mmcli --modem {modem}'
+ # Number of bearers is limited - always disconnect first
+ cmd(f'{base_cmd} --simple-disconnect')
w = WWANIf(wwan['ifname'])
if 'deleted' in wwan or 'disable' in wwan:
w.remove()
- # There are no other WWAN interfaces - stop the daemon
+ # We are the last WWAN interface - there are no other WWAN interfaces
+ # remaining, thus we can stop ModemManager and free resources.
if 'other_interfaces' not in wwan:
cmd(f'systemctl stop {service_name}')
# Clean CRON helper script which is used for to re-connect when
@@ -123,27 +164,25 @@ def apply(wwan):
return None
- ip_type = 'ipv4'
- slaac = dict_search('ipv6.address.autoconf', wwan) != None
- if 'address' in wwan:
- if 'dhcp' in wwan['address'] and ('dhcpv6' in wwan['address'] or slaac):
- ip_type = 'ipv4v6'
- elif 'dhcpv6' in wwan['address'] or slaac:
- ip_type = 'ipv6'
- elif 'dhcp' in wwan['address']:
- ip_type = 'ipv4'
-
- options = f'ip-type={ip_type},apn=' + wwan['apn']
- if 'authentication' in wwan:
- options += ',user={user},password={password}'.format(**wwan['authentication'])
-
- command = f'{base_cmd} --simple-connect="{options}"'
- call(command, stdout=DEVNULL)
- w.update(wwan)
+ if 'shutdown_required' in wwan:
+ ip_type = 'ipv4'
+ slaac = dict_search('ipv6.address.autoconf', wwan) != None
+ if 'address' in wwan:
+ if 'dhcp' in wwan['address'] and ('dhcpv6' in wwan['address'] or slaac):
+ ip_type = 'ipv4v6'
+ elif 'dhcpv6' in wwan['address'] or slaac:
+ ip_type = 'ipv6'
+ elif 'dhcp' in wwan['address']:
+ ip_type = 'ipv4'
- if 'other_interfaces' not in wwan and 'deleted' in wwan:
- cmd(f'systemctl start {service_name}')
+ options = f'ip-type={ip_type},apn=' + wwan['apn']
+ if 'authentication' in wwan:
+ options += ',user={user},password={password}'.format(**wwan['authentication'])
+ command = f'{base_cmd} --simple-connect="{options}"'
+ call(command, stdout=DEVNULL)
+
+ w.update(wwan)
return None
if __name__ == '__main__':
diff --git a/src/conf_mode/policy.py b/src/conf_mode/policy.py
index 6b1d3bf1a..9d8fcfa36 100755
--- a/src/conf_mode/policy.py
+++ b/src/conf_mode/policy.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021 VyOS maintainers and contributors
+# Copyright (C) 2021-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
@@ -114,10 +114,9 @@ def verify(policy):
if 'prefix' not in rule_config:
raise ConfigError(f'A prefix {mandatory_error}')
- # Check prefix duplicates
- if rule_config['prefix'] in entries and ('ge' not in rule_config and 'le' not in rule_config):
- raise ConfigError(f'Prefix {rule_config["prefix"]} is duplicated!')
- entries.append(rule_config['prefix'])
+ if rule_config in entries:
+ raise ConfigError(f'Rule "{rule}" contains a duplicate prefix definition!')
+ entries.append(rule_config)
# route-maps tend to be a bit more complex so they get their own verify() section
diff --git a/src/conf_mode/protocols_bgp.py b/src/conf_mode/protocols_bgp.py
index 64b113873..dace53d37 100755
--- a/src/conf_mode/protocols_bgp.py
+++ b/src/conf_mode/protocols_bgp.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2021 VyOS maintainers and contributors
+# Copyright (C) 2020-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
@@ -213,6 +213,11 @@ def verify(bgp):
if 'non_exist_map' in afi_config['conditionally_advertise']:
verify_route_map(afi_config['conditionally_advertise']['non_exist_map'], bgp)
+ # T4332: bgp deterministic-med cannot be disabled while addpath-tx-bestpath-per-AS is in use
+ if 'addpath_tx_per_as' in afi_config:
+ if dict_search('parameters.deterministic_med', bgp) == None:
+ raise ConfigError('addpath-tx-per-as requires BGP deterministic-med paramtere to be set!')
+
# Validate if configured Prefix list exists
if 'prefix_list' in afi_config:
for tmp in ['import', 'export']:
diff --git a/src/conf_mode/protocols_isis.py b/src/conf_mode/protocols_isis.py
index 9b4b215de..f2501e38a 100755
--- a/src/conf_mode/protocols_isis.py
+++ b/src/conf_mode/protocols_isis.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2021 VyOS maintainers and contributors
+# Copyright (C) 2020-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
@@ -169,28 +169,40 @@ def verify(isis):
# Segment routing checks
if dict_search('segment_routing.global_block', isis):
- high_label_value = dict_search('segment_routing.global_block.high_label_value', isis)
- low_label_value = dict_search('segment_routing.global_block.low_label_value', isis)
+ g_high_label_value = dict_search('segment_routing.global_block.high_label_value', isis)
+ g_low_label_value = dict_search('segment_routing.global_block.low_label_value', isis)
- # If segment routing global block high value is blank, throw error
- if (low_label_value and not high_label_value) or (high_label_value and not low_label_value):
- raise ConfigError('Segment routing global block requires both low and high value!')
+ # If segment routing global block high or low value is blank, throw error
+ if not (g_low_label_value or g_high_label_value):
+ raise ConfigError('Segment routing global-block requires both low and high value!')
# If segment routing global block low value is higher than the high value, throw error
- if int(low_label_value) > int(high_label_value):
- raise ConfigError('Segment routing global block low value must be lower than high value')
+ if int(g_low_label_value) > int(g_high_label_value):
+ raise ConfigError('Segment routing global-block low value must be lower than high value')
if dict_search('segment_routing.local_block', isis):
- high_label_value = dict_search('segment_routing.local_block.high_label_value', isis)
- low_label_value = dict_search('segment_routing.local_block.low_label_value', isis)
+ if dict_search('segment_routing.global_block', isis) == None:
+ raise ConfigError('Segment routing local-block requires global-block to be configured!')
- # If segment routing local block high value is blank, throw error
- if (low_label_value and not high_label_value) or (high_label_value and not low_label_value):
- raise ConfigError('Segment routing local block requires both high and low value!')
+ l_high_label_value = dict_search('segment_routing.local_block.high_label_value', isis)
+ l_low_label_value = dict_search('segment_routing.local_block.low_label_value', isis)
- # If segment routing local block low value is higher than the high value, throw error
- if int(low_label_value) > int(high_label_value):
- raise ConfigError('Segment routing local block low value must be lower than high value')
+ # If segment routing local-block high or low value is blank, throw error
+ if not (l_low_label_value or l_high_label_value):
+ raise ConfigError('Segment routing local-block requires both high and low value!')
+
+ # If segment routing local-block low value is higher than the high value, throw error
+ if int(l_low_label_value) > int(l_high_label_value):
+ raise ConfigError('Segment routing local-block low value must be lower than high value')
+
+ # local-block most live outside global block
+ global_range = range(int(g_low_label_value), int(g_high_label_value) +1)
+ local_range = range(int(l_low_label_value), int(l_high_label_value) +1)
+
+ # Check for overlapping ranges
+ if list(set(global_range) & set(local_range)):
+ raise ConfigError(f'Segment-Routing Global Block ({g_low_label_value}/{g_high_label_value}) '\
+ f'conflicts with Local Block ({l_low_label_value}/{l_high_label_value})!')
return None
diff --git a/src/conf_mode/qos.py b/src/conf_mode/qos.py
index cf447d4b5..dbe3be225 100755
--- a/src/conf_mode/qos.py
+++ b/src/conf_mode/qos.py
@@ -28,36 +28,33 @@ def get_config(config=None):
conf = config
else:
conf = Config()
- base = ['traffic-policy']
+ base = ['qos']
if not conf.exists(base):
return None
qos = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True)
- for traffic_policy in ['drop-tail', 'fair-queue', 'fq-codel', 'limiter',
- 'network-emulator', 'priority-queue', 'random-detect',
- 'rate-control', 'round-robin', 'shaper', 'shaper-hfsc']:
- traffic_policy_us = traffic_policy.replace('-','_')
- # Individual policy type not present on CLI - no need to blend in
- # any default values
- if traffic_policy_us not in qos:
- continue
-
- default_values = defaults(base + [traffic_policy_us])
-
- # class is another tag node which requires individual handling
- class_default_values = defaults(base + [traffic_policy_us, 'class'])
- if 'class' in default_values:
- del default_values['class']
-
- for policy, policy_config in qos[traffic_policy_us].items():
- qos[traffic_policy_us][policy] = dict_merge(
- default_values, qos[traffic_policy_us][policy])
-
- if 'class' in policy_config:
- for policy_class in policy_config['class']:
- qos[traffic_policy_us][policy]['class'][policy_class] = dict_merge(
- class_default_values, qos[traffic_policy_us][policy]['class'][policy_class])
+ if 'policy' in qos:
+ for policy in qos['policy']:
+ # CLI mangles - to _ for better Jinja2 compatibility - do we need
+ # Jinja2 here?
+ policy = policy.replace('-','_')
+
+ default_values = defaults(base + ['policy', policy])
+
+ # class is another tag node which requires individual handling
+ class_default_values = defaults(base + ['policy', policy, 'class'])
+ if 'class' in default_values:
+ del default_values['class']
+
+ for p_name, p_config in qos['policy'][policy].items():
+ qos['policy'][policy][p_name] = dict_merge(
+ default_values, qos['policy'][policy][p_name])
+
+ if 'class' in p_config:
+ for p_class in p_config['class']:
+ qos['policy'][policy][p_name]['class'][p_class] = dict_merge(
+ class_default_values, qos['policy'][policy][p_name]['class'][p_class])
import pprint
pprint.pprint(qos)
diff --git a/src/conf_mode/service_ipoe-server.py b/src/conf_mode/service_ipoe-server.py
index f676fdbbe..2ebee8018 100755
--- a/src/conf_mode/service_ipoe-server.py
+++ b/src/conf_mode/service_ipoe-server.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2020 VyOS maintainers and contributors
+# Copyright (C) 2018-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
@@ -41,6 +41,7 @@ default_config_data = {
'interfaces': [],
'dnsv4': [],
'dnsv6': [],
+ 'client_named_ip_pool': [],
'client_ipv6_pool': [],
'client_ipv6_delegate_prefix': [],
'radius_server': [],
@@ -219,6 +220,22 @@ def get_config(config=None):
conf.set_level(base_path)
+ # Named client-ip-pool
+ if conf.exists(['client-ip-pool', 'name']):
+ for name in conf.list_nodes(['client-ip-pool', 'name']):
+ tmp = {
+ 'name': name,
+ 'gateway_address': '',
+ 'subnet': ''
+ }
+
+ if conf.exists(['client-ip-pool', 'name', name, 'gateway-address']):
+ tmp['gateway_address'] += conf.return_value(['client-ip-pool', 'name', name, 'gateway-address'])
+ if conf.exists(['client-ip-pool', 'name', name, 'subnet']):
+ tmp['subnet'] += conf.return_value(['client-ip-pool', 'name', name, 'subnet'])
+
+ ipoe['client_named_ip_pool'].append(tmp)
+
if conf.exists(['client-ipv6-pool', 'prefix']):
for prefix in conf.list_nodes(['client-ipv6-pool', 'prefix']):
tmp = {
@@ -254,10 +271,6 @@ def verify(ipoe):
if not ipoe['interfaces']:
raise ConfigError('No IPoE interface configured')
- for interface in ipoe['interfaces']:
- if not interface['range']:
- raise ConfigError(f'No IPoE client subnet defined on interface "{ interface }"')
-
if len(ipoe['dnsv4']) > 2:
raise ConfigError('Not more then two IPv4 DNS name-servers can be configured')
diff --git a/src/conf_mode/system-ipv6.py b/src/conf_mode/system-ipv6.py
index 7fb2dd1cf..26aacf46b 100755
--- a/src/conf_mode/system-ipv6.py
+++ b/src/conf_mode/system-ipv6.py
@@ -19,8 +19,6 @@ import os
from sys import exit
from vyos.config import Config
from vyos.configdict import dict_merge
-from vyos.configdict import leaf_node_changed
-from vyos.util import call
from vyos.util import dict_search
from vyos.util import sysctl_write
from vyos.util import write_file
@@ -38,9 +36,6 @@ def get_config(config=None):
opt = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True)
- tmp = leaf_node_changed(conf, base + ['disable'])
- if tmp: opt['reboot_required'] = {}
-
# 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)
@@ -55,15 +50,6 @@ def generate(opt):
pass
def apply(opt):
- # disable IPv6 globally
- tmp = dict_search('disable', opt)
- value = '1' if (tmp != None) else '0'
- sysctl_write('net.ipv6.conf.all.disable_ipv6', value)
-
- if 'reboot_required' in opt:
- print('Changing IPv6 disable parameter will only take affect\n' \
- 'when the system is rebooted.')
-
# configure multipath
tmp = dict_search('multipath.layer4_hashing', opt)
value = '1' if (tmp != None) else '0'
diff --git a/src/conf_mode/system-login.py b/src/conf_mode/system-login.py
index 4dd7f936d..c9c6aa187 100755
--- a/src/conf_mode/system-login.py
+++ b/src/conf_mode/system-login.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2021 VyOS maintainers and contributors
+# Copyright (C) 2020-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
@@ -23,6 +23,7 @@ from pwd import getpwall
from pwd import getpwnam
from spwd import getspnam
from sys import exit
+from time import sleep
from vyos.config import Config
from vyos.configdict import dict_merge
@@ -31,6 +32,7 @@ from vyos.template import render
from vyos.template import is_ipv4
from vyos.util import cmd
from vyos.util import call
+from vyos.util import run
from vyos.util import DEVNULL
from vyos.util import dict_search
from vyos.xml import defaults
@@ -250,13 +252,22 @@ def apply(login):
if 'rm_users' in login:
for user in login['rm_users']:
try:
+ # Disable user to prevent re-login
+ call(f'usermod -s /sbin/nologin {user}')
+
# Logout user if he is still logged in
if user in list(set([tmp[0] for tmp in users()])):
print(f'{user} is logged in, forcing logout!')
- call(f'pkill -HUP -u {user}')
-
- # Remove user account but leave home directory to be safe
- call(f'userdel --remove {user}', stderr=DEVNULL)
+ # re-run command until user is logged out
+ while run(f'pkill -HUP -u {user}'):
+ sleep(0.250)
+
+ # Remove user account but leave home directory in place. Re-run
+ # command until user is removed - userdel might return 8 as
+ # SSH sessions are not all yet properly cleaned away, thus we
+ # simply re-run the command until the account wen't away
+ while run(f'userdel --remove {user}', stderr=DEVNULL):
+ sleep(0.250)
except Exception as e:
raise ConfigError(f'Deleting user "{user}" raised exception: {e}')
diff --git a/src/conf_mode/vrf.py b/src/conf_mode/vrf.py
index c3e2d8efd..f79c8a21e 100755
--- a/src/conf_mode/vrf.py
+++ b/src/conf_mode/vrf.py
@@ -30,7 +30,6 @@ from vyos.util import get_interface_config
from vyos.util import popen
from vyos.util import run
from vyos.util import sysctl_write
-from vyos.util import is_ipv6_enabled
from vyos import ConfigError
from vyos import frr
from vyos import airbag
@@ -219,8 +218,7 @@ def apply(vrf):
# We also should add proper loopback IP addresses to the newly added
# VRF for services bound to the loopback address (SNMP, NTP)
vrf_if.add_addr('127.0.0.1/8')
- if is_ipv6_enabled():
- vrf_if.add_addr('::1/128')
+ vrf_if.add_addr('::1/128')
# add VRF description if available
vrf_if.set_alias(config.get('description', ''))
diff --git a/src/etc/cron.d/check-wwan b/src/etc/cron.d/check-wwan
deleted file mode 100644
index 28190776f..000000000
--- a/src/etc/cron.d/check-wwan
+++ /dev/null
@@ -1 +0,0 @@
-*/5 * * * * root /usr/libexec/vyos/vyos-check-wwan.py
diff --git a/src/migration-scripts/system/22-to-23 b/src/migration-scripts/system/22-to-23
new file mode 100755
index 000000000..7f832e48a
--- /dev/null
+++ b/src/migration-scripts/system/22-to-23
@@ -0,0 +1,50 @@
+#!/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, argv
+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 = ['system', 'ipv6']
+config = ConfigTree(config_file)
+
+if not config.exists(base):
+ # Nothing to do
+ exit(0)
+
+# T4346: drop support to disbale IPv6 address family within the OS Kernel
+if config.exists(base + ['disable']):
+ config.delete(base + ['disable'])
+ # IPv6 address family disable was the only CLI option set - we can cleanup
+ # the entire tree
+ if len(config.list_nodes(base)) == 0:
+ config.delete(base)
+
+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)
diff --git a/src/services/vyos-http-api-server b/src/services/vyos-http-api-server
index 1000d8b72..c1b595412 100755
--- a/src/services/vyos-http-api-server
+++ b/src/services/vyos-http-api-server
@@ -352,7 +352,7 @@ class MultipartRoute(APIRoute):
return error(e.status_code, e.detail)
except Exception as e:
if request.ERR_MISSING_KEY:
- return error(422, "Valid API key is required")
+ return error(401, "Valid API key is required")
if request.ERR_MISSING_DATA:
return error(422, "Non-empty data field is required")
if request.ERR_NOT_JSON:
diff --git a/src/tests/test_util.py b/src/tests/test_util.py
index 91890262c..8ac9a500a 100644
--- a/src/tests/test_util.py
+++ b/src/tests/test_util.py
@@ -26,13 +26,3 @@ class TestVyOSUtil(TestCase):
def test_sysctl_read(self):
self.assertEqual(sysctl_read('net.ipv4.conf.lo.forwarding'), '1')
-
- def test_ipv6_enabled(self):
- tmp = sysctl_read('net.ipv6.conf.all.disable_ipv6')
- # We need to test for both variants as this depends on how the
- # Docker container is started (with or without IPv6 support) - so we
- # will simply check both cases to not make the users life miserable.
- if tmp == '0':
- self.assertTrue(is_ipv6_enabled())
- else:
- self.assertFalse(is_ipv6_enabled())