diff options
191 files changed, 7801 insertions, 3684 deletions
@@ -46,7 +46,11 @@ interface_definitions: $(config_xml_obj) rm -f $(TMPL_DIR)/system/node.def rm -f $(TMPL_DIR)/vpn/node.def rm -f $(TMPL_DIR)/vpn/ipsec/node.def - rm -rf $(TMPL_DIR)/vpn/nipsec + + # XXX: T3781: migrate back to old iptables NAT implementation as we can not use nft + # which requires Kernel 5.10 for proper prefix translation support. Kernel 5.10 + # unfortunately breaks with Intel QAT :( + rm -rf $(TMPL_DIR)/nat # XXX: required until OSPF and RIP is migrated from vyatta-cfg-quagga to vyos-1x mkdir $(TMPL_DIR)/interfaces/loopback/node.tag/ipv6 @@ -85,21 +89,25 @@ op_mode_definitions: $(op_xml_obj) rm -f $(OP_TMPL_DIR)/show/system/node.def rm -f $(OP_TMPL_DIR)/show/vpn/node.def + # XXX: T3781: migrate back to old iptables NAT implementation as we can not use nft + # which requires Kernel 5.10 for proper prefix translation support. Kernel 5.10 + # unfortunately breaks with Intel QAT :( + rm -rf $(OP_TMPL_DIR)/show/nat + # XXX: ping must be able to recursivly call itself as the # options are provided from the script itself ln -s ../node.tag $(OP_TMPL_DIR)/ping/node.tag/node.tag/ -.PHONY: component_versions -.ONESHELL: -component_versions: interface_definitions - $(CURDIR)/scripts/build-component-versions $(BUILD_DIR)/interface-definitions $(DATA_DIR) + # XXX: test if there are empty node.def files - this is not allowed as these + # could mask help strings or mandatory priority statements + find $(OP_TMPL_DIR) -name node.def -type f -empty -exec false {} + || sh -c 'echo "There are empty node.def files! Check your interface definitions." && exit 1' .PHONY: vyshim vyshim: $(MAKE) -C $(SHIM_DIR) .PHONY: all -all: clean interface_definitions op_mode_definitions component_versions vyshim +all: clean interface_definitions op_mode_definitions vyshim .PHONY: clean clean: diff --git a/data/templates/accel-ppp/pptp.config.tmpl b/data/templates/accel-ppp/pptp.config.tmpl index 5a6cfe749..3cfc4a906 100644 --- a/data/templates/accel-ppp/pptp.config.tmpl +++ b/data/templates/accel-ppp/pptp.config.tmpl @@ -2,12 +2,13 @@ [modules] log_syslog pptp -ippool +shaper {% if auth_mode == 'local' %} chap-secrets {% elif auth_mode == 'radius' %} radius {% endif %} +ippool {% for proto in auth_proto %} {{proto}} {% endfor %} @@ -87,6 +88,10 @@ nas-ip-address={{ radius_nas_ip }} bind={{ radius_source_address }} {% endif %} {% endif %} +{# Both chap-secrets and radius block required the gw-ip-address #} +{% if gw_ip is defined and gw_ip is not none %} +gw-ip-address={{ gw_ip }} +{% endif %} [cli] tcp=127.0.0.1:2003 diff --git a/data/templates/accel-ppp/sstp.config.tmpl b/data/templates/accel-ppp/sstp.config.tmpl index 7ca7b1c1e..d48e9ab0d 100644 --- a/data/templates/accel-ppp/sstp.config.tmpl +++ b/data/templates/accel-ppp/sstp.config.tmpl @@ -29,7 +29,9 @@ disable verbose=1 ifname=sstp%d accept=ssl +{% if ssl.ca_cert_file is defined and ssl.ca_cert_file is not none %} ssl-ca-file={{ ssl.ca_cert_file }} +{% endif %} ssl-pemfile={{ ssl.cert_file }} ssl-keyfile={{ ssl.key_file }} diff --git a/data/templates/frr/isisd.frr.tmpl b/data/templates/frr/isisd.frr.tmpl index 8a813d9cb..6cfa076d0 100644 --- a/data/templates/frr/isisd.frr.tmpl +++ b/data/templates/frr/isisd.frr.tmpl @@ -1,5 +1,5 @@ ! -router isis {{ process }} +router isis VyOS {{ 'vrf ' + vrf if vrf is defined and vrf is not none }} net {{ net }} {% if dynamic_hostname is defined %} hostname dynamic @@ -13,8 +13,15 @@ router isis {{ process }} {% if set_overload_bit is defined %} set-overload-bit {% endif %} -{% if domain_password is defined and domain_password.plaintext_password is defined and domain_password.plaintext_password is not none %} +{% if domain_password is defined and domain_password is not none %} +{% if domain_password.md5 is defined and domain_password.md5 is not none %} + domain-password md5 {{ domain_password.plaintext_password }} +{% elif domain_password.plaintext_password is defined and domain_password.plaintext_password is not none %} domain-password clear {{ domain_password.plaintext_password }} +{% endif %} +{% endif %} +{% if log_adjacency_changes is defined %} + log-adjacency-changes {% endif %} {% if lsp_gen_interval is defined and lsp_gen_interval is not none %} lsp-gen-interval {{ lsp_gen_interval }} @@ -95,47 +102,61 @@ router isis {{ process }} {% if spf_delay_ietf is defined and spf_delay_ietf.init_delay is defined and spf_delay_ietf.init_delay is not none %} spf-delay-ietf init-delay {{ spf_delay_ietf.init_delay }} {% endif %} -{% if area_password is defined and area_password.md5 is defined and area_password.md5 is not none %} +{% if area_password is defined and area_password is not none %} +{% if area_password.md5 is defined and area_password.md5 is not none %} area-password md5 {{ area_password.md5 }} -{% elif area_password is defined and area_password.plaintext_password is defined and area_password.plaintext_password is not none %} +{% elif area_password.plaintext_password is defined and area_password.plaintext_password is not none %} 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 %} -{% for level in default_information.originate.ipv4 if default_information.originate.ipv4 is defined %} - default-information originate ipv4 {{ level | replace('_', '-') }} -{% endfor %} -{% for level in default_information.originate.ipv6 if default_information.originate.ipv6 is defined %} - default-information originate ipv6 {{ level | replace('_', '-') }} always +{% 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 }} +{% endfor %} {% endfor %} {% endif %} -{% if redistribute is defined and redistribute.ipv4 is defined and redistribute.ipv4 is not none %} -{% for protocol in redistribute.ipv4 %} -{% for level, level_config in redistribute.ipv4[protocol].items() %} -{% if level_config.metric is defined and level_config.metric is not none %} +{% 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 %} 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 defined and level_config.route_map is not none %} redistribute ipv4 {{ protocol }} {{ level | replace('_', '-') }} route-map {{ level_config.route_map }} -{% else %} +{% else %} redistribute ipv4 {{ protocol }} {{ level | replace('_', '-') }} -{% endif %} +{% endif %} +{% endfor %} {% endfor %} -{% 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 %} + redistribute ipv6 {{ protocol }} {{ level | replace('_', '-') }} metric {{ level_config.metric }} +{% elif level_config.route_map is defined and level_config.route_map is not none %} + redistribute ipv6 {{ protocol }} {{ level | replace('_', '-') }} route-map {{ level_config.route_map }} +{% else %} + redistribute ipv6 {{ protocol }} {{ level | replace('_', '-') }} +{% endif %} +{% endfor %} +{% endfor %} +{% endif %} {% endif %} {% if level is defined and level is not none %} -{% if level == 'level-1' %} - is-type level-1 -{% elif level == 'level-2' %} +{% if level == 'level-2' %} is-type level-2-only -{% elif level == 'level-1-2' %} - is-type level-1-2 +{% else %} + is-type {{ level }} {% endif %} {% endif %} ! {% if interface is defined and interface is not none %} {% for iface, iface_config in interface.items() %} -interface {{ iface }} - ip router isis {{ process }} - ipv6 router isis {{ process }} +interface {{ iface }} {{ 'vrf ' + vrf if vrf is defined and vrf is not none }} + ip router isis VyOS + ipv6 router isis VyOS {% if iface_config.bfd is defined %} isis bfd {% endif %} @@ -174,3 +195,4 @@ interface {{ iface }} {% endif %} {% endfor %} {% endif %} +!
\ No newline at end of file diff --git a/data/templates/frr/route-map.frr.tmpl b/data/templates/frr/route-map.frr.tmpl new file mode 100644 index 000000000..6b33cc126 --- /dev/null +++ b/data/templates/frr/route-map.frr.tmpl @@ -0,0 +1,5 @@ +! +{% if route_map is defined and route_map is not none %} +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 4aaf0132f..26d0b5d73 100644 --- a/data/templates/https/nginx.default.tmpl +++ b/data/templates/https/nginx.default.tmpl @@ -38,6 +38,7 @@ server { # include snippets/snakeoil.conf; {% endif %} + ssl_protocols TLSv1.2 TLSv1.3; # proxy settings for HTTP API, if enabled; 503, if not location ~ /(retrieve|configure|config-file|image|generate|show) { diff --git a/data/templates/openvpn/server.conf.tmpl b/data/templates/openvpn/server.conf.tmpl index c5d665c0b..50bb49134 100644 --- a/data/templates/openvpn/server.conf.tmpl +++ b/data/templates/openvpn/server.conf.tmpl @@ -7,8 +7,6 @@ # verb 3 -user {{ daemon_user }} -group {{ daemon_group }} dev-type {{ device_type }} dev {{ ifname }} persist-key @@ -74,6 +72,16 @@ topology {{ server.topology }} {% for subnet in server.subnet %} {% if subnet | is_ipv4 %} server {{ subnet | address_from_cidr }} {{ subnet | netmask_from_cidr }} nopool +{# First ip address is used as gateway. It's allows to use metrics #} +{% if server.push_route is defined and server.push_route is not none %} +{% for route, route_config in server.push_route.items() %} +{% if route | is_ipv4 %} +push "route {{ route | address_from_cidr }} {{ route | netmask_from_cidr }} {{ subnet | first_host_address }} {{ route_config.metric if route_config.metric is defined else "0" }}" +{% elif route | is_ipv6 %} +push "route-ipv6 {{ route }}" +{% endif %} +{% endfor %} +{% endif %} {# OpenVPN assigns the first IP address to its local interface so the pool used #} {# in net30 topology - where each client receives a /30 must start from the second subnet #} {% if server.topology is defined and server.topology == 'net30' %} @@ -106,15 +114,6 @@ management /run/openvpn/openvpn-mgmt-intf unix ccd-exclusive {% endif %} -{% if server.push_route is defined and server.push_route is not none %} -{% for route in server.push_route %} -{% if route | is_ipv4 %} -push "route {{ route | address_from_cidr }} {{ route | netmask_from_cidr }}" -{% elif route | is_ipv6 %} -push "route-ipv6 {{ route }}" -{% endif %} -{% endfor %} -{% endif %} {% if server.name_server is defined and server.name_server is not none %} {% for nameserver in server.name_server %} {% if nameserver | is_ipv4 %} diff --git a/data/templates/pppoe/peer.tmpl b/data/templates/pppoe/peer.tmpl index 0f78f9384..f416f9947 100644 --- a/data/templates/pppoe/peer.tmpl +++ b/data/templates/pppoe/peer.tmpl @@ -1,8 +1,5 @@ ### Autogenerated by interfaces-pppoe.py ### - -{% if description %} -# {{ description }} -{% endif %} +{{ '# ' ~ description if description is defined else '' }} # Require peer to provide the local IP address if it is not # specified explicitly in the config file. @@ -37,8 +34,14 @@ noproxyarp # Unlimited connection attempts maxfail 0 -plugin rp-pppoe.so -{{ source_interface }} +plugin rp-pppoe.so {{ source_interface }} +{% if access_concentrator is defined and access_concentrator is not none %} +rp_pppoe_ac '{{ access_concentrator }}' +{% endif %} +{% if service_name is defined and service_name is not none %} +rp_pppoe_service '{{ service_name }}' +{% endif %} + persist ifname {{ ifname }} ipparam {{ ifname }} @@ -60,10 +63,6 @@ ipv6cp-use-ipaddr {% endif %} {% endif %} -{% if service_name is defined %} -rp_pppoe_service "{{ service_name }}" -{% endif %} - {% if connect_on_demand is defined %} demand # See T2249. PPP default route options should only be set when in on-demand diff --git a/data/templates/syslog/rsyslog.conf.tmpl b/data/templates/syslog/rsyslog.conf.tmpl index 10fbb9d3c..e25ef48d4 100644 --- a/data/templates/syslog/rsyslog.conf.tmpl +++ b/data/templates/syslog/rsyslog.conf.tmpl @@ -2,47 +2,47 @@ ## file based logging {% if files['global']['marker'] %} $ModLoad immark -{% if files['global']['marker-interval'] %} +{% if files['global']['marker-interval'] %} $MarkMessagePeriod {{files['global']['marker-interval']}} -{% endif %} +{% endif %} {% endif %} {% if files['global']['preserver_fqdn'] %} $PreserveFQDN on {% endif %} -{% for file in files %} -$outchannel {{file}},{{files[file]['log-file']}},{{files[file]['max-size']}},{{files[file]['action-on-max-size']}} -{{files[file]['selectors']}} :omfile:${{file}} +{% for file, file_options in files.items() %} +$outchannel {{ file }},{{ file_options['log-file'] }},{{ file_options['max-size'] }},{{ file_options['action-on-max-size'] }} +{{ file_options['selectors'] }} :omfile:${{ file }} {% endfor %} -{% if console %} +{% if console is defined and console is not none %} ## console logging -{% for con in console %} -{{console[con]['selectors']}} /dev/console -{% endfor %} +{% for con, con_options in console.items() %} +{{ con_options['selectors'] }} /dev/console +{% endfor %} {% endif %} -{% if hosts %} +{% if hosts is defined and hosts is not none %} ## remote logging -{% for host in hosts %} -{% if hosts[host]['proto'] == 'tcp' %} -{% if hosts[host]['port'] %} -{% if hosts[host]['oct_count'] %} -{{hosts[host]['selectors']}} @@(o){{host}}:{{hosts[host]['port']}};RSYSLOG_SyslogProtocol23Format +{% for host, host_options in hosts.items() %} +{% if host_options.proto == 'tcp' %} +{% if host_options.port is defined %} +{% if host_options.oct_count is defined %} +{{ host_options.selectors }} @@(o){{ host }}:{{ host_options.port }};RSYSLOG_SyslogProtocol23Format +{% else %} +{{ host_options.selectors }} @@{{ host }}:{{ host_options.port }} +{% endif %} {% else %} -{{hosts[host]['selectors']}} @@{{host}}:{{hosts[host]['port']}} +{{ host_options.selectors }} @@{{ host }} {% endif %} {% else %} -{{hosts[host]['selectors']}} @@{{host}} -{% endif %} -{% else %} -{% if hosts[host]['port'] %} -{{hosts[host]['selectors']}} @{{host}}:{{hosts[host]['port']}} -{% else %} -{{hosts[host]['selectors']}} @{{host}} +{% if host_options['port'] %} +{{ host_options.selectors }} @{{ host | bracketize_ipv6 }}:{{ host_options.port }} +{% else %} +{{ host_options.selectors }} @{{ host | bracketize_ipv6 }} +{% endif %} {% endif %} -{% endif %} -{% endfor %} +{% endfor %} {% endif %} -{% if user %} -{% for u in user %} -{{user[u]['selectors']}} :omusrmsg:{{u}} -{% endfor %} +{% if user is defined and user is not none %} +{% for username, user_options in user.items() %} +{{ user_options.selectors }} :omusrmsg:{{ username }} +{% endfor %} {% endif %} diff --git a/interface-definitions/bcast-relay.xml.in b/interface-definitions/bcast-relay.xml.in index 1b354d885..a0f73a03b 100644 --- a/interface-definitions/bcast-relay.xml.in +++ b/interface-definitions/bcast-relay.xml.in @@ -1,5 +1,4 @@ <?xml version="1.0"?> -<!-- UDP broadcast relay configuration --> <interfaceDefinition> <node name="service"> <children> @@ -14,8 +13,8 @@ <properties> <help>Unique ID for each UDP port to forward</help> <valueHelp> - <format>1-99</format> - <description>Numerical ID #</description> + <format>u32:1-99</format> + <description>Broadcast relay instance ID</description> </valueHelp> <constraint> <validator name="numeric" argument="--range 1-99"/> diff --git a/interface-definitions/dhcp-relay.xml.in b/interface-definitions/dhcp-relay.xml.in index 8c95239d9..0d485ef80 100644 --- a/interface-definitions/dhcp-relay.xml.in +++ b/interface-definitions/dhcp-relay.xml.in @@ -27,7 +27,7 @@ <properties> <help>Policy to discard packets that have reached specified hop-count</help> <valueHelp> - <format>1-255</format> + <format>u32:1-255</format> <description>Hop count (default: 10)</description> </valueHelp> <constraint> @@ -41,7 +41,7 @@ <properties> <help>Maximum packet size to send to a DHCPv4/BOOTP server</help> <valueHelp> - <format>64-1400</format> + <format>u32:64-1400</format> <description>Maximum packet size (default: 576)</description> </valueHelp> <constraint> diff --git a/interface-definitions/dhcp-server.xml.in b/interface-definitions/dhcp-server.xml.in index 015500043..bafd6f6a2 100644 --- a/interface-definitions/dhcp-server.xml.in +++ b/interface-definitions/dhcp-server.xml.in @@ -96,7 +96,7 @@ <properties> <help>Specifies the clients subnet mask as per RFC 950. If unset, subnet declaration is used.</help> <valueHelp> - <format>0-32</format> + <format>u32:0-32</format> <description>DHCP client prefix length must be 0 to 32</description> </valueHelp> <constraint> diff --git a/interface-definitions/dhcpv6-relay.xml.in b/interface-definitions/dhcpv6-relay.xml.in index 308f94a01..7162cf353 100644 --- a/interface-definitions/dhcpv6-relay.xml.in +++ b/interface-definitions/dhcpv6-relay.xml.in @@ -35,7 +35,7 @@ <properties> <help>Maximum hop count for which requests will be processed</help> <valueHelp> - <format>1-255</format> + <format>u32:1-255</format> <description>Hop count (default: 10)</description> </valueHelp> <constraint> diff --git a/interface-definitions/dhcpv6-server.xml.in b/interface-definitions/dhcpv6-server.xml.in index 5d6c64685..95b1e5602 100644 --- a/interface-definitions/dhcpv6-server.xml.in +++ b/interface-definitions/dhcpv6-server.xml.in @@ -1,5 +1,4 @@ <?xml version="1.0"?> -<!-- DHCPv6 server configuration --> <interfaceDefinition> <node name="service"> <children> @@ -34,7 +33,7 @@ <properties> <help>Preference of this DHCPv6 server compared with others</help> <valueHelp> - <format>0-255</format> + <format>u32:0-255</format> <description>DHCPv6 server preference (0-255)</description> </valueHelp> <constraint> @@ -62,7 +61,7 @@ <properties> <help>Time (in seconds) that stateless clients should wait between refreshing the information they were given</help> <valueHelp> - <format>1-4294967295</format> + <format>u32:1-4294967295</format> <description>DHCPv6 information refresh time</description> </valueHelp> <constraint> @@ -161,7 +160,7 @@ <properties> <help>Default time (in seconds) that will be assigned to a lease</help> <valueHelp> - <format>1-4294967295</format> + <format>u32:1-4294967295</format> <description>DHCPv6 valid lifetime</description> </valueHelp> <constraint> @@ -173,7 +172,7 @@ <properties> <help>Maximum time (in seconds) that will be assigned to a lease</help> <valueHelp> - <format>1-4294967295</format> + <format>u32:1-4294967295</format> <description>Maximum lease time in seconds</description> </valueHelp> <constraint> @@ -185,7 +184,7 @@ <properties> <help>Minimum time (in seconds) that will be assigned to a lease</help> <valueHelp> - <format>1-4294967295</format> + <format>u32:1-4294967295</format> <description>Minimum lease time in seconds</description> </valueHelp> <constraint> @@ -273,7 +272,7 @@ <properties> <help>Length in bits of prefixes to be delegated</help> <valueHelp> - <format>32-64</format> + <format>u32:32-64</format> <description>Delagated prefix length (32-64)</description> </valueHelp> <constraint> diff --git a/interface-definitions/dns-domain-name.xml.in b/interface-definitions/dns-domain-name.xml.in index ff632e1d1..2b1644609 100644 --- a/interface-definitions/dns-domain-name.xml.in +++ b/interface-definitions/dns-domain-name.xml.in @@ -1,37 +1,34 @@ <?xml version="1.0"?> -<!-- host-name configuration --> <interfaceDefinition> <node name="system"> <children> <leafNode name="name-server" owner="${vyos_conf_scripts_dir}/host_name.py"> <properties> - <help>Domain Name Servers (DNS) used by the system (resolv.conf)</help> + <help>System Domain Name Servers (DNS)</help> <priority>400</priority> + <completionHelp> + <script>${vyos_completion_dir}/list_interfaces.py</script> + </completionHelp> <valueHelp> <format>ipv4</format> - <description>Domain Name Server (DNS) address</description> + <description>Domain Name Server IPv4 address</description> </valueHelp> <valueHelp> <format>ipv6</format> - <description>Domain Name Server (DNS) address</description> + <description>Domain Name Server IPv6 address</description> + </valueHelp> + <valueHelp> + <format>txt</format> + <description>Use Domain Name Server from DHCP interface</description> </valueHelp> <multi/> <constraint> <validator name="ipv4-address"/> <validator name="ipv6-address"/> + <validator name="interface-name"/> </constraint> </properties> </leafNode> - <leafNode name="name-servers-dhcp" owner="${vyos_conf_scripts_dir}/host_name.py"> - <properties> - <help>Interfaces whose DHCP client nameservers will be used by the system (resolv.conf)</help> - <priority>400</priority> - <completionHelp> - <script>${vyos_completion_dir}/list_interfaces.py</script> - </completionHelp> - <multi/> - </properties> - </leafNode> <leafNode name="host-name" owner="${vyos_conf_scripts_dir}/host_name.py"> <properties> <help>System host name (default: vyos)</help> diff --git a/interface-definitions/dns-dynamic.xml.in b/interface-definitions/dns-dynamic.xml.in index b0b9158c8..250642691 100644 --- a/interface-definitions/dns-dynamic.xml.in +++ b/interface-definitions/dns-dynamic.xml.in @@ -49,7 +49,7 @@ <properties> <help>Time To Live (default: 600)</help> <valueHelp> - <format>1-86400</format> + <format>u32:1-86400</format> <description>DNS forwarding cache size</description> </valueHelp> <constraint> diff --git a/interface-definitions/dns-forwarding.xml.in b/interface-definitions/dns-forwarding.xml.in index 66b4db403..9b58788c6 100644 --- a/interface-definitions/dns-forwarding.xml.in +++ b/interface-definitions/dns-forwarding.xml.in @@ -18,7 +18,7 @@ <properties> <help>DNS forwarding cache size (default: 10000)</help> <valueHelp> - <format>0-10000</format> + <format>u32:0-10000</format> <description>DNS forwarding cache size</description> </valueHelp> <constraint> @@ -133,7 +133,7 @@ <properties> <help>Maximum amount of time negative entries are cached (default: 3600)</help> <valueHelp> - <format>0-7200</format> + <format>u32:0-7200</format> <description>Seconds to cache NXDOMAIN entries</description> </valueHelp> <constraint> diff --git a/interface-definitions/flow-accounting-conf.xml.in b/interface-definitions/flow-accounting-conf.xml.in index b3980d9e2..b0f308afd 100644 --- a/interface-definitions/flow-accounting-conf.xml.in +++ b/interface-definitions/flow-accounting-conf.xml.in @@ -267,7 +267,7 @@ <properties> <help>Expiry scan interval</help> <valueHelp> - <format>0-2147483647</format> + <format>u32:0-2147483647</format> <description>Expiry scan interval (default 60)</description> </valueHelp> <constraint> @@ -279,7 +279,7 @@ <properties> <help>Generic flow timeout value</help> <valueHelp> - <format>0-2147483647</format> + <format>u32:0-2147483647</format> <description>Generic flow timeout in seconds (default 3600)</description> </valueHelp> <constraint> @@ -291,7 +291,7 @@ <properties> <help>ICMP timeout value</help> <valueHelp> - <format>0-2147483647</format> + <format>u32:0-2147483647</format> <description>ICMP timeout in seconds (default 300)</description> </valueHelp> <constraint> @@ -303,7 +303,7 @@ <properties> <help>Max active timeout value</help> <valueHelp> - <format>0-2147483647</format> + <format>u32:0-2147483647</format> <description>Max active timeout in seconds (default 604800)</description> </valueHelp> <constraint> @@ -315,7 +315,7 @@ <properties> <help>TCP finish timeout value</help> <valueHelp> - <format>0-2147483647</format> + <format>u32:0-2147483647</format> <description>TCP FIN timeout in seconds (default 300)</description> </valueHelp> <constraint> @@ -327,7 +327,7 @@ <properties> <help>TCP generic timeout value</help> <valueHelp> - <format>0-2147483647</format> + <format>u32:0-2147483647</format> <description>TCP generic timeout in seconds (default 3600)</description> </valueHelp> <constraint> @@ -339,7 +339,7 @@ <properties> <help>TCP reset timeout value</help> <valueHelp> - <format>0-2147483647</format> + <format>u32:0-2147483647</format> <description>TCP RST timeout in seconds (default 120)</description> </valueHelp> <constraint> @@ -351,7 +351,7 @@ <properties> <help>UDP timeout value</help> <valueHelp> - <format>0-2147483647</format> + <format>u32:0-2147483647</format> <description>UDP timeout in seconds (default 300)</description> </valueHelp> <constraint> diff --git a/interface-definitions/https.xml.in b/interface-definitions/https.xml.in index b613e30c1..ccb77910a 100644 --- a/interface-definitions/https.xml.in +++ b/interface-definitions/https.xml.in @@ -1,7 +1,5 @@ <?xml version="1.0"?> -<!-- HTTPS configuration --> <interfaceDefinition> - <syntaxVersion component='https' version='2'></syntaxVersion> <node name="service"> <children> <node name="https" owner="${vyos_conf_scripts_dir}/https.py"> @@ -48,7 +46,7 @@ <properties> <help>Port to listen for HTTPS requests; default 443</help> <valueHelp> - <format>1-65535</format> + <format>u32:1-65535</format> <description>Numeric IP port</description> </valueHelp> <constraint> @@ -151,9 +149,9 @@ </properties> </leafNode> <leafNode name="email"> - <properties> - <help>Email address to associate with certificate</help> - </properties> + <properties> + <help>Email address to associate with certificate</help> + </properties> </leafNode> </children> </node> diff --git a/interface-definitions/igmp-proxy.xml.in b/interface-definitions/igmp-proxy.xml.in index d0f44eada..91c912d8b 100644 --- a/interface-definitions/igmp-proxy.xml.in +++ b/interface-definitions/igmp-proxy.xml.in @@ -65,7 +65,7 @@ <properties> <help>TTL threshold (default: 1)</help> <valueHelp> - <format>1-255</format> + <format>u32:1-255</format> <description>TTL threshold for the interfaces (default: 1)</description> </valueHelp> <constraint> diff --git a/interface-definitions/include/accel-ppp/ppp-interface-cache.xml.i b/interface-definitions/include/accel-ppp/ppp-interface-cache.xml.i index 9f223d7ed..019601c85 100644 --- a/interface-definitions/include/accel-ppp/ppp-interface-cache.xml.i +++ b/interface-definitions/include/accel-ppp/ppp-interface-cache.xml.i @@ -3,7 +3,7 @@ <properties> <help>PPP interface cache</help> <valueHelp> - <format>1-256000</format> + <format>u32:1-256000</format> <description>Count of interfaces to keep in cache</description> </valueHelp> <constraint> diff --git a/interface-definitions/include/accel-ppp/radius-additions.xml.i b/interface-definitions/include/accel-ppp/radius-additions.xml.i index e65088c43..44ec64d7f 100644 --- a/interface-definitions/include/accel-ppp/radius-additions.xml.i +++ b/interface-definitions/include/accel-ppp/radius-additions.xml.i @@ -5,7 +5,7 @@ <properties> <help>Maximum jitter value in seconds to be applied to accounting information interval</help> <valueHelp> - <format>1-60</format> + <format>u32:1-60</format> <description>Maximum jitter value in seconds</description> </valueHelp> <constraint> @@ -20,7 +20,7 @@ <properties> <help>Accounting port</help> <valueHelp> - <format>1-65535</format> + <format>u32:1-65535</format> <description>Numeric IP port (default: 1813)</description> </valueHelp> <constraint> @@ -34,7 +34,7 @@ <properties> <help>Mark server unavailable for <n> seconds on failure</help> <valueHelp> - <format>0-600</format> + <format>u32:0-600</format> <description>Fail time penalty</description> </valueHelp> <constraint> @@ -50,7 +50,7 @@ <properties> <help>Timeout in seconds to wait response from RADIUS server</help> <valueHelp> - <format>1-60</format> + <format>u32:1-60</format> <description>Timeout in seconds</description> </valueHelp> <constraint> @@ -64,7 +64,7 @@ <properties> <help>Timeout for Interim-Update packets, terminate session afterwards (default 3 seconds)</help> <valueHelp> - <format>0-60</format> + <format>u32:0-60</format> <description>Timeout in seconds, 0 to keep active</description> </valueHelp> <constraint> @@ -78,7 +78,7 @@ <properties> <help>Number of tries to send Access-Request/Accounting-Request queries</help> <valueHelp> - <format>1-20</format> + <format>u32:1-20</format> <description>Maximum tries</description> </valueHelp> <constraint> diff --git a/interface-definitions/include/bfd.xml.i b/interface-definitions/include/bfd.xml.i new file mode 100644 index 000000000..2bc3664e1 --- /dev/null +++ b/interface-definitions/include/bfd.xml.i @@ -0,0 +1,8 @@ +<!-- include start from bfd.xml.i --> +<leafNode name="bfd"> + <properties> + <help>Enable Bidirectional Forwarding Detection (BFD)</help> + <valueless/> + </properties> +</leafNode> +<!-- include end --> diff --git a/interface-definitions/include/interface/interface-arp-cache-timeout.xml.i b/interface-definitions/include/interface/arp-cache-timeout.xml.i index b269fecd8..70e69e14a 100644 --- a/interface-definitions/include/interface/interface-arp-cache-timeout.xml.i +++ b/interface-definitions/include/interface/arp-cache-timeout.xml.i @@ -3,7 +3,7 @@ <properties> <help>ARP cache entry timeout in seconds</help> <valueHelp> - <format>1-86400</format> + <format>u32:1-86400</format> <description>ARP cache entry timout in seconds (default 30)</description> </valueHelp> <constraint> diff --git a/interface-definitions/include/interface/interface-description.xml.i b/interface-definitions/include/interface/description.xml.i index d618b50d2..d618b50d2 100644 --- a/interface-definitions/include/interface/interface-description.xml.i +++ b/interface-definitions/include/interface/description.xml.i diff --git a/interface-definitions/include/interface/dhcpv6-options.xml.i b/interface-definitions/include/interface/dhcpv6-options.xml.i index a569659a4..a0cac34f1 100644 --- a/interface-definitions/include/interface/dhcpv6-options.xml.i +++ b/interface-definitions/include/interface/dhcpv6-options.xml.i @@ -38,7 +38,7 @@ <properties> <help>Request IPv6 prefix length from peer</help> <valueHelp> - <format>32-64</format> + <format>u32:32-64</format> <description>Length of delegated prefix</description> </valueHelp> <constraint> @@ -71,7 +71,7 @@ <properties> <help>Interface site-Level aggregator (SLA)</help> <valueHelp> - <format>0-128</format> + <format>u32:0-128</format> <description>Decimal integer which fits in the length of SLA IDs</description> </valueHelp> <constraint> diff --git a/interface-definitions/include/interface/interface-dial-on-demand.xml.i b/interface-definitions/include/interface/dial-on-demand.xml.i index 66edd9678..66edd9678 100644 --- a/interface-definitions/include/interface/interface-dial-on-demand.xml.i +++ b/interface-definitions/include/interface/dial-on-demand.xml.i diff --git a/interface-definitions/include/interface/interface-disable-arp-filter.xml.i b/interface-definitions/include/interface/disable-arp-filter.xml.i index 49cddaf76..49cddaf76 100644 --- a/interface-definitions/include/interface/interface-disable-arp-filter.xml.i +++ b/interface-definitions/include/interface/disable-arp-filter.xml.i diff --git a/interface-definitions/include/interface/interface-disable-forwarding.xml.i b/interface-definitions/include/interface/disable-forwarding.xml.i index cb6ef0475..cee9d2a8d 100644 --- a/interface-definitions/include/interface/interface-disable-forwarding.xml.i +++ b/interface-definitions/include/interface/disable-forwarding.xml.i @@ -1,7 +1,7 @@ <!-- include start from interface/interface-disable-forwarding.xml.i --> <leafNode name="disable-forwarding"> <properties> - <help>Disable IPv4 forwarding on this interface</help> + <help>Disable IP forwarding on this interface</help> <valueless/> </properties> </leafNode> diff --git a/interface-definitions/include/interface/interface-disable-link-detect.xml.i b/interface-definitions/include/interface/disable-link-detect.xml.i index c528885b2..c528885b2 100644 --- a/interface-definitions/include/interface/interface-disable-link-detect.xml.i +++ b/interface-definitions/include/interface/disable-link-detect.xml.i diff --git a/interface-definitions/include/interface/interface-disable.xml.i b/interface-definitions/include/interface/disable.xml.i index d90e6395b..d90e6395b 100644 --- a/interface-definitions/include/interface/interface-disable.xml.i +++ b/interface-definitions/include/interface/disable.xml.i diff --git a/interface-definitions/include/interface/interface-eapol.xml.i b/interface-definitions/include/interface/eapol.xml.i index 92b7a3f35..92b7a3f35 100644 --- a/interface-definitions/include/interface/interface-eapol.xml.i +++ b/interface-definitions/include/interface/eapol.xml.i diff --git a/interface-definitions/include/interface/interface-enable-arp-accept.xml.i b/interface-definitions/include/interface/enable-arp-accept.xml.i index 7c5d51857..7c5d51857 100644 --- a/interface-definitions/include/interface/interface-enable-arp-accept.xml.i +++ b/interface-definitions/include/interface/enable-arp-accept.xml.i diff --git a/interface-definitions/include/interface/interface-enable-arp-announce.xml.i b/interface-definitions/include/interface/enable-arp-announce.xml.i index f44599c54..f44599c54 100644 --- a/interface-definitions/include/interface/interface-enable-arp-announce.xml.i +++ b/interface-definitions/include/interface/enable-arp-announce.xml.i diff --git a/interface-definitions/include/interface/interface-enable-arp-ignore.xml.i b/interface-definitions/include/interface/enable-arp-ignore.xml.i index 3ea39613c..3ea39613c 100644 --- a/interface-definitions/include/interface/interface-enable-arp-ignore.xml.i +++ b/interface-definitions/include/interface/enable-arp-ignore.xml.i diff --git a/interface-definitions/include/interface/interface-enable-proxy-arp.xml.i b/interface-definitions/include/interface/enable-proxy-arp.xml.i index dbdeeb7a7..dbdeeb7a7 100644 --- a/interface-definitions/include/interface/interface-enable-proxy-arp.xml.i +++ b/interface-definitions/include/interface/enable-proxy-arp.xml.i diff --git a/interface-definitions/include/interface/interface-hw-id.xml.i b/interface-definitions/include/interface/hw-id.xml.i index 989cd9cb7..989cd9cb7 100644 --- a/interface-definitions/include/interface/interface-hw-id.xml.i +++ b/interface-definitions/include/interface/hw-id.xml.i diff --git a/interface-definitions/include/interface/interface-ipv4-options.xml.i b/interface-definitions/include/interface/interface-ipv4-options.xml.i deleted file mode 100644 index c2d0677b7..000000000 --- a/interface-definitions/include/interface/interface-ipv4-options.xml.i +++ /dev/null @@ -1,18 +0,0 @@ -<!-- include start from interface/interface-ipv4-options.xml.i --> -<node name="ip"> - <properties> - <help>IPv4 routing parameters</help> - </properties> - <children> - #include <include/interface/interface-arp-cache-timeout.xml.i> - #include <include/interface/interface-disable-arp-filter.xml.i> - #include <include/interface/interface-disable-forwarding.xml.i> - #include <include/interface/interface-enable-arp-accept.xml.i> - #include <include/interface/interface-enable-arp-announce.xml.i> - #include <include/interface/interface-enable-arp-ignore.xml.i> - #include <include/interface/interface-enable-proxy-arp.xml.i> - #include <include/interface/interface-proxy-arp-pvlan.xml.i> - #include <include/interface/interface-source-validation.xml.i> - </children> -</node> -<!-- include end --> diff --git a/interface-definitions/include/interface/ipv4-options.xml.i b/interface-definitions/include/interface/ipv4-options.xml.i new file mode 100644 index 000000000..5a45487c5 --- /dev/null +++ b/interface-definitions/include/interface/ipv4-options.xml.i @@ -0,0 +1,18 @@ +<!-- include start from interface/interface-ipv4-options.xml.i --> +<node name="ip"> + <properties> + <help>IPv4 routing parameters</help> + </properties> + <children> + #include <include/interface/arp-cache-timeout.xml.i> + #include <include/interface/disable-arp-filter.xml.i> + #include <include/interface/disable-forwarding.xml.i> + #include <include/interface/enable-arp-accept.xml.i> + #include <include/interface/enable-arp-announce.xml.i> + #include <include/interface/enable-arp-ignore.xml.i> + #include <include/interface/enable-proxy-arp.xml.i> + #include <include/interface/proxy-arp-pvlan.xml.i> + #include <include/interface/source-validation.xml.i> + </children> +</node> +<!-- include end --> diff --git a/interface-definitions/include/interface/ipv6-disable-forwarding.xml.i b/interface-definitions/include/interface/ipv6-disable-forwarding.xml.i deleted file mode 100644 index 4adb77d1b..000000000 --- a/interface-definitions/include/interface/ipv6-disable-forwarding.xml.i +++ /dev/null @@ -1,8 +0,0 @@ -<!-- include start from interface/ipv6-disable-forwarding.xml.i --> -<leafNode name="disable-forwarding"> - <properties> - <help>Disable IPv6 forwarding on this interface</help> - <valueless/> - </properties> -</leafNode> -<!-- include end --> diff --git a/interface-definitions/include/interface/ipv6-dup-addr-detect-transmits.xml.i b/interface-definitions/include/interface/ipv6-dup-addr-detect-transmits.xml.i index 2b5ec0281..babe6d20f 100644 --- a/interface-definitions/include/interface/ipv6-dup-addr-detect-transmits.xml.i +++ b/interface-definitions/include/interface/ipv6-dup-addr-detect-transmits.xml.i @@ -3,12 +3,12 @@ <properties> <help>Number of NS messages to send while performing DAD (default: 1)</help> <valueHelp> - <format>1-n</format> - <description>Number of NS messages to send while performing DAD</description> + <format>u32:0</format> + <description>Disable Duplicate Address Dectection (DAD)</description> </valueHelp> <valueHelp> - <format>0</format> - <description>Disable Duplicate Address Dectection (DAD)</description> + <format>u32:1-n</format> + <description>Number of NS messages to send while performing DAD</description> </valueHelp> <constraint> <validator name="numeric" argument="--non-negative"/> diff --git a/interface-definitions/include/interface/interface-ipv6-options.xml.i b/interface-definitions/include/interface/ipv6-options.xml.i index dcd5a8710..a5b40c789 100644 --- a/interface-definitions/include/interface/interface-ipv6-options.xml.i +++ b/interface-definitions/include/interface/ipv6-options.xml.i @@ -4,8 +4,8 @@ <help>IPv6 routing parameters</help> </properties> <children> + #include <include/interface/disable-forwarding.xml.i> #include <include/interface/ipv6-address.xml.i> - #include <include/interface/ipv6-disable-forwarding.xml.i> #include <include/interface/ipv6-dup-addr-detect-transmits.xml.i> </children> </node> diff --git a/interface-definitions/include/interface/interface-mac.xml.i b/interface-definitions/include/interface/mac.xml.i index d7107ad23..d7107ad23 100644 --- a/interface-definitions/include/interface/interface-mac.xml.i +++ b/interface-definitions/include/interface/mac.xml.i diff --git a/interface-definitions/include/interface/interface-mirror.xml.i b/interface-definitions/include/interface/mirror.xml.i index b3b45fb43..b3b45fb43 100644 --- a/interface-definitions/include/interface/interface-mirror.xml.i +++ b/interface-definitions/include/interface/mirror.xml.i diff --git a/interface-definitions/include/interface/interface-mtu-1200-16000.xml.i b/interface-definitions/include/interface/mtu-1200-16000.xml.i index 3241ba912..730c6e00d 100644 --- a/interface-definitions/include/interface/interface-mtu-1200-16000.xml.i +++ b/interface-definitions/include/interface/mtu-1200-16000.xml.i @@ -3,7 +3,7 @@ <properties> <help>Maximum Transmission Unit (MTU)</help> <valueHelp> - <format>1200-16000</format> + <format>u32:1200-16000</format> <description>Maximum Transmission Unit in byte</description> </valueHelp> <constraint> diff --git a/interface-definitions/include/interface/interface-mtu-1450-16000.xml.i b/interface-definitions/include/interface/mtu-1450-16000.xml.i index 0a35bbbaa..96cfa7054 100644 --- a/interface-definitions/include/interface/interface-mtu-1450-16000.xml.i +++ b/interface-definitions/include/interface/mtu-1450-16000.xml.i @@ -3,7 +3,7 @@ <properties> <help>Maximum Transmission Unit (MTU)</help> <valueHelp> - <format>1450-16000</format> + <format>u32:1450-16000</format> <description>Maximum Transmission Unit in byte</description> </valueHelp> <constraint> diff --git a/interface-definitions/include/interface/interface-mtu-64-8024.xml.i b/interface-definitions/include/interface/mtu-64-8024.xml.i index f75de02ba..3719ece24 100644 --- a/interface-definitions/include/interface/interface-mtu-64-8024.xml.i +++ b/interface-definitions/include/interface/mtu-64-8024.xml.i @@ -3,7 +3,7 @@ <properties> <help>Maximum Transmission Unit (MTU)</help> <valueHelp> - <format>64-8024</format> + <format>u32:64-8024</format> <description>Maximum Transmission Unit in byte</description> </valueHelp> <constraint> diff --git a/interface-definitions/include/interface/interface-mtu-68-1500.xml.i b/interface-definitions/include/interface/mtu-68-1500.xml.i index 9e6fe8760..d74cdfa9c 100644 --- a/interface-definitions/include/interface/interface-mtu-68-1500.xml.i +++ b/interface-definitions/include/interface/mtu-68-1500.xml.i @@ -3,7 +3,7 @@ <properties> <help>Maximum Transmission Unit (MTU)</help> <valueHelp> - <format>68-1500</format> + <format>u32:68-1500</format> <description>Maximum Transmission Unit in byte</description> </valueHelp> <constraint> diff --git a/interface-definitions/include/interface/interface-mtu-68-16000.xml.i b/interface-definitions/include/interface/mtu-68-16000.xml.i index 83af7bbd4..41340fbf3 100644 --- a/interface-definitions/include/interface/interface-mtu-68-16000.xml.i +++ b/interface-definitions/include/interface/mtu-68-16000.xml.i @@ -3,7 +3,7 @@ <properties> <help>Maximum Transmission Unit (MTU)</help> <valueHelp> - <format>68-16000</format> + <format>u32:68-16000</format> <description>Maximum Transmission Unit in byte</description> </valueHelp> <constraint> diff --git a/interface-definitions/include/interface/interface-parameters-flowlabel.xml.i b/interface-definitions/include/interface/parameters-flowlabel.xml.i index f5e868a64..a89bb13f1 100644 --- a/interface-definitions/include/interface/interface-parameters-flowlabel.xml.i +++ b/interface-definitions/include/interface/parameters-flowlabel.xml.i @@ -2,9 +2,16 @@ <leafNode name="flowlabel"> <properties> <help>Specifies the flow label to use in outgoing packets</help> + <completionHelp> + <list>inherit</list> + </completionHelp> <valueHelp> - <format>0x0-0x0FFFFF</format> - <description>Tunnel key, 'inherit' or hex value</description> + <format>inherit</format> + <description>Copy field from original header</description> + </valueHelp> + <valueHelp> + <format>0x0-0x0fffff</format> + <description>Tunnel key, or hex value</description> </valueHelp> <constraint> <regex>^((0x){0,1}(0?[0-9A-Fa-f]{1,5})|inherit)$</regex> diff --git a/interface-definitions/include/interface/interface-parameters-key.xml.i b/interface-definitions/include/interface/parameters-key.xml.i index 1b1d67174..1b1d67174 100644 --- a/interface-definitions/include/interface/interface-parameters-key.xml.i +++ b/interface-definitions/include/interface/parameters-key.xml.i diff --git a/interface-definitions/include/interface/interface-parameters-tos.xml.i b/interface-definitions/include/interface/parameters-tos.xml.i index 83b4e0671..1b342a43e 100644 --- a/interface-definitions/include/interface/interface-parameters-tos.xml.i +++ b/interface-definitions/include/interface/parameters-tos.xml.i @@ -3,7 +3,7 @@ <properties> <help>Specifies TOS value to use in outgoing packets</help> <valueHelp> - <format>0-99</format> + <format>u32:0-99</format> <description>Type of Service (TOS)</description> </valueHelp> <constraint> diff --git a/interface-definitions/include/interface/interface-parameters-ttl.xml.i b/interface-definitions/include/interface/parameters-ttl.xml.i index 21a5e5cd9..8ef8c9149 100644 --- a/interface-definitions/include/interface/interface-parameters-ttl.xml.i +++ b/interface-definitions/include/interface/parameters-ttl.xml.i @@ -3,11 +3,11 @@ <properties> <help>Specifies TTL value to use in outgoing packets</help> <valueHelp> - <format>0</format> - <description>Copy value from original IP header</description> + <format>u32:0</format> + <description>Inherit - copy value from original IP header</description> </valueHelp> <valueHelp> - <format>1-255</format> + <format>u32:1-255</format> <description>Time to Live</description> </valueHelp> <constraint> diff --git a/interface-definitions/include/interface/interface-proxy-arp-pvlan.xml.i b/interface-definitions/include/interface/proxy-arp-pvlan.xml.i index 153dfc072..153dfc072 100644 --- a/interface-definitions/include/interface/interface-proxy-arp-pvlan.xml.i +++ b/interface-definitions/include/interface/proxy-arp-pvlan.xml.i diff --git a/interface-definitions/include/interface/interface-source-validation.xml.i b/interface-definitions/include/interface/source-validation.xml.i index 70914f2e9..70914f2e9 100644 --- a/interface-definitions/include/interface/interface-source-validation.xml.i +++ b/interface-definitions/include/interface/source-validation.xml.i diff --git a/interface-definitions/include/interface/vif-s.xml.i b/interface-definitions/include/interface/vif-s.xml.i index 85885c153..7a41bb242 100644 --- a/interface-definitions/include/interface/vif-s.xml.i +++ b/interface-definitions/include/interface/vif-s.xml.i @@ -2,6 +2,10 @@ <tagNode name="vif-s"> <properties> <help>QinQ TAG-S Virtual Local Area Network (VLAN) ID</help> + <valueHelp> + <format>u32:0-4094</format> + <description>QinQ Virtual Local Area Network (VLAN) ID</description> + </valueHelp> <constraint> <validator name="numeric" argument="--range 0-4094"/> </constraint> @@ -9,11 +13,11 @@ </properties> <children> #include <include/interface/address-ipv4-ipv6-dhcp.xml.i> - #include <include/interface/interface-description.xml.i> + #include <include/interface/description.xml.i> #include <include/interface/dhcp-options.xml.i> #include <include/interface/dhcpv6-options.xml.i> - #include <include/interface/interface-disable-link-detect.xml.i> - #include <include/interface/interface-disable.xml.i> + #include <include/interface/disable-link-detect.xml.i> + #include <include/interface/disable.xml.i> <leafNode name="protocol"> <properties> <help>Protocol used for service VLAN (default: 802.1ad)</help> @@ -35,10 +39,10 @@ </properties> <defaultValue>802.1ad</defaultValue> </leafNode> - #include <include/interface/interface-ipv4-options.xml.i> - #include <include/interface/interface-ipv6-options.xml.i> - #include <include/interface/interface-mac.xml.i> - #include <include/interface/interface-mtu-68-16000.xml.i> + #include <include/interface/ipv4-options.xml.i> + #include <include/interface/ipv6-options.xml.i> + #include <include/interface/mac.xml.i> + #include <include/interface/mtu-68-16000.xml.i> <tagNode name="vif-c"> <properties> <help>QinQ TAG-C Virtual Local Area Network (VLAN) ID</help> @@ -49,19 +53,19 @@ </properties> <children> #include <include/interface/address-ipv4-ipv6-dhcp.xml.i> - #include <include/interface/interface-description.xml.i> + #include <include/interface/description.xml.i> #include <include/interface/dhcp-options.xml.i> #include <include/interface/dhcpv6-options.xml.i> - #include <include/interface/interface-disable-link-detect.xml.i> - #include <include/interface/interface-disable.xml.i> - #include <include/interface/interface-ipv4-options.xml.i> - #include <include/interface/interface-ipv6-options.xml.i> - #include <include/interface/interface-mac.xml.i> - #include <include/interface/interface-mtu-68-16000.xml.i> - #include <include/interface/interface-vrf.xml.i> + #include <include/interface/disable-link-detect.xml.i> + #include <include/interface/disable.xml.i> + #include <include/interface/ipv4-options.xml.i> + #include <include/interface/ipv6-options.xml.i> + #include <include/interface/mac.xml.i> + #include <include/interface/mtu-68-16000.xml.i> + #include <include/interface/vrf.xml.i> </children> </tagNode> - #include <include/interface/interface-vrf.xml.i> + #include <include/interface/vrf.xml.i> </children> </tagNode> <!-- include end --> diff --git a/interface-definitions/include/interface/vif.xml.i b/interface-definitions/include/interface/vif.xml.i index 4e7aeb0f9..fdf09c5f9 100644 --- a/interface-definitions/include/interface/vif.xml.i +++ b/interface-definitions/include/interface/vif.xml.i @@ -3,7 +3,7 @@ <properties> <help>Virtual Local Area Network (VLAN) ID</help> <valueHelp> - <format>0-4094</format> + <format>u32:0-4094</format> <description>Virtual Local Area Network (VLAN) ID</description> </valueHelp> <constraint> @@ -13,12 +13,12 @@ </properties> <children> #include <include/interface/address-ipv4-ipv6-dhcp.xml.i> - #include <include/interface/interface-description.xml.i> + #include <include/interface/description.xml.i> #include <include/interface/dhcp-options.xml.i> #include <include/interface/dhcpv6-options.xml.i> - #include <include/interface/interface-disable-link-detect.xml.i> - #include <include/interface/interface-disable.xml.i> - #include <include/interface/interface-vrf.xml.i> + #include <include/interface/disable-link-detect.xml.i> + #include <include/interface/disable.xml.i> + #include <include/interface/vrf.xml.i> <leafNode name="egress-qos"> <properties> <help>VLAN egress QoS</help> @@ -43,10 +43,10 @@ <constraintErrorMessage>QoS mapping should be in the format of '0:7 2:3' with numbers 0-9</constraintErrorMessage> </properties> </leafNode> - #include <include/interface/interface-ipv4-options.xml.i> - #include <include/interface/interface-ipv6-options.xml.i> - #include <include/interface/interface-mac.xml.i> - #include <include/interface/interface-mtu-68-16000.xml.i> + #include <include/interface/ipv4-options.xml.i> + #include <include/interface/ipv6-options.xml.i> + #include <include/interface/mac.xml.i> + #include <include/interface/mtu-68-16000.xml.i> </children> </tagNode> <!-- include end --> diff --git a/interface-definitions/include/interface/interface-vrf.xml.i b/interface-definitions/include/interface/vrf.xml.i index ef6ca1241..ef6ca1241 100644 --- a/interface-definitions/include/interface/interface-vrf.xml.i +++ b/interface-definitions/include/interface/vrf.xml.i diff --git a/interface-definitions/include/isis-redistribute-ipv4.xml.i b/interface-definitions/include/isis-redistribute-ipv4.xml.i deleted file mode 100644 index 774086a81..000000000 --- a/interface-definitions/include/isis-redistribute-ipv4.xml.i +++ /dev/null @@ -1,56 +0,0 @@ -<!-- include start from isis-redistribute-ipv4.xml.i --> -<node name="level-1"> - <properties> - <help>Redistribute into level-1</help> - </properties> - <children> - <leafNode name="metric"> - <properties> - <help>Metric for redistributed routes</help> - <valueHelp> - <format>u32:0-16777215</format> - <description>ISIS default metric</description> - </valueHelp> - <constraint> - <validator name="numeric" argument="--range 0-16777215"/> - </constraint> - </properties> - </leafNode> - <leafNode name="route-map"> - <properties> - <help>Route map reference</help> - <completionHelp> - <path>policy route-map</path> - </completionHelp> - </properties> - </leafNode> - </children> -</node> -<node name="level-2"> - <properties> - <help>Redistribute into level-2</help> - </properties> - <children> - <leafNode name="metric"> - <properties> - <help>Metric for redistributed routes</help> - <valueHelp> - <format>u32:0-16777215</format> - <description>ISIS default metric</description> - </valueHelp> - <constraint> - <validator name="numeric" argument="--range 0-16777215"/> - </constraint> - </properties> - </leafNode> - <leafNode name="route-map"> - <properties> - <help>Route map reference</help> - <completionHelp> - <path>policy route-map</path> - </completionHelp> - </properties> - </leafNode> - </children> -</node> -<!-- include end --> diff --git a/interface-definitions/include/isis/default-information-level.xml.i b/interface-definitions/include/isis/default-information-level.xml.i new file mode 100644 index 000000000..5ade72a4b --- /dev/null +++ b/interface-definitions/include/isis/default-information-level.xml.i @@ -0,0 +1,32 @@ +<!-- include start from isis/default-information-level.xml.i --> +<node name="level-1"> + <properties> + <help>Distribute default route into level-1</help> + </properties> + <children> + <leafNode name="always"> + <properties> + <help>Always advertise default route</help> + <valueless/> + </properties> + </leafNode> + #include <include/isis/metric.xml.i> + #include <include/route-map.xml.i> + </children> +</node> +<node name="level-2"> + <properties> + <help>Distribute default route into level-2</help> + </properties> + <children> + <leafNode name="always"> + <properties> + <help>Always advertise default route</help> + <valueless/> + </properties> + </leafNode> + #include <include/isis/metric.xml.i> + #include <include/route-map.xml.i> + </children> +</node> +<!-- include end --> diff --git a/interface-definitions/include/isis/metric.xml.i b/interface-definitions/include/isis/metric.xml.i new file mode 100644 index 000000000..30e2cdc10 --- /dev/null +++ b/interface-definitions/include/isis/metric.xml.i @@ -0,0 +1,14 @@ +<!-- include start from isis/metric.xml.i --> +<leafNode name="metric"> + <properties> + <help>Set default metric for circuit</help> + <valueHelp> + <format>u32:0-16777215</format> + <description>Default metric value</description> + </valueHelp> + <constraint> + <validator name="numeric" argument="--range 0-16777215"/> + </constraint> + </properties> +</leafNode> +<!-- include end --> diff --git a/interface-definitions/include/isis/passive.xml.i b/interface-definitions/include/isis/passive.xml.i new file mode 100644 index 000000000..6d05f8cc7 --- /dev/null +++ b/interface-definitions/include/isis/passive.xml.i @@ -0,0 +1,8 @@ +<!-- include start from isis/passive.xml.i --> +<leafNode name="passive"> + <properties> + <help>Configure passive mode for interface</help> + <valueless/> + </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 new file mode 100644 index 000000000..84e2f7bb2 --- /dev/null +++ b/interface-definitions/include/isis/protocol-common-config.xml.i @@ -0,0 +1,769 @@ +<!-- include start from isis/protocol-common-config.xml.i --> +<node name="area-password"> + <properties> + <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> + </children> +</node> +<node name="default-information"> + <properties> + <help>Control distribution of default information</help> + </properties> + <children> + <node name="originate"> + <properties> + <help>Distribute a default route</help> + </properties> + <children> + <node name="ipv4"> + <properties> + <help>Distribute default route for IPv4</help> + </properties> + <children> + #include <include/isis/default-information-level.xml.i> + </children> + </node> + <node name="ipv6"> + <properties> + <help>Distribute default route for IPv6</help> + </properties> + <children> + #include <include/isis/default-information-level.xml.i> + </children> + </node> + </children> + </node> + </children> +</node> +<node name="domain-password"> + <properties> + <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> + </children> +</node> +<leafNode name="dynamic-hostname"> + <properties> + <help>Dynamic hostname for IS-IS</help> + <valueless/> + </properties> +</leafNode> +<leafNode name="level"> + <properties> + <help>IS-IS level number</help> + <completionHelp> + <list>level-1 level-1-2 level-2</list> + </completionHelp> + <valueHelp> + <format>level-1</format> + <description>Act as a station router</description> + </valueHelp> + <valueHelp> + <format>level-1-2</format> + <description>Act as both a station and an area router</description> + </valueHelp> + <valueHelp> + <format>level-2</format> + <description>Act as an area router</description> + </valueHelp> + <constraint> + <regex>^(level-1|level-1-2|level-2)$</regex> + </constraint> + </properties> +</leafNode> +<leafNode name="log-adjacency-changes"> + <properties> + <help>Log adjacency state changes</help> + <valueless/> + </properties> +</leafNode> +<leafNode name="lsp-gen-interval"> + <properties> + <help>Minimum interval between regenerating same LSP</help> + <valueHelp> + <format>u32:1-120</format> + <description>Minimum interval in seconds</description> + </valueHelp> + <constraint> + <validator name="numeric" argument="--range 1-120"/> + </constraint> + </properties> +</leafNode> +<leafNode name="lsp-mtu"> + <properties> + <help>Configure the maximum size of generated LSPs</help> + <valueHelp> + <format>u32:128-4352</format> + <description>Maximum size of generated LSPs</description> + </valueHelp> + <constraint> + <validator name="numeric" argument="--range 128-4352"/> + </constraint> + </properties> + <defaultValue>1497</defaultValue> +</leafNode> +<leafNode name="lsp-refresh-interval"> + <properties> + <help>LSP refresh interval</help> + <valueHelp> + <format>u32:1-65235</format> + <description>LSP refresh interval in seconds</description> + </valueHelp> + <constraint> + <validator name="numeric" argument="--range 1-65235"/> + </constraint> + </properties> +</leafNode> +<leafNode name="max-lsp-lifetime"> + <properties> + <help>Maximum LSP lifetime</help> + <valueHelp> + <format>u32:350-65535</format> + <description>LSP lifetime in seconds</description> + </valueHelp> + <constraint> + <validator name="numeric" argument="--range 1-65535"/> + </constraint> + </properties> +</leafNode> +<leafNode name="metric-style"> + <properties> + <help>Use old-style (ISO 10589) or new-style packet formats</help> + <completionHelp> + <list>narrow transition wide</list> + </completionHelp> + <valueHelp> + <format>narrow</format> + <description>Use old style of TLVs with narrow metric</description> + </valueHelp> + <valueHelp> + <format>transition</format> + <description>Send and accept both styles of TLVs during transition</description> + </valueHelp> + <valueHelp> + <format>wide</format> + <description>Use new style of TLVs to carry wider metric</description> + </valueHelp> + <constraint> + <regex>^(narrow|transition|wide)$</regex> + </constraint> + </properties> +</leafNode> +<leafNode name="net"> + <properties> + <help>A Network Entity Title for this process (ISO only)</help> + <valueHelp> + <format>XX.XXXX. ... .XXX.XX</format> + <description>Network entity title (NET)</description> + </valueHelp> + <constraint> + <regex>[a-fA-F0-9]{2}(\.[a-fA-F0-9]{4}){3,9}\.[a-fA-F0-9]{2}</regex> + </constraint> + </properties> +</leafNode> +<leafNode name="purge-originator"> + <properties> + <help>Use the RFC 6232 purge-originator</help> + <valueless/> + </properties> +</leafNode> +<node name="traffic-engineering"> + <properties> + <help>Show IS-IS neighbor adjacencies</help> + </properties> + <children> + <leafNode name="enable"> + <properties> + <help>Enable MPLS traffic engineering extensions</help> + <valueless/> + </properties> + </leafNode> +<!-- + <node name="inter-as"> + <properties> + <help>MPLS traffic engineering inter-AS support</help> + </properties> + <children> + <leafNode name="level-1"> + <properties> + <help>Area native mode self originate inter-AS LSP with L1 only flooding scope</help> + <valueless/> + </properties> + </leafNode> + <leafNode name="level-1-2"> + <properties> + <help>Area native mode self originate inter-AS LSP with L1 and L2 flooding scope</help> + <valueless/> + </properties> + </leafNode> + <leafNode name="level-2"> + <properties> + <help>Area native mode self originate inter-AS LSP with L2 only flooding scope</help> + <valueless/> + </properties> + </leafNode> + </children> + </node> + <leafNode name="inter-as"> + <properties> + <help>MPLS traffic engineering inter-AS support</help> + <valueless/> + </properties> + </leafNode> +--> + <leafNode name="address"> + <properties> + <help>MPLS traffic engineering router ID</help> + <valueHelp> + <format>ipv4</format> + <description>IPv4 address</description> + </valueHelp> + <constraint> + <validator name="ipv4-address"/> + </constraint> + </properties> + </leafNode> + </children> +</node> +<node name="segment-routing"> + <properties> + <help>Segment-Routing (SPRING) settings</help> + </properties> + <children> + <leafNode name="enable"> + <properties> + <help>Enable segment-routing functionality</help> + <valueless/> + </properties> + </leafNode> + <node name="global-block"> + <properties> + <help>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> + </children> + </node> +<!-- + <node name="local-block"> + <properties> + <help>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> + </children> + </node> +--> + <leafNode name="maximum-label-depth"> + <properties> + <help>Maximum MPLS labels allowed for this router</help> + <valueHelp> + <format>u32:1-16</format> + <description>MPLS label depth</description> + </valueHelp> + <constraint> + <validator name="numeric" argument="--range 1-16"/> + </constraint> + </properties> + </leafNode> + <tagNode name="prefix"> + <properties> + <help>Static IPv4/IPv6 prefix segment/label mapping</help> + <valueHelp> + <format>ipv4net</format> + <description>IPv4 prefix segment</description> + </valueHelp> + <valueHelp> + <format>ipv6net</format> + <description>IPv6 prefix segment</description> + </valueHelp> + <constraint> + <validator name="ipv4-prefix"/> + <validator name="ipv6-prefix"/> + </constraint> + </properties> + <children> + <node name="absolute"> + <properties> + <help>Specify the absolute value of prefix segment/label ID</help> + </properties> + <children> + <leafNode name="value"> + <properties> + <help>Specify the absolute value of prefix segment/label ID</help> + <valueHelp> + <format>u32:16-1048575</format> + <description>The absolute segment/label ID value</description> + </valueHelp> + <constraint> + <validator name="numeric" argument="--range 16-1048575"/> + </constraint> + </properties> + </leafNode> + <leafNode name="explicit-null"> + <properties> + <help>Request upstream neighbor to replace segment/label with explicit null label</help> + <valueless/> + </properties> + </leafNode> + <leafNode name="no-php-flag"> + <properties> + <help>Do not request penultimate hop popping for segment/label</help> + <valueless/> + </properties> + </leafNode> + </children> + </node> + <node name="index"> + <properties> + <help>Specify the index value of prefix segment/label ID</help> + </properties> + <children> + <leafNode name="value"> + <properties> + <help>Specify the index value of prefix segment/label ID</help> + <valueHelp> + <format>u32:0-65535</format> + <description>The index segment/label ID value</description> + </valueHelp> + <constraint> + <validator name="numeric" argument="--range 0-65535"/> + </constraint> + </properties> + </leafNode> + <leafNode name="explicit-null"> + <properties> + <help>Request upstream neighbor to replace segment/label with explicit null label</help> + <valueless/> + </properties> + </leafNode> + <leafNode name="no-php-flag"> + <properties> + <help>Do not request penultimate hop popping for segment/label</help> + <valueless/> + </properties> + </leafNode> + </children> + </node> + </children> + </tagNode> + </children> +</node> +<node name="redistribute"> + <properties> + <help>Redistribute information from another routing protocol</help> + </properties> + <children> + <node name="ipv4"> + <properties> + <help>Redistribute IPv4 routes</help> + </properties> + <children> + <node name="bgp"> + <properties> + <help>Border Gateway Protocol (BGP)</help> + </properties> + <children> + #include <include/isis/redistribute-level-1-2.xml.i> + </children> + </node> + <node name="connected"> + <properties> + <help>Redistribute connected routes into IS-IS</help> + </properties> + <children> + #include <include/isis/redistribute-level-1-2.xml.i> + </children> + </node> + <node name="kernel"> + <properties> + <help>Redistribute kernel routes into IS-IS</help> + </properties> + <children> + #include <include/isis/redistribute-level-1-2.xml.i> + </children> + </node> + <node name="ospf"> + <properties> + <help>Redistribute OSPF routes into IS-IS</help> + </properties> + <children> + #include <include/isis/redistribute-level-1-2.xml.i> + </children> + </node> + <node name="rip"> + <properties> + <help>Redistribute RIP routes into IS-IS</help> + </properties> + <children> + #include <include/isis/redistribute-level-1-2.xml.i> + </children> + </node> + <node name="static"> + <properties> + <help>Redistribute static routes into IS-IS</help> + </properties> + <children> + #include <include/isis/redistribute-level-1-2.xml.i> + </children> + </node> + </children> + </node> + <node name="ipv6"> + <properties> + <help>Redistribute IPv6 routes</help> + </properties> + <children> + <node name="bgp"> + <properties> + <help>Redistribute BGP routes into IS-IS</help> + </properties> + <children> + #include <include/isis/redistribute-level-1-2.xml.i> + </children> + </node> + <node name="connected"> + <properties> + <help>Redistribute connected routes into IS-IS</help> + </properties> + <children> + #include <include/isis/redistribute-level-1-2.xml.i> + </children> + </node> + <node name="kernel"> + <properties> + <help>Redistribute kernel routes into IS-IS</help> + </properties> + <children> + #include <include/isis/redistribute-level-1-2.xml.i> + </children> + </node> + <node name="ospf6"> + <properties> + <help>Redistribute OSPFv3 routes into IS-IS</help> + </properties> + <children> + #include <include/isis/redistribute-level-1-2.xml.i> + </children> + </node> + <node name="ripng"> + <properties> + <help>Redistribute RIPng routes into IS-IS</help> + </properties> + <children> + #include <include/isis/redistribute-level-1-2.xml.i> + </children> + </node> + <node name="static"> + <properties> + <help>Redistribute static routes into IS-IS</help> + </properties> + <children> + #include <include/isis/redistribute-level-1-2.xml.i> + </children> + </node> + </children> + </node> + </children> +</node> +<leafNode name="set-attached-bit"> + <properties> + <help>Set attached bit to identify as L1/L2 router for inter-area traffic</help> + <valueless/> + </properties> +</leafNode> +<leafNode name="set-overload-bit"> + <properties> + <help>Set overload bit to avoid any transit traffic</help> + <valueless/> + </properties> +</leafNode> +<node name="spf-delay-ietf"> + <properties> + <help>IETF SPF delay algorithm</help> + </properties> + <children> + <leafNode name="init-delay"> + <properties> + <help>Delay used while in QUIET state</help> + <valueHelp> + <format>u32:0-60000</format> + <description>Delay used while in QUIET state (in ms)</description> + </valueHelp> + <constraint> + <validator name="numeric" argument="--range 0-60000"/> + </constraint> + </properties> + </leafNode> + <leafNode name="short-delay"> + <properties> + <help>Delay used while in SHORT_WAIT state</help> + <valueHelp> + <format>u32:0-60000</format> + <description>Delay used while in SHORT_WAIT state (in ms)</description> + </valueHelp> + <constraint> + <validator name="numeric" argument="--range 0-60000"/> + </constraint> + </properties> + </leafNode> + <leafNode name="long-delay"> + <properties> + <help>Delay used while in LONG_WAIT</help> + <valueHelp> + <format>u32:0-60000</format> + <description>Delay used while in LONG_WAIT state in ms</description> + </valueHelp> + <constraint> + <validator name="numeric" argument="--range 0-60000"/> + </constraint> + </properties> + </leafNode> + <leafNode name="holddown"> + <properties> + <help>Time with no received IGP events before considering IGP stable</help> + <valueHelp> + <format>u32:0-60000</format> + <description>Time with no received IGP events before considering IGP stable in ms</description> + </valueHelp> + <constraint> + <validator name="numeric" argument="--range 0-60000"/> + </constraint> + </properties> + </leafNode> + <leafNode name="time-to-learn"> + <properties> + <help>Maximum duration needed to learn all the events related to a single failure</help> + <valueHelp> + <format>u32:0-60000</format> + <description>Maximum duration needed to learn all the events related to a single failure in ms</description> + </valueHelp> + <constraint> + <validator name="numeric" argument="--range 0-60000"/> + </constraint> + </properties> + </leafNode> + </children> +</node> +<leafNode name="spf-interval"> + <properties> + <help>Minimum interval between SPF calculations</help> + <valueHelp> + <format>u32:1-120</format> + <description>Interval in seconds</description> + </valueHelp> + <constraint> + <validator name="numeric" argument="--range 1-120"/> + </constraint> + </properties> +</leafNode> +<tagNode name="interface"> + <properties> + <help>Interface params</help> + <completionHelp> + <script>${vyos_completion_dir}/list_interfaces.py</script> + </completionHelp> + </properties> + <children> + #include <include/bfd.xml.i> + <leafNode name="circuit-type"> + <properties> + <help>Configure circuit type for interface</help> + <completionHelp> + <list>level-1 level-1-2 level-2-only</list> + </completionHelp> + <valueHelp> + <format>level-1</format> + <description>Level-1 only adjacencies are formed</description> + </valueHelp> + <valueHelp> + <format>level-1-2</format> + <description>Level-1-2 adjacencies are formed</description> + </valueHelp> + <valueHelp> + <format>level-2-only</format> + <description>Level-2 only adjacencies are formed</description> + </valueHelp> + <constraint> + <regex>^(level-1|level-1-2|level-2-only)$</regex> + </constraint> + </properties> + </leafNode> + <leafNode name="hello-padding"> + <properties> + <help>Add padding to IS-IS hello packets</help> + <valueless/> + </properties> + </leafNode> + <leafNode name="hello-interval"> + <properties> + <help>Set Hello interval</help> + <valueHelp> + <format>u32:1-600</format> + <description>Set Hello interval</description> + </valueHelp> + <constraint> + <validator name="numeric" argument="--range 1-600"/> + </constraint> + </properties> + </leafNode> + <leafNode name="hello-multiplier"> + <properties> + <help>Set Hello interval</help> + <valueHelp> + <format>u32:2-100</format> + <description>Set multiplier for Hello holding time</description> + </valueHelp> + <constraint> + <validator name="numeric" argument="--range 2-100"/> + </constraint> + </properties> + </leafNode> + #include <include/isis/metric.xml.i> + <node name="network"> + <properties> + <help>Set network type</help> + </properties> + <children> + <leafNode name="point-to-point"> + <properties> + <help>point-to-point network type</help> + <valueless/> + </properties> + </leafNode> + </children> + </node> + #include <include/isis/passive.xml.i> + <node name="password"> + <properties> + <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> + </children> + </node> + <leafNode name="priority"> + <properties> + <help>Set priority for Designated Router election</help> + <valueHelp> + <format>u32:0-127</format> + <description>Priority value</description> + </valueHelp> + <constraint> + <validator name="numeric" argument="--range 0-127"/> + </constraint> + </properties> + </leafNode> + <leafNode name="psnp-interval"> + <properties> + <help>Set PSNP interval</help> + <valueHelp> + <format>u32:0-127</format> + <description>PSNP interval in seconds</description> + </valueHelp> + <constraint> + <validator name="numeric" argument="--range 0-127"/> + </constraint> + </properties> + </leafNode> + <leafNode name="no-three-way-handshake"> + <properties> + <help>Disable three-way handshake</help> + <valueless/> + </properties> + </leafNode> + </children> +</tagNode> +#include <include/route-map.xml.i> +<!-- include end -->
\ No newline at end of file diff --git a/interface-definitions/include/isis/redistribute-level-1-2.xml.i b/interface-definitions/include/isis/redistribute-level-1-2.xml.i new file mode 100644 index 000000000..abb85274f --- /dev/null +++ b/interface-definitions/include/isis/redistribute-level-1-2.xml.i @@ -0,0 +1,20 @@ +<!-- include start from isis/redistribute-level-1-2.xml.i --> +<node name="level-1"> + <properties> + <help>Redistribute into level-1</help> + </properties> + <children> + #include <include/isis/metric.xml.i> + #include <include/route-map.xml.i> + </children> +</node> +<node name="level-2"> + <properties> + <help>Redistribute into level-2</help> + </properties> + <children> + #include <include/isis/metric.xml.i> + #include <include/route-map.xml.i> + </children> +</node> +<!-- include end --> diff --git a/interface-definitions/include/nat-rule.xml.i b/interface-definitions/include/nat-rule.xml.i index 579d19bdd..084f1f722 100644 --- a/interface-definitions/include/nat-rule.xml.i +++ b/interface-definitions/include/nat-rule.xml.i @@ -278,7 +278,7 @@ <description>Robust Header Compression</description> </valueHelp> <valueHelp> - <format>0-255</format> + <format>u32:0-255</format> <description>IP protocol number</description> </valueHelp> <constraint> diff --git a/interface-definitions/include/pppoe-access-concentrator.xml.i b/interface-definitions/include/pppoe-access-concentrator.xml.i new file mode 100644 index 000000000..ccfcc1c49 --- /dev/null +++ b/interface-definitions/include/pppoe-access-concentrator.xml.i @@ -0,0 +1,11 @@ +<!-- include start from pppoe-access-concentrator.xml.i --> +<leafNode name="access-concentrator"> + <properties> + <help>Access concentrator name</help> + <constraint> + <regex>[a-zA-Z0-9]{1,100}</regex> + </constraint> + <constraintErrorMessage>Access-concentrator name must be alphanumerical only (max. 100 characters)</constraintErrorMessage> + </properties> +</leafNode> +<!-- include end --> diff --git a/interface-definitions/include/route-map.xml.i b/interface-definitions/include/route-map.xml.i new file mode 100644 index 000000000..88092b7d4 --- /dev/null +++ b/interface-definitions/include/route-map.xml.i @@ -0,0 +1,18 @@ +<!-- include start from route-map.xml.i --> +<leafNode name="route-map"> + <properties> + <help>Specify route-map name to use</help> + <completionHelp> + <path>policy route-map</path> + </completionHelp> + <valueHelp> + <format>txt</format> + <description>Route map name</description> + </valueHelp> + <constraint> + <regex>^[-_a-zA-Z0-9.]+$</regex> + </constraint> + <constraintErrorMessage>Name of route-map can only contain alpha-numeric letters, hyphen and underscores</constraintErrorMessage> + </properties> +</leafNode> +<!-- include end --> diff --git a/interface-definitions/interfaces-bonding.xml.in b/interface-definitions/interfaces-bonding.xml.in index 6c5e2abcc..c63453588 100644 --- a/interface-definitions/interfaces-bonding.xml.in +++ b/interface-definitions/interfaces-bonding.xml.in @@ -49,13 +49,13 @@ </leafNode> </children> </node> - #include <include/interface/interface-description.xml.i> + #include <include/interface/description.xml.i> #include <include/interface/dhcp-options.xml.i> #include <include/interface/dhcpv6-options.xml.i> - #include <include/interface/interface-disable-link-detect.xml.i> - #include <include/interface/interface-disable.xml.i> - #include <include/interface/interface-vrf.xml.i> - #include <include/interface/interface-mirror.xml.i> + #include <include/interface/disable-link-detect.xml.i> + #include <include/interface/disable.xml.i> + #include <include/interface/vrf.xml.i> + #include <include/interface/mirror.xml.i> <leafNode name="hash-policy"> <properties> <help>Bonding transmit hash policy</help> @@ -89,9 +89,9 @@ </properties> <defaultValue>layer2</defaultValue> </leafNode> - #include <include/interface/interface-ipv4-options.xml.i> - #include <include/interface/interface-ipv6-options.xml.i> - #include <include/interface/interface-mac.xml.i> + #include <include/interface/ipv4-options.xml.i> + #include <include/interface/ipv6-options.xml.i> + #include <include/interface/mac.xml.i> <leafNode name="min-links"> <properties> <help>Minimum number of member interfaces required up before enabling bond</help> @@ -182,7 +182,7 @@ </leafNode> </children> </node> - #include <include/interface/interface-mtu-68-16000.xml.i> + #include <include/interface/mtu-68-16000.xml.i> <leafNode name="primary"> <properties> <help>Primary device interface</help> diff --git a/interface-definitions/interfaces-bridge.xml.in b/interface-definitions/interfaces-bridge.xml.in index 15feedca1..144f43f32 100644 --- a/interface-definitions/interfaces-bridge.xml.in +++ b/interface-definitions/interfaces-bridge.xml.in @@ -21,11 +21,11 @@ <properties> <help>MAC address aging interval</help> <valueHelp> - <format>0</format> + <format>u32:0</format> <description>Disable MAC address learning (always flood)</description> </valueHelp> <valueHelp> - <format>10-1000000</format> + <format>u32:10-1000000</format> <description>MAC address aging time in seconds (default: 300)</description> </valueHelp> <constraint> @@ -34,18 +34,18 @@ </properties> <defaultValue>300</defaultValue> </leafNode> - #include <include/interface/interface-description.xml.i> + #include <include/interface/description.xml.i> #include <include/interface/dhcp-options.xml.i> #include <include/interface/dhcpv6-options.xml.i> - #include <include/interface/interface-disable-link-detect.xml.i> - #include <include/interface/interface-disable.xml.i> - #include <include/interface/interface-vrf.xml.i> - #include <include/interface/interface-mtu-68-16000.xml.i> + #include <include/interface/disable-link-detect.xml.i> + #include <include/interface/disable.xml.i> + #include <include/interface/vrf.xml.i> + #include <include/interface/mtu-68-16000.xml.i> <leafNode name="forwarding-delay"> <properties> <help>Forwarding delay</help> <valueHelp> - <format>0-200</format> + <format>u32:0-200</format> <description>Spanning Tree Protocol forwarding delay in seconds (default 15)</description> </valueHelp> <constraint> @@ -59,7 +59,7 @@ <properties> <help>Hello packet advertisment interval</help> <valueHelp> - <format>1-10</format> + <format>u32:1-10</format> <description>Spanning Tree Protocol hello advertisement interval in seconds (default 2)</description> </valueHelp> <constraint> @@ -82,15 +82,21 @@ </leafNode> </children> </node> - #include <include/interface/interface-ipv4-options.xml.i> - #include <include/interface/interface-ipv6-options.xml.i> - #include <include/interface/interface-mac.xml.i> - #include <include/interface/interface-mirror.xml.i> + #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> + <leafNode name="enable-vlan"> + <properties> + <help>Enable VLAN aware bridge</help> + <valueless/> + </properties> + </leafNode> <leafNode name="max-age"> <properties> <help>Interval at which neighbor bridges are removed</help> <valueHelp> - <format>1-40</format> + <format>u32:1-40</format> <description>Bridge maximum aging time in seconds (default 20)</description> </valueHelp> <constraint> @@ -117,7 +123,7 @@ <properties> <help>Specify VLAN id which should natively be present on the link</help> <valueHelp> - <format>1-4094</format> + <format>u32:1-4094</format> <description>Virtual Local Area Network (VLAN) ID</description> </valueHelp> <constraint> @@ -138,7 +144,7 @@ <description>VLAN id range allowed on this interface (use '-' as delimiter)</description> </valueHelp> <constraint> - <regex>^([0-9]{1,4}-[0-9]{1,4})|([0-9]{1,4})$</regex> + <validator name="allowed-vlan"/> </constraint> <constraintErrorMessage>not a valid VLAN ID value or range</constraintErrorMessage> <multi/> @@ -148,7 +154,7 @@ <properties> <help>Bridge port cost</help> <valueHelp> - <format>1-65535</format> + <format>u32:1-65535</format> <description>Path cost value for Spanning Tree Protocol</description> </valueHelp> <constraint> @@ -162,7 +168,7 @@ <properties> <help>Bridge port priority</help> <valueHelp> - <format>0-63</format> + <format>u32:0-63</format> <description>Bridge port priority</description> </valueHelp> <constraint> @@ -172,6 +178,12 @@ </properties> <defaultValue>32</defaultValue> </leafNode> + <leafNode name="isolated"> + <properties> + <help>Port is isolated (also known as Private-VLAN)</help> + <valueless/> + </properties> + </leafNode> </children> </tagNode> </children> @@ -180,7 +192,7 @@ <properties> <help>Priority for this bridge</help> <valueHelp> - <format>0-65535</format> + <format>u32:0-65535</format> <description>Bridge priority (default 32768)</description> </valueHelp> <constraint> @@ -196,7 +208,6 @@ <valueless/> </properties> </leafNode> - #include <include/interface/vif-s.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 84c6903c7..2bc88c1a7 100644 --- a/interface-definitions/interfaces-dummy.xml.in +++ b/interface-definitions/interfaces-dummy.xml.in @@ -17,17 +17,17 @@ </properties> <children> #include <include/interface/address-ipv4-ipv6.xml.i> - #include <include/interface/interface-description.xml.i> - #include <include/interface/interface-disable.xml.i> + #include <include/interface/description.xml.i> + #include <include/interface/disable.xml.i> <node name="ip"> <properties> <help>IPv4 routing parameters</help> </properties> <children> - #include <include/interface/interface-source-validation.xml.i> + #include <include/interface/source-validation.xml.i> </children> </node> - #include <include/interface/interface-vrf.xml.i> + #include <include/interface/vrf.xml.i> </children> </tagNode> </children> diff --git a/interface-definitions/interfaces-ethernet.xml.in b/interface-definitions/interfaces-ethernet.xml.in index 9857e6c8d..27d555552 100644 --- a/interface-definitions/interfaces-ethernet.xml.in +++ b/interface-definitions/interfaces-ethernet.xml.in @@ -17,7 +17,7 @@ </properties> <children> #include <include/interface/address-ipv4-ipv6-dhcp.xml.i> - #include <include/interface/interface-description.xml.i> + #include <include/interface/description.xml.i> #include <include/interface/dhcp-options.xml.i> #include <include/interface/dhcpv6-options.xml.i> <leafNode name="disable-flow-control"> @@ -26,8 +26,8 @@ <valueless/> </properties> </leafNode> - #include <include/interface/interface-disable-link-detect.xml.i> - #include <include/interface/interface-disable.xml.i> + #include <include/interface/disable-link-detect.xml.i> + #include <include/interface/disable.xml.i> <leafNode name="duplex"> <properties> <help>Duplex mode</help> @@ -53,13 +53,13 @@ </properties> <defaultValue>auto</defaultValue> </leafNode> - #include <include/interface/interface-eapol.xml.i> - #include <include/interface/interface-hw-id.xml.i> - #include <include/interface/interface-ipv4-options.xml.i> - #include <include/interface/interface-ipv6-options.xml.i> - #include <include/interface/interface-mac.xml.i> - #include <include/interface/interface-mtu-68-16000.xml.i> - #include <include/interface/interface-mirror.xml.i> + #include <include/interface/eapol.xml.i> + #include <include/interface/hw-id.xml.i> + #include <include/interface/ipv4-options.xml.i> + #include <include/interface/ipv6-options.xml.i> + #include <include/interface/mac.xml.i> + #include <include/interface/mtu-68-16000.xml.i> + #include <include/interface/mirror.xml.i> <node name="offload"> <properties> <help>Configurable offload options</help> @@ -101,12 +101,6 @@ <valueless/> </properties> </leafNode> - <leafNode name="ufo"> - <properties> - <help>Enable UDP Fragmentation Offloading</help> - <valueless/> - </properties> - </leafNode> </children> </node> <leafNode name="speed"> @@ -199,7 +193,7 @@ </node> #include <include/interface/vif-s.xml.i> #include <include/interface/vif.xml.i> - #include <include/interface/interface-vrf.xml.i> + #include <include/interface/vrf.xml.i> </children> </tagNode> </children> diff --git a/interface-definitions/interfaces-geneve.xml.in b/interface-definitions/interfaces-geneve.xml.in index 50031b8b3..6620c8aff 100644 --- a/interface-definitions/interfaces-geneve.xml.in +++ b/interface-definitions/interfaces-geneve.xml.in @@ -17,12 +17,12 @@ </properties> <children> #include <include/interface/address-ipv4-ipv6.xml.i> - #include <include/interface/interface-description.xml.i> - #include <include/interface/interface-disable.xml.i> - #include <include/interface/interface-ipv4-options.xml.i> - #include <include/interface/interface-ipv6-options.xml.i> - #include <include/interface/interface-mac.xml.i> - #include <include/interface/interface-mtu-1450-16000.xml.i> + #include <include/interface/description.xml.i> + #include <include/interface/disable.xml.i> + #include <include/interface/ipv4-options.xml.i> + #include <include/interface/ipv6-options.xml.i> + #include <include/interface/mac.xml.i> + #include <include/interface/mtu-1450-16000.xml.i> #include <include/tunnel-remote.xml.i> <leafNode name="vni"> <properties> diff --git a/interface-definitions/interfaces-l2tpv3.xml.in b/interface-definitions/interfaces-l2tpv3.xml.in index 2edf08070..1cd30b86e 100644 --- a/interface-definitions/interfaces-l2tpv3.xml.in +++ b/interface-definitions/interfaces-l2tpv3.xml.in @@ -17,12 +17,12 @@ </properties> <children> #include <include/interface/address-ipv4-ipv6.xml.i> - #include <include/interface/interface-description.xml.i> + #include <include/interface/description.xml.i> <leafNode name="destination-port"> <properties> <help>UDP destination port for L2TPv3 tunnel (default: 5000)</help> <valueHelp> - <format>1-65535</format> + <format>u32:1-65535</format> <description>Numeric IP port</description> </valueHelp> <constraint> @@ -31,7 +31,7 @@ </properties> <defaultValue>5000</defaultValue> </leafNode> - #include <include/interface/interface-disable.xml.i> + #include <include/interface/disable.xml.i> <leafNode name="encapsulation"> <properties> <help>Encapsulation type (default: UDP)</help> @@ -53,10 +53,10 @@ </properties> <defaultValue>udp</defaultValue> </leafNode> - #include <include/interface/interface-ipv4-options.xml.i> - #include <include/interface/interface-ipv6-options.xml.i> + #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/interface-mtu-68-16000.xml.i> + #include <include/interface/mtu-68-16000.xml.i> <leafNode name="mtu"> <defaultValue>1488</defaultValue> </leafNode> @@ -64,7 +64,7 @@ <properties> <help>Peer session identifier</help> <valueHelp> - <format>1-429496729</format> + <format>u32:1-429496729</format> <description>L2TPv3 peer session identifier</description> </valueHelp> <constraint> @@ -76,7 +76,7 @@ <properties> <help>Peer tunnel identifier</help> <valueHelp> - <format>1-429496729</format> + <format>u32:1-429496729</format> <description>L2TPv3 peer tunnel identifier</description> </valueHelp> <constraint> @@ -89,7 +89,7 @@ <properties> <help>Session identifier</help> <valueHelp> - <format>1-429496729</format> + <format>u32:1-429496729</format> <description>L2TPv3 session identifier</description> </valueHelp> <constraint> @@ -101,7 +101,7 @@ <properties> <help>UDP source port for L2TPv3 tunnel (default: 5000)</help> <valueHelp> - <format>1-65535</format> + <format>u32:1-65535</format> <description>Numeric IP port</description> </valueHelp> <constraint> @@ -114,7 +114,7 @@ <properties> <help>Local tunnel identifier</help> <valueHelp> - <format>1-429496729</format> + <format>u32:1-429496729</format> <description>L2TPv3 local tunnel identifier</description> </valueHelp> <constraint> @@ -122,7 +122,7 @@ </constraint> </properties> </leafNode> - #include <include/interface/interface-vrf.xml.i> + #include <include/interface/vrf.xml.i> </children> </tagNode> </children> diff --git a/interface-definitions/interfaces-loopback.xml.in b/interface-definitions/interfaces-loopback.xml.in index 5d0ca5b0a..7be15ab89 100644 --- a/interface-definitions/interfaces-loopback.xml.in +++ b/interface-definitions/interfaces-loopback.xml.in @@ -17,13 +17,13 @@ </properties> <children> #include <include/interface/address-ipv4-ipv6.xml.i> - #include <include/interface/interface-description.xml.i> + #include <include/interface/description.xml.i> <node name="ip"> <properties> <help>IPv4 routing parameters</help> </properties> <children> - #include <include/interface/interface-source-validation.xml.i> + #include <include/interface/source-validation.xml.i> </children> </node> </children> diff --git a/interface-definitions/interfaces-macsec.xml.in b/interface-definitions/interfaces-macsec.xml.in index fce88b21c..4a566ef8b 100644 --- a/interface-definitions/interfaces-macsec.xml.in +++ b/interface-definitions/interfaces-macsec.xml.in @@ -17,8 +17,8 @@ </properties> <children> #include <include/interface/address-ipv4-ipv6.xml.i> - #include <include/interface/interface-ipv4-options.xml.i> - #include <include/interface/interface-ipv6-options.xml.i> + #include <include/interface/ipv4-options.xml.i> + #include <include/interface/ipv6-options.xml.i> <node name="security"> <properties> <help>Security/Encryption Settings</help> @@ -82,7 +82,7 @@ <properties> <help>Priority of MACsec Key Agreement protocol (MKA) actor (default: 255)</help> <valueHelp> - <format>0-255</format> + <format>u32:0-255</format> <description>MACsec Key Agreement protocol (MKA) priority</description> </valueHelp> <constraint> @@ -97,11 +97,11 @@ <properties> <help>IEEE 802.1X/MACsec replay protection window</help> <valueHelp> - <format>0</format> + <format>u32:0</format> <description>No replay window, strict check</description> </valueHelp> <valueHelp> - <format>1-4294967295</format> + <format>u32:1-4294967295</format> <description>Number of packets that could be misordered</description> </valueHelp> <constraint> @@ -111,14 +111,14 @@ </leafNode> </children> </node> - #include <include/interface/interface-description.xml.i> - #include <include/interface/interface-disable.xml.i> - #include <include/interface/interface-mtu-68-16000.xml.i> + #include <include/interface/description.xml.i> + #include <include/interface/disable.xml.i> + #include <include/interface/mtu-68-16000.xml.i> <leafNode name="mtu"> <defaultValue>1460</defaultValue> </leafNode> #include <include/source-interface-ethernet.xml.i> - #include <include/interface/interface-vrf.xml.i> + #include <include/interface/vrf.xml.i> </children> </tagNode> </children> diff --git a/interface-definitions/interfaces-openvpn.xml.in b/interface-definitions/interfaces-openvpn.xml.in index 681290570..40f8fe65c 100644 --- a/interface-definitions/interfaces-openvpn.xml.in +++ b/interface-definitions/interfaces-openvpn.xml.in @@ -33,7 +33,7 @@ </leafNode> </children> </node> - #include <include/interface/interface-description.xml.i> + #include <include/interface/description.xml.i> <leafNode name="device-type"> <properties> <help>OpenVPN interface device-type (default: tun)</help> @@ -54,7 +54,7 @@ </properties> <defaultValue>tun</defaultValue> </leafNode> - #include <include/interface/interface-disable.xml.i> + #include <include/interface/disable.xml.i> <node name="encryption"> <properties> <help>Data Encryption settings</help> @@ -165,7 +165,7 @@ </leafNode> </children> </node> - #include <include/interface/interface-ipv6-options.xml.i> + #include <include/interface/ipv6-options.xml.i> <leafNode name="hash"> <properties> <help>Hashing Algorithm</help> @@ -206,7 +206,7 @@ <properties> <help>Maximum number of keepalive packet failures (default: 60)</help> <valueHelp> - <format>0-1000</format> + <format>u32:0-1000</format> <description>Maximum number of keepalive packet failures</description> </valueHelp> <constraint> @@ -219,7 +219,7 @@ <properties> <help>Keepalive packet interval in seconds (default: 10)</help> <valueHelp> - <format>0-600</format> + <format>u32:0-600</format> <description>Keepalive packet interval (seconds)</description> </valueHelp> <constraint> @@ -268,7 +268,7 @@ <properties> <help>Local port number to accept connections</help> <valueHelp> - <format>1-65535</format> + <format>u32:1-65535</format> <description>Numeric IP port</description> </valueHelp> <constraint> @@ -378,7 +378,7 @@ <properties> <help>Remote port number to connect to</help> <valueHelp> - <format>1-65535</format> + <format>u32:1-65535</format> <description>Numeric IP port</description> </valueHelp> <constraint> @@ -546,7 +546,7 @@ <properties> <help>Number of maximum client connections</help> <valueHelp> - <format>1-4096</format> + <format>u32:1-4096</format> <description>Number of concurrent clients</description> </valueHelp> <constraint> @@ -571,7 +571,7 @@ <multi/> </properties> </leafNode> - <leafNode name="push-route"> + <tagNode name="push-route"> <properties> <help>Route to be pushed to all clients</help> <valueHelp> @@ -585,9 +585,23 @@ <constraint> <validator name="ip-prefix"/> </constraint> - <multi/> </properties> - </leafNode> + <children> + <leafNode name="metric"> + <properties> + <help>Set metric for this route</help> + <valueHelp> + <format>u32:0-4294967295</format> + <description>Metric for this route</description> + </valueHelp> + <constraint> + <validator name="numeric" argument="--range 0-4294967295"/> + </constraint> + </properties> + <defaultValue>0</defaultValue> + </leafNode> + </children> + </tagNode> <leafNode name="reject-unconfigured-clients"> <properties> <help>Reject connections from clients that are not explicitly configured</help> @@ -755,7 +769,7 @@ <valueless/> </properties> </leafNode> - #include <include/interface/interface-vrf.xml.i> + #include <include/interface/vrf.xml.i> </children> </tagNode> </children> diff --git a/interface-definitions/interfaces-pppoe.xml.in b/interface-definitions/interfaces-pppoe.xml.in index 96479e057..198a53c90 100644 --- a/interface-definitions/interfaces-pppoe.xml.in +++ b/interface-definitions/interfaces-pppoe.xml.in @@ -5,7 +5,7 @@ <tagNode name="pppoe" owner="${vyos_conf_scripts_dir}/interfaces-pppoe.py"> <properties> <help>Point-to-Point Protocol over Ethernet (PPPoE)</help> - <priority>321</priority> + <priority>322</priority> <constraint> <regex>^pppoe[0-9]+$</regex> </constraint> @@ -16,17 +16,9 @@ </valueHelp> </properties> <children> - <leafNode name="access-concentrator"> - <properties> - <help>Access concentrator name (only connect to this concentrator)</help> - <constraint> - <regex>[a-zA-Z0-9]+$</regex> - </constraint> - <constraintErrorMessage>Access concentrator name must be composed of uppper and lower case letters or numbers only</constraintErrorMessage> - </properties> - </leafNode> + #include <include/pppoe-access-concentrator.xml.i> #include <include/interface/authentication.xml.i> - #include <include/interface/interface-dial-on-demand.xml.i> + #include <include/interface/dial-on-demand.xml.i> <leafNode name="default-route"> <properties> <help>Default route insertion behaviour (default: auto)</help> @@ -53,16 +45,20 @@ <defaultValue>auto</defaultValue> </leafNode> #include <include/interface/dhcpv6-options.xml.i> - #include <include/interface/interface-description.xml.i> - #include <include/interface/interface-disable.xml.i> - #include <include/interface/interface-vrf.xml.i> + #include <include/interface/description.xml.i> + #include <include/interface/disable.xml.i> + #include <include/interface/vrf.xml.i> <leafNode name="idle-timeout"> <properties> <help>Delay before disconnecting idle session (in seconds)</help> <valueHelp> - <format>n</format> + <format>u32:0-86400</format> <description>Idle timeout in seconds</description> </valueHelp> + <constraint> + <validator name="numeric" argument="--range 0-86400"/> + </constraint> + <constraintErrorMessage>Timeout must be in range 0 to 86400</constraintErrorMessage> </properties> </leafNode> <node name="ip"> @@ -70,7 +66,7 @@ <help>IPv4 routing parameters</help> </properties> <children> - #include <include/interface/interface-source-validation.xml.i> + #include <include/interface/source-validation.xml.i> </children> </node> <node name="ipv6"> @@ -88,14 +84,7 @@ </node> </children> </node> - <leafNode name="source-interface"> - <properties> - <help>Physical Interface used for this PPPoE session</help> - <completionHelp> - <script>${vyos_completion_dir}/list_interfaces.py --broadcast</script> - </completionHelp> - </properties> - </leafNode> + #include <include/source-interface.xml.i> <leafNode name="local-address"> <properties> <help>IPv4 address of local end of the PPPoE link</help> @@ -108,7 +97,7 @@ </constraint> </properties> </leafNode> - #include <include/interface/interface-mtu-68-1500.xml.i> + #include <include/interface/mtu-68-1500.xml.i> <leafNode name="mtu"> <defaultValue>1492</defaultValue> </leafNode> @@ -136,7 +125,7 @@ <constraint> <regex>[a-zA-Z0-9]+$</regex> </constraint> - <constraintErrorMessage>Service name must be composed of uppper and lower case letters or numbers only</constraintErrorMessage> + <constraintErrorMessage>Service name must be alphanumeric only</constraintErrorMessage> </properties> </leafNode> </children> diff --git a/interface-definitions/interfaces-pseudo-ethernet.xml.in b/interface-definitions/interfaces-pseudo-ethernet.xml.in index 136841290..366892032 100644 --- a/interface-definitions/interfaces-pseudo-ethernet.xml.in +++ b/interface-definitions/interfaces-pseudo-ethernet.xml.in @@ -17,16 +17,16 @@ </properties> <children> #include <include/interface/address-ipv4-ipv6-dhcp.xml.i> - #include <include/interface/interface-description.xml.i> + #include <include/interface/description.xml.i> #include <include/interface/dhcp-options.xml.i> #include <include/interface/dhcpv6-options.xml.i> - #include <include/interface/interface-disable-link-detect.xml.i> - #include <include/interface/interface-disable.xml.i> - #include <include/interface/interface-vrf.xml.i> - #include <include/interface/interface-ipv4-options.xml.i> - #include <include/interface/interface-ipv6-options.xml.i> + #include <include/interface/disable-link-detect.xml.i> + #include <include/interface/disable.xml.i> + #include <include/interface/vrf.xml.i> + #include <include/interface/ipv4-options.xml.i> + #include <include/interface/ipv6-options.xml.i> #include <include/source-interface-ethernet.xml.i> - #include <include/interface/interface-mac.xml.i> + #include <include/interface/mac.xml.i> <leafNode name="mode"> <properties> <help>Receive mode (default: private)</help> @@ -56,7 +56,7 @@ </properties> <defaultValue>private</defaultValue> </leafNode> - #include <include/interface/interface-mtu-68-16000.xml.i> + #include <include/interface/mtu-68-16000.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 bc1f3092d..df9b58992 100644 --- a/interface-definitions/interfaces-tunnel.xml.in +++ b/interface-definitions/interfaces-tunnel.xml.in @@ -16,17 +16,17 @@ </valueHelp> </properties> <children> - #include <include/interface/interface-description.xml.i> + #include <include/interface/description.xml.i> #include <include/interface/address-ipv4-ipv6.xml.i> - #include <include/interface/interface-disable.xml.i> - #include <include/interface/interface-disable-link-detect.xml.i> - #include <include/interface/interface-vrf.xml.i> - #include <include/interface/interface-mtu-64-8024.xml.i> + #include <include/interface/disable.xml.i> + #include <include/interface/disable-link-detect.xml.i> + #include <include/interface/vrf.xml.i> + #include <include/interface/mtu-64-8024.xml.i> <leafNode name="mtu"> <defaultValue>1476</defaultValue> </leafNode> - #include <include/interface/interface-ipv4-options.xml.i> - #include <include/interface/interface-ipv6-options.xml.i> + #include <include/interface/ipv4-options.xml.i> + #include <include/interface/ipv6-options.xml.i> #include <include/source-address-ipv4-ipv6.xml.i> #include <include/tunnel-remote.xml.i> #include <include/source-interface.xml.i> @@ -151,9 +151,9 @@ <valueless/> </properties> </leafNode> - #include <include/interface/interface-parameters-key.xml.i> - #include <include/interface/interface-parameters-tos.xml.i> - #include <include/interface/interface-parameters-ttl.xml.i> + #include <include/interface/parameters-key.xml.i> + #include <include/interface/parameters-tos.xml.i> + #include <include/interface/parameters-ttl.xml.i> <leafNode name="ttl"> <defaultValue>64</defaultValue> </leafNode> @@ -171,8 +171,8 @@ <list>none</list> </completionHelp> <valueHelp> - <format>0-255</format> - <description>Encaplimit (default 4)</description> + <format>u32:0-255</format> + <description>Encaplimit (default: 4)</description> </valueHelp> <valueHelp> <format>none</format> @@ -186,12 +186,12 @@ </properties> <defaultValue>4</defaultValue> </leafNode> - #include <include/interface/interface-parameters-flowlabel.xml.i> + #include <include/interface/parameters-flowlabel.xml.i> <leafNode name="hoplimit"> <properties> <help>Hoplimit</help> <valueHelp> - <format>0-255</format> + <format>u32:0-255</format> <description>Hoplimit (default 64)</description> </valueHelp> <constraint> @@ -205,7 +205,7 @@ <properties> <help>Traffic class (Tclass)</help> <valueHelp> - <format>0x0-0x0FFFFF</format> + <format>0x0-0x0fffff</format> <description>Traffic class, 'inherit' or hex value</description> </valueHelp> <constraint> diff --git a/interface-definitions/interfaces-vxlan.xml.in b/interface-definitions/interfaces-vxlan.xml.in index 848c6259e..a637baf3f 100644 --- a/interface-definitions/interfaces-vxlan.xml.in +++ b/interface-definitions/interfaces-vxlan.xml.in @@ -17,8 +17,8 @@ </properties> <children> #include <include/interface/address-ipv4-ipv6.xml.i> - #include <include/interface/interface-description.xml.i> - #include <include/interface/interface-disable.xml.i> + #include <include/interface/description.xml.i> + #include <include/interface/disable.xml.i> <leafNode name="group"> <properties> <help>Multicast group address for VXLAN interface</help> @@ -35,10 +35,10 @@ </constraint> </properties> </leafNode> - #include <include/interface/interface-ipv4-options.xml.i> - #include <include/interface/interface-ipv6-options.xml.i> - #include <include/interface/interface-mac.xml.i> - #include <include/interface/interface-mtu-1200-16000.xml.i> + #include <include/interface/ipv4-options.xml.i> + #include <include/interface/ipv6-options.xml.i> + #include <include/interface/mac.xml.i> + #include <include/interface/mtu-1200-16000.xml.i> <leafNode name="mtu"> <defaultValue>1450</defaultValue> </leafNode> @@ -70,7 +70,7 @@ </constraint> </properties> </leafNode> - #include <include/interface/interface-vrf.xml.i> + #include <include/interface/vrf.xml.i> </children> </tagNode> </children> diff --git a/interface-definitions/interfaces-wireguard.xml.in b/interface-definitions/interfaces-wireguard.xml.in index 378251fed..73328c16a 100644 --- a/interface-definitions/interfaces-wireguard.xml.in +++ b/interface-definitions/interfaces-wireguard.xml.in @@ -17,16 +17,16 @@ </properties> <children> #include <include/interface/address-ipv4-ipv6.xml.i> - #include <include/interface/interface-description.xml.i> - #include <include/interface/interface-disable.xml.i> - #include <include/interface/interface-vrf.xml.i> + #include <include/interface/description.xml.i> + #include <include/interface/disable.xml.i> + #include <include/interface/vrf.xml.i> #include <include/port-number.xml.i> - #include <include/interface/interface-mtu-68-16000.xml.i> + #include <include/interface/mtu-68-16000.xml.i> <leafNode name="mtu"> <defaultValue>1420</defaultValue> </leafNode> - #include <include/interface/interface-ipv4-options.xml.i> - #include <include/interface/interface-ipv6-options.xml.i> + #include <include/interface/ipv4-options.xml.i> + #include <include/interface/ipv6-options.xml.i> <leafNode name="fwmark"> <properties> <help>A 32-bit fwmark value set on all outgoing packets</help> @@ -118,7 +118,7 @@ <properties> <help>Interval to send keepalive messages</help> <valueHelp> - <format>1-65535</format> + <format>u32:1-65535</format> <description>Interval in seconds</description> </valueHelp> <constraint> diff --git a/interface-definitions/interfaces-wireless.xml.in b/interface-definitions/interfaces-wireless.xml.in index aaeb285f1..048c7b475 100644 --- a/interface-definitions/interfaces-wireless.xml.in +++ b/interface-definitions/interfaces-wireless.xml.in @@ -206,7 +206,7 @@ <properties> <help>Number of antennas on this card</help> <valueHelp> - <format>1-8</format> + <format>u32:1-8</format> <description>Number of antennas for this card</description> </valueHelp> <constraint> @@ -464,7 +464,7 @@ <constraintErrorMessage>Invalid ISO/IEC 3166-1 Country Code</constraintErrorMessage> </properties> </leafNode> - #include <include/interface/interface-description.xml.i> + #include <include/interface/description.xml.i> #include <include/interface/dhcp-options.xml.i> #include <include/interface/dhcpv6-options.xml.i> <leafNode name="disable-broadcast-ssid"> @@ -473,25 +473,25 @@ <valueless/> </properties> </leafNode> - #include <include/interface/interface-disable-link-detect.xml.i> - #include <include/interface/interface-disable.xml.i> - #include <include/interface/interface-vrf.xml.i> + #include <include/interface/disable-link-detect.xml.i> + #include <include/interface/disable.xml.i> + #include <include/interface/vrf.xml.i> <leafNode name="expunge-failing-stations"> <properties> <help>Disassociate stations based on excessive transmission failures</help> <valueless/> </properties> </leafNode> - #include <include/interface/interface-ipv4-options.xml.i> - #include <include/interface/interface-ipv6-options.xml.i> - #include <include/interface/interface-hw-id.xml.i> + #include <include/interface/ipv4-options.xml.i> + #include <include/interface/ipv6-options.xml.i> + #include <include/interface/hw-id.xml.i> <leafNode name="isolate-stations"> <properties> <help>Isolate stations on the AP so they cannot see each other</help> <valueless/> </properties> </leafNode> - #include <include/interface/interface-mac.xml.i> + #include <include/interface/mac.xml.i> <leafNode name="max-stations"> <properties> <help>Maximum number of wireless radio stations. Excess stations will be rejected upon authentication request.</help> diff --git a/interface-definitions/interfaces-wwan.xml.in b/interface-definitions/interfaces-wwan.xml.in index 647ce0bc1..19f152a06 100644 --- a/interface-definitions/interfaces-wwan.xml.in +++ b/interface-definitions/interfaces-wwan.xml.in @@ -28,17 +28,17 @@ #include <include/interface/authentication.xml.i> #include <include/interface/dhcp-options.xml.i> #include <include/interface/dhcpv6-options.xml.i> - #include <include/interface/interface-description.xml.i> - #include <include/interface/interface-disable.xml.i> - #include <include/interface/interface-vrf.xml.i> - #include <include/interface/interface-disable-link-detect.xml.i> - #include <include/interface/interface-mtu-68-1500.xml.i> + #include <include/interface/description.xml.i> + #include <include/interface/disable.xml.i> + #include <include/interface/vrf.xml.i> + #include <include/interface/disable-link-detect.xml.i> + #include <include/interface/mtu-68-1500.xml.i> <leafNode name="mtu"> <defaultValue>1430</defaultValue> </leafNode> - #include <include/interface/interface-ipv4-options.xml.i> - #include <include/interface/interface-ipv6-options.xml.i> - #include <include/interface/interface-dial-on-demand.xml.i> + #include <include/interface/ipv4-options.xml.i> + #include <include/interface/ipv6-options.xml.i> + #include <include/interface/dial-on-demand.xml.i> </children> </tagNode> </children> diff --git a/interface-definitions/ipsec-settings.xml.in b/interface-definitions/ipsec-settings.xml.in index bc54baa27..dbf6625fb 100644 --- a/interface-definitions/ipsec-settings.xml.in +++ b/interface-definitions/ipsec-settings.xml.in @@ -4,7 +4,7 @@ <children> <node name="ipsec"> <children> - <node name="options" owner="${vyos_conf_scripts_dir}/ipsec-settings.py"> + <node name="options" owner="${vyos_conf_scripts_dir}/ipsec-settings.py from-options"> <properties> <help>Global IPsec settings</help> </properties> diff --git a/interface-definitions/lldp.xml.in b/interface-definitions/lldp.xml.in index e14abae14..32ef0ad14 100644 --- a/interface-definitions/lldp.xml.in +++ b/interface-definitions/lldp.xml.in @@ -105,7 +105,7 @@ <properties> <help>ECS ELIN (Emergency location identifier number)</help> <valueHelp> - <format>0-9999999999</format> + <format>u32:0-9999999999</format> <description>Emergency Call Service ELIN number (between 10-25 numbers)</description> </valueHelp> <constraint> diff --git a/interface-definitions/ntp.xml.in b/interface-definitions/ntp.xml.in index 2bfac900b..a518a9def 100644 --- a/interface-definitions/ntp.xml.in +++ b/interface-definitions/ntp.xml.in @@ -82,7 +82,7 @@ </children> </node> #include <include/listen-address.xml.i> - #include <include/interface/interface-vrf.xml.i> + #include <include/interface/vrf.xml.i> </children> </node> </children> diff --git a/interface-definitions/protocols-igmp.xml.in b/interface-definitions/protocols-igmp.xml.in index a9b11e1a3..e10340512 100644 --- a/interface-definitions/protocols-igmp.xml.in +++ b/interface-definitions/protocols-igmp.xml.in @@ -46,9 +46,16 @@ <leafNode name="version"> <properties> <help>IGMP version</help> + <completionHelp> + <list>2 3</list> + </completionHelp> <valueHelp> - <format>2-3</format> - <description>IGMP version</description> + <format>2</format> + <description>IGMP version 2</description> + </valueHelp> + <valueHelp> + <format>3</format> + <description>IGMP version 3</description> </valueHelp> <constraint> <validator name="numeric" argument="--range 2-3"/> @@ -59,7 +66,7 @@ <properties> <help>IGMP host query interval</help> <valueHelp> - <format>1-1800</format> + <format>u32:1-1800</format> <description>Query interval in seconds</description> </valueHelp> <constraint> @@ -71,7 +78,7 @@ <properties> <help>IGMP max query response time</help> <valueHelp> - <format>10-250</format> + <format>u32:10-250</format> <description>Query response value in deci-seconds</description> </valueHelp> <constraint> diff --git a/interface-definitions/protocols-isis.xml.in b/interface-definitions/protocols-isis.xml.in index 624c72a4c..e0bc47bb9 100644 --- a/interface-definitions/protocols-isis.xml.in +++ b/interface-definitions/protocols-isis.xml.in @@ -2,781 +2,15 @@ <interfaceDefinition> <node name="protocols"> <children> - <tagNode name="isis" owner="${vyos_conf_scripts_dir}/protocols_isis.py"> + <node name="isis" owner="${vyos_conf_scripts_dir}/protocols_isis.py"> <properties> <help>Intermediate System to Intermediate System (IS-IS)</help> <priority>610</priority> - <valueHelp> - <format>text(TAG)</format> - <description>ISO Routing area tag</description> - </valueHelp> </properties> <children> - <node name="area-password"> - <properties> - <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> - </children> - </node> - <node name="default-information"> - <properties> - <help>Control distribution of default information</help> - </properties> - <children> - <node name="originate"> - <properties> - <help>Distribute a default route</help> - </properties> - <children> - <node name="ipv4"> - <properties> - <help>Distribute default route for IPv4</help> - </properties> - <children> - <leafNode name="level-1"> - <properties> - <help>Distribute default route into level-1</help> - <valueless/> - </properties> - </leafNode> - <leafNode name="level-2"> - <properties> - <help>Distribute default route into level-2</help> - <valueless/> - </properties> - </leafNode> - </children> - </node> - <node name="ipv6"> - <properties> - <help>Distribute default route for IPv6</help> - </properties> - <children> - <leafNode name="level-1"> - <properties> - <help>Distribute default route into level-1</help> - <completionHelp> - <list>always</list> - </completionHelp> - <valueHelp> - <format>always</format> - <description>Always advertise default route</description> - </valueHelp> - </properties> - </leafNode> - <leafNode name="level-2"> - <properties> - <help>Distribute default route into level-2</help> - <completionHelp> - <list>always</list> - </completionHelp> - <valueHelp> - <format>always</format> - <description>Always advertise default route</description> - </valueHelp> - </properties> - </leafNode> - </children> - </node> - </children> - </node> - </children> - </node> - <node name="domain-password"> - <properties> - <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> ---> - </children> - </node> - <leafNode name="dynamic-hostname"> - <properties> - <help>Dynamic hostname for IS-IS</help> - <valueless/> - </properties> - </leafNode> - <leafNode name="level"> - <properties> - <help>IS-IS level number</help> - <completionHelp> - <list>level-1 level-1-2 level-2</list> - </completionHelp> - <valueHelp> - <format>level-1</format> - <description>Act as a station router</description> - </valueHelp> - <valueHelp> - <format>level-1-2</format> - <description>Act as both a station and an area router</description> - </valueHelp> - <valueHelp> - <format>level-2</format> - <description>Act as an area router</description> - </valueHelp> - <constraint> - <regex>^(level-1|level-1-2|level-2)$</regex> - </constraint> - </properties> - </leafNode> - <leafNode name="lsp-gen-interval"> - <properties> - <help>Minimum interval between regenerating same LSP</help> - <valueHelp> - <format>u32:1-120</format> - <description>Minimum interval in seconds</description> - </valueHelp> - <constraint> - <validator name="numeric" argument="--range 1-120"/> - </constraint> - </properties> - </leafNode> - <leafNode name="lsp-mtu"> - <properties> - <help>Configure the maximum size of generated LSPs</help> - <valueHelp> - <format>u32:128-4352</format> - <description>Maximum size of generated LSPs</description> - </valueHelp> - <constraint> - <validator name="numeric" argument="--range 128-4352"/> - </constraint> - </properties> - </leafNode> - <leafNode name="lsp-refresh-interval"> - <properties> - <help>LSP refresh interval</help> - <valueHelp> - <format>u32:1-65235</format> - <description>LSP refresh interval in seconds</description> - </valueHelp> - <constraint> - <validator name="numeric" argument="--range 1-65235"/> - </constraint> - </properties> - </leafNode> - <leafNode name="max-lsp-lifetime"> - <properties> - <help>Maximum LSP lifetime</help> - <valueHelp> - <format>u32:350-65535</format> - <description>LSP lifetime in seconds</description> - </valueHelp> - <constraint> - <validator name="numeric" argument="--range 1-65535"/> - </constraint> - </properties> - </leafNode> - <leafNode name="metric-style"> - <properties> - <help>Use old-style (ISO 10589) or new-style packet formats</help> - <completionHelp> - <list>narrow transition wide</list> - </completionHelp> - <valueHelp> - <format>narrow</format> - <description>Use old style of TLVs with narrow metric</description> - </valueHelp> - <valueHelp> - <format>transition</format> - <description>Send and accept both styles of TLVs during transition</description> - </valueHelp> - <valueHelp> - <format>wide</format> - <description>Use new style of TLVs to carry wider metric</description> - </valueHelp> - <constraint> - <regex>^(narrow|transition|wide)$</regex> - </constraint> - </properties> - </leafNode> - <leafNode name="net"> - <properties> - <help>A Network Entity Title for this process (ISO only)</help> - <valueHelp> - <format>XX.XXXX. ... .XXX.XX</format> - <description>Network entity title (NET)</description> - </valueHelp> - <constraint> - <regex>[a-fA-F0-9]{2}(\.[a-fA-F0-9]{4}){3,9}\.[a-fA-F0-9]{2}</regex> - </constraint> - </properties> - </leafNode> - <leafNode name="purge-originator"> - <properties> - <help>Use the RFC 6232 purge-originator</help> - <valueless/> - </properties> - </leafNode> - <node name="traffic-engineering"> - <properties> - <help>Show IS-IS neighbor adjacencies</help> - </properties> - <children> - <leafNode name="enable"> - <properties> - <help>Enable MPLS traffic engineering extensions</help> - <valueless/> - </properties> - </leafNode> -<!-- - <node name="inter-as"> - <properties> - <help>MPLS traffic engineering inter-AS support</help> - </properties> - <children> - <leafNode name="level-1"> - <properties> - <help>Area native mode self originate inter-AS LSP with L1 only flooding scope</help> - <valueless/> - </properties> - </leafNode> - <leafNode name="level-1-2"> - <properties> - <help>Area native mode self originate inter-AS LSP with L1 and L2 flooding scope</help> - <valueless/> - </properties> - </leafNode> - <leafNode name="level-2"> - <properties> - <help>Area native mode self originate inter-AS LSP with L2 only flooding scope</help> - <valueless/> - </properties> - </leafNode> - </children> - </node> - <leafNode name="inter-as"> - <properties> - <help>MPLS traffic engineering inter-AS support</help> - <valueless/> - </properties> - </leafNode> ---> - <leafNode name="address"> - <properties> - <help>MPLS traffic engineering router ID</help> - <valueHelp> - <format>ipv4</format> - <description>IPv4 address</description> - </valueHelp> - <constraint> - <validator name="ipv4-address"/> - </constraint> - </properties> - </leafNode> - </children> - </node> - <node name="segment-routing"> - <properties> - <help>Segment-Routing (SPRING) settings</help> - </properties> - <children> - <leafNode name="enable"> - <properties> - <help>Enable segment-routing functionality</help> - <valueless/> - </properties> - </leafNode> - <node name="global-block"> - <properties> - <help>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> - </children> - </node> -<!-- - <node name="local-block"> - <properties> - <help>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> - </children> - </node> ---> - <leafNode name="maximum-label-depth"> - <properties> - <help>Maximum MPLS labels allowed for this router</help> - <valueHelp> - <format>u32:1-16</format> - <description>MPLS label depth</description> - </valueHelp> - <constraint> - <validator name="numeric" argument="--range 1-16"/> - </constraint> - </properties> - </leafNode> - <tagNode name="prefix"> - <properties> - <help>Static IPv4/IPv6 prefix segment/label mapping</help> - <valueHelp> - <format>ipv4net</format> - <description>IPv4 prefix segment</description> - </valueHelp> - <valueHelp> - <format>ipv6net</format> - <description>IPv6 prefix segment</description> - </valueHelp> - <constraint> - <validator name="ipv4-prefix"/> - <validator name="ipv6-prefix"/> - </constraint> - </properties> - <children> - <node name="absolute"> - <properties> - <help>Specify the absolute value of prefix segment/label ID</help> - </properties> - <children> - <leafNode name="value"> - <properties> - <help>Specify the absolute value of prefix segment/label ID</help> - <valueHelp> - <format>u32:16-1048575</format> - <description>The absolute segment/label ID value</description> - </valueHelp> - <constraint> - <validator name="numeric" argument="--range 16-1048575"/> - </constraint> - </properties> - </leafNode> - <leafNode name="explicit-null"> - <properties> - <help>Request upstream neighbor to replace segment/label with explicit null label</help> - <valueless/> - </properties> - </leafNode> - <leafNode name="no-php-flag"> - <properties> - <help>Do not request penultimate hop popping for segment/label</help> - <valueless/> - </properties> - </leafNode> - </children> - </node> - <node name="index"> - <properties> - <help>Specify the index value of prefix segment/label ID</help> - </properties> - <children> - <leafNode name="value"> - <properties> - <help>Specify the index value of prefix segment/label ID</help> - <valueHelp> - <format>u32:0-65535</format> - <description>The index segment/label ID value</description> - </valueHelp> - <constraint> - <validator name="numeric" argument="--range 0-65535"/> - </constraint> - </properties> - </leafNode> - <leafNode name="explicit-null"> - <properties> - <help>Request upstream neighbor to replace segment/label with explicit null label</help> - <valueless/> - </properties> - </leafNode> - <leafNode name="no-php-flag"> - <properties> - <help>Do not request penultimate hop popping for segment/label</help> - <valueless/> - </properties> - </leafNode> - </children> - </node> - </children> - </tagNode> - </children> - </node> - <node name="redistribute"> - <properties> - <help>Redistribute information from another routing protocol</help> - </properties> - <children> - <node name="ipv4"> - <properties> - <help>Redistribute IPv4 routes</help> - </properties> - <children> - <node name="bgp"> - <properties> - <help>Border Gateway Protocol (BGP)</help> - </properties> - <children> - #include <include/isis-redistribute-ipv4.xml.i> - </children> - </node> - <node name="connected"> - <properties> - <help>Redistribute connected routes into IS-IS</help> - </properties> - <children> - #include <include/isis-redistribute-ipv4.xml.i> - </children> - </node> - <node name="kernel"> - <properties> - <help>Redistribute kernel routes into IS-IS</help> - </properties> - <children> - #include <include/isis-redistribute-ipv4.xml.i> - </children> - </node> - <node name="ospf"> - <properties> - <help>Redistribute OSPF routes into IS-IS</help> - </properties> - <children> - #include <include/isis-redistribute-ipv4.xml.i> - </children> - </node> - <node name="rip"> - <properties> - <help>Redistribute RIP routes into IS-IS</help> - </properties> - <children> - #include <include/isis-redistribute-ipv4.xml.i> - </children> - </node> - <node name="static"> - <properties> - <help>Redistribute static routes into IS-IS</help> - </properties> - <children> - #include <include/isis-redistribute-ipv4.xml.i> - </children> - </node> - </children> - </node> - </children> - </node> - <leafNode name="set-attached-bit"> - <properties> - <help>Set attached bit to identify as L1/L2 router for inter-area traffic</help> - <valueless/> - </properties> - </leafNode> - <leafNode name="set-overload-bit"> - <properties> - <help>Set overload bit to avoid any transit traffic</help> - <valueless/> - </properties> - </leafNode> - <node name="spf-delay-ietf"> - <properties> - <help>IETF SPF delay algorithm</help> - </properties> - <children> - <leafNode name="init-delay"> - <properties> - <help>Delay used while in QUIET state</help> - <valueHelp> - <format>u32:0-60000</format> - <description>Delay used while in QUIET state (in ms)</description> - </valueHelp> - <constraint> - <validator name="numeric" argument="--range 0-60000"/> - </constraint> - </properties> - </leafNode> - <leafNode name="short-delay"> - <properties> - <help>Delay used while in SHORT_WAIT state</help> - <valueHelp> - <format>u32:0-60000</format> - <description>Delay used while in SHORT_WAIT state (in ms)</description> - </valueHelp> - <constraint> - <validator name="numeric" argument="--range 0-60000"/> - </constraint> - </properties> - </leafNode> - <leafNode name="long-delay"> - <properties> - <help>Delay used while in LONG_WAIT</help> - <valueHelp> - <format>u32:0-60000</format> - <description>Delay used while in LONG_WAIT state (in ms)</description> - </valueHelp> - <constraint> - <validator name="numeric" argument="--range 0-60000"/> - </constraint> - </properties> - </leafNode> - <leafNode name="holddown"> - <properties> - <help>Time with no received IGP events before considering IGP stable</help> - <valueHelp> - <format>u32:0-60000</format> - <description>Time with no received IGP events before considering IGP stable (in ms)</description> - </valueHelp> - <constraint> - <validator name="numeric" argument="--range 0-60000"/> - </constraint> - </properties> - </leafNode> - <leafNode name="time-to-learn"> - <properties> - <help>Maximum duration needed to learn all the events related to a single failure</help> - <valueHelp> - <format>u32:0-60000</format> - <description>Maximum duration needed to learn all the events related to a single failure (in ms)</description> - </valueHelp> - <constraint> - <validator name="numeric" argument="--range 0-60000"/> - </constraint> - </properties> - </leafNode> - </children> - </node> - <leafNode name="spf-interval"> - <properties> - <help>Minimum interval between SPF calculations</help> - <valueHelp> - <format>u32:1-120</format> - <description>Minimum interval between consecutive SPFs in seconds</description> - </valueHelp> - <constraint> - <validator name="numeric" argument="--range 1-120"/> - </constraint> - </properties> - </leafNode> - <tagNode name="interface"> - <!-- (config-if)# ip router isis WORD (same as name of IS-IS process) - if any section of "interface" pesent --> - <properties> - <help>Interface params</help> - <completionHelp> - <script>${vyos_completion_dir}/list_interfaces.py</script> - </completionHelp> - </properties> - <children> - <leafNode name="bfd"> - <properties> - <help>Enable BFD support</help> - <valueless/> - </properties> - </leafNode> - <leafNode name="circuit-type"> - <properties> - <help>Configure circuit type for interface</help> - <completionHelp> - <list>level-1 level-1-2 level-2-only</list> - </completionHelp> - <valueHelp> - <format>level-1</format> - <description>Level-1 only adjacencies are formed</description> - </valueHelp> - <valueHelp> - <format>level-1-2</format> - <description>Level-1-2 adjacencies are formed</description> - </valueHelp> - <valueHelp> - <format>level-2-only</format> - <description>Level-2 only adjacencies are formed</description> - </valueHelp> - <constraint> - <regex>^(level-1|level-1-2|level-2-only)$</regex> - </constraint> - </properties> - </leafNode> - <leafNode name="hello-padding"> - <properties> - <help>Add padding to IS-IS hello packets</help> - <valueless/> - </properties> - </leafNode> - <leafNode name="hello-interval"> - <properties> - <help>Set Hello interval</help> - <valueHelp> - <format>u32:1-600</format> - <description>Set Hello interval</description> - </valueHelp> - <constraint> - <validator name="numeric" argument="--range 1-600"/> - </constraint> - </properties> - </leafNode> - <leafNode name="hello-multiplier"> - <properties> - <help>Set Hello interval</help> - <valueHelp> - <format>u32:2-100</format> - <description>Set multiplier for Hello holding time</description> - </valueHelp> - <constraint> - <validator name="numeric" argument="--range 2-100"/> - </constraint> - </properties> - </leafNode> - <leafNode name="metric"> - <properties> - <help>Set default metric for circuit</help> - <valueHelp> - <format>u32:0-16777215</format> - <description>Default metric value</description> - </valueHelp> - <constraint> - <validator name="numeric" argument="--range 0-16777215"/> - </constraint> - </properties> - </leafNode> - <node name="network"> - <properties> - <help>Set network type</help> - </properties> - <children> - <leafNode name="point-to-point"> - <properties> - <help>point-to-point network type</help> - <valueless/> - </properties> - </leafNode> - </children> - </node> - <leafNode name="passive"> - <properties> - <help>Configure the passive mode for interface</help> - <valueless/> - </properties> - </leafNode> - <node name="password"> - <properties> - <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> - </children> - </node> - <leafNode name="priority"> - <properties> - <help>Set priority for Designated Router election</help> - <valueHelp> - <format>u32:0-127</format> - <description>Priority value</description> - </valueHelp> - <constraint> - <validator name="numeric" argument="--range 0-127"/> - </constraint> - </properties> - </leafNode> - <leafNode name="psnp-interval"> - <properties> - <help>Set PSNP interval in seconds</help> - <valueHelp> - <format>u32:0-127</format> - <description>Priority value</description> - </valueHelp> - <constraint> - <validator name="numeric" argument="--range 0-127"/> - </constraint> - </properties> - </leafNode> - <leafNode name="no-three-way-handshake"> - <properties> - <help>Disable three-way handshake</help> - <valueless/> - </properties> - </leafNode> - </children> - </tagNode> + #include <include/isis/protocol-common-config.xml.i> </children> - </tagNode> + </node> </children> </node> </interfaceDefinition> diff --git a/interface-definitions/protocols-multicast.xml.in b/interface-definitions/protocols-multicast.xml.in index a06f2b287..1b1382352 100644 --- a/interface-definitions/protocols-multicast.xml.in +++ b/interface-definitions/protocols-multicast.xml.in @@ -38,7 +38,7 @@ <properties> <help>Distance value for this route</help> <valueHelp> - <format>1-255</format> + <format>u32:1-255</format> <description>Distance for this route</description> </valueHelp> <constraint> @@ -74,7 +74,7 @@ <properties> <help>Distance value for this route</help> <valueHelp> - <format>1-255</format> + <format>u32:1-255</format> <description>Distance for this route</description> </valueHelp> <constraint> diff --git a/interface-definitions/protocols-pim.xml.in b/interface-definitions/protocols-pim.xml.in index 6152045a7..bb5cc797b 100644 --- a/interface-definitions/protocols-pim.xml.in +++ b/interface-definitions/protocols-pim.xml.in @@ -21,7 +21,7 @@ <properties> <help>Designated Router Election Priority</help> <valueHelp> - <format>1-4294967295</format> + <format>u32:1-4294967295</format> <description>Value of the new DR Priority</description> </valueHelp> <constraint> @@ -33,7 +33,7 @@ <properties> <help>Hello Interval</help> <valueHelp> - <format>1-180</format> + <format>u32:1-180</format> <description>Hello Interval in seconds</description> </valueHelp> <constraint> @@ -79,7 +79,7 @@ <properties> <help>Keep alive Timer</help> <valueHelp> - <format>31-60000</format> + <format>u32:31-60000</format> <description>Keep alive Timer in seconds</description> </valueHelp> <constraint> diff --git a/interface-definitions/service_console-server.xml.in b/interface-definitions/service_console-server.xml.in index 78eb2d0ba..28aa7ea71 100644 --- a/interface-definitions/service_console-server.xml.in +++ b/interface-definitions/service_console-server.xml.in @@ -27,7 +27,7 @@ </constraint> </properties> <children> - #include <include/interface/interface-description.xml.i> + #include <include/interface/description.xml.i> <leafNode name="speed"> <properties> <help>Serial port baud rate</help> diff --git a/interface-definitions/service_pppoe-server.xml.in b/interface-definitions/service_pppoe-server.xml.in index 9d3420ed2..955c104f7 100644 --- a/interface-definitions/service_pppoe-server.xml.in +++ b/interface-definitions/service_pppoe-server.xml.in @@ -8,14 +8,8 @@ <priority>900</priority> </properties> <children> + #include <include/pppoe-access-concentrator.xml.i> <leafNode name="access-concentrator"> - <properties> - <help>Access concentrator name</help> - <constraint> - <regex>[a-zA-Z0-9]{1,100}</regex> - </constraint> - <constraintErrorMessage>access-concentrator name limited to alphanumerical characters only (max. 100)</constraintErrorMessage> - </properties> <defaultValue>vyos-ac</defaultValue> </leafNode> <node name="authentication"> @@ -129,7 +123,7 @@ <constraint> <regex>[a-zA-Z0-9\-]{1,100}</regex> </constraint> - <constraintErrorMessage>servicename can contain aplhanumerical characters and dashes only (max. 100)</constraintErrorMessage> + <constraintErrorMessage>Service-name can contain aplhanumerical characters and dashes only (max. 100)</constraintErrorMessage> <multi/> </properties> </leafNode> @@ -273,7 +267,7 @@ <properties> <help>PADO delays</help> <valueHelp> - <format>1-999999</format> + <format>u32:1-999999</format> <description>Number in ms</description> </valueHelp> <constraint> @@ -286,7 +280,7 @@ <properties> <help>Number of sessions</help> <valueHelp> - <format>1-999999</format> + <format>u32:1-999999</format> <description>Number of sessions</description> </valueHelp> <constraint> diff --git a/interface-definitions/service_router-advert.xml.in b/interface-definitions/service_router-advert.xml.in index 750ae314c..e18b27f1b 100644 --- a/interface-definitions/service_router-advert.xml.in +++ b/interface-definitions/service_router-advert.xml.in @@ -20,12 +20,12 @@ <properties> <help>Set Hop Count field of the IP header for outgoing packets (default: 64)</help> <valueHelp> - <format>1-255</format> - <description>Value should represent current diameter of the Internet</description> + <format>u32:0</format> + <description>Unspecified (by this router)</description> </valueHelp> <valueHelp> - <format>0</format> - <description>Unspecified (by this router)</description> + <format>u32:1-255</format> + <description>Value should represent current diameter of the Internet</description> </valueHelp> <constraint> <validator name="numeric" argument="--range 0-255"/> @@ -38,7 +38,7 @@ <properties> <help>Lifetime associated with the default router in units of seconds</help> <valueHelp> - <format>4-9000</format> + <format>u32:4-9000</format> <description>Router Lifetime in seconds</description> </valueHelp> <valueHelp> @@ -86,7 +86,7 @@ <properties> <help>Link MTU value placed in RAs, exluded in RAs if unset</help> <valueHelp> - <format>1280-9000</format> + <format>u32:1280-9000</format> <description>Link MTU value in RAs</description> </valueHelp> <constraint> @@ -110,7 +110,7 @@ <properties> <help>Maximum interval between unsolicited multicast RAs (default: 600)</help> <valueHelp> - <format>4-1800</format> + <format>u32:4-1800</format> <description>Maximum interval in seconds</description> </valueHelp> <constraint> @@ -124,7 +124,7 @@ <properties> <help>Minimum interval between unsolicited multicast RAs</help> <valueHelp> - <format>3-1350</format> + <format>u32:3-1350</format> <description>Minimum interval in seconds</description> </valueHelp> <constraint> @@ -173,7 +173,7 @@ <list>infinity</list> </completionHelp> <valueHelp> - <format>1-4294967295</format> + <format>u32:1-4294967295</format> <description>Time in seconds that the route will remain valid</description> </valueHelp> <valueHelp> @@ -272,7 +272,7 @@ <list>infinity</list> </completionHelp> <valueHelp> - <format>1-4294967295</format> + <format>u32:1-4294967295</format> <description>Time in seconds that the prefix will remain valid</description> </valueHelp> <valueHelp> @@ -292,12 +292,12 @@ <properties> <help>Time, in milliseconds, that a node assumes a neighbor is reachable after having received a reachability confirmation</help> <valueHelp> - <format>1-3600000</format> - <description>Reachable Time value in RAs (in milliseconds)</description> + <format>u32:0</format> + <description>Reachable Time unspecified by this router</description> </valueHelp> <valueHelp> - <format>0</format> - <description>Reachable Time unspecified by this router</description> + <format>u32:1-3600000</format> + <description>Reachable Time value in RAs (in milliseconds)</description> </valueHelp> <constraint> <validator name="numeric" argument="--range 0-0 --range 1-3600000"/> @@ -310,12 +310,12 @@ <properties> <help>Time in milliseconds between retransmitted Neighbor Solicitation messages</help> <valueHelp> - <format>1-4294967295</format> - <description>Minimum interval in milliseconds</description> + <format>u32:0</format> + <description>Time, in milliseconds, between retransmitted Neighbor Solicitation messages</description> </valueHelp> <valueHelp> - <format>0</format> - <description>Time, in milliseconds, between retransmitted Neighbor Solicitation messages</description> + <format>u32:1-4294967295</format> + <description>Minimum interval in milliseconds</description> </valueHelp> <constraint> <validator name="numeric" argument="--range 0-0 --range 1-4294967295"/> diff --git a/interface-definitions/service_webproxy.xml.in b/interface-definitions/service_webproxy.xml.in index 7cb0f7ece..2fbac3df0 100644 --- a/interface-definitions/service_webproxy.xml.in +++ b/interface-definitions/service_webproxy.xml.in @@ -214,7 +214,7 @@ <properties> <help>Cache peer options (default: "no-query default")</help> <valueHelp> - <format>text</format> + <format>txt</format> <description>Cache peer options</description> </valueHelp> </properties> diff --git a/interface-definitions/snmp.xml.in b/interface-definitions/snmp.xml.in index f57103eac..3cb736bf7 100644 --- a/interface-definitions/snmp.xml.in +++ b/interface-definitions/snmp.xml.in @@ -626,7 +626,7 @@ </tagNode> </children> </node> - #include <include/interface/interface-vrf.xml.i> + #include <include/interface/vrf.xml.i> </children> </node> </children> diff --git a/interface-definitions/ssh.xml.in b/interface-definitions/ssh.xml.in index 54742f1d0..e3b9d16e1 100644 --- a/interface-definitions/ssh.xml.in +++ b/interface-definitions/ssh.xml.in @@ -138,7 +138,7 @@ <properties> <help>Enable transmission of keepalives from server to client</help> <valueHelp> - <format>1-65535</format> + <format>u32:1-65535</format> <description>Time interval in seconds for keepalive message</description> </valueHelp> <constraint> @@ -146,7 +146,7 @@ </constraint> </properties> </leafNode> - #include <include/interface/interface-vrf.xml.i> + #include <include/interface/vrf.xml.i> </children> </node> </children> diff --git a/interface-definitions/system-login.xml.in b/interface-definitions/system-login.xml.in index 86db3f368..f4613b8a2 100644 --- a/interface-definitions/system-login.xml.in +++ b/interface-definitions/system-login.xml.in @@ -12,7 +12,7 @@ <properties> <help>Local user account information</help> <constraint> - <regex>[a-zA-Z0-9\-_\.]{1,100}</regex> + <regex>^[-_a-zA-Z0-9.]{1,100}</regex> </constraint> <constraintErrorMessage>Username contains illegal characters or\nexceeds 100 character limitation.</constraintErrorMessage> </properties> @@ -44,6 +44,9 @@ <tagNode name="public-keys"> <properties> <help>Remote access public keys</help> + <constraint> + <regex>^[-_a-zA-Z0-9@]+$</regex> + </constraint> <valueHelp> <format>txt</format> <description>Key identifier used by ssh-keygen (usually of form user@host)</description> @@ -52,7 +55,10 @@ <children> <leafNode name="key"> <properties> - <help>Public key value (base64-encoded)</help> + <help>Public key value (Base64 encoded)</help> + <constraint> + <validator name="base64"/> + </constraint> </properties> </leafNode> <leafNode name="options"> @@ -145,7 +151,7 @@ </leafNode> </children> </tagNode> - #include <include/interface/interface-vrf.xml.i> + #include <include/interface/vrf.xml.i> </children> </node> </children> diff --git a/interface-definitions/vpn_ipsec.xml.in b/interface-definitions/vpn_ipsec.xml.in deleted file mode 100644 index 426d7e71c..000000000 --- a/interface-definitions/vpn_ipsec.xml.in +++ /dev/null @@ -1,1167 +0,0 @@ -<?xml version="1.0"?> -<interfaceDefinition> - <node name="vpn"> - <children> - <node name="nipsec" owner="${vyos_conf_scripts_dir}/vpn_ipsec.py"> - <properties> - <help>VPN IP security (IPsec) parameters</help> - </properties> - <children> - <leafNode name="auto-update"> - <properties> - <help>Set auto-update interval for IPsec daemon</help> - <valueHelp> - <format>u32:30-65535</format> - <description>Auto-update interval (s)</description> - </valueHelp> - <constraint> - <validator name="numeric" argument="--range 30-65535"/> - </constraint> - </properties> - </leafNode> - <leafNode name="disable-uniqreqids"> - <properties> - <help>Option to disable requirement for unique IDs in the Security Database</help> - <valueless/> - </properties> - </leafNode> - <tagNode name="esp-group"> - <properties> - <help>Name of Encapsulating Security Payload (ESP) group</help> - </properties> - <children> - <leafNode name="compression"> - <properties> - <help>ESP compression</help> - <completionHelp> - <list>disable enable</list> - </completionHelp> - <valueHelp> - <format>disable</format> - <description>Disable ESP compression (default)</description> - </valueHelp> - <valueHelp> - <format>enable</format> - <description>Enable ESP compression</description> - </valueHelp> - <constraint> - <regex>^(disable|enable)$</regex> - </constraint> - </properties> - </leafNode> - <leafNode name="lifetime"> - <properties> - <help>ESP lifetime</help> - <valueHelp> - <format>u32:30-86400</format> - <description>ESP lifetime in seconds (default 3600)</description> - </valueHelp> - <constraint> - <validator name="numeric" argument="--range 30-86400"/> - </constraint> - </properties> - </leafNode> - <leafNode name="mode"> - <properties> - <help>ESP mode</help> - <completionHelp> - <list>tunnel transport</list> - </completionHelp> - <valueHelp> - <format>tunnel</format> - <description>Tunnel mode (default)</description> - </valueHelp> - <valueHelp> - <format>transport</format> - <description>Transport mode</description> - </valueHelp> - <constraint> - <regex>^(tunnel|transport)$</regex> - </constraint> - </properties> - </leafNode> - <leafNode name="pfs"> - <properties> - <help>ESP Perfect Forward Secrecy</help> - <completionHelp> - <list>enable dh-group1 dh-group2 dh-group5 dh-group14 dh-group15 dh-group16 dh-group17 dh-group18 dh-group19 dh-group20 dh-group21 dh-group22 dh-group23 dh-group24 dh-group25 dh-group26 dh-group27 dh-group28 dh-group29 dh-group30 dh-group31 dh-group32 disable</list> - </completionHelp> - <valueHelp> - <format>enable</format> - <description>Enable PFS. Use ike-groups dh-group (default)</description> - </valueHelp> - <valueHelp> - <format>dh-group1</format> - <description>Enable PFS. Use Diffie-Hellman group 1 (modp768)</description> - </valueHelp> - <valueHelp> - <format>dh-group2</format> - <description>Enable PFS. Use Diffie-Hellman group 2 (modp1024)</description> - </valueHelp> - <valueHelp> - <format>dh-group5</format> - <description>Enable PFS. Use Diffie-Hellman group 5 (modp1536)</description> - </valueHelp> - <valueHelp> - <format>dh-group14</format> - <description>Enable PFS. Use Diffie-Hellman group 14 (modp2048)</description> - </valueHelp> - <valueHelp> - <format>dh-group15</format> - <description>Enable PFS. Use Diffie-Hellman group 15 (modp3072)</description> - </valueHelp> - <valueHelp> - <format>dh-group16</format> - <description>Enable PFS. Use Diffie-Hellman group 16 (modp4096)</description> - </valueHelp> - <valueHelp> - <format>dh-group17</format> - <description>Enable PFS. Use Diffie-Hellman group 17 (modp6144)</description> - </valueHelp> - <valueHelp> - <format>dh-group18</format> - <description>Enable PFS. Use Diffie-Hellman group 18 (modp8192)</description> - </valueHelp> - <valueHelp> - <format>dh-group19</format> - <description>Enable PFS. Use Diffie-Hellman group 19 (ecp256)</description> - </valueHelp> - <valueHelp> - <format>dh-group20</format> - <description>Enable PFS. Use Diffie-Hellman group 20 (ecp384)</description> - </valueHelp> - <valueHelp> - <format>dh-group21</format> - <description>Enable PFS. Use Diffie-Hellman group 21 (ecp521)</description> - </valueHelp> - <valueHelp> - <format>dh-group22</format> - <description>Enable PFS. Use Diffie-Hellman group 22 (modp1024s160)</description> - </valueHelp> - <valueHelp> - <format>dh-group23</format> - <description>Enable PFS. Use Diffie-Hellman group 23 (modp2048s224)</description> - </valueHelp> - <valueHelp> - <format>dh-group24</format> - <description>Enable PFS. Use Diffie-Hellman group 24 (modp2048s256)</description> - </valueHelp> - <valueHelp> - <format>dh-group25</format> - <description>Enable PFS. Use Diffie-Hellman group 25 (ecp192)</description> - </valueHelp> - <valueHelp> - <format>dh-group26</format> - <description>Enable PFS. Use Diffie-Hellman group 26 (ecp224)</description> - </valueHelp> - <valueHelp> - <format>dh-group27</format> - <description>Enable PFS. Use Diffie-Hellman group 27 (ecp224bp)</description> - </valueHelp> - <valueHelp> - <format>dh-group28</format> - <description>Enable PFS. Use Diffie-Hellman group 28 (ecp256bp)</description> - </valueHelp> - <valueHelp> - <format>dh-group29</format> - <description>Enable PFS. Use Diffie-Hellman group 29 (ecp384bp)</description> - </valueHelp> - <valueHelp> - <format>dh-group30</format> - <description>Enable PFS. Use Diffie-Hellman group 30 (ecp512bp)</description> - </valueHelp> - <valueHelp> - <format>dh-group31</format> - <description>Enable PFS. Use Diffie-Hellman group 31 (curve25519)</description> - </valueHelp> - <valueHelp> - <format>dh-group32</format> - <description>Enable PFS. Use Diffie-Hellman group 32 (curve448)</description> - </valueHelp> - <valueHelp> - <format>disable</format> - <description>Disable PFS</description> - </valueHelp> - <constraint> - <regex>^(enable|dh-group1|dh-group2|dh-group5|dh-group14|dh-group15|dh-group16|dh-group17|dh-group18|dh-group19|dh-group20|dh-group21|dh-group22|dh-group23|dh-group24|dh-group25|dh-group26|dh-group27|dh-group28|dh-group29|dh-group30|dh-group31|dh-group32|disable)$</regex> - </constraint> - </properties> - </leafNode> - <tagNode name="proposal"> - <properties> - <help>ESP-group proposal [REQUIRED]</help> - <valueHelp> - <format>u32:1-65535</format> - <description>ESP-group proposal number</description> - </valueHelp> - </properties> - <children> - #include <include/vpn-ipsec-encryption.xml.i> - #include <include/vpn-ipsec-hash.xml.i> - </children> - </tagNode> - </children> - </tagNode> - <tagNode name="ike-group"> - <properties> - <help>Name of Internet Key Exchange (IKE) group</help> - </properties> - <children> - <leafNode name="close-action"> - <properties> - <help>close-action_help</help> - <completionHelp> - <list>none hold clear restart</list> - </completionHelp> - <valueHelp> - <format>none</format> - <description>Set action to none (default)</description> - </valueHelp> - <valueHelp> - <format>hold</format> - <description>Set action to hold</description> - </valueHelp> - <valueHelp> - <format>clear</format> - <description>Set action to clear</description> - </valueHelp> - <valueHelp> - <format>restart</format> - <description>Set action to restart</description> - </valueHelp> - <constraint> - <regex>^(none|hold|clear|restart)$</regex> - </constraint> - </properties> - </leafNode> - <node name="dead-peer-detection"> - <properties> - <help>Dead Peer Detection (DPD)</help> - </properties> - <children> - <leafNode name="action"> - <properties> - <help>Keep-alive failure action</help> - <completionHelp> - <list>hold clear restart</list> - </completionHelp> - <valueHelp> - <format>hold</format> - <description>Set action to hold (default)</description> - </valueHelp> - <valueHelp> - <format>clear</format> - <description>Set action to clear</description> - </valueHelp> - <valueHelp> - <format>restart</format> - <description>Set action to restart</description> - </valueHelp> - <constraint> - <regex>^(hold|clear|restart)$</regex> - </constraint> - </properties> - </leafNode> - <leafNode name="interval"> - <properties> - <help>Keep-alive interval</help> - <valueHelp> - <format>u32:2-86400</format> - <description>Keep-alive interval in seconds (default 30)</description> - </valueHelp> - <constraint> - <validator name="numeric" argument="--range 2-86400"/> - </constraint> - </properties> - </leafNode> - <leafNode name="timeout"> - <properties> - <help>Dead-Peer-Detection keep-alive timeout (IKEv1 only)</help> - <valueHelp> - <format>u32:2-86400</format> - <description>Keep-alive timeout in seconds (default 120)</description> - </valueHelp> - <constraint> - <validator name="numeric" argument="--range 2-86400"/> - </constraint> - </properties> - </leafNode> - </children> - </node> - <leafNode name="ikev2-reauth"> - <properties> - <help>ikev2-reauth_help</help> - <completionHelp> - <list>yes no</list> - </completionHelp> - <valueHelp> - <format>yes</format> - <description>Enable remote host re-autentication during an IKE rekey. Currently broken due to a strong swan bug</description> - </valueHelp> - <valueHelp> - <format>no</format> - <description>Disable remote host re-authenticaton during an IKE rekey. (Default)</description> - </valueHelp> - <constraint> - <regex>^(yes|no)$</regex> - </constraint> - </properties> - </leafNode> - <leafNode name="key-exchange"> - <properties> - <help>Key Exchange Version</help> - <completionHelp> - <list>ikev1 ikev2</list> - </completionHelp> - <valueHelp> - <format>ikev1</format> - <description>Use IKEv1 for Key Exchange [DEFAULT]</description> - </valueHelp> - <valueHelp> - <format>ikev2</format> - <description>Use IKEv2 for Key Exchange</description> - </valueHelp> - <constraint> - <regex>^(ikev1|ikev2)$</regex> - </constraint> - </properties> - </leafNode> - <leafNode name="lifetime"> - <properties> - <help>IKE lifetime</help> - <valueHelp> - <format>u32:30-86400</format> - <description>IKE lifetime in seconds (default 28800)</description> - </valueHelp> - <constraint> - <validator name="numeric" argument="--range 30-86400"/> - </constraint> - </properties> - </leafNode> - <leafNode name="mobike"> - <properties> - <help>Enable MOBIKE Support. MOBIKE is only available for IKEv2.</help> - <completionHelp> - <list>enable disable</list> - </completionHelp> - <valueHelp> - <format>enable</format> - <description>Enable MOBIKE (default for IKEv2)</description> - </valueHelp> - <valueHelp> - <format>disable</format> - <description>Disable MOBIKE</description> - </valueHelp> - <constraint> - <regex>^(enable|disable)$</regex> - </constraint> - </properties> - </leafNode> - <leafNode name="mode"> - <properties> - <help>IKEv1 Phase 1 Mode Selection</help> - <completionHelp> - <list>main aggressive</list> - </completionHelp> - <valueHelp> - <format>main</format> - <description>Use Main mode for Key Exchanges in the IKEv1 Protocol (Recommended Default)</description> - </valueHelp> - <valueHelp> - <format>aggressive</format> - <description>Use Aggressive mode for Key Exchanges in the IKEv1 protocol - We do not recommend users to use aggressive mode as it is much more insecure compared to Main mode.</description> - </valueHelp> - <constraint> - <regex>^(main|aggressive)$</regex> - </constraint> - </properties> - </leafNode> - <tagNode name="proposal"> - <properties> - <help>proposal_help</help> - <valueHelp> - <format>u32:1-65535</format> - <description>IKE-group proposal</description> - </valueHelp> - </properties> - <children> - <leafNode name="dh-group"> - <properties> - <help>dh-grouphelp</help> - <completionHelp> - <list>1 2 5 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32</list> - </completionHelp> - <valueHelp> - <format>1</format> - <description>Diffie-Hellman group 1 (modp768)</description> - </valueHelp> - <valueHelp> - <format>2</format> - <description>Diffie-Hellman group 2 (modp1024)</description> - </valueHelp> - <valueHelp> - <format>5</format> - <description>Diffie-Hellman group 5 (modp1536)</description> - </valueHelp> - <valueHelp> - <format>14</format> - <description>Diffie-Hellman group 14 (modp2048)</description> - </valueHelp> - <valueHelp> - <format>15</format> - <description>Diffie-Hellman group 15 (modp3072)</description> - </valueHelp> - <valueHelp> - <format>16</format> - <description>Diffie-Hellman group 16 (modp4096)</description> - </valueHelp> - <valueHelp> - <format>17</format> - <description>Diffie-Hellman group 17 (modp6144)</description> - </valueHelp> - <valueHelp> - <format>18</format> - <description>Diffie-Hellman group 18 (modp8192)</description> - </valueHelp> - <valueHelp> - <format>19</format> - <description>Diffie-Hellman group 19 (ecp256)</description> - </valueHelp> - <valueHelp> - <format>20</format> - <description>Diffie-Hellman group 20 (ecp384)</description> - </valueHelp> - <valueHelp> - <format>21</format> - <description>Diffie-Hellman group 21 (ecp521)</description> - </valueHelp> - <valueHelp> - <format>22</format> - <description>Diffie-Hellman group 22 (modp1024s160)</description> - </valueHelp> - <valueHelp> - <format>23</format> - <description>Diffie-Hellman group 23 (modp2048s224)</description> - </valueHelp> - <valueHelp> - <format>24</format> - <description>Diffie-Hellman group 24 (modp2048s256)</description> - </valueHelp> - <valueHelp> - <format>25</format> - <description>Diffie-Hellman group 25 (ecp192)</description> - </valueHelp> - <valueHelp> - <format>26</format> - <description>Diffie-Hellman group 26 (ecp224)</description> - </valueHelp> - <valueHelp> - <format>27</format> - <description>Diffie-Hellman group 27 (ecp224bp)</description> - </valueHelp> - <valueHelp> - <format>28</format> - <description>Diffie-Hellman group 28 (ecp256bp)</description> - </valueHelp> - <valueHelp> - <format>29</format> - <description>Diffie-Hellman group 29 (ecp384bp)</description> - </valueHelp> - <valueHelp> - <format>30</format> - <description>Diffie-Hellman group 30 (ecp512bp)</description> - </valueHelp> - <valueHelp> - <format>31</format> - <description>Diffie-Hellman group 31 (curve25519)</description> - </valueHelp> - <valueHelp> - <format>32</format> - <description>Diffie-Hellman group 32 (curve448)</description> - </valueHelp> - <constraint> - <regex>^(1|2|5|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31|32)$</regex> - </constraint> - </properties> - </leafNode> - #include <include/vpn-ipsec-encryption.xml.i> - #include <include/vpn-ipsec-hash.xml.i> - </children> - </tagNode> - </children> - </tagNode> - <leafNode name="include-ipsec-conf"> - <properties> - <help>Sets to include an additional configuration directive file for strongSwan. Use an absolute path to specify the included file</help> - </properties> - </leafNode> - <leafNode name="include-ipsec-secrets"> - <properties> - <help>Sets to include an additional secrets file for strongSwan. Use an absolute path to specify the included file.</help> - </properties> - </leafNode> - <node name="ipsec-interfaces"> - <properties> - <help>Interface to use for VPN [REQUIRED]</help> - </properties> - <children> - <leafNode name="interface"> - <properties> - <help>IPsec interface [REQUIRED]</help> - <completionHelp> - <script>${vyos_completion_dir}/list_interfaces.py</script> - </completionHelp> - <multi/> - </properties> - </leafNode> - </children> - </node> - <node name="logging"> - <properties> - <help>IPsec logging</help> - </properties> - <children> - <leafNode name="log-level"> - <properties> - <help>strongSwan Logger Level</help> - <valueHelp> - <format>u32:0-2</format> - <description>Logger Verbosity Level (default 0)</description> - </valueHelp> - <constraint> - <validator name="numeric" argument="--range 0-2"/> - </constraint> - </properties> - </leafNode> - <leafNode name="log-modes"> - <properties> - <help>Log mode. To see what each log mode exactly does, please refer to the strongSwan documentation</help> - <completionHelp> - <list>dmn mgr ike chd job cfg knl net asn enc lib esp tls tnc imc imv pts any</list> - </completionHelp> - <valueHelp> - <format>dmn</format> - <description>Debug log option for strongSwan</description> - </valueHelp> - <valueHelp> - <format>mgr</format> - <description>Debug log option for strongSwan</description> - </valueHelp> - <valueHelp> - <format>ike</format> - <description>Debug log option for strongSwan</description> - </valueHelp> - <valueHelp> - <format>chd</format> - <description>Debug log option for strongSwan</description> - </valueHelp> - <valueHelp> - <format>job</format> - <description>Debug log option for strongSwan</description> - </valueHelp> - <valueHelp> - <format>cfg</format> - <description>Debug log option for strongSwan</description> - </valueHelp> - <valueHelp> - <format>knl</format> - <description>Debug log option for strongSwan</description> - </valueHelp> - <valueHelp> - <format>net</format> - <description>Debug log option for strongSwan</description> - </valueHelp> - <valueHelp> - <format>asn</format> - <description>Debug log option for strongSwan</description> - </valueHelp> - <valueHelp> - <format>enc</format> - <description>Debug log option for strongSwan</description> - </valueHelp> - <valueHelp> - <format>lib</format> - <description>Debug log option for strongSwan</description> - </valueHelp> - <valueHelp> - <format>esp</format> - <description>Debug log option for strongSwan</description> - </valueHelp> - <valueHelp> - <format>tls</format> - <description>Debug log option for strongSwan</description> - </valueHelp> - <valueHelp> - <format>tnc</format> - <description>Debug log option for strongSwan</description> - </valueHelp> - <valueHelp> - <format>imc</format> - <description>Debug log option for strongSwan</description> - </valueHelp> - <valueHelp> - <format>imv</format> - <description>Debug log option for strongSwan</description> - </valueHelp> - <valueHelp> - <format>pts</format> - <description>Debug log option for strongSwan</description> - </valueHelp> - <valueHelp> - <format>any</format> - <description>Debug log option for strongSwan</description> - </valueHelp> - <constraint> - <regex>^(dmn|mgr|ike|chd|job|cfg|knl|net|asn|enc|lib|esp|tls|tnc|imc|imv|pts|any)$</regex> - </constraint> - <multi/> - </properties> - </leafNode> - </children> - </node> - <node name="nat-networks"> - <properties> - <help>Network Address Translation (NAT) networks</help> - </properties> - <children> - <tagNode name="allowed-network"> - <properties> - <help>NAT networks to allow</help> - <valueHelp> - <format>ipv4net</format> - <description>NAT networks to allow</description> - </valueHelp> - <constraint> - <validator name="ip-prefix"/> - </constraint> - </properties> - <children> - <leafNode name="exclude"> - <properties> - <help>NAT networks to exclude from allowed-networks</help> - <valueHelp> - <format>ipv4net</format> - <description>NAT networks to exclude from allowed-networks</description> - </valueHelp> - <constraint> - <validator name="ip-prefix"/> - </constraint> - <multi/> - </properties> - </leafNode> - </children> - </tagNode> - </children> - </node> - <leafNode name="nat-traversal"> - <properties> - <help>Network Address Translation (NAT) traversal</help> - <completionHelp> - <list>disable enable</list> - </completionHelp> - <valueHelp> - <format>disable</format> - <description>Disable NAT-T</description> - </valueHelp> - <valueHelp> - <format>enable</format> - <description>Enable NAT-T</description> - </valueHelp> - <constraint> - <regex>^(disable|enable)$</regex> - </constraint> - </properties> - </leafNode> - <node name="options"> - <properties> - <help>Global IPsec settings</help> - </properties> - <children> - <leafNode name="disable-route-autoinstall"> - <properties> - <help>Do not automatically install routes to remote networks</help> - <valueless/> - </properties> - </leafNode> - </children> - </node> - <tagNode name="profile"> - <properties> - <help>VPN IPSec Profile</help> - </properties> - <children> - <node name="authentication"> - <properties> - <help>Authentication [REQUIRED]</help> - </properties> - <children> - <node name="mode"> - <properties> - <help>Authentication mode</help> - </properties> - <children> - <leafNode name="pre-shared-secret"> - <properties> - <help>Use pre-shared secret key</help> - <valueless/> - </properties> - </leafNode> - </children> - </node> - <leafNode name="pre-shared-secret"> - <properties> - <help>Pre-shared secret key</help> - <valueHelp> - <format>txt</format> - <description>Pre-shared secret key</description> - </valueHelp> - </properties> - </leafNode> - </children> - </node> - <node name="bind"> - <properties> - <help>DMVPN crypto configuration</help> - </properties> - <children> - <leafNode name="bind_child"> - <properties> - <help>bind_child_help</help> - <valueless/> - </properties> - </leafNode> - </children> - </node> - <leafNode name="esp-group"> - <properties> - <help>Esp group name [REQUIRED]</help> - <completionHelp> - <path>vpn ipsec esp-group</path> - </completionHelp> - </properties> - </leafNode> - <leafNode name="ike-group"> - <properties> - <help>Ike group name [REQUIRED]</help> - <completionHelp> - <path>vpn ipsec ike-group</path> - </completionHelp> - </properties> - </leafNode> - </children> - </tagNode> - <node name="site-to-site"> - <properties> - <help>Site to site VPN</help> - </properties> - <children> - <tagNode name="peer"> - <properties> - <help>VPN peer</help> - <valueHelp> - <format>ipv4</format> - <description>IPv4 address of the peer</description> - </valueHelp> - <valueHelp> - <format>ipv6</format> - <description>IPv6 address of the peer</description> - </valueHelp> - <valueHelp> - <format>txt</format> - <description>Hostname of the peer</description> - </valueHelp> - <valueHelp> - <format><@text></format> - <description>ID of the peer</description> - </valueHelp> - </properties> - <children> - <node name="authentication"> - <properties> - <help>Peer authentication [REQUIRED]</help> - </properties> - <children> - <leafNode name="id"> - <properties> - <help>ID for peer authentication</help> - <valueHelp> - <format>txt</format> - <description>ID used for peer authentication</description> - </valueHelp> - </properties> - </leafNode> - <leafNode name="mode"> - <properties> - <help>Authentication mode</help> - <completionHelp> - <list>pre-shared-secret rsa x509</list> - </completionHelp> - <valueHelp> - <format>pre-shared-secret</format> - <description>pre-shared-secret_description</description> - </valueHelp> - <valueHelp> - <format>rsa</format> - <description>rsa_description</description> - </valueHelp> - <valueHelp> - <format>x509</format> - <description>x509_description</description> - </valueHelp> - <constraint> - <regex>^(pre-shared-secret|rsa|x509)$</regex> - </constraint> - </properties> - </leafNode> - <leafNode name="pre-shared-secret"> - <properties> - <help>Pre-shared secret key</help> - <valueHelp> - <format>txt</format> - <description>Pre-shared secret key</description> - </valueHelp> - </properties> - </leafNode> - <leafNode name="remote-id"> - <properties> - <help>ID for remote authentication</help> - <valueHelp> - <format>txt</format> - <description>ID used for peer authentication</description> - </valueHelp> - </properties> - </leafNode> - <leafNode name="rsa-key-name"> - <properties> - <help>RSA key name</help> - </properties> - </leafNode> - <leafNode name="use-x509-id"> - <properties> - <help>Use certificate common name as ID</help> - <valueless/> - </properties> - </leafNode> - <node name="x509"> - <properties> - <help>X.509 certificate</help> - </properties> - <children> - #include <include/certificate.xml.i> - #include <include/certificate-ca.xml.i> - <leafNode name="crl-file"> - <properties> - <help>File containing the X.509 Certificate Revocation List (CRL)</help> - <valueHelp> - <format>txt</format> - <description>File in /config/auth</description> - </valueHelp> - </properties> - </leafNode> - <node name="key"> - <properties> - <help>Key file and password to open it</help> - </properties> - <children> - <leafNode name="file"> - <properties> - <help>File containing the private key for the X.509 certificate for this host</help> - <valueHelp> - <format>txt</format> - <description>File in /config/auth</description> - </valueHelp> - </properties> - </leafNode> - <leafNode name="password"> - <properties> - <help>Password that protects the private key</help> - <valueHelp> - <format>txt</format> - <description>Password that protects the private key</description> - </valueHelp> - </properties> - </leafNode> - </children> - </node> - </children> - </node> - </children> - </node> - <leafNode name="connection-type"> - <properties> - <help>Connection type</help> - <completionHelp> - <list>initiate respond</list> - </completionHelp> - <valueHelp> - <format>initiate</format> - <description>initiate_description</description> - </valueHelp> - <valueHelp> - <format>respond</format> - <description>respond_description</description> - </valueHelp> - <constraint> - <regex>^(initiate|respond)$</regex> - </constraint> - </properties> - </leafNode> - <leafNode name="default-esp-group"> - <properties> - <help>Defult ESP group name</help> - </properties> - </leafNode> - <leafNode name="description"> - <properties> - <help>VPN peer description</help> - <valueless/> - </properties> - </leafNode> - <leafNode name="dhcp-interface"> - <properties> - <help>DHCP interface to listen on</help> - <valueless/> - </properties> - </leafNode> - <leafNode name="force-encapsulation"> - <properties> - <help>Force UDP Encapsulation for ESP Payloads</help> - <completionHelp> - <list>enable disable</list> - </completionHelp> - <valueHelp> - <format>enable</format> - <description>This endpoint will force UDP encapsulation for this peer</description> - </valueHelp> - <valueHelp> - <format>disable</format> - <description>This endpoint will not force UDP encapsulation for this peer</description> - </valueHelp> - <constraint> - <regex>^(enable|disable)$</regex> - </constraint> - </properties> - </leafNode> - <leafNode name="ike-group"> - <properties> - <help>Internet Key Exchange (IKE) group name [REQUIRED]</help> - <completionHelp> - <path>vpn ipsec ike-group</path> - </completionHelp> - </properties> - </leafNode> - <leafNode name="ikev2-reauth"> - <properties> - <help>Re-authentication of the remote peer during an IKE re-key. IKEv2 option only</help> - <completionHelp> - <list>yes no inherit</list> - </completionHelp> - <valueHelp> - <format>yes</format> - <description>Enable remote host re-autentication during an IKE re-key. Currently broken due to a strong swan bug</description> - </valueHelp> - <valueHelp> - <format>no</format> - <description>Disable remote host re-authenticaton during an IKE re-key.</description> - </valueHelp> - <valueHelp> - <format>inherit</format> - <description>Inherit the reauth configuration form your IKE-group (Default)</description> - </valueHelp> - <constraint> - <regex>^(yes|no|inherit)$</regex> - </constraint> - </properties> - </leafNode> - <leafNode name="local-address"> - <properties> - <help>IPv4 or IPv6 address of a local interface to use for VPN</help> - <completionHelp> - <list>any</list> - </completionHelp> - <valueHelp> - <format>ipv4</format> - <description>IPv4 address of a local interface for VPN</description> - </valueHelp> - <valueHelp> - <format>ipv6</format> - <description>IPv6 address of a local interface for VPN</description> - </valueHelp> - <valueHelp> - <format>any</format> - <description>Allow any IPv4 address present on the system to be used for VPN</description> - </valueHelp> - <constraint> - <validator name="ipv4-address"/> - <validator name="ipv6-address"/> - <regex>^(any)$</regex> - </constraint> - </properties> - </leafNode> - <tagNode name="tunnel"> - <properties> - <help>Peer tunnel [REQUIRED]</help> - <valueHelp> - <format>u32</format> - <description>Peer tunnel [REQUIRED]</description> - </valueHelp> - </properties> - <children> - <leafNode name="allow-nat-networks"> - <properties> - <help>Option to allow NAT networks</help> - <completionHelp> - <list>enable disable</list> - </completionHelp> - <valueHelp> - <format>enable</format> - <description>Enable NAT networks</description> - </valueHelp> - <valueHelp> - <format>disable</format> - <description>Disable NAT networks (default)</description> - </valueHelp> - <constraint> - <regex>^(enable|disable)$</regex> - </constraint> - </properties> - </leafNode> - <leafNode name="allow-public-networks"> - <properties> - <help>Option to allow public networks</help> - <completionHelp> - <list>enable disable</list> - </completionHelp> - <valueHelp> - <format>enable</format> - <description>Enable public networks</description> - </valueHelp> - <valueHelp> - <format>disable</format> - <description>Disable public networks (default)</description> - </valueHelp> - <constraint> - <regex>^(enable|disable)$</regex> - </constraint> - </properties> - </leafNode> - #include <include/generic-disable-node.xml.i> - <leafNode name="esp-group"> - <properties> - <help>ESP group name</help> - <completionHelp> - <path>vpn ipsec esp-group</path> - </completionHelp> - </properties> - </leafNode> - <node name="local"> - <properties> - <help>Local parameters for interesting traffic</help> - </properties> - <children> - <leafNode name="port"> - <properties> - <help>Any TCP or UDP port</help> - <valueHelp> - <format>port name</format> - <description>Named port (any name in /etc/services, e.g., http)</description> - </valueHelp> - <valueHelp> - <format>u32:1-65535</format> - <description>Numbered port</description> - </valueHelp> - </properties> - </leafNode> - <leafNode name="prefix"> - <properties> - <help>Local IPv4 or IPv6 prefix</help> - <valueHelp> - <format>ipv4</format> - <description>Local IPv4 prefix</description> - </valueHelp> - <valueHelp> - <format>ipv6</format> - <description>Local IPv6 prefix</description> - </valueHelp> - <constraint> - <validator name="ipv4-prefix"/> - <validator name="ipv6-prefix"/> - </constraint> - </properties> - </leafNode> - </children> - </node> - <leafNode name="protocol"> - <properties> - <help>Protocol to encrypt</help> - <valueless/> - </properties> - </leafNode> - <node name="remote"> - <properties> - <help>Remote parameters for interesting traffic</help> - </properties> - <children> - <leafNode name="port"> - <properties> - <help>Any TCP or UDP port</help> - <valueHelp> - <format>port name</format> - <description>Named port (any name in /etc/services, e.g., http)</description> - </valueHelp> - <valueHelp> - <format>u32:1-65535</format> - <description>Numbered port</description> - </valueHelp> - </properties> - </leafNode> - <leafNode name="prefix"> - <properties> - <help>Remote IPv4 or IPv6 prefix</help> - <valueHelp> - <format>ipv4</format> - <description>Remote IPv4 prefix</description> - </valueHelp> - <valueHelp> - <format>ipv6</format> - <description>Remote IPv6 prefix</description> - </valueHelp> - <constraint> - <validator name="ipv4-prefix"/> - <validator name="ipv6-prefix"/> - </constraint> - </properties> - </leafNode> - </children> - </node> - </children> - </tagNode> - <node name="vti"> - <properties> - <help>Virtual tunnel interface [REQUIRED]</help> - </properties> - <children> - <leafNode name="bind"> - <properties> - <help>VTI tunnel interface associated with this configuration [REQUIRED]</help> - </properties> - </leafNode> - <leafNode name="esp-group"> - <properties> - <help>ESP group name [REQUIRED]</help> - <completionHelp> - <path>vpn ipsec esp-group</path> - </completionHelp> - </properties> - </leafNode> - </children> - </node> - </children> - </tagNode> - </children> - </node> - </children> - </node> - </children> - </node> -</interfaceDefinition> diff --git a/interface-definitions/vpn_l2tp.xml.in b/interface-definitions/vpn_l2tp.xml.in index 5bdebcb05..787298284 100644 --- a/interface-definitions/vpn_l2tp.xml.in +++ b/interface-definitions/vpn_l2tp.xml.in @@ -220,9 +220,9 @@ #include <include/accel-ppp/radius-additions-disable-accounting.xml.i> <leafNode name="fail-time"> <properties> - <help>Mark server unavailable for <n> seconds on failure</help> + <help>Mark server unavailable for N seconds on failure</help> <valueHelp> - <format>0-600</format> + <format>u32:0-600</format> <description>Fail time penalty</description> </valueHelp> <constraint> diff --git a/interface-definitions/vpn_sstp.xml.in b/interface-definitions/vpn_sstp.xml.in index e4ade844d..840e237cc 100644 --- a/interface-definitions/vpn_sstp.xml.in +++ b/interface-definitions/vpn_sstp.xml.in @@ -25,7 +25,7 @@ </node> </children> </node> - #include <include/interface/interface-mtu-68-1500.xml.i> + #include <include/interface/mtu-68-1500.xml.i> #include <include/accel-ppp/gateway-address.xml.i> #include <include/accel-ppp/name-server.xml.i> <node name="client-ip-pool"> diff --git a/interface-definitions/vrf.xml.in b/interface-definitions/vrf.xml.in index 5fd758a44..306b15d60 100644 --- a/interface-definitions/vrf.xml.in +++ b/interface-definitions/vrf.xml.in @@ -30,17 +30,17 @@ <properties> <help>Routing table associated with this instance</help> <valueHelp> - <format>100-2147483647</format> + <format>u32:100-65535</format> <description>Routing table ID</description> </valueHelp> <constraint> - <validator name="numeric" argument="--range 100-2147483647"/> + <validator name="numeric" argument="--range 100-65535"/> </constraint> - <constraintErrorMessage>VRF routing table must be in range from 100 to 2147483647</constraintErrorMessage> + <constraintErrorMessage>VRF routing table must be in range from 100 to 65535</constraintErrorMessage> </properties> </leafNode> - #include <include/interface/interface-description.xml.i> - #include <include/interface/interface-disable.xml.i> + #include <include/interface/description.xml.i> + #include <include/interface/disable.xml.i> </children> </tagNode> </children> diff --git a/interface-definitions/vrrp.xml.in b/interface-definitions/vrrp.xml.in index 54cd44275..829e7ea01 100644 --- a/interface-definitions/vrrp.xml.in +++ b/interface-definitions/vrrp.xml.in @@ -45,7 +45,7 @@ <properties> <help>VRRP password</help> <valueHelp> - <format>text</format> + <format>txt</format> <description>Password string (up to 8 characters)</description> </valueHelp> <constraint> @@ -282,7 +282,7 @@ <multi/> <help>Sync group member</help> <valueHelp> - <format>text</format> + <format>txt</format> <description>VRRP group name</description> </valueHelp> <completionHelp> diff --git a/op-mode-definitions/dhcp.xml.in b/op-mode-definitions/dhcp.xml.in index 1dacbd5ba..6f0c25110 100644 --- a/op-mode-definitions/dhcp.xml.in +++ b/op-mode-definitions/dhcp.xml.in @@ -22,7 +22,7 @@ <properties> <help>Show DHCP server leases for a specific pool</help> <completionHelp> - <script>sudo ${vyos_op_scripts_dir}/show_dhcp.py --allowed pool</script> + <path>service dhcp-server shared-network-name</path> </completionHelp> </properties> <command>sudo ${vyos_op_scripts_dir}/show_dhcp.py --leases --pool $6</command> @@ -57,7 +57,7 @@ <properties> <help>Show DHCP server statistics for a specific pool</help> <completionHelp> - <script>sudo ${vyos_op_scripts_dir}/show_dhcp.py --allowed pool</script> + <path>service dhcp-server shared-network-name</path> </completionHelp> </properties> <command>sudo ${vyos_op_scripts_dir}/show_dhcp.py --statistics --pool $6</command> diff --git a/op-mode-definitions/dns-forwarding.xml.in b/op-mode-definitions/dns-forwarding.xml.in index 36fe6b5ef..6574f2319 100644 --- a/op-mode-definitions/dns-forwarding.xml.in +++ b/op-mode-definitions/dns-forwarding.xml.in @@ -59,9 +59,6 @@ </children> </node> <node name="reset"> - <properties> - <help>Reset a service</help> - </properties> <children> <node name="dns"> <properties> diff --git a/op-mode-definitions/include/bgp/afi-common.xml.i b/op-mode-definitions/include/bgp/afi-common.xml.i index 7fc59f3b0..4d5f56656 100644 --- a/op-mode-definitions/include/bgp/afi-common.xml.i +++ b/op-mode-definitions/include/bgp/afi-common.xml.i @@ -7,23 +7,33 @@ </completionHelp> </properties> <children> - <leafNode name="exact-match"> - <properties> - <help>Exact match of the communities</help> - </properties> - <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command> - </leafNode> + #include <include/bgp/exact-match.xml.i> </children> <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command> </tagNode> <tagNode name="large-community"> <properties> - <help>List of large-community numbers</help> + <help>Display routes matching the large-communities</help> <completionHelp> <list>AA:BB:CC</list> </completionHelp> </properties> <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command> + <children> + #include <include/bgp/exact-match.xml.i> + </children> +</tagNode> +<tagNode name="large-community-list"> + <properties> + <help>Display routes matching the large-community-list</help> + <completionHelp> + <path>policy large-community-list</path> + </completionHelp> + </properties> + <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command> + <children> + #include <include/bgp/exact-match.xml.i> + </children> </tagNode> <leafNode name="statistics"> <properties> diff --git a/op-mode-definitions/include/bgp/afi-ipv4-ipv6-common.xml.i b/op-mode-definitions/include/bgp/afi-ipv4-ipv6-common.xml.i index f1b699347..a51595b7f 100644 --- a/op-mode-definitions/include/bgp/afi-ipv4-ipv6-common.xml.i +++ b/op-mode-definitions/include/bgp/afi-ipv4-ipv6-common.xml.i @@ -22,12 +22,7 @@ </properties> <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command> </leafNode> - <leafNode name="exact-match"> - <properties> - <help>Exact match of the communities</help> - </properties> - <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command> - </leafNode> + #include <include/bgp/exact-match.xml.i> <leafNode name="graceful-shutdown"> <properties> <help>Graceful shutdown (well-known community)</help> @@ -105,12 +100,7 @@ </completionHelp> </properties> <children> - <leafNode name="exact-match"> - <properties> - <help>Show BGP routes exactly matching specified community list</help> - </properties> - <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command> - </leafNode> + #include <include/bgp/exact-match.xml.i> </children> <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command> </tagNode> diff --git a/op-mode-definitions/include/bgp/exact-match.xml.i b/op-mode-definitions/include/bgp/exact-match.xml.i new file mode 100644 index 000000000..49026db9b --- /dev/null +++ b/op-mode-definitions/include/bgp/exact-match.xml.i @@ -0,0 +1,8 @@ +<!-- included start from bgp/exact-match.xml.i --> +<leafNode name="exact-match"> + <properties> + <help>Exact match of the communities</help> + </properties> + <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command> +</leafNode> +<!-- included end --> diff --git a/op-mode-definitions/ipv4-route.xml.in b/op-mode-definitions/ipv4-route.xml.in index aab3df0f1..8f001d5bb 100644 --- a/op-mode-definitions/ipv4-route.xml.in +++ b/op-mode-definitions/ipv4-route.xml.in @@ -20,11 +20,7 @@ </node> </children> </node> - <node name="reset"> - <properties> - <help>Reset a service</help> - </properties> <children> <node name="ip"> <properties> @@ -56,7 +52,6 @@ </tagNode> </children> </node> - <node name="route"> <properties> <help>Reset IP route</help> @@ -68,7 +63,6 @@ </properties> <command>sudo ip route flush cache</command> </leafNode> - <tagNode name="cache"> <properties> <help>Flush the kernel route cache for a given route</help> diff --git a/op-mode-definitions/ipv6-route.xml.in b/op-mode-definitions/ipv6-route.xml.in index 28f5b1aad..1c238e1f3 100644 --- a/op-mode-definitions/ipv6-route.xml.in +++ b/op-mode-definitions/ipv6-route.xml.in @@ -28,11 +28,7 @@ </node> </children> </node> - <node name="reset"> - <properties> - <help>Reset a service</help> - </properties> <children> <node name="ipv6"> <properties> @@ -64,7 +60,6 @@ </tagNode> </children> </node> - <node name="route"> <properties> <help>Reset IPv6 route</help> @@ -76,7 +71,6 @@ </properties> <command>sudo ip -f inet6 route flush cache</command> </leafNode> - <tagNode name="cache"> <properties> <help>Flush the kernel IPv6 route cache for a given route</help> diff --git a/op-mode-definitions/monitor-protocol.xml.in b/op-mode-definitions/monitor-protocol.xml.in index 6a6bd50f3..f3af3575c 100644 --- a/op-mode-definitions/monitor-protocol.xml.in +++ b/op-mode-definitions/monitor-protocol.xml.in @@ -263,13 +263,14 @@ </node> <node name="ospf"> <properties> - <help>Monitor the Open Shortest Path First (OSPF) protocol</help> + <help>Monitor Open Shortest Path First (OSPF) protocol</help> </properties> <children> #include <include/monitor-background.xml.i> - - <node name="disable"> + <properties> + <help>Disable Open Shortest Path First (OSPF) debugging</help> + </properties> <children> <node name="event"> <properties> @@ -458,6 +459,9 @@ </children> </node> <node name="enable"> + <properties> + <help>Enable Open Shortest Path First (OSPF) debugging</help> + </properties> <children> <node name="event"> <properties> diff --git a/op-mode-definitions/openvpn.xml.in b/op-mode-definitions/openvpn.xml.in index f8dc0cff0..0a8cf64d7 100644 --- a/op-mode-definitions/openvpn.xml.in +++ b/op-mode-definitions/openvpn.xml.in @@ -45,11 +45,11 @@ </children> </node> <node name="reset"> - <properties> - <help>Reset a service</help> - </properties> <children> <node name="openvpn"> + <properties> + <help>Reset OpenVPN client/server connections</help> + </properties> <children> <tagNode name="client"> <properties> diff --git a/op-mode-definitions/pppoe-server.xml.in b/op-mode-definitions/pppoe-server.xml.in index 6d89b3e77..3d0df44a3 100644 --- a/op-mode-definitions/pppoe-server.xml.in +++ b/op-mode-definitions/pppoe-server.xml.in @@ -40,9 +40,6 @@ </children> </node> <node name="reset"> - <properties> - <help>Reset a service</help> - </properties> <children> <node name="pppoe-server"> <properties> diff --git a/op-mode-definitions/reset-conntrack.xml.in b/op-mode-definitions/reset-conntrack.xml.in index 827ba4af4..9c8265f77 100644 --- a/op-mode-definitions/reset-conntrack.xml.in +++ b/op-mode-definitions/reset-conntrack.xml.in @@ -1,9 +1,6 @@ <?xml version="1.0"?> <interfaceDefinition> <node name="reset"> - <properties> - <help>Reset a service</help> - </properties> <children> <node name="conntrack"> <properties> diff --git a/op-mode-definitions/reset-vpn.xml.in b/op-mode-definitions/reset-vpn.xml.in index 71dbb4ed9..94ee1c7df 100644 --- a/op-mode-definitions/reset-vpn.xml.in +++ b/op-mode-definitions/reset-vpn.xml.in @@ -1,9 +1,6 @@ <?xml version="1.0"?> <interfaceDefinition> <node name="reset"> - <properties> - <help>Reset a service</help> - </properties> <children> <node name="vpn"> <properties> diff --git a/op-mode-definitions/restart-frr.xml.in b/op-mode-definitions/restart-frr.xml.in index 96ad1a650..475bd1ee8 100644 --- a/op-mode-definitions/restart-frr.xml.in +++ b/op-mode-definitions/restart-frr.xml.in @@ -2,62 +2,66 @@ <interfaceDefinition> <node name="restart"> <children> - <node name="frr"> + <leafNode name="all"> <properties> - <help>Restart FRRouting daemons</help> + <help>Restart all routing daemons</help> </properties> <command>sudo ${vyos_op_scripts_dir}/restart_frr.py --action restart</command> - <children> - <leafNode name="bfdd"> - <properties> - <help>Restart Bidirectional Forwarding Detection daemon</help> - </properties> - <command>sudo ${vyos_op_scripts_dir}/restart_frr.py --action restart --daemon bfdd</command> - </leafNode> - <leafNode name="bgpd"> - <properties> - <help>Restart Border Gateway Protocol daemon</help> - </properties> - <command>sudo ${vyos_op_scripts_dir}/restart_frr.py --action restart --daemon bgpd</command> - </leafNode> - <leafNode name="ospfd"> - <properties> - <help>Restart OSPFv2 daemon</help> - </properties> - <command>sudo ${vyos_op_scripts_dir}/restart_frr.py --action restart --daemon ospfd</command> - </leafNode> - <leafNode name="ospf6d"> - <properties> - <help>Restart OSPFv3 daemon</help> - </properties> - <command>sudo ${vyos_op_scripts_dir}/restart_frr.py --action restart --daemon ospf6d</command> - </leafNode> - <leafNode name="ripd"> - <properties> - <help>Restart Routing Information Protocol daemon</help> - </properties> - <command>sudo ${vyos_op_scripts_dir}/restart_frr.py --action restart --daemon ripd</command> - </leafNode> - <leafNode name="ripngd"> - <properties> - <help>Restart RIPng daemon</help> - </properties> - <command>sudo ${vyos_op_scripts_dir}/restart_frr.py --action restart --daemon ripngd</command> - </leafNode> - <leafNode name="staticd"> - <properties> - <help>Restart Static Route daemon</help> - </properties> - <command>sudo ${vyos_op_scripts_dir}/restart_frr.py --action restart --daemon staticd</command> - </leafNode> - <leafNode name="zebra"> - <properties> - <help>Restart IP routing manager daemon</help> - </properties> - <command>sudo ${vyos_op_scripts_dir}/restart_frr.py --action restart --daemon zebra</command> - </leafNode> - </children> - </node> + </leafNode> + <leafNode name="bfd"> + <properties> + <help>Restart Bidirectional Forwarding Detection (BFD) daemon</help> + </properties> + <command>sudo ${vyos_op_scripts_dir}/restart_frr.py --action restart --daemon bfdd</command> + </leafNode> + <leafNode name="bgp"> + <properties> + <help>Restart Border Gateway Protocol (BGP) routing daemon</help> + </properties> + <command>sudo ${vyos_op_scripts_dir}/restart_frr.py --action restart --daemon bgpd</command> + </leafNode> + <leafNode name="isis"> + <properties> + <help>Restart Intermediate System to Intermediate System (IS-IS) routing daemon</help> + </properties> + <command>sudo ${vyos_op_scripts_dir}/restart_frr.py --action restart --daemon isisd</command> + </leafNode> + <leafNode name="ospf"> + <properties> + <help>Restart Open Shortest Path First (OSPF) routing daemon</help> + </properties> + <command>sudo ${vyos_op_scripts_dir}/restart_frr.py --action restart --daemon ospfd</command> + </leafNode> + <leafNode name="ospfv3"> + <properties> + <help>Restart IPv6 Open Shortest Path First (OSPFv3) routing daemon</help> + </properties> + <command>sudo ${vyos_op_scripts_dir}/restart_frr.py --action restart --daemon ospf6d</command> + </leafNode> + <leafNode name="rip"> + <properties> + <help>Restart Routing Information Protocol (RIP) routing daemon</help> + </properties> + <command>sudo ${vyos_op_scripts_dir}/restart_frr.py --action restart --daemon ripd</command> + </leafNode> + <leafNode name="ripng"> + <properties> + <help>Restart Routing Information Protocol NG (RIPng) routing daemon</help> + </properties> + <command>sudo ${vyos_op_scripts_dir}/restart_frr.py --action restart --daemon ripngd</command> + </leafNode> + <leafNode name="static"> + <properties> + <help>Restart static routing daemon</help> + </properties> + <command>sudo ${vyos_op_scripts_dir}/restart_frr.py --action restart --daemon staticd</command> + </leafNode> + <leafNode name="zebra"> + <properties> + <help>Restart Routing Information Base (RIB) manager daemon</help> + </properties> + <command>sudo ${vyos_op_scripts_dir}/restart_frr.py --action restart --daemon zebra</command> + </leafNode> </children> </node> </interfaceDefinition> diff --git a/op-mode-definitions/show-interfaces-bonding.xml.in b/op-mode-definitions/show-interfaces-bonding.xml.in index c1c76b059..d4e737d5b 100644 --- a/op-mode-definitions/show-interfaces-bonding.xml.in +++ b/op-mode-definitions/show-interfaces-bonding.xml.in @@ -6,7 +6,7 @@ <children> <tagNode name="bonding"> <properties> - <help>Show bonding interface information</help> + <help>Show specified Bonding interface information</help> <completionHelp> <path>interfaces bonding</path> </completionHelp> @@ -46,7 +46,7 @@ </tagNode> <node name="bonding"> <properties> - <help>Show bonding interface information</help> + <help>Show Bonding interface information</help> </properties> <command>${vyos_op_scripts_dir}/show_interfaces.py --intf-type=bonding --action=show-brief</command> <children> diff --git a/op-mode-definitions/show-interfaces-bridge.xml.in b/op-mode-definitions/show-interfaces-bridge.xml.in index cc4b248b6..d4908b341 100644 --- a/op-mode-definitions/show-interfaces-bridge.xml.in +++ b/op-mode-definitions/show-interfaces-bridge.xml.in @@ -6,7 +6,7 @@ <children> <tagNode name="bridge"> <properties> - <help>Show bridge interface information</help> + <help>Show specified Bridge interface information</help> <completionHelp> <path>interfaces bridge</path> </completionHelp> @@ -23,7 +23,7 @@ </tagNode> <node name="bridge"> <properties> - <help>Show bridge interface information</help> + <help>Show Bridge interface information</help> </properties> <command>${vyos_op_scripts_dir}/show_interfaces.py --intf-type=bridge --action=show-brief</command> <children> diff --git a/op-mode-definitions/show-interfaces-dummy.xml.in b/op-mode-definitions/show-interfaces-dummy.xml.in index 7c24c6921..52d2cc7ee 100644 --- a/op-mode-definitions/show-interfaces-dummy.xml.in +++ b/op-mode-definitions/show-interfaces-dummy.xml.in @@ -6,7 +6,7 @@ <children> <tagNode name="dummy"> <properties> - <help>Show dummy interface information</help> + <help>Show specified Dummy interface information</help> <completionHelp> <path>interfaces dummy</path> </completionHelp> @@ -23,7 +23,7 @@ </tagNode> <node name="dummy"> <properties> - <help>Show dummy interface information</help> + <help>Show Dummy interface information</help> </properties> <command>${vyos_op_scripts_dir}/show_interfaces.py --intf-type=dummy --action=show-brief</command> <children> diff --git a/op-mode-definitions/show-interfaces-ethernet.xml.in b/op-mode-definitions/show-interfaces-ethernet.xml.in index bdcfa55f1..e414291d1 100644 --- a/op-mode-definitions/show-interfaces-ethernet.xml.in +++ b/op-mode-definitions/show-interfaces-ethernet.xml.in @@ -6,7 +6,7 @@ <children> <tagNode name="ethernet"> <properties> - <help>Show ethernet interface information</help> + <help>Show specified Ethernet interface information</help> <completionHelp> <path>interfaces ethernet</path> </completionHelp> @@ -23,19 +23,19 @@ <properties> <help>Visually identify specified ethernet interface</help> </properties> - <command>echo "Blinking interface $4 for 30 seconds."; /sbin/ethtool --identify "$4" 30</command> + <command>echo "Blinking interface $4 for 30 seconds."; ethtool --identify "$4" 30</command> </leafNode> <node name="physical"> <properties> <help>Show physical device information for specified ethernet interface</help> </properties> - <command>/sbin/ethtool "$4"; /sbin/ethtool -i "$4"</command> + <command>ethtool "$4"; ethtool --show-ring "$4"; ethtool --driver "$4"</command> <children> <leafNode name="offload"> <properties> <help>Show physical device offloading capabilities</help> </properties> - <command>/sbin/ethtool -k "$4" | sed -e 1d -e '/fixed/d' -e 's/^\t*//g' -e 's/://' | column -t -s' '</command> + <command>ethtool --show-features "$4" | sed -e 1d -e '/fixed/d' -e 's/^\t*//g' -e 's/://' | column -t -s' '</command> </leafNode> </children> </node> @@ -43,13 +43,13 @@ <properties> <help>Show physical device statistics for specified ethernet interface</help> </properties> - <command>/sbin/ethtool -S "$4"</command> + <command>ethtool --statistics "$4"</command> </leafNode> <leafNode name="transceiver"> <properties> <help>Show transceiver information from modules (e.g SFP+, QSFP)</help> </properties> - <command>/sbin/ethtool -m "$4"</command> + <command>ethtool --module-info "$4"</command> </leafNode> <tagNode name="vif"> <properties> @@ -72,7 +72,7 @@ </tagNode> <node name="ethernet"> <properties> - <help>Show ethernet interface information</help> + <help>Show Ethernet interface information</help> </properties> <command>${vyos_op_scripts_dir}/show_interfaces.py --intf-type=ethernet --action=show-brief</command> <children> diff --git a/op-mode-definitions/show-interfaces-input.xml.in b/op-mode-definitions/show-interfaces-input.xml.in index 15e8203e5..9ae3828c8 100644 --- a/op-mode-definitions/show-interfaces-input.xml.in +++ b/op-mode-definitions/show-interfaces-input.xml.in @@ -6,7 +6,7 @@ <children> <tagNode name="input"> <properties> - <help>Show input interface information</help> + <help>Show specified Input interface information</help> <completionHelp> <path>interfaces input</path> </completionHelp> @@ -23,7 +23,7 @@ </tagNode> <node name="input"> <properties> - <help>Show input interface information</help> + <help>Show Input (ifb) interface information</help> </properties> <command>${vyos_op_scripts_dir}/show_interfaces.py --intf-type=input --action=show-brief</command> <children> diff --git a/op-mode-definitions/show-interfaces-l2tpv3.xml.in b/op-mode-definitions/show-interfaces-l2tpv3.xml.in index 60fee34a1..2a1d6a1c6 100644 --- a/op-mode-definitions/show-interfaces-l2tpv3.xml.in +++ b/op-mode-definitions/show-interfaces-l2tpv3.xml.in @@ -6,7 +6,7 @@ <children> <tagNode name="l2tpv3"> <properties> - <help>Show L2TPv3 interface information</help> + <help>Show specified L2TPv3 interface information</help> <completionHelp> <path>interfaces l2tpv3</path> </completionHelp> diff --git a/op-mode-definitions/show-interfaces-loopback.xml.in b/op-mode-definitions/show-interfaces-loopback.xml.in index b30b57909..25a75ffff 100644 --- a/op-mode-definitions/show-interfaces-loopback.xml.in +++ b/op-mode-definitions/show-interfaces-loopback.xml.in @@ -6,7 +6,7 @@ <children> <tagNode name="loopback"> <properties> - <help>Show loopback interface information</help> + <help>Show specified Loopback interface information</help> <completionHelp> <path>interfaces loopback</path> </completionHelp> @@ -23,7 +23,7 @@ </tagNode> <node name="loopback"> <properties> - <help>Show loopback interface information</help> + <help>Show Loopback interface information</help> </properties> <command>${vyos_op_scripts_dir}/show_interfaces.py --intf-type=loopback --action=show-brief</command> <children> diff --git a/op-mode-definitions/show-interfaces-pppoe.xml.in b/op-mode-definitions/show-interfaces-pppoe.xml.in index 18697a275..767836abf 100644 --- a/op-mode-definitions/show-interfaces-pppoe.xml.in +++ b/op-mode-definitions/show-interfaces-pppoe.xml.in @@ -6,7 +6,7 @@ <children> <tagNode name="pppoe"> <properties> - <help>Show PPPoE interface information</help> + <help>Show specified PPPoE interface information</help> <completionHelp> <path>interfaces pppoe</path> </completionHelp> diff --git a/op-mode-definitions/show-interfaces-pseudo-ethernet.xml.in b/op-mode-definitions/show-interfaces-pseudo-ethernet.xml.in index 195944745..2ae4b5a9e 100644 --- a/op-mode-definitions/show-interfaces-pseudo-ethernet.xml.in +++ b/op-mode-definitions/show-interfaces-pseudo-ethernet.xml.in @@ -6,7 +6,7 @@ <children> <tagNode name="pseudo-ethernet"> <properties> - <help>Show pseudo-ethernet/MACvlan interface information</help> + <help>Show specified Pseudo-Ethernet/MACvlan interface information</help> <completionHelp> <path>interfaces pseudo-ethernet</path> </completionHelp> @@ -23,7 +23,7 @@ </tagNode> <node name="pseudo-ethernet"> <properties> - <help>Show pseudo-ethernet/MACvlan interface information</help> + <help>Show Pseudo-Ethernet/MACvlan interface information</help> </properties> <command>${vyos_op_scripts_dir}/show_interfaces.py --intf-type=pseudo-ethernet --action=show-brief</command> <children> diff --git a/op-mode-definitions/show-interfaces-tunnel.xml.in b/op-mode-definitions/show-interfaces-tunnel.xml.in index 416de0299..51b25efd9 100644 --- a/op-mode-definitions/show-interfaces-tunnel.xml.in +++ b/op-mode-definitions/show-interfaces-tunnel.xml.in @@ -6,7 +6,7 @@ <children> <tagNode name="tunnel"> <properties> - <help>Show tunnel interface information</help> + <help>Show specified Tunnel interface information</help> <completionHelp> <path>interfaces tunnel</path> </completionHelp> @@ -23,7 +23,7 @@ </tagNode> <node name="tunnel"> <properties> - <help>Show tunnel interface information</help> + <help>Show Tunnel interface information</help> </properties> <command>${vyos_op_scripts_dir}/show_interfaces.py --intf-type=tunnel --action=show-brief</command> <children> diff --git a/op-mode-definitions/show-interfaces-vti.xml.in b/op-mode-definitions/show-interfaces-vti.xml.in index f51be2d19..b436b8414 100644 --- a/op-mode-definitions/show-interfaces-vti.xml.in +++ b/op-mode-definitions/show-interfaces-vti.xml.in @@ -6,7 +6,7 @@ <children> <tagNode name="vti"> <properties> - <help>Show vti interface information</help> + <help>Show specified VTI interface information</help> <completionHelp> <path>interfaces vti</path> </completionHelp> @@ -23,7 +23,7 @@ </tagNode> <node name="vti"> <properties> - <help>Show vti interface information</help> + <help>Show VTI interface information</help> </properties> <command>${vyos_op_scripts_dir}/show_interfaces.py --intf-type=vti --action=show-brief</command> <children> diff --git a/op-mode-definitions/show-interfaces-vxlan.xml.in b/op-mode-definitions/show-interfaces-vxlan.xml.in index 4e3cb93cd..1befd428c 100644 --- a/op-mode-definitions/show-interfaces-vxlan.xml.in +++ b/op-mode-definitions/show-interfaces-vxlan.xml.in @@ -6,7 +6,7 @@ <children> <tagNode name="vxlan"> <properties> - <help>Show VXLAN interface information</help> + <help>Show specified VXLAN interface information</help> <completionHelp> <path>interfaces vxlan</path> </completionHelp> diff --git a/op-mode-definitions/show-interfaces-wireguard.xml.in b/op-mode-definitions/show-interfaces-wireguard.xml.in new file mode 100644 index 000000000..c9b754dcd --- /dev/null +++ b/op-mode-definitions/show-interfaces-wireguard.xml.in @@ -0,0 +1,66 @@ +<?xml version="1.0"?> +<interfaceDefinition> + <node name="show"> + <children> + <node name="interfaces"> + <children> + <tagNode name="wireguard"> + <properties> + <help>Show specified WireGuard interface information</help> + <completionHelp> + <script>${vyos_completion_dir}/list_interfaces.py --type wireguard</script> + </completionHelp> + </properties> + <command>${vyos_op_scripts_dir}/show_interfaces.py --intf="$4"</command> + <children> + <leafNode name="allowed-ips"> + <properties> + <help>Show all IP addresses allowed for the specified interface</help> + </properties> + <command>sudo wg show "$4" allowed-ips</command> + </leafNode> + <leafNode name="endpoints"> + <properties> + <help>Show all endpoints for the specified interface</help> + </properties> + <command>sudo wg show "$4" endpoints</command> + </leafNode> + <leafNode name="peers"> + <properties> + <help>Show all peer IDs for the specified interface</help> + </properties> + <command>sudo wg show "$4" peers</command> + </leafNode> + <leafNode name="public-key"> + <properties> + <help>Show interface public-key</help> + </properties> + <command>sudo wg show "$4" public-key</command> + </leafNode> + <leafNode name="summary"> + <properties> + <help>Shows current configuration and device information</help> + </properties> + <command>sudo wg show "$4"</command> + </leafNode> + </children> + </tagNode> + <node name="wireguard"> + <properties> + <help>Show WireGuard interface information</help> + </properties> + <command>${vyos_op_scripts_dir}/show_interfaces.py --intf-type=wireguard --action=show-brief</command> + <children> + <leafNode name="detail"> + <properties> + <help>Show detailed Wireguard interface information</help> + </properties> + <command>${vyos_op_scripts_dir}/show_interfaces.py --intf-type=wireguard --action=show</command> + </leafNode> + </children> + </node> + </children> + </node> + </children> + </node> +</interfaceDefinition> diff --git a/op-mode-definitions/show-interfaces-wireless.xml.in b/op-mode-definitions/show-interfaces-wireless.xml.in new file mode 100644 index 000000000..4a37417aa --- /dev/null +++ b/op-mode-definitions/show-interfaces-wireless.xml.in @@ -0,0 +1,82 @@ +<?xml version="1.0"?> +<interfaceDefinition> + <node name="show"> + <children> + <node name="interfaces"> + <children> + <node name="wireless"> + <properties> + <help>Show Wireless (WLAN) interface information</help> + </properties> + <command>${vyos_op_scripts_dir}/show_interfaces.py --intf-type=wireless --action=show-brief</command> + <children> + <leafNode name="detail"> + <properties> + <help>Show detailed wireless interface information</help> + </properties> + <command>${vyos_op_scripts_dir}/show_interfaces.py --intf-type=wireless --action=show</command> + </leafNode> + <leafNode name="info"> + <properties> + <help>Show wireless interface configuration</help> + </properties> + <command>${vyos_op_scripts_dir}/show_wireless.py --brief</command> + </leafNode> + </children> + </node> + <tagNode name="wireless"> + <properties> + <help>Show specified wireless interface information</help> + <completionHelp> + <script>${vyos_completion_dir}/list_interfaces.py --type wireless</script> + </completionHelp> + </properties> + <command>${vyos_op_scripts_dir}/show_interfaces.py --intf="$4"</command> + <children> + <leafNode name="brief"> + <properties> + <help>Show summary of the specified wireless interface information</help> + </properties> + <command>${vyos_op_scripts_dir}/show_interfaces.py --intf="$4" --action=show-brief</command> + </leafNode> + <node name="scan"> + <properties> + <help>Show summary of the specified wireless interface information</help> + </properties> + <command>sudo ${vyos_op_scripts_dir}/show_wireless.py --scan "$4"</command> + <children> + <leafNode name="detail"> + <properties> + <help>Show detailed scan results</help> + </properties> + <command>sudo /sbin/iw dev "$4" scan ap-force</command> + </leafNode> + </children> + </node> + <leafNode name="stations"> + <properties> + <help>Show specified Wireless interface information</help> + </properties> + <command>${vyos_op_scripts_dir}/show_wireless.py --stations "$4"</command> + </leafNode> + <tagNode name="vif"> + <properties> + <help>Show specified virtual network interface (vif) information</help> + </properties> + <command>${vyos_op_scripts_dir}/show_interfaces.py --intf="$4.$6"</command> + <children> + <leafNode name="brief"> + <properties> + <help>Show summary of specified virtual network interface (vif) information</help> + </properties> + <command>${vyos_op_scripts_dir}/show_interfaces.py --intf="$4.$6" --action=show-brief</command> + </leafNode> + </children> + </tagNode> + </children> + </tagNode> + </children> + </node> + </children> + </node> +</interfaceDefinition> diff --git a/op-mode-definitions/show-interfaces-wwan.xml.in b/op-mode-definitions/show-interfaces-wwan.xml.in index d57e17a13..3cd29b38a 100644 --- a/op-mode-definitions/show-interfaces-wwan.xml.in +++ b/op-mode-definitions/show-interfaces-wwan.xml.in @@ -6,7 +6,7 @@ <children> <tagNode name="wwan"> <properties> - <help>Show Wireless Wire Area Network (WWAN) interface information</help> + <help>Show specified Wireless Wire Area Network (WWAN) interface information</help> <completionHelp> <path>interfaces wwan</path> <script>cd /sys/class/net; ls -d wwan*</script> @@ -68,9 +68,9 @@ </properties> <command>sudo ${vyos_op_scripts_dir}/show_wwan.py --interface=$4 --sim</command> </leafNode> - <leafNode name="summary"> + <leafNode name="detail"> <properties> - <help>Show WWAN module information summary</help> + <help>Show WWAN module detailed information summary</help> </properties> <command>mmcli --modem ${4#wwan}</command> </leafNode> diff --git a/op-mode-definitions/show-system.xml.in b/op-mode-definitions/show-system.xml.in index 5e9bf719e..18a28868d 100644 --- a/op-mode-definitions/show-system.xml.in +++ b/op-mode-definitions/show-system.xml.in @@ -55,12 +55,6 @@ </properties> <command>${vyos_op_scripts_dir}/show_cpu.py</command> </leafNode> - <leafNode name= "integrity"> - <properties> - <help>Checks overall system integrity</help> - </properties> - <command>sudo ${vyos_op_scripts_dir}/show_system_integrity.py</command> - </leafNode> <leafNode name="kernel-messages"> <properties> <help>Show messages in kernel ring buffer</help> diff --git a/op-mode-definitions/terminal.xml.in b/op-mode-definitions/terminal.xml.in index 9c4e629cb..2a76de146 100644 --- a/op-mode-definitions/terminal.xml.in +++ b/op-mode-definitions/terminal.xml.in @@ -40,7 +40,6 @@ </properties> <command>builtin $3</command> </tagNode> - <node name="console"> <properties> <help>Control console behaviors</help> @@ -54,13 +53,11 @@ </leafNode> </children> </node> - <node name="terminal"> <properties> <help>Control terminal behaviors</help> </properties> <children> - <node name="key"> <properties> <help>Set key behaviors</help> @@ -77,7 +74,6 @@ </tagNode> </children> </node> - <node name="pager"> <properties> <help>Set terminal pager to default (less)</help> @@ -93,7 +89,6 @@ </properties> <command>VYATTA_PAGER=$4</command> </tagNode> - <tagNode name="length"> <properties> <help>Set terminal to given number of rows (0 disables paging)</help> @@ -103,7 +98,6 @@ </properties> <command>if [ "$4" -eq 0 ]; then VYATTA_PAGER=cat; else VYATTA_PAGER=${_vyatta_default_pager}; stty rows $4; fi</command> </tagNode> - <tagNode name="width"> <properties> <help>Set terminal to given number of columns</help> @@ -117,6 +111,4 @@ </node> </children> </node> - - </interfaceDefinition> diff --git a/op-mode-definitions/wireguard.xml.in b/op-mode-definitions/wireguard.xml.in index 22b08002d..e2bc8a590 100644 --- a/op-mode-definitions/wireguard.xml.in +++ b/op-mode-definitions/wireguard.xml.in @@ -116,59 +116,6 @@ </node> </children> </node> - <node name="interfaces"> - <children> - <tagNode name="wireguard"> - <properties> - <help>show wireguard interface information</help> - <completionHelp> - <script>${vyos_completion_dir}/list_interfaces.py --type wireguard</script> - </completionHelp> - </properties> - <command>sudo ${vyos_op_scripts_dir}/wireguard.py --showinterface "$4"</command> - <children> - <leafNode name="allowed-ips"> - <properties> - <help>show all allowed-ips for the specified interface</help> - </properties> - <command>sudo wg show "$4" allowed-ips</command> - </leafNode> - <leafNode name="endpoints"> - <properties> - <help>show all endpoints for the specified interface</help> - </properties> - <command>sudo wg show "$4" endpoints</command> - </leafNode> - <leafNode name="peers"> - <properties> - <help>show all peer IDs for the specified interface</help> - </properties> - <command>sudo wg show "$4" peers</command> - </leafNode> - <leafNode name="summary"> - <properties> - <help>Shows current configuration and device information</help> - </properties> - <command>sudo wg show "$4"</command> - </leafNode> - </children> - </tagNode> - <node name="wireguard"> - <properties> - <help>Show wireguard interface information</help> - </properties> - <command>${vyos_op_scripts_dir}/show_interfaces.py --intf-type=wireguard --action=show-brief</command> - <children> - <leafNode name="detail"> - <properties> - <help>Show detailed wireguard interface information</help> - </properties> - <command>${vyos_op_scripts_dir}/show_interfaces.py --intf-type=wireguard --action=show</command> - </leafNode> - </children> - </node> - </children> - </node> </children> </node> <node name="delete"> diff --git a/op-mode-definitions/wireless.xml.in b/op-mode-definitions/wireless.xml.in index a3a9d1f55..5d9db1544 100644 --- a/op-mode-definitions/wireless.xml.in +++ b/op-mode-definitions/wireless.xml.in @@ -37,83 +37,4 @@ </node> </children> </node> - <node name="show"> - <children> - <node name="interfaces"> - <children> - <node name="wireless"> - <properties> - <help>Show wireless interface information</help> - </properties> - <command>${vyos_op_scripts_dir}/show_interfaces.py --intf-type=wireless --action=show-brief</command> - <children> - <leafNode name="detail"> - <properties> - <help>Show detailed wireless interface information</help> - </properties> - <command>${vyos_op_scripts_dir}/show_interfaces.py --intf-type=wireless --action=show</command> - </leafNode> - <leafNode name="info"> - <properties> - <help>Show wireless interface configuration</help> - </properties> - <command>${vyos_op_scripts_dir}/show_wireless.py --brief</command> - </leafNode> - </children> - </node> - <tagNode name="wireless"> - <properties> - <help>Show specified wireless interface information</help> - <completionHelp> - <script>${vyos_completion_dir}/list_interfaces.py --type wireless</script> - </completionHelp> - </properties> - <command>${vyos_op_scripts_dir}/show_interfaces.py --intf="$4"</command> - <children> - <leafNode name="brief"> - <properties> - <help>Show summary of the specified wireless interface information</help> - </properties> - <command>${vyos_op_scripts_dir}/show_interfaces.py --intf="$4" --action=show-brief</command> - </leafNode> - <node name="scan"> - <properties> - <help>Show summary of the specified wireless interface information</help> - </properties> - <command>sudo ${vyos_op_scripts_dir}/show_wireless.py --scan "$4"</command> - <children> - <leafNode name="detail"> - <properties> - <help>Show detailed scan results</help> - </properties> - <command>sudo /sbin/iw dev "$4" scan ap-force</command> - </leafNode> - </children> - </node> - <leafNode name="stations"> - <properties> - <help>Show specified wireless interface information</help> - </properties> - <command>${vyos_op_scripts_dir}/show_wireless.py --stations "$4"</command> - </leafNode> - <tagNode name="vif"> - <properties> - <help>Show specified virtual network interface (vif) information</help> - </properties> - <command>${vyos_op_scripts_dir}/show_interfaces.py --intf="$4.$6"</command> - <children> - <leafNode name="brief"> - <properties> - <help>Show summary of specified virtual network interface (vif) information</help> - </properties> - <command>${vyos_op_scripts_dir}/show_interfaces.py --intf="$4.$6" --action=show-brief</command> - </leafNode> - </children> - </tagNode> - </children> - </tagNode> - </children> - </node> - </children> - </node> </interfaceDefinition> diff --git a/python/vyos/configdict.py b/python/vyos/configdict.py index dba992d56..f9c87708a 100644 --- a/python/vyos/configdict.py +++ b/python/vyos/configdict.py @@ -108,16 +108,20 @@ def leaf_node_changed(conf, path): """ Check if a leaf node was altered. If it has been altered - values has been changed, or it was added/removed, we will return a list containing the old - value(s). If nothing has been changed, None is returned + value(s). If nothing has been changed, None is returned. + + NOTE: path must use the real CLI node name (e.g. with a hyphen!) """ from vyos.configdiff import get_config_diff D = get_config_diff(conf, key_mangling=('-', '_')) D.set_level(conf.get_level()) (new, old) = D.get_value_diff(path) if new != old: + if old is None: + return [''] if isinstance(old, str): return [old] - elif isinstance(old, list): + if isinstance(old, list): if isinstance(new, str): new = [new] elif isinstance(new, type(None)): @@ -343,8 +347,8 @@ def get_interface_dict(config, base, ifname=''): # setup config level which is extracted in get_removed_vlans() config.set_level(base + [ifname]) - dict = config.get_config_dict([], key_mangling=('-', '_'), - get_first_key=True) + dict = config.get_config_dict([], key_mangling=('-', '_'), get_first_key=True, + no_tag_node_value_mangle=True) # Check if interface has been removed. We must use exists() as # get_config_dict() will always return {} - even when an empty interface diff --git a/python/vyos/configsource.py b/python/vyos/configsource.py index 50222e385..b0981d25e 100644 --- a/python/vyos/configsource.py +++ b/python/vyos/configsource.py @@ -161,7 +161,7 @@ class ConfigSourceSession(ConfigSource): if p.returncode != 0: raise VyOSError() else: - return out.decode('ascii') + return out.decode('ascii', 'ignore') def set_level(self, path): """ diff --git a/python/vyos/configverify.py b/python/vyos/configverify.py index 0b6e6fc13..ce7e76eb4 100644 --- a/python/vyos/configverify.py +++ b/python/vyos/configverify.py @@ -67,22 +67,22 @@ def verify_mtu_ipv6(config): min_mtu = 1280 if int(config['mtu']) < min_mtu: interface = config['ifname'] - error_msg = f'IPv6 address will be configured on interface "{interface}" ' \ - f'thus the minimum MTU requirement is {min_mtu}!' + error_msg = f'IPv6 address will be configured on interface "{interface}",\n' \ + f'the required minimum MTU is {min_mtu}!' - for address in (dict_search('address', config) or []): - if address in ['dhcpv6'] or is_ipv6(address): - raise ConfigError(error_msg) + if 'address' in config: + for address in config['address']: + if address in ['dhcpv6'] or is_ipv6(address): + raise ConfigError(error_msg) - tmp = dict_search('ipv6.address', config) - if tmp and 'no_default_link_local' not in tmp: - raise ConfigError('link-local ' + error_msg) + tmp = dict_search('ipv6.address.no_default_link_local', config) + if tmp == None: raise ConfigError('link-local ' + error_msg) - if tmp and 'autoconf' in tmp: - raise ConfigError(error_msg) + tmp = dict_search('ipv6.address.autoconf', config) + if tmp != None: raise ConfigError(error_msg) - if tmp and 'eui64' in tmp: - raise ConfigError(error_msg) + tmp = dict_search('ipv6.address.eui64', config) + if tmp != None: raise ConfigError(error_msg) def verify_tunnel(config): """ @@ -208,8 +208,8 @@ def verify_interface_exists(ifname): Common helper function used by interface implementations to perform recurring validation if an interface actually exists. """ - from netifaces import interfaces - if ifname not in interfaces(): + import os + if not os.path.exists(f'/sys/class/net/{ifname}'): raise ConfigError(f'Interface "{ifname}" does not exist!') def verify_source_interface(config): @@ -385,3 +385,29 @@ def verify_diffie_hellman_length(file, min_keysize): return False +def verify_common_route_maps(config): + """ + Common helper function used by routing protocol implementations to perform + recurring validation if the specified route-map for either zebra to kernel + installation exists (this is the top-level route_map key) or when a route + is redistributed with a route-map that it exists! + """ + # XXX: This function is called in combination with a previous call to: + # tmp = conf.get_config_dict(['policy']) - see protocols_ospf.py as example. + # We should NOT call this with the key_mangling option as this would rename + # route-map hypens '-' to underscores '_' and one could no longer distinguish + # what should have been the "proper" route-map name, as foo-bar and foo_bar + # are two entire different route-map instances! + for route_map in ['route-map', 'route_map']: + if route_map not in config: + continue + tmp = config[route_map] + # Check if the specified route-map exists, if not error out + if dict_search(f'policy.route-map.{tmp}', config) == None: + raise ConfigError(f'Specified route-map "{tmp}" does not exist!') + + if 'redistribute' in config: + for protocol, protocol_config in config['redistribute'].items(): + if 'route_map' in protocol_config: + verify_route_map(protocol_config['route_map'], config) + diff --git a/python/vyos/defaults.py b/python/vyos/defaults.py index 9921e3b5f..ca5e02834 100644 --- a/python/vyos/defaults.py +++ b/python/vyos/defaults.py @@ -13,6 +13,7 @@ # 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/>. +import os directories = { "data": "/usr/share/vyos/", @@ -31,7 +32,7 @@ cfg_vintage = 'vyos' commit_lock = '/opt/vyatta/config/.lock' -version_file = '/usr/share/vyos/component-versions.json' +component_version_json = os.path.join(directories['data'], 'component-versions.json') https_data = { 'listen_addresses' : { '*': ['_'] } diff --git a/python/vyos/ethtool.py b/python/vyos/ethtool.py index bc103959a..bc95767b1 100644 --- a/python/vyos/ethtool.py +++ b/python/vyos/ethtool.py @@ -13,44 +13,96 @@ # 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/>. +import os +import re + from vyos.util import popen class Ethtool: """ Class is used to retrive and cache information about an ethernet adapter """ - # dictionary containing driver featurs, it will be populated on demand and # the content will look like: # { - # 'tls-hw-tx-offload': {'fixed': True, 'on': False}, - # 'tx-checksum-fcoe-crc': {'fixed': True, 'on': False}, - # 'tx-checksum-ip-generic': {'fixed': False, 'on': True}, - # 'tx-checksum-ipv4': {'fixed': True, 'on': False}, - # 'tx-checksum-ipv6': {'fixed': True, 'on': False}, - # 'tx-checksum-sctp': {'fixed': True, 'on': False}, - # 'tx-checksumming': {'fixed': False, 'on': True}, - # 'tx-esp-segmentation': {'fixed': True, 'on': False}, + # 'tls-hw-tx-offload': {'fixed': True, 'enabled': False}, + # 'tx-checksum-fcoe-crc': {'fixed': True, 'enabled': False}, + # 'tx-checksum-ip-generic': {'fixed': False, 'enabled': True}, + # 'tx-checksum-ipv4': {'fixed': True, 'enabled': False}, + # 'tx-checksum-ipv6': {'fixed': True, 'enabled': False}, + # 'tx-checksum-sctp': {'fixed': True, 'enabled': False}, + # 'tx-checksumming': {'fixed': False, 'enabled': True}, + # 'tx-esp-segmentation': {'fixed': True, 'enabled': False}, # } - features = { } - ring_buffers = { } + _features = { } + # dictionary containing available interface speed and duplex settings + # { + # '10' : {'full': '', 'half': ''}, + # '100' : {'full': '', 'half': ''}, + # '1000': {'full': ''} + # } + _speed_duplex = { } + _ring_buffers = { } + _ring_buffers_max = { } + _driver_name = None + _auto_negotiation = None + _flow_control = False + _flow_control_enabled = None def __init__(self, ifname): + # Get driver used for interface + sysfs_file = f'/sys/class/net/{ifname}/device/driver/module' + if os.path.exists(sysfs_file): + link = os.readlink(sysfs_file) + self._driver_name = os.path.basename(link) + + if not self._driver_name: + raise ValueError(f'Could not determine driver for interface {ifname}!') + + # Build a dictinary of supported link-speed and dupley settings. + out, err = popen(f'ethtool {ifname}') + reading = False + pattern = re.compile(r'\d+base.*') + for line in out.splitlines()[1:]: + line = line.lstrip() + if 'Supported link modes:' in line: + reading = True + if 'Supported pause frame use:' in line: + reading = False + if reading: + for block in line.split(): + if pattern.search(block): + speed = block.split('base')[0] + duplex = block.split('/')[-1].lower() + if speed not in self._speed_duplex: + self._speed_duplex.update({ speed : {}}) + if duplex not in self._speed_duplex[speed]: + self._speed_duplex[speed].update({ duplex : ''}) + if 'Auto-negotiation:' in line: + # Split the following string: Auto-negotiation: off + # we are only interested in off or on + tmp = line.split()[-1] + self._auto_negotiation = bool(tmp == 'on') + + if self._auto_negotiation == None: + raise ValueError(f'Could not determine auto-negotiation settings '\ + f'for interface {ifname}!') + # Now populate features dictionaty - out, err = popen(f'ethtool -k {ifname}') + out, err = popen(f'ethtool --show-features {ifname}') # skip the first line, it only says: "Features for eth0": for line in out.splitlines()[1:]: if ":" in line: key, value = [s.strip() for s in line.strip().split(":", 1)] - fixed = "fixed" in value + fixed = bool('fixed' in value) if fixed: value = value.split()[0].strip() - self.features[key.strip()] = { - "on": value == "on", - "fixed": fixed + self._features[key.strip()] = { + 'enabled' : bool(value == 'on'), + 'fixed' : fixed } - out, err = popen(f'ethtool -g {ifname}') + out, err = popen(f'ethtool --show-ring {ifname}') # We are only interested in line 2-5 which contains the device maximum # ringbuffers for line in out.splitlines()[2:6]: @@ -61,45 +113,104 @@ class Ethtool: # output format from 0 -> n/a. As we are only interested in the # tx/rx keys we do not care about RX Mini/Jumbo. if value.isdigit(): - self.ring_buffers[key] = int(value) + self._ring_buffers_max[key] = value + # Now we wan't to get the current RX/TX ringbuffer values - used for + for line in out.splitlines()[7:11]: + if ':' in line: + key, value = [s.strip() for s in line.strip().split(":", 1)] + key = key.lower().replace(' ', '_') + # T3645: ethtool version used on Debian Bullseye changed the + # output format from 0 -> n/a. As we are only interested in the + # tx/rx keys we do not care about RX Mini/Jumbo. + if value.isdigit(): + self._ring_buffers[key] = value + + # Get current flow control settings, but this is not supported by + # all NICs (e.g. vmxnet3 does not support is) + out, err = popen(f'ethtool --show-pause {ifname}') + if len(out.splitlines()) > 1: + self._flow_control = True + # read current flow control setting, this returns: + # ['Autonegotiate:', 'on'] + self._flow_control_enabled = out.splitlines()[1].split()[-1] + + def get_auto_negotiation(self): + return self._auto_negotiation + + def get_driver_name(self): + return self._driver_name + def _get_generic(self, feature): + """ + Generic method to read self._features and return a tuple for feature + enabled and feature is fixed. - def is_fixed_lro(self): - # in case of a missing configuration, rather return "fixed". In Ethtool - # terminology "fixed" means the setting can not be changed by the user. - return self.features.get('large-receive-offload', True).get('fixed', True) + In case of a missing key, return "fixed = True and enabled = False" + """ + fixed = True + enabled = False + if feature in self._features: + if 'enabled' in self._features[feature]: + enabled = self._features[feature]['enabled'] + if 'fixed' in self._features[feature]: + fixed = self._features[feature]['fixed'] + return enabled, fixed - def is_fixed_gro(self): - # in case of a missing configuration, rather return "fixed". In Ethtool - # terminology "fixed" means the setting can not be changed by the user. - return self.features.get('generic-receive-offload', True).get('fixed', True) + def get_generic_receive_offload(self): + return self._get_generic('generic-receive-offload') - def is_fixed_gso(self): - # in case of a missing configuration, rather return "fixed". In Ethtool - # terminology "fixed" means the setting can not be changed by the user. - return self.features.get('generic-segmentation-offload', True).get('fixed', True) + def get_generic_segmentation_offload(self): + return self._get_generic('generic-segmentation-offload') - def is_fixed_sg(self): - # in case of a missing configuration, rather return "fixed". In Ethtool - # terminology "fixed" means the setting can not be changed by the user. - return self.features.get('scatter-gather', True).get('fixed', True) + def get_large_receive_offload(self): + return self._get_generic('large-receive-offload') - def is_fixed_tso(self): - # in case of a missing configuration, rather return "fixed". In Ethtool - # terminology "fixed" means the setting can not be changed by the user. - return self.features.get('tcp-segmentation-offload', True).get('fixed', True) + def get_scatter_gather(self): + return self._get_generic('scatter-gather') - def is_fixed_ufo(self): - # in case of a missing configuration, rather return "fixed". In Ethtool - # terminology "fixed" means the setting can not be changed by the user. - return self.features.get('udp-fragmentation-offload', True).get('fixed', True) + def get_tcp_segmentation_offload(self): + return self._get_generic('tcp-segmentation-offload') - def get_rx_buffer(self): - # Configuration of RX ring-buffers is not supported on every device, + def get_ring_buffer_max(self, rx_tx): + # Configuration of RX/TX ring-buffers is not supported on every device, # thus when it's impossible return None - return self.ring_buffers.get('rx', None) + if rx_tx not in ['rx', 'tx']: + ValueError('Ring-buffer type must be either "rx" or "tx"') + return self._ring_buffers_max.get(rx_tx, None) - def get_tx_buffer(self): - # Configuration of TX ring-buffers is not supported on every device, + def get_ring_buffer(self, rx_tx): + # Configuration of RX/TX ring-buffers is not supported on every device, # thus when it's impossible return None - return self.ring_buffers.get('tx', None) + if rx_tx not in ['rx', 'tx']: + ValueError('Ring-buffer type must be either "rx" or "tx"') + return str(self._ring_buffers.get(rx_tx, None)) + + def check_speed_duplex(self, speed, duplex): + """ Check if the passed speed and duplex combination is supported by + the underlaying network adapter. """ + if isinstance(speed, int): + speed = str(speed) + if speed != 'auto' and not speed.isdigit(): + raise ValueError(f'Value "{speed}" for speed is invalid!') + if duplex not in ['auto', 'full', 'half']: + raise ValueError(f'Value "{duplex}" for duplex is invalid!') + + if self.get_driver_name() in ['vmxnet3', 'virtio_net', 'xen_netfront']: + return False + + if speed in self._speed_duplex: + if duplex in self._speed_duplex[speed]: + return True + return False + + def check_flow_control(self): + """ Check if the NIC supports flow-control """ + if self.get_driver_name() in ['vmxnet3', 'virtio_net', 'xen_netfront']: + return False + return self._flow_control + + def get_flow_control(self): + if self._flow_control_enabled == None: + raise ValueError('Interface does not support changing '\ + 'flow-control settings!') + return self._flow_control_enabled diff --git a/python/vyos/frr.py b/python/vyos/frr.py index 3bab64301..df6849472 100644 --- a/python/vyos/frr.py +++ b/python/vyos/frr.py @@ -68,15 +68,27 @@ Apply the new configuration: import tempfile import re from vyos import util +from vyos.util import chown +from vyos.util import cmd import logging +from logging.handlers import SysLogHandler +import os LOG = logging.getLogger(__name__) +DEBUG = os.path.exists('/tmp/vyos.frr.debug') +if DEBUG: + LOG.setLevel(logging.DEBUG) + ch = SysLogHandler(address='/dev/log') + ch2 = logging.StreamHandler() + LOG.addHandler(ch) + LOG.addHandler(ch2) _frr_daemons = ['zebra', 'bgpd', 'fabricd', 'isisd', 'ospf6d', 'ospfd', 'pbrd', 'pimd', 'ripd', 'ripngd', 'sharpd', 'staticd', 'vrrpd', 'ldpd'] path_vtysh = '/usr/bin/vtysh' path_frr_reload = '/usr/lib/frr/frr-reload.py' +path_config = '/run/frr' class FrrError(Exception): @@ -175,21 +187,42 @@ def reload_configuration(config, daemon=None): f.write(config) f.flush() + LOG.debug(f'reload_configuration: Reloading config using temporary file: {f.name}') cmd = f'{path_frr_reload} --reload' if daemon: cmd += f' --daemon {daemon}' + + if DEBUG: + cmd += f' --debug --stdout' + cmd += f' {f.name}' + LOG.debug(f'reload_configuration: Executing command against frr-reload: "{cmd}"') output, code = util.popen(cmd, stderr=util.STDOUT) f.close() + for i, e in enumerate(output.split('\n')): + LOG.debug(f'frr-reload output: {i:3} {e}') if code == 1: - raise CommitError(f'Configuration FRR failed while commiting code: {repr(output)}') + raise CommitError('FRR configuration failed while running commit. Please ' \ + 'enable debugging to examine logs.\n\n\n' \ + 'To enable debugging run: "touch /tmp/vyos.frr.debug" ' \ + 'and "sudo systemctl stop vyos-configd"') elif code: raise OSError(code, output) return output +def save_configuration(): + """Save FRR configuration to /run/frr/config/frr.conf + It save configuration on each commit. T3217 + """ + + cmd(f'{path_vtysh} -n -w') + + return + + def execute(command): """ Run commands inside vtysh command: str containing commands to execute inside a vtysh session @@ -382,6 +415,11 @@ class FRRConfig: raise ValueError( 'The config element needs to be a string or list type object') + if config: + LOG.debug(f'__init__: frr library initiated with initial config') + for i, e in enumerate(self.config): + LOG.debug(f'__init__: initial {i:3} {e}') + def load_configuration(self, daemon=None): '''Load the running configuration from FRR into the config object daemon: str with name of the FRR Daemon to load configuration from or @@ -390,9 +428,16 @@ class FRRConfig: Using this overwrites the current loaded config objects and replaces the original loaded config ''' self.imported_config = get_configuration(daemon=daemon) - LOG.debug(f'load_configuration: Configuration loaded from FRR: {self.imported_config}') + if daemon: + LOG.debug(f'load_configuration: Configuration loaded from FRR daemon {daemon}') + else: + LOG.debug(f'load_configuration: Configuration loaded from FRR integrated config') + self.original_config = self.imported_config.split('\n') self.config = self.original_config.copy() + + for i, e in enumerate(self.imported_config.split('\n')): + LOG.debug(f'load_configuration: loaded {i:3} {e}') return def test_configuration(self): @@ -408,6 +453,8 @@ class FRRConfig: None to use the consolidated config ''' LOG.debug('commit_configuration: Commiting configuration') + for i, e in enumerate(self.config): + LOG.debug(f'commit_configuration: new_config {i:3} {e}') reload_configuration('\n'.join(self.config), daemon=daemon) def modify_section(self, start_pattern, replacement=[], stop_pattern=r'\S+', remove_stop_mark=False, count=0): @@ -459,7 +506,8 @@ class FRRConfig: start = _find_first_element(self.config, before_pattern) if start < 0: return False - + for i, e in enumerate(addition, start=start): + LOG.debug(f'add_before: add {i:3} {e}') self.config[start:start] = addition return True diff --git a/python/vyos/ifconfig/bridge.py b/python/vyos/ifconfig/bridge.py index 65a4506c5..27073b266 100644 --- a/python/vyos/ifconfig/bridge.py +++ b/python/vyos/ifconfig/bridge.py @@ -1,4 +1,4 @@ -# Copyright 2019 VyOS maintainers and contributors <maintainers@vyos.io> +# Copyright 2019-2021 VyOS maintainers and contributors <maintainers@vyos.io> # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -22,6 +22,7 @@ from vyos.validate import assert_positive from vyos.util import cmd from vyos.util import dict_search from vyos.configdict import get_vlan_ids +from vyos.configdict import list_diff @Interface.register class BridgeIf(Interface): @@ -33,7 +34,6 @@ class BridgeIf(Interface): The Linux bridge code implements a subset of the ANSI/IEEE 802.1d standard. """ - iftype = 'bridge' definition = { **Interface.definition, @@ -267,21 +267,37 @@ class BridgeIf(Interface): for member in (tmp or []): if member in interfaces(): self.del_port(member) - vlan_filter = 0 - vlan_del = set() - vlan_add = set() + # enable/disable Vlan Filter + vlan_filter = '1' if 'enable_vlan' in config else '0' + self.set_vlan_filter(vlan_filter) ifname = config['ifname'] + if int(vlan_filter): + add_vlan = [] + cur_vlan_ids = get_vlan_ids(ifname) + + tmp = dict_search('vif', config) + if tmp: + for vif, vif_config in tmp.items(): + add_vlan.append(vif) + + # Remove redundant VLANs from the system + for vlan in list_diff(cur_vlan_ids, add_vlan): + cmd = f'bridge vlan del dev {ifname} vid {vlan} self' + self._cmd(cmd) + + for vlan in add_vlan: + cmd = f'bridge vlan add dev {ifname} vid {vlan} self' + self._cmd(cmd) + + # VLAN of bridge parent interface is always 1 + # VLAN 1 is the default VLAN for all unlabeled packets + cmd = f'bridge vlan add dev {ifname} vid 1 pvid untagged self' + self._cmd(cmd) + tmp = dict_search('member.interface', config) if tmp: - if self.get_vlan_filter(): - bridge_vlan_ids = get_vlan_ids(ifname) - # Delete VLAN ID for the bridge - if 1 in bridge_vlan_ids: - bridge_vlan_ids.remove(1) - for vlan in bridge_vlan_ids: - vlan_del.add(str(vlan)) for interface, interface_config in tmp.items(): # if interface does yet not exist bail out early and @@ -296,9 +312,15 @@ class BridgeIf(Interface): # not have any addresses configured by CLI so just flush any # remaining ones lower.flush_addrs() + # enslave interface port to bridge self.add_port(interface) + # always set private-vlan/port isolation + tmp = dict_search('isolated', interface_config) + value = 'on' if (tmp != None) else 'off' + lower.set_port_isolation(value) + # set bridge port path cost if 'cost' in interface_config: value = interface_config.get('cost') @@ -309,62 +331,39 @@ class BridgeIf(Interface): value = interface_config.get('priority') lower.set_path_priority(value) - tmp = dict_search('native_vlan_removed', interface_config) - - for vlan_id in (tmp or []): - cmd = f'bridge vlan del dev {interface} vid {vlan_id}' - self._cmd(cmd) - cmd = f'bridge vlan add dev {interface} vid 1 pvid untagged master' - self._cmd(cmd) - vlan_del.add(vlan_id) - vlan_add.add(1) - - tmp = dict_search('allowed_vlan_removed', interface_config) - - for vlan_id in (tmp or []): - cmd = f'bridge vlan del dev {interface} vid {vlan_id}' - self._cmd(cmd) - vlan_del.add(vlan_id) - - if 'native_vlan' in interface_config: - vlan_filter = 1 - cmd = f'bridge vlan del dev {interface} vid 1' - self._cmd(cmd) - vlan_id = interface_config['native_vlan'] - if int(vlan_id) != 1: - if 1 in vlan_add: - vlan_add.remove(1) - vlan_del.add(1) - cmd = f'bridge vlan add dev {interface} vid {vlan_id} pvid untagged master' - self._cmd(cmd) - vlan_add.add(vlan_id) - if vlan_id in vlan_del: - vlan_del.remove(vlan_id) - - if 'allowed_vlan' in interface_config: - vlan_filter = 1 - if 'native_vlan' not in interface_config: - cmd = f'bridge vlan del dev {interface} vid 1' + if int(vlan_filter): + add_vlan = [] + native_vlan_id = None + allowed_vlan_ids= [] + cur_vlan_ids = get_vlan_ids(interface) + + if 'native_vlan' in interface_config: + vlan_id = interface_config['native_vlan'] + add_vlan.append(vlan_id) + native_vlan_id = vlan_id + + if 'allowed_vlan' in interface_config: + for vlan in interface_config['allowed_vlan']: + vlan_range = vlan.split('-') + if len(vlan_range) == 2: + for vlan_add in range(int(vlan_range[0]),int(vlan_range[1]) + 1): + add_vlan.append(str(vlan_add)) + allowed_vlan_ids.append(str(vlan_add)) + else: + add_vlan.append(vlan) + allowed_vlan_ids.append(vlan) + + # Remove redundant VLANs from the system + for vlan in list_diff(cur_vlan_ids, add_vlan): + cmd = f'bridge vlan del dev {interface} vid {vlan} master' self._cmd(cmd) - vlan_del.add(1) - for vlan in interface_config['allowed_vlan']: + + for vlan in allowed_vlan_ids: cmd = f'bridge vlan add dev {interface} vid {vlan} master' self._cmd(cmd) - vlan_add.add(vlan) - if vlan in vlan_del: - vlan_del.remove(vlan) - - for vlan in vlan_del: - cmd = f'bridge vlan del dev {ifname} vid {vlan} self' - self._cmd(cmd) - - for vlan in vlan_add: - cmd = f'bridge vlan add dev {ifname} vid {vlan} self' - self._cmd(cmd) - - # enable/disable Vlan Filter - self.set_vlan_filter(vlan_filter) - + # Setting native VLAN to system + if native_vlan_id: + cmd = f'bridge vlan add dev {interface} vid {native_vlan_id} pvid untagged master' + self._cmd(cmd) - # call base class first super().update(config) diff --git a/python/vyos/ifconfig/ethernet.py b/python/vyos/ifconfig/ethernet.py index df6b96fbf..d06b0a842 100644 --- a/python/vyos/ifconfig/ethernet.py +++ b/python/vyos/ifconfig/ethernet.py @@ -16,9 +16,11 @@ import os import re +from vyos.ethtool import Ethtool from vyos.ifconfig.interface import Interface from vyos.util import run from vyos.util import dict_search +from vyos.util import read_file from vyos.validate import assert_list @Interface.register @@ -42,39 +44,29 @@ class EthernetIf(Interface): @staticmethod def feature(ifname, option, value): - run(f'ethtool -K {ifname} {option} {value}','ifconfig') + run(f'ethtool --features {ifname} {option} {value}') return False _command_set = {**Interface._command_set, **{ 'gro': { 'validate': lambda v: assert_list(v, ['on', 'off']), 'possible': lambda i, v: EthernetIf.feature(i, 'gro', v), - # 'shellcmd': 'ethtool -K {ifname} gro {value}', }, 'gso': { 'validate': lambda v: assert_list(v, ['on', 'off']), 'possible': lambda i, v: EthernetIf.feature(i, 'gso', v), - # 'shellcmd': 'ethtool -K {ifname} gso {value}', }, 'lro': { 'validate': lambda v: assert_list(v, ['on', 'off']), 'possible': lambda i, v: EthernetIf.feature(i, 'lro', v), - # 'shellcmd': 'ethtool -K {ifname} lro {value}', }, 'sg': { 'validate': lambda v: assert_list(v, ['on', 'off']), 'possible': lambda i, v: EthernetIf.feature(i, 'sg', v), - # 'shellcmd': 'ethtool -K {ifname} sg {value}', }, 'tso': { 'validate': lambda v: assert_list(v, ['on', 'off']), 'possible': lambda i, v: EthernetIf.feature(i, 'tso', v), - # 'shellcmd': 'ethtool -K {ifname} tso {value}', - }, - 'ufo': { - 'validate': lambda v: assert_list(v, ['on', 'off']), - 'possible': lambda i, v: EthernetIf.feature(i, 'ufo', v), - # 'shellcmd': 'ethtool -K {ifname} ufo {value}', }, }} @@ -85,24 +77,9 @@ class EthernetIf(Interface): }, }} - def get_driver_name(self): - """ - Return the driver name used by NIC. Some NICs don't support all - features e.g. changing link-speed, duplex - - Example: - >>> from vyos.ifconfig import EthernetIf - >>> i = EthernetIf('eth0') - >>> i.get_driver_name() - 'vmxnet3' - """ - ifname = self.config['ifname'] - sysfs_file = f'/sys/class/net/{ifname}/device/driver/module' - if os.path.exists(sysfs_file): - link = os.readlink(sysfs_file) - return os.path.basename(link) - else: - return None + def __init__(self, ifname, **kargs): + super().__init__(ifname, **kargs) + self.ethtool = Ethtool(ifname) def set_flow_control(self, enable): """ @@ -120,44 +97,20 @@ class EthernetIf(Interface): if enable not in ['on', 'off']: raise ValueError("Value out of range") - driver_name = self.get_driver_name() - if driver_name in ['vmxnet3', 'virtio_net', 'xen_netfront']: - self._debug_msg(f'{driver_name} driver does not support changing '\ - 'flow control settings!') - return - - # Get current flow control settings: - cmd = f'ethtool --show-pause {ifname}' - output, code = self._popen(cmd) - if code == 76: - # the interface does not support it - return '' - if code: - # never fail here as it prevent vyos to boot - print(f'unexpected return code {code} from {cmd}') - return '' - - # The above command returns - with tabs: - # - # Pause parameters for eth0: - # Autonegotiate: on - # RX: off - # TX: off - if re.search("Autonegotiate:\ton", output): - if enable == "on": - # flowcontrol is already enabled - no need to re-enable it again - # this will prevent the interface from flapping as applying the - # flow-control settings will take the interface down and bring - # it back up every time. - return '' - - # Assemble command executed on system. Unfortunately there is no way - # to change this setting via sysfs - cmd = f'ethtool --pause {ifname} autoneg {enable} tx {enable} rx {enable}' - output, code = self._popen(cmd) - if code: - print(f'could not set flowcontrol for {ifname}') - return output + if not self.ethtool.check_flow_control(): + self._debug_msg(f'NIC driver does not support changing flow control settings!') + return False + + current = self.ethtool.get_flow_control() + if current != enable: + # Assemble command executed on system. Unfortunately there is no way + # to change this setting via sysfs + cmd = f'ethtool --pause {ifname} autoneg {enable} tx {enable} rx {enable}' + output, code = self._popen(cmd) + if code: + print(f'Could not set flowcontrol for {ifname}') + return output + return None def set_speed_duplex(self, speed, duplex): """ @@ -179,40 +132,28 @@ class EthernetIf(Interface): if duplex not in ['auto', 'full', 'half']: raise ValueError("Value out of range (duplex)") - driver_name = self.get_driver_name() - if driver_name in ['vmxnet3', 'virtio_net', 'xen_netfront']: - self._debug_msg(f'{driver_name} driver does not support changing '\ - 'speed/duplex settings!') + if not self.ethtool.check_speed_duplex(speed, duplex): + self._debug_msg(f'NIC driver does not support changing speed/duplex settings!') return # Get current speed and duplex settings: ifname = self.config['ifname'] - cmd = f'ethtool {ifname}' - tmp = self._cmd(cmd) - - if re.search("\tAuto-negotiation: on", tmp): + if self.ethtool.get_auto_negotiation(): if speed == 'auto' and duplex == 'auto': # bail out early as nothing is to change return else: - # read in current speed and duplex settings - cur_speed = 0 - cur_duplex = '' - for line in tmp.splitlines(): - if line.lstrip().startswith("Speed:"): - non_decimal = re.compile(r'[^\d.]+') - cur_speed = non_decimal.sub('', line) - continue - - if line.lstrip().startswith("Duplex:"): - cur_duplex = line.split()[-1].lower() - break - + # XXX: read in current speed and duplex settings + # There are some "nice" NICs like AX88179 which do not support + # reading the speed thus we simply fallback to the supplied speed + # to not cause any change here and raise an exception. + cur_speed = read_file(f'/sys/class/net/{ifname}/speed', speed) + cur_duplex = read_file(f'/sys/class/net/{ifname}/duplex', duplex) if (cur_speed == speed) and (cur_duplex == duplex): # bail out early as nothing is to change return - cmd = f'ethtool -s {ifname}' + cmd = f'ethtool --change {ifname}' if speed == 'auto' or duplex == 'auto': cmd += ' autoneg on' else: @@ -229,8 +170,15 @@ class EthernetIf(Interface): >>> i.set_gro(True) """ if not isinstance(state, bool): - raise ValueError("Value out of range") - return self.set_interface('gro', 'on' if state else 'off') + raise ValueError('Value out of range') + + enabled, fixed = self.ethtool.get_generic_receive_offload() + if enabled != state: + if not fixed: + return self.set_interface('gro', 'on' if state else 'off') + else: + print('Adapter does not support changing generic-receive-offload settings!') + return False def set_gso(self, state): """ @@ -241,8 +189,15 @@ class EthernetIf(Interface): >>> i.set_gso(True) """ if not isinstance(state, bool): - raise ValueError("Value out of range") - return self.set_interface('gso', 'on' if state else 'off') + raise ValueError('Value out of range') + + enabled, fixed = self.ethtool.get_generic_segmentation_offload() + if enabled != state: + if not fixed: + return self.set_interface('gso', 'on' if state else 'off') + else: + print('Adapter does not support changing generic-segmentation-offload settings!') + return False def set_lro(self, state): """ @@ -253,12 +208,19 @@ class EthernetIf(Interface): >>> i.set_lro(True) """ if not isinstance(state, bool): - raise ValueError("Value out of range") - return self.set_interface('lro', 'on' if state else 'off') + raise ValueError('Value out of range') + + enabled, fixed = self.ethtool.get_large_receive_offload() + if enabled != state: + if not fixed: + return self.set_interface('gro', 'on' if state else 'off') + else: + print('Adapter does not support changing large-receive-offload settings!') + return False def set_rps(self, state): if not isinstance(state, bool): - raise ValueError("Value out of range") + raise ValueError('Value out of range') rps_cpus = '0' if state: @@ -283,8 +245,15 @@ class EthernetIf(Interface): >>> i.set_sg(True) """ if not isinstance(state, bool): - raise ValueError("Value out of range") - return self.set_interface('sg', 'on' if state else 'off') + raise ValueError('Value out of range') + + enabled, fixed = self.ethtool.get_scatter_gather() + if enabled != state: + if not fixed: + return self.set_interface('gro', 'on' if state else 'off') + else: + print('Adapter does not support changing scatter-gather settings!') + return False def set_tso(self, state): """ @@ -296,40 +265,38 @@ class EthernetIf(Interface): >>> i.set_tso(False) """ if not isinstance(state, bool): - raise ValueError("Value out of range") - return self.set_interface('tso', 'on' if state else 'off') - - def set_ufo(self, state): - """ - Enable UDP fragmentation offloading. State can be either True or False. - - Example: - >>> from vyos.ifconfig import EthernetIf - >>> i = EthernetIf('eth0') - >>> i.set_udp_offload(True) - """ - if not isinstance(state, bool): - raise ValueError("Value out of range") - return self.set_interface('ufo', 'on' if state else 'off') + raise ValueError('Value out of range') + + enabled, fixed = self.ethtool.get_tcp_segmentation_offload() + if enabled != state: + if not fixed: + return self.set_interface('gro', 'on' if state else 'off') + else: + print('Adapter does not support changing tcp-segmentation-offload settings!') + return False - def set_ring_buffer(self, b_type, b_size): + def set_ring_buffer(self, rx_tx, size): """ Example: >>> from vyos.ifconfig import EthernetIf >>> i = EthernetIf('eth0') >>> i.set_ring_buffer('rx', '4096') """ + current_size = self.ethtool.get_ring_buffer(rx_tx) + if current_size == size: + # bail out early if nothing is about to change + return None + ifname = self.config['ifname'] - cmd = f'ethtool -G {ifname} {b_type} {b_size}' + cmd = f'ethtool --set-ring {ifname} {rx_tx} {size}' output, code = self._popen(cmd) # ethtool error codes: # 80 - value already setted # 81 - does not possible to set value if code and code != 80: - print(f'could not set "{b_type}" ring-buffer for {ifname}') + print(f'could not set "{rx_tx}" ring-buffer for {ifname}') return output - def update(self, config): """ General helper function which works on a dictionary retrived by get_config_dict(). It's main intention is to consolidate the scattered @@ -358,9 +325,6 @@ class EthernetIf(Interface): # TSO (TCP segmentation offloading) self.set_tso(dict_search('offload.tso', config) != None) - # UDP fragmentation offloading - self.set_ufo(dict_search('offload.ufo', config) != None) - # Set physical interface speed and duplex if {'speed', 'duplex'} <= set(config): speed = config.get('speed') @@ -369,8 +333,8 @@ class EthernetIf(Interface): # Set interface ring buffer if 'ring_buffer' in config: - for b_type in config['ring_buffer']: - self.set_ring_buffer(b_type, config['ring_buffer'][b_type]) + for rx_tx, size in config['ring_buffer'].items(): + self.set_ring_buffer(rx_tx, size) # call base class first super().update(config) diff --git a/python/vyos/ifconfig/interface.py b/python/vyos/ifconfig/interface.py index 9c02af68f..c53bb964a 100644 --- a/python/vyos/ifconfig/interface.py +++ b/python/vyos/ifconfig/interface.py @@ -38,6 +38,7 @@ from vyos.util import dict_search from vyos.util import read_file from vyos.util import get_interface_config from vyos.template import is_ipv4 +from vyos.template import is_ipv6 from vyos.validate import is_intf_addr_assigned from vyos.validate import is_ipv6_link_local from vyos.validate import assert_boolean @@ -52,6 +53,10 @@ from vyos.ifconfig.vrrp import VRRP from vyos.ifconfig.operational import Operational from vyos.ifconfig import Section +from netaddr import EUI +from netaddr import mac_unix_expanded +from random import getrandbits + class Interface(Control): # This is the class which will be used to create # self.operational, it allows subclasses, such as @@ -367,6 +372,31 @@ class Interface(Control): """ return self.get_interface('mac') + def get_mac_synthetic(self): + """ + Get a synthetic MAC address. This is a common method which can be called + from derived classes to overwrite the get_mac() call in a generic way. + + NOTE: Tunnel interfaces have no "MAC" address by default. The content + of the 'address' file in /sys/class/net/device contains the + local-ip thus we generate a random MAC address instead + + Example: + >>> from vyos.ifconfig import Interface + >>> Interface('eth0').get_mac() + '00:50:ab:cd:ef:00' + """ + # we choose 40 random bytes for the MAC address, this gives + # us e.g. EUI('00-EA-EE-D6-A3-C8') or EUI('00-41-B9-0D-F2-2A') + tmp = EUI(getrandbits(48)).value + # set locally administered bit in MAC address + tmp |= 0xf20000000000 + # convert integer to "real" MAC address representation + mac = EUI(hex(tmp).split('x')[-1]) + # change dialect to use : as delimiter instead of - + mac.dialect = mac_unix_expanded + return str(mac) + def set_mac(self, mac): """ Set interface MAC (Media Access Contrl) address to given value. @@ -559,9 +589,10 @@ class Interface(Control): Delete the address based on the interface's MAC-based EUI64 combined with the prefix address. """ - eui64 = mac2eui64(self.get_mac(), prefix) - prefixlen = prefix.split('/')[1] - self.del_addr(f'{eui64}/{prefixlen}') + if is_ipv6(prefix): + eui64 = mac2eui64(self.get_mac(), prefix) + prefixlen = prefix.split('/')[1] + self.del_addr(f'{eui64}/{prefixlen}') def set_ipv6_forwarding(self, forwarding): """ @@ -1048,12 +1079,14 @@ class Interface(Control): source_if = next(iter(self._config['is_mirror_intf'])) config = self._config['is_mirror_intf'][source_if].get('mirror', None) - # 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) + # Check configuration stored by old perl code before delete T3782 + if not 'redirect' 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: diff --git a/python/vyos/ifconfig/section.py b/python/vyos/ifconfig/section.py index 173a90bb4..0e4447b9e 100644 --- a/python/vyos/ifconfig/section.py +++ b/python/vyos/ifconfig/section.py @@ -46,7 +46,7 @@ class Section: return klass @classmethod - def _basename (cls, name, vlan): + def _basename(cls, name, vlan, vrrp): """ remove the number at the end of interface name name: name of the interface @@ -56,16 +56,18 @@ class Section: name = name.rstrip('.') if vlan: name = name.rstrip('0123456789.') + if vrrp: + name = name.rstrip('0123456789v') return name @classmethod - def section(cls, name, vlan=True): + def section(cls, name, vlan=True, vrrp=True): """ return the name of a section an interface should be under name: name of the interface (eth0, dum1, ...) vlan: should we try try to remove the VLAN from the number """ - name = cls._basename(name, vlan) + name = cls._basename(name, vlan, vrrp) if name in cls._prefixes: return cls._prefixes[name].definition['section'] @@ -79,8 +81,8 @@ class Section: return list(set([cls._prefixes[_].definition['section'] for _ in cls._prefixes])) @classmethod - def klass(cls, name, vlan=True): - name = cls._basename(name, vlan) + def klass(cls, name, vlan=True, vrrp=True): + name = cls._basename(name, vlan, vrrp) if name in cls._prefixes: return cls._prefixes[name] raise ValueError(f'No type found for interface name: {name}') diff --git a/python/vyos/ifconfig/tunnel.py b/python/vyos/ifconfig/tunnel.py index e40756cc7..5258a2cb1 100644 --- a/python/vyos/ifconfig/tunnel.py +++ b/python/vyos/ifconfig/tunnel.py @@ -16,10 +16,6 @@ # https://developers.redhat.com/blog/2019/05/17/an-introduction-to-linux-virtual-interfaces-tunnels/ # https://community.hetzner.com/tutorials/linux-setup-gre-tunnel -from netaddr import EUI -from netaddr import mac_unix_expanded -from random import getrandbits - from vyos.ifconfig.interface import Interface from vyos.util import dict_search from vyos.validate import assert_list @@ -163,26 +159,8 @@ class TunnelIf(Interface): self._cmd(cmd.format(**self.config)) def get_mac(self): - """ - Get current interface MAC (Media Access Contrl) address used. - NOTE: Tunnel interfaces have no "MAC" address by default. The content - of the 'address' file in /sys/class/net/device contains the - local-ip thus we generate a random MAC address instead - Example: - >>> from vyos.ifconfig import Interface - >>> Interface('eth0').get_mac() - '00:50:ab:cd:ef:00' - """ - # we choose 40 random bytes for the MAC address, this gives - # us e.g. EUI('00-EA-EE-D6-A3-C8') or EUI('00-41-B9-0D-F2-2A') - tmp = EUI(getrandbits(48)).value - # set locally administered bit in MAC address - tmp |= 0xf20000000000 - # convert integer to "real" MAC address representation - mac = EUI(hex(tmp).split('x')[-1]) - # change dialect to use : as delimiter instead of - - mac.dialect = mac_unix_expanded - return str(mac) + """ Get a synthetic MAC address. """ + return self.get_mac_synthetic() def update(self, config): """ General helper function which works on a dictionary retrived by diff --git a/python/vyos/ifconfig/wireguard.py b/python/vyos/ifconfig/wireguard.py index 2d2243b84..de1b56ce5 100644 --- a/python/vyos/ifconfig/wireguard.py +++ b/python/vyos/ifconfig/wireguard.py @@ -17,9 +17,6 @@ import os import time from datetime import timedelta -from netaddr import EUI -from netaddr import mac_unix_expanded -from random import getrandbits from hurry.filesize import size from hurry.filesize import alternative @@ -163,28 +160,8 @@ class WireGuardIf(Interface): 'allowed_ips', 'fwmark', 'endpoint', 'keepalive'] def get_mac(self): - """ - Get current interface MAC (Media Access Contrl) address used. - - NOTE: Tunnel interfaces have no "MAC" address by default. The content - of the 'address' file in /sys/class/net/device contains the - local-ip thus we generate a random MAC address instead - - Example: - >>> from vyos.ifconfig import Interface - >>> Interface('eth0').get_mac() - '00:50:ab:cd:ef:00' - """ - # we choose 40 random bytes for the MAC address, this gives - # us e.g. EUI('00-EA-EE-D6-A3-C8') or EUI('00-41-B9-0D-F2-2A') - tmp = EUI(getrandbits(48)).value - # set locally administered bit in MAC address - tmp |= 0xf20000000000 - # convert integer to "real" MAC address representation - mac = EUI(hex(tmp).split('x')[-1]) - # change dialect to use : as delimiter instead of - - mac.dialect = mac_unix_expanded - return str(mac) + """ Get a synthetic MAC address. """ + return self.get_mac_synthetic() def update(self, config): """ General helper function which works on a dictionary retrived by diff --git a/python/vyos/migrator.py b/python/vyos/migrator.py index 9a5fdef2f..4574bb6d1 100644 --- a/python/vyos/migrator.py +++ b/python/vyos/migrator.py @@ -15,6 +15,7 @@ import sys import os +import json import subprocess import vyos.version import vyos.defaults @@ -165,6 +166,20 @@ class Migrator(object): versions_string, os_version_string) + def save_json_record(self, component_versions: dict): + """ + Write component versions to a json file + """ + mask = os.umask(0o113) + version_file = vyos.defaults.component_version_json + try: + with open(version_file, 'w') as f: + f.write(json.dumps(component_versions, indent=2, sort_keys=True)) + except OSError: + pass + finally: + os.umask(mask) + def run(self): """ Gather component versions from config file and system. @@ -182,6 +197,9 @@ class Migrator(object): sys_versions = systemversions.get_system_versions() + # save system component versions in json file for easy reference + self.save_json_record(sys_versions) + rev_versions = self.run_migration_scripts(cfg_versions, sys_versions) if rev_versions != cfg_versions: diff --git a/python/vyos/systemversions.py b/python/vyos/systemversions.py index 5c4deca29..9b3f4f413 100644 --- a/python/vyos/systemversions.py +++ b/python/vyos/systemversions.py @@ -16,15 +16,12 @@ import os import re import sys -import json - import vyos.defaults def get_system_versions(): """ - Get component versions from running system: read vyatta directory - structure for versions, then read vyos JSON file. It is a critical - error if either migration directory or JSON file is unreadable. + Get component versions from running system; critical failure if + unable to read migration directory. """ system_versions = {} @@ -39,25 +36,4 @@ def get_system_versions(): pair = info.split('@') system_versions[pair[0]] = int(pair[1]) - version_dict = {} - path = vyos.defaults.version_file - - if os.path.isfile(path): - with open(path, 'r') as f: - try: - version_dict = json.load(f) - except ValueError as err: - print(f"\nValue error in {path}: {err}") - sys.exit(1) - - for k, v in version_dict.items(): - if not isinstance(v, int): - print(f"\nType error in {path}; expecting Dict[str, int]") - sys.exit(1) - existing = system_versions.get(k) - if existing is None: - system_versions[k] = v - elif v > existing: - system_versions[k] = v - return system_versions diff --git a/python/vyos/util.py b/python/vyos/util.py index f3451fd77..45b1d7bf2 100644 --- a/python/vyos/util.py +++ b/python/vyos/util.py @@ -676,20 +676,20 @@ def find_device_file(device): return None -def dict_search(path, my_dict): - """ Traverse Python dictionary (my_dict) delimited by dot (.). +def dict_search(path, dict_object): + """ Traverse Python dictionary (dict_object) delimited by dot (.). Return value of key if found, None otherwise. - This is faster implementation then jmespath.search('foo.bar', my_dict)""" - if not isinstance(my_dict, dict) or not path: + This is faster implementation then jmespath.search('foo.bar', dict_object)""" + if not isinstance(dict_object, dict) or not path: return None parts = path.split('.') inside = parts[:-1] if not inside: - if path not in my_dict: + if path not in dict_object: return None - return my_dict[path] - c = my_dict + return dict_object[path] + c = dict_object for p in parts[:-1]: c = c.get(p, {}) return c.get(parts[-1], None) diff --git a/schema/interface_definition.rnc b/schema/interface_definition.rnc index d7fc4966c..192a70024 100644 --- a/schema/interface_definition.rnc +++ b/schema/interface_definition.rnc @@ -24,16 +24,9 @@ # Interface definition starts with interfaceDefinition tag that may contain node tags start = element interfaceDefinition { - syntaxVersion*, node* } -# interfaceDefinition may contain syntax version attribute lists. -syntaxVersion = element syntaxVersion -{ - (componentAttr & versionAttr) -} - # node tag may contain node, leafNode, or tagNode tags # Those are intermediate configuration nodes that may only contain # other nodes and must not have values @@ -109,16 +102,6 @@ properties = element properties (element keepChildOrder { empty })? } -componentAttr = attribute component -{ - text -} - -versionAttr = attribute version -{ - text -} - # All nodes must have "name" attribute nodeNameAttr = attribute name { diff --git a/schema/interface_definition.rng b/schema/interface_definition.rng index 3ff60cf18..1ed18f456 100644 --- a/schema/interface_definition.rng +++ b/schema/interface_definition.rng @@ -29,22 +29,10 @@ <start> <element name="interfaceDefinition"> <zeroOrMore> - <ref name="syntaxVersion"/> - </zeroOrMore> - <zeroOrMore> <ref name="node"/> </zeroOrMore> </element> </start> - <!-- interfaceDefinition may contain syntax version attribute lists. --> - <define name="syntaxVersion"> - <element name="syntaxVersion"> - <interleave> - <ref name="componentAttr"/> - <ref name="versionAttr"/> - </interleave> - </element> - </define> <!-- node tag may contain node, leafNode, or tagNode tags Those are intermediate configuration nodes that may only contain @@ -213,12 +201,6 @@ </interleave> </element> </define> - <define name="componentAttr"> - <attribute name="component"/> - </define> - <define name="versionAttr"> - <attribute name="version"/> - </define> <!-- All nodes must have "name" attribute --> <define name="nodeNameAttr"> <attribute name="name"/> diff --git a/scripts/build-command-op-templates b/scripts/build-command-op-templates index c285ee594..d4515b8db 100755 --- a/scripts/build-command-op-templates +++ b/scripts/build-command-op-templates @@ -29,13 +29,10 @@ import functools from lxml import etree as ET # Defaults - validator_dir = "/opt/vyatta/libexec/validators" default_constraint_err_msg = "Invalid value" - ## Get arguments - parser = argparse.ArgumentParser(description='Converts new-style XML interface definitions to old-style command templates') parser.add_argument('--debug', help='Enable debug information output', action='store_true') parser.add_argument('INPUT_FILE', type=str, help="XML interface definition file") @@ -50,11 +47,10 @@ output_dir = args.OUTPUT_DIR debug = args.debug ## Load and validate the inputs - try: xml = ET.parse(input_file) except Exception as e: - print("Failed to load interface definition file {0}".format(input_file)) + print(f"Failed to load interface definition file {input_file}") print(e) sys.exit(1) @@ -64,19 +60,18 @@ try: if not validator.validate(xml): print(validator.error_log) - print("Interface definition file {0} does not match the schema!".format(input_file)) + print(f"Interface definition file {input_file} does not match the schema!") sys.exit(1) except Exception as e: - print("Failed to load the XML schema {0}".format(schema_file)) + print(f"Failed to load the XML schema {schema_file}") print(e) sys.exit(1) if not os.access(output_dir, os.W_OK): - print("The output directory {0} is not writeable".format(output_dir)) + print(f"The output directory {output_dir} is not writeable") sys.exit(1) ## If we got this far, everything must be ok and we can convert the file - def make_path(l): path = functools.reduce(os.path.join, l) if debug: @@ -125,21 +120,14 @@ def get_properties(p): def make_node_def(props, command): # XXX: replace with a template processor if it grows # out of control - node_def = "" if "help" in props: node_def += "help: {0}\n".format(props["help"]) - - if "comp_help" in props: node_def += "allowed: {0}\n".format(props["comp_help"]) - - if command is not None: node_def += "run: {0}\n".format(command.text) - - if debug: print("The contents of the node.def file:\n", node_def) @@ -152,7 +140,6 @@ def process_node(n, tmpl_dir): props_elem = n.find("properties") children = n.find("children") command = n.find("command") - name = n.get("name") node_type = n.tag @@ -160,16 +147,16 @@ def process_node(n, tmpl_dir): my_tmpl_dir.append(name) if debug: - print("Name of the node: {};\n Created directory: ".format(name), end="") + print(f"Name of the node: {name};\n Created directory: ", end="") os.makedirs(make_path(my_tmpl_dir), exist_ok=True) props = get_properties(props_elem) + nodedef_path = os.path.join(make_path(my_tmpl_dir), "node.def") if node_type == "node": if debug: - print("Processing node {}".format(name)) + print(f"Processing node {name}") - nodedef_path = os.path.join(make_path(my_tmpl_dir), "node.def") # Only create the "node.def" file if it exists but is empty, or if it # does not exist at all. if not os.path.exists(nodedef_path) or os.path.getsize(nodedef_path) == 0: @@ -180,19 +167,17 @@ def process_node(n, tmpl_dir): inner_nodes = children.iterfind("*") for inner_n in inner_nodes: process_node(inner_n, my_tmpl_dir) - if node_type == "tagNode": + elif node_type == "tagNode": if debug: - print("Processing tag node {}".format(name)) + print(f"Processing tagNode {name}") os.makedirs(make_path(my_tmpl_dir), exist_ok=True) - nodedef_path = os.path.join(make_path(my_tmpl_dir), "node.def") - if not os.path.exists(nodedef_path): + # Only create the "node.def" file if it exists but is empty, or if it + # does not exist at all. + if not os.path.exists(nodedef_path) or os.path.getsize(nodedef_path) == 0: with open(nodedef_path, "w") as f: f.write('help: {0}\n'.format(props['help'])) - else: - # Something has already generated this file - pass # Create the inner node.tag part my_tmpl_dir.append("node.tag") @@ -201,24 +186,67 @@ def process_node(n, tmpl_dir): print("Created path for the tagNode: {}".format(make_path(my_tmpl_dir)), end="") # Not sure if we want partially defined tag nodes, write the file unconditionally - with open(os.path.join(make_path(my_tmpl_dir), "node.def"), "w") as f: - f.write(make_node_def(props, command)) + nodedef_path = os.path.join(make_path(my_tmpl_dir), "node.def") + # Only create the "node.def" file if it exists but is empty, or if it + # does not exist at all. + if not os.path.exists(nodedef_path) or os.path.getsize(nodedef_path) == 0: + with open(nodedef_path, "w") as f: + f.write(make_node_def(props, command)) if children is not None: inner_nodes = children.iterfind("*") for inner_n in inner_nodes: process_node(inner_n, my_tmpl_dir) - else: + elif node_type == "leafNode": # This is a leaf node if debug: - print("Processing leaf node {}".format(name)) - - with open(os.path.join(make_path(my_tmpl_dir), "node.def"), "w") as f: - f.write(make_node_def(props, command)) + print(f"Processing leaf node {name}") + if not os.path.exists(nodedef_path) or os.path.getsize(nodedef_path) == 0: + with open(nodedef_path, "w") as f: + f.write(make_node_def(props, command)) + else: + print(f"Unknown node_type: {node_type}") + + +def get_node_key(node, attr=None): + """ Return the sorting key of an xml node using tag and attributes """ + if attr is None: + return '%s' % node.tag + ':'.join([node.get(attr) + for attr in sorted(node.attrib)]) + if attr in node.attrib: + return '%s:%s' % (node.tag, node.get(attr)) + return '%s' % node.tag + + +def sort_children(node, attr=None): + """ Sort children along tag and given attribute. if attr is None, sort + along all attributes """ + if not isinstance(node.tag, str): # PYTHON 2: use basestring instead + # not a TAG, it is comment or DATA + # no need to sort + return + # sort child along attr + node[:] = sorted(node, key=lambda child: get_node_key(child, attr)) + # and recurse + for child in node: + sort_children(child, attr) root = xml.getroot() +# process_node() processes the XML tree in a fixed order, "node" before "tagNode" +# before "leafNode". If the generator created a "node.def" file, it can no longer +# be overwritten - else we would have some stale "node.def" files with an empty +# help string (T2555). Without the fixed order this would resulted in a case +# where we get a node and a tagNode with the same name, e.g. "show interfaces +# ethernet" and "show interfaces ethernet eth0" that the node implementation +# was not callable from the CLI, rendering this command useless (T3807). +# +# This can be fixed by forcing the "node", "tagNode", "leafNode" order by sorting +# the input XML file automatically (sorting from https://stackoverflow.com/a/46128043) +# thus adding no additional overhead to the user. +sort_children(root, 'name') + nodes = root.iterfind("*") for n in nodes: process_node(n, [output_dir]) diff --git a/scripts/build-command-templates b/scripts/build-command-templates index d8abb0a13..a0d1015b4 100755 --- a/scripts/build-command-templates +++ b/scripts/build-command-templates @@ -320,6 +320,4 @@ root = xml.getroot() nodes = root.iterfind("*") for n in nodes: - if n.tag == "syntaxVersion": - continue process_node(n, [output_dir]) diff --git a/scripts/build-component-versions b/scripts/build-component-versions deleted file mode 100755 index 5362dbdd4..000000000 --- a/scripts/build-component-versions +++ /dev/null @@ -1,47 +0,0 @@ -#!/usr/bin/env python3 - -import sys -import os -import argparse -import json - -from lxml import etree as ET - -parser = argparse.ArgumentParser() -parser.add_argument('INPUT_DIR', type=str, - help="Directory containing XML interface definition files") -parser.add_argument('OUTPUT_DIR', type=str, - help="Output directory for JSON file") - -args = parser.parse_args() - -input_dir = args.INPUT_DIR -output_dir = args.OUTPUT_DIR - -version_dict = {} - -for filename in os.listdir(input_dir): - filepath = os.path.join(input_dir, filename) - print(filepath) - try: - xml = ET.parse(filepath) - except Exception as e: - print("Failed to load interface definition file {0}".format(filename)) - print(e) - sys.exit(1) - - root = xml.getroot() - version_data = root.iterfind("syntaxVersion") - for ver in version_data: - component = ver.get("component") - version = int(ver.get("version")) - - v = version_dict.get(component) - if v is None: - version_dict[component] = version - elif version > v: - version_dict[component] = version - -out_file = os.path.join(output_dir, 'component-versions.json') -with open(out_file, 'w') as f: - json.dump(version_dict, f, indent=4, sort_keys=True) diff --git a/smoketest/configs/bgp-bfd-communities b/smoketest/configs/bgp-bfd-communities new file mode 100644 index 000000000..3b3056a51 --- /dev/null +++ b/smoketest/configs/bgp-bfd-communities @@ -0,0 +1,533 @@ +interfaces { + ethernet eth0 { + address 192.0.2.100/25 + address 2001:db8::ffff/64 + } + loopback lo { + } +} +policy { + large-community-list ANYCAST_ALL { + rule 10 { + action permit + description "Allow all anycast from anywhere" + regex "4242420696:100:.*" + } + } + large-community-list ANYCAST_INT { + rule 10 { + action permit + description "Allow all anycast from int" + regex 4242420696:100:1 + } + } + prefix-list BGP-BACKBONE-IN { + description "Inbound backbone routes from other sites" + rule 10 { + action deny + description "Block default route" + prefix 0.0.0.0/0 + } + rule 20 { + action deny + description "Block int primary" + ge 21 + prefix 192.168.0.0/20 + } + rule 30 { + action deny + description "Block loopbacks" + ge 25 + prefix 192.168.253.0/24 + } + rule 40 { + action deny + description "Block backbone peering" + ge 25 + prefix 192.168.254.0/24 + } + rule 999 { + action permit + description "Allow everything else" + ge 1 + prefix 0.0.0.0/0 + } + } + prefix-list BGP-BACKBONE-OUT { + description "Outbound backbone routes to other sites" + rule 10 { + action permit + description "Int primary" + ge 23 + prefix 192.168.0.0/20 + } + } + prefix-list GLOBAL { + description "Globally redistributed routes" + rule 10 { + action permit + prefix 192.168.100.1/32 + } + rule 20 { + action permit + prefix 192.168.7.128/25 + } + } + prefix-list6 BGP-BACKBONE-IN-V6 { + description "Inbound backbone routes from other sites" + rule 10 { + action deny + description "Block default route" + prefix ::/0 + } + rule 20 { + action deny + description "Block int primary" + ge 53 + prefix fd52:d62e:8011::/52 + } + rule 30 { + action deny + description "Block peering and stuff" + ge 53 + prefix fd52:d62e:8011:f000::/52 + } + rule 999 { + action permit + description "Allow everything else" + ge 1 + prefix ::/0 + } + } + prefix-list6 BGP-BACKBONE-OUT-V6 { + description "Outbound backbone routes to other sites" + rule 10 { + action permit + ge 64 + prefix fd52:d62e:8011::/52 + } + } + prefix-list6 GLOBAL-V6 { + description "Globally redistributed routes" + rule 10 { + action permit + ge 64 + prefix fd52:d62e:8011:2::/63 + } + } + route-map BGP-REDISTRIBUTE { + rule 10 { + action permit + description "Prepend AS and allow VPN and modem" + match { + ip { + address { + prefix-list GLOBAL + } + } + } + set { + as-path-prepend 4242420666 + } + } + rule 20 { + action permit + description "Allow VPN" + match { + ipv6 { + address { + prefix-list GLOBAL-V6 + } + } + } + } + } + route-map BGP-BACKBONE-IN { + rule 10 { + action permit + match { + ip { + address { + prefix-list BGP-BACKBONE-IN + } + } + } + } + rule 20 { + action permit + match { + ipv6 { + address { + prefix-list BGP-BACKBONE-IN-V6 + } + } + } + } + rule 30 { + action permit + match { + large-community { + large-community-list ANYCAST_ALL + } + } + } + } + route-map BGP-BACKBONE-OUT { + rule 10 { + action permit + match { + ip { + address { + prefix-list BGP-BACKBONE-OUT + } + } + } + } + rule 20 { + action permit + match { + ipv6 { + address { + prefix-list BGP-BACKBONE-OUT-V6 + } + } + } + } + rule 30 { + action permit + match { + large-community { + large-community-list ANYCAST_INT + } + } + set { + as-path-prepend 4242420666 + } + } + } +} +protocols { + bfd { + peer 192.168.253.1 { + interval { + receive 50 + transmit 50 + } + multihop + source { + address 192.168.253.3 + } + } + peer 192.168.253.2 { + interval { + receive 50 + transmit 50 + } + multihop + source { + address 192.168.253.3 + } + } + peer 192.168.253.6 { + interval { + receive 50 + transmit 50 + } + multihop + source { + address 192.168.253.3 + } + } + peer 192.168.253.7 { + interval { + receive 50 + transmit 50 + } + multihop + source { + address 192.168.253.3 + } + } + peer 192.168.253.12 { + interval { + receive 100 + transmit 100 + } + multihop + source { + address 192.168.253.3 + } + } + peer fd52:d62e:8011:fffe:192:168:253:1 { + interval { + receive 50 + transmit 50 + } + multihop + source { + address fd52:d62e:8011:fffe:192:168:253:3 + } + } + peer fd52:d62e:8011:fffe:192:168:253:2 { + interval { + receive 50 + transmit 50 + } + multihop + source { + address fd52:d62e:8011:fffe:192:168:253:3 + } + } + peer fd52:d62e:8011:fffe:192:168:253:6 { + interval { + receive 50 + transmit 50 + } + multihop + source { + address fd52:d62e:8011:fffe:192:168:253:3 + } + } + peer fd52:d62e:8011:fffe:192:168:253:7 { + interval { + receive 50 + transmit 50 + } + multihop + source { + address fd52:d62e:8011:fffe:192:168:253:3 + } + } + peer fd52:d62e:8011:fffe:192:168:253:12 { + interval { + receive 100 + transmit 100 + } + multihop + source { + address fd52:d62e:8011:fffe:192:168:253:3 + } + } + } + bgp 4242420666 { + address-family { + ipv4-unicast { + redistribute { + connected { + route-map BGP-REDISTRIBUTE + } + static { + route-map BGP-REDISTRIBUTE + } + } + } + ipv6-unicast { + redistribute { + connected { + route-map BGP-REDISTRIBUTE + } + } + } + } + neighbor 192.168.253.1 { + peer-group INT + } + neighbor 192.168.253.2 { + peer-group INT + } + neighbor 192.168.253.6 { + peer-group DAL13 + } + neighbor 192.168.253.7 { + peer-group DAL13 + } + neighbor 192.168.253.12 { + address-family { + ipv4-unicast { + route-map { + export BGP-BACKBONE-OUT + import BGP-BACKBONE-IN + } + soft-reconfiguration { + inbound + } + } + } + bfd { + } + ebgp-multihop 2 + remote-as 4242420669 + update-source dum0 + } + neighbor fd52:d62e:8011:fffe:192:168:253:1 { + address-family { + ipv6-unicast { + peer-group INTv6 + } + } + } + neighbor fd52:d62e:8011:fffe:192:168:253:2 { + address-family { + ipv6-unicast { + peer-group INTv6 + } + } + } + neighbor fd52:d62e:8011:fffe:192:168:253:6 { + address-family { + ipv6-unicast { + peer-group DAL13v6 + } + } + } + neighbor fd52:d62e:8011:fffe:192:168:253:7 { + address-family { + ipv6-unicast { + peer-group DAL13v6 + } + } + } + neighbor fd52:d62e:8011:fffe:192:168:253:12 { + address-family { + ipv6-unicast { + route-map { + export BGP-BACKBONE-OUT + import BGP-BACKBONE-IN + } + soft-reconfiguration { + inbound + } + } + } + bfd { + } + ebgp-multihop 2 + remote-as 4242420669 + update-source dum0 + } + parameters { + confederation { + identifier 4242420696 + peers 4242420668 + peers 4242420669 + } + default { + no-ipv4-unicast + } + distance { + global { + external 220 + internal 220 + local 220 + } + } + graceful-restart { + } + } + peer-group DAL13 { + address-family { + ipv4-unicast { + route-map { + export BGP-BACKBONE-OUT + import BGP-BACKBONE-IN + } + soft-reconfiguration { + inbound + } + } + } + bfd + ebgp-multihop 2 + remote-as 4242420668 + update-source dum0 + } + peer-group DAL13v6 { + address-family { + ipv6-unicast { + route-map { + export BGP-BACKBONE-OUT + import BGP-BACKBONE-IN + } + soft-reconfiguration { + inbound + } + } + } + bfd + ebgp-multihop 2 + remote-as 4242420668 + update-source dum0 + } + peer-group INT { + address-family { + ipv4-unicast { + default-originate { + } + soft-reconfiguration { + inbound + } + } + } + bfd + remote-as 4242420666 + update-source dum0 + } + peer-group INTv6 { + address-family { + ipv6-unicast { + default-originate { + } + soft-reconfiguration { + inbound + } + } + } + bfd + remote-as 4242420666 + update-source dum0 + } + } +} +system { + config-management { + commit-revisions 200 + } + console { + device ttyS0 { + speed 115200 + } + } + host-name vyos + login { + user vyos { + authentication { + encrypted-password $6$2Ta6TWHd/U$NmrX0x9kexCimeOcYK1MfhMpITF9ELxHcaBU/znBq.X2ukQOj61fVI2UYP/xBzP4QtiTcdkgs7WOQMHWsRymO/ + plaintext-password "" + } + level admin + } + } + ntp { + server 0.pool.ntp.org { + } + server 1.pool.ntp.org { + } + server 2.pool.ntp.org { + } + } + syslog { + global { + facility all { + level info + } + facility protocols { + level debug + } + } + } + time-zone Europe/Berlin +} + +/* 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@10:vrrp@2:wanloadbalance@3:webgui@1:webproxy@1:webproxy@2:zone-policy@1" === */ +/* Release version: 1.2.6-S1 */ diff --git a/smoketest/configs/bgp-big-as-cloud b/smoketest/configs/bgp-big-as-cloud new file mode 100644 index 000000000..694243d1e --- /dev/null +++ b/smoketest/configs/bgp-big-as-cloud @@ -0,0 +1,1956 @@ +firewall { + all-ping enable + broadcast-ping disable + config-trap disable + group { + address-group bgp-peers-4 { + address 192.0.68.3 + address 192.0.68.2 + address 192.0.176.193 + address 192.0.52.0-192.0.52.255 + address 192.0.53.0-192.0.53.255 + address 192.0.16.209 + address 192.0.192.0-192.0.192.255 + address 192.0.193.0-192.0.193.255 + address 192.0.194.0-192.0.194.255 + address 192.0.195.0-192.0.195.255 + address 192.0.196.0-192.0.196.255 + address 192.0.197.0-192.0.197.255 + address 192.0.198.0-192.0.198.255 + address 192.0.199.0-192.0.199.255 + } + address-group vrrp-peers-4 { + address 192.0.68.3 + address 192.0.160.3 + address 192.0.98.3 + address 192.0.71.131 + address 192.0.84.67 + address 192.0.71.195 + address 192.0.71.115 + address 192.0.70.195 + address 192.0.70.179 + address 192.0.70.163 + address 192.0.70.147 + address 192.0.70.131 + address 192.0.70.19 + address 192.0.70.3 + address 192.0.71.99 + address 192.0.68.67 + address 192.0.71.67 + address 192.0.71.3 + address 192.0.68.35 + address 192.0.68.131 + address 192.0.69.2 + address 192.0.70.35 + address 192.0.70.67 + } + ipv6-address-group bgp-peers-6 { + address 2001:db8:c::3 + address 2001:db8:1000::2e9 + address 2001:db8:24::fb + address 2001:db8:24::fc + address 2001:db8:24::fd + address 2001:db8:24::2e + address 2001:db8:24::3d + address 2001:db8:24::4a + address 2001:db8:24::5e + address 2001:db8:24::7 + address 2001:db8:24::11 + address 2001:db8:24::18 + address 2001:db8:24::20 + address 2001:db8:24::22 + address 2001:db8:24::31 + address 2001:db8:24::58 + address 2001:db8:24::64 + address 2001:db8:24::a5 + address 2001:db8:24::aa + address 2001:db8:24::ab + address 2001:db8:24::b0 + address 2001:db8:24::b3 + address 2001:db8:24::bd + address 2001:db8:24::c + address 2001:db8:24::d2 + address 2001:db8:24::d3 + address 2001:db8:838::1 + address 2001:db8::1a27:5051:c09d + address 2001:db8::1a27:5051:c19d + address 2001:db8::20ad:0:1 + address 2001:db8::2306:0:1 + address 2001:db8::2ca:0:1 + address 2001:db8::2ca:0:2 + address 2001:db8::2ca:0:3 + address 2001:db8::2ca:0:4 + } + ipv6-address-group vrrp-peers-6 { + address fe80::fe89:15cf + } + ipv6-network-group AS64512-6 { + network 2001::/29 + } + network-group AS64512-4 { + network 192.0.68.0/22 + network 192.0.98.0/24 + network 192.0.160.0/24 + network 192.0.84.0/22 + } + } + ipv6-name management-to-local-6 { + default-action reject + enable-default-log + } + ipv6-name management-to-peers-6 { + default-action reject + enable-default-log + } + ipv6-name management-to-servers-6 { + default-action reject + enable-default-log + } + ipv6-name peers-to-local-6 { + default-action reject + enable-default-log + rule 500 { + action accept + protocol icmpv6 + } + rule 501 { + action accept + protocol vrrp + source { + group { + address-group vrrp-peers-6 + } + } + } + rule 502 { + action accept + destination { + port bgp + } + protocol tcp + source { + group { + address-group bgp-peers-6 + } + } + } + rule 503 { + action accept + protocol tcp + source { + group { + address-group bgp-peers-6 + } + port bgp + } + } + } + ipv6-name peers-to-management-6 { + default-action reject + enable-default-log + } + ipv6-name peers-to-servers-6 { + default-action reject + enable-default-log + rule 9990 { + action reject + source { + group { + network-group AS64512-6 + } + } + } + rule 9999 { + action accept + destination { + group { + network-group AS64512-6 + } + } + } + } + ipv6-name servers-to-local-6 { + default-action reject + enable-default-log + rule 500 { + action accept + protocol icmpv6 + } + rule 501 { + action accept + protocol vrrp + source { + group { + address-group vrrp-peers-6 + } + } + } + rule 511 { + action accept + protocol tcp_udp + source { + port 53 + } + } + } + ipv6-name servers-to-management-6 { + default-action reject + enable-default-log + } + ipv6-name servers-to-peers-6 { + default-action reject + enable-default-log + rule 51 { + action accept + source { + group { + network-group AS64512-6 + } + } + } + } + ipv6-receive-redirects disable + ipv6-src-route disable + ip-src-route disable + log-martians enable + name management-to-local-4 { + default-action reject + enable-default-log + rule 500 { + action accept + protocol icmp + } + rule 501 { + action accept + destination { + port 22 + } + protocol tcp + } + rule 502 { + action accept + destination { + port snmp + } + protocol udp + } + } + name management-to-peers-4 { + default-action reject + enable-default-log + } + name management-to-servers-4 { + default-action reject + enable-default-log + } + name peers-to-local-4 { + default-action reject + enable-default-log + rule 500 { + action accept + protocol icmp + } + rule 501 { + action accept + protocol vrrp + source { + group { + address-group vrrp-peers-4 + } + } + } + rule 502 { + action accept + destination { + port bgp + } + protocol tcp + source { + group { + address-group bgp-peers-4 + } + } + } + rule 503 { + action accept + protocol tcp + source { + group { + address-group bgp-peers-4 + } + port bgp + } + } + } + name peers-to-management-4 { + default-action reject + enable-default-log + } + name peers-to-servers-4 { + default-action reject + enable-default-log + rule 9990 { + action reject + source { + group { + network-group AS64512-4 + } + } + } + rule 9999 { + action accept + destination { + group { + network-group AS64512-4 + } + } + } + } + name servers-to-local-4 { + default-action reject + enable-default-log + rule 500 { + action accept + protocol icmp + } + rule 501 { + action accept + protocol vrrp + source { + group { + address-group vrrp-peers-4 + } + } + } + rule 511 { + action accept + protocol tcp_udp + source { + port 53 + } + } + } + name servers-to-management-4 { + default-action reject + enable-default-log + } + name servers-to-peers-4 { + default-action reject + enable-default-log + rule 51 { + action accept + source { + group { + network-group AS64512-4 + } + } + } + } + receive-redirects disable + send-redirects enable + source-validation disable + syn-cookies enable + twa-hazards-protection disable +} +high-availability { + vrrp { + group 11-4 { + interface eth0.11 + priority 200 + virtual-address 192.0.68.1/27 + vrid 4 + } + group 11-6 { + interface eth0.11 + priority 200 + virtual-address 2001:db8:c::1/64 + vrid 6 + } + group 102-4 { + interface eth0.102 + priority 200 + virtual-address 192.0.98.1/24 + vrid 4 + } + group 102-6 { + interface eth0.102 + priority 200 + virtual-address 2001:db8:0:102::1/64 + vrid 6 + } + group 105-4 { + interface eth0.105 + priority 200 + virtual-address 192.0.160.1/24 + vrid 4 + } + group 105-6 { + interface eth0.105 + priority 200 + virtual-address 2001:db8:0:105::1/64 + vrid 6 + } + group 1001-4 { + interface eth0.1001 + priority 200 + virtual-address 192.0.68.33/27 + vrid 4 + } + group 1001-6 { + interface eth0.1001 + priority 200 + virtual-address 2001:db8:0:1001::1/64 + vrid 6 + } + group 1002-4 { + interface eth0.1002 + priority 200 + virtual-address 192.0.68.65/26 + vrid 4 + } + group 1002-6 { + interface eth0.1002 + priority 200 + virtual-address 2001:db8:0:1002::1/64 + vrid 6 + } + group 1003-4 { + interface eth0.1003 + priority 200 + virtual-address 192.0.68.129/25 + vrid 4 + } + group 1003-6 { + interface eth0.1003 + priority 200 + virtual-address 2001:db8:0:1003::1/64 + vrid 6 + } + group 1004-4 { + interface eth0.1004 + priority 200 + virtual-address 192.0.69.1/24 + vrid 4 + } + group 1004-6 { + interface eth0.1004 + priority 200 + virtual-address 2001:db8:0:1004::1/64 + vrid 6 + } + group 1005-4 { + interface eth0.1005 + priority 200 + virtual-address 192.0.70.1/28 + vrid 4 + } + group 1005-6 { + interface eth0.1005 + priority 200 + virtual-address 2001:db8:0:1005::1/64 + vrid 6 + } + group 1006-4 { + interface eth0.1006 + priority 200 + virtual-address 192.0.70.17/28 + vrid 4 + } + group 1006-6 { + interface eth0.1006 + priority 200 + virtual-address 2001:db8:0:1006::1/64 + vrid 6 + } + group 1007-4 { + interface eth0.1007 + priority 200 + virtual-address 192.0.70.33/27 + vrid 4 + } + group 1007-6 { + interface eth0.1007 + priority 200 + virtual-address 2001:db8:0:1007::1/64 + vrid 6 + } + group 1008-4 { + interface eth0.1008 + priority 200 + virtual-address 192.0.70.65/26 + vrid 4 + } + group 1008-6 { + interface eth0.1008 + priority 200 + virtual-address 2001:db8:0:1008::1/64 + vrid 6 + } + group 1009-4 { + interface eth0.1009 + priority 200 + virtual-address 192.0.70.129/28 + vrid 4 + } + group 1009-6 { + interface eth0.1009 + priority 200 + virtual-address 2001:db8:0:1009::1/64 + vrid 6 + } + group 1010-4 { + interface eth0.1010 + priority 200 + virtual-address 192.0.70.145/28 + vrid 4 + } + group 1010-6 { + interface eth0.1010 + priority 200 + virtual-address 2001:db8:0:1010::1/64 + vrid 6 + } + group 1011-4 { + interface eth0.1011 + priority 200 + virtual-address 192.0.70.161/28 + vrid 4 + } + group 1011-6 { + interface eth0.1011 + priority 200 + virtual-address 2001:db8:0:1011::1/64 + vrid 6 + } + group 1012-4 { + interface eth0.1012 + priority 200 + virtual-address 192.0.70.177/28 + vrid 4 + } + group 1012-6 { + interface eth0.1012 + priority 200 + virtual-address 2001:db8:0:1012::1/64 + vrid 6 + } + group 1013-4 { + interface eth0.1013 + priority 200 + virtual-address 192.0.70.193/27 + vrid 4 + } + group 1013-6 { + interface eth0.1013 + priority 200 + virtual-address 2001:db8:0:1013::1/64 + vrid 6 + } + group 1014-4 { + interface eth0.1014 + priority 200 + virtual-address 192.0.84.65/26 + vrid 4 + } + group 1014-6 { + interface eth0.1014 + priority 200 + virtual-address 2001:db8:0:1014::1/64 + vrid 6 + } + group 1015-4 { + interface eth0.1015 + priority 200 + virtual-address 192.0.71.1/26 + vrid 4 + } + group 1015-6 { + interface eth0.1015 + priority 200 + virtual-address 2001:db8:0:1015::1/64 + vrid 6 + } + group 1016-4 { + interface eth0.1016 + priority 200 + virtual-address 192.0.71.65/27 + vrid 4 + } + group 1016-6 { + interface eth0.1016 + priority 200 + virtual-address 2001:db8:0:1016::1/64 + vrid 6 + } + group 1017-4 { + interface eth0.1017 + priority 200 + virtual-address 192.0.71.97/28 + vrid 4 + } + group 1017-6 { + interface eth0.1017 + priority 200 + virtual-address 2001:db8:0:1017::1/64 + vrid 6 + } + group 1018-4 { + interface eth0.1018 + priority 200 + virtual-address 192.0.71.113/28 + vrid 4 + } + group 1018-6 { + interface eth0.1018 + priority 200 + virtual-address 2001:db8:0:1018::1/64 + vrid 6 + } + group 1019-4 { + interface eth0.1019 + priority 200 + virtual-address 192.0.71.129/26 + vrid 4 + } + group 1019-6 { + interface eth0.1019 + priority 200 + virtual-address 2001:db8:0:1019::1/64 + vrid 6 + } + group 1020-4 { + interface eth0.1020 + priority 200 + virtual-address 192.0.71.193/26 + vrid 4 + } + group 1020-6 { + interface eth0.1020 + priority 200 + virtual-address 2001:db8:0:1020::1/64 + vrid 6 + } + } +} +interfaces { + ethernet eth0 { + address 192.0.0.11/16 + duplex auto + smp-affinity auto + speed auto + vif 11 { + address 192.0.68.2/27 + address 2001:db8:c::2/64 + } + vif 102 { + address 192.0.98.2/24 + address 2001:db8:0:102::2/64 + } + vif 105 { + address 192.0.160.2/24 + address 2001:db8:0:105::2/64 + } + vif 838 { + address 192.0.16.210/30 + address 2001:db8:838::2/64 + } + vif 886 { + address 192.0.193.224/21 + address 2001:db8::3:669:0:1/64 + } + vif 1001 { + address 192.0.68.34/27 + address 2001:db8:0:1001::2/64 + } + vif 1002 { + address 192.0.68.66/26 + address 2001:db8:0:1002::2/64 + } + vif 1003 { + address 192.0.68.130/25 + address 2001:db8:0:1003::2/64 + } + vif 1004 { + address 192.0.69.2/24 + address 2001:db8:0:1004::2/64 + } + vif 1005 { + address 192.0.70.2/28 + address 2001:db8:0:1005::2/64 + } + vif 1006 { + address 192.0.70.18/28 + address 2001:db8:0:1006::2/64 + } + vif 1007 { + address 192.0.70.34/27 + address 2001:db8:0:1007::2/64 + } + vif 1008 { + address 192.0.70.66/26 + address 2001:db8:0:1008::2/64 + } + vif 1009 { + address 192.0.70.130/28 + address 2001:db8:0:1009::2/64 + } + vif 1010 { + address 192.0.70.146/28 + address 2001:db8:0:1010::2/64 + } + vif 1011 { + address 192.0.70.162/28 + address 2001:db8:0:1011::2/64 + } + vif 1012 { + address 192.0.70.178/28 + address 2001:db8:0:1012::2/64 + } + vif 1013 { + address 192.0.70.194/27 + address 2001:db8:0:1013::3/64 + } + vif 1014 { + address 192.0.84.66/26 + address 2001:db8:0:1014::2/64 + } + vif 1015 { + address 192.0.71.2/26 + address 2001:db8:0:1015::2/64 + } + vif 1016 { + address 192.0.71.66/27 + address 2001:db8:0:1016::2/64 + } + vif 1017 { + address 192.0.71.98/28 + address 2001:db8:0:1017::2/64 + } + vif 1018 { + address 192.0.71.114/28 + address 2001:db8:0:1018::2/64 + } + vif 1019 { + address 192.0.71.130/26 + address 2001:db8:0:1019::2/64 + } + vif 1020 { + address 192.0.71.194/26 + address 2001:db8:0:1020::2/64 + } + vif 4088 { + address 2001:db8:24::c7/64 + address 192.0.52.199/23 + } + vif 4089 { + address 192.0.176.194/30 + address 2001:db8:1000::2ea/126 + } + } + loopback lo { + } +} +policy { + as-path-list AS64513-AS64514 { + rule 10 { + action permit + regex "^64513 64514$" + } + } + as-path-list AS64512 { + rule 10 { + action permit + regex ^$ + } + } + prefix-list defaultV4 { + rule 10 { + action permit + prefix 0.0.0.0/0 + } + } + prefix-list hostrouteV4 { + rule 10 { + action permit + ge 32 + prefix 192.0.160.0/24 + } + rule 20 { + action permit + ge 32 + prefix 192.0.98.0/24 + } + rule 30 { + action permit + ge 32 + prefix 192.0.68.0/22 + } + rule 40 { + action permit + ge 32 + prefix 192.0.84.0/22 + } + } + prefix-list vyosV4 { + rule 10 { + action permit + prefix 192.0.160.0/24 + } + rule 20 { + action permit + prefix 192.0.98.0/24 + } + rule 30 { + action permit + prefix 192.0.68.0/22 + } + rule 40 { + action permit + prefix 192.0.84.0/22 + } + } + prefix-list privateV4 { + rule 10 { + action permit + le 32 + prefix 192.0.0.0/8 + } + rule 20 { + action permit + le 32 + prefix 192.0.0.0/12 + } + rule 30 { + action permit + le 32 + prefix 192.0.0.0/16 + } + } + prefix-list6 all6 { + rule 10 { + action permit + ge 4 + prefix 2000::/3 + } + } + prefix-list6 hostrouteV6 { + rule 20 { + action permit + ge 128 + prefix 2001:db8::/29 + } + } + prefix-list6 vyosV6 { + rule 20 { + action permit + prefix 2001:db8::/29 + } + } + prefix-list6 privateV6 { + rule 10 { + action permit + prefix fc00::/7 + } + } + route-map ExportRouteMap { + rule 5 { + action permit + match { + as-path AS64512 + ip { + address { + prefix-list hostrouteV4 + } + } + } + set { + community 65000:666 + } + } + rule 10 { + action permit + match { + as-path AS64512 + ip { + address { + prefix-list vyosV4 + } + } + } + } + rule 15 { + action permit + match { + as-path AS64512 + ipv6 { + address { + prefix-list hostrouteV6 + } + } + } + set { + community 65000:666 + } + } + rule 20 { + action permit + match { + as-path AS64512 + ipv6 { + address { + prefix-list vyosV6 + } + } + } + } + rule 100 { + action deny + } + } + route-map ExportRouteMapAS64515 { + rule 10 { + action permit + match { + ipv6 { + address { + prefix-list all6 + } + } + } + } + rule 20 { + action deny + match { + ip { + address { + prefix-list defaultV4 + } + } + } + } + rule 100 { + action deny + } + } + route-map ExportRouteMapAS64516 { + rule 5 { + action permit + match { + as-path AS64512 + ip { + address { + prefix-list hostrouteV4 + } + } + } + set { + community 65000:666 + } + } + rule 10 { + action permit + match { + as-path AS64512 + ip { + address { + prefix-list vyosV4 + } + } + } + } + rule 15 { + action permit + match { + as-path AS64512 + ipv6 { + address { + prefix-list hostrouteV6 + } + } + } + set { + community 65000:666 + } + } + rule 20 { + action permit + match { + as-path AS64512 + ipv6 { + address { + prefix-list vyosV6 + } + } + } + } + rule 100 { + action deny + } + } + route-map ExportRouteMapAS64517 { + rule 5 { + action permit + match { + as-path AS64512 + ip { + address { + prefix-list hostrouteV4 + } + } + } + set { + community 64517:666 + } + } + rule 10 { + action permit + match { + as-path AS64512 + ip { + address { + prefix-list vyosV4 + } + } + } + } + rule 15 { + action permit + match { + as-path AS64512 + ipv6 { + address { + prefix-list hostrouteV6 + } + } + } + set { + community 64517:666 + } + } + rule 20 { + action permit + match { + as-path AS64512 + ipv6 { + address { + prefix-list vyosV6 + } + } + } + } + rule 100 { + action deny + } + } + route-map ExportRouteMapAS64513 { + rule 5 { + action permit + match { + as-path AS64512 + ip { + address { + prefix-list hostrouteV4 + } + } + } + set { + community 64513:666 + } + } + rule 10 { + action permit + match { + as-path AS64512 + ip { + address { + prefix-list vyosV4 + } + } + } + } + rule 15 { + action permit + match { + as-path AS64512 + ipv6 { + address { + prefix-list hostrouteV6 + } + } + } + set { + community 64513:666 + } + } + rule 20 { + action permit + match { + as-path AS64512 + ipv6 { + address { + prefix-list vyosV6 + } + } + } + } + rule 100 { + action deny + } + } + route-map ImportRouteMap { + rule 10 { + action deny + match { + ip { + address { + prefix-list privateV4 + } + } + } + } + rule 15 { + action deny + match { + ipv6 { + address { + prefix-list privateV6 + } + } + } + } + rule 20 { + action deny + match { + ip { + address { + prefix-list vyosV4 + } + } + } + } + rule 30 { + action deny + match { + ipv6 { + address { + prefix-list vyosV6 + } + } + } + } + rule 40 { + action deny + match { + as-path AS64512 + } + } + rule 50 { + action permit + match { + as-path AS64513-AS64514 + } + set { + weight 10001 + } + } + rule 65535 { + action permit + } + } +} +protocols { + bgp 64500 { + address-family { + ipv4-unicast { + network 192.0.98.0/24 { + } + network 192.0.160.0/24 { + } + network 192.0.68.0/22 { + } + network 192.0.84.0/22 { + } + redistribute { + static { + route-map ExportRouteMap + } + } + } + ipv6-unicast { + network 2001:db8::/29 { + } + redistribute { + static { + route-map ExportRouteMap + } + } + } + } + maximum-paths { + ebgp 8 + ibgp 16 + } + neighbor 192.0.16.209 { + address-family { + ipv4-unicast { + route-map { + export ExportRouteMapAS64516 + import ImportRouteMap + } + } + } + remote-as 64501 + } + neighbor 192.0.192.6 { + address-family { + ipv4-unicast { + maximum-prefix 100 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64502 + } + neighbor 192.0.192.157 { + address-family { + ipv4-unicast { + maximum-prefix 350000 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64503 + } + neighbor 192.0.192.228 { + address-family { + ipv4-unicast { + maximum-prefix 10000 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64504 + } + neighbor 192.0.193.157 { + address-family { + ipv4-unicast { + maximum-prefix 350000 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64505 + } + neighbor 192.0.193.202 { + address-family { + ipv4-unicast { + maximum-prefix 10000 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64506 + } + neighbor 192.0.193.223 { + address-family { + ipv4-unicast { + maximum-prefix 10000 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64507 + } + neighbor 192.0.194.161 { + address-family { + ipv4-unicast { + maximum-prefix 10000 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64508 + } + neighbor 192.0.194.171 { + address-family { + ipv4-unicast { + maximum-prefix 10000 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64509 + } + neighbor 192.0.176.193 { + address-family { + ipv4-unicast { + route-map { + export ExportRouteMapAS64516 + import ImportRouteMap + } + } + } + remote-as 64510 + } + neighbor 192.0.52.12 { + address-family { + ipv4-unicast { + maximum-prefix 300 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64511 + } + neighbor 192.0.52.17 { + address-family { + ipv4-unicast { + maximum-prefix 75 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + password vyosvyos + remote-as 64512 + } + neighbor 192.0.52.24 { + address-family { + ipv4-unicast { + maximum-prefix 300 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64513 + } + neighbor 192.0.52.32 { + address-family { + ipv4-unicast { + maximum-prefix 50 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + password vyosfoooo + remote-as 64514 + } + neighbor 192.0.52.34 { + address-family { + ipv4-unicast { + maximum-prefix 10 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64515 + } + neighbor 192.0.52.46 { + address-family { + ipv4-unicast { + maximum-prefix 10 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64516 + } + neighbor 192.0.52.49 { + address-family { + ipv4-unicast { + maximum-prefix 75 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + password secret + remote-as 64517 + } + neighbor 192.0.52.74 { + address-family { + ipv4-unicast { + maximum-prefix 15000 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + password secretvyos + remote-as 64518 + } + neighbor 192.0.52.94 { + address-family { + ipv4-unicast { + maximum-prefix 250 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64519 + } + neighbor 192.0.52.100 { + address-family { + ipv4-unicast { + maximum-prefix 50 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64520 + } + neighbor 192.0.52.119 { + address-family { + ipv4-unicast { + maximum-prefix 30 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64521 + } + neighbor 192.0.52.165 { + address-family { + ipv4-unicast { + maximum-prefix 50 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64522 + } + neighbor 192.0.52.170 { + address-family { + ipv4-unicast { + maximum-prefix 150000 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64523 + } + neighbor 192.0.52.171 { + address-family { + ipv4-unicast { + maximum-prefix 10000 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64524 + } + neighbor 192.0.52.179 { + address-family { + ipv4-unicast { + maximum-prefix 20 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64525 + } + neighbor 192.0.52.189 { + address-family { + ipv4-unicast { + maximum-prefix 1000 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64526 + } + neighbor 192.0.52.210 { + address-family { + ipv4-unicast { + maximum-prefix 15 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64527 + } + neighbor 192.0.52.211 { + address-family { + ipv4-unicast { + maximum-prefix 15 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64528 + } + neighbor 192.0.52.251 { + address-family { + ipv4-unicast { + route-map { + export ExportRouteMap + import ImportRouteMap + } + weight 1010 + } + } + remote-as 64529 + } + neighbor 192.0.52.252 { + address-family { + ipv4-unicast { + route-map { + export ExportRouteMap + } + weight 1010 + } + } + remote-as 64530 + } + neighbor 192.0.52.253 { + address-family { + ipv4-unicast { + route-map { + export ExportRouteMapAS64515 + import ImportRouteMap + } + } + } + passive + remote-as 64531 + } + neighbor 192.0.68.3 { + address-family { + ipv4-unicast { + nexthop-self + soft-reconfiguration { + inbound + } + } + } + remote-as 64532 + update-source 192.0.68.2 + } + neighbor 2001:db8:838::1 { + address-family { + ipv6-unicast { + route-map { + export ExportRouteMapAS64516 + import ImportRouteMap + } + } + } + remote-as 64533 + } + neighbor 2001:db8:c::3 { + address-family { + ipv6-unicast { + nexthop-self + soft-reconfiguration { + inbound + } + } + } + remote-as 64534 + update-source 2001:db8:c::2 + } + neighbor 2001:db8:24::2e { + address-family { + ipv6-unicast { + maximum-prefix 5 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + password vyossecret + remote-as 64535 + } + neighbor 2001:db8:24::4a { + address-family { + ipv6-unicast { + maximum-prefix 1000 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64536 + } + neighbor 2001:db8:24::5e { + address-family { + ipv6-unicast { + maximum-prefix 200 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64537 + } + neighbor 2001:db8:24::11 { + address-family { + ipv6-unicast { + maximum-prefix 20 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64538 + } + neighbor 2001:db8:24::18 { + address-family { + ipv6-unicast { + maximum-prefix 300 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64539 + } + neighbor 2001:db8:24::20 { + address-family { + ipv6-unicast { + maximum-prefix 10 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64540 + } + neighbor 2001:db8:24::22 { + address-family { + ipv6-unicast { + maximum-prefix 5 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64541 + } + neighbor 2001:db8:24::31 { + address-family { + ipv6-unicast { + maximum-prefix 20 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64542 + } + neighbor 2001:db8:24::58 { + address-family { + ipv6-unicast { + maximum-prefix 15 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64543 + } + neighbor 2001:db8:24::64 { + address-family { + ipv6-unicast { + maximum-prefix 10 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + password geheim + remote-as 64544 + } + neighbor 2001:db8:24::a5 { + address-family { + ipv6-unicast { + maximum-prefix 10 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64545 + } + neighbor 2001:db8:24::aa { + address-family { + ipv6-unicast { + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64546 + } + neighbor 2001:db8:24::ab { + address-family { + ipv6-unicast { + maximum-prefix 1800 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64547 + } + neighbor 2001:db8:24::b0 { + address-family { + ipv6-unicast { + maximum-prefix 5 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + password secret123 + remote-as 64548 + } + parameters { + default { + no-ipv4-unicast + } + log-neighbor-changes + router-id 192.0.68.2 + } + } + static { + route 192.0.98.0/24 { + blackhole { + } + } + route 192.0.160.0/24 { + blackhole { + } + } + route 192.0.68.0/22 { + blackhole { + } + } + route 192.0.84.0/22 { + blackhole { + } + } + route6 2001:db8::/29 { + blackhole { + } + } + } +} +system { + config-management { + commit-revisions 100 + } + console { + device ttyS0 { + speed 115200 + } + } + flow-accounting { + disable-imt + interface eth0.4088 + interface eth0.4089 + netflow { + engine-id 1 + server 192.0.2.55 { + port 2055 + } + version 9 + } + syslog-facility daemon + } + host-name vyos + login { + user vyos { + authentication { + encrypted-password $6$2Ta6TWHd/U$NmrX0x9kexCimeOcYK1MfhMpITF9ELxHcaBU/znBq.X2ukQOj61fVI2UYP/xBzP4QtiTcdkgs7WOQMHWsRymO/ + plaintext-password "" + } + } + } + name-server 2001:db8::1 + name-server 2001:db8::2 + name-server 192.0.2.1 + name-server 192.0.2.2 + ntp { + server 0.pool.ntp.org { + } + server 1.pool.ntp.org { + } + server 2.pool.ntp.org { + } + } + syslog { + global { + facility all { + level all + } + preserve-fqdn + } + } + time-zone Europe/Zurich +} +zone-policy { + zone local { + default-action drop + from management { + firewall { + ipv6-name management-to-local-6 + name management-to-local-4 + } + } + from peers { + firewall { + ipv6-name peers-to-local-6 + name peers-to-local-4 + } + } + from servers { + firewall { + ipv6-name servers-to-local-6 + name servers-to-local-4 + } + } + local-zone + } + zone management { + default-action reject + from peers { + firewall { + ipv6-name peers-to-management-6 + name peers-to-management-4 + } + } + from servers { + firewall { + ipv6-name servers-to-management-6 + name servers-to-management-4 + } + } + interface eth0 + } + zone peers { + default-action reject + from management { + firewall { + ipv6-name management-to-peers-6 + name management-to-peers-4 + } + } + from servers { + firewall { + ipv6-name servers-to-peers-6 + name servers-to-peers-4 + } + } + interface eth0.4088 + interface eth0.4089 + interface eth0.11 + interface eth0.838 + interface eth0.886 + } + zone servers { + default-action reject + from management { + firewall { + ipv6-name management-to-servers-6 + name management-to-servers-4 + } + } + from peers { + firewall { + ipv6-name peers-to-servers-6 + name peers-to-servers-4 + } + } + interface eth0.1001 + interface eth0.105 + interface eth0.102 + interface eth0.1019 + interface eth0.1014 + interface eth0.1020 + interface eth0.1018 + interface eth0.1013 + interface eth0.1012 + interface eth0.1011 + interface eth0.1010 + interface eth0.1009 + interface eth0.1006 + interface eth0.1005 + interface eth0.1017 + interface eth0.1016 + interface eth0.1002 + interface eth0.1015 + interface eth0.1003 + interface eth0.1004 + interface eth0.1007 + interface eth0.1008 + } +} + + +/* 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.5 */ diff --git a/smoketest/configs/dialup-router-complex b/smoketest/configs/dialup-router-complex new file mode 100644 index 000000000..fef79ea56 --- /dev/null +++ b/smoketest/configs/dialup-router-complex @@ -0,0 +1,1662 @@ +firewall { + all-ping enable + broadcast-ping disable + config-trap disable + group { + address-group MEDIA-STREAMING-CLIENTS { + address 172.16.35.241 + address 172.16.35.242 + address 172.16.35.243 + } + address-group DMZ-WEBSERVER { + address 172.16.36.10 + address 172.16.36.40 + address 172.16.36.20 + } + address-group DMZ-RDP-SERVER { + address 172.16.33.40 + } + address-group DOMAIN-CONTROLLER { + address 172.16.100.10 + address 172.16.100.20 + } + address-group AUDIO-STREAM { + address 172.16.35.20 + address 172.16.35.21 + address 172.16.35.22 + address 172.16.35.23 + } + ipv6-network-group LOCAL-ADDRESSES { + network ff02::/64 + network fe80::/10 + } + network-group SSH-IN-ALLOW { + network 192.0.2.0/24 + network 10.0.0.0/8 + network 172.16.0.0/12 + network 192.168.0.0/16 + } + port-group SMART-TV-PORTS { + port 5005-5006 + port 80 + port 443 + port 3722 + } + } + ipv6-name ALLOW-ALL-6 { + default-action accept + } + ipv6-name ALLOW-BASIC-6 { + default-action drop + enable-default-log + rule 1 { + action accept + state { + established enable + related enable + } + } + rule 2 { + action drop + state { + invalid enable + } + } + rule 10 { + action accept + protocol icmpv6 + } + } + ipv6-name ALLOW-ESTABLISHED-6 { + default-action drop + enable-default-log + rule 1 { + action accept + state { + established enable + related enable + } + } + rule 2 { + action drop + state { + invalid enable + } + } + rule 10 { + action accept + destination { + group { + network-group LOCAL-ADDRESSES + } + } + protocol icmpv6 + source { + address fe80::/10 + } + } + rule 20 { + action accept + icmpv6 { + type echo-request + } + protocol icmpv6 + } + rule 21 { + action accept + icmpv6 { + type destination-unreachable + } + protocol icmpv6 + } + rule 22 { + action accept + icmpv6 { + type packet-too-big + } + protocol icmpv6 + } + rule 23 { + action accept + icmpv6 { + type time-exceeded + } + protocol icmpv6 + } + rule 24 { + action accept + icmpv6 { + type parameter-problem + } + protocol icmpv6 + } + } + ipv6-name WAN-LOCAL-6 { + default-action drop + enable-default-log + rule 1 { + action accept + state { + established enable + related enable + } + } + rule 2 { + action drop + state { + invalid enable + } + } + rule 10 { + action accept + destination { + address ff02::/64 + } + protocol icmpv6 + source { + address fe80::/10 + } + } + rule 50 { + action accept + description DHCPv6 + destination { + address fe80::/10 + port 546 + } + protocol udp + source { + address fe80::/10 + port 547 + } + } + } + ipv6-receive-redirects disable + ipv6-src-route disable + ip-src-route disable + log-martians enable + name DMZ-GUEST { + default-action drop + enable-default-log + rule 1 { + action accept + state { + established enable + related enable + } + } + rule 2 { + action drop + log enable + state { + invalid enable + } + } + } + name DMZ-LAN { + default-action drop + enable-default-log + rule 1 { + action accept + state { + established enable + related enable + } + } + rule 2 { + action drop + log enable + state { + invalid enable + } + } + rule 100 { + action accept + description "NTP and LDAP to AD DC" + destination { + group { + address-group DOMAIN-CONTROLLER + } + port 123,389,636 + } + protocol tcp_udp + } + rule 300 { + action accept + destination { + group { + address-group DMZ-RDP-SERVER + } + port 3389 + } + protocol tcp_udp + source { + address 172.16.36.20 + } + } + } + name DMZ-LOCAL { + default-action drop + enable-default-log + rule 1 { + action accept + state { + established enable + related enable + } + } + rule 2 { + action drop + log enable + state { + invalid enable + } + } + rule 50 { + action accept + destination { + address 172.16.254.30 + port 53 + } + protocol tcp_udp + } + rule 123 { + action accept + destination { + port 123 + } + protocol udp + } + } + name DMZ-WAN { + default-action accept + } + name GUEST-DMZ { + default-action drop + enable-default-log + rule 1 { + action accept + state { + established enable + related enable + } + } + rule 2 { + action drop + log enable + state { + invalid enable + } + } + rule 100 { + action accept + destination { + port 80,443 + } + protocol tcp + } + } + name GUEST-IOT { + default-action drop + enable-default-log + rule 1 { + action accept + state { + established enable + related enable + } + } + rule 2 { + action drop + log enable + state { + invalid enable + } + } + rule 100 { + action accept + description "MEDIA-STREAMING-CLIENTS Devices to GUEST" + destination { + group { + address-group MEDIA-STREAMING-CLIENTS + } + } + protocol tcp_udp + } + rule 110 { + action accept + description "AUDIO-STREAM Devices to GUEST" + destination { + group { + address-group AUDIO-STREAM + } + } + protocol tcp_udp + } + rule 200 { + action accept + description "MCAST relay" + destination { + address 224.0.0.251 + port 5353 + } + protocol udp + } + rule 300 { + action accept + description "BCAST relay" + destination { + port 1900 + } + protocol udp + } + } + name GUEST-LAN { + default-action drop + enable-default-log + rule 1 { + action accept + state { + established enable + related enable + } + } + rule 2 { + action drop + log enable + state { + invalid enable + } + } + } + name GUEST-LOCAL { + default-action drop + enable-default-log + rule 1 { + action accept + state { + established enable + related enable + } + } + rule 2 { + action drop + log enable + state { + invalid enable + } + } + rule 10 { + action accept + description DNS + destination { + address 172.31.0.254 + port 53 + } + protocol tcp_udp + } + rule 11 { + action accept + description DHCP + destination { + port 67 + } + protocol udp + } + rule 15 { + action accept + destination { + address 172.31.0.254 + } + protocol icmp + } + rule 200 { + action accept + description "MCAST relay" + destination { + address 224.0.0.251 + port 5353 + } + protocol udp + } + rule 210 { + action accept + description "AUDIO-STREAM Broadcast" + destination { + port 1900 + } + protocol udp + } + } + name GUEST-WAN { + default-action drop + enable-default-log + rule 1 { + action accept + state { + established enable + related enable + } + } + rule 2 { + action drop + log enable + state { + invalid enable + } + } + rule 25 { + action accept + description SMTP + destination { + port 25,587 + } + protocol tcp + } + rule 53 { + action accept + destination { + port 53 + } + protocol tcp_udp + } + rule 60 { + action accept + source { + address 172.31.0.200 + } + } + rule 80 { + action accept + source { + address 172.31.0.200 + } + } + rule 100 { + action accept + protocol icmp + } + rule 110 { + action accept + description POP3 + destination { + port 110,995 + } + protocol tcp + } + rule 123 { + action accept + description "NTP Client" + destination { + port 123 + } + protocol udp + } + rule 143 { + action accept + description IMAP + destination { + port 143,993 + } + protocol tcp + } + rule 200 { + action accept + destination { + port 80,443 + } + protocol tcp + } + rule 500 { + action accept + description "L2TP IPSec" + destination { + port 500,4500 + } + protocol udp + } + rule 600 { + action accept + destination { + port 5222-5224 + } + protocol tcp + } + rule 601 { + action accept + destination { + port 3478-3497,4500,16384-16387,16393-16402 + } + protocol udp + } + rule 1000 { + action accept + source { + address 172.31.0.184 + } + } + } + name IOT-GUEST { + default-action drop + enable-default-log + rule 1 { + action accept + state { + established enable + related enable + } + } + rule 2 { + action drop + log enable + state { + invalid enable + } + } + rule 100 { + action accept + description "MEDIA-STREAMING-CLIENTS Devices to IOT" + protocol tcp_udp + source { + group { + address-group MEDIA-STREAMING-CLIENTS + } + } + } + rule 110 { + action accept + description "AUDIO-STREAM Devices to IOT" + protocol tcp_udp + source { + group { + address-group AUDIO-STREAM + } + } + } + rule 200 { + action accept + description "MCAST relay" + destination { + address 224.0.0.251 + port 5353 + } + protocol udp + } + rule 300 { + action accept + description "BCAST relay" + destination { + port 1900 + } + protocol udp + } + } + name IOT-LAN { + default-action drop + enable-default-log + rule 1 { + action accept + state { + established enable + related enable + } + } + rule 2 { + action drop + log enable + state { + invalid enable + } + } + rule 100 { + action accept + description "AppleTV to LAN" + destination { + group { + port-group SMART-TV-PORTS + } + } + protocol tcp_udp + source { + group { + address-group MEDIA-STREAMING-CLIENTS + } + } + } + rule 110 { + action accept + description "AUDIO-STREAM Devices to LAN" + protocol tcp_udp + source { + group { + address-group AUDIO-STREAM + } + } + } + } + name IOT-LOCAL { + default-action drop + enable-default-log + rule 1 { + action accept + state { + established enable + related enable + } + } + rule 2 { + action drop + log enable + state { + invalid enable + } + } + rule 10 { + action accept + description DNS + destination { + address 172.16.254.30 + port 53 + } + protocol tcp_udp + } + rule 11 { + action accept + description DHCP + destination { + port 67 + } + protocol udp + } + rule 15 { + action accept + destination { + address 172.16.35.254 + } + protocol icmp + } + rule 200 { + action accept + description "MCAST relay" + destination { + address 224.0.0.251 + port 5353 + } + protocol udp + } + rule 201 { + action accept + description "MCAST relay" + destination { + address 172.16.35.254 + port 5353 + } + protocol udp + } + rule 210 { + action accept + description "AUDIO-STREAM Broadcast" + destination { + port 1900,1902,6969 + } + protocol udp + } + } + name IOT-WAN { + default-action accept + } + name LAN-DMZ { + default-action drop + enable-default-log + rule 1 { + action accept + state { + established enable + related enable + } + } + rule 2 { + action drop + log enable + state { + invalid enable + } + } + rule 22 { + action accept + description "SSH into DMZ" + destination { + port 22 + } + protocol tcp + } + rule 100 { + action accept + destination { + group { + address-group DMZ-WEBSERVER + } + port 22,80,443 + } + protocol tcp + } + } + name LAN-GUEST { + default-action drop + enable-default-log + rule 1 { + action accept + state { + established enable + related enable + } + } + rule 2 { + action drop + log enable + state { + invalid enable + } + } + } + name LAN-IOT { + default-action accept + } + name LAN-LOCAL { + default-action accept + } + name LAN-WAN { + default-action accept + } + name LOCAL-DMZ { + default-action drop + enable-default-log + rule 1 { + action accept + state { + established enable + related enable + } + } + rule 2 { + action drop + log enable + state { + invalid enable + } + } + } + name LOCAL-GUEST { + default-action drop + enable-default-log + rule 1 { + action accept + state { + established enable + related enable + } + } + rule 2 { + action drop + log enable + state { + invalid enable + } + } + rule 5 { + action accept + protocol icmp + } + rule 200 { + action accept + description "MCAST relay" + destination { + address 224.0.0.251 + port 5353 + } + protocol udp + } + rule 300 { + action accept + description "BCAST relay" + destination { + port 1900 + } + protocol udp + } + } + name LOCAL-IOT { + default-action drop + enable-default-log + rule 1 { + action accept + state { + established enable + related enable + } + } + rule 2 { + action drop + log enable + state { + invalid enable + } + } + rule 5 { + action accept + protocol icmp + } + rule 200 { + action accept + description "MCAST relay" + destination { + address 224.0.0.251 + port 5353 + } + protocol udp + } + rule 300 { + action accept + description "BCAST relay" + destination { + port 1900,6969 + } + protocol udp + } + } + name LOCAL-LAN { + default-action accept + } + name LOCAL-WAN { + default-action drop + enable-default-log + rule 1 { + action accept + state { + established enable + related enable + } + } + rule 2 { + action drop + log enable + state { + invalid enable + } + } + rule 10 { + action accept + protocol icmp + } + rule 50 { + action accept + description DNS + destination { + port 53 + } + protocol tcp_udp + } + rule 80 { + action accept + destination { + port 80,443 + } + protocol tcp + } + rule 123 { + action accept + description NTP + destination { + port 123 + } + protocol udp + } + } + name WAN-DMZ { + default-action drop + enable-default-log + rule 1 { + action accept + state { + established enable + related enable + } + } + rule 2 { + action drop + log enable + state { + invalid enable + } + } + rule 100 { + action accept + destination { + address 172.16.36.10 + port 80,443 + } + protocol tcp + } + } + name WAN-GUEST { + default-action drop + enable-default-log + rule 1 { + action accept + state { + established enable + related enable + } + } + rule 2 { + action drop + log enable + state { + invalid enable + } + } + rule 1000 { + action accept + destination { + address 172.31.0.184 + } + } + rule 8000 { + action accept + destination { + address 172.31.0.200 + port 10000 + } + protocol udp + } + } + name WAN-IOT { + default-action drop + enable-default-log + rule 1 { + action accept + state { + established enable + related enable + } + } + rule 2 { + action drop + log enable + state { + invalid enable + } + } + } + name WAN-LAN { + default-action drop + enable-default-log + rule 1 { + action accept + state { + established enable + related enable + } + } + rule 2 { + action drop + log enable + state { + invalid enable + } + } + rule 1000 { + action accept + destination { + address 172.16.33.40 + port 3389 + } + protocol tcp + source { + group { + network-group SSH-IN-ALLOW + } + } + } + } + name WAN-LOCAL { + default-action drop + enable-default-log + rule 1 { + action accept + state { + established enable + related enable + } + } + rule 2 { + action drop + log enable + state { + invalid enable + } + } + rule 22 { + action accept + destination { + port 22 + } + protocol tcp + source { + group { + network-group SSH-IN-ALLOW + } + } + } + } + options { + interface pppoe0 { + adjust-mss 1452 + adjust-mss6 1432 + } + } + receive-redirects disable + send-redirects enable + source-validation disable + syn-cookies enable + twa-hazards-protection disable +} +interfaces { + dummy dum0 { + address 172.16.254.30/32 + } + ethernet eth0 { + duplex auto + speed auto + vif 5 { + address 172.16.37.254/24 + } + vif 10 { + address 172.16.33.254/24 + } + vif 20 { + address 172.31.0.254/24 + } + vif 35 { + address 172.16.35.254/24 + } + vif 50 { + address 172.16.36.254/24 + } + vif 100 { + address 172.16.100.254/24 + } + vif 201 { + address 172.18.201.254/24 + } + vif 202 { + address 172.18.202.254/24 + } + vif 203 { + address 172.18.203.254/24 + } + vif 204 { + address 172.18.204.254/24 + } + } + ethernet eth1 { + vif 7 { + description FTTH-PPPoE + } + } + loopback lo { + address 172.16.254.30/32 + } + pppoe pppoe0 { + authentication { + password vyos + user vyos + } + default-route auto + description "FTTH 100/50MBit" + dhcpv6-options { + pd 0 { + interface eth0.10 { + address 1 + sla-id 10 + } + interface eth0.20 { + address 1 + sla-id 20 + } + length 56 + } + } + ipv6 { + address { + autoconf + } + } + mtu 1492 + no-peer-dns + source-interface eth1.7 + } +} +nat { + destination { + rule 100 { + description HTTP(S) + destination { + port 80,443 + } + inbound-interface pppoe0 + log + protocol tcp + translation { + address 172.16.36.10 + } + } + rule 1000 { + destination { + port 3389 + } + disable + inbound-interface pppoe0 + protocol tcp + translation { + address 172.16.33.40 + } + } + rule 8000 { + destination { + port 10000 + } + inbound-interface pppoe0 + log + protocol udp + translation { + address 172.31.0.200 + } + } + } + source { + rule 100 { + log + outbound-interface pppoe0 + source { + address 172.16.32.0/19 + } + translation { + address masquerade + } + } + rule 200 { + outbound-interface pppoe0 + source { + address 172.16.100.0/24 + } + translation { + address masquerade + } + } + rule 300 { + outbound-interface pppoe0 + source { + address 172.31.0.0/24 + } + translation { + address masquerade + } + } + rule 400 { + outbound-interface pppoe0 + source { + address 172.18.200.0/21 + } + translation { + address masquerade + } + } + } +} +protocols { + static { + interface-route6 2000::/3 { + next-hop-interface pppoe0 { + } + } + route 10.0.0.0/8 { + blackhole { + distance 254 + } + } + route 169.254.0.0/16 { + blackhole { + distance 254 + } + } + route 172.16.0.0/12 { + blackhole { + distance 254 + } + } + route 192.168.0.0/16 { + blackhole { + distance 254 + } + } + } +} +service { + dhcp-server { + shared-network-name BACKBONE { + authoritative + subnet 172.16.37.0/24 { + default-router 172.16.37.254 + dns-server 172.16.254.30 + domain-name vyos.net + domain-search vyos.net + lease 86400 + ntp-server 172.16.254.30 + range 0 { + start 172.16.37.120 + stop 172.16.37.149 + } + static-mapping AP1.wue3 { + ip-address 172.16.37.231 + mac-address 18:e8:29:6c:c3:a5 + } + } + } + shared-network-name GUEST { + authoritative + subnet 172.31.0.0/24 { + default-router 172.31.0.254 + dns-server 172.31.0.254 + domain-name vyos.net + domain-search vyos.net + lease 86400 + range 0 { + start 172.31.0.100 + stop 172.31.0.199 + } + static-mapping host01 { + ip-address 172.31.0.200 + mac-address 00:50:00:00:00:01 + } + static-mapping host02 { + ip-address 172.31.0.184 + mac-address 00:50:00:00:00:02 + } + } + } + shared-network-name IOT { + authoritative + subnet 172.16.35.0/24 { + default-router 172.16.35.254 + dns-server 172.16.254.30 + domain-name vyos.net + domain-search vyos.net + lease 86400 + ntp-server 172.16.254.30 + range 0 { + start 172.16.35.101 + stop 172.16.35.149 + } + } + } + shared-network-name LAN { + authoritative + subnet 172.16.33.0/24 { + default-router 172.16.33.254 + dns-server 172.16.254.30 + domain-name vyos.net + domain-search vyos.net + lease 86400 + ntp-server 172.16.254.30 + range 0 { + start 172.16.33.100 + stop 172.16.33.189 + } + } + } + } + dns { + forwarding { + allow-from 172.16.0.0/12 + cache-size 0 + domain 16.172.in-addr.arpa { + addnta + recursion-desired + server 172.16.100.10 + server 172.16.100.20 + server 172.16.110.30 + } + domain 18.172.in-addr.arpa { + addnta + recursion-desired + server 172.16.100.10 + server 172.16.100.20 + server 172.16.110.30 + } + domain vyos.net { + addnta + recursion-desired + server 172.16.100.20 + server 172.16.100.10 + server 172.16.110.30 + } + ignore-hosts-file + listen-address 172.16.254.30 + listen-address 172.31.0.254 + negative-ttl 60 + } + } + lldp { + legacy-protocols { + cdp + } + snmp { + enable + } + } + mdns { + repeater { + interface eth0.35 + interface eth0.10 + } + } + router-advert { + interface eth0.10 { + prefix ::/64 { + preferred-lifetime 2700 + valid-lifetime 5400 + } + } + interface eth0.20 { + prefix ::/64 { + preferred-lifetime 2700 + valid-lifetime 5400 + } + } + } + snmp { + community fooBar { + authorization ro + network 172.16.100.0/24 + } + contact "VyOS maintainers and contributors <maintainers@vyos.io>" + listen-address 172.16.254.30 { + port 161 + } + location "The Internet" + } + ssh { + disable-host-validation + port 22 + } +} +system { + config-management { + commit-revisions 200 + } + conntrack { + expect-table-size 2048 + hash-size 32768 + modules { + sip { + disable + } + } + table-size 262144 + timeout { + icmp 30 + other 600 + udp { + other 300 + stream 300 + } + } + } + console { + device ttyS0 { + speed 115200 + } + } + domain-name vyos.net + host-name vyos + login { + user vyos { + authentication { + encrypted-password $6$2Ta6TWHd/U$NmrX0x9kexCimeOcYK1MfhMpITF9ELxHcaBU/znBq.X2ukQOj61fVI2UYP/xBzP4QtiTcdkgs7WOQMHWsRymO/ + plaintext-password "" + } + } + } + name-server 172.16.254.30 + ntp { + allow-clients { + address 172.16.0.0/12 + } + server 0.pool.ntp.org { + } + server 1.pool.ntp.org { + } + server 2.pool.ntp.org { + } + } + option { + ctrl-alt-delete ignore + reboot-on-panic + startup-beep + } + syslog { + global { + facility all { + level debug + } + facility protocols { + level debug + } + } + host 172.16.100.1 { + facility all { + level warning + } + } + } + time-zone Europe/Berlin +} +traffic-policy { + shaper QoS { + bandwidth 50mbit + default { + bandwidth 100% + burst 15k + queue-limit 1000 + queue-type fq-codel + } + } +} +zone-policy { + zone DMZ { + default-action drop + from GUEST { + firewall { + name GUEST-DMZ + } + } + from LAN { + firewall { + name LAN-DMZ + } + } + from LOCAL { + firewall { + name LOCAL-DMZ + } + } + from WAN { + firewall { + name WAN-DMZ + } + } + interface eth0.50 + } + zone GUEST { + default-action drop + from DMZ { + firewall { + name DMZ-GUEST + } + } + from IOT { + firewall { + name IOT-GUEST + } + } + from LAN { + firewall { + name LAN-GUEST + } + } + from LOCAL { + firewall { + ipv6-name ALLOW-ALL-6 + name LOCAL-GUEST + } + } + from WAN { + firewall { + ipv6-name ALLOW-ESTABLISHED-6 + name WAN-GUEST + } + } + interface eth0.20 + } + zone IOT { + default-action drop + from GUEST { + firewall { + name GUEST-IOT + } + } + from LAN { + firewall { + name LAN-IOT + } + } + from LOCAL { + firewall { + name LOCAL-IOT + } + } + from WAN { + firewall { + name WAN-IOT + } + } + interface eth0.35 + } + zone LAN { + default-action drop + from DMZ { + firewall { + name DMZ-LAN + } + } + from GUEST { + firewall { + name GUEST-LAN + } + } + from IOT { + firewall { + name IOT-LAN + } + } + from LOCAL { + firewall { + ipv6-name ALLOW-ALL-6 + name LOCAL-LAN + } + } + from WAN { + firewall { + ipv6-name ALLOW-ESTABLISHED-6 + name WAN-LAN + } + } + interface eth0.5 + interface eth0.10 + interface eth0.100 + interface eth0.201 + interface eth0.202 + interface eth0.203 + interface eth0.204 + } + zone LOCAL { + default-action drop + from DMZ { + firewall { + name DMZ-LOCAL + } + } + from GUEST { + firewall { + ipv6-name ALLOW-ESTABLISHED-6 + name GUEST-LOCAL + } + } + from IOT { + firewall { + name IOT-LOCAL + } + } + from LAN { + firewall { + ipv6-name ALLOW-ALL-6 + name LAN-LOCAL + } + } + from WAN { + firewall { + ipv6-name WAN-LOCAL-6 + name WAN-LOCAL + } + } + local-zone + } + zone WAN { + default-action drop + from DMZ { + firewall { + name DMZ-WAN + } + } + from GUEST { + firewall { + ipv6-name ALLOW-ALL-6 + name GUEST-WAN + } + } + from IOT { + firewall { + name IOT-WAN + } + } + from LAN { + firewall { + ipv6-name ALLOW-ALL-6 + name LAN-WAN + } + } + from LOCAL { + firewall { + ipv6-name ALLOW-ALL-6 + name LOCAL-WAN + } + } + interface pppoe0 + } +} + + +// Warning: Do not remove the following line. +// vyos-config-version: "broadcast-relay@1:cluster@1:config-management@1:conntrack@1:conntrack-sync@1:dhcp-relay@2:dhcp-server@5:dhcpv6-server@1:dns-forwarding@3:firewall@5:https@2:interfaces@18:ipoe-server@1:ipsec@5:l2tp@3:lldp@1:mdns@1:nat@5:ntp@1:pppoe-server@5:pptp@2:qos@1:quagga@6:salt@1:snmp@2:ssh@2:sstp@3:system@20:vrrp@2:vyos-accel-ppp@2:wanloadbalance@3:webproxy@2:zone-policy@1" +// Release version: 1.3-beta-202101091250 diff --git a/smoketest/configs/dialup-router-medium-vpn b/smoketest/configs/dialup-router-medium-vpn index dfb3d9621..af7c075e4 100644 --- a/smoketest/configs/dialup-router-medium-vpn +++ b/smoketest/configs/dialup-router-medium-vpn @@ -624,6 +624,7 @@ system { } } name-server 192.168.0.1 + name-servers-dhcp pppoe0 ntp { allow-clients { address 192.168.0.0/16 diff --git a/smoketest/configs/isis-small b/smoketest/configs/isis-small new file mode 100644 index 000000000..247ae32b5 --- /dev/null +++ b/smoketest/configs/isis-small @@ -0,0 +1,104 @@ +interfaces { + dummy dum0 { + address 203.0.113.1/24 + } + ethernet eth0 { + duplex auto + speed auto + } + ethernet eth1 { + address 192.0.2.1/24 + duplex auto + speed auto + } + ethernet eth2 { + duplex auto + speed auto + } + ethernet eth3 { + duplex auto + speed auto + } +} +policy { + prefix-list EXPORT-ISIS { + rule 10 { + action permit + prefix 203.0.113.0/24 + } + } + route-map EXPORT-ISIS { + rule 10 { + action permit + match { + ip { + address { + prefix-list EXPORT-ISIS + } + } + } + } + } +} +protocols { + isis FOO { + interface eth1 { + bfd + } + net 49.0001.1921.6800.1002.00 + redistribute { + ipv4 { + connected { + level-2 { + route-map EXPORT-ISIS + } + } + } + } + } +} +system { + config-management { + commit-revisions 200 + } + console { + device ttyS0 { + speed 115200 + } + } + domain-name vyos.io + host-name vyos + login { + user vyos { + authentication { + encrypted-password $6$2Ta6TWHd/U$NmrX0x9kexCimeOcYK1MfhMpITF9ELxHcaBU/znBq.X2ukQOj61fVI2UYP/xBzP4QtiTcdkgs7WOQMHWsRymO/ + plaintext-password "" + } + level admin + } + } + ntp { + server 0.pool.ntp.org { + } + server 1.pool.ntp.org { + } + server 2.pool.ntp.org { + } + } + syslog { + global { + facility all { + level info + } + facility protocols { + level debug + } + } + } + time-zone Europe/Berlin +} + + +// Warning: Do not remove the following line. +// vyos-config-version: "broadcast-relay@1:cluster@1:config-management@1:conntrack@1:conntrack-sync@1:dhcp-relay@2:dhcp-server@5:dhcpv6-server@1:dns-forwarding@3:firewall@5:https@2:interfaces@18:ipoe-server@1:ipsec@5:l2tp@3:lldp@1:mdns@1:nat@5:ntp@1:pppoe-server@5:pptp@2:qos@1:quagga@7:rpki@1:salt@1:snmp@2:ssh@2:sstp@3:system@20:vrrp@2:vyos-accel-ppp@2:wanloadbalance@3:webproxy@2:zone-policy@1" +// Release version: 1.3.0-rc1 diff --git a/smoketest/configs/tunnel-broker b/smoketest/configs/tunnel-broker new file mode 100644 index 000000000..d4a5c2dfc --- /dev/null +++ b/smoketest/configs/tunnel-broker @@ -0,0 +1,135 @@ +interfaces { + dummy dum0 { + address 192.0.2.0/32 + } + dummy dum1 { + address 192.0.2.1/32 + } + dummy dum2 { + address 192.0.2.2/32 + } + dummy dum3 { + address 192.0.2.3/32 + } + dummy dum4 { + address 192.0.2.4/32 + } + ethernet eth0 { + duplex auto + smp-affinity auto + speed auto + address 172.18.202.10/24 + } + l2tpv3 l2tpeth10 { + destination-port 5010 + encapsulation ip + local-ip 172.18.202.10 + peer-session-id 110 + peer-tunnel-id 10 + remote-ip 172.18.202.110 + session-id 110 + source-port 5010 + tunnel-id 10 + } + l2tpv3 l2tpeth20 { + destination-port 5020 + encapsulation ip + local-ip 172.18.202.10 + peer-session-id 120 + peer-tunnel-id 20 + remote-ip 172.18.202.120 + session-id 120 + source-port 5020 + tunnel-id 20 + } + l2tpv3 l2tpeth30 { + destination-port 5030 + encapsulation ip + local-ip 172.18.202.10 + peer-session-id 130 + peer-tunnel-id 30 + remote-ip 172.18.202.130 + session-id 130 + source-port 5030 + tunnel-id 30 + } + tunnel tun100 { + address 172.16.0.1/30 + encapsulation gre-bridge + local-ip 192.0.2.0 + remote-ip 192.0.2.100 + } + tunnel tun200 { + address 172.16.0.5/30 + encapsulation gre + local-ip 192.0.2.1 + remote-ip 192.0.2.101 + } + tunnel tun300 { + address 172.16.0.9/30 + encapsulation ipip + local-ip 192.0.2.2 + remote-ip 192.0.2.102 + } + tunnel tun400 { + address 172.16.0.13/30 + encapsulation gre-bridge + local-ip 192.0.2.3 + remote-ip 192.0.2.103 + } + tunnel tun500 { + address 172.16.0.17/30 + encapsulation gre + local-ip 192.0.2.4 + remote-ip 192.0.2.104 + } +} +protocols { + static { + route 0.0.0.0/0 { + next-hop 172.18.202.254 { + } + } + } +} +system { + config-management { + commit-revisions 100 + } + console { + device ttyS0 { + speed 115200 + } + } + host-name vyos + login { + user vyos { + authentication { + encrypted-password $6$O5gJRlDYQpj$MtrCV9lxMnZPMbcxlU7.FI793MImNHznxGoMFgm3Q6QP3vfKJyOSRCt3Ka/GzFQyW1yZS4NS616NLHaIPPFHc0 + plaintext-password "" + } + } + } + ntp { + server 0.pool.ntp.org { + } + server 1.pool.ntp.org { + } + server 2.pool.ntp.org { + } + } + 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@10:vrrp@2:wanloadbalance@3:webgui@1:webproxy@1:webproxy@2:zone-policy@1" === */ +/* Release version: 1.2.6-S1 */ diff --git a/smoketest/configs/vrf-basic b/smoketest/configs/vrf-basic new file mode 100644 index 000000000..ded33f683 --- /dev/null +++ b/smoketest/configs/vrf-basic @@ -0,0 +1,231 @@ +interfaces { + ethernet eth0 { + address 192.0.2.1/24 + } + ethernet eth1 { + duplex auto + speed auto + vrf green + } + ethernet eth2 { + vrf red + } +} +protocols { + static { + route 0.0.0.0/0 { + next-hop 192.0.2.254 { + distance 10 + } + } + table 10 { + interface-route 1.0.0.0/8 { + next-hop-interface eth0 { + distance 20 + } + } + interface-route 2.0.0.0/8 { + next-hop-interface eth0 { + distance 20 + } + } + interface-route 3.0.0.0/8 { + next-hop-interface eth0 { + distance 20 + } + } + } + table 20 { + interface-route 4.0.0.0/8 { + next-hop-interface eth0 { + distance 20 + } + } + interface-route 5.0.0.0/8 { + next-hop-interface eth0 { + distance 50 + } + } + interface-route 6.0.0.0/8 { + next-hop-interface eth0 { + distance 60 + } + } + interface-route6 2001:db8:100::/40 { + next-hop-interface eth1 { + distance 20 + } + } + interface-route6 2001:db8::/40 { + next-hop-interface eth1 { + distance 10 + } + } + route 11.0.0.0/8 { + next-hop 1.1.1.1 { + next-hop-interface eth0 + } + } + route 12.0.0.0/8 { + next-hop 1.1.1.1 { + next-hop-interface eth0 + } + } + route 13.0.0.0/8 { + next-hop 1.1.1.1 { + next-hop-interface eth0 + } + } + } + table 30 { + interface-route6 2001:db8:200::/40 { + next-hop-interface eth1 { + distance 20 + } + } + route 14.0.0.0/8 { + next-hop 2.2.1.1 { + next-hop-interface eth1 + } + } + route 15.0.0.0/8 { + next-hop 2.2.1.1 { + next-hop-interface eth1 + } + } + } + } + vrf green { + static { + interface-route 100.0.0.0/8 { + next-hop-interface eth0 { + distance 200 + next-hop-vrf default + } + } + interface-route 101.0.0.0/8 { + next-hop-interface eth0 { + next-hop-vrf default + } + next-hop-interface eth1 { + } + } + interface-route6 2001:db8:300::/40 { + next-hop-interface eth1 { + distance 20 + next-hop-vrf default + } + } + route 20.0.0.0/8 { + next-hop 1.1.1.1 { + next-hop-interface eth1 + next-hop-vrf default + } + } + route 21.0.0.0/8 { + next-hop 2.2.1.1 { + next-hop-interface eth1 + next-hop-vrf default + } + } + route6 2001:db8:100::/40 { + next-hop fe80::1 { + interface eth0 + next-hop-vrf default + } + } + } + } + vrf red { + static { + interface-route 103.0.0.0/8 { + next-hop-interface eth0 { + distance 201 + next-hop-vrf default + } + } + interface-route 104.0.0.0/8 { + next-hop-interface eth0 { + next-hop-vrf default + } + next-hop-interface eth1 { + next-hop-vrf default + } + } + interface-route6 2001:db8:400::/40 { + next-hop-interface eth1 { + distance 24 + next-hop-vrf default + } + } + route 30.0.0.0/8 { + next-hop 1.1.1.1 { + next-hop-interface eth1 + } + } + route 40.0.0.0/8 { + next-hop 2.2.1.1 { + next-hop-interface eth1 + next-hop-vrf default + } + } + route6 2001:db8:100::/40 { + next-hop fe80::1 { + interface eth0 + next-hop-vrf default + } + } + } + } +} +system { + config-management { + commit-revisions 100 + } + console { + device ttyS0 { + speed 115200 + } + } + host-name vyos + login { + user vyos { + authentication { + encrypted-password $6$O5gJRlDYQpj$MtrCV9lxMnZPMbcxlU7.FI793MImNHznxGoMFgm3Q6QP3vfKJyOSRCt3Ka/GzFQyW1yZS4NS616NLHaIPPFHc0 + plaintext-password "" + } + } + } + nt + ntp { + server 0.pool.ntp.org { + } + server 1.pool.ntp.org { + } + server 2.pool.ntp.org { + } + } + syslog { + global { + facility all { + level info + } + facility protocols { + level debug + } + } + } + time-zone Europe/Berlin +} +vrf { + name green { + table 1000 + } + name red { + table 2000 + } +} + +// Warning: Do not remove the following line. +// vyos-config-version: "broadcast-relay@1:cluster@1:config-management@1:conntrack@1:conntrack-sync@1:dhcp-relay@2:dhcp-server@5:dhcpv6-server@1:dns-forwarding@3:firewall@5:https@2:interfaces@18:ipoe-server@1:ipsec@5:l2tp@3:lldp@1:mdns@1:nat@5:ntp@1:pppoe-server@5:pptp@2:qos@1:quagga@6:salt@1:snmp@2:ssh@2:sstp@3:system@20:vrrp@2:vyos-accel-ppp@2:wanloadbalance@3:webproxy@2:zone-policy@1" +// Release version: 1.3-beta-202101231023 diff --git a/smoketest/scripts/cli/base_interfaces_test.py b/smoketest/scripts/cli/base_interfaces_test.py index 6f8eda26a..4acde99d3 100644 --- a/smoketest/scripts/cli/base_interfaces_test.py +++ b/smoketest/scripts/cli/base_interfaces_test.py @@ -246,11 +246,19 @@ class BasicInterfaceTest: for intf in self._interfaces: base = self._base_path + [intf] self.cli_set(base + ['mtu', self._mtu]) - self.cli_set(base + ['ipv6', 'address', 'no-default-link-local']) for option in self._options.get(intf, []): self.cli_set(base + option.split()) + # check validate() - can not set low MTU if 'no-default-link-local' + # is not set on CLI + with self.assertRaises(ConfigSessionError): + self.cli_commit() + + for intf in self._interfaces: + base = self._base_path + [intf] + self.cli_set(base + ['ipv6', 'address', 'no-default-link-local']) + # commit interface changes self.cli_commit() @@ -438,28 +446,30 @@ class BasicInterfaceTest: tmp = read_file(f'/proc/sys/net/ipv4/neigh/{interface}/base_reachable_time_ms') self.assertEqual(tmp, str((int(arp_tmo) * 1000))) # tmo value is in milli seconds - tmp = read_file(f'/proc/sys/net/ipv4/conf/{interface}/arp_filter') + proc_base = f'/proc/sys/net/ipv4/conf/{interface}' + + tmp = read_file(f'{proc_base}/arp_filter') self.assertEqual('0', tmp) - tmp = read_file(f'/proc/sys/net/ipv4/conf/{interface}/arp_accept') + tmp = read_file(f'{proc_base}/arp_accept') self.assertEqual('1', tmp) - tmp = read_file(f'/proc/sys/net/ipv4/conf/{interface}/arp_announce') + tmp = read_file(f'{proc_base}/arp_announce') self.assertEqual('1', tmp) - tmp = read_file(f'/proc/sys/net/ipv4/conf/{interface}/arp_ignore') + tmp = read_file(f'{proc_base}/arp_ignore') self.assertEqual('1', tmp) - tmp = read_file(f'/proc/sys/net/ipv4/conf/{interface}/forwarding') + tmp = read_file(f'{proc_base}/forwarding') self.assertEqual('0', tmp) - tmp = read_file(f'/proc/sys/net/ipv4/conf/{interface}/proxy_arp') + tmp = read_file(f'{proc_base}/proxy_arp') self.assertEqual('1', tmp) - tmp = read_file(f'/proc/sys/net/ipv4/conf/{interface}/proxy_arp_pvlan') + tmp = read_file(f'{proc_base}/proxy_arp_pvlan') self.assertEqual('1', tmp) - tmp = read_file(f'/proc/sys/net/ipv4/conf/{interface}/rp_filter') + tmp = read_file(f'{proc_base}/rp_filter') self.assertEqual('2', tmp) def test_interface_ipv6_options(self): @@ -479,10 +489,12 @@ class BasicInterfaceTest: self.cli_commit() for interface in self._interfaces: - tmp = read_file(f'/proc/sys/net/ipv6/conf/{interface}/forwarding') + proc_base = f'/proc/sys/net/ipv6/conf/{interface}' + + tmp = read_file(f'{proc_base}/forwarding') self.assertEqual('0', tmp) - tmp = read_file(f'/proc/sys/net/ipv6/conf/{interface}/dad_transmits') + tmp = read_file(f'{proc_base}/dad_transmits') self.assertEqual(dad_transmits, tmp) def test_dhcpv6_client_options(self): diff --git a/smoketest/scripts/cli/base_vyostest_shim.py b/smoketest/scripts/cli/base_vyostest_shim.py index 18e4e567e..93b2ca150 100644 --- a/smoketest/scripts/cli/base_vyostest_shim.py +++ b/smoketest/scripts/cli/base_vyostest_shim.py @@ -20,7 +20,9 @@ from time import sleep from vyos.configsession import ConfigSession from vyos.configsession import ConfigSessionError from vyos import ConfigError +from vyos.defaults import commit_lock from vyos.util import cmd +from vyos.util import run save_config = '/tmp/vyos-smoketest-save' @@ -70,21 +72,16 @@ class VyOSUnitTestSHIM: def cli_commit(self): self._session.commit() + # during a commit there is a process opening commit_lock, and run() returns 0 + while run(f'sudo lsof | grep -q {commit_lock}') == 0: + sleep(0.250) def getFRRconfig(self, string, end='$'): """ Retrieve current "running configuration" from FRR """ command = f'vtysh -c "show run" | sed -n "/^{string}{end}/,/^!/p"' - - count = 0 - tmp = '' - while count < 10 and tmp == '': - # Let FRR settle after a config change first before harassing it again - sleep(1) - tmp = cmd(command) - count += 1 - - if self.debug or tmp == '': + out = cmd(command) + if self.debug: import pprint print(f'\n\ncommand "{command}" returned:\n') - pprint.pprint(tmp) - return tmp + pprint.pprint(out) + return out diff --git a/smoketest/scripts/cli/test_interfaces_bridge.py b/smoketest/scripts/cli/test_interfaces_bridge.py index 4014c1a4c..2152dba72 100755 --- a/smoketest/scripts/cli/test_interfaces_bridge.py +++ b/smoketest/scripts/cli/test_interfaces_bridge.py @@ -63,6 +63,32 @@ class BridgeInterfaceTest(BasicInterfaceTest.TestCase): super().tearDown() + def test_isolated_interfaces(self): + # Add member interfaces to bridge and set STP cost/priority + for interface in self._interfaces: + base = self._base_path + [interface] + self.cli_set(base + ['stp']) + + # assign members to bridge interface + for member in self._members: + base_member = base + ['member', 'interface', member] + self.cli_set(base_member + ['isolated']) + + # commit config + self.cli_commit() + + for interface in self._interfaces: + tmp = get_interface_config(interface) + # STP must be enabled as configured above + self.assertEqual(1, tmp['linkinfo']['info_data']['stp_state']) + + # validate member interface configuration + for member in self._members: + tmp = get_interface_config(member) + # Isolated must be enabled as configured above + self.assertTrue(tmp['linkinfo']['info_slave_data']['isolated']) + + def test_add_remove_bridge_member(self): # Add member interfaces to bridge and set STP cost/priority for interface in self._interfaces: @@ -97,12 +123,34 @@ class BridgeInterfaceTest(BasicInterfaceTest.TestCase): cost += 1 priority += 1 + + def test_vif_8021q_interfaces(self): + for interface in self._interfaces: + base = self._base_path + [interface] + self.cli_set(base + ['enable-vlan']) + super().test_vif_8021q_interfaces() + + def test_vif_8021q_lower_up_down(self): + for interface in self._interfaces: + base = self._base_path + [interface] + self.cli_set(base + ['enable-vlan']) + super().test_vif_8021q_lower_up_down() + + def test_vif_8021q_mtu_limits(self): + for interface in self._interfaces: + base = self._base_path + [interface] + self.cli_set(base + ['enable-vlan']) + super().test_vif_8021q_mtu_limits() + def test_bridge_vlan_filter(self): + vif_vlan = 2 # Add member interface to bridge and set VLAN filter for interface in self._interfaces: base = self._base_path + [interface] - self.cli_set(base + ['vif', '1', 'address', '192.0.2.1/24']) - self.cli_set(base + ['vif', '2', 'address', '192.0.3.1/24']) + self.cli_set(base + ['enable-vlan']) + self.cli_set(base + ['address', '192.0.2.1/24']) + self.cli_set(base + ['vif', str(vif_vlan), 'address', '192.0.3.1/24']) + self.cli_set(base + ['vif', str(vif_vlan), 'mtu', self._mtu]) vlan_id = 101 allowed_vlan = 2 @@ -174,6 +222,7 @@ class BridgeInterfaceTest(BasicInterfaceTest.TestCase): for interface in self._interfaces: self.cli_delete(self._base_path + [interface, 'member']) + def test_bridge_vlan_members(self): # T2945: ensure that VIFs are not dropped from bridge vifs = ['300', '400'] diff --git a/smoketest/scripts/cli/test_nat.py b/smoketest/scripts/cli/test_nat.py index 0706f234e..0706f234e 100755..100644 --- a/smoketest/scripts/cli/test_nat.py +++ b/smoketest/scripts/cli/test_nat.py diff --git a/smoketest/scripts/cli/test_protocols_isis.py b/smoketest/scripts/cli/test_protocols_isis.py new file mode 100755 index 000000000..482162b0e --- /dev/null +++ b/smoketest/scripts/cli/test_protocols_isis.py @@ -0,0 +1,170 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2021 VyOS maintainers and contributors +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or later as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +import unittest + +from base_vyostest_shim import VyOSUnitTestSHIM +from vyos.configsession import ConfigSession +from vyos.configsession import ConfigSessionError +from vyos.ifconfig import Section +from vyos.util import process_named_running + +PROCESS_NAME = 'isisd' +base_path = ['protocols', 'isis'] + +domain = 'VyOS' +net = '49.0001.1921.6800.1002.00' + +class TestProtocolsISIS(VyOSUnitTestSHIM.TestCase): + @classmethod + def setUpClass(cls): + cls._interfaces = Section.interfaces('ethernet') + + # call base-classes classmethod + super(cls, cls).setUpClass() + + def tearDown(self): + self.cli_delete(base_path) + self.cli_commit() + + # Check for running process + self.assertTrue(process_named_running(PROCESS_NAME)) + + def isis_base_config(self): + self.cli_set(base_path + ['net', net]) + for interface in self._interfaces: + self.cli_set(base_path + ['interface', interface]) + + def test_isis_01_redistribute(self): + prefix_list = 'EXPORT-ISIS' + route_map = 'EXPORT-ISIS' + rule = '10' + + self.cli_set(['policy', 'prefix-list', prefix_list, 'rule', rule, 'action', 'permit']) + self.cli_set(['policy', 'prefix-list', prefix_list, 'rule', rule, 'prefix', '203.0.113.0/24']) + self.cli_set(['policy', 'route-map', route_map, 'rule', rule, 'action', 'permit']) + self.cli_set(['policy', 'route-map', route_map, 'rule', rule, 'match', 'ip', 'address', 'prefix-list', prefix_list]) + + self.cli_set(base_path) + + # verify() - net id and interface are mandatory + with self.assertRaises(ConfigSessionError): + self.cli_commit() + + self.isis_base_config() + self.cli_set(base_path + ['redistribute', 'ipv4', 'connected', 'level-2', 'route-map', route_map]) + self.cli_set(base_path + ['log-adjacency-changes']) + + # Commit all changes + self.cli_commit() + + # Verify all changes + tmp = self.getFRRconfig(f'router isis {domain}') + 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}') + self.assertIn(f' ip router isis {domain}', tmp) + self.assertIn(f' ipv6 router isis {domain}', tmp) + + self.cli_delete(['policy', 'route-map', route_map]) + self.cli_delete(['policy', 'prefix-list', prefix_list]) + + def test_isis_02_zebra_route_map(self): + # Implemented because of T3328 + route_map = 'foo-isis-in' + + self.cli_set(['policy', 'route-map', route_map, 'rule', '10', 'action', 'permit']) + + 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]) + + # 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) + self.assertIn(zebra_route_map, frrconfig) + + # 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) + self.assertNotIn(zebra_route_map, frrconfig) + + self.cli_delete(['policy', 'route-map', route_map]) + + def test_isis_03_default_information(self): + metric = '50' + route_map = 'default-foo-' + + self.isis_base_config() + for afi in ['ipv4', 'ipv6']: + for level in ['level-1', 'level-2']: + self.cli_set(base_path + ['default-information', 'originate', afi, level, 'always']) + self.cli_set(base_path + ['default-information', 'originate', afi, level, 'metric', metric]) + self.cli_set(base_path + ['default-information', 'originate', afi, level, 'route-map', route_map + level + afi]) + + # Commit all changes + self.cli_commit() + + # Verify all changes + tmp = self.getFRRconfig(f'router isis {domain}') + self.assertIn(f' net {net}', tmp) + + for afi in ['ipv4', 'ipv6']: + for level in ['level-1', 'level-2']: + route_map_name = route_map + level + afi + self.assertIn(f' default-information originate {afi} {level} always route-map {route_map_name} metric {metric}', tmp) + + def test_isis_04_password(self): + password = 'foo' + + self.isis_base_config() + + self.cli_set(base_path + ['area-password', 'plaintext-password', password]) + self.cli_set(base_path + ['area-password', 'md5', password]) + self.cli_set(base_path + ['domain-password', 'plaintext-password', password]) + self.cli_set(base_path + ['domain-password', 'md5', password]) + + # verify() - can not use both md5 and plaintext-password for area-password + with self.assertRaises(ConfigSessionError): + self.cli_commit() + self.cli_delete(base_path + ['area-password', 'md5', password]) + + # verify() - can not use both md5 and plaintext-password for domain-password + with self.assertRaises(ConfigSessionError): + self.cli_commit() + self.cli_delete(base_path + ['domain-password', 'md5', password]) + + # Commit all changes + self.cli_commit() + + # Verify all changes + tmp = self.getFRRconfig(f'router isis {domain}') + self.assertIn(f' net {net}', tmp) + self.assertIn(f' domain-password clear {password}', tmp) + self.assertIn(f' area-password clear {password}', tmp) + +if __name__ == '__main__': + unittest.main(verbosity=2) diff --git a/smoketest/scripts/cli/test_system_login.py b/smoketest/scripts/cli/test_system_login.py index 8327235fb..af3a5851c 100755 --- a/smoketest/scripts/cli/test_system_login.py +++ b/smoketest/scripts/cli/test_system_login.py @@ -31,7 +31,19 @@ from vyos.util import read_file from vyos.template import inc_ip base_path = ['system', 'login'] -users = ['vyos1', 'vyos2'] +users = ['vyos1', 'vyos-roxx123', 'VyOS-123_super.Nice'] + +ssh_pubkey = """ +AAAAB3NzaC1yc2EAAAADAQABAAABgQD0NuhUOEtMIKnUVFIHoFatqX/c4mjerXyF +TlXYfVt6Ls2NZZsUSwHbnhK4BKDrPvVZMW/LycjQPzWW6TGtk6UbZP1WqdviQ9hP +jsEeKJSTKciMSvQpjBWyEQQPXSKYQC7ryQQilZDqnJgzqwzejKEe+nhhOdBvjuZc +uukxjT69E0UmWAwLxzvfiurwiQaC7tG+PwqvtfHOPL3i6yRO2C5ORpFarx8PeGDS +IfIXJCr3LoUbLHeuE7T2KaOKQcX0UsWJ4CoCapRLpTVYPDB32BYfgq7cW1Sal1re +EGH2PzuXBklinTBgCHA87lHjpwDIAqdmvMj7SXIW9LxazLtP+e37sexE7xEs0cpN +l68txdDbY2P2Kbz5mqGFfCvBYKv9V2clM5vyWNy/Xp5TsCis89nn83KJmgFS7sMx +pHJz8umqkxy3hfw0K7BRFtjWd63sbOP8Q/SDV7LPaIfIxenA9zv2rY7y+AIqTmSr +TTSb0X1zPGxPIRFy5GoGtO9Mm5h4OZk= +""" class TestSystemLogin(VyOSUnitTestSHIM.TestCase): def tearDown(self): @@ -42,6 +54,8 @@ class TestSystemLogin(VyOSUnitTestSHIM.TestCase): self.cli_commit() def test_add_linux_system_user(self): + # We are not allowed to re-use a username already taken by the Linux + # base system system_user = 'backup' self.cli_set(base_path + ['user', system_user, 'authentication', 'plaintext-password', system_user]) @@ -75,9 +89,30 @@ class TestSystemLogin(VyOSUnitTestSHIM.TestCase): (stdout, stderr) = proc.communicate() # stdout is something like this: - # b'Linux vyos 4.19.101-amd64-vyos #1 SMP Sun Feb 2 10:18:07 UTC 2020 x86_64 GNU/Linux\n' + # b'Linux LR1.wue3 5.10.61-amd64-vyos #1 SMP Fri Aug 27 08:55:46 UTC 2021 x86_64 GNU/Linux\n' self.assertTrue(len(stdout) > 40) + def test_system_user_ssh_key(self): + ssh_user = 'ssh-test_user' + public_keys = 'vyos' + type = 'ssh-rsa' + + self.cli_set(base_path + ['user', ssh_user, 'authentication', 'public-keys', public_keys, 'key', ssh_pubkey.replace('\n','')]) + + # check validate() - missing type for public-key + with self.assertRaises(ConfigSessionError): + self.cli_commit() + self.cli_set(base_path + ['user', ssh_user, 'authentication', 'public-keys', public_keys, 'type', type]) + + self.cli_commit() + + # Check that SSH key was written properly + tmp = cmd(f'sudo cat /home/{ssh_user}/.ssh/authorized_keys') + key = f'{type} ' + ssh_pubkey.replace('\n','') + self.assertIn(key, tmp) + + self.cli_delete(base_path + ['user', ssh_user]) + def test_radius_kernel_features(self): # T2886: RADIUS requires some Kernel options to be present kernel = platform.release() @@ -201,4 +236,4 @@ class TestSystemLogin(VyOSUnitTestSHIM.TestCase): self.assertTrue(tmp) if __name__ == '__main__': - unittest.main(verbosity=2) + unittest.main(verbosity=2, failfast=True) diff --git a/src/conf_mode/host_name.py b/src/conf_mode/host_name.py index f4c75c257..a7135911d 100755 --- a/src/conf_mode/host_name.py +++ b/src/conf_mode/host_name.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (C) 2018-2020 VyOS maintainers and contributors +# Copyright (C) 2018-2021 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 @@ -14,10 +14,6 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. -""" -conf-mode script for 'system host-name' and 'system domain-name'. -""" - import re import sys import copy @@ -25,10 +21,13 @@ import copy import vyos.util import vyos.hostsd_client -from vyos.config import Config from vyos import ConfigError -from vyos.util import cmd, call, process_named_running - +from vyos.config import Config +from vyos.ifconfig import Section +from vyos.template import is_ip +from vyos.util import cmd +from vyos.util import call +from vyos.util import process_named_running from vyos import airbag airbag.enable() @@ -37,7 +36,7 @@ default_config_data = { 'domain_name': '', 'domain_search': [], 'nameserver': [], - 'nameservers_dhcp_interfaces': [], + 'nameservers_dhcp_interfaces': {}, 'static_host_mapping': {} } @@ -51,29 +50,37 @@ def get_config(config=None): hosts = copy.deepcopy(default_config_data) - hosts['hostname'] = conf.return_value("system host-name") + hosts['hostname'] = conf.return_value(['system', 'host-name']) # This may happen if the config is not loaded yet, # e.g. if run by cloud-init if not hosts['hostname']: hosts['hostname'] = default_config_data['hostname'] - if conf.exists("system domain-name"): - hosts['domain_name'] = conf.return_value("system domain-name") + if conf.exists(['system', 'domain-name']): + hosts['domain_name'] = conf.return_value(['system', 'domain-name']) hosts['domain_search'].append(hosts['domain_name']) - for search in conf.return_values("system domain-search domain"): + for search in conf.return_values(['system', 'domain-search', 'domain']): hosts['domain_search'].append(search) - hosts['nameserver'] = conf.return_values("system name-server") + if conf.exists(['system', 'name-server']): + for ns in conf.return_values(['system', 'name-server']): + if is_ip(ns): + hosts['nameserver'].append(ns) + else: + tmp = '' + if_type = Section.section(ns) + if conf.exists(['interfaces', if_type, ns, 'address']): + tmp = conf.return_values(['interfaces', if_type, ns, 'address']) - hosts['nameservers_dhcp_interfaces'] = conf.return_values("system name-servers-dhcp") + hosts['nameservers_dhcp_interfaces'].update({ ns : tmp }) # system static-host-mapping - for hn in conf.list_nodes('system static-host-mapping host-name'): + for hn in conf.list_nodes(['system', 'static-host-mapping', 'host-name']): hosts['static_host_mapping'][hn] = {} - hosts['static_host_mapping'][hn]['address'] = conf.return_value(f'system static-host-mapping host-name {hn} inet') - hosts['static_host_mapping'][hn]['aliases'] = conf.return_values(f'system static-host-mapping host-name {hn} alias') + hosts['static_host_mapping'][hn]['address'] = conf.return_value(['system', 'static-host-mapping', 'host-name', hn, 'inet']) + hosts['static_host_mapping'][hn]['aliases'] = conf.return_values(['system', 'static-host-mapping', 'host-name', hn, 'alias']) return hosts @@ -103,8 +110,10 @@ def verify(hosts): if not hostname_regex.match(a) and len(a) != 0: raise ConfigError(f'Invalid alias "{a}" in static-host-mapping "{host}"') - # TODO: add warnings for nameservers_dhcp_interfaces if interface doesn't - # exist or doesn't have address dhcp(v6) + for interface, interface_config in hosts['nameservers_dhcp_interfaces'].items(): + # Warnin user if interface does not have DHCP or DHCPv6 configured + if not set(interface_config).intersection(['dhcp', 'dhcpv6']): + print(f'WARNING: "{interface}" is not a DHCP interface but uses DHCP name-server option!') return None diff --git a/src/conf_mode/interfaces-bridge.py b/src/conf_mode/interfaces-bridge.py index 5b0046a72..4d3ebc587 100755 --- a/src/conf_mode/interfaces-bridge.py +++ b/src/conf_mode/interfaces-bridge.py @@ -18,7 +18,6 @@ import os from sys import exit from netifaces import interfaces -import re from vyos.config import Config from vyos.configdict import get_interface_dict @@ -41,26 +40,6 @@ from vyos import ConfigError from vyos import airbag airbag.enable() -def helper_check_removed_vlan(conf,bridge,key,key_mangling): - key_update = re.sub(key_mangling[0], key_mangling[1], key) - if dict_search('member.interface', bridge): - for interface in bridge['member']['interface']: - tmp = leaf_node_changed(conf, ['member', 'interface',interface,key]) - if tmp: - if 'member' in bridge: - if 'interface' in bridge['member']: - if interface in bridge['member']['interface']: - bridge['member']['interface'][interface].update({f'{key_update}_removed': tmp }) - else: - bridge['member']['interface'].update({interface: {f'{key_update}_removed': tmp }}) - else: - bridge['member'].update({ 'interface': {interface: {f'{key_update}_removed': tmp }}}) - else: - bridge.update({'member': { 'interface': {interface: {f'{key_update}_removed': tmp }}}}) - - return bridge - - def get_config(config=None): """ Retrive CLI config as dictionary. Dictionary can never be empty, as at least the @@ -80,12 +59,6 @@ def get_config(config=None): bridge['member'].update({'interface_remove': tmp }) else: bridge.update({'member': {'interface_remove': tmp }}) - - - # determine which members vlan have been removed - - bridge = helper_check_removed_vlan(conf,bridge,'native-vlan',('-', '_')) - bridge = helper_check_removed_vlan(conf,bridge,'allowed-vlan',('-', '_')) if dict_search('member.interface', bridge): # XXX: T2665: we need a copy of the dict keys for iteration, else we will get: @@ -99,7 +72,6 @@ def get_config(config=None): # the default dictionary is not properly paged into the dict (see T2665) # thus we will ammend it ourself default_member_values = defaults(base + ['member', 'interface']) - vlan_aware = False for interface,interface_config in bridge['member']['interface'].items(): bridge['member']['interface'][interface] = dict_merge( default_member_values, bridge['member']['interface'][interface]) @@ -120,19 +92,11 @@ def get_config(config=None): # Bridge members must not have an assigned address tmp = has_address_configured(conf, interface) if tmp: bridge['member']['interface'][interface].update({'has_address' : ''}) - + # VLAN-aware bridge members must not have VLAN interface configuration - if 'native_vlan' in interface_config: - vlan_aware = True - - if 'allowed_vlan' in interface_config: - vlan_aware = True - - - if vlan_aware: - tmp = has_vlan_subinterface_configured(conf,interface) - if tmp: - if tmp: bridge['member']['interface'][interface].update({'has_vlan' : ''}) + tmp = has_vlan_subinterface_configured(conf,interface) + if 'enable_vlan' in bridge and tmp: + bridge['member']['interface'][interface].update({'has_vlan' : ''}) return bridge @@ -142,8 +106,8 @@ def verify(bridge): verify_dhcpv6(bridge) verify_vrf(bridge) - - vlan_aware = False + + ifname = bridge['ifname'] if dict_search('member.interface', bridge): for interface, interface_config in bridge['member']['interface'].items(): @@ -166,31 +130,24 @@ def verify(bridge): if 'has_address' in interface_config: raise ConfigError(error_msg + 'it has an address assigned!') - - if 'has_vlan' in interface_config: - raise ConfigError(error_msg + 'it has an VLAN subinterface assigned!') - - # VLAN-aware bridge members must not have VLAN interface configuration - if 'native_vlan' in interface_config: - vlan_aware = True - - if 'allowed_vlan' in interface_config: - vlan_aware = True - - if vlan_aware and 'wlan' in interface: - raise ConfigError(error_msg + 'VLAN aware cannot be set!') - - if 'allowed_vlan' in interface_config: - for vlan in interface_config['allowed_vlan']: - if re.search('[0-9]{1,4}-[0-9]{1,4}', vlan): - vlan_range = vlan.split('-') - if int(vlan_range[0]) <1 and int(vlan_range[0])>4094: - raise ConfigError('VLAN ID must be between 1 and 4094') - if int(vlan_range[1]) <1 and int(vlan_range[1])>4094: - raise ConfigError('VLAN ID must be between 1 and 4094') - else: - if int(vlan) <1 and int(vlan)>4094: - raise ConfigError('VLAN ID must be between 1 and 4094') + + if 'enable_vlan' in bridge: + if 'has_vlan' in interface_config: + raise ConfigError(error_msg + 'it has an VLAN subinterface assigned!') + + if 'wlan' in interface: + raise ConfigError(error_msg + 'VLAN aware cannot be set!') + else: + for option in ['allowed_vlan', 'native_vlan']: + if option in interface_config: + raise ConfigError('Can not use VLAN options on non VLAN aware bridge') + + if 'enable_vlan' in bridge: + if dict_search('vif.1', bridge): + raise ConfigError(f'VLAN 1 sub interface cannot be set for VLAN aware bridge {ifname}, and VLAN 1 is always the parent interface') + else: + if dict_search('vif', bridge): + raise ConfigError(f'You must first activate "enable-vlan" of {ifname} bridge to use "vif"') return None diff --git a/src/conf_mode/interfaces-ethernet.py b/src/conf_mode/interfaces-ethernet.py index 349b0e7a3..de851262b 100755 --- a/src/conf_mode/interfaces-ethernet.py +++ b/src/conf_mode/interfaces-ethernet.py @@ -62,12 +62,6 @@ def verify(ethernet): ifname = ethernet['ifname'] verify_interface_exists(ifname) - - # No need to check speed and duplex keys as both have default values. - if ((ethernet['speed'] == 'auto' and ethernet['duplex'] != 'auto') or - (ethernet['speed'] != 'auto' and ethernet['duplex'] == 'auto')): - raise ConfigError('Speed/Duplex missmatch. Must be both auto or manually configured') - verify_mtu(ethernet) verify_mtu_ipv6(ethernet) verify_dhcpv6(ethernet) @@ -76,25 +70,31 @@ def verify(ethernet): verify_eapol(ethernet) verify_mirror(ethernet) - # verify offloading capabilities - if dict_search('offload.rps', ethernet) != None: - if not os.path.exists(f'/sys/class/net/{ifname}/queues/rx-0/rps_cpus'): - raise ConfigError('Interface does not suport RPS!') + ethtool = Ethtool(ifname) + # No need to check speed and duplex keys as both have default values. + if ((ethernet['speed'] == 'auto' and ethernet['duplex'] != 'auto') or + (ethernet['speed'] != 'auto' and ethernet['duplex'] == 'auto')): + raise ConfigError('Speed/Duplex missmatch. Must be both auto or manually configured') - driver = EthernetIf(ifname).get_driver_name() - # T3342 - Xen driver requires special treatment - if driver == 'vif': - if int(ethernet['mtu']) > 1500 and dict_search('offload.sg', ethernet) == None: - raise ConfigError('Xen netback drivers requires scatter-gatter offloading '\ - 'for MTU size larger then 1500 bytes') + if ethernet['speed'] != 'auto' and ethernet['duplex'] != 'auto': + # We need to verify if the requested speed and duplex setting is + # supported by the underlaying NIC. + speed = ethernet['speed'] + duplex = ethernet['duplex'] + if not ethtool.check_speed_duplex(speed, duplex): + raise ConfigError(f'Adapter does not support changing speed and duplex '\ + f'settings to: {speed}/{duplex}!') + + if 'disable_flow_control' in ethernet: + if not ethtool.check_flow_control(): + raise ConfigError('Adapter does not support changing flow-control settings!') - ethtool = Ethtool(ifname) if 'ring_buffer' in ethernet: - max_rx = ethtool.get_rx_buffer() + max_rx = ethtool.get_ring_buffer_max('rx') if not max_rx: raise ConfigError('Driver does not support RX ring-buffer configuration!') - max_tx = ethtool.get_tx_buffer() + max_tx = ethtool.get_ring_buffer_max('tx') if not max_tx: raise ConfigError('Driver does not support TX ring-buffer configuration!') @@ -108,6 +108,18 @@ def verify(ethernet): raise ConfigError(f'Driver only supports a maximum TX ring-buffer '\ f'size of "{max_tx}" bytes!') + # verify offloading capabilities + if dict_search('offload.rps', ethernet) != None: + if not os.path.exists(f'/sys/class/net/{ifname}/queues/rx-0/rps_cpus'): + raise ConfigError('Interface does not suport RPS!') + + driver = ethtool.get_driver_name() + # T3342 - Xen driver requires special treatment + if driver == 'vif': + if int(ethernet['mtu']) > 1500 and dict_search('offload.sg', ethernet) == None: + raise ConfigError('Xen netback drivers requires scatter-gatter offloading '\ + 'for MTU size larger then 1500 bytes') + if {'is_bond_member', 'mac'} <= set(ethernet): print(f'WARNING: changing mac address "{mac}" will be ignored as "{ifname}" ' f'is a member of bond "{is_bond_member}"'.format(**ethernet)) diff --git a/src/conf_mode/interfaces-openvpn.py b/src/conf_mode/interfaces-openvpn.py index 0a420f7bf..c3620d690 100755 --- a/src/conf_mode/interfaces-openvpn.py +++ b/src/conf_mode/interfaces-openvpn.py @@ -40,6 +40,7 @@ from vyos.util import call from vyos.util import chown from vyos.util import chmod_600 from vyos.util import dict_search +from vyos.util import makedir from vyos.validate import is_addr_assigned from vyos import ConfigError @@ -79,9 +80,6 @@ def get_config(config=None): openvpn = get_interface_dict(conf, base) openvpn['auth_user_pass_file'] = '/run/openvpn/{ifname}.pw'.format(**openvpn) - openvpn['daemon_user'] = user - openvpn['daemon_group'] = group - return openvpn def verify(openvpn): @@ -425,6 +423,10 @@ def verify(openvpn): def generate(openvpn): interface = openvpn['ifname'] directory = os.path.dirname(cfg_file.format(**openvpn)) + # create base config directory on demand + makedir(directory, user, group) + # enforce proper permissions on /run/openvpn + chown(directory, user, group) # we can't know in advance which clients have been removed, # thus all client configs will be removed and re-added on demand @@ -436,9 +438,7 @@ def generate(openvpn): return None # create client config directory on demand - if not os.path.exists(ccd_dir): - os.makedirs(ccd_dir, 0o755) - chown(ccd_dir, user, group) + makedir(ccd_dir, user, group) # Fix file permissons for keys fix_permissions = [] diff --git a/src/conf_mode/interfaces-tunnel.py b/src/conf_mode/interfaces-tunnel.py index e5958e9ae..22a9f0e18 100755 --- a/src/conf_mode/interfaces-tunnel.py +++ b/src/conf_mode/interfaces-tunnel.py @@ -18,6 +18,7 @@ import os from sys import exit from netifaces import interfaces +from ipaddress import IPv4Address from vyos.config import Config from vyos.configdict import dict_merge @@ -31,6 +32,7 @@ from vyos.configverify import verify_mtu_ipv6 from vyos.configverify import verify_vrf from vyos.configverify import verify_tunnel from vyos.ifconfig import Interface +from vyos.ifconfig import Section from vyos.ifconfig import TunnelIf from vyos.template import is_ipv4 from vyos.template import is_ipv6 @@ -74,6 +76,38 @@ def verify(tunnel): verify_tunnel(tunnel) + # If tunnel source address any and key not set + if tunnel['encapsulation'] in ['gre'] and \ + tunnel['source_address'] == '0.0.0.0' and \ + dict_search('parameters.ip.key', tunnel) == None: + raise ConfigError('Tunnel parameters ip key must be set!') + + if tunnel['encapsulation'] in ['gre', 'gretap']: + if dict_search('parameters.ip.key', tunnel) != None: + # Check pairs tunnel source-address/encapsulation/key with exists tunnels. + # Prevent the same key for 2 tunnels with same source-address/encap. T2920 + for tunnel_if in Section.interfaces('tunnel'): + tunnel_cfg = get_interface_config(tunnel_if) + exist_encap = tunnel_cfg['linkinfo']['info_kind'] + exist_source_address = tunnel_cfg['address'] + exist_key = tunnel_cfg['linkinfo']['info_data']['ikey'] + new_source_address = tunnel['source_address'] + # Convert tunnel key to ip key, format "ip -j link show" + # 1 => 0.0.0.1, 999 => 0.0.3.231 + orig_new_key = int(tunnel['parameters']['ip']['key']) + new_key = IPv4Address(orig_new_key) + new_key = str(new_key) + if tunnel['encapsulation'] == exist_encap and \ + new_source_address == exist_source_address and \ + new_key == exist_key: + raise ConfigError(f'Key "{orig_new_key}" for source-address "{new_source_address}" ' \ + f'is already used for tunnel "{tunnel_if}"!') + + # Keys are not allowed with ipip and sit tunnels + if tunnel['encapsulation'] in ['ipip', 'sit']: + if dict_search('parameters.ip.key', tunnel) != None: + raise ConfigError('Keys are not allowed with ipip and sit tunnels!') + verify_mtu_ipv6(tunnel) verify_address(tunnel) verify_vrf(tunnel) diff --git a/src/conf_mode/ipsec-settings.py b/src/conf_mode/ipsec-settings.py index 7ca2d9b44..771f635a0 100755 --- a/src/conf_mode/ipsec-settings.py +++ b/src/conf_mode/ipsec-settings.py @@ -18,7 +18,9 @@ import re import os from time import sleep -from sys import exit + +# Top level import so that configd can override it +from sys import argv from vyos.config import Config from vyos import ConfigError @@ -216,6 +218,20 @@ def generate(data): remove_confs(delim_ipsec_l2tp_begin, delim_ipsec_l2tp_end, ipsec_secrets_file) remove_confs(delim_ipsec_l2tp_begin, delim_ipsec_l2tp_end, ipsec_conf_file) +def is_charon_responsive(): + # Check if charon responds to strokes + # + # Sometimes it takes time to fully initialize, + # so waiting for the process to come to live isn't always enough + # + # There's no official "no-op" stroke so we use the "memusage" stroke as a substitute + from os import system + res = system("ipsec stroke memusage >&/dev/null") + if res == 0: + return True + else: + return False + def restart_ipsec(): try: # Restart the IPsec daemon when it's running. @@ -223,17 +239,28 @@ def restart_ipsec(): # there's a chance that this script will run before charon is up, # so we can't assume it's running and have to check and wait if needed. - # First, wait for charon to get started by the old ipsec.pl script. + # But before everything else, there's a catch! + # This script is run from _two_ places: "vpn ipsec options" and the top level "vpn" node + # When IPsec isn't set up yet, and a user wants to commit an IPsec config with some + # "vpn ipsec settings", this script will first be called before StrongSWAN is started by vpn-config.pl! + # Thus if this script is run from "settings" _and_ charon is unresponsive, + # we shouldn't wait for it, else there will be a deadlock. + # We indicate that by running the script under vyshim from "vpn ipsec options" (which sets a variable named "argv") + # and running it without configd from "vpn ipsec" + if "from-options" in argv: + if not is_charon_responsive(): + return + + # If we got this far, then we actually need to restart StrongSWAN + + # First, wait for charon to get started by the old vpn-config.pl script. from time import sleep, time from os import system now = time() while True: if (time() - now) > 60: raise OSError("Timeout waiting for the IPsec process to become responsive") - # There's no oficial "no-op" stroke, - # so we use memusage to check if charon is alive and responsive - res = system("ipsec stroke memusage >&/dev/null") - if res == 0: + if is_charon_responsive(): break sleep(5) diff --git a/src/conf_mode/protocols_isis.py b/src/conf_mode/protocols_isis.py index da91f3b11..0c179b724 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 VyOS maintainers and contributors +# Copyright (C) 2020-2021 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 @@ -19,12 +19,16 @@ import os from sys import exit from vyos.config import Config +from vyos.configdict import dict_merge from vyos.configdict import node_changed -from vyos import ConfigError -from vyos.util import call +from vyos.configverify import verify_common_route_maps +from vyos.configverify import verify_interface_exists +from vyos.ifconfig import Interface from vyos.util import dict_search -from vyos.template import render +from vyos.util import get_interface_config from vyos.template import render_to_string +from vyos.xml import defaults +from vyos import ConfigError from vyos import frr from vyos import airbag airbag.enable() @@ -34,126 +38,172 @@ def get_config(config=None): conf = config else: conf = Config() - base = ['protocols', 'isis'] - isis = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True) + base = ['protocols', 'isis'] + isis = conf.get_config_dict(base, key_mangling=('-', '_'), + get_first_key=True) + + interfaces_removed = node_changed(conf, base + ['interface']) + if interfaces_removed: + isis['interface_removed'] = list(interfaces_removed) + + # Bail out early if configuration tree does not exist + if not conf.exists(base): + isis.update({'deleted' : ''}) + return isis + + # We have gathered the dict representation of the CLI, but there are default + # options which we need to update into the dictionary retrived. + # XXX: Note that we can not call defaults(base), as defaults does not work + # on an instance of a tag node. + default_values = defaults(base) + # merge in default values + isis = dict_merge(default_values, isis) + + # We also need some additional information from the config, prefix-lists + # and route-maps for instance. They will be used in verify(). + # + # XXX: one MUST always call this without the key_mangling() option! See + # vyos.configverify.verify_common_route_maps() for more information. + tmp = conf.get_config_dict(['policy']) + # Merge policy dict into "regular" config dict + isis = dict_merge(tmp, isis) return isis def verify(isis): # bail out early - looks like removal from running config - if not isis: + if not isis or 'deleted' in isis: return None - for process, isis_config in isis.items(): - # If more then one isis process is defined (Frr only supports one) - # http://docs.frrouting.org/en/latest/isisd.html#isis-router - if len(isis) > 1: - raise ConfigError('Only one isis process can be defined') - - # If network entity title (net) not defined - if 'net' not in isis_config: - raise ConfigError('ISIS net format iso is mandatory!') - - # If interface not set - if 'interface' not in isis_config: - raise ConfigError('ISIS interface is mandatory!') - - # If md5 and plaintext-password set at the same time - if 'area_password' in isis_config: - if {'md5', 'plaintext_password'} <= set(isis_config['encryption']): - raise ConfigError('Can not use both md5 and plaintext-password for ISIS area-password!') - - # If one param from delay set, but not set others - if 'spf_delay_ietf' in isis_config: - required_timers = ['holddown', 'init_delay', 'long_delay', 'short_delay', 'time_to_learn'] - exist_timers = [] - for elm_timer in required_timers: - if elm_timer in isis_config['spf_delay_ietf']: - exist_timers.append(elm_timer) - - exist_timers = set(required_timers).difference(set(exist_timers)) - if len(exist_timers) > 0: - raise ConfigError('All types of delay must be specified: ' + ', '.join(exist_timers).replace('_', '-')) - - # If Redistribute set, but level don't set - if 'redistribute' in isis_config: - proc_level = isis_config.get('level','').replace('-','_') - for proto, proto_config in isis_config.get('redistribute', {}).get('ipv4', {}).items(): + if 'net' not in isis: + raise ConfigError('Network entity is mandatory!') + + # last byte in IS-IS area address must be 0 + tmp = isis['net'].split('.') + if int(tmp[-1]) != 0: + raise ConfigError('Last byte of IS-IS network entity title must always be 0!') + + verify_common_route_maps(isis) + + # If interface not set + if 'interface' not in isis: + raise ConfigError('Interface used for routing updates is mandatory!') + + for interface in isis['interface']: + verify_interface_exists(interface) + # Interface MTU must be >= configured lsp-mtu + mtu = Interface(interface).get_mtu() + area_mtu = isis['lsp_mtu'] + # Recommended maximum PDU size = interface MTU - 3 bytes + recom_area_mtu = mtu - 3 + if mtu < int(area_mtu) or int(area_mtu) > recom_area_mtu: + raise ConfigError(f'Interface {interface} has MTU {mtu}, ' \ + f'current area MTU is {area_mtu}! \n' \ + f'Recommended area lsp-mtu {recom_area_mtu} or less ' \ + '(calculated on MTU size).') + + # If md5 and plaintext-password set at the same time + for password in ['area_password', 'domain_password']: + if password in isis: + if {'md5', 'plaintext_password'} <= set(isis[password]): + tmp = password.replace('_', '-') + raise ConfigError(f'Can use either md5 or plaintext-password for {tmp}!') + + # If one param from delay set, but not set others + if 'spf_delay_ietf' in isis: + required_timers = ['holddown', 'init_delay', 'long_delay', 'short_delay', 'time_to_learn'] + exist_timers = [] + for elm_timer in required_timers: + if elm_timer in isis['spf_delay_ietf']: + exist_timers.append(elm_timer) + + exist_timers = set(required_timers).difference(set(exist_timers)) + if len(exist_timers) > 0: + raise ConfigError('All types of delay must be specified: ' + ', '.join(exist_timers).replace('_', '-')) + + # If Redistribute set, but level don't set + if 'redistribute' in isis: + proc_level = isis.get('level','').replace('-','_') + for afi in ['ipv4', 'ipv6']: + if afi not in isis['redistribute']: + continue + + for proto, proto_config in isis['redistribute'][afi].items(): if 'level_1' not in proto_config and 'level_2' not in proto_config: - raise ConfigError('Redistribute level-1 or level-2 should be specified in \"protocols isis {} redistribute ipv4 {}\"'.format(process, proto)) - for redistribute_level in proto_config.keys(): - if proc_level and proc_level != 'level_1_2' and proc_level != redistribute_level: - raise ConfigError('\"protocols isis {0} redistribute ipv4 {2} {3}\" cannot be used with \"protocols isis {0} level {1}\"'.format(process, proc_level, proto, redistribute_level)) - - # Segment routing checks - if dict_search('segment_routing', isis_config): - if dict_search('segment_routing.global_block', isis_config): - high_label_value = dict_search('segment_routing.global_block.high_label_value', isis_config) - low_label_value = dict_search('segment_routing.global_block.low_label_value', isis_config) - # If segment routing global block high value is blank, throw error - if low_label_value and not high_label_value: - raise ConfigError('Segment routing global block high value must not be left blank') - # If segment routing global block low value is blank, throw error - if high_label_value and not low_label_value: - raise ConfigError('Segment routing global block low value must not be left blank') - # 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 dict_search('segment_routing.local_block', isis_config): - high_label_value = dict_search('segment_routing.local_block.high_label_value', isis_config) - low_label_value = dict_search('segment_routing.local_block.low_label_value', isis_config) - # If segment routing local block high value is blank, throw error - if low_label_value and not high_label_value: - raise ConfigError('Segment routing local block high value must not be left blank') - # If segment routing local block low value is blank, throw error - if high_label_value and not low_label_value: - raise ConfigError('Segment routing local block low value must not be left blank') - # 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') + raise ConfigError(f'Redistribute level-1 or level-2 should be specified in ' \ + f'"protocols isis {process} redistribute {afi} {proto}"!') + + for redistr_level, redistr_config in proto_config.items(): + if proc_level and proc_level != 'level_1_2' and proc_level != redistr_level: + raise ConfigError(f'"protocols isis {process} redistribute {afi} {proto} {redistr_level}" ' \ + f'can not be used with \"protocols isis {process} level {proc_level}\"') + + # 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) + + # 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 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 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 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!') + + # 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') return None def generate(isis): - if not isis: - isis['new_frr_config'] = '' + if not isis or 'deleted' in isis: + isis['frr_isisd_config'] = '' + isis['frr_zebra_config'] = '' return None - # only one ISIS process is supported, so we can directly send the first key - # of the config dict - process = list(isis.keys())[0] - isis[process]['process'] = process - - isis['new_frr_config'] = render_to_string('frr/isisd.frr.tmpl', - isis[process]) - + isis['protocol'] = 'isis' # required for frr/route-map.frr.tmpl + isis['frr_zebra_config'] = render_to_string('frr/route-map.frr.tmpl', isis) + isis['frr_isisd_config'] = render_to_string('frr/isisd.frr.tmpl', isis) return None def apply(isis): + isis_daemon = 'isisd' + zebra_daemon = 'zebra' + # Save original configuration prior to starting any commit actions frr_cfg = frr.FRRConfig() - frr_cfg.load_configuration(daemon='isisd') - frr_cfg.modify_section(r'interface \S+', '') - frr_cfg.modify_section(f'router isis \S+', '') - frr_cfg.add_before(r'(ip prefix-list .*|route-map .*|line vty)', isis['new_frr_config']) - frr_cfg.commit_configuration(daemon='isisd') - - # If FRR config is blank, rerun the blank commit x times due to frr-reload - # behavior/bug not properly clearing out on one commit. - if isis['new_frr_config'] == '': - for a in range(5): - frr_cfg.commit_configuration(daemon='isisd') - - # Debugging - ''' - print('') - print('--------- DEBUGGING ----------') - print(f'Existing config:\n{frr_cfg["original_config"]}\n\n') - print(f'Replacement config:\n{isis["new_frr_config"]}\n\n') - print(f'Modified config:\n{frr_cfg["modified_config"]}\n\n') - ''' + + # The route-map used for the FIB (zebra) is part of the zebra daemon + frr_cfg.load_configuration(zebra_daemon) + frr_cfg.modify_section(r'(\s+)?ip protocol isis route-map [-a-zA-Z0-9.]+$', '', '(\s|!)') + frr_cfg.add_before(r'(ip prefix-list .*|route-map .*|line vty)', isis['frr_zebra_config']) + frr_cfg.commit_configuration(zebra_daemon) + + frr_cfg.load_configuration(isis_daemon) + frr_cfg.modify_section(f'^router isis VyOS$', '') + + for key in ['interface', 'interface_removed']: + if key not in isis: + continue + for interface in isis[key]: + frr_cfg.modify_section(f'^interface {interface}$', '') + + frr_cfg.add_before(r'(ip prefix-list .*|route-map .*|line vty)', isis['frr_isisd_config']) + frr_cfg.commit_configuration(isis_daemon) + + # Save configuration to /run/frr/config/frr.conf + frr.save_configuration() return None diff --git a/src/conf_mode/protocols_rip.py b/src/conf_mode/protocols_rip.py index 8ddd705f2..f36abbf90 100755 --- a/src/conf_mode/protocols_rip.py +++ b/src/conf_mode/protocols_rip.py @@ -125,7 +125,7 @@ def get_config(config=None): conf.set_level(base) - # Get distribute list interface + # Get distribute list interface for dist_iface in conf.list_nodes('distribute-list interface'): # Set level 'distribute-list interface ethX' conf.set_level(base + ['distribute-list', 'interface', dist_iface]) @@ -301,6 +301,7 @@ def apply(rip): if os.path.exists(config_file): call(f'vtysh -d ripd -f {config_file}') + call('sudo vtysh --writeconfig --noerror') os.remove(config_file) else: print("File {0} not found".format(config_file)) diff --git a/src/conf_mode/system-login.py b/src/conf_mode/system-login.py index 59ea1d34b..8aa43dd32 100755 --- a/src/conf_mode/system-login.py +++ b/src/conf_mode/system-login.py @@ -59,7 +59,7 @@ def get_config(config=None): conf = Config() base = ['system', 'login'] login = conf.get_config_dict(base, key_mangling=('-', '_'), - get_first_key=True) + no_tag_node_value_mangle=True, get_first_key=True) # users no longer existing in the running configuration need to be deleted local_users = get_local_users() @@ -246,7 +246,9 @@ def apply(login): # XXX: Should we deny using root at all? home_dir = getpwnam(user).pw_dir render(f'{home_dir}/.ssh/authorized_keys', 'login/authorized_keys.tmpl', - user_config, permission=0o600, user=user, group='users') + user_config, permission=0o600, + formater=lambda _: _.replace(""", '"'), + user=user, group='users') except Exception as e: raise ConfigError(f'Adding user "{user}" raised exception: "{e}"') diff --git a/src/conf_mode/vpn_ipsec.py b/src/conf_mode/vpn_ipsec.py deleted file mode 100755 index 969266c30..000000000 --- a/src/conf_mode/vpn_ipsec.py +++ /dev/null @@ -1,67 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (C) 2020 VyOS maintainers and contributors -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 2 or later as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. - -import os - -from sys import exit - -from vyos.config import Config -from vyos.template import render -from vyos.util import call -from vyos.util import dict_search -from vyos import ConfigError -from vyos import airbag -from pprint import pprint -airbag.enable() - -def get_config(config=None): - if config: - conf = config - else: - conf = Config() - base = ['vpn', 'nipsec'] - if not conf.exists(base): - return None - - # retrieve common dictionary keys - ipsec = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True) - return ipsec - -def verify(ipsec): - if not ipsec: - return None - -def generate(ipsec): - if not ipsec: - return None - - return ipsec - -def apply(ipsec): - if not ipsec: - return None - - pprint(ipsec) - -if __name__ == '__main__': - try: - c = get_config() - verify(c) - generate(c) - apply(c) - except ConfigError as e: - print(e) - exit(1) diff --git a/src/conf_mode/vpn_sstp.py b/src/conf_mode/vpn_sstp.py index 47367f125..11925dfa4 100755 --- a/src/conf_mode/vpn_sstp.py +++ b/src/conf_mode/vpn_sstp.py @@ -57,9 +57,7 @@ def verify(sstp): # SSL certificate checks # tmp = dict_search('ssl.ca_cert_file', sstp) - if not tmp: - raise ConfigError(f'SSL CA certificate file required!') - else: + if tmp: if not os.path.isfile(tmp): raise ConfigError(f'SSL CA certificate "{tmp}" does not exist!') diff --git a/src/etc/systemd/system/openvpn@.service.d/override.conf b/src/etc/systemd/system/openvpn@.service.d/override.conf index 7946484a3..03fe6b587 100644 --- a/src/etc/systemd/system/openvpn@.service.d/override.conf +++ b/src/etc/systemd/system/openvpn@.service.d/override.conf @@ -7,3 +7,7 @@ WorkingDirectory= WorkingDirectory=/run/openvpn ExecStart= ExecStart=/usr/sbin/openvpn --daemon openvpn-%i --config %i.conf --status %i.status 30 --writepid %i.pid +User=openvpn +Group=openvpn +AmbientCapabilities=CAP_IPC_LOCK CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_RAW CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_DAC_OVERRIDE CAP_AUDIT_WRITE +CapabilityBoundingSet=CAP_IPC_LOCK CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_RAW CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_DAC_OVERRIDE CAP_AUDIT_WRITE diff --git a/src/migration-scripts/interfaces/20-to-21 b/src/migration-scripts/interfaces/20-to-21 new file mode 100755 index 000000000..0bd858760 --- /dev/null +++ b/src/migration-scripts/interfaces/20-to-21 @@ -0,0 +1,120 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2021 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/>. + +# T3619: mirror Linux Kernel defaults for ethernet offloading options into VyOS +# CLI. See https://phabricator.vyos.net/T3619#102254 for all the details. +# T3787: Remove deprecated UDP fragmentation offloading option + +from sys import argv + +from vyos.ethtool import Ethtool +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 = ['interfaces', 'ethernet'] +config = ConfigTree(config_file) + +if not config.exists(base): + exit(0) + +for ifname in config.list_nodes(base): + eth = Ethtool(ifname) + + # If GRO is enabled by the Kernel - we reflect this on the CLI. If GRO is + # enabled via CLI but not supported by the NIC - we remove it from the CLI + configured = config.exists(base + [ifname, 'offload', 'gro']) + enabled, fixed = eth.get_generic_receive_offload() + if configured and fixed: + config.delete(base + [ifname, 'offload', 'gro']) + elif enabled and not fixed: + config.set(base + [ifname, 'offload', 'gro']) + + # If GSO is enabled by the Kernel - we reflect this on the CLI. If GSO is + # enabled via CLI but not supported by the NIC - we remove it from the CLI + configured = config.exists(base + [ifname, 'offload', 'gso']) + enabled, fixed = eth.get_generic_segmentation_offload() + if configured and fixed: + config.delete(base + [ifname, 'offload', 'gso']) + elif enabled and not fixed: + config.set(base + [ifname, 'offload', 'gso']) + + # If LRO is enabled by the Kernel - we reflect this on the CLI. If LRO is + # enabled via CLI but not supported by the NIC - we remove it from the CLI + configured = config.exists(base + [ifname, 'offload', 'lro']) + enabled, fixed = eth.get_large_receive_offload() + if configured and fixed: + config.delete(base + [ifname, 'offload', 'lro']) + elif enabled and not fixed: + config.set(base + [ifname, 'offload', 'lro']) + + # If SG is enabled by the Kernel - we reflect this on the CLI. If SG is + # enabled via CLI but not supported by the NIC - we remove it from the CLI + configured = config.exists(base + [ifname, 'offload', 'sg']) + enabled, fixed = eth.get_scatter_gather() + if configured and fixed: + config.delete(base + [ifname, 'offload', 'sg']) + elif enabled and not fixed: + config.set(base + [ifname, 'offload', 'sg']) + + # If TSO is enabled by the Kernel - we reflect this on the CLI. If TSO is + # enabled via CLI but not supported by the NIC - we remove it from the CLI + configured = config.exists(base + [ifname, 'offload', 'tso']) + enabled, fixed = eth.get_tcp_segmentation_offload() + if configured and fixed: + config.delete(base + [ifname, 'offload', 'tso']) + elif enabled and not fixed: + config.set(base + [ifname, 'offload', 'tso']) + + # Remove deprecated UDP fragmentation offloading option + if config.exists(base + [ifname, 'offload', 'ufo']): + config.delete(base + [ifname, 'offload', 'ufo']) + + # Also while processing the interface configuration, not all adapters support + # changing the speed and duplex settings. If the desired speed and duplex + # values do not work for the NIC driver, we change them back to the default + # value of "auto" - which will be applied if the CLI node is deleted. + speed_path = base + [ifname, 'speed'] + duplex_path = base + [ifname, 'duplex'] + # speed and duplex must always be set at the same time if not set to "auto" + if config.exists(speed_path) and config.exists(duplex_path): + speed = config.return_value(speed_path) + duplex = config.return_value(duplex_path) + if speed != 'auto' and duplex != 'auto': + if not eth.check_speed_duplex(speed, duplex): + config.delete(speed_path) + config.delete(duplex_path) + + # Also while processing the interface configuration, not all adapters support + # changing disabling flow-control - or change this setting. If disabling + # flow-control is not supported by the NIC, we remove the setting from CLI + flow_control_path = base + [ifname, 'disable-flow-control'] + if config.exists(flow_control_path): + if not eth.check_flow_control(): + config.delete(flow_control_path) + +try: + with open(file_name, 'w') as f: + f.write(config.to_string()) +except OSError as e: + print("Failed to save the modified config: {}".format(e)) + exit(1) diff --git a/src/migration-scripts/isis/0-to-1 b/src/migration-scripts/isis/0-to-1 new file mode 100755 index 000000000..93cbbbed5 --- /dev/null +++ b/src/migration-scripts/isis/0-to-1 @@ -0,0 +1,59 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2021 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/>. + +# T3417: migrate IS-IS tagNode to node as we can only have one IS-IS process + +from sys import argv +from sys import exit + +from vyos.configtree import ConfigTree + +if (len(argv) < 1): + print("Must specify file name!") + exit(1) + +file_name = argv[1] + +with open(file_name, 'r') as f: + config_file = f.read() + +base = ['protocols', 'isis'] +config = ConfigTree(config_file) + +if not config.exists(base): + # Nothing to do + exit(0) + +# Only one IS-IS process is supported, thus this operation is save +isis_base = base + config.list_nodes(base) + +# We need a temporary copy of the config +tmp_base = ['protocols', 'isis2'] +config.copy(isis_base, tmp_base) + +# Now it's save to delete the old configuration +config.delete(base) + +# Rename temporary copy to new final config (IS-IS domain key is static and no +# longer required to be set via CLI) +config.rename(tmp_base, 'isis') + +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/migration-scripts/system/20-to-21 b/src/migration-scripts/system/20-to-21 new file mode 100755 index 000000000..1728995de --- /dev/null +++ b/src/migration-scripts/system/20-to-21 @@ -0,0 +1,48 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2021 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/>. + +# T3795: merge "system name-servers-dhcp" into "system name-server" + +import os + +from sys import 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', 'name-servers-dhcp'] +config = ConfigTree(config_file) +if not config.exists(base): + # Nothing to do + exit(0) + +for interface in config.return_values(base): + config.set(['system', 'name-server'], value=interface, replace=False) + +config.delete(base) + +try: + with open(file_name, 'w') as f: + f.write(config.to_string()) +except OSError as e: + print("Failed to save the modified config: {}".format(e)) + exit(1) diff --git a/src/op_mode/ping.py b/src/op_mode/ping.py index 2144ab53c..60bbc0c78 100755 --- a/src/op_mode/ping.py +++ b/src/op_mode/ping.py @@ -62,8 +62,8 @@ options = { }, 'interface': { 'ping': '{command} -I {value}', - 'type': '<interface> <X.X.X.X> <h:h:h:h:h:h:h:h>', - 'help': 'Interface to use as source for ping' + 'type': '<interface>', + 'help': 'Source interface' }, 'interval': { 'ping': '{command} -i {value}', @@ -115,6 +115,10 @@ options = { 'type': '<bytes>', 'help': 'Number of bytes to send' }, + 'source-address': { + 'ping': '{command} -I {value}', + 'type': '<x.x.x.x> <h:h:h:h:h:h:h:h>', + }, 'ttl': { 'ping': '{command} -t {value}', 'type': '<ttl>', @@ -234,4 +238,4 @@ if __name__ == '__main__': # print(f'{command} {host}') os.system(f'{command} {host}') -
\ No newline at end of file + diff --git a/src/op_mode/restart_frr.py b/src/op_mode/restart_frr.py index d1b66b33f..109c8dd7b 100755 --- a/src/op_mode/restart_frr.py +++ b/src/op_mode/restart_frr.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (C) 2019 VyOS maintainers and contributors +# Copyright (C) 2019-2021 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 @@ -13,16 +13,19 @@ # # 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 sys +import os import argparse import logging -from logging.handlers import SysLogHandler -from pathlib import Path import psutil +from logging.handlers import SysLogHandler +from shutil import rmtree + from vyos.util import call +from vyos.util import ask_yes_no +from vyos.util import process_named_running +from vyos.util import makedir # some default values watchfrr = '/usr/lib/frr/watchfrr.sh' @@ -40,40 +43,45 @@ logger.setLevel(logging.INFO) def _check_safety(): try: # print warning - answer = input("WARNING: This is a potentially unsafe function! You may lose the connection to the router or active configuration after running this command. Use it at your own risk! Continue? [y/N]: ") - if not answer.lower() == "y": - logger.error("User aborted command") + if not ask_yes_no('WARNING: This is a potentially unsafe function!\n' \ + 'You may lose the connection to the router or active configuration after\n' \ + 'running this command. Use it at your own risk!\n\n' + 'Continue?'): return False # check if another restart process already running if len([process for process in psutil.process_iter(attrs=['pid', 'name', 'cmdline']) if 'python' in process.info['name'] and 'restart_frr.py' in process.info['cmdline'][1]]) > 1: - logger.error("Another restart_frr.py already running") - answer = input("Another restart_frr.py process is already running. It is unsafe to continue. Do you want to process anyway? [y/N]: ") - if not answer.lower() == "y": + message = 'Another restart_frr.py process is already running!' + logger.error(message) + if not ask_yes_no(f'\n{message} It is unsafe to continue.\n\n' \ + 'Do you want to process anyway?'): return False # check if watchfrr.sh is running - for process in psutil.process_iter(attrs=['pid', 'name', 'cmdline']): - if 'bash' in process.info['name'] and watchfrr in process.info['cmdline']: - logger.error("Another {} already running".format(watchfrr)) - answer = input("Another {} process is already running. It is unsafe to continue. Do you want to process anyway? [y/N]: ".format(watchfrr)) - if not answer.lower() == "y": - return False + tmp = os.path.basename(watchfrr) + if process_named_running(tmp): + message = f'Another {tmp} process is already running.' + logger.error(message) + if not ask_yes_no(f'{message} It is unsafe to continue.\n\n' \ + 'Do you want to process anyway?'): + return False # check if vtysh is running - for process in psutil.process_iter(attrs=['pid', 'name', 'cmdline']): - if 'vtysh' in process.info['name']: - logger.error("The vtysh is running by another task") - answer = input("The vtysh is running by another task. It is unsafe to continue. Do you want to process anyway? [y/N]: ") - if not answer.lower() == "y": - return False + if process_named_running('vtysh'): + message = 'vtysh process is executed by another task.' + logger.error(message) + if not ask_yes_no(f'{message} It is unsafe to continue.\n\n' \ + 'Do you want to process anyway?'): + return False # check if temporary directory exists - if Path(frrconfig_tmp).exists(): - logger.error("The temporary directory \"{}\" already exists".format(frrconfig_tmp)) - answer = input("The temporary directory \"{}\" already exists. It is unsafe to continue. Do you want to process anyway? [y/N]: ".format(frrconfig_tmp)) - if not answer.lower() == "y": + if os.path.exists(frrconfig_tmp): + message = f'Temporary directory "{frrconfig_tmp}" already exists!' + logger.error(message) + if not ask_yes_no(f'{message} It is unsafe to continue.\n\n' \ + 'Do you want to process anyway?'): return False + except: logger.error("Something goes wrong in _check_safety()") return False @@ -84,94 +92,68 @@ def _check_safety(): # write active config to file def _write_config(): # create temporary directory - Path(frrconfig_tmp).mkdir(parents=False, exist_ok=True) + makedir(frrconfig_tmp) # save frr.conf to it - command = "{} -n -w --config_dir {} 2> /dev/null".format(vtysh, frrconfig_tmp) + command = f'{vtysh} -n -w --config_dir {frrconfig_tmp} 2> /dev/null' return_code = call(command) - if not return_code == 0: - logger.error("Failed to save active config: \"{}\" returned exit code: {}".format(command, return_code)) + if return_code != 0: + logger.error(f'Failed to save active config: "{command}" returned exit code: {return_code}') return False - logger.info("Active config saved to {}".format(frrconfig_tmp)) + logger.info(f'Active config saved to {frrconfig_tmp}') return True # clear and remove temporary directory def _cleanup(): - tmpdir = Path(frrconfig_tmp) - try: - if tmpdir.exists(): - for file in tmpdir.iterdir(): - file.unlink() - tmpdir.rmdir() - except: - logger.error("Failed to remove temporary directory {}".format(frrconfig_tmp)) - print("Failed to remove temporary directory {}".format(frrconfig_tmp)) - -# check if daemon is running -def _daemon_check(daemon): - command = "{} print_status {}".format(watchfrr, daemon) - return_code = call(command) - if not return_code == 0: - logger.error("Daemon \"{}\" is not running".format(daemon)) - return False - - # return True if all checks were passed - return True + if os.path.isdir(frrconfig_tmp): + rmtree(frrconfig_tmp) # restart daemon def _daemon_restart(daemon): - command = "{} restart {}".format(watchfrr, daemon) + command = f'{watchfrr} restart {daemon}' return_code = call(command) if not return_code == 0: - logger.error("Failed to restart daemon \"{}\"".format(daemon)) + logger.error(f'Failed to restart daemon "{daemon}"!') return False # return True if restarted successfully - logger.info("Daemon \"{}\" restarted".format(daemon)) + logger.info(f'Daemon "{daemon}" restarted!') return True # reload old config def _reload_config(daemon): if daemon != '': - command = "{} -n -b --config_dir {} -d {} 2> /dev/null".format(vtysh, frrconfig_tmp, daemon) + command = f'{vtysh} -n -b --config_dir {frrconfig_tmp} -d {daemon} 2> /dev/null' else: - command = "{} -n -b --config_dir {} 2> /dev/null".format(vtysh, frrconfig_tmp) + command = f'{vtysh} -n -b --config_dir {frrconfig_tmp} 2> /dev/null' return_code = call(command) if not return_code == 0: - logger.error("Failed to reinstall configuration") + logger.error('Failed to re-install configuration!') return False # return True if restarted successfully - logger.info("Configuration reinstalled successfully") - return True - -# check all daemons if they are running -def _check_args_daemon(daemons): - for daemon in daemons: - if not _daemon_check(daemon): - return False + logger.info('Configuration re-installed successfully!') return True # define program arguments cmd_args_parser = argparse.ArgumentParser(description='restart frr daemons') cmd_args_parser.add_argument('--action', choices=['restart'], required=True, help='action to frr daemons') -cmd_args_parser.add_argument('--daemon', choices=['bfdd', 'bgpd', 'ospfd', 'ospf6d', 'ripd', 'ripngd', 'staticd', 'zebra'], required=False, nargs='*', help='select single or multiple daemons') +cmd_args_parser.add_argument('--daemon', choices=['bfdd', 'bgpd', 'ospfd', 'ospf6d', 'isisd', 'ripd', 'ripngd', 'staticd', 'zebra'], required=False, nargs='*', help='select single or multiple daemons') # parse arguments cmd_args = cmd_args_parser.parse_args() - # main logic # restart daemon if cmd_args.action == 'restart': # check if it is safe to restart FRR if not _check_safety(): print("\nOne of the safety checks was failed or user aborted command. Exiting.") - sys.exit(1) + exit(1) if not _write_config(): print("Failed to save active config") _cleanup() - sys.exit(1) + exit(1) # a little trick to make further commands more clear if not cmd_args.daemon: @@ -179,19 +161,20 @@ if cmd_args.action == 'restart': # check all daemons if they are running if cmd_args.daemon != ['']: - if not _check_args_daemon(cmd_args.daemon): - print("Warning: some of listed daemons are not running") + for daemon in cmd_args.daemon: + if not process_named_running(daemon): + print('WARNING: some of listed daemons are not running!') # run command to restart daemon for daemon in cmd_args.daemon: if not _daemon_restart(daemon): - print("Failed to restart daemon: {}".format(daemon)) + print('Failed to restart daemon: {daemon}') _cleanup() - sys.exit(1) + exit(1) # reinstall old configuration _reload_config(daemon) # cleanup after all actions _cleanup() -sys.exit(0) +exit(0) diff --git a/src/op_mode/show_dhcp.py b/src/op_mode/show_dhcp.py index ff1e3cc56..9f65b1bd6 100755 --- a/src/op_mode/show_dhcp.py +++ b/src/op_mode/show_dhcp.py @@ -178,7 +178,7 @@ if __name__ == '__main__': group = parser.add_mutually_exclusive_group() group.add_argument("-l", "--leases", action="store_true", help="Show DHCP leases") group.add_argument("-s", "--statistics", action="store_true", help="Show DHCP statistics") - group.add_argument("--allowed", type=str, choices=["pool", "sort", "state"], help="Show allowed values for argument") + group.add_argument("--allowed", type=str, choices=["sort", "state"], help="Show allowed values for argument") parser.add_argument("-p", "--pool", type=str, help="Show lease for specific pool") parser.add_argument("-S", "--sort", type=str, default='ip', help="Sort by") @@ -189,11 +189,7 @@ if __name__ == '__main__': conf = Config() - if args.allowed == 'pool': - if conf.exists_effective('service dhcp-server'): - print(' '.join(conf.list_effective_nodes("service dhcp-server shared-network-name"))) - exit(0) - elif args.allowed == 'sort': + if args.allowed == 'sort': print(' '.join(lease_display_fields.keys())) exit(0) elif args.allowed == 'state': diff --git a/src/op_mode/show_interfaces.py b/src/op_mode/show_interfaces.py index 79bb8e2a6..aef2d8060 100755 --- a/src/op_mode/show_interfaces.py +++ b/src/op_mode/show_interfaces.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright 2017, 2019 VyOS maintainers and contributors <maintainers@vyos.io> +# Copyright 2017-2021 VyOS maintainers and contributors <maintainers@vyos.io> # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -19,9 +19,7 @@ import os import re import sys import glob -import datetime import argparse -import netifaces from vyos.ifconfig import Section from vyos.ifconfig import Interface @@ -54,27 +52,27 @@ def filtered_interfaces(ifnames, iftypes, vif, vrrp): ifnames: a list of interfaces names to consider, empty do not filter return an instance of the interface class """ - allnames = Section.interfaces() + if isinstance(iftypes, list): + for iftype in iftypes: + yield from filtered_interfaces(ifnames, iftype, vif, vrrp) - vrrp_interfaces = VRRP.active_interfaces() if vrrp else [] - - for ifname in allnames: + for ifname in Section.interfaces(iftypes): + # Bail out early if interface name not part of our search list if ifnames and ifname not in ifnames: continue - # return the class which can handle this interface name - klass = Section.klass(ifname) - # connect to the interface - interface = klass(ifname, create=False, debug=False) - - if iftypes and interface.definition['section'] not in iftypes: - continue + # As we are only "reading" from the interface - we must use the + # generic base class which exposes all the data via a common API + interface = Interface(ifname, create=False, debug=False) + # VLAN interfaces have a '.' in their name by convention if vif and not '.' in ifname: continue - if vrrp and ifname not in vrrp_interfaces: - continue + if vrrp: + vrrp_interfaces = VRRP.active_interfaces() + if ifname not in vrrp_interfaces: + continue yield interface diff --git a/src/op_mode/show_system_integrity.py b/src/op_mode/show_system_integrity.py deleted file mode 100755 index c34d41e80..000000000 --- a/src/op_mode/show_system_integrity.py +++ /dev/null @@ -1,70 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (C) 2020 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 sys -import os -import re -import json -from datetime import datetime, timedelta - -version_file = r'/usr/share/vyos/version.json' - - -def _get_sys_build_version(): - if not os.path.exists(version_file): - return None - buf = open(version_file, 'r').read() - j = json.loads(buf) - if not 'built_on' in j: - return None - return datetime.strptime(j['built_on'], '%a %d %b %Y %H:%M %Z') - - -def _check_pkgs(build_stamp): - pkg_diffs = { - 'buildtime': str(build_stamp), - 'pkg': {} - } - - pkg_info = os.listdir('/var/lib/dpkg/info/') - for file in pkg_info: - if re.search('\.list$', file): - fts = os.stat('/var/lib/dpkg/info/' + file).st_mtime - dt_str = (datetime.utcfromtimestamp( - fts).strftime('%Y-%m-%d %H:%M:%S')) - fdt = datetime.strptime(dt_str, '%Y-%m-%d %H:%M:%S') - if fdt > build_stamp: - pkg_diffs['pkg'].update( - {str(re.sub('\.list', '', file)): str(fdt)}) - - if len(pkg_diffs['pkg']) != 0: - return pkg_diffs - else: - return None - - -if __name__ == '__main__': - built_date = _get_sys_build_version() - if not built_date: - sys.exit(1) - pkgs = _check_pkgs(built_date) - if pkgs: - print ( - "The following packages don\'t fit the image creation time\nbuild time:\t" + pkgs['buildtime']) - for k, v in pkgs['pkg'].items(): - print ("installed: " + v + '\t' + k) diff --git a/src/op_mode/show_wwan.py b/src/op_mode/show_wwan.py index 249dda2a5..529b5bd0f 100755 --- a/src/op_mode/show_wwan.py +++ b/src/op_mode/show_wwan.py @@ -34,13 +34,17 @@ required = parser.add_argument_group('Required arguments') required.add_argument("--interface", help="WWAN interface name, e.g. wwan0", required=True) def qmi_cmd(device, command, silent=False): - tmp = cmd(f'qmicli --device={device} --device-open-proxy {command}') - tmp = tmp.replace(f'[{cdc}] ', '') - if not silent: - # skip first line as this only holds the info headline - for line in tmp.splitlines()[1:]: - print(line.lstrip()) - return tmp + try: + tmp = cmd(f'qmicli --device={device} --device-open-proxy {command}') + tmp = tmp.replace(f'[{cdc}] ', '') + if not silent: + # skip first line as this only holds the info headline + for line in tmp.splitlines()[1:]: + print(line.lstrip()) + return tmp + except: + print('Command not supported by Modem') + exit(1) if __name__ == '__main__': args = parser.parse_args() diff --git a/src/services/vyos-configd b/src/services/vyos-configd index 6f770b696..670b6e66a 100755 --- a/src/services/vyos-configd +++ b/src/services/vyos-configd @@ -133,8 +133,7 @@ def explicit_print(path, mode, msg): logger.critical("error explicit_print") def run_script(script, config, args) -> int: - if args: - script.argv = args + script.argv = args config.set_level([]) try: c = script.get_config(config) @@ -208,7 +207,7 @@ def process_node_data(config, data) -> int: return R_ERROR_DAEMON script_name = None - args = None + args = [] res = re.match(r'^(VYOS_TAGNODE_VALUE=[^/]+)?.*\/([^/]+).py(.*)', data) if res.group(1): @@ -221,7 +220,7 @@ def process_node_data(config, data) -> int: return R_ERROR_DAEMON if res.group(3): args = res.group(3).split() - args.insert(0, f'{script_name}.py') + args.insert(0, f'{script_name}.py') if script_name not in include_set: return R_PASS diff --git a/src/validators/allowed-vlan b/src/validators/allowed-vlan new file mode 100755 index 000000000..11389390b --- /dev/null +++ b/src/validators/allowed-vlan @@ -0,0 +1,19 @@ +#! /usr/bin/python3 + +import sys +import re + +if __name__ == '__main__': + if len(sys.argv)>1: + allowed_vlan = sys.argv[1] + if re.search('[0-9]{1,4}-[0-9]{1,4}', allowed_vlan): + for tmp in allowed_vlan.split('-'): + if int(tmp) not in range(1, 4095): + sys.exit(1) + else: + if int(allowed_vlan) not in range(1, 4095): + sys.exit(1) + else: + sys.exit(2) + + sys.exit(0) diff --git a/src/validators/base64 b/src/validators/base64 new file mode 100755 index 000000000..e2b1e730d --- /dev/null +++ b/src/validators/base64 @@ -0,0 +1,27 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2021 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 base64 +from sys import argv + +if __name__ == '__main__': + if len(argv) != 2: + exit(1) + try: + base64.b64decode(argv[1]) + except: + exit(1) + exit(0) |