diff options
Diffstat (limited to 'data/templates')
209 files changed, 6321 insertions, 5253 deletions
diff --git a/data/templates/accel-ppp/chap-secrets.config_dict.tmpl b/data/templates/accel-ppp/chap-secrets.config_dict.j2 index da64b64d5..51e66d57c 100644 --- a/data/templates/accel-ppp/chap-secrets.config_dict.tmpl +++ b/data/templates/accel-ppp/chap-secrets.config_dict.j2 @@ -1,12 +1,10 @@ # username server password acceptable local IP addresses shaper -{% if authentication is defined and authentication.local_users is defined and authentication.local_users.username is defined %} -{% for user, user_config in authentication.local_users.username.items() %} -{% if user_config.disabled is not defined %} -{% if user_config.rate_limit is defined %} +{% if authentication.local_users.username is vyos_defined %} +{% for user, user_config in authentication.local_users.username.items() if user_config.disabled is not vyos_defined %} +{% if user_config.rate_limit is vyos_defined %} {{ "%-12s" | format(user) }} * {{ "%-16s" | format(user_config.password) }} {{ "%-16s" | format(user_config.static_ip) }} {{ user_config.rate_limit.download }}/{{ user_config.rate_limit.upload }} -{% else %} +{% else %} {{ "%-12s" | format(user) }} * {{ "%-16s" | format(user_config.password) }} {{ "%-16s" | format(user_config.static_ip) }} -{% endif %} -{% endif %} -{% endfor %} +{% endif %} +{% endfor %} {% endif %} diff --git a/data/templates/accel-ppp/chap-secrets.ipoe.tmpl b/data/templates/accel-ppp/chap-secrets.ipoe.j2 index 1df878fcf..a1430ec22 100644 --- a/data/templates/accel-ppp/chap-secrets.ipoe.tmpl +++ b/data/templates/accel-ppp/chap-secrets.ipoe.j2 @@ -1,18 +1,18 @@ # username server password acceptable local IP addresses shaper {% for interface in auth_interfaces %} -{% for mac in interface.mac %} -{% if mac.rate_upload and mac.rate_download %} -{% if mac.vlan_id %} +{% for mac in interface.mac %} +{% if mac.rate_upload and mac.rate_download %} +{% if mac.vlan_id %} {{ interface.name }}.{{ mac.vlan_id }} * {{ mac.address | lower }} * {{ mac.rate_download }}/{{ mac.rate_upload }} -{% else %} +{% else %} {{ interface.name }} * {{ mac.address | lower }} * {{ mac.rate_download }}/{{ mac.rate_upload }} -{% endif %} -{% else %} -{% if mac.vlan_id %} +{% endif %} +{% else %} +{% if mac.vlan_id %} {{ interface.name }}.{{ mac.vlan_id }} * {{ mac.address | lower }} * -{% else %} +{% else %} {{ interface.name }} * {{ mac.address | lower }} * -{% endif %} -{% endif %} -{% endfor %} +{% endif %} +{% endif %} +{% endfor %} {% endfor %} diff --git a/data/templates/accel-ppp/chap-secrets.tmpl b/data/templates/accel-ppp/chap-secrets.j2 index 6cace5401..cc3ddc28f 100644 --- a/data/templates/accel-ppp/chap-secrets.tmpl +++ b/data/templates/accel-ppp/chap-secrets.j2 @@ -1,10 +1,10 @@ # username server password acceptable local IP addresses shaper {% for user in local_users %} -{% if user.state == 'enabled' %} -{% if user.upload and user.download %} +{% if user.state == 'enabled' %} +{% if user.upload and user.download %} {{ "%-12s" | format(user.name) }} * {{ "%-16s" | format(user.password) }} {{ "%-16s" | format(user.ip) }} {{ user.download }}/{{ user.upload }} -{% else %} +{% else %} {{ "%-12s" | format(user.name) }} * {{ "%-16s" | format(user.password) }} {{ "%-16s" | format(user.ip) }} -{% endif %} -{% endif %} +{% endif %} +{% endif %} {% endfor %} diff --git a/data/templates/accel-ppp/config_chap_secrets_radius.j2 b/data/templates/accel-ppp/config_chap_secrets_radius.j2 index 49af3a228..bb820497b 100644 --- a/data/templates/accel-ppp/config_chap_secrets_radius.j2 +++ b/data/templates/accel-ppp/config_chap_secrets_radius.j2 @@ -1,33 +1,33 @@ -{% if authentication.mode is defined and authentication.mode == 'local' %} +{% if authentication.mode is vyos_defined('local') %} [chap-secrets] chap-secrets={{ chap_secrets_file }} -{% elif authentication.mode is defined and authentication.mode == 'radius' %} +{% elif authentication.mode is vyos_defined('radius') %} [radius] verbose=1 -{% for server, options in authentication.radius.server.items() if not options.disable is defined %} +{% for server, options in authentication.radius.server.items() if not options.disable is vyos_defined %} server={{ server }},{{ options.key }},auth-port={{ options.port }},acct-port={{ options.acct_port }},req-limit=0,fail-time={{ options.fail_time }} -{% endfor %} -{% if authentication.radius.acct_interim_jitter is defined and authentication.radius.acct_interim_jitter is not none %} +{% endfor %} +{% if authentication.radius.acct_interim_jitter is vyos_defined %} acct-interim-jitter={{ authentication.radius.acct_interim_jitter }} -{% endif %} +{% endif %} acct-timeout={{ authentication.radius.acct_timeout }} timeout={{ authentication.radius.timeout }} max-try={{ authentication.radius.max_try }} -{% if authentication.radius.nas_identifier is defined and authentication.radius.nas_identifier is not none %} +{% if authentication.radius.nas_identifier is vyos_defined %} nas-identifier={{ authentication.radius.nas_identifier }} -{% endif %} -{% if authentication.radius.nas_ip_address is defined and authentication.radius.nas_ip_address is not none %} +{% endif %} +{% if authentication.radius.nas_ip_address is vyos_defined %} nas-ip-address={{ authentication.radius.nas_ip_address }} -{% endif %} -{% if authentication.radius.source_address is defined and authentication.radius.source_address is not none %} +{% endif %} +{% if authentication.radius.source_address is vyos_defined %} bind={{ authentication.radius.source_address }} -{% endif %} -{% if authentication.radius.dynamic_author.server is defined and authentication.radius.dynamic_author.server is not none %} +{% endif %} +{% if authentication.radius.dynamic_author.server is vyos_defined %} dae-server={{ authentication.radius.dynamic_author.server }}:{{ authentication.radius.dynamic_author.port }},{{ authentication.radius.dynamic_author.key }} -{% endif %} +{% endif %} {% endif %} {# Both chap-secrets and radius block required the gw-ip-address #} -{% if gateway_address is defined and gateway_address is not none %} +{% if gateway_address is vyos_defined %} gw-ip-address={{ gateway_address }} {% endif %} diff --git a/data/templates/accel-ppp/config_ip_pool.j2 b/data/templates/accel-ppp/config_ip_pool.j2 index 3b0f68084..0bef4ad69 100644 --- a/data/templates/accel-ppp/config_ip_pool.j2 +++ b/data/templates/accel-ppp/config_ip_pool.j2 @@ -1,14 +1,14 @@ -{% if client_ip_pool is defined and client_ip_pool is not none %} +{% if client_ip_pool is vyos_defined %} [ip-pool] -{% if gateway_address is defined and gateway_address is not none %} +{% if gateway_address is vyos_defined %} gw-ip-address={{ gateway_address }} -{% endif %} -{% if client_ip_pool.start is defined and client_ip_pool.stop is defined and client_ip_pool.start is not none and client_ip_pool.stop is not none %} +{% endif %} +{% if client_ip_pool.start is vyos_defined and client_ip_pool.stop is vyos_defined %} {{ client_ip_pool.start }}-{{ client_ip_pool.stop.split('.')[3] }} -{% endif %} -{% if client_ip_pool.subnet is defined and client_ip_pool.subnet is not none %} -{% for subnet in client_ip_pool.subnet %} +{% endif %} +{% if client_ip_pool.subnet is vyos_defined %} +{% for subnet in client_ip_pool.subnet %} {{ subnet }} -{% endfor %} -{% endif %} +{% endfor %} +{% endif %} {% endif %} diff --git a/data/templates/accel-ppp/config_ipv6_pool.j2 b/data/templates/accel-ppp/config_ipv6_pool.j2 index f45bf9442..953469577 100644 --- a/data/templates/accel-ppp/config_ipv6_pool.j2 +++ b/data/templates/accel-ppp/config_ipv6_pool.j2 @@ -1,20 +1,20 @@ -{% if client_ipv6_pool is defined and client_ipv6_pool is not none %} +{% if client_ipv6_pool is vyos_defined %} [ipv6-nd] AdvAutonomousFlag=1 -{% if client_ipv6_pool.prefix is defined and client_ipv6_pool.prefix is not none %} +{% if client_ipv6_pool.prefix is vyos_defined %} [ipv6-pool] -{% for prefix, options in client_ipv6_pool.prefix.items() %} +{% for prefix, options in client_ipv6_pool.prefix.items() %} {{ prefix }},{{ options.mask }} -{% endfor %} -{% if client_ipv6_pool.delegate is defined and client_ipv6_pool.delegate is not none %} -{% for prefix, options in client_ipv6_pool.delegate.items() %} +{% endfor %} +{% if client_ipv6_pool.delegate is vyos_defined %} +{% for prefix, options in client_ipv6_pool.delegate.items() %} delegate={{ prefix }},{{ options.delegation_prefix }} -{% endfor %} +{% endfor %} +{% endif %} {% endif %} -{% endif %} -{% if client_ipv6_pool.delegate is defined and client_ipv6_pool.delegate is not none %} +{% if client_ipv6_pool.delegate is vyos_defined %} [ipv6-dhcp] verbose=1 -{% endif %} +{% endif %} {% endif %} diff --git a/data/templates/accel-ppp/config_modules_auth_mode.j2 b/data/templates/accel-ppp/config_modules_auth_mode.j2 index e3d578b38..3fb8a011f 100644 --- a/data/templates/accel-ppp/config_modules_auth_mode.j2 +++ b/data/templates/accel-ppp/config_modules_auth_mode.j2 @@ -1,5 +1,5 @@ -{% if authentication is defined and authentication.mode is defined and authentication.mode == 'local' %} +{% if authentication.mode is vyos_defined('local') %} chap-secrets -{% elif authentication is defined and authentication.mode is defined and authentication.mode == 'radius' %} +{% elif authentication.mode is vyos_defined('radius') %} radius {% endif %} diff --git a/data/templates/accel-ppp/config_modules_auth_protocols.j2 b/data/templates/accel-ppp/config_modules_auth_protocols.j2 index 454d37792..285468406 100644 --- a/data/templates/accel-ppp/config_modules_auth_protocols.j2 +++ b/data/templates/accel-ppp/config_modules_auth_protocols.j2 @@ -1,10 +1,10 @@ {% for protocol in authentication.protocols %} {# this should be fixed in the CLI by a migrator #} -{% if protocol == 'chap' %} +{% if protocol == 'chap' %} auth_chap_md5 -{% elif protocol == 'mschap' %} +{% elif protocol == 'mschap' %} auth_mschap_v1 -{% else %} +{% else %} auth_{{ protocol.replace('-', '_') }} -{% endif %} +{% endif %} {% endfor %} diff --git a/data/templates/accel-ppp/config_modules_ipv6.j2 b/data/templates/accel-ppp/config_modules_ipv6.j2 index 02740ce7c..6174779a5 100644 --- a/data/templates/accel-ppp/config_modules_ipv6.j2 +++ b/data/templates/accel-ppp/config_modules_ipv6.j2 @@ -1,4 +1,4 @@ -{% if ppp_options.ipv6 is defined and ppp_options.ipv6 != 'deny' %} +{% if ppp_options.ipv6 is vyos_defined and ppp_options.ipv6 is not vyos_defined('deny') %} ipv6pool ipv6_nd ipv6_dhcp diff --git a/data/templates/accel-ppp/config_name_server.j2 b/data/templates/accel-ppp/config_name_server.j2 index 2bf064f92..9c745fe62 100644 --- a/data/templates/accel-ppp/config_name_server.j2 +++ b/data/templates/accel-ppp/config_name_server.j2 @@ -1,13 +1,13 @@ -{% if name_server_ipv4 is defined and name_server_ipv4 is not none %} +{% if name_server_ipv4 is vyos_defined %} [dns] -{% for ns in name_server_ipv4 %} +{% for ns in name_server_ipv4 %} dns{{ loop.index }}={{ ns }} -{% endfor %} +{% endfor %} {% endif %} -{% if name_server_ipv6 is defined and name_server_ipv6 is not none %} +{% if name_server_ipv6 is vyos_defined %} [ipv6-dns] -{% for ns in name_server_ipv6 %} +{% for ns in name_server_ipv6 %} {{ ns }} -{% endfor %} +{% endfor %} {% endif %} diff --git a/data/templates/accel-ppp/config_shaper_radius.j2 b/data/templates/accel-ppp/config_shaper_radius.j2 index 8de5f5df3..942cdf132 100644 --- a/data/templates/accel-ppp/config_shaper_radius.j2 +++ b/data/templates/accel-ppp/config_shaper_radius.j2 @@ -1,10 +1,13 @@ -{% if authentication is defined and authentication.mode is defined and authentication.mode == 'radius' %} -{% if authentication is defined and authentication.radius is defined and authentication.radius.rate_limit is defined and authentication.radius.rate_limit.enable is defined %} +{% if authentication.mode is vyos_defined('radius') %} +{% if authentication.radius.rate_limit.enable is vyos_defined %} [shaper] verbose=1 attr={{ authentication.radius.rate_limit.attribute }} -{% if authentication.radius.rate_limit.vendor is defined and authentication.radius.rate_limit.vendor is not none %} +{% if authentication.radius.rate_limit.vendor is vyos_defined %} vendor={{ authentication.radius.rate_limit.vendor }} +{% endif %} +{% if authentication.radius.rate_limit.multiplier is vyos_defined %} +rate-multiplier={{ authentication.radius.rate_limit.multiplier }} +{% endif %} {% endif %} -{% endif %} {% endif %} diff --git a/data/templates/accel-ppp/ipoe.config.j2 b/data/templates/accel-ppp/ipoe.config.j2 new file mode 100644 index 000000000..3c0d47b27 --- /dev/null +++ b/data/templates/accel-ppp/ipoe.config.j2 @@ -0,0 +1,142 @@ +{# j2lint: disable=operator-enclosed-by-spaces #} +### generated by ipoe.py ### +[modules] +log_syslog +ipoe +shaper +ipv6pool +ipv6_nd +ipv6_dhcp +ippool +{% if auth_mode == 'radius' %} +radius +{% elif auth_mode == 'local' %} +chap-secrets +{% endif %} + +[core] +thread-count={{ thread_cnt }} + +[log] +syslog=accel-ipoe,daemon +copy=1 +level=5 + +[ipoe] +verbose=1 +{% for interface in interfaces %} +{% set tmp = 'interface=' %} +{% if interface.vlan_mon %} +{% set tmp = tmp ~ 're:' ~ interface.name ~ '\.\d+' %} +{% else %} +{% set tmp = tmp ~ interface.name %} +{% endif %} +{{ tmp }},shared={{ interface.shared }},mode={{ interface.mode }},ifcfg={{ interface.ifcfg }}{{ ',range=' ~ interface.range if interface.range is defined and interface.range is not none }},start={{ interface.sess_start }},ipv6=1 +{% endfor %} +{% if auth_mode == 'noauth' %} +noauth=1 +{% if client_named_ip_pool %} +{% for pool in client_named_ip_pool %} +{% if pool.subnet is defined %} +ip-pool={{ pool.name }} +{% endif %} +{% if pool.gateway_address is defined %} +gw-ip-address={{ pool.gateway_address }}/{{ pool.subnet.split('/')[1] }} +{% endif %} +{% endfor %} +{% endif %} +{% elif auth_mode == 'local' %} +username=ifname +password=csid +{% endif %} +proxy-arp=1 + +{% for interface in interfaces %} +{% if (interface.shared == '0') and (interface.vlan_mon) %} +vlan-mon={{ interface.name }},{{ interface.vlan_mon | join(',') }} +{% endif %} +{% endfor %} + +{% if dnsv4 %} +[dns] +{% for dns in dnsv4 %} +dns{{ loop.index }}={{ dns }} +{% endfor %} +{% endif %} + +{% if dnsv6 %} +[ipv6-dns] +{% for dns in dnsv6 %} +{{ dns }} +{% endfor %} +{% endif %} + +[ipv6-nd] +verbose=1 + +[ipv6-dhcp] +verbose=1 + +{% if client_named_ip_pool %} +[ip-pool] +{% for pool in client_named_ip_pool %} +{% if pool.subnet is defined %} +{{ pool.subnet }},name={{ pool.name }} +{% endif %} +{% if pool.gateway_address is defined %} +gw-ip-address={{ pool.gateway_address }}/{{ pool.subnet.split('/')[1] }} +{% endif %} +{% endfor %} +{% endif %} + +{% if client_ipv6_pool %} +[ipv6-pool] +{% for p in client_ipv6_pool %} +{{ p.prefix }},{{ p.mask }} +{% endfor %} +{% for p in client_ipv6_delegate_prefix %} +delegate={{ p.prefix }},{{ p.mask }} +{% endfor %} +{% endif %} + +{% if auth_mode == 'local' %} +[chap-secrets] +chap-secrets={{ chap_secrets_file }} +{% elif auth_mode == 'radius' %} +[radius] +verbose=1 +{% for r in radius_server %} +server={{ r.server }},{{ r.key }},auth-port={{ r.port }},acct-port={{ r.acct_port }},req-limit=0,fail-time={{ r.fail_time }} +{% endfor %} + +{% if radius_acct_inter_jitter %} +acct-interim-jitter={{ radius_acct_inter_jitter }} +{% endif %} + +acct-timeout={{ radius_acct_tmo }} +timeout={{ radius_timeout }} +max-try={{ radius_max_try }} +{% if radius_nas_id %} +nas-identifier={{ radius_nas_id }} +{% endif %} +{% if radius_nas_ip %} +nas-ip-address={{ radius_nas_ip }} +{% endif %} +{% if radius_source_address %} +bind={{ radius_source_address }} +{% endif %} +{% if radius_dynamic_author %} +dae-server={{ radius_dynamic_author.server }}:{{ radius_dynamic_author.port }},{{ radius_dynamic_author.key }} +{% endif %} +{% if radius_shaper_attr %} +[shaper] +verbose=1 +attr={{ radius_shaper_attr }} +{% if radius_shaper_vendor %} +vendor={{ radius_shaper_vendor }} +{% endif %} +{% endif %} +{% endif %} + +[cli] +tcp=127.0.0.1:2002 diff --git a/data/templates/accel-ppp/ipoe.config.tmpl b/data/templates/accel-ppp/ipoe.config.tmpl deleted file mode 100644 index 1cf2ab0be..000000000 --- a/data/templates/accel-ppp/ipoe.config.tmpl +++ /dev/null @@ -1,116 +0,0 @@ -### generated by ipoe.py ### -[modules] -log_syslog -ipoe -shaper -ipv6pool -ipv6_nd -ipv6_dhcp -ippool -{% if auth_mode == 'radius' %} -radius -{% elif auth_mode == 'local' %} -chap-secrets -{% endif %} - -[core] -thread-count={{ thread_cnt }} - -[log] -syslog=accel-ipoe,daemon -copy=1 -level=5 - -[ipoe] -verbose=1 -{% for interface in interfaces %} -{% if interface.vlan_mon %} -interface=re:{{ interface.name }}\.\d+,{% else %}interface={{ interface.name }},{% endif %}shared={{ interface.shared }},mode={{ interface.mode }},ifcfg={{ interface.ifcfg }},range={{ interface.range }},start={{ interface.sess_start }},ipv6=1 -{% endfor %} -{% if auth_mode == 'noauth' %} -noauth=1 -{% elif auth_mode == 'local' %} -username=ifname -password=csid -{% endif %} -proxy-arp=1 - -{% for interface in interfaces %} -{% if (interface.shared == '0') and (interface.vlan_mon) %} -vlan-mon={{ interface.name }},{{ interface.vlan_mon | join(',') }} -{% endif %} -{% endfor %} - -{% if dnsv4 %} -[dns] -{% for dns in dnsv4 %} -dns{{ loop.index }}={{ dns }} -{% endfor %} -{% endif %} - -{% if dnsv6 %} -[ipv6-dns] -{% for dns in dnsv6 %} -{{ dns }} -{% endfor %} -{% endif %} - -[ipv6-nd] -verbose=1 - -[ipv6-dhcp] -verbose=1 - -{% if client_ipv6_pool %} -[ipv6-pool] -{% for p in client_ipv6_pool %} -{{ p.prefix }},{{ p.mask }} -{% endfor %} -{% for p in client_ipv6_delegate_prefix %} -delegate={{ p.prefix }},{{ p.mask }} -{% endfor %} -{% endif %} - -{% if auth_mode == 'local' %} -[chap-secrets] -chap-secrets={{ chap_secrets_file }} -{% elif auth_mode == 'radius' %} -[radius] -verbose=1 -{% for r in radius_server %} -server={{ r.server }},{{ r.key }},auth-port={{ r.port }},acct-port={{ r.acct_port }},req-limit=0,fail-time={{ r.fail_time }} -{% endfor %} - -{% if radius_acct_inter_jitter %} -acct-interim-jitter={{ radius_acct_inter_jitter }} -{% endif %} - -acct-timeout={{ radius_acct_tmo }} -timeout={{ radius_timeout }} -max-try={{ radius_max_try }} -{% if radius_nas_id %} -nas-identifier={{ radius_nas_id }} -{% endif %} -{% if radius_nas_ip %} -nas-ip-address={{ radius_nas_ip }} -{% endif %} -{% if radius_source_address %} -bind={{ radius_source_address }} -{% endif %} - -{% if radius_dynamic_author %} -dae-server={{ radius_dynamic_author.server }}:{{ radius_dynamic_author.port }},{{ radius_dynamic_author.key }} -{% endif %} - -{% if radius_shaper_attr %} -[shaper] -verbose=1 -attr={{ radius_shaper_attr }} -{% if radius_shaper_vendor %} -vendor={{ radius_shaper_vendor }} -{% endif %} -{% endif %} -{% endif %} - -[cli] -tcp=127.0.0.1:2002 diff --git a/data/templates/accel-ppp/l2tp.config.tmpl b/data/templates/accel-ppp/l2tp.config.j2 index 9fcda76d4..9eeaf7622 100644 --- a/data/templates/accel-ppp/l2tp.config.tmpl +++ b/data/templates/accel-ppp/l2tp.config.j2 @@ -3,9 +3,9 @@ log_syslog l2tp chap-secrets -{% for proto in auth_proto: %} -{{proto}} -{% endfor%} +{% for proto in auth_proto %} +{{ proto }} +{% endfor %} {% if auth_mode == 'radius' %} radius @@ -18,7 +18,7 @@ ipv6_nd ipv6_dhcp [core] -thread-count={{thread_cnt}} +thread-count={{ thread_cnt }} [log] syslog=accel-l2tp,daemon @@ -27,23 +27,23 @@ level=5 {% if dnsv4 %} [dns] -{% for dns in dnsv4 %} +{% for dns in dnsv4 %} dns{{ loop.index }}={{ dns }} -{% endfor %} +{% endfor %} {% endif %} {% if dnsv6 %} [ipv6-dns] -{% for dns in dnsv6 %} +{% for dns in dnsv6 %} {{ dns }} -{% endfor %} +{% endfor %} {% endif %} {% if wins %} [wins] -{% for server in wins %} +{% for server in wins %} wins{{ loop.index }}={{ server }} -{% endfor %} +{% endfor %} {% endif %} [l2tp] @@ -66,14 +66,14 @@ host-name={{ lns_host_name }} {% if client_ip_pool or client_ip_subnets %} [ip-pool] -{% if client_ip_pool %} +{% if client_ip_pool %} {{ client_ip_pool }} -{% endif %} -{% if client_ip_subnets %} -{% for sn in client_ip_subnets %} -{{sn}} -{% endfor %} -{% endif %} +{% endif %} +{% if client_ip_subnets %} +{% for sn in client_ip_subnets %} +{{ sn }} +{% endfor %} +{% endif %} {% endif %} {% if gateway_address %} gw-ip-address={{ gateway_address }} @@ -85,27 +85,24 @@ chap-secrets={{ chap_secrets_file }} {% elif auth_mode == 'radius' %} [radius] verbose=1 -{% for r in radius_server %} +{% for r in radius_server %} server={{ r.server }},{{ r.key }},auth-port={{ r.port }},acct-port={{ r.acct_port }},req-limit=0,fail-time={{ r.fail_time }} -{% endfor %} - -{% if radius_acct_inter_jitter %} +{% endfor %} +{% if radius_acct_inter_jitter %} acct-interim-jitter={{ radius_acct_inter_jitter }} -{% endif %} - +{% endif %} acct-timeout={{ radius_acct_tmo }} timeout={{ radius_timeout }} max-try={{ radius_max_try }} - -{% if radius_nas_id %} +{% if radius_nas_id %} nas-identifier={{ radius_nas_id }} -{% endif %} -{% if radius_nas_ip %} +{% endif %} +{% if radius_nas_ip %} nas-ip-address={{ radius_nas_ip }} -{% endif %} -{% if radius_source_address %} +{% endif %} +{% if radius_source_address %} bind={{ radius_source_address }} -{% endif %} +{% endif %} {% endif %} {% if gateway_address %} gw-ip-address={{ gateway_address }} @@ -128,12 +125,12 @@ ipv6=allow {% if client_ipv6_pool %} [ipv6-pool] -{% for p in client_ipv6_pool %} +{% for p in client_ipv6_pool %} {{ p.prefix }},{{ p.mask }} -{% endfor %} -{% for p in client_ipv6_delegate_prefix %} +{% endfor %} +{% for p in client_ipv6_delegate_prefix %} delegate={{ p.prefix }},{{ p.mask }} -{% endfor %} +{% endfor %} {% endif %} {% if client_ipv6_delegate_prefix %} @@ -145,9 +142,9 @@ verbose=1 [shaper] verbose=1 attr={{ radius_shaper_attr }} -{% if radius_shaper_vendor %} +{% if radius_shaper_vendor %} vendor={{ radius_shaper_vendor }} -{% endif %} +{% endif %} {% endif %} [cli] diff --git a/data/templates/accel-ppp/pppoe.config.j2 b/data/templates/accel-ppp/pppoe.config.j2 new file mode 100644 index 000000000..0a92e2d54 --- /dev/null +++ b/data/templates/accel-ppp/pppoe.config.j2 @@ -0,0 +1,172 @@ +### generated by accel_pppoe.py ### +[modules] +log_syslog +pppoe +shaper +{# Common authentication backend definitions #} +{% include 'accel-ppp/config_modules_auth_mode.j2' %} +ippool +{# Common IPv6 definitions #} +{% include 'accel-ppp/config_modules_ipv6.j2' %} +{# Common authentication protocols (pap, chap ...) #} +{% include 'accel-ppp/config_modules_auth_protocols.j2' %} + +{% if snmp is vyos_defined %} +net-snmp +{% endif %} +{% if limits is vyos_defined %} +connlimit +{% endif %} +{% if extended_scripts is vyos_defined %} +sigchld +pppd_compat +{% endif %} + +[core] +thread-count={{ thread_count }} + +[log] +syslog=accel-pppoe,daemon +copy=1 +level=5 + +{% if snmp.master_agent is vyos_defined %} +[snmp] +master=1 +{% endif %} + +[client-ip-range] +disable + +{# Common IP pool definitions #} +{% include 'accel-ppp/config_ip_pool.j2' %} + +{# Common IPv6 pool definitions #} +{% include 'accel-ppp/config_ipv6_pool.j2' %} + +{# Common DNS name-server definition #} +{% include 'accel-ppp/config_name_server.j2' %} + +{% if wins_server is vyos_defined %} +[wins] +{% for server in wins_server %} +wins{{ loop.index }}={{ server }} +{% endfor %} +{% endif %} + +{# Common chap-secrets and RADIUS server/option definitions #} +{% include 'accel-ppp/config_chap_secrets_radius.j2' %} + +{% if session_control is vyos_defined and session_control is not vyos_defined('disable') %} +[common] +single-session={{ session_control }} +{% endif %} + +[ppp] +verbose=1 +check-ip=1 +ccp={{ "1" if ppp_options.ccp is vyos_defined else "0" }} +unit-preallocate={{ "1" if authentication.radius.preallocate_vif is vyos_defined else "0" }} +{% if ppp_options.min_mtu is vyos_defined %} +min-mtu={{ ppp_options.min_mtu }} +{% else %} +min-mtu={{ mtu }} +{% endif %} +{% if ppp_options.mru is vyos_defined %} +mru={{ ppp_options.mru }} +{% endif %} +mppe={{ ppp_options.mppe }} +lcp-echo-interval={{ ppp_options.lcp_echo_interval }} +lcp-echo-timeout={{ ppp_options.lcp_echo_timeout }} +lcp-echo-failure={{ ppp_options.lcp_echo_failure }} +{% if ppp_options.ipv4 is vyos_defined %} +ipv4={{ ppp_options.ipv4 }} +{% endif %} +{# IPv6 #} +{% if ppp_options.ipv6 is vyos_defined %} +ipv6={{ ppp_options.ipv6 }} +{% if ppp_options.ipv6_intf_id is vyos_defined %} +ipv6-intf-id={{ ppp_options.ipv6_intf_id }} +{% endif %} +{% if ppp_options.ipv6_peer_intf_id is vyos_defined %} +ipv6-peer-intf-id={{ ppp_options.ipv6_peer_intf_id }} +{% endif %} +ipv6-accept-peer-intf-id={{ "1" if ppp_options.ipv6_accept_peer_intf_id is vyos_defined else "0" }} +{% endif %} +{# MTU #} +mtu={{ mtu }} +{% if ppp_options.interface_cache is vyos_defined %} +unit-cache={{ ppp_options.interface_cache }} +{% endif %} + +[pppoe] +verbose=1 +ac-name={{ access_concentrator }} + +{% if interface is vyos_defined %} +{% for iface, iface_config in interface.items() %} +{% if iface_config.vlan_id is not vyos_defined and iface_config.vlan_range is not vyos_defined %} +interface={{ iface }} +{% endif %} +{% if iface_config.vlan_range is vyos_defined %} +{% for regex in iface_config.regex %} +interface=re:^{{ iface | replace('.', '\\.') }}\.({{ regex }})$ +{% endfor %} +vlan-mon={{ iface }},{{ iface_config.vlan_range | join(',') }} +{% endif %} +{% if iface_config.vlan_id is vyos_defined %} +{% for vlan in iface_config.vlan_id %} +vlan-mon={{ iface }},{{ vlan }} +interface=re:^{{ iface | replace('.', '\\.') }}\.{{ vlan }}$ +{% endfor %} +{% endif %} +{% endfor %} +{% endif %} + +{% if service_name %} +service-name={{ service_name | join(',') }} +{% endif %} + +{% if pado_delay %} +{% set pado_delay_param = namespace(value='0') %} +{% for delay in pado_delay | sort(attribute='0') %} +{% if not loop.last %} +{% set pado_delay_param.value = pado_delay_param.value + ',' + delay + ':' + pado_delay[delay].sessions %} +{% else %} +{% set pado_delay_param.value = pado_delay_param.value + ',-1:' + pado_delay[delay].sessions %} +{% endif %} +{% endfor %} +pado-delay={{ pado_delay_param.value }} +{% endif %} +{% if authentication.radius.called_sid_format is vyos_defined %} +called-sid={{ authentication.radius.called_sid_format }} +{% endif %} + +{% if limits is vyos_defined %} +[connlimit] +{% if limits.connection_limit is vyos_defined %} +limit={{ limits.connection_limit }} +{% endif %} +{% if limits.burst is vyos_defined %} +burst={{ limits.burst }} +{% endif %} +{% if limits.timeout is vyos_defined %} +timeout={{ limits.timeout }} +{% endif %} +{% endif %} + +{# Common RADIUS shaper configuration #} +{% include 'accel-ppp/config_shaper_radius.j2' %} + +{% if extended_scripts is vyos_defined %} +[pppd-compat] +verbose=1 +radattr-prefix=/run/accel-pppd/radattr +{% set script_name = {'on_up': 'ip-up', 'on_down': 'ip-down', 'on_change':'ip-change', 'on_pre_up':'ip-pre-up'} %} +{% for script in extended_scripts %} +{{ script_name[script] }}={{ extended_scripts[script] }} +{% endfor %} +{% endif %} + +[cli] +tcp=127.0.0.1:2001 diff --git a/data/templates/accel-ppp/pppoe.config.tmpl b/data/templates/accel-ppp/pppoe.config.tmpl deleted file mode 100644 index 238e7ee15..000000000 --- a/data/templates/accel-ppp/pppoe.config.tmpl +++ /dev/null @@ -1,174 +0,0 @@ -### generated by accel_pppoe.py ### -[modules] -log_syslog -pppoe -shaper -{# Common authentication backend definitions #} -{% include 'accel-ppp/config_modules_auth_mode.j2' %} -ippool -{# Common IPv6 definitions #} -{% include 'accel-ppp/config_modules_ipv6.j2' %} -{# Common authentication protocols (pap, chap ...) #} -{% include 'accel-ppp/config_modules_auth_protocols.j2' %} - -{% if snmp is defined %} -net-snmp -{% endif %} -{% if limits is defined %} -connlimit -{% endif %} -{% if extended_scripts is defined %} -sigchld -pppd_compat -{% endif %} - -[core] -thread-count={{ thread_count }} - -[log] -syslog=accel-pppoe,daemon -copy=1 -level=5 - -{% if snmp is defined and snmp.master_agent is defined %} -[snmp] -master=1 -{% endif %} - -[client-ip-range] -disable - -{# Common IP pool definitions #} -{% include 'accel-ppp/config_ip_pool.j2' %} - -{# Common IPv6 pool definitions #} -{% include 'accel-ppp/config_ipv6_pool.j2' %} - -{# Common DNS name-server definition #} -{% include 'accel-ppp/config_name_server.j2' %} - -{% if wins_server is defined and wins_server is not none %} -[wins] -{% for server in wins_server %} -wins{{ loop.index }}={{ server }} -{% endfor %} -{% endif %} - -{# Common chap-secrets and RADIUS server/option definitions #} -{% include 'accel-ppp/config_chap_secrets_radius.j2' %} - -{% if session_control is defined and session_control != 'disable' %} -[common] -single-session={{ session_control }} -{% endif %} - -[ppp] -verbose=1 -check-ip=1 -ccp={{ "1" if ppp_options.ccp is defined else "0" }} -unit-preallocate={{ "1" if authentication.radius.preallocate_vif is defined else "0" }} -{% if ppp_options.min_mtu is defined and ppp_options.min_mtu is not none %} -min-mtu={{ ppp_options.min_mtu }} -{% else %} -min-mtu={{ mtu }} -{% endif %} -{% if ppp_options.mru is defined and ppp_options.mru is not none %} -mru={{ ppp_options.mru }} -{% endif %} -mppe={{ ppp_options.mppe }} -lcp-echo-interval={{ ppp_options.lcp_echo_interval }} -lcp-echo-timeout={{ ppp_options.lcp_echo_timeout }} -lcp-echo-failure={{ ppp_options.lcp_echo_failure }} -{% if ppp_options.ipv4 is defined and ppp_options.ipv4 is not none %} -ipv4={{ ppp_options.ipv4 }} -{% endif %} -{# IPv6 #} -{% if ppp_options.ipv6 is defined and ppp_options.ipv6 is not none %} -ipv6={{ ppp_options.ipv6 }} -{% if ppp_options.ipv6_intf_id is defined and ppp_options.ipv6_intf_id is not none %} -ipv6-intf-id={{ ppp_options.ipv6_intf_id }} -{% endif %} -{% if ppp_options.ipv6_peer_intf_id is defined and ppp_options.ipv6_peer_intf_id is not none %} -ipv6-peer-intf-id={{ ppp_options.ipv6_peer_intf_id }} -{% endif %} -ipv6-accept-peer-intf-id={{ "1" if ppp_options.ipv6_accept_peer_intf_id is defined else "0" }} -{% endif %} -{# MTU #} -mtu={{ mtu }} -{% if ppp_options.interface_cache is defined and ppp_options.interface_cache is not none %} -unit-cache={{ ppp_options.interface_cache }} -{% endif %} - -[pppoe] -verbose=1 -ac-name={{ access_concentrator }} - -{% if interface is defined and interface is not none %} -{% for iface, iface_config in interface.items() %} -{% if iface_config.vlan_id is not defined and iface_config.vlan_range is not defined %} -interface={{ iface }} -{% endif %} -{% if iface_config.vlan_id is defined and iface_config.vlan_range is not defined %} -{% for vlan in iface_config.vlan_id %} -interface={{ iface }}.{{ vlan }} -vlan-mon={{ iface }},{{ vlan }} -{% endfor %} -{% endif %} -{% if iface_config.vlan_range is defined and iface_config.vlan_id is not defined %} -vlan-mon={{ iface }},{{ iface_config.vlan_range | join(',') }} -interface=re:{{ iface | replace('.', '\\.') }}\.\d+ -{% endif %} -{% if iface_config.vlan_id is defined and iface_config.vlan_range is defined %} -vlan-mon={{ iface }},{{ iface_config.vlan_id | join(',') }},{{ iface_config.vlan_range | join(',') }} -interface=re:{{ iface | replace('.', '\\.') }}\.\d+ -{% endif %} -{% endfor %} -{% endif %} - -{% if service_name %} -service-name={{ service_name | join(',') }} -{% endif %} - -{% if pado_delay %} -{% set pado_delay_param = namespace(value='0') %} -{% for delay in pado_delay|sort(attribute='0') %} -{% if not loop.last %} -{% set pado_delay_param.value = pado_delay_param.value + ',' + delay + ':' + pado_delay[delay].sessions %} -{% else %} -{% set pado_delay_param.value = pado_delay_param.value + ',-1:' + pado_delay[delay].sessions %} -{% endif %} -{% endfor %} -pado-delay={{ pado_delay_param.value }} -{% endif %} -{% if authentication.radius.called_sid_format is defined and authentication.radius.called_sid_format is not none %} -called-sid={{ authentication.radius.called_sid_format }} -{% endif %} - -{% if limits is defined %} -[connlimit] -{% if limits.connection_limit is defined and limits.connection_limit is not none %} -limit={{ limits.connection_limit }} -{% endif %} -{% if limits.burst is defined and limits.burst %} -burst={{ limits.burst }} -{% endif %} -{% if limits.timeout is defined and limits.timeout is not none %} -timeout={{ limits.timeout }} -{% endif %} -{% endif %} - -{# Common RADIUS shaper configuration #} -{% include 'accel-ppp/config_shaper_radius.j2' %} - -{% if extended_scripts is defined %} -[pppd-compat] -verbose=1 -radattr-prefix=/run/accel-pppd/radattr -{% set script_name = {'on_up': 'ip-up', 'on_down': 'ip-down', 'on_change':'ip-change', 'on_pre_up':'ip-pre-up'} %} -{% for script in extended_scripts %} -{{ script_name[script] }}={{ extended_scripts[script] }} -{% endfor %} -{% endif %} - -[cli] -tcp=127.0.0.1:2001 diff --git a/data/templates/accel-ppp/pptp.config.tmpl b/data/templates/accel-ppp/pptp.config.j2 index 3cfc4a906..cc1a45d6b 100644 --- a/data/templates/accel-ppp/pptp.config.tmpl +++ b/data/templates/accel-ppp/pptp.config.j2 @@ -10,7 +10,7 @@ radius {% endif %} ippool {% for proto in auth_proto %} -{{proto}} +{{ proto }} {% endfor %} [core] @@ -23,16 +23,16 @@ level=5 {% if dnsv4 %} [dns] -{% for dns in dnsv4 %} +{% for dns in dnsv4 %} dns{{ loop.index }}={{ dns }} -{% endfor %} +{% endfor %} {% endif %} {% if wins %} [wins] -{% for server in wins %} +{% for server in wins %} wins{{ loop.index }}={{ server }} -{% endfor %} +{% endfor %} {% endif %} @@ -42,7 +42,7 @@ ifname=pptp%d bind={{ outside_addr }} {% endif %} verbose=1 -ppp-max-mtu={{mtu}} +ppp-max-mtu={{ mtu }} mppe={{ ppp_mppe }} echo-interval=10 echo-failure=3 @@ -66,27 +66,27 @@ chap-secrets={{ chap_secrets_file }} {% elif auth_mode == 'radius' %} [radius] verbose=1 -{% for r in radius_server %} +{% for r in radius_server %} server={{ r.server }},{{ r.key }},auth-port={{ r.port }},acct-port={{ r.acct_port }},req-limit=0,fail-time={{ r.fail_time }} -{% endfor %} +{% endfor %} -{% if radius_acct_inter_jitter %} +{% if radius_acct_inter_jitter %} acct-interim-jitter={{ radius_acct_inter_jitter }} -{% endif %} +{% endif %} acct-timeout={{ radius_acct_tmo }} timeout={{ radius_timeout }} max-try={{ radius_max_try }} -{% if radius_nas_id %} +{% if radius_nas_id %} nas-identifier={{ radius_nas_id }} -{% endif %} -{% if radius_nas_ip %} +{% endif %} +{% if radius_nas_ip %} nas-ip-address={{ radius_nas_ip }} -{% endif %} -{% if radius_source_address %} +{% endif %} +{% if radius_source_address %} bind={{ radius_source_address }} -{% endif %} +{% endif %} {% endif %} {# Both chap-secrets and radius block required the gw-ip-address #} {% if gw_ip is defined and gw_ip is not none %} diff --git a/data/templates/accel-ppp/sstp.config.tmpl b/data/templates/accel-ppp/sstp.config.j2 index 8fd7d230d..5c6f19306 100644 --- a/data/templates/accel-ppp/sstp.config.tmpl +++ b/data/templates/accel-ppp/sstp.config.j2 @@ -50,7 +50,7 @@ verbose=1 check-ip=1 {# MTU #} mtu={{ mtu }} -ipv6={{ 'allow' if ppp_options.ipv6 == "deny" and client_ipv6_pool is defined else ppp_options.ipv6 }} +ipv6={{ 'allow' if ppp_options.ipv6 is vyos_defined("deny") and client_ipv6_pool is vyos_defined else ppp_options.ipv6 }} ipv4={{ ppp_options.ipv4 }} mppe={{ ppp_options.mppe }} diff --git a/data/templates/bcast-relay/udp-broadcast-relay.j2 b/data/templates/bcast-relay/udp-broadcast-relay.j2 new file mode 100644 index 000000000..75740e04c --- /dev/null +++ b/data/templates/bcast-relay/udp-broadcast-relay.j2 @@ -0,0 +1,5 @@ +### Autogenerated by bcast_relay.py ### + +# UDP broadcast relay configuration for instance {{ id }} +{{ '# ' ~ description if description is vyos_defined }} +DAEMON_ARGS="{{ '-s ' ~ address if address is vyos_defined }} {{ instance }} {{ port }} {{ interface | join(' ') }}" diff --git a/data/templates/bcast-relay/udp-broadcast-relay.tmpl b/data/templates/bcast-relay/udp-broadcast-relay.tmpl deleted file mode 100644 index 73e9acad4..000000000 --- a/data/templates/bcast-relay/udp-broadcast-relay.tmpl +++ /dev/null @@ -1,7 +0,0 @@ -### Autogenerated by bcast_relay.py ### - -# UDP broadcast relay configuration for instance {{ id }} -{% if description %} -# Comment: {{ description }} -{% endif %} -DAEMON_ARGS="{{ '-s ' + address if address is defined }} {{ instance }} {{ port }} {{ interface | join(' ') }}" diff --git a/data/templates/conntrack/nftables-ct.j2 b/data/templates/conntrack/nftables-ct.j2 new file mode 100644 index 000000000..16a03fc6e --- /dev/null +++ b/data/templates/conntrack/nftables-ct.j2 @@ -0,0 +1,48 @@ +#!/usr/sbin/nft -f + +{% set nft_ct_ignore_name = 'VYOS_CT_IGNORE' %} +{% set nft_ct_timeout_name = 'VYOS_CT_TIMEOUT' %} + +# we first flush all chains and render the content from scratch - this makes +# any delta check obsolete +flush chain raw {{ nft_ct_ignore_name }} +flush chain raw {{ nft_ct_timeout_name }} + +table raw { + chain {{ nft_ct_ignore_name }} { +{% if ignore.rule is vyos_defined %} +{% for rule, rule_config in ignore.rule.items() %} + # rule-{{ rule }} {{ '- ' ~ rule_config.description if rule_config.description is vyos_defined }} +{% set nft_command = '' %} +{% if rule_config.inbound_interface is vyos_defined %} +{% set nft_command = nft_command ~ ' iifname ' ~ rule_config.inbound_interface %} +{% endif %} +{% if rule_config.protocol is vyos_defined %} +{% set nft_command = nft_command ~ ' ip protocol ' ~ rule_config.protocol %} +{% endif %} +{% if rule_config.destination.address is vyos_defined %} +{% set nft_command = nft_command ~ ' ip daddr ' ~ rule_config.destination.address %} +{% endif %} +{% if rule_config.destination.port is vyos_defined %} +{% set nft_command = nft_command ~ ' ' ~ rule_config.protocol ~ ' dport { ' ~ rule_config.destination.port ~ ' }' %} +{% endif %} +{% if rule_config.source.address is vyos_defined %} +{% set nft_command = nft_command ~ ' ip saddr ' ~ rule_config.source.address %} +{% endif %} +{% if rule_config.source.port is vyos_defined %} +{% set nft_command = nft_command ~ ' ' ~ rule_config.protocol ~ ' sport { ' ~ rule_config.source.port ~ ' }' %} +{% endif %} + {{ nft_command }} counter notrack comment ignore-{{ rule }} +{% endfor %} +{% endif %} + return + } + chain {{ nft_ct_timeout_name }} { +{% if timeout.custom.rule is vyos_defined %} +{% for rule, rule_config in timeout.custom.rule.items() %} + # rule-{{ rule }} {{ '- ' ~ rule_config.description if rule_config.description is vyos_defined }} +{% endfor %} +{% endif %} + return + } +} diff --git a/data/templates/conntrack/sysctl.conf.tmpl b/data/templates/conntrack/sysctl.conf.j2 index 9e97c3286..075402c04 100644 --- a/data/templates/conntrack/sysctl.conf.tmpl +++ b/data/templates/conntrack/sysctl.conf.j2 @@ -6,7 +6,7 @@ net.netfilter.nf_conntrack_max = {{ table_size }} net.ipv4.tcp_max_syn_backlog = {{ tcp.half_open_connections }} -net.netfilter.nf_conntrack_tcp_loose = {{ '1' if tcp.loose == 'enable' else '0' }} +net.netfilter.nf_conntrack_tcp_loose = {{ '1' if tcp.loose is vyos_defined('enable') else '0' }} net.netfilter.nf_conntrack_tcp_max_retrans = {{ tcp.max_retrans }} net.netfilter.nf_conntrack_icmp_timeout = {{ timeout.icmp }} diff --git a/data/templates/conntrack/vyos_nf_conntrack.conf.tmpl b/data/templates/conntrack/vyos_nf_conntrack.conf.j2 index 111459485..111459485 100644 --- a/data/templates/conntrack/vyos_nf_conntrack.conf.tmpl +++ b/data/templates/conntrack/vyos_nf_conntrack.conf.j2 diff --git a/data/templates/conntrackd/conntrackd.conf.tmpl b/data/templates/conntrackd/conntrackd.conf.j2 index 45b7bff09..66024869d 100644 --- a/data/templates/conntrackd/conntrackd.conf.tmpl +++ b/data/templates/conntrackd/conntrackd.conf.j2 @@ -3,45 +3,45 @@ # Synchronizer settings Sync { Mode FTFW { - DisableExternalCache {{ 'on' if disable_external_cache is defined else 'off' }} + DisableExternalCache {{ 'on' if disable_external_cache is vyos_defined else 'off' }} } {% for iface, iface_config in interface.items() %} -{% if iface_config.peer is defined and iface_config.peer is not none %} +{% if iface_config.peer is vyos_defined %} UDP { -{% if listen_address is defined and listen_address is not none %} +{% if listen_address is vyos_defined %} IPv4_address {{ listen_address }} -{% endif %} +{% endif %} IPv4_Destination_Address {{ iface_config.peer }} - Port {{ iface_config.port if iface_config.port is defined else '3780' }} + Port {{ iface_config.port if iface_config.port is vyos_defined else '3780' }} Interface {{ iface }} SndSocketBuffer {{ sync_queue_size | int *1024 *1024 }} RcvSocketBuffer {{ sync_queue_size | int *1024 *1024 }} Checksum on } -{% else %} +{% else %} Multicast { -{% set ip_address = iface | get_ipv4 %} +{% set ip_address = iface | get_ipv4 %} IPv4_address {{ mcast_group }} - Group {{ iface_config.port if iface_config.port is defined else '3780' }} + Group {{ iface_config.port if iface_config.port is vyos_defined else '3780' }} IPv4_interface {{ ip_address[0] | ip_from_cidr }} Interface {{ iface }} SndSocketBuffer {{ sync_queue_size | int *1024 *1024 }} RcvSocketBuffer {{ sync_queue_size | int *1024 *1024 }} Checksum on } -{% endif %} +{% endif %} {% endfor %} -{% if expect_sync is defined and expect_sync is not none %} +{% if expect_sync is vyos_defined %} Options { -{% if 'all' in expect_sync %} +{% if 'all' in expect_sync %} ExpectationSync on -{% else %} +{% else %} ExpectationSync { -{% for protocol in expect_sync %} +{% for protocol in expect_sync %} {{ protocol }} -{% endfor %} +{% endfor %} } -{% endif %} +{% endif %} } {% endif %} } @@ -83,29 +83,29 @@ General { NetlinkBufferSizeMaxGrowth {{ event_listen_queue_size | int *1024 *1024 }} NetlinkOverrunResync off NetlinkEventsReliable on -{% if ignore_address is defined or accept_protocol is defined %} +{% if ignore_address is vyos_defined or accept_protocol is vyos_defined %} Filter From Userspace { -{% if ignore_address is defined and ignore_address is not none %} +{% if ignore_address is vyos_defined %} Address Ignore { -{% for address in ignore_address if address | is_ipv4 %} +{% for address in ignore_address if address | is_ipv4 %} IPv4_address {{ address }} -{% endfor %} -{% for address in ignore_address if address | is_ipv6 %} +{% endfor %} +{% for address in ignore_address if address | is_ipv6 %} IPv6_address {{ address }} -{% endfor %} +{% endfor %} } -{% endif %} -{% if accept_protocol is defined and accept_protocol is not none %} +{% endif %} +{% if accept_protocol is vyos_defined %} Protocol Accept { -{% for protocol in accept_protocol %} -{% if protocol == 'icmp6' %} +{% for protocol in accept_protocol %} +{% if protocol == 'icmp6' %} IPv6-ICMP -{% else %} +{% else %} {{ protocol | upper }} -{% endif %} -{% endfor %} +{% endif %} +{% endfor %} } -{% endif %} +{% endif %} } {% endif %} } diff --git a/data/templates/conntrackd/conntrackd.op-mode.j2 b/data/templates/conntrackd/conntrackd.op-mode.j2 new file mode 100644 index 000000000..82f7e2859 --- /dev/null +++ b/data/templates/conntrackd/conntrackd.op-mode.j2 @@ -0,0 +1,13 @@ +Source Destination Protocol +{% for parsed in data if parsed.flow.meta is vyos_defined %} +{% for key in parsed.flow.meta %} +{% if key['@direction'] == 'original' %} +{% set saddr = key.layer3.src | bracketize_ipv6 %} +{% set sport = key.layer4.sport %} +{% set daddr = key.layer3.dst | bracketize_ipv6 %} +{% set dport = key.layer4.dport %} +{% set protocol = key.layer4['@protoname'] %} +{{ "%-48s" | format(saddr ~ ':' ~ sport) }} {{ "%-48s" | format(daddr ~ ':' ~ dport) }} {{ protocol }} +{% endif %} +{% endfor %} +{% endfor %} diff --git a/data/templates/conntrackd/conntrackd.op-mode.tmpl b/data/templates/conntrackd/conntrackd.op-mode.tmpl deleted file mode 100644 index 82a4b09ad..000000000 --- a/data/templates/conntrackd/conntrackd.op-mode.tmpl +++ /dev/null @@ -1,13 +0,0 @@ -Source Destination Protocol -{% for parsed in data if parsed.flow is defined and parsed.flow.meta is defined %} -{% for key in parsed.flow.meta %} -{% if key['@direction'] == 'original' %} -{% set saddr = key.layer3.src | bracketize_ipv6 %} -{% set sport = key.layer4.sport %} -{% set daddr = key.layer3.dst | bracketize_ipv6 %} -{% set dport = key.layer4.dport %} -{% set protocol = key.layer4['@protoname'] %} -{{ "%-48s" | format(saddr ~ ':' ~ sport) }} {{ "%-48s" | format(daddr ~ ':' ~ dport) }} {{ protocol }} -{% endif %} -{% endfor %} -{% endfor %} diff --git a/data/templates/conserver/conserver.conf.tmpl b/data/templates/conserver/conserver.conf.j2 index 4e7b5d8d7..1823657d7 100644 --- a/data/templates/conserver/conserver.conf.tmpl +++ b/data/templates/conserver/conserver.conf.j2 @@ -17,7 +17,7 @@ default * { ## {% for key, value in device.items() %} {# Depending on our USB serial console we could require a path adjustment #} -{% set path = '/dev' if key.startswith('ttyS') else '/dev/serial/by-bus' %} +{% set path = '/dev' if key.startswith('ttyS') else '/dev/serial/by-bus' %} console {{ key }} { master localhost; type device; diff --git a/data/templates/conserver/dropbear@.service.tmpl b/data/templates/conserver/dropbear@.service.j2 index e355dab43..e355dab43 100644 --- a/data/templates/conserver/dropbear@.service.tmpl +++ b/data/templates/conserver/dropbear@.service.j2 diff --git a/data/templates/container/registries.conf.j2 b/data/templates/container/registries.conf.j2 new file mode 100644 index 000000000..2e86466a1 --- /dev/null +++ b/data/templates/container/registries.conf.j2 @@ -0,0 +1,27 @@ +### Autogenerated by container.py ### + +# For more information on this configuration file, see containers-registries.conf(5). +# +# NOTE: RISK OF USING UNQUALIFIED IMAGE NAMES +# We recommend always using fully qualified image names including the registry +# server (full dns name), namespace, image name, and tag +# (e.g., registry.redhat.io/ubi8/ubi:latest). Pulling by digest (i.e., +# quay.io/repository/name@digest) further eliminates the ambiguity of tags. +# When using short names, there is always an inherent risk that the image being +# pulled could be spoofed. For example, a user wants to pull an image named +# `foobar` from a registry and expects it to come from myregistry.com. If +# myregistry.com is not first in the search list, an attacker could place a +# different `foobar` image at a registry earlier in the search list. The user +# would accidentally pull and run the attacker's image and code rather than the +# intended content. We recommend only adding registries which are completely +# trusted (i.e., registries which don't allow unknown or anonymous users to +# create accounts with arbitrary names). This will prevent an image from being +# spoofed, squatted or otherwise made insecure. If it is necessary to use one +# of these registries, it should be added at the end of the list. +# +# An array of host[:port] registries to try when pulling an unqualified image, in order. +# unqualified-search-registries = ["example.com"] + +{% if registry is vyos_defined %} +unqualified-search-registries = {{ registry }} +{% endif %} diff --git a/data/templates/container/storage.conf.j2 b/data/templates/container/storage.conf.j2 new file mode 100644 index 000000000..665f9bf95 --- /dev/null +++ b/data/templates/container/storage.conf.j2 @@ -0,0 +1,4 @@ +### Autogenerated by container.py ### +[storage] + driver = "vfs" + graphroot = "/usr/lib/live/mount/persistence/container/storage" diff --git a/data/templates/containers/registry.tmpl b/data/templates/containers/registry.tmpl deleted file mode 100644 index 0347de673..000000000 --- a/data/templates/containers/registry.tmpl +++ /dev/null @@ -1,5 +0,0 @@ -### Autogenerated by /usr/libexec/vyos/conf_mode/containers.py ### - -{% if registry is defined and registry is not none %} -unqualified-search-registries = {{ registry }} -{% endif %} diff --git a/data/templates/containers/storage.tmpl b/data/templates/containers/storage.tmpl deleted file mode 100644 index 3a69b7252..000000000 --- a/data/templates/containers/storage.tmpl +++ /dev/null @@ -1,5 +0,0 @@ -### Autogenerated by /usr/libexec/vyos/conf_mode/containers.py ### - -[storage] - driver = "vfs" - graphroot = "/config/containers/storage" diff --git a/data/templates/dhcp-client/daemon-options.j2 b/data/templates/dhcp-client/daemon-options.j2 new file mode 100644 index 000000000..b21ad08ab --- /dev/null +++ b/data/templates/dhcp-client/daemon-options.j2 @@ -0,0 +1,4 @@ +### Autogenerated by interface.py ### +{% set if_metric = '-e IF_METRIC=' ~ dhcp_options.default_route_distance if dhcp_options.default_route_distance is vyos_defined else '' %} +DHCLIENT_OPTS="-nw -cf /var/lib/dhcp/dhclient_{{ ifname }}.conf -pf /var/lib/dhcp/dhclient_{{ ifname }}.pid -lf /var/lib/dhcp/dhclient_{{ ifname }}.leases {{ if_metric }} {{ ifname }}" + diff --git a/data/templates/dhcp-client/daemon-options.tmpl b/data/templates/dhcp-client/daemon-options.tmpl deleted file mode 100644 index 40629dca1..000000000 --- a/data/templates/dhcp-client/daemon-options.tmpl +++ /dev/null @@ -1,4 +0,0 @@ -### Autogenerated by interface.py ### - -DHCLIENT_OPTS="-nw -cf /var/lib/dhcp/dhclient_{{ifname}}.conf -pf /var/lib/dhcp/dhclient_{{ifname}}.pid -lf /var/lib/dhcp/dhclient_{{ifname}}.leases{{" -e IF_METRIC=" ~ dhcp_options.default_route_distance if dhcp_options.default_route_distance is defined and dhcp_options.default_route_distance is not none}} {{ifname}}" - diff --git a/data/templates/dhcp-client/ipv4.tmpl b/data/templates/dhcp-client/ipv4.j2 index b3e74c22b..cc5ddf09c 100644 --- a/data/templates/dhcp-client/ipv4.tmpl +++ b/data/templates/dhcp-client/ipv4.j2 @@ -7,26 +7,26 @@ initial-interval 2; interface "{{ ifname }}" { send host-name "{{ dhcp_options.host_name }}"; -{% if dhcp_options.client_id is defined and dhcp_options.client_id is not none %} -{% set client_id = dhcp_options.client_id %} +{% if dhcp_options.client_id is vyos_defined %} +{% set client_id = dhcp_options.client_id %} {# Use HEX representation of client-id as it is send in MAC-address style using hex characters. If not HEX, use double quotes ASCII format #} -{% if not dhcp_options.client_id.split(':') | length >= 5 %} -{% set client_id = '"' + dhcp_options.client_id + '"' %} -{% endif %} - send dhcp-client-identifier {{ client_id }}; +{% if not dhcp_options.client_id.split(':') | length >= 5 %} +{% set client_id = '"' + dhcp_options.client_id + '"' %} +{% endif %} + send dhcp-client-identifier {{ client_id }}; {% endif %} -{% if dhcp_options.vendor_class_id is defined and dhcp_options.vendor_class_id is not none %} +{% if dhcp_options.vendor_class_id is vyos_defined %} send vendor-class-identifier "{{ dhcp_options.vendor_class_id }}"; {% endif %} # The request statement causes the client to request that any server responding to the # client send the client its values for the specified options. - request subnet-mask, broadcast-address,{{ " routers," if dhcp_options.no_default_route is not defined }} domain-name-servers, + request subnet-mask, broadcast-address,{{ " routers," if dhcp_options.no_default_route is not vyos_defined }} domain-name-servers, rfc3442-classless-static-routes, domain-name, interface-mtu; # The require statement lists options that must be sent in order for an offer to be # accepted. Offers that do not contain all the listed options will be ignored! require subnet-mask; -{% if dhcp_options.reject is defined and dhcp_options.reject is not none %} +{% if dhcp_options.reject is vyos_defined %} # Block addresses coming from theses dhcp servers if configured. reject {{ dhcp_options.reject | join(', ') }}; {% endif %} diff --git a/data/templates/dhcp-client/ipv6.j2 b/data/templates/dhcp-client/ipv6.j2 new file mode 100644 index 000000000..e136b1789 --- /dev/null +++ b/data/templates/dhcp-client/ipv6.j2 @@ -0,0 +1,60 @@ +### Autogenerated by interface.py ### + +# man https://www.unix.com/man-page/debian/5/dhcp6c.conf/ +interface {{ ifname }} { +{% if dhcpv6_options.duid is vyos_defined %} + send client-id {{ dhcpv6_options.duid }}; +{% endif %} +{% if address is vyos_defined and 'dhcpv6' in address %} + request domain-name-servers; + request domain-name; +{% if dhcpv6_options.parameters_only is vyos_defined %} + information-only; +{% endif %} +{% if dhcpv6_options.temporary is not vyos_defined %} + send ia-na 0; # non-temporary address +{% endif %} +{% if dhcpv6_options.rapid_commit is vyos_defined %} + send rapid-commit; # wait for immediate reply instead of advertisements +{% endif %} +{% endif %} +{% if dhcpv6_options.pd is vyos_defined %} +{% for pd in dhcpv6_options.pd %} + send ia-pd {{ pd }}; # prefix delegation #{{ pd }} +{% endfor %} +{% endif %} +}; + +{% if address is vyos_defined and 'dhcpv6' in address %} +{% if dhcpv6_options.temporary is not vyos_defined %} +id-assoc na 0 { + # Identity association for non temporary address +}; +{% endif %} +{% endif %} + +{% if dhcpv6_options.pd is vyos_defined %} +{% for pd, pd_config in dhcpv6_options.pd.items() %} +id-assoc pd {{ pd }} { +{# length got a default value #} + prefix ::/{{ pd_config.length }} infinity; +{% set sla_len = 64 - pd_config.length | int %} +{% set count = namespace(value=0) %} +{% for interface, interface_config in pd_config.interface.items() if pd_config.interface is vyos_defined %} + prefix-interface {{ interface }} { + sla-len {{ sla_len }}; +{% if interface_config.sla_id is vyos_defined %} + sla-id {{ interface_config.sla_id }}; +{% else %} + sla-id {{ count.value }}; +{% endif %} +{% if interface_config.address is vyos_defined %} + ifid {{ interface_config.address }}; +{% endif %} + }; +{% set count.value = count.value + 1 %} +{% endfor %} +}; +{% endfor %} +{% endif %} + diff --git a/data/templates/dhcp-client/ipv6.tmpl b/data/templates/dhcp-client/ipv6.tmpl deleted file mode 100644 index c292664e9..000000000 --- a/data/templates/dhcp-client/ipv6.tmpl +++ /dev/null @@ -1,60 +0,0 @@ -### Autogenerated by interface.py ### - -# man https://www.unix.com/man-page/debian/5/dhcp6c.conf/ -interface {{ ifname }} { -{% if dhcpv6_options is defined and dhcpv6_options.duid is defined and dhcpv6_options.duid is not none %} - send client-id {{ dhcpv6_options.duid }}; -{% endif %} -{% if address is defined and 'dhcpv6' in address %} - request domain-name-servers; - request domain-name; -{% if dhcpv6_options is defined and dhcpv6_options.parameters_only is defined %} - information-only; -{% endif %} -{% if dhcpv6_options is not defined or dhcpv6_options.temporary is not defined %} - send ia-na 0; # non-temporary address -{% endif %} -{% if dhcpv6_options is defined and dhcpv6_options.rapid_commit is defined %} - send rapid-commit; # wait for immediate reply instead of advertisements -{% endif %} -{% endif %} -{% if dhcpv6_options is defined and dhcpv6_options.pd is defined %} -{% for pd in dhcpv6_options.pd %} - send ia-pd {{ pd }}; # prefix delegation #{{ pd }} -{% endfor %} -{% endif %} -}; - -{% if address is defined and 'dhcpv6' in address %} -{% if dhcpv6_options is not defined or dhcpv6_options.temporary is not defined %} -id-assoc na 0 { - # Identity association for non temporary address -}; -{% endif %} -{% endif %} - -{% if dhcpv6_options is defined and dhcpv6_options.pd is defined %} -{% for pd in dhcpv6_options.pd %} -id-assoc pd {{ pd }} { -{# length got a default value #} - prefix ::/{{ dhcpv6_options.pd[pd].length }} infinity; -{% set sla_len = 64 - dhcpv6_options.pd[pd].length|int %} -{% set count = namespace(value=0) %} -{% for interface in dhcpv6_options.pd[pd].interface if dhcpv6_options.pd[pd].interface is defined %} - prefix-interface {{ interface }} { - sla-len {{ sla_len }}; -{% if dhcpv6_options.pd[pd].interface[interface].sla_id is defined and dhcpv6_options.pd[pd].interface[interface].sla_id is not none %} - sla-id {{ dhcpv6_options.pd[pd].interface[interface].sla_id }}; -{% else %} - sla-id {{ count.value }}; -{% endif %} -{% if dhcpv6_options.pd[pd].interface[interface].address is defined and dhcpv6_options.pd[pd].interface[interface].address is not none %} - ifid {{ dhcpv6_options.pd[pd].interface[interface].address }}; -{% endif %} - }; -{% set count.value = count.value + 1 %} -{% endfor %} -}; -{% endfor %} -{% endif %} - diff --git a/data/templates/dhcp-relay/dhcrelay.conf.tmpl b/data/templates/dhcp-relay/dhcrelay.conf.j2 index a9d17ed9a..11710bd8e 100644 --- a/data/templates/dhcp-relay/dhcrelay.conf.tmpl +++ b/data/templates/dhcp-relay/dhcrelay.conf.j2 @@ -1,6 +1,6 @@ ### Autogenerated by dhcp_relay.py ### -{% set max_size = '-A ' + relay_options.max_size if relay_options.max_size is defined and relay_options.max_size is not none %} +{% set max_size = '-A ' ~ relay_options.max_size if relay_options.max_size is vyos_defined %} {# hop_count and relay_agents_packets is a default option, thus it is always present #} OPTIONS="-c {{ relay_options.hop_count }} -a -m {{ relay_options.relay_agents_packets }} {{ max_size }} -i {{ interface | join(' -i ') }} {{ server | join(' ') }}" diff --git a/data/templates/dhcp-relay/dhcrelay6.conf.j2 b/data/templates/dhcp-relay/dhcrelay6.conf.j2 new file mode 100644 index 000000000..6365346b4 --- /dev/null +++ b/data/templates/dhcp-relay/dhcrelay6.conf.j2 @@ -0,0 +1,21 @@ +### Autogenerated by dhcpv6_relay.py ### + +{# upstream_interface is mandatory so it's always present #} +{% set upstream = namespace(value='') %} +{% for interface, config in upstream_interface.items() %} +{% for address in config.address %} +{% set upstream.value = upstream.value ~ '-u ' ~ address ~ '%' ~ interface ~ ' ' %} +{% endfor %} +{% endfor %} +{# listen_interface is mandatory so it's always present #} +{% set listen = namespace(value='') %} +{% for interface, config in listen_interface.items() %} +{% if config.address is vyos_defined %} +{% set listen.value = listen.value ~ '-l ' ~ config.address ~ '%' ~ interface ~ ' ' %} +{% else %} +{% set listen.value = listen.value ~ '-l ' ~ interface ~ ' ' %} +{% endif %} +{% endfor %} + +OPTIONS="{{ listen.value }} {{ upstream.value }} -c {{ max_hop_count }} {{ '-I' if use_interface_id_option is vyos_defined }}" + diff --git a/data/templates/dhcp-relay/dhcrelay6.conf.tmpl b/data/templates/dhcp-relay/dhcrelay6.conf.tmpl deleted file mode 100644 index 58c216b7c..000000000 --- a/data/templates/dhcp-relay/dhcrelay6.conf.tmpl +++ /dev/null @@ -1,21 +0,0 @@ -### Autogenerated by dhcpv6_relay.py ### - -{# upstream_interface is mandatory so it's always present #} -{% set upstream = namespace(value='') %} -{% for interface, config in upstream_interface.items() %} -{% for address in config.address %} -{% set upstream.value = upstream.value + '-u ' + address + '%' + interface + ' ' %} -{% endfor %} -{% endfor %} -{# listen_interface is mandatory so it's always present #} -{% set listen = namespace(value='') %} -{% for interface, config in listen_interface.items() %} -{% if config.address is defined and config.address is not none %} -{% set listen.value = listen.value + '-l ' + config.address + '%' + interface + ' ' %} -{% else %} -{% set listen.value = listen.value + '-l ' + interface + ' ' %} -{% endif %} -{% endfor %} - -OPTIONS="{{ listen.value }} {{ upstream.value }} -c {{ max_hop_count }} {{ '-I' if use_interface_id_option is defined }}" - diff --git a/data/templates/dhcp-server/dhcpd.conf.j2 b/data/templates/dhcp-server/dhcpd.conf.j2 new file mode 100644 index 000000000..4c2da0aa5 --- /dev/null +++ b/data/templates/dhcp-server/dhcpd.conf.j2 @@ -0,0 +1,246 @@ +### Autogenerated by dhcp_server.py ### + +# For options please consult the following website: +# https://www.isc.org/wp-content/uploads/2017/08/dhcp43options.html +# +# log-facility local7; +{% if hostfile_update is vyos_defined %} +on release { + set ClientName = pick-first-value(host-decl-name, option fqdn.hostname, option host-name); + set ClientIp = binary-to-ascii(10, 8, ".",leased-address); + execute("/usr/libexec/vyos/system/on-dhcp-event.sh", "release", "", ClientIp, "", ""); +} +on expiry { + set ClientName = pick-first-value(host-decl-name, option fqdn.hostname, option host-name); + set ClientIp = binary-to-ascii(10, 8, ".",leased-address); + execute("/usr/libexec/vyos/system/on-dhcp-event.sh", "release", "", ClientIp, "", ""); +} +{% endif %} + +{{ 'use-host-decl-names on;' if host_decl_name is vyos_defined }} +ddns-update-style {{ 'interim' if dynamic_dns_update is vyos_defined else 'none' }}; +option rfc3442-static-route code 121 = array of integer 8; +option windows-static-route code 249 = array of integer 8; +option wpad-url code 252 = text; + +# Vendor specific options - Ubiquiti Networks +option space ubnt; +option ubnt.unifi-controller code 1 = ip-address; +class "ubnt" { + match if substring (option vendor-class-identifier , 0, 4) = "ubnt"; + option vendor-class-identifier "ubnt"; + vendor-option-space ubnt; +} + +{% if global_parameters is vyos_defined %} +# The following {{ global_parameters | length }} line(s) have been added as +# global-parameters in the CLI and have not been validated !!! +{% for parameter in global_parameters %} +{{ parameter }} +{% endfor %} + +{% endif %} +{% if failover is vyos_defined %} +# DHCP failover configuration +failover peer "{{ failover.name }}" { +{% if failover.status == 'primary' %} + primary; + mclt 1800; + split 128; +{% elif failover.status == 'secondary' %} + secondary; +{% endif %} + address {{ failover.source_address }}; + port 647; + peer address {{ failover.remote }}; + peer port 647; + max-response-delay 30; + max-unacked-updates 10; + load balance max seconds 3; +} +{% endif %} +{% if listen_address is vyos_defined %} + +# DHCP server serving relay subnet, we need a connector to the real world +{% for address in listen_address %} +# Connected subnet statement for listen-address {{ address }} +subnet {{ address | network_from_ipv4 }} netmask {{ address | netmask_from_ipv4 }} { } +{% endfor %} +{% endif %} + +# Shared network configration(s) +{% if shared_network_name is vyos_defined %} +{% for network, network_config in shared_network_name.items() if network_config.disable is not vyos_defined %} +shared-network {{ network }} { +{% if network_config.authoritative is vyos_defined %} + authoritative; +{% endif %} +{% if network_config.name_server is vyos_defined %} + option domain-name-servers {{ network_config.name_server | join(', ') }}; +{% endif %} +{% if network_config.domain_name is vyos_defined %} + option domain-name "{{ network_config.domain_name }}"; +{% endif %} +{% if network_config.domain_search is vyos_defined %} + option domain-search "{{ network_config.domain_search | join('", "') }}"; +{% endif %} +{% if network_config.ntp_server is vyos_defined %} + option ntp-servers {{ network_config.ntp_server | join(', ') }}; +{% endif %} +{% if network_config.ping_check is vyos_defined %} + ping-check true; +{% endif %} +{% if network_config.shared_network_parameters is vyos_defined %} + # The following {{ network_config.shared_network_parameters | length }} line(s) + # were added as shared-network-parameters in the CLI and have not been validated +{% for parameter in network_config.shared_network_parameters %} + {{ parameter }} +{% endfor %} +{% endif %} +{% if network_config.subnet is vyos_defined %} +{% for subnet, subnet_config in network_config.subnet.items() %} +{% if subnet_config.description is vyos_defined %} + # {{ subnet_config.description }} +{% endif %} + subnet {{ subnet | address_from_cidr }} netmask {{ subnet | netmask_from_cidr }} { +{% if subnet_config.name_server is vyos_defined %} + option domain-name-servers {{ subnet_config.name_server | join(', ') }}; +{% endif %} +{% if subnet_config.domain_name is vyos_defined %} + option domain-name "{{ subnet_config.domain_name }}"; +{% endif %} +{% if subnet_config.domain_search is vyos_defined %} + option domain-search "{{ subnet_config.domain_search | join('", "') }}"; +{% endif %} +{% if subnet_config.ntp_server is vyos_defined %} + option ntp-servers {{ subnet_config.ntp_server | join(', ') }}; +{% endif %} +{% if subnet_config.pop_server is vyos_defined %} + option pop-server {{ subnet_config.pop_server | join(', ') }}; +{% endif %} +{% if subnet_config.smtp_server is vyos_defined %} + option smtp-server {{ subnet_config.smtp_server | join(', ') }}; +{% endif %} +{% if subnet_config.time_server is vyos_defined %} + option time-servers {{ subnet_config.time_server | join(', ') }}; +{% endif %} +{% if subnet_config.wins_server is vyos_defined %} + option netbios-name-servers {{ subnet_config.wins_server | join(', ') }}; +{% endif %} +{% if subnet_config.static_route is vyos_defined %} +{% set static_default_route = '' %} +{% if subnet_config.default_router is vyos_defined %} +{% set static_default_route = ', ' ~ '0.0.0.0/0' | isc_static_route(subnet_config.default_router) %} +{% endif %} +{% if subnet_config.static_route is vyos_defined %} +{% set rfc3442_routes = [] %} +{% for route, route_options in subnet_config.static_route.items() %} +{% set rfc3442_routes = rfc3442_routes.append(route | isc_static_route(route_options.next_hop)) %} +{% endfor %} + option rfc3442-static-route {{ rfc3442_routes | join(', ') }}{{ static_default_route }}; + option windows-static-route {{ rfc3442_routes | join(', ') }}; +{% endif %} +{% endif %} +{% if subnet_config.ip_forwarding is vyos_defined %} + option ip-forwarding true; +{% endif %} +{% if subnet_config.default_router is vyos_defined %} + option routers {{ subnet_config.default_router }}; +{% endif %} +{% if subnet_config.server_identifier is vyos_defined %} + option dhcp-server-identifier {{ subnet_config.server_identifier }}; +{% endif %} +{% if subnet_config.subnet_parameters is vyos_defined %} + # The following {{ subnet_config.subnet_parameters | length }} line(s) were added as + # subnet-parameters in the CLI and have not been validated!!! +{% for parameter in subnet_config.subnet_parameters %} + {{ parameter }} +{% endfor %} +{% endif %} +{% if subnet_config.tftp_server_name is vyos_defined %} + option tftp-server-name "{{ subnet_config.tftp_server_name }}"; +{% endif %} +{% if subnet_config.bootfile_name is vyos_defined %} + option bootfile-name "{{ subnet_config.bootfile_name }}"; + filename "{{ subnet_config.bootfile_name }}"; +{% endif %} +{% if subnet_config.bootfile_server is vyos_defined %} + next-server {{ subnet_config.bootfile_server }}; +{% endif %} +{% if subnet_config.bootfile_size is vyos_defined %} + option boot-size {{ subnet_config.bootfile_size }}; +{% endif %} +{% if subnet_config.time_offset is vyos_defined %} + option time-offset {{ subnet_config.time_offset }}; +{% endif %} +{% if subnet_config.wpad_url is vyos_defined %} + option wpad-url "{{ subnet_config.wpad_url }}"; +{% endif %} +{% if subnet_config.client_prefix_length is vyos_defined %} + option subnet-mask {{ ('0.0.0.0/' ~ subnet_config.client_prefix_length) | netmask_from_cidr }}; +{% endif %} +{% if subnet_config.lease is vyos_defined %} + default-lease-time {{ subnet_config.lease }}; + max-lease-time {{ subnet_config.lease }}; +{% endif %} +{% if network_config.ping_check is not vyos_defined and subnet_config.ping_check is vyos_defined %} + ping-check true; +{% endif %} +{% if subnet_config.static_mapping is vyos_defined %} +{% for host, host_config in subnet_config.static_mapping.items() if host_config.disable is not vyos_defined %} + host {{ host | replace('_','-') if host_decl_name is vyos_defined else network | replace('_','-') ~ '_' ~ host | replace('_','-') }} { +{% if host_config.ip_address is vyos_defined %} + fixed-address {{ host_config.ip_address }}; +{% endif %} + hardware ethernet {{ host_config.mac_address }}; +{% if host_config.static_mapping_parameters is vyos_defined %} + # The following {{ host_config.static_mapping_parameters | length }} line(s) were added + # as static-mapping-parameters in the CLI and have not been validated +{% for parameter in host_config.static_mapping_parameters %} + {{ parameter }} +{% endfor %} +{% endif %} + } +{% endfor %} +{% endif %} +{% if subnet_config.vendor_option.ubiquiti.unifi_controller is vyos_defined %} + option ubnt.unifi-controller {{ subnet_config.vendor_option.ubiquiti.unifi_controller }}; +{% endif %} +{% if subnet_config.range is vyos_defined %} +{# pool configuration can only be used if there follows a range option #} + pool { +{% endif %} +{% if subnet_config.enable_failover is vyos_defined %} + failover peer "{{ failover.name }}"; + deny dynamic bootp clients; +{% endif %} +{% if subnet_config.range is vyos_defined %} +{% for range, range_options in subnet_config.range.items() %} + range {{ range_options.start }} {{ range_options.stop }}; +{% endfor %} +{% endif %} +{% if subnet_config.range is vyos_defined %} +{# pool configuration can only be used if there follows a range option #} + } +{% endif %} + } +{% endfor %} +{% endif %} + on commit { + set shared-networkname = "{{ network }}"; +{% if hostfile_update is vyos_defined %} + set ClientIp = binary-to-ascii(10, 8, ".", leased-address); + set ClientMac = binary-to-ascii(16, 8, ":", substring(hardware, 1, 6)); + set ClientName = pick-first-value(host-decl-name, option fqdn.hostname, option host-name, "empty_hostname"); + if not (ClientName = "empty_hostname") { + set ClientDomain = pick-first-value(config-option domain-name, "..YYZ!"); + execute("/usr/libexec/vyos/system/on-dhcp-event.sh", "commit", ClientName, ClientIp, ClientMac, ClientDomain); + } else { + log(concat("Hostname is not defined for client with IP: ", ClientIP, " MAC: ", ClientMac)); + } +{% endif %} + } +} + +{% endfor %} +{% endif %} diff --git a/data/templates/dhcp-server/dhcpd.conf.tmpl b/data/templates/dhcp-server/dhcpd.conf.tmpl deleted file mode 100644 index 233e2cc53..000000000 --- a/data/templates/dhcp-server/dhcpd.conf.tmpl +++ /dev/null @@ -1,231 +0,0 @@ -### Autogenerated by dhcp_server.py ### - -# For options please consult the following website: -# https://www.isc.org/wp-content/uploads/2017/08/dhcp43options.html -# -# log-facility local7; -{% if hostfile_update is defined %} -on release { - set ClientName = pick-first-value(host-decl-name, option fqdn.hostname, option host-name); - set ClientIp = binary-to-ascii(10, 8, ".",leased-address); - execute("/usr/libexec/vyos/system/on-dhcp-event.sh", "release", "", ClientIp, "", ""); -} -on expiry { - set ClientName = pick-first-value(host-decl-name, option fqdn.hostname, option host-name); - set ClientIp = binary-to-ascii(10, 8, ".",leased-address); - execute("/usr/libexec/vyos/system/on-dhcp-event.sh", "release", "", ClientIp, "", ""); -} -{% endif %} - -{{ 'use-host-decl-names on;' if host_decl_name is defined }} -ddns-update-style {{ 'interim' if dynamic_dns_update is defined else 'none' }}; -option rfc3442-static-route code 121 = array of integer 8; -option windows-static-route code 249 = array of integer 8; -option wpad-url code 252 = text; - -{% if global_parameters is defined and global_parameters is not none %} -# The following {{ global_parameters | length }} line(s) have been added as -# global-parameters in the CLI and have not been validated !!! -{% for parameter in global_parameters %} -{{ parameter }} -{% endfor %} - -{% endif %} -{% if failover is defined and failover is not none %} -# DHCP failover configuration -failover peer "{{ failover.name }}" { -{% if failover.status == 'primary' %} - primary; - mclt 1800; - split 128; -{% elif failover.status == 'secondary' %} - secondary; -{% endif %} - address {{ failover.source_address }}; - port 520; - peer address {{ failover.remote }}; - peer port 520; - max-response-delay 30; - max-unacked-updates 10; - load balance max seconds 3; -} -{% endif %} -{% if listen_address is defined and listen_address is not none %} - -# DHCP server serving relay subnet, we need a connector to the real world -{% for address in listen_address %} -# Connected subnet statement for listen-address {{ address }} -subnet {{ address | network_from_ipv4 }} netmask {{ address | netmask_from_ipv4 }} { } -{% endfor %} -{% endif %} - -# Shared network configration(s) -{% if shared_network_name is defined and shared_network_name is not none %} -{% for network, network_config in shared_network_name.items() if network_config.disable is not defined %} -shared-network {{ network | replace('_','-') }} { -{% if network_config.authoritative is defined %} - authoritative; -{% endif %} -{% if network_config.name_server is defined and network_config.name_server is not none %} - option domain-name-servers {{ network_config.name_server | join(', ') }}; -{% endif %} -{% if network_config.domain_name is defined and network_config.domain_name is not none %} - option domain-name "{{ network_config.domain_name }}"; -{% endif %} -{% if network_config.domain_search is defined and network_config.domain_search is not none %} - option domain-search "{{ network_config.domain_search | join('", "') }}"; -{% endif %} -{% if network_config.ntp_server is defined and network_config.ntp_server is not none %} - option ntp-servers {{ network_config.ntp_server | join(', ') }}; -{% endif %} -{% if network_config.ping_check is defined %} - ping-check true; -{% endif %} -{% if network_config.shared_network_parameters is defined and network_config.shared_network_parameters is not none %} - # The following {{ network_config.shared_network_parameters | length }} line(s) - # were added as shared-network-parameters in the CLI and have not been validated -{% for parameter in network_config.shared_network_parameters %} - {{ parameter }} -{% endfor %} -{% endif %} -{% if network_config.subnet is defined and network_config.subnet is not none %} -{% for subnet, subnet_config in network_config.subnet.items() %} -{% if subnet_config.description is defined and subnet_config.description is not none %} - # {{ subnet_config.description }} -{% endif %} - subnet {{ subnet | address_from_cidr }} netmask {{ subnet | netmask_from_cidr }} { -{% if subnet_config.name_server is defined and subnet_config.name_server is not none %} - option domain-name-servers {{ subnet_config.name_server | join(', ') }}; -{% endif %} -{% if subnet_config.domain_name is defined and subnet_config.domain_name is not none %} - option domain-name "{{ subnet_config.domain_name }}"; -{% endif %} -{% if subnet_config.domain_search is defined and subnet_config.domain_search is not none %} - option domain-search "{{ subnet_config.domain_search | join('", "') }}"; -{% endif %} -{% if subnet_config.ntp_server is defined and subnet_config.ntp_server is not none %} - option ntp-servers {{ subnet_config.ntp_server | join(', ') }}; -{% endif %} -{% if subnet_config.pop_server is defined and subnet_config.pop_server is not none %} - option pop-server {{ subnet_config.pop_server | join(', ') }}; -{% endif %} -{% if subnet_config.smtp_server is defined and subnet_config.smtp_server is not none %} - option smtp-server {{ subnet_config.smtp_server | join(', ') }}; -{% endif %} -{% if subnet_config.time_server is defined and subnet_config.time_server is not none %} - option time-servers {{ subnet_config.time_server | join(', ') }}; -{% endif %} -{% if subnet_config.wins_server is defined and subnet_config.wins_server is not none %} - option netbios-name-servers {{ subnet_config.wins_server | join(', ') }}; -{% endif %} -{% if subnet_config.static_route is defined and subnet_config.static_route is not none %} -{% set static_default_route = '' %} -{% if subnet_config.default_router and subnet_config.default_router is not none %} -{% set static_default_route = ', ' + '0.0.0.0/0' | isc_static_route(subnet_config.default_router) %} -{% endif %} -{% if subnet_config.static_route is defined and subnet_config.static_route is not none %} -{% set rfc3442_routes = [] %} -{% for route, route_options in subnet_config.static_route.items() %} -{% set rfc3442_routes = rfc3442_routes.append(route | isc_static_route(route_options.next_hop)) %} -{% endfor %} - option rfc3442-static-route {{ rfc3442_routes | join(', ') }}{{ static_default_route }}; - option windows-static-route {{ rfc3442_routes | join(', ') }}; -{% endif %} -{% endif %} -{% if subnet_config.ip_forwarding is defined %} - option ip-forwarding true; -{% endif %} -{% if subnet_config.default_router and subnet_config.default_router is not none %} - option routers {{ subnet_config.default_router }}; -{% endif %} -{% if subnet_config.server_identifier is defined and subnet_config.server_identifier is not none %} - option dhcp-server-identifier {{ subnet_config.server_identifier }}; -{% endif %} -{% if subnet_config.subnet_parameters is defined and subnet_config.subnet_parameters is not none %} - # The following {{ subnet_config.subnet_parameters | length }} line(s) were added as - # subnet-parameters in the CLI and have not been validated!!! -{% for parameter in subnet_config.subnet_parameters %} - {{ parameter }} -{% endfor %} -{% endif %} -{% if subnet_config.tftp_server_name is defined and subnet_config.tftp_server_name is not none %} - option tftp-server-name "{{ subnet_config.tftp_server_name }}"; -{% endif %} -{% if subnet_config.bootfile_name is defined and subnet_config.bootfile_name is not none %} - option bootfile-name "{{ subnet_config.bootfile_name }}"; - filename "{{ subnet_config.bootfile_name }}"; -{% endif %} -{% if subnet_config.bootfile_server is defined and subnet_config.bootfile_server is not none %} - next-server {{ subnet_config.bootfile_server }}; -{% endif %} -{% if subnet_config.time_offset is defined and subnet_config.time_offset is not none %} - option time-offset {{ subnet_config.time_offset }}; -{% endif %} -{% if subnet_config.wpad_url is defined and subnet_config.wpad_url is not none %} - option wpad-url "{{ subnet_config.wpad_url }}"; -{% endif %} -{% if subnet_config.client_prefix_length is defined and subnet_config.client_prefix_length is not none %} - option subnet-mask {{ subnet_config.client_prefix_length }}; -{% endif %} -{% if subnet_config.lease is defined and subnet_config.lease is not none %} - default-lease-time {{ subnet_config.lease }}; - max-lease-time {{ subnet_config.lease }}; -{% endif %} -{% if network_config.ping_check is not defined and subnet_config.ping_check is defined %} - ping-check true; -{% endif %} -{% if subnet_config.static_mapping is defined and subnet_config.static_mapping is not none %} -{% for host, host_config in subnet_config.static_mapping.items() if host_config.disable is not defined %} - host {{ host | replace('_','-') if host_decl_name is defined else network | replace('_','-') + '_' + host | replace('_','-') }} { -{% if host_config.ip_address is defined and host_config.ip_address is not none %} - fixed-address {{ host_config.ip_address }}; -{% endif %} - hardware ethernet {{ host_config.mac_address }}; -{% if host_config.static_mapping_parameters is defined and host_config.static_mapping_parameters is not none %} - # The following {{ host_config.static_mapping_parameters | length }} line(s) were added - # as static-mapping-parameters in the CLI and have not been validated -{% for parameter in host_config.static_mapping_parameters %} - {{ parameter }} -{% endfor %} -{% endif %} - } -{% endfor %} -{% endif %} -{% if subnet_config.range is defined and subnet_config.range is not none %} -{# pool configuration can only be used if there follows a range option #} - pool { -{% endif %} -{% if subnet_config.enable_failover is defined %} - failover peer "{{ failover.name }}"; - deny dynamic bootp clients; -{% endif %} -{% if subnet_config.range is defined and subnet_config.range is not none %} -{% for range, range_options in subnet_config.range.items() %} - range {{ range_options.start }} {{ range_options.stop }}; -{% endfor %} -{% endif %} -{% if subnet_config.range is defined and subnet_config.range is not none %} -{# pool configuration can only be used if there follows a range option #} - } -{% endif %} - } -{% endfor %} -{% endif %} - on commit { - set shared-networkname = "{{ network | replace('_','-') }}"; -{% if hostfile_update is defined %} - set ClientIp = binary-to-ascii(10, 8, ".", leased-address); - set ClientMac = binary-to-ascii(16, 8, ":", substring(hardware, 1, 6)); - set ClientName = pick-first-value(host-decl-name, option fqdn.hostname, option host-name, "empty_hostname"); - if not (ClientName = "empty_hostname") { - set ClientDomain = pick-first-value(config-option domain-name, "..YYZ!"); - execute("/usr/libexec/vyos/system/on-dhcp-event.sh", "commit", ClientName, ClientIp, ClientMac, ClientDomain); - } else { - log(concat("Hostname is not defined for client with IP: ", ClientIP, " MAC: ", ClientMac)); - } -{% endif %} - } -} - -{% endfor %} -{% endif %} diff --git a/data/templates/dhcp-server/dhcpdv6.conf.j2 b/data/templates/dhcp-server/dhcpdv6.conf.j2 new file mode 100644 index 000000000..5c3471316 --- /dev/null +++ b/data/templates/dhcp-server/dhcpdv6.conf.j2 @@ -0,0 +1,132 @@ +### Autogenerated by dhcpv6_server.py ### + +# For options please consult the following website: +# https://www.isc.org/wp-content/uploads/2017/08/dhcp43options.html + +log-facility local7; +{% if preference is vyos_defined %} +option dhcp6.preference {{ preference }}; +{% endif %} + +{% if global_parameters.name_server is vyos_defined %} +option dhcp6.name-servers {{ global_parameters.name_server | join(', ') }}; +{% endif %} + +# Vendor specific options - Cisco +option space cisco code width 2 length width 2; +option cisco.tftp-servers code 1 = array of ip6-address; +option vsio.cisco code 9 = encapsulate cisco; + +# Shared network configration(s) +{% if shared_network_name is vyos_defined %} +{% for network, network_config in shared_network_name.items() if network_config.disable is not vyos_defined %} +shared-network {{ network }} { +{% if network_config.common_options is vyos_defined %} +{% if network_config.common_options.info_refresh_time is vyos_defined %} + option dhcp6.info-refresh-time {{ network_config.common_options.info_refresh_time }}; +{% endif %} +{% if network_config.common_options.domain_search is vyos_defined %} + option dhcp6.domain-search "{{ network_config.common_options.domain_search | join('", "') }}"; +{% endif %} +{% if network_config.common_options.name_server is vyos_defined %} + option dhcp6.name-servers {{ network_config.common_options.name_server | join(', ') }}; +{% endif %} +{% endif %} +{% if network_config.subnet is vyos_defined %} +{% for subnet, subnet_config in network_config.subnet.items() %} + subnet6 {{ subnet }} { +{% if subnet_config.address_range is vyos_defined %} +{% if subnet_config.address_range.prefix is vyos_defined %} +{% for prefix, prefix_config in subnet_config.address_range.prefix.items() %} + range6 {{ prefix }} {{ "temporary" if prefix_config.temporary is vyos_defined }}; +{% endfor %} +{% endif %} +{% if subnet_config.address_range.start is vyos_defined %} +{% for address, address_config in subnet_config.address_range.start.items() %} + range6 {{ address }} {{ address_config.stop }}; +{% endfor %} +{% endif %} +{% endif %} +{% if subnet_config.domain_search is vyos_defined %} + option dhcp6.domain-search "{{ subnet_config.domain_search | join('", "') }}"; +{% endif %} +{% if subnet_config.lease_time is vyos_defined %} +{% if subnet_config.lease_time.default is vyos_defined %} + default-lease-time {{ subnet_config.lease_time.default }}; +{% endif %} +{% if subnet_config.lease_time.maximum is vyos_defined %} + max-lease-time {{ subnet_config.lease_time.maximum }}; +{% endif %} +{% if subnet_config.lease_time.minimum is vyos_defined %} + min-lease-time {{ subnet_config.lease_time.minimum }}; +{% endif %} +{% endif %} +{% if subnet_config.name_server is vyos_defined %} + option dhcp6.name-servers {{ subnet_config.name_server | join(', ') }}; +{% endif %} +{% if subnet_config.nis_domain is vyos_defined %} + option dhcp6.nis-domain-name "{{ subnet_config.nis_domain }}"; +{% endif %} +{% if subnet_config.nis_server is vyos_defined %} + option dhcp6.nis-servers {{ subnet_config.nis_server | join(', ') }}; +{% endif %} +{% if subnet_config.nisplus_domain is vyos_defined %} + option dhcp6.nisp-domain-name "{{ subnet_config.nisplus_domain }}"; +{% endif %} +{% if subnet_config.nisplus_server is vyos_defined %} + option dhcp6.nisp-servers {{ subnet_config.nisplus_server | join(', ') }}; +{% endif %} +{% if subnet_config.sip_server is vyos_defined %} +{% set server_ip = [] %} +{% set server_fqdn = [] %} +{% for address in subnet_config.sip_server %} +{% if address | is_ipv6 %} +{% set server_ip = server_ip.append(address) %} +{% else %} +{% set server_fqdn = server_fqdn.append(address) %} +{% endif %} +{% endfor %} +{% if server_ip is vyos_defined and server_ip | length > 0 %} + option dhcp6.sip-servers-addresses {{ server_ip | join(', ') }}; +{% endif %} +{% if server_fqdn is vyos_defined and server_fqdn | length > 0 %} + option dhcp6.sip-servers-names "{{ server_fqdn | join('", "') }}"; +{% endif %} +{% endif %} +{% if subnet_config.sntp_server is vyos_defined %} + option dhcp6.sntp-servers {{ subnet_config.sntp_server | join(', ') }}; +{% endif %} +{% if subnet_config.prefix_delegation.start is vyos_defined %} +{% for prefix, prefix_config in subnet_config.prefix_delegation.start.items() %} + prefix6 {{ prefix }} {{ prefix_config.stop }} /{{ prefix_config.prefix_length }}; +{% endfor %} +{% endif %} +{% if subnet_config.static_mapping is vyos_defined %} + + # begin configuration of static client mappings +{% for host, host_config in subnet_config.static_mapping.items() if host_config.disable is not vyos_defined %} + host {{ network | replace('_','-') }}_{{ host | replace('_','-') }} { +{% if host_config.identifier is vyos_defined %} + host-identifier option dhcp6.client-id {{ host_config.identifier }}; +{% endif %} +{% if host_config.ipv6_address is vyos_defined %} + fixed-address6 {{ host_config.ipv6_address }}; +{% endif %} +{% if host_config.ipv6_prefix is vyos_defined %} + fixed-prefix6 {{ host_config.ipv6_prefix }}; +{% endif %} + } +{% endfor %} +{% endif %} +{% if subnet_config.vendor_option.cisco.tftp_server is vyos_defined %} + option cisco.tftp-servers {{ subnet_config.vendor_option.cisco.tftp_server | join(', ') }}; +{% endif %} + } +{% endfor %} +{% endif %} + on commit { + set shared-networkname = "{{ network }}"; + } +} +{% endfor %} +{% endif %} diff --git a/data/templates/dhcp-server/dhcpdv6.conf.tmpl b/data/templates/dhcp-server/dhcpdv6.conf.tmpl deleted file mode 100644 index 45d629928..000000000 --- a/data/templates/dhcp-server/dhcpdv6.conf.tmpl +++ /dev/null @@ -1,124 +0,0 @@ -### Autogenerated by dhcpv6_server.py ### - -# For options please consult the following website: -# https://www.isc.org/wp-content/uploads/2017/08/dhcp43options.html - -log-facility local7; -{% if preference is defined and preference is not none %} -option dhcp6.preference {{ preference }}; -{% endif %} - -{% if global_parameters is defined and global_parameters.name_server is defined and global_parameters.name_server is not none %} -option dhcp6.name-servers {{ global_parameters.name_server | join(', ') }}; -{% endif %} - -# Shared network configration(s) -{% if shared_network_name is defined and shared_network_name is not none %} -{% for network, network_config in shared_network_name.items() if network_config.disable is not defined %} -shared-network {{ network | replace('_','-') }} { -{% if network_config.common_options is defined and network_config.common_options is not none %} -{% if network_config.common_options.info_refresh_time is defined and network_config.common_options.info_refresh_time is not none %} - option dhcp6.info-refresh-time {{ network_config.common_options.info_refresh_time }}; -{% endif %} -{% if network_config.common_options.domain_search is defined and network_config.common_options.domain_search is not none %} - option dhcp6.domain-search "{{ network_config.common_options.domain_search | join('", "') }}"; -{% endif %} -{% if network_config.common_options.name_server is defined and network_config.common_options.name_server is not none %} - option dhcp6.name-servers {{ network_config.common_options.name_server | join(', ') }}; -{% endif %} -{% endif %} -{% if network_config.subnet is defined and network_config.subnet is not none %} -{% for subnet, subnet_config in network_config.subnet.items() %} - subnet6 {{ subnet }} { -{% if subnet_config.address_range is defined and subnet_config.address_range is not none %} -{% if subnet_config.address_range.prefix is defined and subnet_config.address_range.prefix is not none %} -{% for prefix, prefix_config in subnet_config.address_range.prefix.items() %} - range6 {{ prefix }} {{ "temporary" if prefix_config.temporary is defined }}; -{% endfor %} -{% endif %} -{% if subnet_config.address_range.start is defined and subnet_config.address_range.start is not none %} -{% for address, address_config in subnet_config.address_range.start.items() %} - range6 {{ address }} {{ address_config.stop }}; -{% endfor %} -{% endif %} -{% endif %} -{% if subnet_config.domain_search is defined and subnet_config.domain_search is not none %} - option dhcp6.domain-search "{{ subnet_config.domain_search | join('", "') }}"; -{% endif %} -{% if subnet_config.lease_time is defined and subnet_config.lease_time is not none %} -{% if subnet_config.lease_time.default is defined and subnet_config.lease_time.default is not none %} - default-lease-time {{ subnet_config.lease_time.default }}; -{% endif %} -{% if subnet_config.lease_time.maximum is defined and subnet_config.lease_time.maximum is not none %} - max-lease-time {{ subnet_config.lease_time.maximum }}; -{% endif %} -{% if subnet_config.lease_time.minimum is defined and subnet_config.lease_time.minimum is not none %} - min-lease-time {{ subnet_config.lease_time.minimum }}; -{% endif %} -{% endif %} -{% if subnet_config.name_server is defined and subnet_config.name_server is not none %} - option dhcp6.name-servers {{ subnet_config.name_server | join(', ') }}; -{% endif %} -{% if subnet_config.nis_domain is defined and subnet_config.nis_domain is not none %} - option dhcp6.nis-domain-name "{{ subnet_config.nis_domain }}"; -{% endif %} -{% if subnet_config.nis_server is defined and subnet_config.nis_server is not none %} - option dhcp6.nis-servers {{ subnet_config.nis_server | join(', ') }}; -{% endif %} -{% if subnet_config.nisplus_domain is defined and subnet_config.nisplus_domain is not none %} - option dhcp6.nisp-domain-name "{{ subnet_config.nisplus_domain }}"; -{% endif %} -{% if subnet_config.nisplus_server is defined and subnet_config.nisplus_server is not none %} - option dhcp6.nisp-servers {{ subnet_config.nisplus_server | join(', ') }}; -{% endif %} -{% if subnet_config.sip_server is defined and subnet_config.sip_server is not none %} -{% set server_ip = [] %} -{% set server_fqdn = [] %} -{% for address in subnet_config.sip_server %} -{% if address | is_ipv6 %} -{% set server_ip = server_ip.append(address) %} -{% else %} -{% set server_fqdn = server_fqdn.append(address) %} -{% endif %} -{% endfor %} -{% if server_ip is defined and server_ip | length > 0 %} - option dhcp6.sip-servers-addresses {{ server_ip | join(', ') }}; -{% endif %} -{% if server_fqdn is defined and server_fqdn | length > 0 %} - option dhcp6.sip-servers-names "{{ server_fqdn | join('", "') }}"; -{% endif %} -{% endif %} -{% if subnet_config.sntp_server is defined and subnet_config.sntp_server is not none %} - option dhcp6.sntp-servers {{ subnet_config.sntp_server | join(', ') }}; -{% endif %} -{% if subnet_config.prefix_delegation is defined and subnet_config.prefix_delegation.start is defined and subnet_config.prefix_delegation.start is not none %} -{% for prefix, prefix_config in subnet_config.prefix_delegation.start.items() %} - prefix6 {{ prefix }} {{ prefix_config.stop }} /{{ prefix_config.prefix_length }}; -{% endfor %} -{% endif %} -{% if subnet_config.static_mapping is defined and subnet_config.static_mapping is not none %} - - # begin configuration of static client mappings -{% for host, host_config in subnet_config.static_mapping.items() if host_config.disable is not defined %} - host {{ network | replace('_','-') }}_{{ host | replace('_','-') }} { -{% if host_config.identifier is defined and host_config.identifier is not none %} - host-identifier option dhcp6.client-id {{ host_config.identifier }}; -{% endif %} -{% if host_config.ipv6_address is defined and host_config.ipv6_address is not none %} - fixed-address6 {{ host_config.ipv6_address }}; -{% endif %} -{% if host_config.ipv6_prefix is defined and host_config.ipv6_prefix is not none %} - fixed-prefix6 {{ host_config.ipv6_prefix }}; -{% endif %} - } -{% endfor %} -{% endif %} - } -{% endfor %} -{% endif %} - on commit { - set shared-networkname = "{{ network | replace('_','-') }}"; - } -} -{% endfor %} -{% endif %} diff --git a/data/templates/dns-forwarding/recursor.conf.tmpl b/data/templates/dns-forwarding/recursor.conf.j2 index d44f756e8..c1950e1bc 100644 --- a/data/templates/dns-forwarding/recursor.conf.tmpl +++ b/data/templates/dns-forwarding/recursor.conf.j2 @@ -1,3 +1,4 @@ +{# j2lint: disable=single-statement-per-line #} ### Autogenerated by dns_forwarding.py ### # XXX: pdns recursor doesn't like whitespace near entry separators, @@ -19,8 +20,11 @@ max-cache-entries={{ cache_size }} # negative TTL for NXDOMAIN max-negative-ttl={{ negative_ttl }} +# timeout +network-timeout={{ timeout }} + # ignore-hosts-file -export-etc-hosts={{ 'no' if ignore_hosts_file is defined else 'yes' }} +export-etc-hosts={{ 'no' if ignore_hosts_file is vyos_defined else 'yes' }} # listen-address local-address={{ listen_address | join(',') }} @@ -29,7 +33,10 @@ local-address={{ listen_address | join(',') }} dnssec={{ dnssec }} # serve rfc1918 records -serve-rfc1918={{ 'no' if no_serve_rfc1918 is defined else 'yes' }} +serve-rfc1918={{ 'no' if no_serve_rfc1918 is vyos_defined else 'yes' }} + +# zones +auth-zones={% for z in authoritative_zones %}{{ z.name }}={{ z.file }}{{- "," if not loop.last -}}{% endfor %} forward-zones-file=recursor.forward-zones.conf diff --git a/data/templates/dns-forwarding/recursor.conf.lua.tmpl b/data/templates/dns-forwarding/recursor.conf.lua.j2 index e2506238d..e2506238d 100644 --- a/data/templates/dns-forwarding/recursor.conf.lua.tmpl +++ b/data/templates/dns-forwarding/recursor.conf.lua.j2 diff --git a/data/templates/dns-forwarding/recursor.forward-zones.conf.tmpl b/data/templates/dns-forwarding/recursor.forward-zones.conf.j2 index 3ab0c804d..de3269e47 100644 --- a/data/templates/dns-forwarding/recursor.forward-zones.conf.tmpl +++ b/data/templates/dns-forwarding/recursor.forward-zones.conf.j2 @@ -1,3 +1,4 @@ +{# j2lint: disable=operator-enclosed-by-spaces #} # Autogenerated by VyOS (vyos-hostsd) # Do not edit, your changes will get overwritten @@ -7,11 +8,11 @@ {# the order of tags, then by the order of nameservers within that tag #} {% set n = namespace(dot_zone_ns='') %} {% for tag in name_server_tags_recursor %} -{% set ns = '' %} -{% if tag in name_servers %} -{% set ns = ns + name_servers[tag]|join(', ') %} -{% set n.dot_zone_ns = (n.dot_zone_ns, ns)|join(', ') if n.dot_zone_ns != '' else ns %} -{% endif %} +{% set ns = '' %} +{% if tag in name_servers %} +{% set ns = ns + name_servers[tag] | join(', ') %} +{% set n.dot_zone_ns = (n.dot_zone_ns, ns) | join(', ') if n.dot_zone_ns != '' else ns %} +{% endif %} # {{ tag }}: {{ ns }} {% endfor %} @@ -19,10 +20,10 @@ +.={{ n.dot_zone_ns }} {% endif %} -{% if forward_zones is defined %} +{% if forward_zones is vyos_defined %} # zones added via 'service dns forwarding domain' -{% for zone, zonedata in forward_zones.items() %} -{{ "+" if zonedata['recursion_desired'] is defined }}{{ zone | replace('_', '-') }}={{ zonedata['server']|join(', ') }} -{% endfor %} +{% for zone, zonedata in forward_zones.items() %} +{{ "+" if zonedata.recursion_desired is vyos_defined }}{{ zone | replace('_', '-') }}={{ zonedata.server | join(', ') }} +{% endfor %} {% endif %} diff --git a/data/templates/dns-forwarding/recursor.vyos-hostsd.conf.lua.j2 b/data/templates/dns-forwarding/recursor.vyos-hostsd.conf.lua.j2 new file mode 100644 index 000000000..987c7de1f --- /dev/null +++ b/data/templates/dns-forwarding/recursor.vyos-hostsd.conf.lua.j2 @@ -0,0 +1,30 @@ +-- Autogenerated by VyOS (vyos-hostsd) -- +-- Do not edit, your changes will get overwritten -- + +{% if hosts %} +-- from 'system static-host-mapping' and DHCP server +{% for tag, taghosts in hosts.items() %} +{% for host, hostprops in taghosts.items() %} +addNTA("{{ host }}.", "{{ tag }}") +{% for a in hostprops['aliases'] %} +addNTA("{{ a }}.", "{{ tag }} alias") +{% endfor %} +{% endfor %} +{% endfor %} +{% endif %} + +{% if forward_zones is vyos_defined %} +-- from 'service dns forwarding domain' +{% for zone, zonedata in forward_zones.items() %} +{% if zonedata.addnta is vyos_defined %} +addNTA("{{ zone }}", "static") +{% endif %} +{% endfor %} +{% endif %} + +{% if authoritative_zones is vyos_defined %} +-- from 'service dns forwarding authoritative-domain' +{% for zone in authoritative_zones %} +addNTA("{{ zone }}", "static") +{% endfor %} +{% endif %} diff --git a/data/templates/dns-forwarding/recursor.vyos-hostsd.conf.lua.tmpl b/data/templates/dns-forwarding/recursor.vyos-hostsd.conf.lua.tmpl deleted file mode 100644 index 784d5c360..000000000 --- a/data/templates/dns-forwarding/recursor.vyos-hostsd.conf.lua.tmpl +++ /dev/null @@ -1,24 +0,0 @@ --- Autogenerated by VyOS (vyos-hostsd) -- --- Do not edit, your changes will get overwritten -- - -{% if hosts %} --- from 'system static-host-mapping' and DHCP server -{% for tag, taghosts in hosts.items() %} -{% for host, hostprops in taghosts.items() %} -addNTA("{{ host }}.", "{{ tag }}") -{% for a in hostprops['aliases'] %} -addNTA("{{ a }}.", "{{ tag }} alias") -{% endfor %} -{% endfor %} -{% endfor %} -{% endif %} - -{% if forward_zones is defined %} --- from 'service dns forwarding domain' -{% for zone, zonedata in forward_zones.items() %} -{% if zonedata['addnta'] is defined %} -addNTA("{{ zone }}", "static") -{% endif %} -{% endfor %} -{% endif %} - diff --git a/data/templates/dns-forwarding/recursor.zone.conf.j2 b/data/templates/dns-forwarding/recursor.zone.conf.j2 new file mode 100644 index 000000000..25193c2ec --- /dev/null +++ b/data/templates/dns-forwarding/recursor.zone.conf.j2 @@ -0,0 +1,6 @@ +; +; Autogenerated by dns_forwarding.py +; +{% for r in records %} +{{ r.name }} {{ r.ttl }} {{ r.type }} {{ r.value }} +{% endfor %} diff --git a/data/templates/dynamic-dns/ddclient.conf.j2 b/data/templates/dynamic-dns/ddclient.conf.j2 new file mode 100644 index 000000000..3c2d17cbb --- /dev/null +++ b/data/templates/dynamic-dns/ddclient.conf.j2 @@ -0,0 +1,51 @@ +### Autogenerated by dynamic_dns.py ### +daemon=1m +syslog=yes +ssl=yes + +{% if interface is vyos_defined %} +{% for iface, iface_config in interface.items() %} +# ddclient configuration for interface "{{ iface }}" +{% if iface_config.use_web is vyos_defined %} +{% set web_skip = ", web-skip='" ~ iface_config.use_web.skip ~ "'" if iface_config.use_web.skip is vyos_defined else '' %} +use=web, web='{{ iface_config.use_web.url }}'{{ web_skip }} +{% else %} +{{ 'usev6=if' if iface_config.ipv6_enable is vyos_defined else 'use=if' }}, if={{ iface }} +{% endif %} + +{% if iface_config.rfc2136 is vyos_defined %} +{% for rfc2136, config in iface_config.rfc2136.items() %} +{% for dns_record in config.record if config.record is vyos_defined %} +# RFC2136 dynamic DNS configuration for {{ rfc2136 }}, {{ config.zone }}, {{ dns_record }} +server={{ config.server }} +protocol=nsupdate +password={{ config.key }} +ttl={{ config.ttl }} +zone={{ config.zone }} +{{ dns_record }} + +{% endfor %} +{% endfor %} +{% endif %} + +{% if iface_config.service is vyos_defined %} +{% for service, config in iface_config.service.items() %} +{% for dns_record in config.host_name %} +# DynDNS provider configuration for {{ service }}, {{ dns_record }} +protocol={{ config.protocol }}, +max-interval=28d, +login={{ config.login }}, +password='{{ config.password }}', +{% if config.server is vyos_defined %} +server={{ config.server }}, +{% endif %} +{% if config.zone is vyos_defined %} +zone={{ config.zone }}, +{% endif %} +{{ dns_record }} + +{% endfor %} +{% endfor %} +{% endif %} +{% endfor %} +{% endif %} diff --git a/data/templates/dynamic-dns/ddclient.conf.tmpl b/data/templates/dynamic-dns/ddclient.conf.tmpl deleted file mode 100644 index 517e4bad4..000000000 --- a/data/templates/dynamic-dns/ddclient.conf.tmpl +++ /dev/null @@ -1,49 +0,0 @@ -### Autogenerated by dynamic_dns.py ### -daemon=1m -syslog=yes -ssl=yes - -{% for iface in interface %} -# ddclient configuration for interface "{{ iface }}" -{% if interface[iface].use_web is defined and interface[iface].use_web is not none %} -{% set web_skip = ", web-skip='" + interface[iface].use_web.skip + "'" if interface[iface].use_web.skip is defined else '' %} -use=web, web='{{ interface[iface].use_web.url }}'{{ web_skip }} -{% else %} -{{ 'usev6=if' if interface[iface].ipv6_enable is defined else 'use=if' }}, if={{ iface }} -{% endif %} - -{% if interface[iface].rfc2136 is defined and interface[iface].rfc2136 is not none %} -{% for rfc2136, config in interface[iface].rfc2136.items() %} -{% for dns_record in config.record if config.record is defined %} -# RFC2136 dynamic DNS configuration for {{ rfc2136 }}, {{ config.zone }}, {{ dns_record }} -server={{ config.server }} -protocol=nsupdate -password={{ config.key }} -ttl={{ config.ttl }} -zone={{ config.zone }} -{{ dns_record }} - -{% endfor %} -{% endfor %} -{% endif %} - -{% if interface[iface].service is defined and interface[iface].service is not none %} -{% for service, config in interface[iface].service.items() %} -{% for dns_record in config.host_name %} -# DynDNS provider configuration for {{ service }}, {{ dns_record }} -protocol={{ config.protocol }}, -max-interval=28d, -login={{ config.login }}, -password='{{ config.password }}', -{% if config.server %} -server={{ config.server }}, -{% endif %} -{% if config.zone %} -zone={{ config.zone }}, -{% endif %} -{{ dns_record }} - -{% endfor %} -{% endfor %} -{% endif %} -{% endfor %} diff --git a/data/templates/ethernet/wpa_supplicant.conf.tmpl b/data/templates/ethernet/wpa_supplicant.conf.j2 index 308d777f1..8f140f6cb 100644 --- a/data/templates/ethernet/wpa_supplicant.conf.tmpl +++ b/data/templates/ethernet/wpa_supplicant.conf.j2 @@ -31,19 +31,19 @@ ap_scan=0 fast_reauth=1 network={ -{% if eapol is defined and eapol is not none %} -{% if eapol.ca_certificate is defined and eapol.ca_certificate is not none %} +{% if eapol is vyos_defined %} +{% if eapol.ca_certificate is vyos_defined %} ca_cert="/run/wpa_supplicant/{{ ifname }}_ca.pem" -{% endif %} +{% endif %} client_cert="/run/wpa_supplicant/{{ ifname }}_cert.pem" private_key="/run/wpa_supplicant/{{ ifname }}_cert.key" -{% endif %} +{% endif %} # list of accepted authenticated key management protocols key_mgmt=IEEE8021X eap=TLS -{% if mac is defined and mac is not none %} +{% if mac is vyos_defined %} identity="{{ mac }}" {% else %} identity="{{ hw_id }}" diff --git a/data/templates/firewall/nftables-defines.j2 b/data/templates/firewall/nftables-defines.j2 new file mode 100644 index 000000000..4fa92f2e3 --- /dev/null +++ b/data/templates/firewall/nftables-defines.j2 @@ -0,0 +1,32 @@ +{% if group is vyos_defined %} +{% if group.address_group is vyos_defined %} +{% for group_name, group_conf in group.address_group.items() %} +define A_{{ group_name }} = { {{ group_conf.address | join(",") }} } +{% endfor %} +{% endif %} +{% if group.ipv6_address_group is vyos_defined %} +{% for group_name, group_conf in group.ipv6_address_group.items() %} +define A6_{{ group_name }} = { {{ group_conf.address | join(",") }} } +{% endfor %} +{% endif %} +{% if group.mac_group is vyos_defined %} +{% for group_name, group_conf in group.mac_group.items() %} +define M_{{ group_name }} = { {{ group_conf.mac_address | join(",") }} } +{% endfor %} +{% endif %} +{% if group.network_group is vyos_defined %} +{% for group_name, group_conf in group.network_group.items() %} +define N_{{ group_name }} = { {{ group_conf.network | join(",") }} } +{% endfor %} +{% endif %} +{% if group.ipv6_network_group is vyos_defined %} +{% for group_name, group_conf in group.ipv6_network_group.items() %} +define N6_{{ group_name }} = { {{ group_conf.network | join(",") }} } +{% endfor %} +{% endif %} +{% if group.port_group is vyos_defined %} +{% for group_name, group_conf in group.port_group.items() %} +define P_{{ group_name }} = { {{ group_conf.port | join(",") }} } +{% endfor %} +{% endif %} +{% endif %}
\ No newline at end of file diff --git a/data/templates/firewall/nftables-nat.j2 b/data/templates/firewall/nftables-nat.j2 new file mode 100644 index 000000000..1481e9104 --- /dev/null +++ b/data/templates/firewall/nftables-nat.j2 @@ -0,0 +1,182 @@ +#!/usr/sbin/nft -f + +{% macro nat_rule(rule, config, chain) %} +{% set comment = '' %} +{% set base_log = '' %} +{% set src_addr = 'ip saddr ' ~ config.source.address.replace('!','!= ') if config.source.address is vyos_defined %} +{% set dst_addr = 'ip daddr ' ~ config.destination.address.replace('!','!= ') if config.destination.address is vyos_defined %} +{# negated port groups need special treatment, move != in front of { } group #} +{% if config.source.port is vyos_defined and config.source.port.startswith('!') %} +{% set src_port = 'sport != { ' ~ config.source.port.replace('!','') ~ ' }' %} +{% else %} +{% set src_port = 'sport { ' ~ config.source.port ~ ' }' if config.source.port is vyos_defined %} +{% endif %} +{# negated port groups need special treatment, move != in front of { } group #} +{% if config.destination.port is vyos_defined and config.destination.port.startswith('!') %} +{% set dst_port = 'dport != { ' ~ config.destination.port.replace('!','') ~ ' }' %} +{% else %} +{% set dst_port = 'dport { ' ~ config.destination.port ~ ' }' if config.destination.port is vyos_defined %} +{% endif %} +{% if chain is vyos_defined('PREROUTING') %} +{% set comment = 'DST-NAT-' ~ rule %} +{% set base_log = '[NAT-DST-' ~ rule %} +{% set interface = ' iifname "' ~ config.inbound_interface ~ '"' if config.inbound_interface is vyos_defined and config.inbound_interface is not vyos_defined('any') else '' %} +{% if config.translation.address is vyos_defined %} +{# support 1:1 network translation #} +{% if config.translation.address | is_ip_network %} +{% set trns_addr = 'dnat ip prefix to ip daddr map { ' ~ config.destination.address ~ ' : ' ~ config.translation.address ~ ' }' %} +{# we can now clear out the dst_addr part as it's already covered in aboves map #} +{% set dst_addr = '' %} +{% else %} +{% set trns_addr = 'dnat to ' ~ config.translation.address %} +{% endif %} +{% endif %} +{% elif chain is vyos_defined('POSTROUTING') %} +{% set comment = 'SRC-NAT-' ~ rule %} +{% set base_log = '[NAT-SRC-' ~ rule %} +{% set interface = ' oifname "' ~ config.outbound_interface ~ '"' if config.outbound_interface is vyos_defined and config.outbound_interface is not vyos_defined('any') else '' %} +{% if config.translation.address is vyos_defined %} +{% if config.translation.address is vyos_defined('masquerade') %} +{% set trns_addr = config.translation.address %} +{% if config.translation.port is vyos_defined %} +{% set trns_addr = trns_addr ~ ' to ' %} +{% endif %} +{# support 1:1 network translation #} +{% elif config.translation.address | is_ip_network %} +{% set trns_addr = 'snat ip prefix to ip saddr map { ' ~ config.source.address ~ ' : ' ~ config.translation.address ~ ' }' %} +{# we can now clear out the src_addr part as it's already covered in aboves map #} +{% set src_addr = '' %} +{% else %} +{% set trns_addr = 'snat to ' ~ config.translation.address %} +{% endif %} +{% endif %} +{% endif %} +{% set trns_port = ':' ~ config.translation.port if config.translation.port is vyos_defined %} +{# protocol has a default value thus it is always present #} +{% if config.protocol is vyos_defined('tcp_udp') %} +{% set protocol = 'tcp' %} +{% set comment = comment ~ ' tcp_udp' %} +{% else %} +{% set protocol = config.protocol %} +{% endif %} +{% if config.log is vyos_defined %} +{% if config.exclude is vyos_defined %} +{% set log = base_log ~ '-EXCL]' %} +{% elif config.translation.address is vyos_defined('masquerade') %} +{% set log = base_log ~ '-MASQ]' %} +{% else %} +{% set log = base_log ~ ']' %} +{% endif %} +{% endif %} +{% if config.exclude is vyos_defined %} +{# rule has been marked as 'exclude' thus we simply return here #} +{% set trns_addr = 'return' %} +{% set trns_port = '' %} +{% endif %} +{# T1083: NAT address and port translation options #} +{% if config.translation.options is vyos_defined %} +{% if config.translation.options.address_mapping is vyos_defined('persistent') %} +{% set trns_opts_addr = 'persistent' %} +{% endif %} +{% if config.translation.options.port_mapping is vyos_defined('random') %} +{% set trns_opts_port = 'random' %} +{% elif config.translation.options.port_mapping is vyos_defined('fully-random') %} +{% set trns_opts_port = 'fully-random' %} +{% endif %} +{% endif %} +{% if trns_opts_addr is vyos_defined and trns_opts_port is vyos_defined %} +{% set trns_opts = trns_opts_addr ~ ',' ~ trns_opts_port %} +{% elif trns_opts_addr is vyos_defined %} +{% set trns_opts = trns_opts_addr %} +{% elif trns_opts_port is vyos_defined %} +{% set trns_opts = trns_opts_port %} +{% endif %} +{% set output = 'add rule ip nat ' ~ chain ~ interface %} +{% if protocol is not vyos_defined('all') %} +{% set output = output ~ ' ip protocol ' ~ protocol %} +{% endif %} +{% if src_addr is vyos_defined %} +{% set output = output ~ ' ' ~ src_addr %} +{% endif %} +{% if src_port is vyos_defined %} +{% set output = output ~ ' ' ~ protocol ~ ' ' ~ src_port %} +{% endif %} +{% if dst_addr is vyos_defined %} +{% set output = output ~ ' ' ~ dst_addr %} +{% endif %} +{% if dst_port is vyos_defined %} +{% set output = output ~ ' ' ~ protocol ~ ' ' ~ dst_port %} +{% endif %} +{# Count packets #} +{% set output = output ~ ' counter' %} +{# Special handling of log option, we must repeat the entire rule before the #} +{# NAT translation options are added, this is essential #} +{% if log is vyos_defined %} +{% set log_output = output ~ ' log prefix "' ~ log ~ '" comment "' ~ comment ~ '"' %} +{% endif %} +{% if trns_addr is vyos_defined %} +{% set output = output ~ ' ' ~ trns_addr %} +{% endif %} +{% if trns_port is vyos_defined %} +{# Do not add a whitespace here, translation port must be directly added after IP address #} +{# e.g. 192.0.2.10:3389 #} +{% set output = output ~ trns_port %} +{% endif %} +{% if trns_opts is vyos_defined %} +{% set output = output ~ ' ' ~ trns_opts %} +{% endif %} +{% if comment is vyos_defined %} +{% set output = output ~ ' comment "' ~ comment ~ '"' %} +{% endif %} +{{ log_output if log_output is vyos_defined }} +{{ output }} +{# Special handling if protocol is tcp_udp, we must repeat the entire rule with udp as protocol #} +{% if config.protocol is vyos_defined('tcp_udp') %} +{# Beware of trailing whitespace, without it the comment tcp_udp will be changed to udp_udp #} +{{ log_output | replace('tcp ', 'udp ') if log_output is vyos_defined }} +{{ output | replace('tcp ', 'udp ') }} +{% endif %} +{% endmacro %} + +# Start with clean SNAT and DNAT chains +flush chain ip nat PREROUTING +flush chain ip nat POSTROUTING +{% if helper_functions is vyos_defined('remove') %} +{# NAT if going to be disabled - remove rules and targets from nftables #} +{% set base_command = 'delete rule ip raw' %} +{{ base_command }} PREROUTING handle {{ pre_ct_ignore }} +{{ base_command }} OUTPUT handle {{ out_ct_ignore }} +{{ base_command }} PREROUTING handle {{ pre_ct_conntrack }} +{{ base_command }} OUTPUT handle {{ out_ct_conntrack }} + +delete chain ip raw NAT_CONNTRACK + +{% elif helper_functions is vyos_defined('add') %} +{# NAT if enabled - add targets to nftables #} +add chain ip raw NAT_CONNTRACK +add rule ip raw NAT_CONNTRACK counter accept +{% set base_command = 'add rule ip raw' %} +{{ base_command }} PREROUTING position {{ pre_ct_ignore }} counter jump VYOS_CT_HELPER +{{ base_command }} OUTPUT position {{ out_ct_ignore }} counter jump VYOS_CT_HELPER +{{ base_command }} PREROUTING position {{ pre_ct_conntrack }} counter jump NAT_CONNTRACK +{{ base_command }} OUTPUT position {{ out_ct_conntrack }} counter jump NAT_CONNTRACK +{% endif %} + +# +# Destination NAT rules build up here +# +add rule ip nat PREROUTING counter jump VYOS_PRE_DNAT_HOOK +{% if destination.rule is vyos_defined %} +{% for rule, config in destination.rule.items() if config.disable is not vyos_defined %} +{{ nat_rule(rule, config, 'PREROUTING') }} +{% endfor %} +{% endif %} +# +# Source NAT rules build up here +# +add rule ip nat POSTROUTING counter jump VYOS_PRE_SNAT_HOOK +{% if source.rule is vyos_defined %} +{% for rule, config in source.rule.items() if config.disable is not vyos_defined %} +{{ nat_rule(rule, config, 'POSTROUTING') }} +{% endfor %} +{% endif %} diff --git a/data/templates/firewall/nftables-nat.tmpl b/data/templates/firewall/nftables-nat.tmpl deleted file mode 100644 index 40ed1b916..000000000 --- a/data/templates/firewall/nftables-nat.tmpl +++ /dev/null @@ -1,181 +0,0 @@ -#!/usr/sbin/nft -f - -{% macro nat_rule(rule, config, chain) %} -{% set comment = '' %} -{% set base_log = '' %} -{% set src_addr = 'ip saddr ' + config.source.address.replace('!','!= ') if config.source is defined and config.source.address is defined and config.source.address is not none %} -{% set dst_addr = 'ip daddr ' + config.destination.address.replace('!','!= ') if config.destination is defined and config.destination.address is defined and config.destination.address is not none %} -{# negated port groups need special treatment, move != in front of { } group #} -{% if config.source is defined and config.source.port is defined and config.source.port is not none and config.source.port.startswith('!=') %} -{% set src_port = 'sport != { ' + config.source.port.replace('!=','') + ' }' %} -{% else %} -{% set src_port = 'sport { ' + config.source.port + ' }' if config.source is defined and config.source.port is defined and config.source.port is not none %} -{% endif %} -{# negated port groups need special treatment, move != in front of { } group #} -{% if config.destination is defined and config.destination.port is defined and config.destination.port is not none and config.destination.port.startswith('!=') %} -{% set dst_port = 'dport != { ' + config.destination.port.replace('!=','') + ' }' %} -{% else %} -{% set dst_port = 'dport { ' + config.destination.port + ' }' if config.destination is defined and config.destination.port is defined and config.destination.port is not none %} -{% endif %} -{% if chain == 'PREROUTING' %} -{% set comment = 'DST-NAT-' + rule %} -{% set base_log = '[NAT-DST-' + rule %} -{% set interface = ' iifname "' + config.inbound_interface + '"' if config.inbound_interface is defined and config.inbound_interface != 'any' else '' %} -{% if config.translation is defined and config.translation.address is defined and config.translation.address is not none %} -{# support 1:1 network translation #} -{% if config.translation.address | is_ip_network %} -{% set trns_addr = 'dnat ip prefix to ip daddr map { ' + config.destination.address + ' : ' + config.translation.address + ' }' %} -{# we can now clear out the dst_addr part as it's already covered in aboves map #} -{% set dst_addr = '' %} -{% else %} -{% set trns_addr = 'dnat to ' + config.translation.address %} -{% endif %} -{% endif %} -{% elif chain == 'POSTROUTING' %} -{% set comment = 'SRC-NAT-' + rule %} -{% set base_log = '[NAT-SRC-' + rule %} -{% set interface = ' oifname "' + config.outbound_interface + '"' if config.outbound_interface is defined and config.outbound_interface != 'any' else '' %} -{% if config.translation is defined and config.translation.address is defined and config.translation.address is not none %} -{% if config.translation.address == 'masquerade' %} -{% set trns_addr = config.translation.address %} -{% if config.translation.port is defined and config.translation.port is not none %} -{% set trns_addr = trns_addr + ' to ' %} -{% endif %} -{# support 1:1 network translation #} -{% elif config.translation.address | is_ip_network %} -{% set trns_addr = 'snat ip prefix to ip saddr map { ' + config.source.address + ' : ' + config.translation.address + ' }' %} -{# we can now clear out the src_addr part as it's already covered in aboves map #} -{% set src_addr = '' %} -{% else %} -{% set trns_addr = 'snat to ' + config.translation.address %} -{% endif %} -{% endif %} -{% endif %} -{% set trns_port = ':' + config.translation.port if config.translation is defined and config.translation.port is defined and config.translation.port is not none %} -{# protocol has a default value thus it is always present #} -{% if config.protocol == 'tcp_udp' %} -{% set protocol = 'tcp' %} -{% set comment = comment + ' tcp_udp' %} -{% else %} -{% set protocol = config.protocol %} -{% endif %} -{% if config.log is defined %} -{% if config.exclude is defined %} -{% set log = base_log + '-EXCL]' %} -{% elif config.translation is defined and config.translation.address is defined and config.translation.address == 'masquerade' %} -{% set log = base_log +'-MASQ]' %} -{% else %} -{% set log = base_log + ']' %} -{% endif %} -{% endif %} -{% if config.exclude is defined %} -{# rule has been marked as 'exclude' thus we simply return here #} -{% set trns_addr = 'return' %} -{% set trns_port = '' %} -{% endif %} -{# T1083: NAT address and port translation options #} -{% if config.translation is defined and config.translation.options is defined and config.translation.options is not none %} -{% if config.translation.options.address_mapping is defined and config.translation.options.address_mapping == "persistent" %} -{% set trns_opts_addr = 'persistent' %} -{% endif %} -{% if config.translation.options.port_mapping is defined %} -{% if config.translation.options.port_mapping == "random" %} -{% set trns_opts_port = 'random' %} -{% elif config.translation.options.port_mapping == "fully-random" %} -{% set trns_opts_port = 'fully-random' %} -{% endif %} -{% endif %} -{% endif %} -{% if trns_opts_addr and trns_opts_port %} -{% set trns_opts = trns_opts_addr + ',' + trns_opts_port %} -{% elif trns_opts_addr %} -{% set trns_opts = trns_opts_addr %} -{% elif trns_opts_port %} -{% set trns_opts = trns_opts_port %} -{% endif %} -{% set output = 'add rule ip nat ' + chain + interface %} -{% if protocol != 'all' %} -{% set output = output + ' ip protocol ' + protocol %} -{% endif %} -{% if src_addr %} -{% set output = output + ' ' + src_addr %} -{% endif %} -{% if src_port %} -{% set output = output + ' ' + protocol + ' ' + src_port %} -{% endif %} -{% if dst_addr %} -{% set output = output + ' ' + dst_addr %} -{% endif %} -{% if dst_port %} -{% set output = output + ' ' + protocol + ' ' + dst_port %} -{% endif %} -{# Count packets #} -{% set output = output + ' counter' %} -{# Special handling of log option, we must repeat the entire rule before the #} -{# NAT translation options are added, this is essential #} -{% if log %} -{% set log_output = output + ' log prefix "' + log + '" comment "' + comment + '"' %} -{% endif %} -{% if trns_addr %} -{% set output = output + ' ' + trns_addr %} -{% endif %} -{% if trns_port %} -{# Do not add a whitespace here, translation port must be directly added after IP address #} -{# e.g. 192.0.2.10:3389 #} -{% set output = output + trns_port %} -{% endif %} -{% if trns_opts %} -{% set output = output + ' ' + trns_opts %} -{% endif %} -{% if comment %} -{% set output = output + ' comment "' + comment + '"' %} -{% endif %} -{{ log_output if log_output }} -{{ output }} -{# Special handling if protocol is tcp_udp, we must repeat the entire rule with udp as protocol #} -{% if config.protocol == 'tcp_udp' %} -{# Beware of trailing whitespace, without it the comment tcp_udp will be changed to udp_udp #} -{{ log_output | replace('tcp ', 'udp ') if log_output }} -{{ output | replace('tcp ', 'udp ') }} -{% endif %} -{% endmacro %} - -# Start with clean NAT table -flush table ip nat -{% if helper_functions == 'remove' %} -{# NAT if going to be disabled - remove rules and targets from nftables #} -{% set base_command = 'delete rule ip raw' %} -{{ base_command }} PREROUTING handle {{ pre_ct_ignore }} -{{ base_command }} OUTPUT handle {{ out_ct_ignore }} -{{ base_command }} PREROUTING handle {{ pre_ct_conntrack }} -{{ base_command }} OUTPUT handle {{ out_ct_conntrack }} - -delete chain ip raw NAT_CONNTRACK - -{% elif helper_functions == 'add' %} -{# NAT if enabled - add targets to nftables #} -add chain ip raw NAT_CONNTRACK -add rule ip raw NAT_CONNTRACK counter accept -{% set base_command = 'add rule ip raw' %} -{{ base_command }} PREROUTING position {{ pre_ct_ignore }} counter jump VYATTA_CT_HELPER -{{ base_command }} OUTPUT position {{ out_ct_ignore }} counter jump VYATTA_CT_HELPER -{{ base_command }} PREROUTING position {{ pre_ct_conntrack }} counter jump NAT_CONNTRACK -{{ base_command }} OUTPUT position {{ out_ct_conntrack }} counter jump NAT_CONNTRACK -{% endif %} - -# -# Destination NAT rules build up here -# -{% if destination is defined and destination.rule is defined and destination.rule is not none %} -{% for rule, config in destination.rule.items() if config.disable is not defined %} -{{ nat_rule(rule, config, 'PREROUTING') }} -{% endfor %} -{% endif %} -# -# Source NAT rules build up here -# -{% if source is defined and source.rule is defined and source.rule is not none %} -{% for rule, config in source.rule.items() if config.disable is not defined %} -{{ nat_rule(rule, config, 'POSTROUTING') }} -{% endfor %} -{% endif %} diff --git a/data/templates/firewall/nftables-nat66.j2 b/data/templates/firewall/nftables-nat66.j2 new file mode 100644 index 000000000..003b138b2 --- /dev/null +++ b/data/templates/firewall/nftables-nat66.j2 @@ -0,0 +1,102 @@ +#!/usr/sbin/nft -f + +{% macro nptv6_rule(rule,config, chain) %} +{% set comment = '' %} +{% set base_log = '' %} +{% set src_prefix = 'ip6 saddr ' ~ config.source.prefix if config.source.prefix is vyos_defined %} +{% set dest_address = 'ip6 daddr ' ~ config.destination.address if config.destination.address is vyos_defined %} +{% if chain is vyos_defined('PREROUTING') %} +{% set comment = 'DST-NAT66-' ~ rule %} +{% set base_log = '[NAT66-DST-' ~ rule %} +{% set interface = ' iifname "' ~ config.inbound_interface ~ '"' if config.inbound_interface is vyos_defined and config.inbound_interface is not vyos_defined('any') else '' %} +{% if config.translation.address | is_ip_network %} +{# support 1:1 network translation #} +{% set dnat_type = 'dnat prefix to ' %} +{% else %} +{% set dnat_type = 'dnat to ' %} +{% endif %} +{% set trns_address = dnat_type ~ config.translation.address if config.translation.address is vyos_defined %} +{% elif chain is vyos_defined('POSTROUTING') %} +{% set comment = 'SRC-NAT66-' ~ rule %} +{% set base_log = '[NAT66-SRC-' ~ rule %} +{% if config.translation.address is vyos_defined %} +{% if config.translation.address is vyos_defined('masquerade') %} +{% set trns_address = config.translation.address %} +{% else %} +{% if config.translation.address | is_ip_network %} +{# support 1:1 network translation #} +{% set snat_type = 'snat prefix to ' %} +{% else %} +{% set snat_type = 'snat to ' %} +{% endif %} +{% set trns_address = snat_type ~ config.translation.address %} +{% endif %} +{% endif %} +{% set interface = ' oifname "' ~ config.outbound_interface ~ '"' if config.outbound_interface is vyos_defined else '' %} +{% endif %} +{% if config.log is vyos_defined %} +{% if config.translation.address is vyos_defined('masquerade') %} +{% set log = base_log ~ '-MASQ]' %} +{% else %} +{% set log = base_log ~ ']' %} +{% endif %} +{% endif %} +{% set output = 'add rule ip6 nat ' ~ chain ~ interface %} +{# Count packets #} +{% set output = output ~ ' counter' %} +{# Special handling of log option, we must repeat the entire rule before the #} +{# NAT translation options are added, this is essential #} +{% if log is vyos_defined %} +{% set log_output = output ~ ' log prefix "' ~ log ~ '" comment "' ~ comment ~ '"' %} +{% endif %} +{% if src_prefix is vyos_defined %} +{% set output = output ~ ' ' ~ src_prefix %} +{% endif %} +{% if dest_address is vyos_defined %} +{% set output = output ~ ' ' ~ dest_address %} +{% endif %} +{% if trns_address is vyos_defined %} +{% set output = output ~ ' ' ~ trns_address %} +{% endif %} +{% if comment is vyos_defined %} +{% set output = output ~ ' comment "' ~ comment ~ '"' %} +{% endif %} +{{ log_output if log_output is vyos_defined }} +{{ output }} +{% endmacro %} + +# Start with clean NAT table +flush table ip6 nat +{% if helper_functions is vyos_defined('remove') %} +{# NAT if going to be disabled - remove rules and targets from nftables #} +{% set base_command = 'delete rule ip6 raw' %} +{{ base_command }} PREROUTING handle {{ pre_ct_conntrack }} +{{ base_command }} OUTPUT handle {{ out_ct_conntrack }} + +delete chain ip6 raw NAT_CONNTRACK + +{% elif helper_functions is vyos_defined('add') %} +{# NAT if enabled - add targets to nftables #} +add chain ip6 raw NAT_CONNTRACK +add rule ip6 raw NAT_CONNTRACK counter accept +{% set base_command = 'add rule ip6 raw' %} +{{ base_command }} PREROUTING position {{ pre_ct_conntrack }} counter jump NAT_CONNTRACK +{{ base_command }} OUTPUT position {{ out_ct_conntrack }} counter jump NAT_CONNTRACK +{% endif %} + +# +# Destination NAT66 rules build up here +# +{% if destination.rule is vyos_defined %} +{% for rule, config in destination.rule.items() if config.disable is not vyos_defined %} +{{ nptv6_rule(rule, config, 'PREROUTING') }} +{% endfor %} +{% endif %} +# +# Source NAT66 rules build up here +# +{% if source.rule is vyos_defined %} +{% for rule, config in source.rule.items() if config.disable is not vyos_defined %} +{{ nptv6_rule(rule, config, 'POSTROUTING') }} +{% endfor %} +{% endif %} diff --git a/data/templates/firewall/nftables-nat66.tmpl b/data/templates/firewall/nftables-nat66.tmpl deleted file mode 100644 index e5c1b1b8d..000000000 --- a/data/templates/firewall/nftables-nat66.tmpl +++ /dev/null @@ -1,102 +0,0 @@ -#!/usr/sbin/nft -f - -{% macro nptv6_rule(rule,config, chain) %} -{% set comment = '' %} -{% set base_log = '' %} -{% set src_prefix = "ip6 saddr " + config.source.prefix if config.source is defined and config.source.prefix is defined and config.source.prefix is not none %} -{% set dest_address = "ip6 daddr " + config.destination.address if config.destination is defined and config.destination.address is defined and config.destination.address is not none %} -{% if chain == "PREROUTING" %} -{% set comment = "DST-NAT66-" + rule %} -{% set base_log = '[NAT66-DST-' + rule %} -{% set interface = " iifname \"" + config.inbound_interface + "\"" if config.inbound_interface is defined and config.inbound_interface != 'any' else '' %} -{% if config.translation.address | is_ip_network %} -{# support 1:1 network translation #} -{% set dnat_type = "dnat prefix to " %} -{% else %} -{% set dnat_type = "dnat to " %} -{% endif %} -{% set trns_address = dnat_type + config.translation.address if config.translation is defined and config.translation.address is defined and config.translation.address is not none %} -{% elif chain == "POSTROUTING" %} -{% set comment = 'SRC-NAT66-' + rule %} -{% set base_log = '[NAT66-SRC-' + rule %} -{% if config.translation is defined and config.translation.address is defined and config.translation.address is not none %} -{% if config.translation.address == 'masquerade' %} -{% set trns_address = config.translation.address %} -{% else %} -{% if config.translation.address | is_ip_network %} -{# support 1:1 network translation #} -{% set snat_type = "snat prefix to " %} -{% else %} -{% set snat_type = "snat to " %} -{% endif %} -{% set trns_address = snat_type + config.translation.address %} -{% endif %} -{% endif %} -{% set interface = " oifname \"" + config.outbound_interface + "\"" if config.outbound_interface is defined else '' %} -{% endif %} -{% if config.log is defined %} -{% if config.translation is defined and config.translation.address is defined and config.translation.address == 'masquerade' %} -{% set log = base_log +'-MASQ]' %} -{% else %} -{% set log = base_log + "]" %} -{% endif %} -{% endif %} -{% set output = "add rule ip6 nat " + chain + interface %} -{# Count packets #} -{% set output = output + " counter" %} -{# Special handling of log option, we must repeat the entire rule before the #} -{# NAT translation options are added, this is essential #} -{% if log %} -{% set log_output = output + " log prefix \"" + log + "\" comment \"" + comment + "\"" %} -{% endif %} -{% if src_prefix %} -{% set output = output + " " + src_prefix %} -{% endif %} -{% if dest_address %} -{% set output = output + " " + dest_address %} -{% endif %} -{% if trns_address %} -{% set output = output + " " + trns_address %} -{% endif %} -{% if comment %} -{% set output = output + " comment \"" + comment + "\"" %} -{% endif %} -{{ log_output if log_output }} -{{ output }} -{% endmacro %} - -# Start with clean NAT table -flush table ip6 nat -{% if helper_functions == 'remove' %} -{# NAT if going to be disabled - remove rules and targets from nftables #} -{% set base_command = "delete rule ip6 raw" %} -{{base_command}} PREROUTING handle {{ pre_ct_conntrack }} -{{base_command}} OUTPUT handle {{ out_ct_conntrack }} - -delete chain ip6 raw NAT_CONNTRACK - -{% elif helper_functions == 'add' %} -{# NAT if enabled - add targets to nftables #} -add chain ip6 raw NAT_CONNTRACK -add rule ip6 raw NAT_CONNTRACK counter accept -{% set base_command = "add rule ip6 raw" %} -{{ base_command }} PREROUTING position {{ pre_ct_conntrack }} counter jump NAT_CONNTRACK -{{ base_command }} OUTPUT position {{ out_ct_conntrack }} counter jump NAT_CONNTRACK -{% endif %} - -# -# Destination NAT66 rules build up here -# -{% if destination is defined and destination.rule is defined and destination.rule is not none %} -{% for rule, config in destination.rule.items() if config.disable is not defined %} -{{ nptv6_rule(rule, config, 'PREROUTING') }} -{% endfor %} -{% endif %} -# -# Source NAT66 rules build up here -# -{% if source is defined and source.rule is defined and source.rule is not none %} -{% for rule, config in source.rule.items() if config.disable is not defined %} -{{ nptv6_rule(rule, config, 'POSTROUTING') }} -{% endfor %} -{% endif %} diff --git a/data/templates/firewall/nftables-policy.j2 b/data/templates/firewall/nftables-policy.j2 new file mode 100644 index 000000000..0154c9f7e --- /dev/null +++ b/data/templates/firewall/nftables-policy.j2 @@ -0,0 +1,55 @@ +#!/usr/sbin/nft -f + +{% if cleanup_commands is vyos_defined %} +{% for command in cleanup_commands %} +{{ command }} +{% endfor %} +{% endif %} + +include "/run/nftables_defines.conf" + +table ip mangle { +{% if first_install is vyos_defined %} + chain VYOS_PBR_PREROUTING { + type filter hook prerouting priority -150; policy accept; + } + chain VYOS_PBR_POSTROUTING { + type filter hook postrouting priority -150; policy accept; + } +{% endif %} +{% if route is vyos_defined %} +{% for route_text, conf in route.items() %} + chain VYOS_PBR_{{ route_text }} { +{% if conf.rule is vyos_defined %} +{% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %} + {{ rule_conf | nft_rule(route_text, rule_id, 'ip') }} +{% endfor %} +{% endif %} + {{ conf | nft_default_rule(route_text) }} + } +{% endfor %} +{% endif %} +} + +table ip6 mangle { +{% if first_install is vyos_defined %} + chain VYOS_PBR6_PREROUTING { + type filter hook prerouting priority -150; policy accept; + } + chain VYOS_PBR6_POSTROUTING { + type filter hook postrouting priority -150; policy accept; + } +{% endif %} +{% if route6 is vyos_defined %} +{% for route_text, conf in route6.items() %} + chain VYOS_PBR6_{{ route_text }} { +{% if conf.rule is vyos_defined %} +{% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %} + {{ rule_conf | nft_rule(route_text, rule_id, 'ip6') }} +{% endfor %} +{% endif %} + {{ conf | nft_default_rule(route_text) }} + } +{% endfor %} +{% endif %} +} diff --git a/data/templates/firewall/nftables-vrf-zones.tmpl b/data/templates/firewall/nftables-vrf-zones.j2 index eecf47b78..eecf47b78 100644 --- a/data/templates/firewall/nftables-vrf-zones.tmpl +++ b/data/templates/firewall/nftables-vrf-zones.j2 diff --git a/data/templates/firewall/nftables.j2 b/data/templates/firewall/nftables.j2 new file mode 100644 index 000000000..fac3fad03 --- /dev/null +++ b/data/templates/firewall/nftables.j2 @@ -0,0 +1,274 @@ +#!/usr/sbin/nft -f + +{% if cleanup_commands is vyos_defined %} +{% for command in cleanup_commands %} +{{ command }} +{% endfor %} +{% endif %} + +include "/run/nftables_defines.conf" + +table ip filter { +{% if first_install is vyos_defined %} + chain VYOS_FW_FORWARD { + type filter hook forward priority 0; policy accept; + jump VYOS_POST_FW + } + chain VYOS_FW_LOCAL { + type filter hook input priority 0; policy accept; + jump VYOS_POST_FW + } + chain VYOS_FW_OUTPUT { + type filter hook output priority 0; policy accept; + jump VYOS_POST_FW + } + chain VYOS_POST_FW { + return + } + chain VYOS_FRAG_MARK { + type filter hook prerouting priority -450; policy accept; + ip frag-off & 0x3fff != 0 meta mark set 0xffff1 return + } +{% endif %} +{% if name is vyos_defined %} +{% set ns = namespace(sets=[]) %} +{% for name_text, conf in name.items() %} + chain NAME_{{ name_text }} { +{% if conf.rule is vyos_defined %} +{% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %} + {{ rule_conf | nft_rule(name_text, rule_id) }} +{% if rule_conf.recent is vyos_defined %} +{% set ns.sets = ns.sets + [name_text + '_' + rule_id] %} +{% endif %} +{% endfor %} +{% endif %} + {{ conf | nft_default_rule(name_text) }} + } +{% endfor %} +{% for set_name in ns.sets %} + set RECENT_{{ set_name }} { + type ipv4_addr + size 65535 + flags dynamic + } +{% endfor %} +{% endif %} +{% if state_policy is vyos_defined %} + chain VYOS_STATE_POLICY { +{% if state_policy.established is vyos_defined %} + {{ state_policy.established | nft_state_policy('established') }} +{% endif %} +{% if state_policy.invalid is vyos_defined %} + {{ state_policy.invalid | nft_state_policy('invalid') }} +{% endif %} +{% if state_policy.related is vyos_defined %} + {{ state_policy.related | nft_state_policy('related') }} +{% endif %} + return + } +{% endif %} +} + +table ip6 filter { +{% if first_install is vyos_defined %} + chain VYOS_FW6_FORWARD { + type filter hook forward priority 0; policy accept; + jump VYOS_POST_FW6 + } + chain VYOS_FW6_LOCAL { + type filter hook input priority 0; policy accept; + jump VYOS_POST_FW6 + } + chain VYOS_FW6_OUTPUT { + type filter hook output priority 0; policy accept; + jump VYOS_POST_FW6 + } + chain VYOS_POST_FW6 { + return + } + chain VYOS_FRAG6_MARK { + type filter hook prerouting priority -450; policy accept; + exthdr frag exists meta mark set 0xffff1 return + } +{% endif %} +{% if ipv6_name is vyos_defined %} +{% set ns = namespace(sets=[]) %} +{% for name_text, conf in ipv6_name.items() %} + chain NAME6_{{ name_text }} { +{% if conf.rule is vyos_defined %} +{% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %} + {{ rule_conf | nft_rule(name_text, rule_id, 'ip6') }} +{% if rule_conf.recent is vyos_defined %} +{% set ns.sets = ns.sets + [name_text + '_' + rule_id] %} +{% endif %} +{% endfor %} +{% endif %} + {{ conf | nft_default_rule(name_text) }} + } +{% endfor %} +{% for set_name in ns.sets %} + set RECENT6_{{ set_name }} { + type ipv6_addr + size 65535 + flags dynamic + } +{% endfor %} +{% endif %} +{% if state_policy is vyos_defined %} + chain VYOS_STATE_POLICY6 { +{% if state_policy.established is vyos_defined %} + {{ state_policy.established | nft_state_policy('established', ipv6=True) }} +{% endif %} +{% if state_policy.invalid is vyos_defined %} + {{ state_policy.invalid | nft_state_policy('invalid', ipv6=True) }} +{% endif %} +{% if state_policy.related is vyos_defined %} + {{ state_policy.related | nft_state_policy('related', ipv6=True) }} +{% endif %} + return + } +{% endif %} +} + +{% if first_install is vyos_defined %} +table ip nat { + chain PREROUTING { + type nat hook prerouting priority -100; policy accept; + counter jump VYOS_PRE_DNAT_HOOK + } + + chain POSTROUTING { + type nat hook postrouting priority 100; policy accept; + counter jump VYOS_PRE_SNAT_HOOK + } + + chain VYOS_PRE_DNAT_HOOK { + return + } + + chain VYOS_PRE_SNAT_HOOK { + return + } +} + +table ip6 nat { + chain PREROUTING { + type nat hook prerouting priority -100; policy accept; + counter jump VYOS_DNPT_HOOK + } + + chain POSTROUTING { + type nat hook postrouting priority 100; policy accept; + counter jump VYOS_SNPT_HOOK + } + + chain VYOS_DNPT_HOOK { + return + } + + chain VYOS_SNPT_HOOK { + return + } +} + +table inet mangle { + chain FORWARD { + type filter hook forward priority -150; policy accept; + } +} + +table raw { + chain VYOS_TCP_MSS { + type filter hook forward priority -300; policy accept; + } + + chain PREROUTING { + type filter hook prerouting priority -200; policy accept; + counter jump VYOS_CT_IGNORE + counter jump VYOS_CT_TIMEOUT + counter jump VYOS_CT_PREROUTING_HOOK + counter jump FW_CONNTRACK + notrack + } + + chain OUTPUT { + type filter hook output priority -200; policy accept; + counter jump VYOS_CT_IGNORE + counter jump VYOS_CT_TIMEOUT + counter jump VYOS_CT_OUTPUT_HOOK + counter jump FW_CONNTRACK + notrack + } + + ct helper rpc_tcp { + type "rpc" protocol tcp; + } + + ct helper rpc_udp { + type "rpc" protocol udp; + } + + ct helper tns_tcp { + type "tns" protocol tcp; + } + + chain VYOS_CT_HELPER { + ct helper set "rpc_tcp" tcp dport {111} return + ct helper set "rpc_udp" udp dport {111} return + ct helper set "tns_tcp" tcp dport {1521,1525,1536} return + return + } + + chain VYOS_CT_IGNORE { + return + } + + chain VYOS_CT_TIMEOUT { + return + } + + chain VYOS_CT_PREROUTING_HOOK { + return + } + + chain VYOS_CT_OUTPUT_HOOK { + return + } + + chain FW_CONNTRACK { + accept + } +} + +table ip6 raw { + chain VYOS_TCP_MSS { + type filter hook forward priority -300; policy accept; + } + + chain PREROUTING { + type filter hook prerouting priority -300; policy accept; + counter jump VYOS_CT_PREROUTING_HOOK + counter jump FW_CONNTRACK + notrack + } + + chain OUTPUT { + type filter hook output priority -300; policy accept; + counter jump VYOS_CT_OUTPUT_HOOK + counter jump FW_CONNTRACK + notrack + } + + chain VYOS_CT_PREROUTING_HOOK { + return + } + + chain VYOS_CT_OUTPUT_HOOK { + return + } + + chain FW_CONNTRACK { + accept + } +} +{% endif %} diff --git a/data/templates/firewall/upnpd.conf.j2 b/data/templates/firewall/upnpd.conf.j2 new file mode 100644 index 000000000..27573cbf9 --- /dev/null +++ b/data/templates/firewall/upnpd.conf.j2 @@ -0,0 +1,172 @@ +# This is the UPNP configuration file + +# WAN network interface +ext_ifname={{ wan_interface }} +{% if wan_ip is vyos_defined %} +# If the WAN interface has several IP addresses, you +# can specify the one to use below +{% for addr in wan_ip %} +ext_ip={{ addr }} +{% endfor %} +{% endif %} + +# LAN network interfaces IPs / networks +{% if listen is vyos_defined %} +# There can be multiple listening IPs for SSDP traffic, in that case +# use multiple 'listening_ip=...' lines, one for each network interface. +# It can be IP address or network interface name (ie. "eth0") +# It is mandatory to use the network interface name in order to enable IPv6 +# HTTP is available on all interfaces. +# When MULTIPLE_EXTERNAL_IP is enabled, the external IP +# address associated with the subnet follows. For example: +# listening_ip=192.168.0.1/24 88.22.44.13 +{% for addr in listen %} +{% if addr | is_ipv4 %} +listening_ip={{ addr }} +{% elif addr | is_ipv6 %} +ipv6_listening_ip={{ addr }} +{% else %} +listening_ip={{ addr }} +{% endif %} +{% endfor %} +{% endif %} + +# CAUTION: mixing up WAN and LAN interfaces may introduce security risks! +# Be sure to assign the correct interfaces to LAN and WAN and consider +# implementing UPnP permission rules at the bottom of this configuration file + +# Port for HTTP (descriptions and SOAP) traffic. Set to 0 for autoselect. +#http_port=0 +# Port for HTTPS. Set to 0 for autoselect (default) +#https_port=0 + +# Path to the UNIX socket used to communicate with MiniSSDPd +# If running, MiniSSDPd will manage M-SEARCH answering. +# default is /var/run/minissdpd.sock +#minissdpdsocket=/var/run/minissdpd.sock + +{% if nat_pmp is vyos_defined %} +# Enable NAT-PMP support (default is no) +enable_natpmp=yes +{% endif %} + +# Enable UPNP support (default is yes) +enable_upnp=yes + +{% if pcp_lifetime is vyos_defined %} +# PCP +# Configure the minimum and maximum lifetime of a port mapping in seconds +# 120s and 86400s (24h) are suggested values from PCP-base +{% if pcp_lifetime.max is vyos_defined %} +max_lifetime={{ pcp_lifetime.max }} +{% endif %} +{% if pcp_lifetime.min is vyos_defined %} +min_lifetime={{ pcp_lifetime.min }} +{% endif %} +{% endif %} + + +# To enable the next few runtime options, see compile time +# ENABLE_MANUFACTURER_INFO_CONFIGURATION (config.h) + +{% if friendly_name is vyos_defined %} +# Name of this service, default is "`uname -s` router" +friendly_name= {{ friendly_name }} +{% endif %} + +# Manufacturer name, default is "`uname -s`" +manufacturer_name=VyOS + +# Manufacturer URL, default is URL of OS vendor +manufacturer_url=https://vyos.io/ + +# Model name, default is "`uname -s` router" +model_name=VyOS Router Model + +# Model description, default is "`uname -s` router" +model_description=Vyos open source enterprise router/firewall operating system + +# Model URL, default is URL of OS vendor +model_url=https://vyos.io/ + +{% if secure_mode is vyos_defined %} +# Secure Mode, UPnP clients can only add mappings to their own IP +secure_mode=yes +{% else %} +# Secure Mode, UPnP clients can only add mappings to their own IP +secure_mode=no +{% endif %} + +{% if presentation_url is vyos_defined %} +# Default presentation URL is HTTP address on port 80 +# If set to an empty string, no presentationURL element will appear +# in the XML description of the device, which prevents MS Windows +# from displaying an icon in the "Network Connections" panel. +#presentation_url= {{ presentation_url }} +{% endif %} + +# Report system uptime instead of daemon uptime +system_uptime=yes + +# Unused rules cleaning. +# never remove any rule before this threshold for the number +# of redirections is exceeded. default to 20 +clean_ruleset_threshold=10 +# Clean process work interval in seconds. default to 0 (disabled). +# a 600 seconds (10 minutes) interval makes sense +clean_ruleset_interval=600 + +# Anchor name in pf (default is miniupnpd) +anchor=VyOS + +uuid={{ uuid }} + +# Lease file location +lease_file=/config/upnp.leases + +# Daemon's serial and model number when reporting to clients +# (in XML description) +#serial=12345678 +#model_number=1 + +{% if rules is vyos_defined %} +# UPnP permission rules +# (allow|deny) (external port range) IP/mask (internal port range) +# A port range is <min port>-<max port> or <port> if there is only +# one port in the range. +# IP/mask format must be nnn.nnn.nnn.nnn/nn +# It is advised to only allow redirection of port >= 1024 +# and end the rule set with "deny 0-65535 0.0.0.0/0 0-65535" +# The following default ruleset allows specific LAN side IP addresses +# to request only ephemeral ports. It is recommended that users +# modify the IP ranges to match their own internal networks, and +# also consider implementing network-specific restrictions +# CAUTION: failure to enforce any rules may permit insecure requests to be made! +{% for rule, config in rules.items() %} +{% if config.disable is vyos_defined %} +{{ config.action }} {{ config.external_port_range }} {{ config.ip }} {{ config.internal_port_range }} +{% endif %} +{% endfor %} +{% endif %} + +{% if stun is vyos_defined %} +# WAN interface must have public IP address. Otherwise it is behind NAT +# and port forwarding is impossible. In some cases WAN interface can be +# behind unrestricted NAT 1:1 when all incoming traffic is NAT-ed and +# routed to WAN interfaces without any filtering. In this cases miniupnpd +# needs to know public IP address and it can be learnt by asking external +# server via STUN protocol. Following option enable retrieving external +# public IP address from STUN server and detection of NAT type. You need +# to specify also external STUN server in stun_host option below. +# This option is disabled by default. +ext_perform_stun=yes +# Specify STUN server, either hostname or IP address +# Some public STUN servers: +# stun.stunprotocol.org +# stun.sipgate.net +# stun.xten.com +# stun.l.google.com (on non standard port 19302) +ext_stun_host={{ stun.host }} +# Specify STUN UDP port, by default it is standard port 3478. +ext_stun_port={{ stun.port }} +{% endif %} diff --git a/data/templates/frr/bfdd.frr.j2 b/data/templates/frr/bfdd.frr.j2 new file mode 100644 index 000000000..c4adeb402 --- /dev/null +++ b/data/templates/frr/bfdd.frr.j2 @@ -0,0 +1,58 @@ +{% if profile is vyos_defined or peer is vyos_defined %} +bfd +{% if profile is vyos_defined %} +{% for profile_name, profile_config in profile.items() %} + profile {{ profile_name }} + detect-multiplier {{ profile_config.interval.multiplier }} + receive-interval {{ profile_config.interval.receive }} + transmit-interval {{ profile_config.interval.transmit }} +{% if profile_config.interval.echo_interval is vyos_defined %} + echo transmit-interval {{ profile_config.interval.echo_interval }} + echo receive-interval {{ profile_config.interval.echo_interval }} +{% endif %} +{% if profile_config.echo_mode is vyos_defined %} + echo-mode +{% endif %} +{% if profile_config.passive is vyos_defined %} + passive-mode +{% endif %} +{% if profile_config.shutdown is vyos_defined %} + shutdown +{% else %} + no shutdown +{% endif %} + exit + ! +{% endfor %} +{% endif %} +{% if peer is vyos_defined %} +{% for peer_name, peer_config in peer.items() %} + peer {{ peer_name }} {{ 'multihop' if peer_config.multihop is vyos_defined }} {{ 'local-address ' ~ peer_config.source.address if peer_config.source.address is vyos_defined }} {{ 'interface ' ~ peer_config.source.interface if peer_config.source.interface is vyos_defined }} {{ 'vrf ' ~ peer_config.vrf if peer_config.vrf is vyos_defined }} + detect-multiplier {{ peer_config.interval.multiplier }} + receive-interval {{ peer_config.interval.receive }} + transmit-interval {{ peer_config.interval.transmit }} +{% if peer_config.interval.echo_interval is vyos_defined %} + echo transmit-interval {{ peer_config.interval.echo_interval }} + echo receive-interval {{ peer_config.interval.echo_interval }} +{% endif %} +{% if peer_config.echo_mode is vyos_defined %} + echo-mode +{% endif %} +{% if peer_config.passive is vyos_defined %} + passive-mode +{% endif %} +{% if peer_config.profile is vyos_defined %} + profile {{ peer_config.profile }} +{% endif %} +{% if peer_config.shutdown is vyos_defined %} + shutdown +{% else %} + no shutdown +{% endif %} + exit + ! +{% endfor %} +{% endif %} +exit +! +{% endif %} diff --git a/data/templates/frr/bfdd.frr.tmpl b/data/templates/frr/bfdd.frr.tmpl deleted file mode 100644 index 16f8be92c..000000000 --- a/data/templates/frr/bfdd.frr.tmpl +++ /dev/null @@ -1,44 +0,0 @@ -! -bfd -{% if profile is defined and profile is not none %} -{% for profile_name, profile_config in profile.items() %} - profile {{ profile_name }} - detect-multiplier {{ profile_config.interval.multiplier }} - receive-interval {{ profile_config.interval.receive }} - transmit-interval {{ profile_config.interval.transmit }} -{% if profile_config.interval['echo-interval'] is defined and profile_config.interval['echo-interval'] is not none %} - echo-interval {{ profile_config.interval['echo-interval'] }} -{% endif %} -{% if profile_config['echo-mode'] is defined %} - echo-mode -{% endif %} -{% if profile_config.shutdown is defined %} - shutdown -{% else %} - no shutdown -{% endif %} - exit -{% endfor %} -{% endif %} -{% if peer is defined and peer is not none %} -{% for peer_name, peer_config in peer.items() %} - peer {{ peer_name }}{{ ' multihop' if peer_config.multihop is defined }}{{ ' local-address ' + peer_config.source.address if peer_config.source is defined and peer_config.source.address is defined }}{{ ' interface ' + peer_config.source.interface if peer_config.source is defined and peer_config.source.interface is defined }} - detect-multiplier {{ peer_config.interval.multiplier }} - receive-interval {{ peer_config.interval.receive }} - transmit-interval {{ peer_config.interval.transmit }} -{% if peer_config.interval['echo-interval'] is defined and peer_config.interval['echo-interval'] is not none %} - echo-interval {{ peer_config.interval['echo-interval'] }} -{% endif %} -{% if peer_config['echo-mode'] is defined %} - echo-mode -{% endif %} -{% if peer_config.shutdown is defined %} - shutdown -{% else %} - no shutdown -{% endif %} - exit -{% endfor %} -{% endif %} - end -! diff --git a/data/templates/frr/bgpd.frr.j2 b/data/templates/frr/bgpd.frr.j2 new file mode 100644 index 000000000..7029f39af --- /dev/null +++ b/data/templates/frr/bgpd.frr.j2 @@ -0,0 +1,533 @@ +{### MACRO definition for recurring peer patter, this can be either fed by a ###} +{### peer-group or an individual BGP neighbor ###} +{% macro bgp_neighbor(neighbor, config, peer_group=false) %} +{% if peer_group == true %} + neighbor {{ neighbor }} peer-group +{% elif config.peer_group is vyos_defined %} + neighbor {{ neighbor }} peer-group {{ config.peer_group }} +{% endif %} +{% if config.remote_as is vyos_defined %} + neighbor {{ neighbor }} remote-as {{ config.remote_as }} +{% endif %} +{% if config.interface.remote_as is vyos_defined %} + neighbor {{ neighbor }} interface remote-as {{ config.interface.remote_as }} +{% endif %} +{% if config.advertisement_interval is vyos_defined %} + neighbor {{ neighbor }} advertisement-interval {{ config.advertisement_interval }} +{% endif %} +{% if config.bfd is vyos_defined %} + neighbor {{ neighbor }} bfd +{% if config.bfd.check_control_plane_failure is vyos_defined %} + neighbor {{ neighbor }} bfd check-control-plane-failure +{% endif %} +{% if config.bfd.profile is vyos_defined %} + neighbor {{ neighbor }} bfd profile {{ config.bfd.profile }} +{% endif %} +{% endif %} +{% if config.capability is vyos_defined %} +{% if config.capability.dynamic is vyos_defined %} + neighbor {{ neighbor }} capability dynamic +{% endif %} +{% if config.capability.extended_nexthop is vyos_defined %} + neighbor {{ neighbor }} capability extended-nexthop +{% endif %} +{% endif %} +{% if config.description is vyos_defined %} + neighbor {{ neighbor }} description {{ config.description }} +{% endif %} +{% if config.disable_capability_negotiation is vyos_defined %} + neighbor {{ neighbor }} dont-capability-negotiate +{% endif %} +{% if config.ebgp_multihop is vyos_defined %} + neighbor {{ neighbor }} ebgp-multihop {{ config.ebgp_multihop }} +{% endif %} +{% if config.graceful_restart is vyos_defined %} +{% if config.graceful_restart is vyos_defined('enable') %} +{% set graceful_restart = 'graceful-restart' %} +{% elif config.graceful_restart is vyos_defined('disable') %} +{% set graceful_restart = 'graceful-restart-disable' %} +{% elif config.graceful_restart is vyos_defined('restart-helper') %} +{% set graceful_restart = 'graceful-restart-helper' %} +{% endif %} + neighbor {{ neighbor }} {{ graceful_restart }} +{% endif %} +{% if config.local_as is vyos_defined %} +{% for local_as, local_as_config in config.local_as.items() %} +{# There can be only one local-as value, this is checked in the Python code #} + neighbor {{ neighbor }} local-as {{ local_as }} {{ 'no-prepend' if local_as_config.no_prepend is vyos_defined }} {{ 'replace-as' if local_as_config.no_prepend is vyos_defined and local_as_config.no_prepend.replace_as is vyos_defined }} +{% endfor %} +{% endif %} +{% if config.override_capability is vyos_defined %} + neighbor {{ neighbor }} override-capability +{% endif %} +{% if config.passive is vyos_defined %} + neighbor {{ neighbor }} passive +{% endif %} +{% if config.password is vyos_defined %} + neighbor {{ neighbor }} password {{ config.password }} +{% endif %} +{% if config.port is vyos_defined %} + neighbor {{ neighbor }} port {{ config.port }} +{% endif %} +{% if config.shutdown is vyos_defined %} + neighbor {{ neighbor }} shutdown +{% endif %} +{% if config.solo is vyos_defined %} + neighbor {{ neighbor }} solo +{% endif %} +{% if config.strict_capability_match is vyos_defined %} + neighbor {{ neighbor }} strict-capability-match +{% endif %} +{% if config.ttl_security.hops is vyos_defined %} + neighbor {{ neighbor }} ttl-security hops {{ config.ttl_security.hops }} +{% endif %} +{% if config.timers.connect is vyos_defined %} + neighbor {{ neighbor }} timers connect {{ config.timers.connect }} +{% endif %} +{% if config.timers.keepalive is vyos_defined and config.timers.holdtime is vyos_defined %} + neighbor {{ neighbor }} timers {{ config.timers.keepalive }} {{ config.timers.holdtime }} +{% endif %} +{% if config.update_source is vyos_defined %} + neighbor {{ neighbor }} update-source {{ config.update_source }} +{% endif %} +{% if config.interface is vyos_defined %} +{% if config.interface.peer_group is vyos_defined %} + neighbor {{ neighbor }} interface peer-group {{ config.interface.peer_group }} +{% endif %} +{% if config.interface.source_interface is vyos_defined %} + neighbor {{ neighbor }} interface {{ config.interface.source_interface }} +{% endif %} +{% if config.interface.v6only is vyos_defined %} +{% if config.interface.v6only.peer_group is vyos_defined %} + neighbor {{ neighbor }} interface v6only peer-group {{ config.interface.v6only.peer_group }} +{% endif %} +{% if config.interface.v6only.remote_as is vyos_defined %} + neighbor {{ neighbor }} interface v6only remote-as {{ config.interface.v6only.remote_as }} +{% endif %} +{% endif %} +{% endif %} + ! +{% if config.address_family is vyos_defined %} +{% for afi, afi_config in config.address_family.items() %} +{% if afi == 'ipv4_unicast' %} + address-family ipv4 unicast +{% elif afi == 'ipv4_multicast' %} + address-family ipv4 multicast +{% elif afi == 'ipv4_labeled_unicast' %} + address-family ipv4 labeled-unicast +{% elif afi == 'ipv4_vpn' %} + address-family ipv4 vpn +{% elif afi == 'ipv4_flowspec' %} + address-family ipv4 flowspec +{% elif afi == 'ipv6_unicast' %} + address-family ipv6 unicast +{% elif afi == 'ipv6_multicast' %} + address-family ipv6 multicast +{% elif afi == 'ipv6_labeled_unicast' %} + address-family ipv6 labeled-unicast +{% elif afi == 'ipv6_vpn' %} + address-family ipv6 vpn +{% elif afi == 'ipv6_flowspec' %} + address-family ipv6 flowspec +{% elif afi == 'l2vpn_evpn' %} + address-family l2vpn evpn +{% endif %} +{% if afi_config.addpath_tx_all is vyos_defined %} + neighbor {{ neighbor }} addpath-tx-all-paths +{% endif %} +{% if afi_config.addpath_tx_per_as is vyos_defined %} + neighbor {{ neighbor }} addpath-tx-bestpath-per-AS +{% endif %} +{% if afi_config.allowas_in is vyos_defined %} + neighbor {{ neighbor }} allowas-in {{ afi_config.allowas_in.number if afi_config.allowas_in.number is vyos_defined }} +{% endif %} +{% if afi_config.as_override is vyos_defined %} + neighbor {{ neighbor }} as-override +{% endif %} +{% if afi_config.conditionally_advertise is vyos_defined %} +{% if afi_config.conditionally_advertise.advertise_map is vyos_defined %} +{% set exist_non_exist_map = 'exist-map' %} +{% if afi_config.conditionally_advertise.exist_map is vyos_defined %} +{% set exist_non_exist_map = 'exist-map ' ~ afi_config.conditionally_advertise.exist_map %} +{% elif afi_config.conditionally_advertise.non_exist_map is vyos_defined %} +{% set exist_non_exist_map = 'non-exist-map ' ~ afi_config.conditionally_advertise.non_exist_map %} +{% endif %} + neighbor {{ neighbor }} advertise-map {{ afi_config.conditionally_advertise.advertise_map }} {{ exist_non_exist_map }} +{% endif %} +{% endif %} +{% if afi_config.remove_private_as is vyos_defined %} + neighbor {{ neighbor }} remove-private-AS +{% endif %} +{% if afi_config.route_reflector_client is vyos_defined %} + neighbor {{ neighbor }} route-reflector-client +{% endif %} +{% if afi_config.weight is vyos_defined %} + neighbor {{ neighbor }} weight {{ afi_config.weight }} +{% endif %} +{% if afi_config.attribute_unchanged is vyos_defined %} + neighbor {{ neighbor }} attribute-unchanged {{ 'as-path ' if afi_config.attribute_unchanged.as_path is vyos_defined }}{{ 'med ' if afi_config.attribute_unchanged.med is vyos_defined }}{{ 'next-hop ' if afi_config.attribute_unchanged.next_hop is vyos_defined }} +{% endif %} +{% if afi_config.capability.orf.prefix_list.send is vyos_defined %} + neighbor {{ neighbor }} capability orf prefix-list send +{% endif %} +{% if afi_config.capability.orf.prefix_list.receive is vyos_defined %} + neighbor {{ neighbor }} capability orf prefix-list receive +{% endif %} +{% if afi_config.default_originate is vyos_defined %} + neighbor {{ neighbor }} default-originate {{ 'route-map ' ~ afi_config.default_originate.route_map if afi_config.default_originate.route_map is vyos_defined }} +{% endif %} +{% if afi_config.distribute_list.export is vyos_defined %} + neighbor {{ neighbor }} distribute-list {{ afi_config.distribute_list.export }} out +{% endif %} +{% if afi_config.distribute_list.import is vyos_defined %} + neighbor {{ neighbor }} distribute-list {{ afi_config.distribute_list.import }} in +{% endif %} +{% if afi_config.filter_list.export is vyos_defined %} + neighbor {{ neighbor }} filter-list {{ afi_config.filter_list.export }} out +{% endif %} +{% if afi_config.filter_list.import is vyos_defined %} + neighbor {{ neighbor }} filter-list {{ afi_config.filter_list.import }} in +{% endif %} +{% if afi_config.maximum_prefix is vyos_defined %} + neighbor {{ neighbor }} maximum-prefix {{ afi_config.maximum_prefix }} +{% endif %} +{% if afi_config.maximum_prefix_out is vyos_defined %} + neighbor {{ neighbor }} maximum-prefix-out {{ afi_config.maximum_prefix_out }} +{% endif %} +{% if afi_config.nexthop_self is vyos_defined %} + neighbor {{ neighbor }} next-hop-self {{ 'force' if afi_config.nexthop_self.force is vyos_defined }} +{% endif %} +{% if afi_config.route_server_client is vyos_defined %} + neighbor {{ neighbor }} route-server-client +{% endif %} +{% if afi_config.route_map.export is vyos_defined %} + neighbor {{ neighbor }} route-map {{ afi_config.route_map.export }} out +{% endif %} +{% if afi_config.route_map.import is vyos_defined %} + neighbor {{ neighbor }} route-map {{ afi_config.route_map.import }} in +{% endif %} +{% if afi_config.prefix_list.export is vyos_defined %} + neighbor {{ neighbor }} prefix-list {{ afi_config.prefix_list.export }} out +{% endif %} +{% if afi_config.prefix_list.import is vyos_defined %} + neighbor {{ neighbor }} prefix-list {{ afi_config.prefix_list.import }} in +{% endif %} +{% if afi_config.soft_reconfiguration.inbound is vyos_defined %} + neighbor {{ neighbor }} soft-reconfiguration inbound +{% endif %} +{% if afi_config.unsuppress_map is vyos_defined %} + neighbor {{ neighbor }} unsuppress-map {{ afi_config.unsuppress_map }} +{% endif %} +{% if afi_config.disable_send_community.extended is vyos_defined %} + no neighbor {{ neighbor }} send-community extended +{% endif %} +{% if afi_config.disable_send_community.standard is vyos_defined %} + no neighbor {{ neighbor }} send-community standard +{% endif %} + neighbor {{ neighbor }} activate + exit-address-family + ! +{% endfor %} +{% endif %} +{% endmacro %} +! +router bgp {{ local_as }} {{ 'vrf ' ~ vrf if vrf is vyos_defined }} +{% if parameters.ebgp_requires_policy is vyos_defined %} + bgp ebgp-requires-policy +{% else %} + no bgp ebgp-requires-policy +{% endif %} +{# Option must be set before any neighbor - see https://phabricator.vyos.net/T3463 #} + no bgp default ipv4-unicast +{# Workaround for T2100 until we have decided about a migration script #} + no bgp network import-check +{% if address_family is vyos_defined %} +{% for afi, afi_config in address_family.items() %} + ! +{% if afi == 'ipv4_unicast' %} + address-family ipv4 unicast +{% elif afi == 'ipv4_multicast' %} + address-family ipv4 multicast +{% elif afi == 'ipv4_labeled_unicast' %} + address-family ipv4 labeled-unicast +{% elif afi == 'ipv4_vpn' %} + address-family ipv4 vpn +{% elif afi == 'ipv4_flowspec' %} + address-family ipv4 flowspec +{% elif afi == 'ipv6_unicast' %} + address-family ipv6 unicast +{% elif afi == 'ipv6_multicast' %} + address-family ipv6 multicast +{% elif afi == 'ipv6_labeled_unicast' %} + address-family ipv6 labeled-unicast +{% elif afi == 'ipv6_vpn' %} + address-family ipv6 vpn +{% elif afi == 'ipv6_flowspec' %} + address-family ipv6 flowspec +{% elif afi == 'l2vpn_evpn' %} + address-family l2vpn evpn +{% if afi_config.rd is vyos_defined %} + rd {{ afi_config.rd }} +{% endif %} +{% endif %} +{% if afi_config.aggregate_address is vyos_defined %} +{% for aggregate, aggregate_config in afi_config.aggregate_address.items() %} + aggregate-address {{ aggregate }}{{ ' as-set' if aggregate_config.as_set is vyos_defined }}{{ ' summary-only' if aggregate_config.summary_only is vyos_defined }} +{% if aggregate_config.route_map is vyos_defined %} + aggregate-address {{ aggregate }} route-map {{ aggregate_config.route_map }} +{% endif %} +{% endfor %} +{% endif %} +{% if afi_config.maximum_paths.ebgp is vyos_defined %} + maximum-paths {{ afi_config.maximum_paths.ebgp }} +{% endif %} +{% if afi_config.maximum_paths.ibgp is vyos_defined %} + maximum-paths ibgp {{ afi_config.maximum_paths.ibgp }} +{% endif %} +{% if afi_config.redistribute is vyos_defined %} +{% for protocol, protocol_config in afi_config.redistribute.items() %} +{% if protocol == 'table' %} + redistribute table {{ protocol_config.table }} +{% else %} +{% set redistribution_protocol = protocol %} +{% if protocol == 'ospfv3' %} +{% set redistribution_protocol = 'ospf6' %} +{% endif %} + redistribute {{ redistribution_protocol }} {{ 'metric ' ~ protocol_config.metric if protocol_config.metric is vyos_defined }} {{ 'route-map ' ~ protocol_config.route_map if protocol_config.route_map is vyos_defined }} + {####### we need this blank line!! #######} + +{% endif %} +{% endfor %} +{% endif %} +{% if afi_config.network is vyos_defined %} +{% for network, network_config in afi_config.network.items() %} + network {{ network }} {{ 'route-map ' ~ network_config.route_map if network_config.route_map is vyos_defined }} {{ 'backdoor' if network_config.backdoor is vyos_defined }} {{ 'rd ' ~ network_config.rd if network_config.rd is vyos_defined }} {{ 'label ' ~ network_config.label if network_config.label is vyos_defined }} +{####### we need this blank line!! #######} + +{% endfor %} +{% endif %} +{% if afi_config.advertise is vyos_defined %} +{% for adv_afi, adv_afi_config in afi_config.advertise.items() %} +{% if adv_afi_config.unicast is vyos_defined %} + advertise {{ adv_afi }} unicast {{ 'route-map ' ~ adv_afi_config.unicast.route_map if adv_afi_config.unicast.route_map is vyos_defined }} +{% endif %} +{% endfor %} +{% endif %} +{% if afi_config.distance.external is vyos_defined and afi_config.distance.internal is vyos_defined and afi_config.distance.local is vyos_defined %} + distance bgp {{ afi_config.distance.external }} {{ afi_config.distance.internal }} {{ afi_config.distance.local }} +{% endif %} +{% if afi_config.distance.prefix is vyos_defined %} +{% for prefix in afi_config.distance.prefix %} + distance {{ afi_config.distance.prefix[prefix].distance }} {{ prefix }} +{% endfor %} +{% endif %} +{% if afi_config.export.vpn is vyos_defined %} + export vpn +{% endif %} +{% if afi_config.import.vpn is vyos_defined %} + import vpn +{% endif %} +{% if afi_config.import.vrf is vyos_defined %} +{% for vrf in afi_config.import.vrf %} + import vrf {{ vrf }} +{% endfor %} +{% endif %} +{% if afi_config.label.vpn.export is vyos_defined %} + label vpn export {{ afi_config.label.vpn.export }} +{% endif %} +{% if afi_config.local_install is vyos_defined %} +{% for interface in afi_config.local_install.interface %} + local-install {{ interface }} +{% endfor %} +{% endif %} +{% if afi_config.advertise_all_vni is vyos_defined %} + advertise-all-vni +{% endif %} +{% if afi_config.advertise_default_gw is vyos_defined %} + advertise-default-gw +{% endif %} +{% if afi_config.advertise_pip is vyos_defined %} + advertise-pip ip {{ afi_config.advertise_pip }} +{% endif %} +{% if afi_config.advertise_svi_ip is vyos_defined %} + advertise-svi-ip +{% endif %} +{% if afi_config.rt_auto_derive is vyos_defined %} + autort rfc8365-compatible +{% endif %} +{% if afi_config.flooding.disable is vyos_defined %} + flooding disable +{% endif %} +{% if afi_config.flooding.head_end_replication is vyos_defined %} + flooding head-end-replication +{% endif %} +{% if afi_config.rd.vpn.export is vyos_defined %} + rd vpn export {{ afi_config.rd.vpn.export }} +{% endif %} +{% if afi_config.route_target.vpn.both is vyos_defined %} + route-target vpn both {{ afi_config.route_target.vpn.both }} +{% else %} +{% if afi_config.route_target.vpn.export is vyos_defined %} + route-target vpn export {{ afi_config.route_target.vpn.export }} +{% endif %} +{% if afi_config.route_target.vpn.import is vyos_defined %} + route-target vpn import {{ afi_config.route_target.vpn.import }} +{% endif %} +{% endif %} +{% if afi_config.route_target.both is vyos_defined %} + route-target both {{ afi_config.route_target.both }} +{% else %} +{% if afi_config.route_target.export is vyos_defined %} + route-target export {{ afi_config.route_target.export }} +{% endif %} +{% if afi_config.route_target.import is vyos_defined %} + route-target import {{ afi_config.route_target.import }} +{% endif %} +{% endif %} +{% if afi_config.route_map.vpn.export is vyos_defined %} + route-map vpn export {{ afi_config.route_map.vpn.export }} +{% endif %} +{% if afi_config.route_map.vpn.import is vyos_defined %} + route-map vpn import {{ afi_config.route_map.vpn.import }} +{% endif %} +{% if afi_config.vni is vyos_defined %} +{% for vni, vni_config in afi_config.vni.items() %} + vni {{ vni }} +{% if vni_config.advertise_default_gw is vyos_defined %} + advertise-default-gw +{% endif %} +{% if vni_config.advertise_svi_ip is vyos_defined %} + advertise-svi-ip +{% endif %} +{% if vni_config.rd is vyos_defined %} + rd {{ vni_config.rd }} +{% endif %} +{% if vni_config.route_target.both is vyos_defined %} + route-target both {{ vni_config.route_target.both }} +{% endif %} +{% if vni_config.route_target.export is vyos_defined %} + route-target export {{ vni_config.route_target.export }} +{% endif %} +{% if vni_config.route_target.import is vyos_defined %} + route-target import {{ vni_config.route_target.import }} +{% endif %} + exit-vni +{% endfor %} +{% endif %} + exit-address-family +{% endfor %} +{% endif %} + ! +{% if peer_group is vyos_defined %} +{% for peer, config in peer_group.items() %} +{{ bgp_neighbor(peer, config, true) }} +{% endfor %} +{% endif %} + ! +{% if neighbor is vyos_defined %} +{% for peer, config in neighbor.items() %} +{{ bgp_neighbor(peer, config) }} +{% endfor %} +{% endif %} + ! +{% if listen.limit is vyos_defined %} + bgp listen limit {{ listen.limit }} +{% endif %} +{% if listen.range is vyos_defined %} +{% for prefix, options in listen.range.items() %} +{% if options.peer_group is vyos_defined %} + bgp listen range {{ prefix }} peer-group {{ options.peer_group }} +{% endif %} +{% endfor %} +{% endif %} +{% if parameters.always_compare_med is vyos_defined %} + bgp always-compare-med +{% endif %} +{% if parameters.bestpath.as_path is vyos_defined %} +{% for option in parameters.bestpath.as_path %} +{# replace is required for multipath-relax option #} + bgp bestpath as-path {{ option | replace('_', '-') }} +{% endfor %} +{% endif %} +{% if parameters.bestpath.bandwidth is vyos_defined %} + bgp bestpath bandwidth {{ parameters.bestpath.bandwidth }} +{% endif %} +{% if parameters.bestpath.compare_routerid is vyos_defined %} + bgp bestpath compare-routerid +{% endif %} +{% if parameters.bestpath.med is vyos_defined %} + bgp bestpath med {{ 'confed' if parameters.bestpath.med.confed is vyos_defined }} {{ 'missing-as-worst' if parameters.bestpath.med.missing_as_worst is vyos_defined }} +{% endif %} +{% if parameters.cluster_id is vyos_defined %} + bgp cluster-id {{ parameters.cluster_id }} +{% endif %} +{% if parameters.conditional_advertisement.timer is vyos_defined %} + bgp conditional-advertisement timer {{ parameters.conditional_advertisement.timer }} +{% endif %} +{% if parameters.confederation.identifier is vyos_defined %} + bgp confederation identifier {{ parameters.confederation.identifier }} +{% endif %} +{% if parameters.confederation.peers is vyos_defined %} + bgp confederation peers {{ parameters.confederation.peers | join(' ') }} +{% endif %} +{% if parameters.dampening.half_life is vyos_defined %} +{# Doesn't work in current FRR configuration; vtysh (bgp dampening 16 751 2001 61) #} + bgp dampening {{ parameters.dampening.half_life }} {{ parameters.dampening.re_use if parameters.dampening.re_use is vyos_defined }} {{ parameters.dampening.start_suppress_time if parameters.dampening.start_suppress_time is vyos_defined }} {{ parameters.dampening.max_suppress_time if parameters.dampening.max_suppress_time is vyos_defined }} +{% endif %} +{% if parameters.default.local_pref is vyos_defined %} + bgp default local-preference {{ parameters.default.local_pref }} +{% endif %} +{% if parameters.deterministic_med is vyos_defined %} + bgp deterministic-med +{% endif %} +{% if parameters.distance.global.external is vyos_defined and parameters.distance.global.internal is vyos_defined and parameters.distance.global.local is vyos_defined %} + distance bgp {{ parameters.distance.global.external }} {{ parameters.distance.global.internal }} {{ parameters.distance.global.local }} +{% endif %} +{% if parameters.distance.prefix is vyos_defined %} +{% for prefix in parameters.distance.prefix %} + distance {{ parameters.distance.prefix[prefix].distance }} {{ prefix }} +{% endfor %} +{% endif %} +{% if parameters.fast_convergence is vyos_defined %} + bgp fast-convergence +{% endif %} +{% if parameters.graceful_restart is vyos_defined %} + bgp graceful-restart {{ 'stalepath-time ' ~ parameters.graceful_restart.stalepath_time if parameters.graceful_restart.stalepath_time is vyos_defined }} +{% endif %} +{% if parameters.graceful_shutdown is vyos_defined %} + bgp graceful-shutdown +{% endif %} +{% if parameters.log_neighbor_changes is vyos_defined %} + bgp log-neighbor-changes +{% endif %} +{% if parameters.minimum_holdtime is vyos_defined %} + bgp minimum-holdtime {{ parameters.minimum_holdtime }} +{% endif %} +{% if parameters.network_import_check is vyos_defined %} + bgp network import-check +{% endif %} +{% if parameters.no_client_to_client_reflection is vyos_defined %} + no bgp client-to-client reflection +{% endif %} +{% if parameters.no_fast_external_failover is vyos_defined %} + no bgp fast-external-failover +{% endif %} +{% if parameters.no_suppress_duplicates is vyos_defined %} + no bgp suppress-duplicates +{% endif %} +{% if parameters.reject_as_sets is vyos_defined %} + bgp reject-as-sets +{% endif %} +{% if parameters.router_id is vyos_defined and parameters.router_id is not none %} + bgp router-id {{ parameters.router_id }} +{% endif %} +{% if parameters.shutdown is vyos_defined %} + bgp shutdown +{% endif %} +{% if parameters.suppress_fib_pending is vyos_defined %} + bgp suppress-fib-pending +{% endif %} +{% if timers.keepalive is vyos_defined and timers.holdtime is vyos_defined %} + timers bgp {{ timers.keepalive }} {{ timers.holdtime }} +{% endif %} +exit diff --git a/data/templates/frr/bgpd.frr.tmpl b/data/templates/frr/bgpd.frr.tmpl deleted file mode 100644 index 61936bb56..000000000 --- a/data/templates/frr/bgpd.frr.tmpl +++ /dev/null @@ -1,528 +0,0 @@ -{### MACRO definition for recurring peer patter, this can be either fed by a ###} -{### peer-group or an individual BGP neighbor ###} -{% macro bgp_neighbor(neighbor, config, peer_group=false) %} -{% if peer_group == true %} - neighbor {{ neighbor }} peer-group -{% elif config.peer_group is defined and config.peer_group is not none %} - neighbor {{ neighbor }} peer-group {{ config.peer_group }} -{% endif %} -{% if config.remote_as is defined and config.remote_as is not none %} - neighbor {{ neighbor }} remote-as {{ config.remote_as }} -{% endif %} -{% if config.interface is defined and config.interface.remote_as is defined and config.interface.remote_as is not none %} - neighbor {{ neighbor }} interface remote-as {{ config.interface.remote_as }} -{% endif %} -{% if config.advertisement_interval is defined and config.advertisement_interval is not none %} - neighbor {{ neighbor }} advertisement-interval {{ config.advertisement_interval }} -{% endif %} -{% if config.bfd is defined %} - neighbor {{ neighbor }} bfd -{% endif %} -{% if config.capability is defined and config.capability is not none %} -{% if config.capability.dynamic is defined %} - neighbor {{ neighbor }} capability dynamic -{% endif %} -{% if config.capability.extended_nexthop is defined %} - neighbor {{ neighbor }} capability extended-nexthop -{% endif %} -{% endif %} -{% if config.description is defined and config.description is not none %} - neighbor {{ neighbor }} description {{ config.description }} -{% endif %} -{% if config.disable_capability_negotiation is defined %} - neighbor {{ neighbor }} dont-capability-negotiate -{% endif %} -{% if config.ebgp_multihop is defined and config.ebgp_multihop is not none %} - neighbor {{ neighbor }} ebgp-multihop {{ config.ebgp_multihop }} -{% endif %} -{% if config.graceful_restart is defined and config.graceful_restart is not none %} -{% if config.graceful_restart == 'enable' %} -{% set graceful_restart = 'graceful-restart' %} -{% elif config.graceful_restart == 'disable' %} -{% set graceful_restart = 'graceful-restart-disable' %} -{% elif config.graceful_restart == 'restart-helper' %} -{% set graceful_restart = 'graceful-restart-helper' %} -{% endif %} - neighbor {{ neighbor }} {{ graceful_restart }} -{% endif %} -{% if config.local_as is defined and config.local_as is not none %} -{% for local_as, local_as_config in config.local_as.items() %} -{# There can be only one local-as value, this is checked in the Python code #} - neighbor {{ neighbor }} local-as {{ local_as }} {{ 'no-prepend' if local_as_config.no_prepend is defined }} {{ 'replace-as' if local_as_config.no_prepend is defined and local_as_config.no_prepend.replace_as is defined }} -{% endfor %} -{% endif %} -{% if config.override_capability is defined %} - neighbor {{ neighbor }} override-capability -{% endif %} -{% if config.passive is defined %} - neighbor {{ neighbor }} passive -{% endif %} -{% if config.password is defined and config.password is not none %} - neighbor {{ neighbor }} password {{ config.password }} -{% endif %} -{% if config.port is defined and config.port is not none %} - neighbor {{ neighbor }} port {{ config.port }} -{% endif %} -{% if config.shutdown is defined %} - neighbor {{ neighbor }} shutdown -{% endif %} -{% if config.solo is defined %} - neighbor {{ neighbor }} solo -{% endif %} -{% if config.strict_capability_match is defined %} - neighbor {{ neighbor }} strict-capability-match -{% endif %} -{% if config.ttl_security is defined and config.ttl_security.hops is defined and config.ttl_security.hops is not none %} - neighbor {{ neighbor }} ttl-security hops {{ config.ttl_security.hops }} -{% endif %} -{% if config.timers is defined %} -{% if config.timers.connect is defined and config.timers.connect is not none %} - neighbor {{ neighbor }} timers connect {{ config.timers.connect }} -{% endif %} -{% if config.timers.holdtime is defined and config.timers.keepalive is defined and config.timers.holdtime is not none and config.timers.keepalive is not none %} - neighbor {{ neighbor }} timers {{ config.timers.keepalive }} {{ config.timers.holdtime }} -{% endif %} -{% endif %} -{% if config.update_source is defined and config.update_source is not none %} - neighbor {{ neighbor }} update-source {{ config.update_source }} -{% endif %} -{% if config.interface is defined and config.interface is not none %} -{% if config.interface.peer_group is defined and config.interface.peer_group is not none %} - neighbor {{ neighbor }} interface peer-group {{ config.interface.peer_group }} -{% endif %} -{% if config.interface.source_interface is defined and config.interface.source_interface is not none %} - neighbor {{ neighbor }} interface {{ config.interface.source_interface }} -{% endif %} -{% if config.interface.v6only is defined and config.interface.v6only is not none %} -{% if config.interface.v6only.peer_group is defined and config.interface.v6only.peer_group is not none %} - neighbor {{ neighbor }} interface v6only peer-group {{ config.interface.v6only.peer_group }} -{% endif %} -{% if config.interface.v6only.remote_as is defined and config.interface.v6only.remote_as is not none %} - neighbor {{ neighbor }} interface v6only remote-as {{ config.interface.v6only.remote_as }} -{% endif %} -{% endif %} -{% endif %} - ! -{% if config.address_family is defined and config.address_family is not none %} -{% for afi, afi_config in config.address_family.items() %} -{% if afi == 'ipv4_unicast' %} - address-family ipv4 unicast -{% elif afi == 'ipv4_multicast' %} - address-family ipv4 multicast -{% elif afi == 'ipv4_labeled_unicast' %} - address-family ipv4 labeled-unicast -{% elif afi == 'ipv4_vpn' %} - address-family ipv4 vpn -{% elif afi == 'ipv4_flowspec' %} - address-family ipv4 flowspec -{% elif afi == 'ipv6_unicast' %} - address-family ipv6 unicast -{% elif afi == 'ipv6_multicast' %} - address-family ipv6 multicast -{% elif afi == 'ipv6_labeled_unicast' %} - address-family ipv6 labeled-unicast -{% elif afi == 'ipv6_vpn' %} - address-family ipv6 vpn -{% elif afi == 'ipv6_flowspec' %} - address-family ipv6 flowspec -{% elif afi == 'l2vpn_evpn' %} - address-family l2vpn evpn -{% endif %} -{% if afi_config.addpath_tx_all is defined %} - neighbor {{ neighbor }} addpath-tx-all-paths -{% endif %} -{% if afi_config.addpath_tx_per_as is defined %} - neighbor {{ neighbor }} addpath-tx-bestpath-per-AS -{% endif %} -{% if afi_config.allowas_in is defined and afi_config.allowas_in is not none %} - neighbor {{ neighbor }} allowas-in {{ afi_config.allowas_in.number if afi_config.allowas_in.number is defined }} -{% endif %} -{% if afi_config.as_override is defined %} - neighbor {{ neighbor }} as-override -{% endif %} -{% if afi_config.remove_private_as is defined %} - neighbor {{ neighbor }} remove-private-AS -{% endif %} -{% if afi_config.route_reflector_client is defined %} - neighbor {{ neighbor }} route-reflector-client -{% endif %} -{% if afi_config.weight is defined and afi_config.weight is not none %} - neighbor {{ neighbor }} weight {{ afi_config.weight }} -{% endif %} -{% if afi_config.attribute_unchanged is defined and afi_config.attribute_unchanged is not none %} - neighbor {{ neighbor }} attribute-unchanged {{ 'as-path ' if afi_config.attribute_unchanged.as_path is defined }}{{ 'med ' if afi_config.attribute_unchanged.med is defined }}{{ 'next-hop ' if afi_config.attribute_unchanged.next_hop is defined }} -{% endif %} -{% if afi_config.capability is defined and afi_config.capability.orf is defined and afi_config.capability.orf.prefix_list is defined and afi_config.capability.orf.prefix_list.send is defined %} - neighbor {{ neighbor }} capability orf prefix-list send -{% endif %} -{% if afi_config.capability is defined and afi_config.capability.orf is defined and afi_config.capability.orf.prefix_list is defined and afi_config.capability.orf.prefix_list.receive is defined %} - neighbor {{ neighbor }} capability orf prefix-list receive -{% endif %} -{% if afi_config.default_originate is defined %} - neighbor {{ neighbor }} default-originate {{ 'route-map ' ~ afi_config.default_originate.route_map if afi_config.default_originate.route_map is defined }} -{% endif %} -{% if afi_config.distribute_list is defined and afi_config.distribute_list is not none %} -{% if afi_config.distribute_list.export is defined and afi_config.distribute_list.export is not none %} - neighbor {{ neighbor }} distribute-list {{ afi_config.distribute_list.export }} out -{% endif %} -{% if afi_config.distribute_list.import is defined and afi_config.distribute_list.import is not none %} - neighbor {{ neighbor }} distribute-list {{ afi_config.distribute_list.import }} in -{% endif %} -{% endif %} -{% if afi_config.filter_list is defined and afi_config.filter_list is not none %} -{% if afi_config.filter_list.export is defined and afi_config.filter_list.export is not none %} - neighbor {{ neighbor }} filter-list {{ afi_config.filter_list.export }} out -{% endif %} -{% if afi_config.filter_list.import is defined and afi_config.filter_list.import is not none %} - neighbor {{ neighbor }} filter-list {{ afi_config.filter_list.import }} in -{% endif %} -{% endif %} -{% if afi_config.maximum_prefix is defined and afi_config.maximum_prefix is not none %} - neighbor {{ neighbor }} maximum-prefix {{ afi_config.maximum_prefix }} -{% endif %} -{% if afi_config.maximum_prefix_out is defined and afi_config.maximum_prefix_out is not none %} - neighbor {{ neighbor }} maximum-prefix-out {{ afi_config.maximum_prefix_out }} -{% endif %} -{% if afi_config.nexthop_self is defined %} - neighbor {{ neighbor }} next-hop-self {{ 'force' if afi_config.nexthop_self.force is defined }} -{% endif %} -{% if afi_config.route_server_client is defined %} - neighbor {{ neighbor }} route-server-client -{% endif %} -{% if afi_config.route_map is defined and afi_config.route_map is not none %} -{% if afi_config.route_map.export is defined and afi_config.route_map.export is not none %} - neighbor {{ neighbor }} route-map {{ afi_config.route_map.export }} out -{% endif %} -{% if afi_config.route_map.import is defined and afi_config.route_map.import is not none %} - neighbor {{ neighbor }} route-map {{ afi_config.route_map.import }} in -{% endif %} -{% endif %} -{% if afi_config.prefix_list is defined and afi_config.prefix_list is not none %} -{% if afi_config.prefix_list.export is defined and afi_config.prefix_list.export is not none %} - neighbor {{ neighbor }} prefix-list {{ afi_config.prefix_list.export }} out -{% endif %} -{% if afi_config.prefix_list.import is defined and afi_config.prefix_list.import is not none %} - neighbor {{ neighbor }} prefix-list {{ afi_config.prefix_list.import }} in -{% endif %} -{% endif %} -{% if afi_config.soft_reconfiguration is defined and afi_config.soft_reconfiguration.inbound is defined %} - neighbor {{ neighbor }} soft-reconfiguration inbound -{% endif %} -{% if afi_config.unsuppress_map is defined and afi_config.unsuppress_map is not none %} - neighbor {{ neighbor }} unsuppress-map {{ afi_config.unsuppress_map }} -{% endif %} -{% if afi_config.disable_send_community is defined and afi_config.disable_send_community.extended is defined %} - no neighbor {{ neighbor }} send-community extended -{% endif %} -{% if afi_config.disable_send_community is defined and afi_config.disable_send_community.standard is defined %} - no neighbor {{ neighbor }} send-community standard -{% endif %} - neighbor {{ neighbor }} activate - exit-address-family - ! -{% endfor %} -{% endif %} -{% endmacro %} -! -router bgp {{ local_as }} {{ 'vrf ' ~ vrf if vrf is defined and vrf is not none }} -{% if parameters is defined and parameters.ebgp_requires_policy is defined %} - bgp ebgp-requires-policy -{% else %} - no bgp ebgp-requires-policy -{% endif %} -{# Option must be set before any neighbor - see https://phabricator.vyos.net/T3463 #} - no bgp default ipv4-unicast -{# Workaround for T2100 until we have decided about a migration script #} - no bgp network import-check -{% if address_family is defined and address_family is not none %} -{% for afi, afi_config in address_family.items() %} - ! -{% if afi == 'ipv4_unicast' %} - address-family ipv4 unicast -{% elif afi == 'ipv4_multicast' %} - address-family ipv4 multicast -{% elif afi == 'ipv4_labeled_unicast' %} - address-family ipv4 labeled-unicast -{% elif afi == 'ipv4_vpn' %} - address-family ipv4 vpn -{% elif afi == 'ipv4_flowspec' %} - address-family ipv4 flowspec -{% elif afi == 'ipv6_unicast' %} - address-family ipv6 unicast -{% elif afi == 'ipv6_multicast' %} - address-family ipv6 multicast -{% elif afi == 'ipv6_labeled_unicast' %} - address-family ipv6 labeled-unicast -{% elif afi == 'ipv6_vpn' %} - address-family ipv6 vpn -{% elif afi == 'ipv6_flowspec' %} - address-family ipv6 flowspec -{% elif afi == 'l2vpn_evpn' %} - address-family l2vpn evpn -{% if afi_config.rd is defined and afi_config.rd is not none %} - rd {{ afi_config.rd }} -{% endif %} -{% endif %} -{% if afi_config.aggregate_address is defined and afi_config.aggregate_address is not none %} -{% for aggregate, aggregate_config in afi_config.aggregate_address.items() %} - aggregate-address {{ aggregate }}{{ ' as-set' if aggregate_config.as_set is defined }}{{ ' summary-only' if aggregate_config.summary_only is defined }} -{% if aggregate_config.route_map is defined and aggregate_config.route_map is not none %} - aggregate-address {{ aggregate }} route-map {{ aggregate_config.route_map }} -{% endif %} -{% endfor %} -{% endif %} -{% if afi_config.maximum_paths is defined and afi_config.maximum_paths.ebgp is defined and afi_config.maximum_paths.ebgp is not none %} - maximum-paths {{ afi_config.maximum_paths.ebgp }} -{% endif %} -{% if afi_config.maximum_paths is defined and afi_config.maximum_paths.ibgp is defined and afi_config.maximum_paths.ibgp is not none %} - maximum-paths ibgp {{ afi_config.maximum_paths.ibgp }} -{% endif %} -{% if afi_config.redistribute is defined and afi_config.redistribute is not none %} -{% for protocol in afi_config.redistribute %} -{% if protocol == 'table' %} - redistribute table {{ afi_config.redistribute[protocol].table }} -{% else %} -{% set redistribution_protocol = protocol %} -{% if protocol == 'ospfv3' %} -{% set redistribution_protocol = 'ospf6' %} -{% endif %} - redistribute {{ redistribution_protocol }}{% if afi_config.redistribute[protocol].metric is defined %} metric {{ afi_config.redistribute[protocol].metric }}{% endif %}{% if afi_config.redistribute[protocol].route_map is defined %} route-map {{ afi_config.redistribute[protocol].route_map }}{% endif %} -{####### we need this blank line!! #######} - -{% endif %} -{% endfor %} -{% endif %} -{% if afi_config.network is defined and afi_config.network is not none %} -{% for network in afi_config.network %} - network {{ network }}{% if afi_config.network[network].route_map is defined %} route-map {{ afi_config.network[network].route_map }}{% endif %}{% if afi_config.network[network].backdoor is defined %} backdoor{% endif %}{% if afi_config.network[network].rd is defined and afi_config.network[network].label is defined%} rd {{ afi_config.network[network].rd }} label {{ afi_config.network[network].label }}{% endif %} -{####### we need this blank line!! #######} - -{% endfor %} -{% endif %} -{% if afi_config.advertise is defined and afi_config.advertise is not none %} -{% for adv_afi, adv_afi_config in afi_config.advertise.items() %} -{% if adv_afi_config.unicast is defined and adv_afi_config.unicast is not none %} - advertise {{ adv_afi }} unicast {{ 'route-map ' ~ adv_afi_config.unicast.route_map if adv_afi_config.unicast.route_map is defined }} -{% endif %} -{% endfor %} -{% endif %} -{% if afi_config.distance is defined and afi_config.distance is not none %} -{% if afi_config.distance is defined and afi_config.distance.external is defined and afi_config.distance.internal is defined and afi_config.distance.local is defined %} - distance bgp {{ afi_config.distance.external }} {{ afi_config.distance.internal }} {{ afi_config.distance.local }} -{% endif %} -{% if afi_config.distance.prefix is defined and afi_config.distance.prefix is not none %} -{% for prefix in afi_config.distance.prefix %} - distance {{ afi_config.distance.prefix[prefix].distance }} {{ prefix }} -{% endfor %} -{% endif %} -{% endif %} -{% if afi_config.export is defined and afi_config.export.vpn is defined %} - export vpn -{% endif %} -{% if afi_config.import is defined and afi_config.import is not none %} -{% if afi_config.import.vpn is defined %} - import vpn -{% endif %} -{% if afi_config.import.vrf is defined and afi_config.import.vrf is not none %} -{% for vrf in afi_config.import.vrf %} - import vrf {{ vrf }} -{% endfor %} -{% endif %} -{% endif %} -{% if afi_config.label is defined and afi_config.label.vpn is defined and afi_config.label.vpn.export is defined and afi_config.label.vpn.export is not none %} - label vpn export {{ afi_config.label.vpn.export }} -{% endif %} -{% if afi_config.local_install is defined and afi_config.local_install is not none %} -{% for interface in afi_config.local_install.interface %} - local-install {{ interface }} -{% endfor %} -{% endif %} -{% if afi_config.advertise_all_vni is defined %} - advertise-all-vni -{% endif %} -{% if afi_config.advertise_default_gw is defined %} - advertise-default-gw -{% endif %} -{% if afi_config.advertise_pip is defined and afi_config.advertise_pip is not none %} - advertise-pip ip {{ afi_config.advertise_pip }} -{% endif %} -{% if afi_config.advertise_svi_ip is defined %} - advertise-svi-ip -{% endif %} -{% if afi_config.rt_auto_derive is defined %} - autort rfc8365-compatible -{% endif %} -{% if afi_config.flooding is defined and afi_config.flooding.disable is defined %} - flooding disable -{% endif %} -{% if afi_config.flooding is defined and afi_config.flooding.head_end_replication is defined %} - flooding head-end-replication -{% endif %} -{% if afi_config.rd is defined and afi_config.rd.vpn is defined and afi_config.rd.vpn.export is defined %} - rd vpn export {{ afi_config.rd.vpn.export }} -{% endif %} -{% if afi_config.route_target is defined and afi_config.route_target is not none %} -{% if afi_config.route_target.vpn is defined and afi_config.route_target.vpn is not none %} -{% if afi_config.route_target.vpn.both is defined and afi_config.route_target.vpn.both is not none %} - route-target vpn both {{ afi_config.route_target.vpn.both }} -{% else %} -{% if afi_config.route_target.vpn.export is defined and afi_config.route_target.vpn.export is not none %} - route-target vpn export {{ afi_config.route_target.vpn.export }} -{% endif %} -{% if afi_config.route_target.vpn.import is defined and afi_config.route_target.vpn.import is not none %} - route-target vpn import {{ afi_config.route_target.vpn.import }} -{% endif %} -{% endif %} -{% endif %} -{% if afi_config.route_target.both is defined and afi_config.route_target.both is not none %} - route-target both {{ afi_config.route_target.both }} -{% else %} -{% if afi_config.route_target.export is defined and afi_config.route_target.export is not none %} - route-target export {{ afi_config.route_target.export }} -{% endif %} -{% if afi_config.route_target.import is defined and afi_config.route_target.import is not none %} - route-target import {{ afi_config.route_target.import }} -{% endif %} -{% endif %} -{% endif %} -{% if afi_config.route_map is defined and afi_config.route_map.vpn is defined and afi_config.route_map.vpn is not none %} -{% if afi_config.route_map.vpn.export is defined and afi_config.route_map.vpn.export is not none %} - route-map vpn export {{ afi_config.route_map.vpn.export }} -{% endif %} -{% if afi_config.route_map.vpn.import is defined and afi_config.route_map.vpn.import is not none %} - route-map vpn import {{ afi_config.route_map.vpn.import }} -{% endif %} -{% endif %} -{% if afi_config.vni is defined and afi_config.vni is not none %} -{% for vni, vni_config in afi_config.vni.items() %} - vni {{ vni }} -{% if vni_config.advertise_default_gw is defined %} - advertise-default-gw -{% endif %} -{% if vni_config.advertise_svi_ip is defined %} - advertise-svi-ip -{% endif %} -{% if vni_config.rd is defined and vni_config.rd is not none %} - rd {{ vni_config.rd }} -{% endif %} -{% if vni_config.route_target is defined and vni_config.route_target is not none %} -{% if vni_config.route_target.both is defined and vni_config.route_target.both is not none %} - route-target both {{ vni_config.route_target.both }} -{% endif %} -{% if vni_config.route_target.export is defined and vni_config.route_target.export is not none %} - route-target export {{ vni_config.route_target.export }} -{% endif %} -{% if vni_config.route_target.import is defined and vni_config.route_target.import is not none %} - route-target import {{ vni_config.route_target.import }} -{% endif %} -{% endif %} - exit-vni -{% endfor %} -{% endif %} - exit-address-family -{% endfor %} -{% endif %} - ! -{% if peer_group is defined and peer_group is not none %} -{% for peer, config in peer_group.items() %} -{{ bgp_neighbor(peer, config, true) }} -{% endfor %} -{% endif %} - ! -{% if neighbor is defined and neighbor is not none %} -{% for peer, config in neighbor.items() %} -{{ bgp_neighbor(peer, config) }} -{% endfor %} -{% endif %} - ! -{% if listen is defined %} -{% if listen.limit is defined and listen.limit is not none %} - bgp listen limit {{ listen.limit }} -{% endif %} -{% for prefix, options in listen.range.items() %} -{% if options.peer_group is defined and options.peer_group is not none %} - bgp listen range {{ prefix }} peer-group {{ options.peer_group }} -{% endif %} -{% endfor %} -{% endif %} -{% if parameters is defined %} -{% if parameters.always_compare_med is defined %} - bgp always-compare-med -{% endif %} -{% if parameters.bestpath is defined and parameters.bestpath is not none %} -{% if parameters.bestpath.as_path is defined and parameters.bestpath.as_path is not none %} -{% for option in parameters.bestpath.as_path %} -{# replace is required for multipath-relax option #} - bgp bestpath as-path {{ option|replace('_', '-') }} -{% endfor %} -{% endif %} -{% if parameters.bestpath.bandwidth is defined and parameters.bestpath.bandwidth is not none %} - bgp bestpath bandwidth {{ parameters.bestpath.bandwidth }} -{% endif %} -{% if parameters.bestpath.compare_routerid is defined %} - bgp bestpath compare-routerid -{% endif %} -{% if parameters.bestpath.med is defined and parameters.bestpath.med is not none %} - bgp bestpath med {{ 'confed' if parameters.bestpath.med.confed is defined }} {{ 'missing-as-worst' if parameters.bestpath.med.missing_as_worst is defined }} -{% endif %} -{% endif %} -{% if parameters.cluster_id is defined and parameters.cluster_id is not none %} - bgp cluster-id {{ parameters.cluster_id }} -{% endif %} -{% if parameters.confederation is defined and parameters.confederation is not none %} -{% if parameters.confederation.identifier is defined and parameters.confederation.identifier is not none %} - bgp confederation identifier {{ parameters.confederation.identifier }} -{% endif %} -{% if parameters.confederation.peers is defined and parameters.confederation.peers is not none %} - bgp confederation peers {{ parameters.confederation.peers | join(' ') }} -{% endif %} -{% endif %} -{% if parameters.dampening is defined and parameters.dampening is defined and parameters.dampening.half_life is defined and parameters.dampening.half_life is not none %} -{# Doesn't work in current FRR configuration; vtysh (bgp dampening 16 751 2001 61) #} - bgp dampening {{ parameters.dampening.half_life }} {{ parameters.dampening.re_use if parameters.dampening.re_use is defined }} {{ parameters.dampening.start_suppress_time if parameters.dampening.start_suppress_time is defined }} {{ parameters.dampening.max_suppress_time if parameters.dampening.max_suppress_time is defined }} -{% endif %} -{% if parameters.default is defined and parameters.default is not none %} -{% if parameters.default.local_pref is defined and parameters.default.local_pref is not none %} - bgp default local-preference {{ parameters.default.local_pref }} -{% endif %} -{% endif %} -{% if parameters.deterministic_med is defined %} - bgp deterministic-med -{% endif %} -{% if parameters.distance is defined and parameters.distance is not none %} -{% if parameters.distance.global is defined and parameters.distance.global.external is defined and parameters.distance.global.internal is defined and parameters.distance.global.local is defined %} - distance bgp {{ parameters.distance.global.external }} {{ parameters.distance.global.internal }} {{ parameters.distance.global.local }} -{% endif %} -{% if parameters.distance.prefix is defined and parameters.distance.prefix is not none %} -{% for prefix in parameters.distance.prefix %} - distance {{ parameters.distance.prefix[prefix].distance }} {{ prefix }} -{% endfor %} -{% endif %} -{% endif %} -{% if parameters.graceful_restart is defined %} - bgp graceful-restart {{ 'stalepath-time ' ~ parameters.graceful_restart.stalepath_time if parameters.graceful_restart.stalepath_time is defined }} -{% endif %} -{% if parameters.graceful_shutdown is defined %} - bgp graceful-shutdown -{% endif %} -{% if parameters.log_neighbor_changes is defined %} - bgp log-neighbor-changes -{% endif %} -{% if parameters.network_import_check is defined %} - bgp network import-check -{% endif %} -{% if parameters.no_client_to_client_reflection is defined %} - no bgp client-to-client reflection -{% endif %} -{% if parameters.no_fast_external_failover is defined %} - no bgp fast-external-failover -{% endif %} -{% if parameters.router_id is defined and parameters.router_id is not none %} - bgp router-id {{ parameters.router_id }} -{% endif %} -{% endif %} -{% if timers is defined and timers.keepalive is defined and timers.holdtime is defined %} - timers bgp {{ timers.keepalive }} {{ timers.holdtime }} -{% endif %} - end -!
\ No newline at end of file diff --git a/data/templates/frr/igmp.frr.j2 b/data/templates/frr/igmp.frr.j2 new file mode 100644 index 000000000..ce1f8fdda --- /dev/null +++ b/data/templates/frr/igmp.frr.j2 @@ -0,0 +1,41 @@ +! +{% for iface in old_ifaces %} +interface {{ iface }} +{% for group in old_ifaces[iface].gr_join %} +{% if old_ifaces[iface].gr_join[group] %} +{% for source in old_ifaces[iface].gr_join[group] %} + no ip igmp join {{ group }} {{ source }} +{% endfor %} +{% else %} + no ip igmp join {{ group }} +{% endif %} +{% endfor %} + no ip igmp +! +{% endfor %} +{% for interface, interface_config in ifaces.items() %} +interface {{ interface }} +{% if interface_config.version %} + ip igmp version {{ interface_config.version }} +{% else %} +{# IGMP default version 3 #} + ip igmp +{% endif %} +{% if interface_config.query_interval %} + ip igmp query-interval {{ interface_config.query_interval }} +{% endif %} +{% if interface_config.query_max_resp_time %} + ip igmp query-max-response-time {{ interface_config.query_max_resp_time }} +{% endif %} +{% for group in interface_config.gr_join %} +{% if ifaces[iface].gr_join[group] %} +{% for source in ifaces[iface].gr_join[group] %} + ip igmp join {{ group }} {{ source }} +{% endfor %} +{% else %} + ip igmp join {{ group }} +{% endif %} +{% endfor %} +! +{% endfor %} +! diff --git a/data/templates/frr/igmp.frr.tmpl b/data/templates/frr/igmp.frr.tmpl deleted file mode 100644 index 49b5aeaa5..000000000 --- a/data/templates/frr/igmp.frr.tmpl +++ /dev/null @@ -1,41 +0,0 @@ -! -{% for iface in old_ifaces %} -interface {{ iface }} -{% for group in old_ifaces[iface].gr_join %} -{% if old_ifaces[iface].gr_join[group] %} -{% for source in old_ifaces[iface].gr_join[group] %} - no ip igmp join {{ group }} {{ source }} -{% endfor %} -{% else %} - no ip igmp join {{ group }} -{% endif %} -{% endfor %} - no ip igmp -! -{% endfor %} -{% for iface in ifaces %} -interface {{ iface }} -{% if ifaces[iface].version %} - ip igmp version {{ ifaces[iface].version }} -{% else %} -{# IGMP default version 3 #} - ip igmp -{% endif %} -{% if ifaces[iface].query_interval %} - ip igmp query-interval {{ ifaces[iface].query_interval }} -{% endif %} -{% if ifaces[iface].query_max_resp_time %} - ip igmp query-max-response-time {{ ifaces[iface].query_max_resp_time }} -{% endif %} -{% for group in ifaces[iface].gr_join %} -{% if ifaces[iface].gr_join[group] %} -{% for source in ifaces[iface].gr_join[group] %} - ip igmp join {{ group }} {{ source }} -{% endfor %} -{% else %} - ip igmp join {{ group }} -{% endif %} -{% endfor %} -! -{% endfor %} -! diff --git a/data/templates/frr/isisd.frr.j2 b/data/templates/frr/isisd.frr.j2 new file mode 100644 index 000000000..8e95348bc --- /dev/null +++ b/data/templates/frr/isisd.frr.j2 @@ -0,0 +1,197 @@ +! +{% if interface is vyos_defined %} +{% for iface, iface_config in interface.items() %} +interface {{ iface }} + ip router isis VyOS + ipv6 router isis VyOS +{% if iface_config.bfd is vyos_defined %} + isis bfd +{% if iface_config.bfd.profile is vyos_defined %} + isis bfd profile {{ iface_config.bfd.profile }} +{% endif %} +{% endif %} +{% if iface_config.network.point_to_point is vyos_defined %} + isis network point-to-point +{% endif %} +{% if iface_config.circuit_type is vyos_defined %} + isis circuit-type {{ iface_config.circuit_type }} +{% endif %} +{% if iface_config.hello_interval is vyos_defined %} + isis hello-interval {{ iface_config.hello_interval }} +{% endif %} +{% if iface_config.hello_multiplier is vyos_defined %} + isis hello-multiplier {{ iface_config.hello_multiplier }} +{% endif %} +{% if iface_config.hello_padding is vyos_defined %} + isis hello padding +{% endif %} +{% if iface_config.metric is vyos_defined %} + isis metric {{ iface_config.metric }} +{% endif %} +{% if iface_config.passive is vyos_defined %} + isis passive +{% endif %} +{% if iface_config.password.md5 is vyos_defined %} + isis password md5 {{ iface_config.password.md5 }} +{% elif iface_config.password.plaintext_password is vyos_defined %} + isis password clear {{ iface_config.password.plaintext_password }} +{% endif %} +{% if iface_config.priority is vyos_defined %} + isis priority {{ iface_config.priority }} +{% endif %} +{% if iface_config.psnp_interval is vyos_defined %} + isis psnp-interval {{ iface_config.psnp_interval }} +{% endif %} +{% if iface_config.no_three_way_handshake is vyos_defined %} + no isis three-way-handshake +{% endif %} +exit +! +{% endfor %} +{% endif %} +! +router isis VyOS {{ 'vrf ' + vrf if vrf is vyos_defined }} + net {{ net }} +{% if dynamic_hostname is vyos_defined %} + hostname dynamic +{% endif %} +{% if purge_originator is vyos_defined %} + purge-originator +{% endif %} +{% if set_attached_bit is vyos_defined %} + set-attached-bit +{% endif %} +{% if set_overload_bit is vyos_defined %} + set-overload-bit +{% endif %} +{% if domain_password.md5 is vyos_defined %} + domain-password md5 {{ domain_password.plaintext_password }} +{% elif domain_password.plaintext_password is vyos_defined %} + domain-password clear {{ domain_password.plaintext_password }} +{% endif %} +{% if log_adjacency_changes is vyos_defined %} + log-adjacency-changes +{% endif %} +{% if lsp_gen_interval is vyos_defined %} + lsp-gen-interval {{ lsp_gen_interval }} +{% endif %} +{% if lsp_mtu is vyos_defined %} + lsp-mtu {{ lsp_mtu }} +{% endif %} +{% if lsp_refresh_interval is vyos_defined %} + lsp-refresh-interval {{ lsp_refresh_interval }} +{% endif %} +{% if max_lsp_lifetime is vyos_defined %} + max-lsp-lifetime {{ max_lsp_lifetime }} +{% endif %} +{% if spf_interval is vyos_defined %} + spf-interval {{ spf_interval }} +{% endif %} +{% if traffic_engineering.enable is vyos_defined %} + mpls-te on +{% endif %} +{% if traffic_engineering.address is vyos_defined %} + mpls-te router-address {{ traffic_engineering.address }} +{% endif %} +{% if traffic_engineering.inter_as is vyos_defined %} +{% set level = '' %} +{% if traffic_engineering.inter_as.level_1 is vyos_defined %} +{% set level = ' level-1' %} +{% endif %} +{% if traffic_engineering.inter_as.level_1_2 is vyos_defined %} +{% set level = ' level-1-2' %} +{% endif %} +{% if traffic_engineering.inter_as.level_2 is vyos_defined %} +{% set level = ' level-2-only' %} +{% endif %} + mpls-te inter-as{{ level }} +{% endif %} +{% if segment_routing is vyos_defined %} +{% if segment_routing.enable is vyos_defined %} + segment-routing on +{% endif %} +{% if segment_routing.maximum_label_depth is vyos_defined %} + segment-routing node-msd {{ segment_routing.maximum_label_depth }} +{% endif %} +{% if segment_routing.global_block is vyos_defined %} +{% if segment_routing.local_block is vyos_defined %} + segment-routing global-block {{ segment_routing.global_block.low_label_value }} {{ segment_routing.global_block.high_label_value }} local-block {{ segment_routing.local_block.low_label_value }} {{ segment_routing.local_block.high_label_value }} +{% else %} + segment-routing global-block {{ segment_routing.global_block.low_label_value }} {{ segment_routing.global_block.high_label_value }} +{% endif %} +{% endif %} +{% if segment_routing.prefix is vyos_defined %} +{% for prefix, prefix_config in segment_routing.prefix.items() %} +{% if prefix_config.absolute is vyos_defined %} +{% if prefix_config.absolute.value is vyos_defined %} + segment-routing prefix {{ prefixes }} absolute {{ prefix_config.absolute.value }} +{% if prefix_config.absolute.explicit_null is vyos_defined %} + segment-routing prefix {{ prefixes }} absolute {{ prefix_config.absolute.value }} explicit-null +{% endif %} +{% if prefix_config.absolute.no_php_flag is vyos_defined %} + segment-routing prefix {{ prefixes }} absolute {{ prefix_config.absolute.value }} no-php-flag +{% endif %} +{% endif %} +{% if prefix_config.index is vyos_defined %} +{% if prefix_config.index.value is vyos_defined %} + segment-routing prefix {{ prefixes }} index {{ prefix_config.index.value }} +{% if prefix_config.index.explicit_null is vyos_defined %} + segment-routing prefix {{ prefixes }} index {{ prefix_config.index.value }} explicit-null +{% endif %} +{% if prefix_config.index.no_php_flag is vyos_defined %} + segment-routing prefix {{ prefixes }} index {{ prefix_config.index.value }} no-php-flag +{% endif %} +{% endif %} +{% endif %} +{% endif %} +{% endfor %} +{% endif %} +{% endif %} +{% if spf_delay_ietf.init_delay is vyos_defined %} + spf-delay-ietf init-delay {{ spf_delay_ietf.init_delay }} short-delay {{ spf_delay_ietf.short_delay }} long-delay {{ spf_delay_ietf.long_delay }} holddown {{ spf_delay_ietf.holddown }} time-to-learn {{ spf_delay_ietf.time_to_learn }} +{% endif %} +{% if area_password.md5 is vyos_defined %} + area-password md5 {{ area_password.md5 }} +{% elif area_password.plaintext_password is vyos_defined %} + area-password clear {{ area_password.plaintext_password }} +{% endif %} +{% if default_information.originate is vyos_defined %} +{% for afi, afi_config in default_information.originate.items() %} +{% for level, level_config in afi_config.items() %} + default-information originate {{ afi }} {{ level | replace('_', '-') }} {{ 'always' if level_config.always is vyos_defined }} {{ 'route-map ' ~ level_config.route_map if level_config.route_map is vyos_defined }} {{ 'metric ' ~ level_config.metric if level_config.metric is vyos_defined }} +{% endfor %} +{% endfor %} +{% endif %} +{% if redistribute.ipv4 is vyos_defined %} +{% for protocol, protocol_options in redistribute.ipv4.items() %} +{% for level, level_config in protocol_options.items() %} +{% if level_config.metric is vyos_defined %} + redistribute ipv4 {{ protocol }} {{ level | replace('_', '-') }} metric {{ level_config.metric }} +{% elif level_config.route_map is vyos_defined %} + redistribute ipv4 {{ protocol }} {{ level | replace('_', '-') }} route-map {{ level_config.route_map }} +{% else %} + redistribute ipv4 {{ protocol }} {{ level | replace('_', '-') }} +{% endif %} +{% endfor %} +{% endfor %} +{% endif %} +{% if redistribute.ipv6 is vyos_defined %} +{% for protocol, protocol_options in redistribute.ipv6.items() %} +{% for level, level_config in protocol_options.items() %} +{% if level_config.metric is vyos_defined %} + redistribute ipv6 {{ protocol }} {{ level | replace('_', '-') }} metric {{ level_config.metric }} +{% elif level_config.route_map is vyos_defined %} + redistribute ipv6 {{ protocol }} {{ level | replace('_', '-') }} route-map {{ level_config.route_map }} +{% else %} + redistribute ipv6 {{ protocol }} {{ level | replace('_', '-') }} +{% endif %} +{% endfor %} +{% endfor %} +{% endif %} +{% if level is vyos_defined('level-2') %} + is-type level-2-only +{% elif level is vyos_defined %} + is-type {{ level }} +{% endif %} +exit +!
\ No newline at end of file diff --git a/data/templates/frr/isisd.frr.tmpl b/data/templates/frr/isisd.frr.tmpl deleted file mode 100644 index 51ac40060..000000000 --- a/data/templates/frr/isisd.frr.tmpl +++ /dev/null @@ -1,198 +0,0 @@ -! -router isis VyOS {{ 'vrf ' + vrf if vrf is defined and vrf is not none }} - net {{ net }} -{% if dynamic_hostname is defined %} - hostname dynamic -{% endif %} -{% if purge_originator is defined %} - purge-originator -{% endif %} -{% if set_attached_bit is defined %} - set-attached-bit -{% endif %} -{% if set_overload_bit is defined %} - set-overload-bit -{% endif %} -{% if domain_password is defined and domain_password is not none %} -{% if domain_password.md5 is defined and domain_password.md5 is not none %} - 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 }} -{% endif %} -{% if lsp_mtu is defined and lsp_mtu is not none %} - lsp-mtu {{ lsp_mtu }} -{% endif %} -{% if lsp_refresh_interval is defined and lsp_refresh_interval is not none %} - lsp-refresh-interval {{ lsp_refresh_interval }} -{% endif %} -{% if max_lsp_lifetime is defined and max_lsp_lifetime is not none %} - max-lsp-lifetime {{ max_lsp_lifetime }} -{% endif %} -{% if spf_interval is defined and spf_interval is not none %} - spf-interval {{ spf_interval }} -{% endif %} -{% if traffic_engineering is defined and traffic_engineering is not none %} -{% if traffic_engineering.enable is defined %} - mpls-te on -{% endif %} -{% if traffic_engineering.address is defined %} - mpls-te router-address {{ traffic_engineering.address }} -{% endif %} -{% if traffic_engineering.inter_as is defined %} -{% if traffic_engineering.inter_as.level_1 is defined %} - mpls-te inter-as level-1 -{% endif %} -{% if traffic_engineering.inter_as.level_1_2 is defined %} - mpls-te inter-as level-1-2 -{% endif %} -{% if traffic_engineering.inter_as.level_2 is defined %} - mpls-te inter-as level-2-only -{% endif %} -{% else %} - mpls-te inter-as -{% endif %} -{% endif %} -{% if segment_routing is defined %} -{% if segment_routing.enable is defined %} - segment-routing on -{% endif %} -{% if segment_routing.maximum_label_depth is defined %} - segment-routing node-msd {{ segment_routing.maximum_label_depth }} -{% endif %} -{% if segment_routing.global_block is defined %} - segment-routing global-block {{ segment_routing.global_block.low_label_value }} {{ segment_routing.global_block.high_label_value }} -{% endif %} -{% if segment_routing.local_block is defined %} - segment-routing local-block {{ segment_routing.global_block.low_label_value }} {{ segment_routing.local_block.high_label_value }} -{% endif %} -{% if segment_routing.prefix is defined %} -{% for prefixes in segment_routing.prefix %} -{% if segment_routing.prefix[prefixes].absolute is defined %} -{% if segment_routing.prefix[prefixes].absolute.value is defined %} - segment-routing prefix {{ prefixes }} absolute {{ segment_routing.prefix[prefixes].absolute.value }} -{% if segment_routing.prefix[prefixes].absolute.explicit_null is defined %} - segment-routing prefix {{ prefixes }} absolute {{ segment_routing.prefix[prefixes].absolute.value }} explicit-null -{% endif %} -{% if segment_routing.prefix[prefixes].absolute.no_php_flag is defined %} - segment-routing prefix {{ prefixes }} absolute {{ segment_routing.prefix[prefixes].absolute.value }} no-php-flag -{% endif %} -{% endif %} -{% if segment_routing.prefix[prefixes].index is defined %} -{% if segment_routing.prefix[prefixes].index.value is defined %} - segment-routing prefix {{ prefixes }} index {{ segment_routing.prefix[prefixes].index.value }} -{% if segment_routing.prefix[prefixes].index.explicit_null is defined %} - segment-routing prefix {{ prefixes }} index {{ segment_routing.prefix[prefixes].index.value }} explicit-null -{% endif %} -{% if segment_routing.prefix[prefixes].index.no_php_flag is defined %} - segment-routing prefix {{ prefixes }} index {{ segment_routing.prefix[prefixes].index.value }} no-php-flag -{% endif %} -{% endif %} -{% endif %} -{% endif %} -{% endfor %} -{% endif %} -{% endif %} -{% if spf_delay_ietf is defined and spf_delay_ietf.init_delay is defined and spf_delay_ietf.init_delay is not none %} - spf-delay-ietf init-delay {{ spf_delay_ietf.init_delay }} short-delay {{ spf_delay_ietf.short_delay }} long-delay {{ spf_delay_ietf.long_delay }} holddown {{ spf_delay_ietf.holddown }} time-to-learn {{ spf_delay_ietf.time_to_learn }} -{% endif %} -{% if area_password is defined and area_password is not none %} -{% if area_password.md5 is defined and area_password.md5 is not none %} - area-password md5 {{ area_password.md5 }} -{% 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 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 %} -{% 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 %} - redistribute ipv4 {{ protocol }} {{ level | replace('_', '-') }} route-map {{ level_config.route_map }} -{% else %} - redistribute ipv4 {{ protocol }} {{ level | replace('_', '-') }} -{% endif %} -{% 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-2' %} - is-type level-2-only -{% else %} - is-type {{ level }} -{% endif %} -{% endif %} -! -{% if interface is defined and interface is not none %} -{% for iface, iface_config in interface.items() %} -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 %} -{% if iface_config.network is defined and iface_config.network.point_to_point is defined %} - isis network point-to-point -{% endif %} -{% if iface_config.circuit_type is defined %} - isis circuit-type {{ iface_config.circuit_type }} -{% endif %} -{% if iface_config.hello_interval is defined and iface_config.hello_interval is not none %} - isis hello-interval {{ iface_config.hello_interval }} -{% endif %} -{% if iface_config.hello_multiplier is defined and iface_config.hello_multiplier is not none %} - isis hello-multiplier {{ iface_config.hello_multiplier }} -{% endif %} -{% if iface_config.hello_padding is defined %} - isis hello padding -{% endif %} -{% if iface_config.metric is defined and iface_config.metric is not none %} - isis metric {{ iface_config.metric }} -{% endif %} -{% if iface_config.passive is defined %} - isis passive -{% endif %} -{% if iface_config.password is defined and iface_config.password.plaintext_password is defined and iface_config.password.plaintext_password is not none %} - isis password clear {{ iface_config.password.plaintext_password }} -{% endif %} -{% if iface_config.priority is defined and iface_config.priority is not none %} - isis priority {{ iface_config.priority }} -{% endif %} -{% if iface_config.psnp_interval is defined and iface_config.psnp_interval is not none %} - isis psnp-interval {{ iface_config.psnp_interval }} -{% endif %} -{% if iface_config.no_three_way_handshake is defined %} - no isis three-way-handshake -{% endif %} -{% endfor %} -{% endif %} -!
\ No newline at end of file diff --git a/data/templates/frr/ldpd.frr.j2 b/data/templates/frr/ldpd.frr.j2 new file mode 100644 index 000000000..11aff331a --- /dev/null +++ b/data/templates/frr/ldpd.frr.j2 @@ -0,0 +1,149 @@ +! +{% if ldp is vyos_defined %} +mpls ldp +{% if ldp.router_id is vyos_defined %} + router-id {{ ldp.router_id }} +{% endif %} +{% if ldp.parameters.cisco_interop_tlv is vyos_defined %} + dual-stack cisco-interop +{% endif %} +{% if ldp.parameters.transport_prefer_ipv4 is vyos_defined %} + dual-stack transport-connection prefer ipv4 +{% endif %} +{% if ldp.parameters.ordered_control is vyos_defined %} + ordered-control +{% endif %} +{% if ldp.neighbor is vyos_defined %} +{% for neighbor, neighbor_config in ldp.neighbor %} +{% if neighbor_config.password is vyos_defined %} + neighbor {{ neighbors }} password {{ neighbor_config.password }} +{% endif %} +{% if neighbor_config.ttl_security is vyos_defined %} +{% if neighbor_config.ttl_security.disable is vyos_defined %} + neighbor {{ neighbors }} ttl-security disable +{% else %} + neighbor {{ neighbors }} ttl-security hops {{ neighbor_config.ttl_security }} +{% endif %} +{% endif %} +{% if neighbor_config.session_holdtime is vyos_defined %} + neighbor {{ neighbors }} session holdtime {{ neighbor_config.session_holdtime }} +{% endif %} +{% endfor %} +{% endif %} + ! +{% if ldp.discovery.transport_ipv4_address is vyos_defined %} + address-family ipv4 +{% if ldp.allocation.ipv4.access_list is vyos_defined %} + label local allocate for {{ ldp.allocation.ipv4.access_list }} +{% else %} + label local allocate host-routes +{% endif %} +{% if ldp.discovery.transport_ipv4_address is vyos_defined %} + discovery transport-address {{ ldp.discovery.transport_ipv4_address }} +{% endif %} +{% if ldp.discovery.hello_ipv4_holdtime is vyos_defined %} + discovery hello holdtime {{ ldp.discovery.hello_ipv4_holdtime }} +{% endif %} +{% if ldp.discovery.hello_ipv4_interval is vyos_defined %} + discovery hello interval {{ ldp.discovery.hello_ipv4_interval }} +{% endif %} +{% if ldp.discovery.session_ipv4_holdtime is vyos_defined %} + session holdtime {{ ldp.discovery.session_ipv4_holdtime }} +{% endif %} +{% if ldp.import.ipv4.import_filter.filter_access_list is vyos_defined %} +{% if ldp.import.ipv4.import_filter.neighbor_access_list is vyos_defined %} + label remote accept for {{ ldp.import.ipv4.import_filter.filter_access_list }} from {{ ldp.import.ipv4.import_filter.neighbor_access_list }} +{% else %} + label remote accept for {{ ldp.import.ipv4.import_filter.filter_access_list }} +{% endif %} +{% endif %} +{% if ldp.export.ipv4.explicit_null is vyos_defined %} + label local advertise explicit-null +{% endif %} +{% if ldp.export.ipv4.export_filter.filter_access_list is vyos_defined %} +{% if ldp.export.ipv4.export_filter.neighbor_access_list is vyos_defined %} + label local advertise for {{ ldp.export.ipv4.export_filter.filter_access_list }} to {{ ldp.export.ipv4.export_filter.neighbor_access_list }} +{% else %} + label local advertise for {{ ldp.export.ipv4.export_filter.filter_access_list }} +{% endif %} +{% endif %} +{% if ldp.targeted_neighbor is vyos_defined %} +{% if ldp.targeted_neighbor.ipv4.enable is vyos_defined %} + discovery targeted-hello accept +{% endif %} +{% if ldp.targeted_neighbor.ipv4.hello_holdtime is vyos_defined %} + discovery targeted-hello holdtime {{ ldp.targeted_neighbor.ipv4.hello_holdtime }} +{% endif %} +{% if ldp.targeted_neighbor.ipv4.hello_interval is vyos_defined %} + discovery targeted-hello interval {{ ldp.targeted_neighbor.ipv4.hello_interval }} +{% endif %} +{% for addresses in ldp.targeted_neighbor.ipv4.address %} + neighbor {{ addresses }} targeted +{% endfor %} +{% endif %} +{% if ldp.interface is vyos_defined %} +{% for interface in ldp.interface %} + interface {{ interface }} + exit +{% endfor %} +{% endif %} + exit-address-family +{% else %} + no address-family ipv4 +{% endif %} + ! +{% if ldp.discovery.transport_ipv6_address is vyos_defined %} + address-family ipv6 +{% if ldp.allocation.ipv6.access_list6 is vyos_defined %} + label local allocate for {{ ldp.allocation.ipv6.access_list6 }} +{% else %} + label local allocate host-routes +{% endif %} +{% if ldp.discovery.transport_ipv6_address is vyos_defined %} + discovery transport-address {{ ldp.discovery.transport_ipv6_address }} +{% endif %} +{% if ldp.discovery.hello_ipv6_holdtime is vyos_defined %} + discovery hello holdtime {{ ldp.discovery.hello_ipv6_holdtime }} +{% endif %} +{% if ldp.discovery.hello_ipv6_interval is vyos_defined %} + discovery hello interval {{ ldp.discovery.hello_ipv6_interval }} +{% endif %} +{% if ldp.discovery.session_ipv6_holdtime is vyos_defined %} + session holdtime {{ ldp.discovery.session_ipv6_holdtime }} +{% endif %} +{% if ldp.import.ipv6.import_filter.filter_access_list6 is vyos_defined %} + label remote accept for {{ ldp.import.ipv6.import_filter.filter_access_list6 }} {{ 'from ' ~ ldp.import.ipv6.import_filter.neighbor_access_list6 if ldp.import.ipv6.import_filter.neighbor_access_list6 is vyos_defined }} +{% endif %} +{% if ldp.export.ipv6.explicit_null is vyos_defined %} + label local advertise explicit-null +{% endif %} +{% if ldp.export.ipv6.export_filter.filter_access_list6 is vyos_defined %} + label local advertise for {{ ldp.export.ipv6.export_filter.filter_access_list6 }} {{ 'to ' ~ ldp.export.ipv6.export_filter.neighbor_access_list6 if ldp.export.ipv6.export_filter.neighbor_access_list6 is vyos_defined }} +{% endif %} +{% if ldp.targeted_neighbor is vyos_defined %} +{% if ldp.targeted_neighbor.ipv6.enable is vyos_defined %} + discovery targeted-hello accept +{% endif %} +{% if ldp.targeted_neighbor.ipv6.hello_holdtime is vyos_defined %} + discovery targeted-hello holdtime {{ ldp.targeted_neighbor.ipv6.hello_holdtime }} +{% endif %} +{% if ldp.targeted_neighbor.ipv6.hello_interval is vyos_defined %} + discovery targeted-hello interval {{ ldp.targeted_neighbor.ipv6.hello_interval }} +{% endif %} +{% for addresses in ldp.targeted_neighbor.ipv6.address %} + neighbor {{ addresses }} targeted +{% endfor %} +{% endif %} +{% if ldp.interface is vyos_defined %} +{% for interface in ldp.interface %} + interface {{ interface }} +{% endfor %} +{% endif %} + exit-address-family +{% else %} + no address-family ipv6 +{% endif %} + ! +exit +{% endif %} +! diff --git a/data/templates/frr/ldpd.frr.tmpl b/data/templates/frr/ldpd.frr.tmpl deleted file mode 100644 index 0a5411552..000000000 --- a/data/templates/frr/ldpd.frr.tmpl +++ /dev/null @@ -1,187 +0,0 @@ -! -{% if ldp is defined %} -mpls ldp -{% if ldp.router_id is defined %} -router-id {{ ldp.router_id }} -{% endif %} -{% if ldp.parameters is defined %} -{% if ldp.parameters.cisco_interop_tlv is defined %} -dual-stack cisco-interop -{% endif %} -{% if ldp.parameters.transport_prefer_ipv4 is defined%} -dual-stack transport-connection prefer ipv4 -{% endif %} -{% if ldp.parameters.ordered_control is defined%} -ordered-control -{% endif %} -{% endif %} -{% if ldp.neighbor is defined %} -{% for neighbors in ldp.neighbor %} -{% if ldp.neighbor[neighbors].password is defined %} -neighbor {{neighbors}} password {{ldp.neighbor[neighbors].password}} -{% endif %} -{% if ldp.neighbor[neighbors].ttl_security is defined %} -{% if 'disable' in ldp.neighbor[neighbors].ttl_security %} -neighbor {{neighbors}} ttl-security disable -{% else %} -neighbor {{neighbors}} ttl-security hops {{ldp.neighbor[neighbors].ttl_security}} -{% endif %} -{% endif %} -{% if ldp.neighbor[neighbors].session_holdtime is defined %} -neighbor {{neighbors}} session holdtime {{ldp.neighbor[neighbors].session_holdtime}} -{% endif %} -{% endfor %} -{% endif %} -! -{% if ldp.discovery is defined %} -{% if ldp.discovery.transport_ipv4_address is defined %} -address-family ipv4 -{% if ldp.allocation is defined %} -{% if ldp.allocation.ipv4 is defined %} -{% if ldp.allocation.ipv4.access_list is defined %} -label local allocate for {{ ldp.allocation.ipv4.access_list }} -{% endif %} -{% endif %} -{% else %} -label local allocate host-routes -{% endif %} -{% if ldp.discovery.transport_ipv4_address is defined %} -discovery transport-address {{ ldp.discovery.transport_ipv4_address }} -{% endif %} -{% if ldp.discovery.hello_ipv4_holdtime is defined %} -discovery hello holdtime {{ ldp.discovery.hello_ipv4_holdtime }} -{% endif %} -{% if ldp.discovery.hello_ipv4_interval is defined %} -discovery hello interval {{ ldp.discovery.hello_ipv4_interval }} -{% endif %} -{% if ldp.discovery.session_ipv4_holdtime is defined %} -session holdtime {{ ldp.discovery.session_ipv4_holdtime }} -{% endif %} -{% if ldp.import is defined %} -{% if ldp.import.ipv4 is defined %} -{% if ldp.import.ipv4.import_filter is defined %} -{% if ldp.import.ipv4.import_filter.filter_access_list is defined %} -{% if ldp.import.ipv4.import_filter.neighbor_access_list is defined %} -label remote accept for {{ ldp.import.ipv4.import_filter.filter_access_list }} from {{ ldp.import.ipv4.import_filter.neighbor_access_list }} -{% else %} -label remote accept for {{ ldp.import.ipv4.import_filter.filter_access_list }} -{% endif %} -{% endif %} -{% endif %} -{% endif %} -{% endif %} -{% if ldp.export is defined %} -{% if ldp.export.ipv4 is defined %} -{% if ldp.export.ipv4.explicit_null is defined %} -label local advertise explicit-null -{% endif %} -{% if ldp.export.ipv4.export_filter is defined %} -{% if ldp.export.ipv4.export_filter.filter_access_list is defined %} -{% if ldp.export.ipv4.export_filter.neighbor_access_list is defined %} -label local advertise for {{ ldp.export.ipv4.export_filter.filter_access_list }} to {{ ldp.export.ipv4.export_filter.neighbor_access_list }} -{% else %} -label local advertise for {{ ldp.export.ipv4.export_filter.filter_access_list }} -{% endif %} -{% endif %} -{% endif %} -{% endif %} -{% endif %} -{% if ldp.targeted_neighbor is defined %} -{% if ldp.targeted_neighbor.ipv4.enable is defined %} -discovery targeted-hello accept -{% endif %} -{% if ldp.targeted_neighbor.ipv4.hello_holdtime is defined %} -discovery targeted-hello holdtime {{ ldp.targeted_neighbor.ipv4.hello_holdtime }} -{% endif %} -{% if ldp.targeted_neighbor.ipv4.hello_interval is defined %} -discovery targeted-hello interval {{ ldp.targeted_neighbor.ipv4.hello_interval }} -{% endif %} -{% for addresses in ldp.targeted_neighbor.ipv4.address %} -neighbor {{addresses}} targeted -{% endfor %} -{% endif %} -{% for interfaces in ldp.interface %} -interface {{interfaces}} -{% endfor %} -exit-address-family -{% else %} -no address-family ipv4 -{% endif %} -{% endif %} -! -{% if ldp.discovery is defined %} -{% if ldp.discovery.transport_ipv6_address is defined %} -address-family ipv6 -{% if ldp.allocation is defined %} -{% if ldp.allocation.ipv6 is defined %} -{% if ldp.allocation.ipv6.access_list6 is defined %} -label local allocate for {{ ldp.allocation.ipv6.access_list6 }} -{% endif %} -{% endif %} -{% else %} -label local allocate host-routes -{% endif %} -{% if ldp.discovery.transport_ipv6_address is defined %} -discovery transport-address {{ ldp.discovery.transport_ipv6_address }} -{% endif %} -{% if ldp.discovery.hello_ipv6_holdtime is defined %} -discovery hello holdtime {{ ldp.discovery.hello_ipv6_holdtime }} -{% endif %} -{% if ldp.discovery.hello_ipv6_interval is defined %} -discovery hello interval {{ ldp.discovery.hello_ipv6_interval }} -{% endif %} -{% if ldp.discovery.session_ipv6_holdtime is defined %} -session holdtime {{ ldp.discovery.session_ipv6_holdtime }} -{% endif %} -{% if ldp.import is defined %} -{% if ldp.import.ipv6 is defined %} -{% if ldp.import.ipv6.import_filter is defined %} -{% if ldp.import.ipv6.import_filter.filter_access_list6 is defined %} -{% if ldp.import.ipv6.import_filter.neighbor_access_list6 is defined %} -label remote accept for {{ ldp.import.ipv6.import_filter.filter_access_list6 }} from {{ ldp.import.ipv6.import_filter.neighbor_access_list6 }} -{% else %} -label remote accept for {{ ldp.import.ipv6.import_filter.filter_access_list6 }} -{% endif %} -{% endif %} -{% endif %} -{% endif %} -{% endif %} -{% if ldp.export is defined %} -{% if ldp.export.ipv6 is defined %} -{% if ldp.export.ipv6.explicit_null is defined %} -label local advertise explicit-null -{% endif %} -{% if ldp.export.ipv6.export_filter is defined %} -{% if ldp.export.ipv6.export_filter.filter_access_list6 is defined %} -{% if ldp.export.ipv6.export_filter.neighbor_access_list6 is defined %} -label local advertise for {{ ldp.export.ipv6.export_filter.filter_access_list6 }} to {{ ldp.export.ipv6.export_filter.neighbor_access_list6 }} -{% else %} -label local advertise for {{ ldp.export.ipv6.export_filter.filter_access_list6 }} -{% endif %} -{% endif %} -{% endif %} -{% endif %} -{% endif %} -{% if ldp.targeted_neighbor is defined %} -{% if ldp.targeted_neighbor.ipv6.enable is defined %} -discovery targeted-hello accept -{% endif %} -{% if ldp.targeted_neighbor.ipv6.hello_holdtime is defined %} -discovery targeted-hello holdtime {{ ldp.targeted_neighbor.ipv6.hello_holdtime }} -{% endif %} -{% if ldp.targeted_neighbor.ipv6.hello_interval is defined %} -discovery targeted-hello interval {{ ldp.targeted_neighbor.ipv6.hello_interval }} -{% endif %} -{% for addresses in ldp.targeted_neighbor.ipv6.address %} -neighbor {{addresses}} targeted -{% endfor %} -{% endif %} -{% for interfaces in ldp.interface %} -interface {{interfaces}} -{% endfor %} -exit-address-family -{% else %} -no address-family ipv6 -{% endif %} -{% endif %} -{% endif %} diff --git a/data/templates/frr/ospf6d.frr.j2 b/data/templates/frr/ospf6d.frr.j2 new file mode 100644 index 000000000..84394ed1a --- /dev/null +++ b/data/templates/frr/ospf6d.frr.j2 @@ -0,0 +1,95 @@ +! +{% if interface is vyos_defined %} +{% for iface, iface_config in interface.items() %} +interface {{ iface }} +{% if iface_config.area is vyos_defined %} + ipv6 ospf6 area {{ iface_config.area }} +{% endif %} +{% if iface_config.cost is vyos_defined %} + ipv6 ospf6 cost {{ iface_config.cost }} +{% endif %} +{% if iface_config.priority is vyos_defined %} + ipv6 ospf6 priority {{ iface_config.priority }} +{% endif %} +{% if iface_config.hello_interval is vyos_defined %} + ipv6 ospf6 hello-interval {{ iface_config.hello_interval }} +{% endif %} +{% if iface_config.retransmit_interval is vyos_defined %} + ipv6 ospf6 retransmit-interval {{ iface_config.retransmit_interval }} +{% endif %} +{% if iface_config.transmit_delay is vyos_defined %} + ipv6 ospf6 transmit-delay {{ iface_config.transmit_delay }} +{% endif %} +{% if iface_config.dead_interval is vyos_defined %} + ipv6 ospf6 dead-interval {{ iface_config.dead_interval }} +{% endif %} +{% if iface_config.bfd is vyos_defined %} + ipv6 ospf6 bfd +{% endif %} +{% if iface_config.bfd.profile is vyos_defined %} + ipv6 ospf6 bfd profile {{ iface_config.bfd.profile }} +{% endif %} +{% if iface_config.mtu_ignore is vyos_defined %} + ipv6 ospf6 mtu-ignore +{% endif %} +{% if iface_config.ifmtu is vyos_defined %} + ipv6 ospf6 ifmtu {{ iface_config.ifmtu }} +{% endif %} +{% if iface_config.network is vyos_defined %} + ipv6 ospf6 network {{ iface_config.network }} +{% endif %} +{% if iface_config.instance_id is vyos_defined %} + ipv6 ospf6 instance-id {{ iface_config.instance_id }} +{% endif %} +{% if iface_config.passive is vyos_defined %} + ipv6 ospf6 passive +{% endif %} +exit +! +{% endfor %} +{% endif %} +! +router ospf6 {{ 'vrf ' ~ vrf if vrf is vyos_defined }} +{% if area is vyos_defined %} +{% for area_id, area_config in area.items() %} +{% if area_config.area_type is vyos_defined %} +{% for type, type_config in area_config.area_type.items() %} + area {{ area_id }} {{ type }} {{ 'default-information-originate' if type_config.default_information_originate is vyos_defined }} {{ 'no-summary' if type_config.no_summary is vyos_defined }} +{% endfor %} +{% endif %} +{% if area_config.range is vyos_defined %} +{% for prefix, prefix_config in area_config.range.items() %} + area {{ area_id }} range {{ prefix }} {{ 'advertise' if prefix_config.advertise is vyos_defined }} {{ 'not-advertise' if prefix_config.not_advertise is vyos_defined }} +{% endfor %} +{% endif %} +{% if area_config.export_list is vyos_defined %} + area {{ area_id }} export-list {{ area_config.export_list }} +{% endif %} +{% if area_config.import_list is vyos_defined %} + area {{ area_id }} import-list {{ area_config.import_list }} +{% endif %} +{% endfor %} +{% endif %} + auto-cost reference-bandwidth {{ auto_cost.reference_bandwidth }} +{% if default_information.originate is vyos_defined %} + default-information originate {{ 'always' if default_information.originate.always is vyos_defined }} {{ 'metric ' ~ default_information.originate.metric if default_information.originate.metric is vyos_defined }} {{ 'metric-type ' ~ default_information.originate.metric_type if default_information.originate.metric_type is vyos_defined }} {{ 'route-map ' ~ default_information.originate.route_map if default_information.originate.route_map is vyos_defined }} +{% endif %} +{% if distance.global is vyos_defined %} + distance {{ distance.global }} +{% endif %} +{% if distance.ospfv3 is vyos_defined %} + distance ospf6 {{ 'intra-area ' ~ distance.ospfv3.intra_area if distance.ospfv3.intra_area is vyos_defined }} {{ 'inter-area ' ~ distance.ospfv3.inter_area if distance.ospfv3.inter_area is vyos_defined }} {{ 'external ' ~ distance.ospfv3.external if distance.ospfv3.external is vyos_defined }} +{% endif %} +{% if log_adjacency_changes is vyos_defined %} + log-adjacency-changes {{ "detail" if log_adjacency_changes.detail is vyos_defined }} +{% endif %} +{% if parameters.router_id is vyos_defined %} + ospf6 router-id {{ parameters.router_id }} +{% endif %} +{% if redistribute is vyos_defined %} +{% for protocol, options in redistribute.items() %} + redistribute {{ protocol }} {{ 'route-map ' ~ options.route_map if options.route_map is vyos_defined }} +{% endfor %} +{% endif %} +exit +! diff --git a/data/templates/frr/ospf6d.frr.tmpl b/data/templates/frr/ospf6d.frr.tmpl deleted file mode 100644 index a8c53738f..000000000 --- a/data/templates/frr/ospf6d.frr.tmpl +++ /dev/null @@ -1,92 +0,0 @@ -! -{% if interface is defined and interface is not none %} -{% for iface, iface_config in interface.items() %} -interface {{ iface }} -{% if iface_config.cost is defined and iface_config.cost is not none %} - ipv6 ospf6 cost {{ iface_config.cost }} -{% endif %} -{% if iface_config.priority is defined and iface_config.priority is not none %} - ipv6 ospf6 priority {{ iface_config.priority }} -{% endif %} -{% if iface_config.hello_interval is defined and iface_config.hello_interval is not none %} - ipv6 ospf6 hello-interval {{ iface_config.hello_interval }} -{% endif %} -{% if iface_config.retransmit_interval is defined and iface_config.retransmit_interval is not none %} - ipv6 ospf6 retransmit-interval {{ iface_config.retransmit_interval }} -{% endif %} -{% if iface_config.transmit_delay is defined and iface_config.transmit_delay is not none %} - ipv6 ospf6 transmit-delay {{ iface_config.transmit_delay }} -{% endif %} -{% if iface_config.dead_interval is defined and iface_config.dead_interval is not none %} - ipv6 ospf6 dead-interval {{ iface_config.dead_interval }} -{% endif %} -{% if iface_config.bfd is defined %} - ipv6 ospf6 bfd -{% endif %} -{% if iface_config.mtu_ignore is defined %} - ipv6 ospf6 mtu-ignore -{% endif %} -{% if iface_config.ifmtu is defined and iface_config.ifmtu is not none %} - ipv6 ospf6 ifmtu {{ iface_config.ifmtu }} -{% endif %} -{% if iface_config.network is defined and iface_config.network is not none %} - ipv6 ospf6 network {{ iface_config.network }} -{% endif %} -{% if iface_config.instance_id is defined and iface_config.instance_id is not none %} - ipv6 ospf6 instance-id {{ iface_config.instance_id }} -{% endif %} -{% if iface_config.passive is defined %} - ipv6 ospf6 passive -{% endif %} -! -{% endfor %} -{% endif %} -! -router ospf6 -{% if area is defined and area is not none %} -{% for area_id, area_config in area.items() %} -{% if area_config.interface is defined and area_config.interface is not none %} -{% for interface in area_config.interface %} - interface {{ interface }} area {{ area_id }} -{% endfor %} -{% endif %} -{% if area_config.area_type is defined and area_config.area_type is not none %} -{% for type, type_config in area_config.area_type.items() %} - area {{ area_id }} {{ type }} {{ 'no-summary' if type_config.no_summary is defined }} -{% endfor %} -{% endif %} -{% if area_config.range is defined and area_config.range is not none %} -{% for prefix, prefix_config in area_config.range.items() %} - area {{ area_id }} range {{ prefix }} {{ 'advertise' if prefix_config.advertise is defined }} {{ 'not-advertise' if prefix_config.not_advertise is defined }} -{% endfor %} -{% endif %} -{% if area_config.export_list is defined and area_config.export_list is not none %} - area {{ area_id }} export-list {{ area_config.export_list }} -{% endif %} -{% if area_config.import_list is defined and area_config.import_list is not none %} - area {{ area_id }} import-list {{ area_config.import_list }} -{% endif %} -{% endfor %} -{% endif %} -{% if distance is defined and distance is not none %} -{% if distance.global is defined and distance.global is not none %} - distance {{ distance.global }} -{% endif %} -{% if distance.ospfv3 is defined and distance.ospfv3 is not none %} - distance ospf6 {{ 'intra-area ' + distance.ospfv3.intra_area if distance.ospfv3.intra_area is defined }} {{ 'inter-area ' + distance.ospfv3.inter_area if distance.ospfv3.inter_area is defined }} {{ 'external ' + distance.ospfv3.external if distance.ospfv3.external is defined }} -{% endif %} -{% endif %} -{% if log_adjacency_changes is defined %} - log-adjacency-changes {{ "detail" if log_adjacency_changes.detail is defined }} -{% endif %} -{% if parameters is defined and parameters is not none %} -{% if parameters.router_id is defined and parameters.router_id is not none %} - ospf6 router-id {{ parameters.router_id }} -{% endif %} -{% endif %} -{% if redistribute is defined and redistribute is not none %} -{% for protocol, options in redistribute.items() %} - redistribute {{ protocol }} {{ 'route-map ' + options.route_map if options.route_map is defined }} -{% endfor %} -{% endif %} -! diff --git a/data/templates/frr/ospfd.frr.j2 b/data/templates/frr/ospfd.frr.j2 new file mode 100644 index 000000000..427fc8be7 --- /dev/null +++ b/data/templates/frr/ospfd.frr.j2 @@ -0,0 +1,189 @@ +! +{% if interface is vyos_defined %} +{% for iface, iface_config in interface.items() %} +interface {{ iface }} +{% if iface_config.authentication.plaintext_password is vyos_defined %} + ip ospf authentication-key {{ iface_config.authentication.plaintext_password }} +{% elif iface_config.authentication.md5 is vyos_defined %} + ip ospf authentication message-digest +{% if iface_config.authentication.md5.key_id is vyos_defined %} +{% for key, key_config in iface_config.authentication.md5.key_id.items() %} + ip ospf message-digest-key {{ key }} md5 {{ key_config.md5_key }} +{% endfor %} +{% endif %} +{% endif %} +{% if iface_config.area is vyos_defined %} + ip ospf area {{ iface_config.area }} +{% endif %} +{% if iface_config.bandwidth is vyos_defined %} + bandwidth {{ iface_config.bandwidth }} +{% endif %} +{% if iface_config.cost is vyos_defined %} + ip ospf cost {{ iface_config.cost }} +{% endif %} +{% if iface_config.priority is vyos_defined %} + ip ospf priority {{ iface_config.priority }} +{% endif %} +{% if iface_config.hello_interval is vyos_defined %} + ip ospf hello-interval {{ iface_config.hello_interval }} +{% endif %} +{% if iface_config.retransmit_interval is vyos_defined %} + ip ospf retransmit-interval {{ iface_config.retransmit_interval }} +{% endif %} +{% if iface_config.transmit_delay is vyos_defined %} + ip ospf transmit-delay {{ iface_config.transmit_delay }} +{% endif %} +{% if iface_config.dead_interval is vyos_defined %} + ip ospf dead-interval {{ iface_config.dead_interval }} +{% elif iface_config.hello_multiplier is vyos_defined %} + ip ospf dead-interval minimal hello-multiplier {{ iface_config.hello_multiplier }} +{% endif %} +{% if iface_config.bfd is vyos_defined %} + ip ospf bfd +{% endif %} +{% if iface_config.bfd.profile is vyos_defined %} + ip ospf bfd profile {{ iface_config.bfd.profile }} +{% endif %} +{% if iface_config.mtu_ignore is vyos_defined %} + ip ospf mtu-ignore +{% endif %} +{% if iface_config.network is vyos_defined %} + ip ospf network {{ iface_config.network }} +{% endif %} +{% if iface_config.passive is vyos_defined %} + {{ 'no ' if iface_config.passive.disable is vyos_defined }}ip ospf passive +{% endif %} +exit +! +{% endfor %} +{% endif %} +! +router ospf {{ 'vrf ' ~ vrf if vrf is vyos_defined }} +{% if access_list is vyos_defined %} +{% for acl, acl_config in access_list.items() %} +{% for protocol in acl_config.export if acl_config.export is vyos_defined %} + distribute-list {{ acl }} out {{ protocol }} +{% endfor %} +{% endfor %} +{% endif %} +{% if area is vyos_defined %} +{% for area_id, area_config in area.items() %} +{% if area_config.area_type is vyos_defined %} +{% for type, type_config in area_config.area_type.items() if type != 'normal' %} + area {{ area_id }} {{ type }} {{ 'no-summary' if type_config.no_summary is vyos_defined }} +{% if type_config.default_cost is vyos_defined %} + area {{ area_id }} default-cost {{ type_config.default_cost }} +{% endif %} +{% endfor %} +{% endif %} +{% if area_config.authentication is vyos_defined %} + area {{ area_id }} authentication {{ 'message-digest' if area_config.authentication is vyos_defined('md5') }} +{% endif %} +{% for network in area_config.network if area_config.network is vyos_defined %} + network {{ network }} area {{ area_id }} +{% endfor %} +{% if area_config.range is vyos_defined %} +{% for range, range_config in area_config.range.items() %} +{% if range_config.cost is vyos_defined %} + area {{ area_id }} range {{ range }} cost {{ range_config.cost }} +{% endif %} +{% if range_config.not_advertise is vyos_defined %} + area {{ area_id }} range {{ range }} not-advertise +{% endif %} +{% if range_config.substitute is vyos_defined %} + area {{ area_id }} range {{ range }} substitute {{ range_config.substitute }} +{% endif %} +{% endfor %} +{% endif %} +{% if area_config.export_list is vyos_defined %} + area {{ area_id }} export-list {{ area_config.export_list }} +{% endif %} +{% if area_config.import_list is vyos_defined %} + area {{ area_id }} import-list {{ area_config.import_list }} +{% endif %} +{% if area_config.shortcut is vyos_defined %} + area {{ area_id }} shortcut {{ area_config.shortcut }} +{% endif %} +{% if area_config.virtual_link is vyos_defined %} +{% for link, link_config in area_config.virtual_link.items() %} +{% if link_config.authentication.plaintext_password is vyos_defined %} + area {{ area_id }} virtual-link {{ link }} authentication-key {{ link_config.authentication.plaintext_password }} +{% elif link_config.authentication.md5.key_id is vyos_defined %} +{% for key, key_config in link_config.authentication.md5.key_id.items() %} + area {{ area_id }} virtual-link {{ link }} message-digest-key {{ key }} md5 {{ key_config.md5_key }} +{% endfor %} +{% endif %} +{# The following values are default values #} + area {{ area_id }} virtual-link {{ link }} hello-interval {{ link_config.hello_interval }} retransmit-interval {{ link_config.retransmit_interval }} transmit-delay {{ link_config.transmit_delay }} dead-interval {{ link_config.dead_interval }} +{% endfor %} +{% endif %} +{% endfor %} +{% endif %} +{% if auto_cost.reference_bandwidth is vyos_defined %} + auto-cost reference-bandwidth {{ auto_cost.reference_bandwidth }} +{% endif %} +{% if default_information.originate is vyos_defined %} + default-information originate {{ 'always' if default_information.originate.always is vyos_defined }} {{ 'metric ' + default_information.originate.metric if default_information.originate.metric is vyos_defined }} {{ 'metric-type ' + default_information.originate.metric_type if default_information.originate.metric_type is vyos_defined }} {{ 'route-map ' + default_information.originate.route_map if default_information.originate.route_map is vyos_defined }} +{% endif %} +{% if default_metric is vyos_defined %} + default-metric {{ default_metric }} +{% endif %} +{% if maximum_paths is vyos_defined %} + maximum-paths {{ maximum_paths }} +{% endif %} +{% if distance.global is vyos_defined %} + distance {{ distance.global }} +{% endif %} +{% if distance.ospf is vyos_defined %} + distance ospf {{ 'intra-area ' + distance.ospf.intra_area if distance.ospf.intra_area is vyos_defined }} {{ 'inter-area ' + distance.ospf.inter_area if distance.ospf.inter_area is vyos_defined }} {{ 'external ' + distance.ospf.external if distance.ospf.external is vyos_defined }} +{% endif %} +{% if log_adjacency_changes is vyos_defined %} + log-adjacency-changes {{ "detail" if log_adjacency_changes.detail is vyos_defined }} +{% endif %} +{% if max_metric.router_lsa.administrative is vyos_defined %} + max-metric router-lsa administrative +{% endif %} +{% if max_metric.router_lsa.on_shutdown is vyos_defined %} + max-metric router-lsa on-shutdown {{ max_metric.router_lsa.on_shutdown }} +{% endif %} +{% if max_metric.router_lsa.on_startup is vyos_defined %} + max-metric router-lsa on-startup {{ max_metric.router_lsa.on_startup }} +{% endif %} +{% if mpls_te.enable is vyos_defined %} + mpls-te on + mpls-te router-address {{ mpls_te.router_address }} +{% endif %} +{% if neighbor is vyos_defined %} +{% for address, address_config in neighbor.items() %} + neighbor {{ address }} {{ 'priority ' + address_config.priority if address_config.priority is vyos_defined }} {{ 'poll-interval ' + address_config.poll_interval if address_config.poll_interval is vyos_defined }} +{% endfor %} +{% endif %} +{% if parameters.abr_type is vyos_defined %} + ospf abr-type {{ parameters.abr_type }} +{% endif %} +{% if parameters.router_id is vyos_defined %} + ospf router-id {{ parameters.router_id }} +{% endif %} +{% if passive_interface.default is vyos_defined %} + passive-interface default +{% endif %} +{% if redistribute is vyos_defined %} +{% for protocol, protocols_options in redistribute.items() %} +{% if protocol == 'table' %} +{% for table, table_options in protocols_options.items() %} + redistribute {{ protocol }} {{ table }} {{ 'metric ' + table_options.metric if table_options.metric is vyos_defined }} {{ 'metric-type ' + table_options.metric_type if table_options.metric_type is vyos_defined }} {{ 'route-map ' + table_options.route_map if table_options.route_map is vyos_defined }} +{% endfor %} +{% else %} + redistribute {{ protocol }} {{ 'metric ' + protocols_options.metric if protocols_options.metric is vyos_defined }} {{ 'metric-type ' + protocols_options.metric_type if protocols_options.metric_type is vyos_defined }} {{ 'route-map ' + protocols_options.route_map if protocols_options.route_map is vyos_defined }} +{% endif %} +{% endfor %} +{% endif %} +{% if refresh.timers is vyos_defined %} + refresh timer {{ refresh.timers }} +{% endif %} +{% if timers.throttle.spf.delay is vyos_defined and timers.throttle.spf.initial_holdtime is vyos_defined and timers.throttle.spf.max_holdtime is vyos_defined %} +{# Timer values have default values #} + timers throttle spf {{ timers.throttle.spf.delay }} {{ timers.throttle.spf.initial_holdtime }} {{ timers.throttle.spf.max_holdtime }} +{% endif %} +exit +! diff --git a/data/templates/frr/ospfd.frr.tmpl b/data/templates/frr/ospfd.frr.tmpl deleted file mode 100644 index 90a6bbd56..000000000 --- a/data/templates/frr/ospfd.frr.tmpl +++ /dev/null @@ -1,192 +0,0 @@ -! -{% if interface is defined and interface is not none %} -{% for iface, iface_config in interface.items() %} -interface {{ iface }} {{ 'vrf ' + vrf if vrf is defined and vrf is not none }} -{% if iface_config.authentication is defined and iface_config.authentication is not none %} -{% if iface_config.authentication.plaintext_password is defined and iface_config.authentication.plaintext_password is not none %} - ip ospf authentication-key {{ iface_config.authentication.plaintext_password }} -{% elif iface_config.authentication.md5 is defined %} - ip ospf authentication message-digest -{% if iface_config.authentication.md5.key_id is defined and iface_config.authentication.md5.key_id is not none %} -{% for key, key_config in iface_config.authentication.md5.key_id.items() %} - ip ospf message-digest-key {{ key }} md5 {{ key_config.md5_key }} -{% endfor %} -{% endif %} -{% endif %} -{% endif %} -{% if iface_config.area is defined and iface_config.area is not none %} - ip ospf area {{ iface_config.area }} -{% endif %} -{% if iface_config.bandwidth is defined and iface_config.bandwidth is not none %} - bandwidth {{ iface_config.bandwidth }} -{% endif %} -{% if iface_config.cost is defined and iface_config.cost is not none %} - ip ospf cost {{ iface_config.cost }} -{% endif %} -{% if iface_config.priority is defined and iface_config.priority is not none %} - ip ospf priority {{ iface_config.priority }} -{% endif %} -{% if iface_config.hello_interval is defined and iface_config.hello_interval is not none %} - ip ospf hello-interval {{ iface_config.hello_interval }} -{% endif %} -{% if iface_config.retransmit_interval is defined and iface_config.retransmit_interval is not none %} - ip ospf retransmit-interval {{ iface_config.retransmit_interval }} -{% endif %} -{% if iface_config.transmit_delay is defined and iface_config.transmit_delay is not none %} - ip ospf transmit-delay {{ iface_config.transmit_delay }} -{% endif %} -{% if iface_config.dead_interval is defined and iface_config.dead_interval is not none %} - ip ospf dead-interval {{ iface_config.dead_interval }} -{% elif iface_config.hello_multiplier is defined and iface_config.hello_multiplier is not none %} - ip ospf dead-interval minimal hello-multiplier {{ iface_config.hello_multiplier }} -{% endif %} -{% if iface_config.bfd is defined %} - ip ospf bfd -{% endif %} -{% if iface_config.mtu_ignore is defined %} - ip ospf mtu-ignore -{% endif %} -{% if iface_config.network is defined and iface_config.network is not none %} - ip ospf network {{ iface_config.network }} -{% endif %} -! -{% endfor %} -{% endif %} -! -router ospf {{ 'vrf ' + vrf if vrf is defined and vrf is not none }} -{% if access_list is defined and access_list is not none %} -{% for acl, acl_config in access_list.items() %} -{% for protocol in acl_config.export if acl_config.export is defined %} - distribute-list {{ acl }} out {{ protocol }} -{% endfor %} -{% endfor %} -{% endif %} -{% if area is defined and area is not none %} -{% for area_id, area_config in area.items() %} -{% if area_config.area_type is defined and area_config.area_type is not none %} -{% for type, type_config in area_config.area_type.items() if type != 'normal' %} - area {{ area_id }} {{ type }} {{ 'no-summary' if type_config.no_summary is defined }} -{% if type_config.default_cost is defined and type_config.default_cost is not none %} - area {{ area_id }} default-cost {{ type_config.default_cost }} -{% endif %} -{% endfor %} -{% endif %} -{% if area_config.authentication is defined and area_config.authentication is not none %} - area {{ area_id }} authentication {{ 'message-digest' if area_config.authentication == 'md5' }} -{% endif %} -{% for network in area_config.network if area_config.network is defined %} - network {{ network }} area {{ area_id }} -{% endfor %} -{% if area_config.range is defined and area_config.range is not none %} -{% for range, range_config in area_config.range.items() %} -{% if range_config.cost is defined and range_config.cost is not none %} - area {{ area_id }} range {{ range }} cost {{ range_config.cost }} -{% endif %} -{% if range_config.not_advertise is defined %} - area {{ area_id }} range {{ range }} not-advertise -{% endif %} -{% if range_config.substitute is defined and range_config.substitute is not none %} - area {{ area_id }} range {{ range }} substitute {{ range_config.substitute }} -{% endif %} -{% endfor %} -{% endif %} -{% if area_config.shortcut is defined and area_config.shortcut is not none %} - area {{ area_id }} shortcut {{ area_config.shortcut }} -{% endif %} -{% if area_config.virtual_link is defined and area_config.virtual_link is not none %} -{% for link, link_config in area_config.virtual_link.items() %} -{% if link_config.authentication is defined and link_config.authentication is not none %} -{% if link_config.authentication.plaintext_password is defined and link_config.authentication.plaintext_password is not none %} - area {{ area_id }} virtual-link {{ link }} authentication-key {{ link_config.authentication.plaintext_password }} -{% elif link_config.authentication.md5 is defined and link_config.authentication.md5.key_id is defined and link_config.authentication.md5.key_id is not none %} -{% for key, key_config in link_config.authentication.md5.key_id.items() %} - area {{ area_id }} virtual-link {{ link }} message-digest-key {{ key }} md5 {{ key_config.md5_key }} -{% endfor %} -{% endif %} -{% endif %} -{# The following values are default values #} - area {{ area_id }} virtual-link {{ link }} hello-interval {{ link_config.hello_interval }} retransmit-interval {{ link_config.retransmit_interval }} transmit-delay {{ link_config.transmit_delay }} dead-interval {{ link_config.dead_interval }} -{% endfor %} -{% endif %} -{% endfor %} -{% endif %} -{% if auto_cost is defined and auto_cost.reference_bandwidth is defined and auto_cost.reference_bandwidth is not none %} - auto-cost reference-bandwidth {{ auto_cost.reference_bandwidth }} -{% endif %} -{% if default_information is defined and default_information.originate is defined and default_information.originate is not none %} - default-information originate {{ 'always' if default_information.originate.always is defined }} {{ 'metric ' + default_information.originate.metric if default_information.originate.metric is defined }} {{ 'metric-type ' + default_information.originate.metric_type if default_information.originate.metric_type is defined }} {{ 'route-map ' + default_information.originate.route_map if default_information.originate.route_map is defined }} -{% endif %} -{% if default_metric is defined and default_metric is not none %} - default-metric {{ default_metric }} -{% endif %} -{% if distance is defined and distance is not none %} -{% if distance.global is defined and distance.global is not none %} - distance {{ distance.global }} -{% endif %} -{% if distance.ospf is defined and distance.ospf is not none %} - distance ospf {{ 'intra-area ' + distance.ospf.intra_area if distance.ospf.intra_area is defined }} {{ 'inter-area ' + distance.ospf.inter_area if distance.ospf.inter_area is defined }} {{ 'external ' + distance.ospf.external if distance.ospf.external is defined }} -{% endif %} -{% endif %} -{% if log_adjacency_changes is defined %} - log-adjacency-changes {{ "detail" if log_adjacency_changes.detail is defined }} -{% endif %} -{% if max_metric is defined and max_metric.router_lsa is defined and max_metric.router_lsa is not none %} -{% if max_metric.router_lsa.administrative is defined %} - max-metric router-lsa administrative -{% endif %} -{% if max_metric.router_lsa.on_shutdown is defined and max_metric.router_lsa.on_shutdown is not none %} - max-metric router-lsa on-shutdown {{ max_metric.router_lsa.on_shutdown }} -{% endif %} -{% if max_metric.router_lsa.on_startup is defined and max_metric.router_lsa.on_startup is not none %} - max-metric router-lsa on-startup {{ max_metric.router_lsa.on_startup }} -{% endif %} -{% endif %} -{% if mpls_te is defined and mpls_te.enable is defined %} - mpls-te on - mpls-te router-address {{ mpls_te.router_address }} -{% endif %} -{% if neighbor is defined and neighbor is not none%} -{% for address, address_config in neighbor.items() %} - neighbor {{ address }} {{ 'priority ' + address_config.priority if address_config.priority is defined }} {{ 'poll-interval ' + address_config.poll_interval if address_config.poll_interval is defined }} -{% endfor %} -{% endif %} -{% if parameters is defined and parameters is not none %} -{% if parameters.abr_type is defined and parameters.abr_type is not none %} - ospf abr-type {{ parameters.abr_type }} -{% endif %} -{% if parameters.router_id is defined and parameters.router_id is not none %} - ospf router-id {{ parameters.router_id }} -{% endif %} -{% endif %} -{% if passive_interface is defined and passive_interface is not none %} -{% for interface in passive_interface %} - passive-interface {{ interface }} -{% endfor %} -{% endif %} -{% if passive_interface_exclude is defined and passive_interface_exclude is not none %} -{% for interface in passive_interface_exclude if passive_interface_exclude is defined %} -{% if interface.startswith('vlink') %} -{% set interface = interface.upper() %} -{% endif %} - no passive-interface {{ interface }} -{% endfor %} -{% endif %} -{% if redistribute is defined and redistribute is not none %} -{% for protocol, protocols_options in redistribute.items() %} -{% if protocol == 'table' %} -{% for table, table_options in protocols_options.items() %} - redistribute {{ protocol }} {{ table }} {{ 'metric ' + table_options.metric if table_options.metric is defined }} {{ 'metric-type ' + table_options.metric_type if table_options.metric_type is defined }} {{ 'route-map ' + table_options.route_map if table_options.route_map is defined }} -{% endfor %} -{% else %} - redistribute {{ protocol }} {{ 'metric ' + protocols_options.metric if protocols_options.metric is defined }} {{ 'metric-type ' + protocols_options.metric_type if protocols_options.metric_type is defined }} {{ 'route-map ' + protocols_options.route_map if protocols_options.route_map is defined }} -{% endif %} -{% endfor %} -{% endif %} -{% if refresh is defined and refresh.timers is defined and refresh.timers is not none %} - refresh timer {{ refresh.timers }} -{% endif %} -{% if timers is defined and timers.throttle is defined and timers.throttle.spf is defined and timers.throttle.spf is not none %} -{# Timer values have default values #} - timers throttle spf {{ timers.throttle.spf.delay }} {{ timers.throttle.spf.initial_holdtime }} {{ timers.throttle.spf.max_holdtime }} -{% endif %} -! diff --git a/data/templates/frr/pimd.frr.tmpl b/data/templates/frr/pimd.frr.j2 index a5b56223a..cb2f2aa98 100644 --- a/data/templates/frr/pimd.frr.tmpl +++ b/data/templates/frr/pimd.frr.j2 @@ -1,8 +1,8 @@ ! {% for rp_addr in old_pim.rp %} -{% for group in old_pim.rp[rp_addr] %} +{% for group in old_pim.rp[rp_addr] %} no ip pim rp {{ rp_addr }} {{ group }} -{% endfor %} +{% endfor %} {% endfor %} {% if old_pim.rp_keep_alive %} no ip pim rp keep-alive-timer {{ old_pim.rp_keep_alive }} @@ -15,18 +15,18 @@ no ip pim {% for iface in pim.ifaces %} interface {{ iface }} ip pim -{% if pim.ifaces[iface].dr_prio %} +{% if pim.ifaces[iface].dr_prio %} ip pim drpriority {{ pim.ifaces[iface].dr_prio }} -{% endif %} -{% if pim.ifaces[iface].hello %} +{% endif %} +{% if pim.ifaces[iface].hello %} ip pim hello {{ pim.ifaces[iface].hello }} -{% endif %} +{% endif %} ! {% endfor %} {% for rp_addr in pim.rp %} -{% for group in pim.rp[rp_addr] %} +{% for group in pim.rp[rp_addr] %} ip pim rp {{ rp_addr }} {{ group }} -{% endfor %} +{% endfor %} {% endfor %} {% if pim.rp_keep_alive %} ip pim rp keep-alive-timer {{ pim.rp_keep_alive }} diff --git a/data/templates/frr/policy.frr.j2 b/data/templates/frr/policy.frr.j2 new file mode 100644 index 000000000..a42b73e98 --- /dev/null +++ b/data/templates/frr/policy.frr.j2 @@ -0,0 +1,331 @@ +{% if access_list is vyos_defined %} +{% for acl, acl_config in access_list.items() | natural_sort %} +{% if acl_config.description is vyos_defined %} +access-list {{ acl }} remark {{ acl_config.description }} +{% endif %} +{% if acl_config.rule is vyos_defined %} +{% for rule, rule_config in acl_config.rule.items() | natural_sort %} +{% set ip = '' %} +{% set src = '' %} +{% set src_mask = '' %} +{% if rule_config.source.any is vyos_defined %} +{% set src = 'any' %} +{% elif rule_config.source.host is vyos_defined %} +{% set src = 'host ' ~ rule_config.source.host %} +{% elif rule_config.source.network is vyos_defined %} +{% set src = rule_config.source.network %} +{% set src_mask = rule_config.source.inverse_mask %} +{% endif %} +{% set dst = '' %} +{% set dst_mask = '' %} +{% if (acl | int >= 100 and acl | int <= 199) or (acl | int >= 2000 and acl | int <= 2699) %} +{% set ip = 'ip' %} +{% set dst = 'any' %} +{% if rule_config.destination.any is vyos_defined %} +{% set dst = 'any' %} +{% elif rule_config.destination.host is vyos_defined %} +{% set dst = 'host ' ~ rule_config.destination.host %} +{% elif rule_config.destination.network is vyos_defined %} +{% set dst = rule_config.destination.network %} +{% set dst_mask = rule_config.destination.inverse_mask %} +{% endif %} +{% endif %} +access-list {{ acl }} seq {{ rule }} {{ rule_config.action }} {{ ip }} {{ src }} {{ src_mask }} {{ dst }} {{ dst_mask }} +{% endfor %} +{% endif %} +{% endfor %} +{% endif %} +! +{% if access_list6 is vyos_defined %} +{% for acl, acl_config in access_list6.items() | natural_sort %} +{% if acl_config.description is vyos_defined %} +ipv6 access-list {{ acl }} remark {{ acl_config.description }} +{% endif %} +{% if acl_config.rule is vyos_defined %} +{% for rule, rule_config in acl_config.rule.items() | natural_sort %} +{% set src = '' %} +{% if rule_config.source.any is vyos_defined %} +{% set src = 'any' %} +{% elif rule_config.source.network is vyos_defined %} +{% set src = rule_config.source.network %} +{% endif %} +ipv6 access-list {{ acl }} seq {{ rule }} {{ rule_config.action }} {{ src }} {{ 'exact-match' if rule_config.source.exact_match is vyos_defined }} +{% endfor %} +{% endif %} +{% endfor %} +{% endif %} +! +{% if as_path_list is vyos_defined %} +{% for acl, acl_config in as_path_list.items() | natural_sort %} +{% if acl_config.rule is vyos_defined %} +{% for rule, rule_config in acl_config.rule.items() | natural_sort %} +bgp as-path access-list {{ acl }} seq {{ rule }} {{ rule_config.action }} {{ rule_config.regex }} +{% endfor %} +{% endif %} +{% endfor %} +{% endif %} +! +{% if community_list is vyos_defined %} +{% for list, list_config in community_list.items() | natural_sort %} +{% if list_config.rule is vyos_defined %} +{% for rule, rule_config in list_config.rule.items() | natural_sort %} +{# by default, if casting to int fails it returns 0 #} +{% if list | int != 0 %} +bgp community-list {{ list }} seq {{ rule }} {{ rule_config.action }} {{ rule_config.regex }} +{% else %} +bgp community-list expanded {{ list }} seq {{ rule }} {{ rule_config.action }} {{ rule_config.regex }} +{% endif %} +{% endfor %} +{% endif %} +{% endfor %} +{% endif %} +! +{% if extcommunity_list is vyos_defined %} +{% for list, list_config in extcommunity_list.items() | natural_sort %} +{% if list_config.rule is vyos_defined %} +{% for rule, rule_config in list_config.rule.items() | natural_sort %} +{# by default, if casting to int fails it returns 0 #} +{% if list | int != 0 %} +bgp extcommunity-list {{ list }} seq {{ rule }} {{ rule_config.action }} {{ rule_config.regex }} +{% else %} +bgp extcommunity-list expanded {{ list }} seq {{ rule }} {{ rule_config.action }} {{ rule_config.regex }} +{% endif %} +{% endfor %} +{% endif %} +{% endfor %} +{% endif %} +! +{% if large_community_list is vyos_defined %} +{% for list, list_config in large_community_list.items() | natural_sort %} +{% if list_config.rule is vyos_defined %} +{% for rule, rule_config in list_config.rule.items() | natural_sort %} +{# by default, if casting to int fails it returns 0 #} +{% if list | int != 0 %} +bgp large-community-list {{ list }} seq {{ rule }} {{ rule_config.action }} {{ rule_config.regex }} +{% else %} +bgp large-community-list expanded {{ list }} seq {{ rule }} {{ rule_config.action }} {{ rule_config.regex }} +{% endif %} +{% endfor %} +{% endif %} +{% endfor %} +{% endif %} +! +{% if prefix_list is vyos_defined %} +{% for prefix_list, prefix_list_config in prefix_list.items() | natural_sort %} +{% if prefix_list_config.description is vyos_defined %} +ip prefix-list {{ prefix_list }} description {{ prefix_list_config.description }} +{% endif %} +{% if prefix_list_config.rule is vyos_defined %} +{% for rule, rule_config in prefix_list_config.rule.items() | natural_sort %} +{% if rule_config.prefix is vyos_defined %} +ip prefix-list {{ prefix_list }} seq {{ rule }} {{ rule_config.action }} {{ rule_config.prefix }} {{ 'ge ' ~ rule_config.ge if rule_config.ge is vyos_defined }} {{ 'le ' ~ rule_config.le if rule_config.le is vyos_defined }} +{% endif %} +{% endfor %} +{% endif %} +{% endfor %} +{% endif %} +! +{% if prefix_list6 is vyos_defined %} +{% for prefix_list, prefix_list_config in prefix_list6.items() | natural_sort %} +{% if prefix_list_config.description is vyos_defined %} +ipv6 prefix-list {{ prefix_list }} description {{ prefix_list_config.description }} +{% endif %} +{% if prefix_list_config.rule is vyos_defined %} +{% for rule, rule_config in prefix_list_config.rule.items() | natural_sort %} +{% if rule_config.prefix is vyos_defined %} +ipv6 prefix-list {{ prefix_list }} seq {{ rule }} {{ rule_config.action }} {{ rule_config.prefix }} {{ 'ge ' ~ rule_config.ge if rule_config.ge is vyos_defined }} {{ 'le ' ~ rule_config.le if rule_config.le is vyos_defined }} +{% endif %} +{% endfor %} +{% endif %} +{% endfor %} +{% endif %} +! +{% if route_map is vyos_defined %} +{% for route_map, route_map_config in route_map.items() | natural_sort %} +{% if route_map_config.rule is vyos_defined %} +{% for rule, rule_config in route_map_config.rule.items() | natural_sort %} +route-map {{ route_map }} {{ rule_config.action }} {{ rule }} +{% if rule_config.call is vyos_defined %} + call {{ rule_config.call }} +{% endif %} +{% if rule_config.continue is vyos_defined %} + on-match goto {{ rule_config.continue }} +{% endif %} +{% if rule_config.description is vyos_defined %} + description {{ rule_config.description }} +{% endif %} +{% if rule_config.match is vyos_defined %} +{% if rule_config.match.as_path is vyos_defined %} + match as-path {{ rule_config.match.as_path }} +{% endif %} +{% if rule_config.match.community.community_list is vyos_defined %} + match community {{ rule_config.match.community.community_list }} {{ 'exact-match' if rule_config.match.community.exact_match is vyos_defined }} +{% endif %} +{% if rule_config.match.extcommunity is vyos_defined %} + match extcommunity {{ rule_config.match.extcommunity }} +{% endif %} +{% if rule_config.match.evpn.default_route is vyos_defined %} + match evpn default-route +{% endif %} +{% if rule_config.match.evpn.rd is vyos_defined %} + match evpn rd {{ rule_config.match.evpn.rd }} +{% endif %} +{% if rule_config.match.evpn.route_type is vyos_defined %} + match evpn route-type {{ rule_config.match.evpn.route_type }} +{% endif %} +{% if rule_config.match.evpn.vni is vyos_defined %} + match evpn vni {{ rule_config.match.evpn.vni }} +{% endif %} +{% if rule_config.match.interface is vyos_defined %} + match interface {{ rule_config.match.interface }} +{% endif %} +{% if rule_config.match.ip.address.access_list is vyos_defined %} + match ip address {{ rule_config.match.ip.address.access_list }} +{% endif %} +{% if rule_config.match.ip.address.prefix_list is vyos_defined %} + match ip address prefix-list {{ rule_config.match.ip.address.prefix_list }} +{% endif %} +{% if rule_config.match.ip.nexthop.access_list is vyos_defined %} + match ip next-hop {{ rule_config.match.ip.nexthop.access_list }} +{% endif %} +{% if rule_config.match.ip.nexthop.prefix_list is vyos_defined %} + match ip next-hop prefix-list {{ rule_config.match.ip.nexthop.prefix_list }} +{% endif %} +{% if rule_config.match.ip.route_source.access_list is vyos_defined %} + match ip route-source {{ rule_config.match.ip.route_source.access_list }} +{% endif %} +{% if rule_config.match.ip.route_source.prefix_list is vyos_defined %} + match ip route-source prefix-list {{ rule_config.match.ip.route_source.prefix_list }} +{% endif %} +{% if rule_config.match.ipv6.address.access_list is vyos_defined %} + match ipv6 address {{ rule_config.match.ipv6.address.access_list }} +{% endif %} +{% if rule_config.match.ipv6.address.prefix_list is vyos_defined %} + match ipv6 address prefix-list {{ rule_config.match.ipv6.address.prefix_list }} +{% endif %} +{% if rule_config.match.ipv6.nexthop is vyos_defined %} + match ipv6 next-hop address {{ rule_config.match.ipv6.nexthop }} +{% endif %} +{% if rule_config.match.large_community.large_community_list is vyos_defined %} + match large-community {{ rule_config.match.large_community.large_community_list }} +{% endif %} +{% if rule_config.match.local_preference is vyos_defined %} + match local-preference {{ rule_config.match.local_preference }} +{% endif %} +{% if rule_config.match.metric is vyos_defined %} + match metric {{ rule_config.match.metric }} +{% endif %} +{% if rule_config.match.origin is vyos_defined %} + match origin {{ rule_config.match.origin }} +{% endif %} +{% if rule_config.match.peer is vyos_defined %} + match peer {{ rule_config.match.peer }} +{% endif %} +{% if rule_config.match.rpki is vyos_defined %} + match rpki {{ rule_config.match.rpki }} +{% endif %} +{% if rule_config.match.tag is vyos_defined %} + match tag {{ rule_config.match.tag }} +{% endif %} +{% endif %} +{% if rule_config.on_match.next is vyos_defined %} + on-match next +{% endif %} +{% if rule_config.on_match.goto is vyos_defined %} + on-match goto {{ rule_config.on_match.goto }} +{% endif %} +{% if rule_config.set is vyos_defined %} +{% if rule_config.set.aggregator.as is vyos_defined and rule_config.set.aggregator.ip is vyos_defined %} + set aggregator as {{ rule_config.set.aggregator.as }} {{ rule_config.set.aggregator.ip }} +{% endif %} +{% if rule_config.set.as_path.exclude is vyos_defined %} + set as-path exclude {{ rule_config.set.as_path.exclude }} +{% endif %} +{% if rule_config.set.as_path.prepend is vyos_defined %} + set as-path prepend {{ rule_config.set.as_path.prepend }} +{% endif %} +{% if rule_config.set.as_path.prepend_last_as is vyos_defined %} + set as-path prepend last-as {{ rule_config.set.as_path.prepend_last_as }} +{% endif %} +{% if rule_config.set.atomic_aggregate is vyos_defined %} + set atomic-aggregate +{% endif %} +{% if rule_config.set.comm_list.comm_list is vyos_defined %} + set comm-list {{ rule_config.set.comm_list.comm_list }} {{ 'delete' if rule_config.set.comm_list.delete is vyos_defined }} +{% endif %} +{% if rule_config.set.community is vyos_defined %} + set community {{ rule_config.set.community }} +{% endif %} +{% if rule_config.set.distance is vyos_defined %} + set distance {{ rule_config.set.distance }} +{% endif %} +{% if rule_config.set.evpn.gateway.ipv4 is vyos_defined %} + set evpn gateway-ip ipv4 {{ rule_config.set.evpn.gateway.ipv4 }} +{% endif %} +{% if rule_config.set.evpn.gateway.ipv6 is vyos_defined %} + set evpn gateway-ip ipv6 {{ rule_config.set.evpn.gateway.ipv6 }} +{% endif %} +{% if rule_config.set.extcommunity.bandwidth is vyos_defined %} + set extcommunity bandwidth {{ rule_config.set.extcommunity.bandwidth }} +{% endif %} +{% if rule_config.set.extcommunity.rt is vyos_defined %} + set extcommunity rt {{ rule_config.set.extcommunity.rt }} +{% endif %} +{% if rule_config.set.extcommunity.soo is vyos_defined %} + set extcommunity soo {{ rule_config.set.extcommunity.soo }} +{% endif %} +{% if rule_config.set.ip_next_hop is vyos_defined %} + set ip next-hop {{ rule_config.set.ip_next_hop }} +{% endif %} +{% if rule_config.set.ipv6_next_hop.global is vyos_defined %} + set ipv6 next-hop global {{ rule_config.set.ipv6_next_hop.global }} +{% endif %} +{% if rule_config.set.ipv6_next_hop.local is vyos_defined %} + set ipv6 next-hop local {{ rule_config.set.ipv6_next_hop.local }} +{% endif %} +{% if rule_config.set.ipv6_next_hop.peer_address is vyos_defined %} + set ipv6 next-hop peer-address +{% endif %} +{% if rule_config.set.ipv6_next_hop.prefer_global is vyos_defined %} + set ipv6 next-hop prefer-global +{% endif %} +{% if rule_config.set.large_community is vyos_defined %} + set large-community {{ rule_config.set.large_community }} +{% endif %} +{% if rule_config.set.large_comm_list_delete is vyos_defined %} + set large-comm-list {{ rule_config.set.large_comm_list_delete }} delete +{% endif %} +{% if rule_config.set.local_preference is vyos_defined %} + set local-preference {{ rule_config.set.local_preference }} +{% endif %} +{% if rule_config.set.metric is vyos_defined %} + set metric {{ rule_config.set.metric }} +{% endif %} +{% if rule_config.set.metric_type is vyos_defined %} + set metric-type {{ rule_config.set.metric_type }} +{% endif %} +{% if rule_config.set.origin is vyos_defined %} + set origin {{ rule_config.set.origin }} +{% endif %} +{% if rule_config.set.originator_id is vyos_defined %} + set originator-id {{ rule_config.set.originator_id }} +{% endif %} +{% if rule_config.set.src is vyos_defined %} + set src {{ rule_config.set.src }} +{% endif %} +{% if rule_config.set.table is vyos_defined %} + set table {{ rule_config.set.table }} +{% endif %} +{% if rule_config.set.tag is vyos_defined %} + set tag {{ rule_config.set.tag }} +{% endif %} +{% if rule_config.set.weight is vyos_defined %} + set weight {{ rule_config.set.weight }} +{% endif %} +{% endif %} +exit +! +{% endfor %} +{% endif %} +{% endfor %} +{% endif %} diff --git a/data/templates/frr/policy.frr.tmpl b/data/templates/frr/policy.frr.tmpl deleted file mode 100644 index 51adc1902..000000000 --- a/data/templates/frr/policy.frr.tmpl +++ /dev/null @@ -1,322 +0,0 @@ -! -{% if access_list is defined and access_list is not none %} -{% for acl, acl_config in access_list.items() | natural_sort %} -{% if acl_config.description is defined and acl_config.description is not none %} -access-list {{ acl }} remark {{ acl_config.description }} -{% endif %} -{% if acl_config.rule is defined and acl_config.rule is not none %} -{% for rule, rule_config in acl_config.rule.items() | natural_sort %} -{% set ip = '' %} -{% set src = '' %} -{% set src_mask = '' %} -{% if rule_config.source is defined and rule_config.source.any is defined %} -{% set src = 'any' %} -{% elif rule_config.source is defined and rule_config.source.host is defined and rule_config.source.host is not none %} -{% set src = 'host ' + rule_config.source.host %} -{% elif rule_config.source is defined and rule_config.source.network is defined and rule_config.source.network is not none %} -{% set src = rule_config.source.network %} -{% set src_mask = rule_config.source.inverse_mask %} -{% endif %} -{% set dst = '' %} -{% set dst_mask = '' %} -{% if (acl|int >= 100 and acl|int <= 199) or (acl|int >= 2000 and acl|int <= 2699) %} -{% set ip = 'ip' %} -{% set dst = 'any' %} -{% if rule_config.destination is defined and rule_config.destination.any is defined %} -{% set dst = 'any' %} -{% elif rule_config.destination is defined and rule_config.destination.host is defined and rule_config.destination.host is not none %} -{% set dst = 'host ' + rule_config.destination.host %} -{% elif rule_config.destination is defined and rule_config.destination.network is defined and rule_config.destination.network is not none %} -{% set dst = rule_config.destination.network %} -{% set dst_mask = rule_config.destination.inverse_mask %} -{% endif %} -{% endif %} -access-list {{ acl }} seq {{ rule }} {{ rule_config.action }} {{ ip }} {{ src }} {{ src_mask }} {{ dst }} {{ dst_mask }} -{% endfor %} -{% endif %} -{% endfor %} -{% endif %} -! -{% if access_list6 is defined and access_list6 is not none %} -{% for acl, acl_config in access_list6.items() | natural_sort %} -{% if acl_config.description is defined and acl_config.description is not none %} -ipv6 access-list {{ acl }} remark {{ acl_config.description }} -{% endif %} -{% if acl_config.rule is defined and acl_config.rule is not none %} -{% for rule, rule_config in acl_config.rule.items() | natural_sort %} -{% set src = '' %} -{% if rule_config.source is defined and rule_config.source.any is defined %} -{% set src = 'any' %} -{% elif rule_config.source is defined and rule_config.source.network is defined and rule_config.source.network is not none %} -{% set src = rule_config.source.network %} -{% endif %} -ipv6 access-list {{ acl }} seq {{ rule }} {{ rule_config.action }} {{ src }} {{ 'exact-match' if rule_config.source.exact_match is defined }} -{% endfor %} -{% endif %} -{% endfor %} -{% endif %} -! -{% if as_path_list is defined and as_path_list is not none %} -{% for acl, acl_config in as_path_list.items() | natural_sort %} -{% if acl_config.rule is defined and acl_config.rule is not none %} -{% for rule, rule_config in acl_config.rule.items() | natural_sort %} -bgp as-path access-list {{ acl }} {{ rule_config.action }} {{ rule_config.regex }} -{% endfor %} -{% endif %} -{% endfor %} -{% endif %} -! -{% if community_list is defined and community_list is not none %} -{% for list, list_config in community_list.items() | natural_sort %} -{% if list_config.rule is defined and list_config.rule is not none %} -{% for rule, rule_config in list_config.rule.items() | natural_sort %} -{# by default, if casting to int fails it returns 0 #} -{% if list|int != 0 %} -bgp community-list {{ list }} seq {{ rule }} {{ rule_config.action }} {{ rule_config.regex }} -{% else %} -bgp community-list expanded {{ list }} seq {{ rule }} {{ rule_config.action }} {{ rule_config.regex }} -{% endif %} -{% endfor %} -{% endif %} -{% endfor %} -{% endif %} -! -{% if extcommunity_list is defined and extcommunity_list is not none %} -{% for list, list_config in extcommunity_list.items() | natural_sort %} -{% if list_config.rule is defined and list_config.rule is not none %} -{% for rule, rule_config in list_config.rule.items() | natural_sort %} -{# by default, if casting to int fails it returns 0 #} -{% if list|int != 0 %} -bgp extcommunity-list {{ list }} seq {{ rule }} {{ rule_config.action }} {{ rule_config.regex }} -{% else %} -bgp extcommunity-list expanded {{ list }} seq {{ rule }} {{ rule_config.action }} {{ rule_config.regex }} -{% endif %} -{% endfor %} -{% endif %} -{% endfor %} -{% endif %} -! -{% if large_community_list is defined and large_community_list is not none %} -{% for list, list_config in large_community_list.items() | natural_sort %} -{% if list_config.rule is defined and list_config.rule is not none %} -{% for rule, rule_config in list_config.rule.items() | natural_sort %} -{# by default, if casting to int fails it returns 0 #} -{% if list|int != 0 %} -bgp large-community-list {{ list }} seq {{ rule }} {{ rule_config.action }} {{ rule_config.regex }} -{% else %} -bgp large-community-list expanded {{ list }} seq {{ rule }} {{ rule_config.action }} {{ rule_config.regex }} -{% endif %} -{% endfor %} -{% endif %} -{% endfor %} -{% endif %} -! -{% if prefix_list is defined and prefix_list is not none %} -{% for prefix_list, prefix_list_config in prefix_list.items() | natural_sort %} -{% if prefix_list_config.description is defined and prefix_list_config.description is not none %} -ip prefix-list {{ prefix_list }} description {{ prefix_list_config.description }} -{% endif %} -{% if prefix_list_config.rule is defined and prefix_list_config.rule is not none %} -{% for rule, rule_config in prefix_list_config.rule.items() | natural_sort %} -{% if rule_config.prefix is defined and rule_config.prefix is not none %} -ip prefix-list {{ prefix_list }} seq {{ rule }} {{ rule_config.action }} {{ rule_config.prefix }} {{ 'ge ' + rule_config.ge if rule_config.ge is defined }} {{ 'le ' + rule_config.le if rule_config.le is defined }} -{% endif %} -{% endfor %} -{% endif %} -{% endfor %} -{% endif %} -! -{% if prefix_list6 is defined and prefix_list6 is not none %} -{% for prefix_list, prefix_list_config in prefix_list6.items() | natural_sort %} -{% if prefix_list_config.description is defined and prefix_list_config.description is not none %} -ipv6 prefix-list {{ prefix_list }} description {{ prefix_list_config.description }} -{% endif %} -{% if prefix_list_config.rule is defined and prefix_list_config.rule is not none %} -{% for rule, rule_config in prefix_list_config.rule.items() | natural_sort %} -{% if rule_config.prefix is defined and rule_config.prefix is not none %} -ipv6 prefix-list {{ prefix_list }} seq {{ rule }} {{ rule_config.action }} {{ rule_config.prefix }} {{ 'ge ' + rule_config.ge if rule_config.ge is defined }} {{ 'le ' + rule_config.le if rule_config.le is defined }} -{% endif %} -{% endfor %} -{% endif %} -{% endfor %} -{% endif %} -! -{% if route_map is defined and route_map is not none %} -{% for route_map, route_map_config in route_map.items() | natural_sort %} -{% if route_map_config.rule is defined and route_map_config.rule is not none %} -{% for rule, rule_config in route_map_config.rule.items() | natural_sort %} -route-map {{ route_map }} {{ rule_config.action }} {{ rule }} -{% if rule_config.call is defined and rule_config.call is not none %} - call {{ rule_config.call }} -{% endif %} -{% if rule_config.continue is defined and rule_config.continue is not none %} - on-match goto {{ rule_config.continue }} -{% endif %} -{% if rule_config.description is defined and rule_config.description is not none %} - description {{ rule_config.description }} -{% endif %} -{% if rule_config.match is defined and rule_config.match is not none %} -{% if rule_config.match.as_path is defined and rule_config.match.as_path is not none %} - match as-path {{ rule_config.match.as_path }} -{% endif %} -{% if rule_config.match.community is defined and rule_config.match.community.community_list is defined and rule_config.match.community.community_list is not none %} - match community {{ rule_config.match.community.community_list }} {{ 'exact-match' if rule_config.match.community.exact_match is defined }} -{% endif %} -{% if rule_config.match.extcommunity is defined and rule_config.match.extcommunity is not none %} - match extcommunity {{ rule_config.match.extcommunity }} -{% endif %} -{% if rule_config.match.evpn is defined and rule_config.match.evpn.default_route is defined %} - match evpn default-route -{% endif %} -{% if rule_config.match.evpn is defined and rule_config.match.evpn.rd is defined and rule_config.match.evpn.rd is not none %} - match evpn rd {{ rule_config.match.evpn.rd }} -{% endif %} -{% if rule_config.match.evpn is defined and rule_config.match.evpn.route_type is defined and rule_config.match.evpn.route_type is not none %} - match evpn route-type {{ rule_config.match.evpn.route_type }} -{% endif %} -{% if rule_config.match.evpn is defined and rule_config.match.evpn.vni is defined and rule_config.match.evpn.vni is not none %} - match evpn vni {{ rule_config.match.evpn.vni }} -{% endif %} -{% if rule_config.match.interface is defined and rule_config.match.interface is not none %} - match interface {{ rule_config.match.interface }} -{% endif %} -{% if rule_config.match.ip is defined and rule_config.match.ip.address is defined and rule_config.match.ip.address.access_list is defined and rule_config.match.ip.address.access_list is not none %} - match ip address {{ rule_config.match.ip.address.access_list }} -{% endif %} -{% if rule_config.match.ip is defined and rule_config.match.ip.address is defined and rule_config.match.ip.address.prefix_list is defined and rule_config.match.ip.address.prefix_list is not none %} - match ip address prefix-list {{ rule_config.match.ip.address.prefix_list }} -{% endif %} -{% if rule_config.match.ip is defined and rule_config.match.ip.nexthop is defined and rule_config.match.ip.nexthop.access_list is defined and rule_config.match.ip.nexthop.access_list is not none %} - match ip next-hop {{ rule_config.match.ip.nexthop.access_list }} -{% endif %} -{% if rule_config.match.ip is defined and rule_config.match.ip.nexthop is defined and rule_config.match.ip.nexthop.prefix_list is defined and rule_config.match.ip.nexthop.prefix_list is not none %} - match ip next-hop prefix-list {{ rule_config.match.ip.nexthop.prefix_list }} -{% endif %} -{% if rule_config.match.ip is defined and rule_config.match.ip.route_source is defined and rule_config.match.ip.route_source.access_list is defined and rule_config.match.ip.route_source.access_list is not none %} - match ip route-source {{ rule_config.match.ip.route_source.access_list }} -{% endif %} -{% if rule_config.match.ip is defined and rule_config.match.ip.route_source is defined and rule_config.match.ip.route_source.prefix_list is defined and rule_config.match.ip.route_source.prefix_list is not none %} - match ip route-source prefix-list {{ rule_config.match.ip.route_source.prefix_list }} -{% endif %} -{% if rule_config.match.ipv6 is defined and rule_config.match.ipv6.address is defined and rule_config.match.ipv6.address.access_list is defined and rule_config.match.ipv6.address.access_list is not none %} - match ipv6 address {{ rule_config.match.ipv6.address.access_list }} -{% endif %} -{% if rule_config.match.ipv6 is defined and rule_config.match.ipv6.address is defined and rule_config.match.ipv6.address.prefix_list is defined and rule_config.match.ipv6.address.prefix_list is not none %} - match ipv6 address prefix-list {{ rule_config.match.ipv6.address.prefix_list }} -{% endif %} -{% if rule_config.match.ipv6 is defined and rule_config.match.ipv6.nexthop is defined and rule_config.match.ipv6.nexthop is not none %} - match ipv6 next-hop {{ rule_config.match.ipv6.nexthop }} -{% endif %} -{% if rule_config.match.large_community is defined and rule_config.match.large_community.large_community_list is defined and rule_config.match.large_community.large_community_list is not none %} - match large-community {{ rule_config.match.large_community.large_community_list }} -{% endif %} -{% if rule_config.match.local_preference is defined and rule_config.match.local_preference is not none %} - match local-preference {{ rule_config.match.local_preference }} -{% endif %} -{% if rule_config.match.metric is defined and rule_config.match.metric is not none %} - match metric {{ rule_config.match.metric }} -{% endif %} -{% if rule_config.match.origin is defined and rule_config.match.origin is not none %} - match origin {{ rule_config.match.origin }} -{% endif %} -{% if rule_config.match.peer is defined and rule_config.match.peer is not none %} - match peer {{ rule_config.match.peer }} -{% endif %} -{% if rule_config.match.rpki is defined and rule_config.match.rpki is not none %} - match rpki {{ rule_config.match.rpki }} -{% endif %} -{% if rule_config.match.tag is defined and rule_config.match.tag is not none %} - match tag {{ rule_config.match.tag }} -{% endif %} -{% endif %} -{% if rule_config.on_match is defined and rule_config.on_match is not none %} -{% if rule_config.on_match.next is defined %} - on-match next -{% endif %} -{% if rule_config.on_match.goto is defined and rule_config.on_match.goto is not none %} - on-match goto {{ rule_config.on_match.goto }} -{% endif %} -{% endif %} -{% if rule_config.set is defined and rule_config.set is not none %} -{% if rule_config.set.aggregator is defined and rule_config.set.aggregator.as is defined and rule_config.set.aggregator.ip is defined %} - set aggregator as {{ rule_config.set.aggregator.as }} {{ rule_config.set.aggregator.ip }} -{% endif %} -{% if rule_config.set.as_path_exclude is defined and rule_config.set.as_path_exclude is not none %} - set as-path exclude {{ rule_config.set.as_path_exclude }} -{% endif %} -{% if rule_config.set.as_path_prepend is defined and rule_config.set.as_path_prepend is not none %} - set as-path prepend {{ rule_config.set.as_path_prepend }} -{% endif %} -{% if rule_config.set.atomic_aggregate is defined %} - set atomic-aggregate -{% endif %} -{% if rule_config.set.comm_list is defined and rule_config.set.comm_list.comm_list is defined and rule_config.set.comm_list.comm_list is not none %} - set comm-list {{ rule_config.set.comm_list.comm_list }} {{ 'delete' if rule_config.set.comm_list.delete is defined }} -{% endif %} -{% if rule_config.set.community is defined and rule_config.set.community is not none %} - set community {{ rule_config.set.community }} -{% endif %} -{% if rule_config.set.distance is defined and rule_config.set.distance is not none %} - set distance {{ rule_config.set.distance }} -{% endif %} -{% if rule_config.set.extcommunity is defined and rule_config.set.extcommunity.bandwidth is defined and rule_config.set.extcommunity.bandwidth is not none %} - set extcommunity bandwidth {{ rule_config.set.extcommunity.bandwidth }} -{% endif %} -{% if rule_config.set.extcommunity is defined and rule_config.set.extcommunity.rt is defined and rule_config.set.extcommunity.rt is not none %} - set extcommunity rt {{ rule_config.set.extcommunity.rt }} -{% endif %} -{% if rule_config.set.extcommunity is defined and rule_config.set.extcommunity.soo is defined and rule_config.set.extcommunity.soo is not none %} - set extcommunity soo {{ rule_config.set.extcommunity.soo }} -{% endif %} -{% if rule_config.set.ip_next_hop is defined and rule_config.set.ip_next_hop is not none %} - set ip next-hop {{ rule_config.set.ip_next_hop }} -{% endif %} -{% if rule_config.set.ipv6_next_hop is defined and rule_config.set.ipv6_next_hop.global is defined and rule_config.set.ipv6_next_hop.global is not none %} - set ipv6 next-hop global {{ rule_config.set.ipv6_next_hop.global }} -{% endif %} -{% if rule_config.set.ipv6_next_hop is defined and rule_config.set.ipv6_next_hop.local is defined and rule_config.set.ipv6_next_hop.local is not none %} - set ipv6 next-hop local {{ rule_config.set.ipv6_next_hop.local }} -{% endif %} -{% if rule_config.set.ipv6_next_hop is defined and rule_config.set.ipv6_next_hop.prefer_global is defined %} - set ipv6 next-hop prefer-global -{% endif %} -{% if rule_config.set.large_community is defined and rule_config.set.large_community is not none %} - set large-community {{ rule_config.set.large_community }} -{% endif %} -{% if rule_config.set.large_comm_list_delete is defined and rule_config.set.large_comm_list_delete is not none %} - set large-comm-list {{ rule_config.set.large_comm_list_delete }} delete -{% endif %} -{% if rule_config.set.local_preference is defined and rule_config.set.local_preference is not none %} - set local-preference {{ rule_config.set.local_preference }} -{% endif %} -{% if rule_config.set.metric is defined and rule_config.set.metric is not none %} - set metric {{ rule_config.set.metric }} -{% endif %} -{% if rule_config.set.metric_type is defined and rule_config.set.metric_type is not none %} - set metric-type {{ rule_config.set.metric_type }} -{% endif %} -{% if rule_config.set.origin is defined and rule_config.set.origin is not none %} - set origin {{ rule_config.set.origin }} -{% endif %} -{% if rule_config.set.originator_id is defined and rule_config.set.originator_id is not none %} - set originator-id {{ rule_config.set.originator_id }} -{% endif %} -{% if rule_config.set.src is defined and rule_config.set.src is not none %} - set src {{ rule_config.set.src }} -{% endif %} -{% if rule_config.set.table is defined and rule_config.set.table is not none %} - set table {{ rule_config.set.table }} -{% endif %} -{% if rule_config.set.tag is defined and rule_config.set.tag is not none %} - set tag {{ rule_config.set.tag }} -{% endif %} -{% if rule_config.set.weight is defined and rule_config.set.weight is not none %} - set weight {{ rule_config.set.weight }} -{% endif %} -{% endif %} -{% endfor %} -! -{% endif %} -{% endfor %} -{% endif %} -! diff --git a/data/templates/frr/rip_ripng.frr.j2 b/data/templates/frr/rip_ripng.frr.j2 index de180ee6b..dd547bb3e 100644 --- a/data/templates/frr/rip_ripng.frr.j2 +++ b/data/templates/frr/rip_ripng.frr.j2 @@ -1,36 +1,36 @@ -{% if default_information is defined and default_information.originate is defined %} +{% if default_information is vyos_defined %} default-information originate {% endif %} -{% if default_metric is defined and default_metric is not none %} +{% if default_metric is vyos_defined %} default-metric {{ default_metric }} {% endif %} -{% if passive_interface is defined and passive_interface is not none %} -{% for interface in passive_interface %} +{% if passive_interface is vyos_defined %} +{% for interface in passive_interface %} passive-interface {{ interface }} -{% endfor %} +{% endfor %} {% endif %} -{% if network is defined and network is not none %} -{% for prefix in network %} +{% if network is vyos_defined %} +{% for prefix in network %} network {{ prefix }} -{% endfor %} +{% endfor %} {% endif %} -{% if interface is defined and interface is not none %} -{% for ifname in interface %} +{% if interface is vyos_defined %} +{% for ifname in interface %} network {{ ifname }} -{% endfor %} +{% endfor %} {% endif %} -{% if route is defined and route is not none %} -{% for prefix in route %} +{% if route is vyos_defined %} +{% for prefix in route %} route {{ prefix }} -{% endfor %} +{% endfor %} {% endif %} {# timers have default values #} timers basic {{ timers['update'] }} {{ timers.timeout }} {{ timers.garbage_collection }} -{% if redistribute is defined and redistribute is not none %} -{% for protocol, protocol_config in redistribute.items() %} -{% if protocol == 'ospfv3' %} -{% set protocol = 'ospf6' %} -{% endif %} - redistribute {{ protocol }} {{ 'metric ' + protocol_config.metric if protocol_config.metric is defined }} {{ 'route-map ' + protocol_config.route_map if protocol_config.route_map is defined }} -{% endfor %} +{% if redistribute is vyos_defined %} +{% for protocol, protocol_config in redistribute.items() %} +{% if protocol is vyos_defined('ospfv3') %} +{% set protocol = 'ospf6' %} +{% endif %} + redistribute {{ protocol }} {{ 'metric ' ~ protocol_config.metric if protocol_config.metric is vyos_defined }} {{ 'route-map ' ~ protocol_config.route_map if protocol_config.route_map is vyos_defined }} +{% endfor %} {% endif %} diff --git a/data/templates/frr/ripd.frr.j2 b/data/templates/frr/ripd.frr.j2 new file mode 100644 index 000000000..df35150ca --- /dev/null +++ b/data/templates/frr/ripd.frr.j2 @@ -0,0 +1,92 @@ +{# RIP key-chain definition #} +{% if interface is vyos_defined %} +{% for iface, iface_config in interface.items() %} +{% if iface_config.authentication.md5 is vyos_defined %} +key chain {{ iface }}-rip +{% for key_id, key_options in iface_config.authentication.md5.items() %} + key {{ key_id }} +{% if key_options.password is vyos_defined %} + key-string {{ key_options.password }} +{% endif %} + exit +{% endfor %} +exit +{% endif %} +{% endfor %} +{% endif %} +! +{# Interface specific configuration #} +{% if interface is vyos_defined %} +{% for iface, iface_config in interface.items() %} +interface {{ iface }} +{% if iface_config.authentication.plaintext_password is vyos_defined %} + ip rip authentication mode text + ip rip authentication string {{ iface_config.authentication.plaintext_password }} +{% elif iface_config.authentication.md5 is vyos_defined %} + ip rip authentication key-chain {{ iface }}-rip + ip rip authentication mode md5 +{% endif %} +{% if iface_config.split_horizon.disable is vyos_defined %} + no ip rip split-horizon +{% endif %} +{% if iface_config.split_horizon.poison_reverse is vyos_defined %} + ip rip split-horizon poisoned-reverse +{% endif %} +exit +! +{% endfor %} +{% endif %} +! +router rip +{% if default_distance is vyos_defined %} + distance {{ default_distance }} +{% endif %} +{% if network_distance is vyos_defined %} +{% for network, network_config in network_distance.items() %} +{% if network_config.distance is vyos_defined %} + distance {{ network_config.distance }} {{ network }} +{% endif %} +{% endfor %} +{% endif %} +{% if neighbor is vyos_defined %} +{% for address in neighbor %} + neighbor {{ address }} +{% endfor %} +{% endif %} +{% if distribute_list is vyos_defined %} +{% if distribute_list.access_list.in is vyos_defined %} + distribute-list {{ distribute_list.access_list.in }} in +{% endif %} +{% if distribute_list.access_list.out is vyos_defined %} + distribute-list {{ distribute_list.access_list.out }} out +{% endif %} +{% if distribute_list.interface is vyos_defined %} +{% for interface, interface_config in distribute_list.interface.items() %} +{% if interface_config.access_list.in is vyos_defined %} + distribute-list {{ interface_config.access_list.in }} in {{ interface }} +{% endif %} +{% if interface_config.access_list.out is vyos_defined %} + distribute-list {{ interface_config.access_list.out }} out {{ interface }} +{% endif %} +{% if interface_config.prefix_list.in is vyos_defined %} + distribute-list prefix {{ interface_config.prefix_list.in }} in {{ interface }} +{% endif %} +{% if interface_config.prefix_list.out is vyos_defined %} + distribute-list prefix {{ interface_config.prefix_list.out }} out {{ interface }} +{% endif %} +{% endfor %} +{% endif %} +{% if distribute_list.prefix_list.in is vyos_defined %} + distribute-list prefix {{ distribute_list.prefix_list.in }} in +{% endif %} +{% if distribute_list.prefix_list.out is vyos_defined %} + distribute-list prefix {{ distribute_list.prefix_list.out }} out +{% endif %} +{% endif %} +{% include 'frr/rip_ripng.frr.j2' %} +exit +! +{% if route_map is vyos_defined %} +ip protocol rip route-map {{ route_map }} +{% endif %} +! diff --git a/data/templates/frr/ripd.frr.tmpl b/data/templates/frr/ripd.frr.tmpl deleted file mode 100644 index cabc236f0..000000000 --- a/data/templates/frr/ripd.frr.tmpl +++ /dev/null @@ -1,96 +0,0 @@ -! -{# RIP key-chain definition #} -{% if interface is defined and interface is not none %} -{% for iface, iface_config in interface.items() %} -{% if iface_config.authentication is defined and iface_config.authentication.md5 is defined and iface_config.authentication.md5 is not none %} -key chain {{ iface }}-rip -{% for key_id, key_options in iface_config.authentication.md5.items() %} - key {{ key_id }} -{% if key_options.password is defined and key_options.password is not none %} - key-string {{ key_options.password }} -{% endif %} -{% endfor %} -{% endif %} -{% endfor %} -{% endif %} -! -{# Interface specific configuration #} -{% if interface is defined and interface is not none %} -{% for iface, iface_config in interface.items() %} -interface {{ iface }} -{% if iface_config.authentication is defined and iface_config.authentication.plaintext_password is defined and iface_config.authentication.plaintext_password is not none %} - ip rip authentication mode text - ip rip authentication string {{ iface_config.authentication.plaintext_password }} -{% elif iface_config.authentication is defined and iface_config.authentication.md5 is defined and iface_config.authentication.md5 is not none %} - ip rip authentication key-chain {{ iface }}-rip - ip rip authentication mode md5 -{% endif %} -{% if iface_config.split_horizon is defined and iface_config.split_horizon.disable is defined %} - no ip rip split-horizon -{% endif %} -{% if iface_config.split_horizon is defined and iface_config.split_horizon.poison_reverse is defined %} - ip rip split-horizon poisoned-reverse -{% endif %} -{% endfor %} -{% endif %} -! -router rip -{% if default_distance is defined and default_distance is not none %} - distance {{ default_distance }} -{% endif %} -{% if network_distance is defined and network_distance is not none %} -{% for network, network_config in network_distance.items() %} -{% if network_config.distance is defined and network_config.distance is not none %} - distance {{ network_config.distance }} {{ network }} -{% endif %} -{% endfor %} -{% endif %} -{% if neighbor is defined and neighbor is not none %} -{% for address in neighbor %} - neighbor {{ address }} -{% endfor %} -{% endif %} -{% if distribute_list is defined and distribute_list is not none %} -{% if distribute_list.access_list is defined and distribute_list.access_list is not none %} -{% if distribute_list.access_list.in is defined and distribute_list.access_list.in is not none %} - distribute-list {{ distribute_list.access_list.in }} in -{% endif %} -{% if distribute_list.access_list.out is defined and distribute_list.access_list.out is not none %} - distribute-list {{ distribute_list.access_list.out }} out -{% endif %} -{% endif %} -{% if distribute_list.interface is defined and distribute_list.interface is not none %} -{% for interface, interface_config in distribute_list.interface.items() %} -{% if interface_config.access_list is defined and interface_config.access_list is not none %} -{% if interface_config.access_list.in is defined and interface_config.access_list.in is not none %} - distribute-list {{ interface_config.access_list.in }} in {{ interface }} -{% endif %} -{% if interface_config.access_list.out is defined and interface_config.access_list.out is not none %} - distribute-list {{ interface_config.access_list.out }} out {{ interface }} -{% endif %} -{% endif %} -{% if interface_config.prefix_list is defined and interface_config.prefix_list is not none %} -{% if interface_config.prefix_list.in is defined and interface_config.prefix_list.in is not none %} - distribute-list prefix {{ interface_config.prefix_list.in }} in {{ interface }} -{% endif %} -{% if interface_config.prefix_list.out is defined and interface_config.prefix_list.out is not none %} - distribute-list prefix {{ interface_config.prefix_list.out }} out {{ interface }} -{% endif %} -{% endif %} -{% endfor %} -{% endif %} -{% if distribute_list.prefix_list is defined and distribute_list.prefix_list is not none %} -{% if distribute_list.prefix_list.in is defined and distribute_list.prefix_list.in is not none %} - distribute-list prefix {{ distribute_list.prefix_list.in }} in -{% endif %} -{% if distribute_list.prefix_list.out is defined and distribute_list.prefix_list.out is not none %} - distribute-list prefix {{ distribute_list.prefix_list.out }} out -{% endif %} -{% endif %} -{% endif %} -{% include 'frr/rip_ripng.frr.j2' %} -! -{% if route_map is defined and route_map is not none %} -ip protocol rip route-map {{ route_map }} -{% endif %} -! diff --git a/data/templates/frr/ripngd.frr.j2 b/data/templates/frr/ripngd.frr.j2 new file mode 100644 index 000000000..7919b1bad --- /dev/null +++ b/data/templates/frr/ripngd.frr.j2 @@ -0,0 +1,57 @@ +{# Interface specific configuration #} +{% if interface is vyos_defined %} +{% for iface, iface_config in interface.items() %} +interface {{ iface }} +{% if iface_config.split_horizon.disable is vyos_defined %} + no ipv6 rip split-horizon +{% endif %} +{% if iface_config.split_horizon.poison_reverse is vyos_defined %} + ipv6 rip split-horizon poisoned-reverse +{% endif %} +exit +{% endfor %} +{% endif %} +! +router ripng +{% if aggregate_address is vyos_defined %} +{% for prefix in aggregate_address %} + aggregate-address {{ prefix }} +{% endfor %} +{% endif %} +{% if distribute_list is vyos_defined %} +{% if distribute_list.access_list.in is vyos_defined %} + ipv6 distribute-list {{ distribute_list.access_list.in }} in +{% endif %} +{% if distribute_list.access_list.out is vyos_defined %} + ipv6 distribute-list {{ distribute_list.access_list.out }} out +{% endif %} +{% if distribute_list.interface is vyos_defined %} +{% for interface, interface_config in distribute_list.interface.items() %} +{% if interface_config.access_list.in is vyos_defined %} + ipv6 distribute-list {{ interface_config.access_list.in }} in {{ interface }} +{% endif %} +{% if interface_config.access_list.out is vyos_defined %} + ipv6 distribute-list {{ interface_config.access_list.out }} out {{ interface }} +{% endif %} +{% if interface_config.prefix_list.in is vyos_defined %} + ipv6 distribute-list prefix {{ interface_config.prefix_list.in }} in {{ interface }} +{% endif %} +{% if interface_config.prefix_list.out is vyos_defined %} + ipv6 distribute-list prefix {{ interface_config.prefix_list.out }} out {{ interface }} +{% endif %} +{% endfor %} +{% endif %} +{% if distribute_list.prefix_list.in is vyos_defined %} + ipv6 distribute-list prefix {{ distribute_list.prefix_list.in }} in +{% endif %} +{% if distribute_list.prefix_list.out is vyos_defined %} + ipv6 distribute-list prefix {{ distribute_list.prefix_list.out }} out +{% endif %} +{% endif %} +{% include 'frr/rip_ripng.frr.j2' %} +exit +! +{% if route_map is vyos_defined %} +ipv6 protocol ripng route-map {{ route_map }} +{% endif %} +! diff --git a/data/templates/frr/ripngd.frr.tmpl b/data/templates/frr/ripngd.frr.tmpl deleted file mode 100644 index 25df15121..000000000 --- a/data/templates/frr/ripngd.frr.tmpl +++ /dev/null @@ -1,60 +0,0 @@ -! -{# Interface specific configuration #} -{% if interface is defined and interface is not none %} -{% for iface, iface_config in interface.items() %} -interface {{ iface }} -{% if iface_config.split_horizon is defined and iface_config.split_horizon.disable is defined %} - no ipv6 rip split-horizon -{% endif %} -{% if iface_config.split_horizon is defined and iface_config.split_horizon.poison_reverse is defined %} - ipv6 rip split-horizon poisoned-reverse -{% endif %} -{% endfor %} -{% endif %} -! -router ripng -{% if aggregate_address is defined and aggregate_address is not none %} -{% for prefix in aggregate_address %} - aggregate-address {{ prefix }} -{% endfor %} -{% endif %} -{% if distribute_list is defined and distribute_list is not none %} -{% if distribute_list.access_list is defined and distribute_list.access_list is not none %} -{% if distribute_list.access_list.in is defined and distribute_list.access_list.in is not none %} - ipv6 distribute-list {{ distribute_list.access_list.in }} in -{% endif %} -{% if distribute_list.access_list.out is defined and distribute_list.access_list.out is not none %} - ipv6 distribute-list {{ distribute_list.access_list.out }} out -{% endif %} -{% endif %} -{% if distribute_list.interface is defined and distribute_list.interface is not none %} -{% for interface, interface_config in distribute_list.interface.items() %} -{% if interface_config.access_list is defined and interface_config.access_list is not none %} -{% if interface_config.access_list.in is defined and interface_config.access_list.in is not none %} - ipv6 distribute-list {{ interface_config.access_list.in }} in {{ interface }} -{% endif %} -{% if interface_config.access_list.out is defined and interface_config.access_list.out is not none %} - ipv6 distribute-list {{ interface_config.access_list.out }} out {{ interface }} -{% endif %} -{% endif %} -{% if interface_config.prefix_list is defined and interface_config.prefix_list is not none %} -{% if interface_config.prefix_list.in is defined and interface_config.prefix_list.in is not none %} - ipv6 distribute-list prefix {{ interface_config.prefix_list.in }} in {{ interface }} -{% endif %} -{% if interface_config.prefix_list.out is defined and interface_config.prefix_list.out is not none %} - ipv6 distribute-list prefix {{ interface_config.prefix_list.out }} out {{ interface }} -{% endif %} -{% endif %} -{% endfor %} -{% endif %} -{% if distribute_list.prefix_list is defined and distribute_list.prefix_list is not none %} -{% if distribute_list.prefix_list.in is defined and distribute_list.prefix_list.in is not none %} - ipv6 distribute-list prefix {{ distribute_list.prefix_list.in }} in -{% endif %} -{% if distribute_list.prefix_list.out is defined and distribute_list.prefix_list.out is not none %} - ipv6 distribute-list prefix {{ distribute_list.prefix_list.out }} out -{% endif %} -{% endif %} -{% endif %} -{% include 'frr/rip_ripng.frr.j2' %} -! diff --git a/data/templates/frr/rpki.frr.tmpl b/data/templates/frr/rpki.frr.j2 index fbdfa27c3..9a549d6de 100644 --- a/data/templates/frr/rpki.frr.tmpl +++ b/data/templates/frr/rpki.frr.j2 @@ -1,17 +1,18 @@ ! {# as FRR does not support deleting the entire rpki section we leave it in place even when it's empty #} rpki -{% if cache is defined and cache is not none %} -{% for peer, peer_config in cache.items() %} -{# port is mandatory and preference uses a default value #} -{% if peer_config.ssh is defined and peer_config.ssh.username is defined and peer_config.ssh.username is not none %} +{% if cache is vyos_defined %} +{% for peer, peer_config in cache.items() %} +{# port is mandatory and preference uses a default value #} +{% if peer_config.ssh.username is vyos_defined %} rpki cache {{ peer | replace('_', '-') }} {{ peer_config.port }} {{ peer_config.ssh.username }} {{ peer_config.ssh.private_key_file }} {{ peer_config.ssh.public_key_file }} {{ peer_config.ssh.known_hosts_file }} preference {{ peer_config.preference }} -{% else %} +{% else %} rpki cache {{ peer | replace('_', '-') }} {{ peer_config.port }} preference {{ peer_config.preference }} -{% endif %} -{% endfor %} +{% endif %} +{% endfor %} {% endif %} -{% if polling_period is defined and polling_period is not none %} +{% if polling_period is vyos_defined %} rpki polling_period {{ polling_period }} {% endif %} +exit ! diff --git a/data/templates/frr/static_mcast.frr.tmpl b/data/templates/frr/static_mcast.frr.j2 index 4f114109a..491d4b54a 100644 --- a/data/templates/frr/static_mcast.frr.tmpl +++ b/data/templates/frr/static_mcast.frr.j2 @@ -1,20 +1,20 @@ ! {% for route_gr in old_mroute %} -{% for nh in old_mroute[route_gr] %} -{% if old_mroute[route_gr][nh] %} +{% for nh in old_mroute[route_gr] %} +{% if old_mroute[route_gr][nh] %} no ip mroute {{ route_gr }} {{ nh }} {{ old_mroute[route_gr][nh] }} -{% else %} +{% else %} no ip mroute {{ route_gr }} {{ nh }} -{% endif %} -{% endfor %} +{% endif %} +{% endfor %} {% endfor %} {% for route_gr in mroute %} -{% for nh in mroute[route_gr] %} -{% if mroute[route_gr][nh] %} +{% for nh in mroute[route_gr] %} +{% if mroute[route_gr][nh] %} ip mroute {{ route_gr }} {{ nh }} {{ mroute[route_gr][nh] }} -{% else %} +{% else %} ip mroute {{ route_gr }} {{ nh }} -{% endif %} -{% endfor %} +{% endif %} +{% endfor %} {% endfor %} ! diff --git a/data/templates/frr/static_routes_macro.j2 b/data/templates/frr/static_routes_macro.j2 index 3b432b49b..1c64ac58b 100644 --- a/data/templates/frr/static_routes_macro.j2 +++ b/data/templates/frr/static_routes_macro.j2 @@ -1,21 +1,24 @@ {% macro static_routes(ip_ipv6, prefix, prefix_config, table=None) %} -{% if prefix_config.blackhole is defined %} -{{ ip_ipv6 }} route {{ prefix }} blackhole {{ prefix_config.blackhole.distance if prefix_config.blackhole.distance is defined }} {{ 'tag ' + prefix_config.blackhole.tag if prefix_config.blackhole.tag is defined }} {{ 'table ' + table if table is defined and table is not none }} -{% endif %} -{% if prefix_config.dhcp_interface is defined and prefix_config.dhcp_interface is not none %} +{% if prefix_config.blackhole is vyos_defined %} +{{ ip_ipv6 }} route {{ prefix }} blackhole {{ prefix_config.blackhole.distance if prefix_config.blackhole.distance is vyos_defined }} {{ 'tag ' ~ prefix_config.blackhole.tag if prefix_config.blackhole.tag is vyos_defined }} {{ 'table ' ~ table if table is vyos_defined and table is not none }} +{% endif %} +{% if prefix_config.reject is vyos_defined %} +{{ ip_ipv6 }} route {{ prefix }} reject {{ prefix_config.reject.distance if prefix_config.reject.distance is vyos_defined }} {{ 'tag ' ~ prefix_config.reject.tag if prefix_config.reject.tag is vyos_defined }} {{ 'table ' ~ table if table is vyos_defined }} +{% endif %} +{% if prefix_config.dhcp_interface is vyos_defined %} {% set next_hop = prefix_config.dhcp_interface | get_dhcp_router %} -{% if next_hop is defined and next_hop is not none %} -{{ ip_ipv6 }} route {{ prefix }} {{ next_hop }} {{ prefix_config.dhcp_interface }} +{% if next_hop is vyos_defined %} +{{ ip_ipv6 }} route {{ prefix }} {{ next_hop }} {{ prefix_config.dhcp_interface }} {{ 'table ' ~ table if table is vyos_defined }} {% endif %} -{% endif %} -{% if prefix_config.interface is defined and prefix_config.interface is not none %} +{% endif %} +{% if prefix_config.interface is vyos_defined %} {% for interface, interface_config in prefix_config.interface.items() if interface_config.disable is not defined %} -{{ ip_ipv6 }} route {{ prefix }} {{ interface }} {{ interface_config.distance if interface_config.distance is defined }} {{ 'nexthop-vrf ' + interface_config.vrf if interface_config.vrf is defined }} {{ 'table ' + table if table is defined and table is not none }} +{{ ip_ipv6 }} route {{ prefix }} {{ interface }} {{ interface_config.distance if interface_config.distance is vyos_defined }} {{ 'nexthop-vrf ' ~ interface_config.vrf if interface_config.vrf is vyos_defined }} {{ 'table ' ~ table if table is vyos_defined }} {% endfor %} -{% endif %} -{% if prefix_config.next_hop is defined and prefix_config.next_hop is not none %} +{% endif %} +{% if prefix_config.next_hop is vyos_defined and prefix_config.next_hop is not none %} {% for next_hop, next_hop_config in prefix_config.next_hop.items() if next_hop_config.disable is not defined %} -{{ ip_ipv6 }} route {{ prefix }} {{ next_hop }} {{ next_hop_config.interface if next_hop_config.interface is defined }} {{ next_hop_config.distance if next_hop_config.distance is defined }} {{ 'nexthop-vrf ' + next_hop_config.vrf if next_hop_config.vrf is defined }} {{ 'table ' + table if table is defined and table is not none }} +{{ ip_ipv6 }} route {{ prefix }} {{ next_hop }} {{ next_hop_config.interface if next_hop_config.interface is vyos_defined }} {{ next_hop_config.distance if next_hop_config.distance is vyos_defined }} {{ 'nexthop-vrf ' ~ next_hop_config.vrf if next_hop_config.vrf is vyos_defined }} {{ 'table ' ~ table if table is vyos_defined }} {% endfor %} -{% endif %} +{% endif %} {% endmacro %} diff --git a/data/templates/frr/staticd.frr.j2 b/data/templates/frr/staticd.frr.j2 new file mode 100644 index 000000000..589f03c2c --- /dev/null +++ b/data/templates/frr/staticd.frr.j2 @@ -0,0 +1,64 @@ +{% from 'frr/static_routes_macro.j2' import static_routes %} +! +{% set ip_prefix = 'ip' %} +{% set ipv6_prefix = 'ipv6' %} +{% if vrf is vyos_defined %} +{# We need to add an additional whitespace in front of the prefix #} +{# when VRFs are in use, thus we use a variable for prefix handling #} +{% set ip_prefix = ' ip' %} +{% set ipv6_prefix = ' ipv6' %} +vrf {{ vrf }} +{% endif %} +{# IPv4 routing #} +{% if route is vyos_defined %} +{% for prefix, prefix_config in route.items() %} +{{ static_routes(ip_prefix, prefix, prefix_config) }} +{% endfor %} +{% endif %} +{# IPv4 default routes from DHCP interfaces #} +{% if dhcp is vyos_defined %} +{% for interface, interface_config in dhcp.items() %} +{% set next_hop = interface | get_dhcp_router %} +{% if next_hop is vyos_defined %} +{{ ip_prefix }} route 0.0.0.0/0 {{ next_hop }} {{ interface }} tag 210 {{ interface_config.dhcp_options.default_route_distance if interface_config.dhcp_options.default_route_distance is vyos_defined }} +{% endif %} +{% endfor %} +{% endif %} +{# IPv4 default routes from PPPoE interfaces #} +{% if pppoe is vyos_defined %} +{% for interface, interface_config in pppoe.items() %} +{{ ip_prefix }} route 0.0.0.0/0 {{ interface }} tag 210 {{ interface_config.default_route_distance if interface_config.default_route_distance is vyos_defined }} +{% endfor %} +{% endif %} +{# IPv6 routing #} +{% if route6 is vyos_defined %} +{% for prefix, prefix_config in route6.items() %} +{{ static_routes(ipv6_prefix, prefix, prefix_config) }} +{% endfor %} +{% endif %} +{% if vrf is vyos_defined %} + exit-vrf +{% endif %} +! +{# Policy route tables #} +{% if table is vyos_defined %} +{% for table_id, table_config in table.items() %} +{% if table_config.route is vyos_defined %} +{% for prefix, prefix_config in table_config.route.items() %} +{{ static_routes('ip', prefix, prefix_config, table_id) }} +{% endfor %} +{% endif %} +! +{% if table_config.route6 is vyos_defined %} +{% for prefix, prefix_config in table_config.route6.items() %} +{{ static_routes('ipv6', prefix, prefix_config, table_id) }} +{% endfor %} +{% endif %} +! +{% endfor %} +{% endif %} +! +{% if route_map is vyos_defined %} +ip protocol static route-map {{ route_map }} +! +{% endif %} diff --git a/data/templates/frr/staticd.frr.tmpl b/data/templates/frr/staticd.frr.tmpl deleted file mode 100644 index bfe959c1d..000000000 --- a/data/templates/frr/staticd.frr.tmpl +++ /dev/null @@ -1,58 +0,0 @@ -{% from 'frr/static_routes_macro.j2' import static_routes %} -! -{% set ip_prefix = 'ip' %} -{% set ipv6_prefix = 'ipv6' %} -{% if vrf is defined and vrf is not none %} -{# We need to add an additional whitespace in front of the prefix #} -{# when VRFs are in use, thus we use a variable for prefix handling #} -{% set ip_prefix = ' ip' %} -{% set ipv6_prefix = ' ipv6' %} -vrf {{ vrf }} -{% endif %} -{# IPv4 routing #} -{% if route is defined and route is not none %} -{% for prefix, prefix_config in route.items() %} -{{ static_routes(ip_prefix, prefix, prefix_config) }} -{%- endfor -%} -{% endif %} -{# IPv4 default routes from DHCP interfaces #} -{% if dhcp is defined and dhcp is not none %} -{% for interface in dhcp %} -{% set next_hop = interface | get_dhcp_router %} -{% if next_hop is defined and next_hop is not none %} -{{ ip_prefix }} route 0.0.0.0/0 {{ next_hop }} {{ interface }} tag 210 210 -{% endif %} -{% endfor %} -{% endif %} -{# IPv6 routing #} -{% if route6 is defined and route6 is not none %} -{% for prefix, prefix_config in route6.items() %} -{{ static_routes(ipv6_prefix, prefix, prefix_config) }} -{%- endfor -%} -{% endif %} -{% if vrf is defined and vrf is not none %} - exit-vrf -{% endif %} -! -{# Policy route tables #} -{% if table is defined and table is not none %} -{% for table_id, table_config in table.items() %} -{% if table_config.route is defined and table_config.route is not none %} -{% for prefix, prefix_config in table_config.route.items() %} -{{ static_routes('ip', prefix, prefix_config, table_id) }} -{%- endfor -%} -{% endif %} -! -{% if table_config.route6 is defined and table_config.route6 is not none %} -{% for prefix, prefix_config in table_config.route6.items() %} -{{ static_routes('ipv6', prefix, prefix_config, table_id) }} -{%- endfor -%} -{% endif %} -! -{% endfor %} -{% endif %} -! -{% if route_map is defined and route_map is not none %} -ip protocol static route-map {{ route_map }} -! -{% endif %} diff --git a/data/templates/frr/vrf-vni.frr.j2 b/data/templates/frr/vrf-vni.frr.j2 new file mode 100644 index 000000000..e5f4810a1 --- /dev/null +++ b/data/templates/frr/vrf-vni.frr.j2 @@ -0,0 +1,9 @@ +{% if name is vyos_defined %} +{% for vrf, vrf_config in name.items() %} +vrf {{ vrf }} +{% if vrf_config.vni is vyos_defined %} + vni {{ vrf_config.vni }} +{% endif %} + exit-vrf +{% endfor %} +{% endif %} diff --git a/data/templates/frr/vrf-vni.frr.tmpl b/data/templates/frr/vrf-vni.frr.tmpl deleted file mode 100644 index 299c9719e..000000000 --- a/data/templates/frr/vrf-vni.frr.tmpl +++ /dev/null @@ -1,9 +0,0 @@ -{% if name is defined and name is not none %} -{% for vrf, vrf_config in name.items() %} -vrf {{ vrf }} -{% if vrf_config.vni is defined and vrf_config.vni is not none %} - vni {{ vrf_config.vni }} -{% endif %} - exit-vrf -{% endfor %} -{% endif %} diff --git a/data/templates/frr/vrf.route-map.frr.j2 b/data/templates/frr/vrf.route-map.frr.j2 new file mode 100644 index 000000000..5e0c56a7b --- /dev/null +++ b/data/templates/frr/vrf.route-map.frr.j2 @@ -0,0 +1,10 @@ +! +{% if vrf is vyos_defined and route_map is vyos_defined %} +vrf {{ vrf }} + ip protocol {{ protocol }} route-map {{ route_map }} + exit-vrf +! +{% elif route_map is vyos_defined %} +ip protocol {{ protocol }} route-map {{ route_map }} +{% endif %} +! diff --git a/data/templates/frr/vrf.route-map.frr.tmpl b/data/templates/frr/vrf.route-map.frr.tmpl deleted file mode 100644 index cb0e07616..000000000 --- a/data/templates/frr/vrf.route-map.frr.tmpl +++ /dev/null @@ -1,10 +0,0 @@ -! -{% if vrf is defined and vrf is not none and route_map is defined and route_map is not none %} -vrf {{ vrf }} - ip protocol {{ protocol }} route-map {{ route_map }} - exit-vrf -! -{% elif route_map is defined and route_map is not none %} -ip protocol {{ protocol }} route-map {{ route_map }} -{% endif %} -! diff --git a/data/templates/getty/serial-getty.service.tmpl b/data/templates/getty/serial-getty.service.j2 index 0183eae7d..0183eae7d 100644 --- a/data/templates/getty/serial-getty.service.tmpl +++ b/data/templates/getty/serial-getty.service.j2 diff --git a/data/templates/high-availability/keepalived.conf.j2 b/data/templates/high-availability/keepalived.conf.j2 new file mode 100644 index 000000000..6684dbc2c --- /dev/null +++ b/data/templates/high-availability/keepalived.conf.j2 @@ -0,0 +1,169 @@ +# Autogenerated by VyOS +# Do not edit this file, all your changes will be lost +# on next commit or reboot + +global_defs { + dynamic_interfaces + script_user root + notify_fifo /run/keepalived/keepalived_notify_fifo + notify_fifo_script /usr/libexec/vyos/system/keepalived-fifo.py +} + +{% if vrrp.group is vyos_defined %} +{% for name, group_config in vrrp.group.items() if group_config.disable is not vyos_defined %} +{% if group_config.health_check.script is vyos_defined %} +vrrp_script healthcheck_{{ name }} { + script "{{ group_config.health_check.script }}" + interval {{ group_config.health_check.interval }} + fall {{ group_config.health_check.failure_count }} + rise 1 +} +{% endif %} +vrrp_instance {{ name }} { +{% if group_config.description is vyos_defined %} + # {{ group_config.description }} +{% endif %} + state BACKUP + interface {{ group_config.interface }} + virtual_router_id {{ group_config.vrid }} + priority {{ group_config.priority }} + advert_int {{ group_config.advertise_interval }} +{% if group_config.track.exclude_vrrp_interface is vyos_defined %} + dont_track_primary +{% endif %} +{% if group_config.no_preempt is not vyos_defined and group_config.preempt_delay is vyos_defined %} + preempt_delay {{ group_config.preempt_delay }} +{% elif group_config.no_preempt is vyos_defined %} + nopreempt +{% endif %} +{% if group_config.peer_address is vyos_defined %} + unicast_peer { {{ group_config.peer_address }} } +{% endif %} +{% if group_config.hello_source_address is vyos_defined %} +{% if group_config.peer_address is vyos_defined %} + unicast_src_ip {{ group_config.hello_source_address }} +{% else %} + mcast_src_ip {{ group_config.hello_source_address }} +{% endif %} +{% endif %} +{% if group_config.rfc3768_compatibility is vyos_defined and group_config.peer_address is vyos_defined %} + use_vmac {{ group_config.interface }}v{{ group_config.vrid }} + vmac_xmit_base +{% elif group_config.rfc3768_compatibility is vyos_defined %} + use_vmac {{ group_config.interface }}v{{ group_config.vrid }} +{% endif %} +{% if group_config.authentication is vyos_defined %} + authentication { + auth_pass "{{ group_config.authentication.password }}" +{% if group_config.authentication.type is vyos_defined('plaintext-password') %} + auth_type PASS +{% else %} + auth_type {{ group_config.authentication.type | upper }} +{% endif %} + } +{% endif %} +{% if group_config.address is vyos_defined %} + virtual_ipaddress { +{% for addr, addr_config in group_config.address.items() %} + {{ addr }}{{ ' dev ' + addr_config.interface if addr_config.interface is vyos_defined }} +{% endfor %} + } +{% endif %} +{% if group_config.excluded_address is vyos_defined %} + virtual_ipaddress_excluded { +{% for addr in group_config.excluded_address %} + {{ addr }} +{% endfor %} + } +{% endif %} +{% if group_config.track.interface is vyos_defined %} + track_interface { +{% for interface in group_config.track.interface %} + {{ interface }} +{% endfor %} + } +{% endif %} +{% if group_config.health_check.script is vyos_defined %} + track_script { + healthcheck_{{ name }} + } +{% endif %} +} +{% endfor %} +{% endif %} + +{% if vrrp.sync_group is vyos_defined %} +{% for name, sync_group_config in vrrp.sync_group.items() if sync_group_config.disable is not vyos_defined %} +vrrp_sync_group {{ name }} { + group { +{% if sync_group_config.member is vyos_defined %} +{% for member in sync_group_config.member %} + {{ member }} +{% endfor %} +{% endif %} + } + +{# Health-check scripts should be in section sync-group if member is part of the sync-group T4081 #} +{% if vrrp.group is vyos_defined %} +{% for name, group_config in vrrp.group.items() if group_config.disable is not vyos_defined %} +{% if group_config.health_check.script is vyos_defined and name in sync_group_config.member %} + track_script { + healthcheck_{{ name }} + } +{% endif %} +{% endfor %} +{% endif %} +{% if conntrack_sync_group is vyos_defined(name) %} +{% set vyos_helper = "/usr/libexec/vyos/vyos-vrrp-conntracksync.sh" %} + notify_master "{{ vyos_helper }} master {{ name }}" + notify_backup "{{ vyos_helper }} backup {{ name }}" + notify_fault "{{ vyos_helper }} fault {{ name }}" +{% endif %} +} +{% endfor %} +{% endif %} + +{% if virtual_server is vyos_defined %} +# Virtual-server configuration +{% for vserver, vserver_config in virtual_server.items() %} +virtual_server {{ vserver }} {{ vserver_config.port }} { + delay_loop {{ vserver_config.delay_loop }} +{% if vserver_config.algorithm is vyos_defined('round-robin') %} + lb_algo rr +{% elif vserver_config.algorithm is vyos_defined('weighted-round-robin') %} + lb_algo wrr +{% elif vserver_config.algorithm is vyos_defined('least-connection') %} + lb_algo lc +{% elif vserver_config.algorithm is vyos_defined('weighted-least-connection') %} + lb_algo wlc +{% elif vserver_config.algorithm is vyos_defined('source-hashing') %} + lb_algo sh +{% elif vserver_config.algorithm is vyos_defined('destination-hashing') %} + lb_algo dh +{% elif vserver_config.algorithm is vyos_defined('locality-based-least-connection') %} + lb_algo lblc +{% endif %} +{% if vserver_config.forward_method is vyos_defined('nat') %} + lb_kind NAT +{% elif vserver_config.forward_method is vyos_defined('direct') %} + lb_kind DR +{% elif vserver_config.forward_method is vyos_defined('tunnel') %} + lb_kind TUN +{% endif %} + persistence_timeout {{ vserver_config.persistence_timeout }} + protocol {{ vserver_config.protocol | upper }} +{% if vserver_config.real_server is vyos_defined %} +{% for rserver, rserver_config in vserver_config.real_server.items() %} + real_server {{ rserver }} {{ rserver_config.port }} { + weight 1 + {{ vserver_config.protocol | upper }}_CHECK { +{% if rserver_config.connection_timeout is vyos_defined %} + connect_timeout {{ rserver_config.connection_timeout }} +{% endif %} + } + } +{% endfor %} +{% endif %} +} +{% endfor %} +{% endif %} diff --git a/data/templates/https/nginx.default.tmpl b/data/templates/https/nginx.default.j2 index 9d73baeee..70e62ae7a 100644 --- a/data/templates/https/nginx.default.tmpl +++ b/data/templates/https/nginx.default.j2 @@ -1,74 +1,56 @@ ### Autogenerated by https.py ### # Default server configuration -# -server { - listen 80 default_server; - listen [::]:80 default_server; - server_name _; - return 301 https://$host$request_uri; -} {% for server in server_block_list %} server { - # SSL configuration # -{% if server.address == '*' %} +{% if server.address == '*' %} listen {{ server.port }} ssl; listen [::]:{{ server.port }} ssl; -{% else %} +{% else %} listen {{ server.address | bracketize_ipv6 }}:{{ server.port }} ssl; -{% endif %} +{% endif %} -{% for name in server.name %} +{% for name in server.name %} server_name {{ name }}; -{% endfor %} +{% endfor %} -{% if server.certbot %} +{% if server.certbot %} ssl_certificate {{ server.certbot_dir }}/live/{{ server.certbot_domain_dir }}/fullchain.pem; ssl_certificate_key {{ server.certbot_dir }}/live/{{ server.certbot_domain_dir }}/privkey.pem; include {{ server.certbot_dir }}/options-ssl-nginx.conf; ssl_dhparam {{ server.certbot_dir }}/ssl-dhparams.pem; -{% elif server.vyos_cert %} +{% elif server.vyos_cert %} ssl_certificate {{ server.vyos_cert.crt }}; ssl_certificate_key {{ server.vyos_cert.key }}; -{% else %} +{% else %} # # Self signed certs generated by the ssl-cert package # Don't use them in a production server! # include snippets/snakeoil.conf; -{% endif %} +{% 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|docs|openapi.json|redoc|graphql) { -{% if server.api %} +{% if server.api %} +{% if server.api.socket %} + proxy_pass http://unix:/run/api.sock; +{% else %} proxy_pass http://localhost:{{ server.api.port }}; +{% endif %} proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_read_timeout 600; proxy_buffering off; -{% else %} +{% else %} return 503; -{% endif %} +{% endif %} } error_page 497 =301 https://$host:{{ server.port }}$request_uri; - error_page 501 502 503 =200 @50*_json; - -{% if api_set %} - location @50*_json { - default_type application/json; - return 200 '{"error": "service https api unavailable at this proxy address: set service https api-restrict virtual-host"}'; - } -{% else %} - location @50*_json { - default_type application/json; - return 200 '{"error": "Start service in configuration mode: set service https api"}'; - } -{% endif %} - } {% endfor %} diff --git a/data/templates/https/override.conf.j2 b/data/templates/https/override.conf.j2 new file mode 100644 index 000000000..c2c191b06 --- /dev/null +++ b/data/templates/https/override.conf.j2 @@ -0,0 +1,15 @@ +{% set vrf_command = 'ip vrf exec ' ~ vrf ~ ' ' if vrf is vyos_defined else '' %} +[Unit] +StartLimitIntervalSec=0 +After=vyos-router.service + +[Service] +ExecStartPre= +ExecStartPre={{ vrf_command }}/usr/sbin/nginx -t -q -g 'daemon on; master_process on;' +ExecStart= +ExecStart={{ vrf_command }}/usr/sbin/nginx -g 'daemon on; master_process on;' +ExecReload= +ExecReload={{ vrf_command }}/usr/sbin/nginx -g 'daemon on; master_process on;' -s reload +Restart=always +RestartPreventExitStatus= +RestartSec=10 diff --git a/data/templates/https/vyos-http-api.service.j2 b/data/templates/https/vyos-http-api.service.j2 new file mode 100644 index 000000000..fb424e06c --- /dev/null +++ b/data/templates/https/vyos-http-api.service.j2 @@ -0,0 +1,22 @@ +{% set vrf_command = 'ip vrf exec ' ~ vrf ~ ' ' if vrf is vyos_defined else '' %} +[Unit] +Description=VyOS HTTP API service +After=vyos-router.service +Requires=vyos-router.service + +[Service] +ExecStart={{ vrf_command }}/usr/libexec/vyos/services/vyos-http-api-server +Type=idle + +SyslogIdentifier=vyos-http-api +SyslogFacility=daemon + +Restart=on-failure + +# Does't work but leave it here +User=root +Group=vyattacfg + +[Install] +WantedBy=vyos.target + diff --git a/data/templates/ids/fastnetmon.tmpl b/data/templates/ids/fastnetmon.j2 index 1f6a1c808..c482002fa 100644 --- a/data/templates/ids/fastnetmon.tmpl +++ b/data/templates/ids/fastnetmon.j2 @@ -25,36 +25,32 @@ unban_only_if_attack_finished = on # For each subnet, list track speed in bps and pps for both directions enable_subnet_counters = off -{% if "mirror" in mode %} +{% if mode.mirror is vyos_defined %} mirror_afpacket = on {% endif %} -{% if "in" in direction %} -process_incoming_traffic = on -{% endif %} -{% if "out" in direction %} -process_outgoing_traffic = on -{% endif %} -{% for th in threshold %} -{% if th == "fps" %} +process_incoming_traffic = {{ 'on' if direction is vyos_defined and 'in' in direction else 'off' }} +process_outgoing_traffic = {{ 'on' if direction is vyos_defined and 'out' in direction else 'off' }} + +{% if threshold is vyos_defined %} +{% for thr, thr_value in threshold.items() %} +{% if thr is vyos_defined('fps') %} ban_for_flows = on -threshold_flows = {{ threshold[th] }} -{% endif %} -{% if th == "mbps" %} +threshold_flows = {{ thr_value }} +{% elif thr is vyos_defined('mbps') %} ban_for_bandwidth = on -threshold_mbps = {{ threshold[th] }} -{% endif %} -{% if th == "pps" %} +threshold_mbps = {{ thr_value }} +{% elif thr is vyos_defined('pps') %} ban_for_pps = on -threshold_pps = {{ threshold[th] }} +threshold_pps = {{ thr_value }} +{% endif %} +{% endfor %} {% endif %} -{% endfor %} -{% if listen_interface %} -{% set value = listen_interface if listen_interface is string else listen_interface | join(',') %} -interfaces = {{ value }} +{% if listen_interface is vyos_defined %} +interfaces = {{ listen_interface | join(',') }} {% endif %} -{% if alert_script %} +{% if alert_script is vyos_defined %} notify_script_path = {{ alert_script }} {% endif %} diff --git a/data/templates/ids/fastnetmon_networks_list.j2 b/data/templates/ids/fastnetmon_networks_list.j2 new file mode 100644 index 000000000..1c81180be --- /dev/null +++ b/data/templates/ids/fastnetmon_networks_list.j2 @@ -0,0 +1,7 @@ +{% if network is vyos_defined(var_type=str) %} +{{ network }} +{% else %} +{% for net in network %} +{{ net }} +{% endfor %} +{% endif %} diff --git a/data/templates/ids/fastnetmon_networks_list.tmpl b/data/templates/ids/fastnetmon_networks_list.tmpl deleted file mode 100644 index d58990053..000000000 --- a/data/templates/ids/fastnetmon_networks_list.tmpl +++ /dev/null @@ -1,7 +0,0 @@ -{% if network is string %} -{{ network }} -{% else %} -{% for net in network %} -{{ net }} -{% endfor %} -{% endif %} diff --git a/data/templates/igmp-proxy/igmpproxy.conf.tmpl b/data/templates/igmp-proxy/igmpproxy.conf.j2 index e3966def3..ab3c9fd31 100644 --- a/data/templates/igmp-proxy/igmpproxy.conf.tmpl +++ b/data/templates/igmp-proxy/igmpproxy.conf.j2 @@ -14,27 +14,27 @@ # ######################################################## -{% if disable_quickleave is not defined %} +{% if disable_quickleave is not vyos_defined %} quickleave {% endif %} -{% if interface is defined and interface is not none %} -{% for iface, config in interface.items() %} +{% if interface is vyos_defined %} +{% for iface, config in interface.items() %} # Configuration for {{ iface }} ({{ config.role }} interface) -{% if config.role == 'disabled' %} +{% if config.role is vyos_defined('disabled') %} phyint {{ iface }} disabled -{% else %} +{% else %} phyint {{ iface }} {{ config.role }} ratelimit 0 threshold {{ config.threshold }} -{% endif %} -{% if config.alt_subnet is defined and config.alt_subnet is not none %} -{% for subnet in config.alt_subnet %} +{% endif %} +{% if config.alt_subnet is vyos_defined %} +{% for subnet in config.alt_subnet %} altnet {{ subnet }} -{% endfor %} -{% endif %} -{% if config.whitelist is defined and config.whitelist is not none %} -{% for subnet in config.whitelist %} +{% endfor %} +{% endif %} +{% if config.whitelist is vyos_defined %} +{% for subnet in config.whitelist %} whitelist {{ subnet }} -{% endfor %} -{% endif %} -{% endfor %} +{% endfor %} +{% endif %} +{% endfor %} {% endif %} diff --git a/data/templates/ipsec/charon.tmpl b/data/templates/ipsec/charon.j2 index 4d710921e..388559af8 100644 --- a/data/templates/ipsec/charon.tmpl +++ b/data/templates/ipsec/charon.j2 @@ -1,6 +1,5 @@ # Options for the charon IKE daemon. charon { - # Accept unencrypted ID and HASH payloads in IKEv1 Main Mode. # accept_unencrypted_mainmode_messages = no @@ -20,6 +19,17 @@ charon { # Send Cisco Unity vendor ID payload (IKEv1 only). # cisco_unity = no + # Cisco FlexVPN +{% if options is vyos_defined %} + cisco_flexvpn = {{ 'yes' if options.flexvpn is vyos_defined else 'no' }} +{% if options.virtual_ip is vyos_defined %} + install_virtual_ip = yes +{% endif %} +{% if options.interface is vyos_defined %} + install_virtual_ip_on = {{ options.interface }} +{% endif %} +{% endif %} + # Close the IKE_SA if setup of the CHILD_SA along with IKE_AUTH failed. # close_ike_on_child_failure = no diff --git a/data/templates/ipsec/charon/dhcp.conf.tmpl b/data/templates/ipsec/charon/dhcp.conf.j2 index 92774b275..aaa5613fb 100644 --- a/data/templates/ipsec/charon/dhcp.conf.tmpl +++ b/data/templates/ipsec/charon/dhcp.conf.j2 @@ -1,12 +1,10 @@ dhcp { load = yes -{% if remote_access is defined and remote_access.dhcp is defined %} -{% if remote_access.dhcp.interface is defined %} +{% if remote_access.dhcp.interface is vyos_defined %} interface = {{ remote_access.dhcp.interface }} -{% endif %} -{% if remote_access.dhcp.server is defined %} +{% endif %} +{% if remote_access.dhcp.server is vyos_defined %} server = {{ remote_access.dhcp.server }} -{% endif %} {% endif %} # Always use the configured server address. diff --git a/data/templates/ipsec/charon/eap-radius.conf.tmpl b/data/templates/ipsec/charon/eap-radius.conf.j2 index 5ec35c988..8495011fe 100644 --- a/data/templates/ipsec/charon/eap-radius.conf.tmpl +++ b/data/templates/ipsec/charon/eap-radius.conf.j2 @@ -41,7 +41,7 @@ eap-radius { load = yes # NAS-Identifier to include in RADIUS messages. - nas_identifier = {{ remote_access.radius.nas_identifier if remote_access is defined and remote_access.radius is defined and remote_access.radius.nas_identifier is defined else 'strongSwan' }} + nas_identifier = {{ remote_access.radius.nas_identifier if remote_access.radius.nas_identifier is vyos_defined else 'strongSwan' }} # Port of RADIUS server (authentication). # port = 1812 @@ -94,19 +94,19 @@ eap-radius { # Section to specify multiple RADIUS servers. servers { -{% if remote_access is defined and remote_access.radius is defined and remote_access.radius.server is defined %} -{% for server, server_options in remote_access.radius.server.items() if server_options.disable is not defined %} +{% if remote_access.radius.server is vyos_defined %} +{% for server, server_options in remote_access.radius.server.items() if server_options.disable is not vyos_defined %} {{ server | replace('.', '-') }} { address = {{ server }} secret = {{ server_options.key }} auth_port = {{ server_options.port }} -{% if server_options.disable_accounting is not defined %} - acct_port = {{ server_options.port | int +1 }} -{% endif %} +{% if server_options.disable_accounting is not vyos_defined %} + acct_port = {{ server_options.port | int + 1 }} +{% endif %} sockets = 20 } -{% endfor %} -{% endif %} +{% endfor %} +{% endif %} } # Section to configure multiple XAuth authentication rounds via RADIUS. diff --git a/data/templates/ipsec/interfaces_use.conf.tmpl b/data/templates/ipsec/interfaces_use.conf.j2 index a77102396..c1bf8270d 100644 --- a/data/templates/ipsec/interfaces_use.conf.tmpl +++ b/data/templates/ipsec/interfaces_use.conf.j2 @@ -1,5 +1,5 @@ -{% if interface is defined %} +{% if interface is vyos_defined %} charon { interfaces_use = {{ ', '.join(interface) }} } -{% endif %}
\ No newline at end of file +{% endif %}
\ No newline at end of file diff --git a/data/templates/ipsec/ios_profile.tmpl b/data/templates/ipsec/ios_profile.j2 index af6c79d6e..c8e17729a 100644 --- a/data/templates/ipsec/ios_profile.tmpl +++ b/data/templates/ipsec/ios_profile.j2 @@ -41,7 +41,7 @@ <!-- Remote identity, can be a FQDN, a userFQDN, an IP or (theoretically) a certificate's subject DN. Can't be empty. IMPORTANT: DNs are currently not handled correctly, they are always sent as identities of type FQDN --> <key>RemoteIdentifier</key> - <string>{{ authentication.id if authentication.id is defined else 'fooo' }}</string> + <string>{{ authentication.id if authentication.id is vyos_defined else 'VyOS' }}</string> <!-- Local IKE identity, same restrictions as above. If it is empty the client's IP address will be used --> <key>LocalIdentifier</key> <string></string> diff --git a/data/templates/ipsec/ipsec.conf.j2 b/data/templates/ipsec/ipsec.conf.j2 new file mode 100644 index 000000000..f63995b38 --- /dev/null +++ b/data/templates/ipsec/ipsec.conf.j2 @@ -0,0 +1,19 @@ +# Created by VyOS - manual changes will be overwritten + +config setup +{% set charondebug = '' %} +{% if log.subsystem is vyos_defined %} +{% set subsystem = log.subsystem %} +{% if 'any' in log.subsystem %} +{% set subsystem = ['dmn', 'mgr', 'ike', 'chd','job', 'cfg', 'knl', + 'net', 'asn', 'enc', 'lib', 'esp', 'tls', 'tnc', + 'imc', 'imv', 'pts'] %} +{% endif %} +{% set charondebug = subsystem | join (' ' ~ log.level ~ ', ') ~ ' ' ~ log.level %} +{% endif %} + charondebug = "{{ charondebug }}" + uniqueids = {{ "no" if disable_uniqreqids is vyos_defined else "yes" }} + +{% if include_ipsec_conf is vyos_defined %} +include {{ include_ipsec_conf }} +{% endif %} diff --git a/data/templates/ipsec/ipsec.conf.tmpl b/data/templates/ipsec/ipsec.conf.tmpl deleted file mode 100644 index 1cb531e76..000000000 --- a/data/templates/ipsec/ipsec.conf.tmpl +++ /dev/null @@ -1,18 +0,0 @@ -# Created by VyOS - manual changes will be overwritten - -config setup -{% set charondebug = '' %} -{% if log is defined and log.subsystem is defined and log.subsystem is not none %} -{% set subsystem = log.subsystem %} -{% if 'any' in log.subsystem %} -{% set subsystem = ['dmn', 'mgr', 'ike', 'chd','job', 'cfg', 'knl', 'net', 'asn', - 'enc', 'lib', 'esp', 'tls', 'tnc', 'imc', 'imv', 'pts'] %} -{% endif %} -{% set charondebug = subsystem | join (' ' ~ log.level ~ ', ') ~ ' ' ~ log.level %} -{% endif %} - charondebug = "{{ charondebug }}" - uniqueids = {{ "no" if disable_uniqreqids is defined else "yes" }} - -{% if include_ipsec_conf is defined %} -include {{ include_ipsec_conf }} -{% endif %} diff --git a/data/templates/ipsec/ipsec.secrets.tmpl b/data/templates/ipsec/ipsec.secrets.j2 index 057e291ed..a87ac9bc7 100644 --- a/data/templates/ipsec/ipsec.secrets.tmpl +++ b/data/templates/ipsec/ipsec.secrets.j2 @@ -1,5 +1,5 @@ # Created by VyOS - manual changes will be overwritten -{% if include_ipsec_secrets is defined %} +{% if include_ipsec_secrets is vyos_defined %} include {{ include_ipsec_secrets }} -{% endif %} +{% endif %} diff --git a/data/templates/ipsec/swanctl.conf.j2 b/data/templates/ipsec/swanctl.conf.j2 new file mode 100644 index 000000000..bf6b8259c --- /dev/null +++ b/data/templates/ipsec/swanctl.conf.j2 @@ -0,0 +1,131 @@ +### Autogenerated by vpn_ipsec.py ### +{% import 'ipsec/swanctl/l2tp.j2' as l2tp_tmpl %} +{% import 'ipsec/swanctl/profile.j2' as profile_tmpl %} +{% import 'ipsec/swanctl/peer.j2' as peer_tmpl %} +{% import 'ipsec/swanctl/remote_access.j2' as remote_access_tmpl %} + +connections { +{% if profile is vyos_defined %} +{% for name, profile_conf in profile.items() if profile_conf.disable is not vyos_defined and profile_conf.bind.tunnel is vyos_defined %} +{{ profile_tmpl.conn(name, profile_conf, ike_group, esp_group) }} +{% endfor %} +{% endif %} +{% if site_to_site.peer is vyos_defined %} +{% for peer, peer_conf in site_to_site.peer.items() if peer not in dhcp_no_address and peer_conf.disable is not vyos_defined %} +{{ peer_tmpl.conn(peer, peer_conf, ike_group, esp_group) }} +{% endfor %} +{% endif %} +{% if remote_access.connection is vyos_defined %} +{% for rw, rw_conf in remote_access.connection.items() if rw_conf.disable is not vyos_defined %} +{{ remote_access_tmpl.conn(rw, rw_conf, ike_group, esp_group) }} +{% endfor %} +{% endif %} +{% if l2tp %} +{{ l2tp_tmpl.conn(l2tp, l2tp_outside_address, l2tp_ike_default, l2tp_esp_default, ike_group, esp_group) }} +{% endif %} +} + +pools { +{% if remote_access.pool is vyos_defined %} +{% for pool, pool_config in remote_access.pool.items() %} + {{ pool }} { +{% if pool_config.prefix is vyos_defined %} + addrs = {{ pool_config.prefix }} +{% endif %} +{% if pool_config.name_server is vyos_defined %} + dns = {{ pool_config.name_server | join(',') }} +{% endif %} +{% if pool_config.exclude is vyos_defined %} + split_exclude = {{ pool_config.exclude | join(',') }} +{% endif %} + } +{% endfor %} +{% endif %} +} + +secrets { +{% if profile is vyos_defined %} +{% for name, profile_conf in profile.items() if profile_conf.disable is not vyos_defined and profile_conf.bind.tunnel is vyos_defined %} +{% if profile_conf.authentication.mode is vyos_defined('pre-shared-secret') %} +{% for interface in profile_conf.bind.tunnel %} + ike-dmvpn-{{ interface }} { + secret = {{ profile_conf.authentication.pre_shared_secret }} + } +{% endfor %} +{% endif %} +{% endfor %} +{% endif %} +{% if site_to_site.peer is vyos_defined %} +{% for peer, peer_conf in site_to_site.peer.items() if peer not in dhcp_no_address and peer_conf.disable is not vyos_defined %} +{% set peer_name = peer.replace("@", "") | dot_colon_to_dash %} +{% if peer_conf.authentication.mode is vyos_defined('pre-shared-secret') %} + ike_{{ peer_name }} { +{% if peer_conf.local_address is vyos_defined %} + id-local = {{ peer_conf.local_address }} # dhcp:{{ peer_conf.dhcp_interface if 'dhcp_interface' in peer_conf else 'no' }} +{% endif %} + id-remote = {{ peer }} +{% if peer_conf.authentication.id is vyos_defined %} + id-localid = {{ peer_conf.authentication.id }} +{% endif %} +{% if peer_conf.authentication.remote_id is vyos_defined %} + id-remoteid = {{ peer_conf.authentication.remote_id }} +{% endif %} + secret = "{{ peer_conf.authentication.pre_shared_secret }}" + } +{% elif peer_conf.authentication.mode is vyos_defined('x509') %} + private_{{ peer_name }} { + file = {{ peer_conf.authentication.x509.certificate }}.pem +{% if peer_conf.authentication.x509.passphrase is vyos_defined %} + secret = "{{ peer_conf.authentication.x509.passphrase }}" +{% endif %} + } +{% elif peer_conf.authentication.mode is vyos_defined('rsa') %} + rsa_{{ peer_name }}_local { + file = {{ peer_conf.authentication.rsa.local_key }}.pem +{% if peer_conf.authentication.rsa.passphrase is vyos_defined %} + secret = "{{ peer_conf.authentication.rsa.passphrase }}" +{% endif %} + } +{% endif %} +{% endfor %} +{% endif %} +{% if remote_access.connection is vyos_defined %} +{% for ra, ra_conf in remote_access.connection.items() if ra_conf.disable is not vyos_defined %} +{% if ra_conf.authentication.server_mode is vyos_defined('pre-shared-secret') %} + ike_{{ ra }} { +{% if ra_conf.authentication.id is vyos_defined %} + id = "{{ ra_conf.authentication.id }}" +{% elif ra_conf.local_address is vyos_defined %} + id = "{{ ra_conf.local_address }}" +{% endif %} + secret = "{{ ra_conf.authentication.pre_shared_secret }}" + } +{% endif %} +{% if ra_conf.authentication.client_mode is vyos_defined('eap-mschapv2') and ra_conf.authentication.local_users.username is vyos_defined %} +{% for user, user_conf in ra_conf.authentication.local_users.username.items() if user_conf.disable is not vyos_defined %} + eap-{{ ra }}-{{ user }} { + secret = "{{ user_conf.password }}" + id-{{ ra }}-{{ user }} = "{{ user }}" + } +{% endfor %} +{% endif %} +{% endfor %} +{% endif %} +{% if l2tp %} +{% if l2tp.authentication.mode is vyos_defined('pre-shared-secret') %} + ike_l2tp_remote_access { + id = "{{ l2tp_outside_address }}" + secret = "{{ l2tp.authentication.pre_shared_secret }}" + } +{% elif l2tp.authentication.mode is vyos_defined('x509') %} + private_l2tp_remote_access { + id = "{{ l2tp_outside_address }}" + file = {{ l2tp.authentication.x509.certificate }}.pem +{% if l2tp.authentication.x509.passphrase is vyos_defined %} + secret = "{{ l2tp.authentication.x509.passphrase }}" +{% endif %} + } +{% endif %} +{% endif %} +} + diff --git a/data/templates/ipsec/swanctl.conf.tmpl b/data/templates/ipsec/swanctl.conf.tmpl deleted file mode 100644 index 161f19f95..000000000 --- a/data/templates/ipsec/swanctl.conf.tmpl +++ /dev/null @@ -1,131 +0,0 @@ -### Autogenerated by vpn_ipsec.py ### -{% import 'ipsec/swanctl/l2tp.tmpl' as l2tp_tmpl %} -{% import 'ipsec/swanctl/profile.tmpl' as profile_tmpl %} -{% import 'ipsec/swanctl/peer.tmpl' as peer_tmpl %} -{% import 'ipsec/swanctl/remote_access.tmpl' as remote_access_tmpl %} - -connections { -{% if profile is defined %} -{% for name, profile_conf in profile.items() if profile_conf.disable is not defined and profile_conf.bind is defined and profile_conf.bind.tunnel is defined %} -{{ profile_tmpl.conn(name, profile_conf, ike_group, esp_group) }} -{% endfor %} -{% endif %} -{% if site_to_site is defined and site_to_site.peer is defined %} -{% for peer, peer_conf in site_to_site.peer.items() if peer not in dhcp_no_address and peer_conf.disable is not defined %} -{{ peer_tmpl.conn(peer, peer_conf, ike_group, esp_group) }} -{% endfor %} -{% endif %} -{% if remote_access is defined and remote_access.connection is defined and remote_access.connection is not none %} -{% for rw, rw_conf in remote_access.connection.items() if rw_conf.disable is not defined %} -{{ remote_access_tmpl.conn(rw, rw_conf, ike_group, esp_group) }} -{% endfor %} -{% endif %} -{% if l2tp %} -{{ l2tp_tmpl.conn(l2tp, l2tp_outside_address, l2tp_ike_default, l2tp_esp_default, ike_group, esp_group) }} -{% endif %} -} - -pools { -{% if remote_access is defined and remote_access.pool is defined and remote_access.pool is not none %} -{% for pool, pool_config in remote_access.pool.items() %} - {{ pool }} { -{% if pool_config.prefix is defined and pool_config.prefix is not none %} - addrs = {{ pool_config.prefix }} -{% endif %} -{% if pool_config.name_server is defined and pool_config.name_server is not none %} - dns = {{ pool_config.name_server | join(',') }} -{% endif %} -{% if pool_config.exclude is defined and pool_config.exclude is not none %} - split_exclude = {{ pool_config.exclude | join(',') }} -{% endif %} - } -{% endfor %} -{% endif %} -} - -secrets { -{% if profile is defined %} -{% for name, profile_conf in profile.items() if profile_conf.disable is not defined and profile_conf.bind is defined and profile_conf.bind.tunnel is defined %} -{% if profile_conf.authentication.mode == 'pre-shared-secret' %} -{% for interface in profile_conf.bind.tunnel %} - ike-dmvpn-{{ interface }} { - secret = {{ profile_conf.authentication.pre_shared_secret }} - } -{% endfor %} -{% endif %} -{% endfor %} -{% endif %} -{% if site_to_site is defined and site_to_site.peer is defined %} -{% for peer, peer_conf in site_to_site.peer.items() if peer not in dhcp_no_address and peer_conf.disable is not defined %} -{% set peer_name = peer.replace(".", "-").replace("@", "") %} -{% if peer_conf.authentication.mode == 'pre-shared-secret' %} - ike_{{ peer_name }} { -{% if peer_conf.local_address is defined %} - id-local = {{ peer_conf.local_address }} # dhcp:{{ peer_conf.dhcp_interface if 'dhcp_interface' in peer_conf else 'no' }} -{% endif %} - id-remote = {{ peer }} -{% if peer_conf.authentication.id is defined %} - id-localid = {{ peer_conf.authentication.id }} -{% endif %} -{% if peer_conf.authentication.remote_id is defined %} - id-remoteid = {{ peer_conf.authentication.remote_id }} -{% endif %} - secret = "{{ peer_conf.authentication.pre_shared_secret }}" - } -{% elif peer_conf.authentication.mode == 'x509' %} - private_{{ peer_name }} { - file = {{ peer_conf.authentication.x509.certificate }}.pem -{% if peer_conf.authentication.x509.passphrase is defined %} - secret = "{{ peer_conf.authentication.x509.passphrase }}" -{% endif %} - } -{% elif peer_conf.authentication.mode == 'rsa' %} - rsa_{{ peer_name }}_local { - file = {{ peer_conf.authentication.rsa.local_key }}.pem -{% if peer_conf.authentication.rsa.passphrase is defined %} - secret = "{{ peer_conf.authentication.rsa.passphrase }}" -{% endif %} - } -{% endif %} -{% endfor %} -{% endif %} -{% if remote_access is defined and remote_access.connection is defined and remote_access.connection is not none %} -{% for ra, ra_conf in remote_access.connection.items() if ra_conf.disable is not defined %} -{% if ra_conf.authentication.server_mode == 'pre-shared-secret' %} - ike_{{ ra }} { -{% if ra_conf.authentication.id is defined %} - id = "{{ ra_conf.authentication.id }}" -{% elif ra_conf.local_address is defined %} - id = "{{ ra_conf.local_address }}" -{% endif %} - secret = "{{ ra_conf.authentication.pre_shared_secret }}" - } -{% endif %} -{% if ra_conf.authentication.client_mode == 'eap-mschapv2' and ra_conf.authentication.local_users is defined and ra_conf.authentication.local_users.username is defined %} -{% for user, user_conf in ra_conf.authentication.local_users.username.items() if user_conf.disable is not defined %} - eap-{{ ra }}-{{ user }} { - secret = "{{ user_conf.password }}" - id-{{ ra }}-{{ user }} = "{{ user }}" - } -{% endfor %} -{% endif %} -{% endfor %} -{% endif %} -{% if l2tp %} -{% if l2tp.authentication.mode == 'pre-shared-secret' %} - ike_l2tp_remote_access { - id = "{{ l2tp_outside_address }}" - secret = "{{ l2tp.authentication.pre_shared_secret }}" - } -{% elif l2tp.authentication.mode == 'x509' %} - private_l2tp_remote_access { - id = "{{ l2tp_outside_address }}" - file = {{ l2tp.authentication.x509.certificate }}.pem -{% if l2tp.authentication.x509.passphrase is defined %} - secret = "{{ l2tp.authentication.x509.passphrase }}" -{% endif %} - } -{% endif %} -{% endif %} -} - diff --git a/data/templates/ipsec/swanctl/l2tp.tmpl b/data/templates/ipsec/swanctl/l2tp.j2 index 4cd1b4af3..7e63865cc 100644 --- a/data/templates/ipsec/swanctl/l2tp.tmpl +++ b/data/templates/ipsec/swanctl/l2tp.j2 @@ -1,6 +1,6 @@ {% macro conn(l2tp, l2tp_outside_address, l2tp_ike_default, l2tp_esp_default, ike_group, esp_group) %} -{% set l2tp_ike = ike_group[l2tp.ike_group] if l2tp.ike_group is defined else None %} -{% set l2tp_esp = esp_group[l2tp.esp_group] if l2tp.esp_group is defined else None %} +{% set l2tp_ike = ike_group[l2tp.ike_group] if l2tp.ike_group is vyos_defined else None %} +{% set l2tp_esp = esp_group[l2tp.esp_group] if l2tp.esp_group is vyos_defined else None %} l2tp_remote_access { proposals = {{ l2tp_ike | get_esp_ike_cipher | join(',') if l2tp_ike else l2tp_ike_default }} local_addrs = {{ l2tp_outside_address }} @@ -10,9 +10,9 @@ reauth_time = 0 local { auth = {{ 'psk' if l2tp.authentication.mode == 'pre-shared-secret' else 'pubkey' }} -{% if l2tp.authentication.mode == 'x509' %} +{% if l2tp.authentication.mode == 'x509' %} certs = {{ l2tp.authentication.x509.certificate }}.pem -{% endif %} +{% endif %} } remote { auth = {{ 'psk' if l2tp.authentication.mode == 'pre-shared-secret' else 'pubkey' }} diff --git a/data/templates/ipsec/swanctl/peer.j2 b/data/templates/ipsec/swanctl/peer.j2 new file mode 100644 index 000000000..90d2c774f --- /dev/null +++ b/data/templates/ipsec/swanctl/peer.j2 @@ -0,0 +1,166 @@ +{% macro conn(peer, peer_conf, ike_group, esp_group) %} +{% set name = peer.replace("@", "") | dot_colon_to_dash %} +{# peer needs to reference the global IKE configuration for certain values #} +{% set ike = ike_group[peer_conf.ike_group] %} + peer_{{ name }} { + proposals = {{ ike | get_esp_ike_cipher | join(',') }} + version = {{ ike.key_exchange[4:] if ike.key_exchange is vyos_defined else "0" }} +{% if peer_conf.virtual_address is vyos_defined %} + vips = {{ peer_conf.virtual_address | join(', ') }} +{% endif %} + local_addrs = {{ peer_conf.local_address if peer_conf.local_address != 'any' else '0.0.0.0/0' }} # dhcp:{{ peer_conf.dhcp_interface if 'dhcp_interface' in peer_conf else 'no' }} + remote_addrs = {{ peer if peer not in ['any', '0.0.0.0'] and peer[0:1] != '@' else '0.0.0.0/0' }} +{% if peer_conf.authentication.mode is vyos_defined('x509') %} + send_cert = always +{% endif %} +{% if ike.dead_peer_detection is vyos_defined %} + dpd_timeout = {{ ike.dead_peer_detection.timeout }} + dpd_delay = {{ ike.dead_peer_detection.interval }} +{% endif %} +{% if ike.key_exchange is vyos_defined('ikev1') and ike.mode is vyos_defined('aggressive') %} + aggressive = yes +{% endif %} + rekey_time = {{ ike.lifetime }}s + mobike = {{ "yes" if ike.mobike is not defined or ike.mobike == "enable" else "no" }} +{% if peer[0:1] == '@' %} + keyingtries = 0 + reauth_time = 0 +{% elif peer_conf.connection_type is not vyos_defined or peer_conf.connection_type is vyos_defined('initiate') %} + keyingtries = 0 +{% elif peer_conf.connection_type is vyos_defined('respond') %} + keyingtries = 1 +{% endif %} +{% if peer_conf.force_encapsulation is vyos_defined('enable') %} + encap = yes +{% endif %} + local { +{% if peer_conf.authentication.id is vyos_defined %} + id = "{{ peer_conf.authentication.id }}" +{% endif %} + auth = {{ 'psk' if peer_conf.authentication.mode == 'pre-shared-secret' else 'pubkey' }} +{% if peer_conf.authentication.mode == 'x509' %} + certs = {{ peer_conf.authentication.x509.certificate }}.pem +{% elif peer_conf.authentication.mode == 'rsa' %} + pubkeys = {{ peer_conf.authentication.rsa.local_key }}.pem +{% endif %} + } + remote { +{% if peer_conf.authentication.remote_id is vyos_defined %} + id = "{{ peer_conf.authentication.remote_id }}" +{% else %} + id = "{{ peer }}" +{% endif %} + auth = {{ 'psk' if peer_conf.authentication.mode == 'pre-shared-secret' else 'pubkey' }} +{% if peer_conf.authentication.mode == 'rsa' %} + pubkeys = {{ peer_conf.authentication.rsa.remote_key }}.pem +{% endif %} + } + children { +{% if peer_conf.vti.bind is vyos_defined and peer_conf.tunnel is not vyos_defined %} +{% set vti_esp = esp_group[ peer_conf.vti.esp_group ] if peer_conf.vti.esp_group is vyos_defined else esp_group[ peer_conf.default_esp_group ] %} + peer_{{ name }}_vti { + esp_proposals = {{ vti_esp | get_esp_ike_cipher(ike) | join(',') }} +{% if vti_esp.life_bytes is vyos_defined %} + life_bytes = {{ vti_esp.life_bytes }} +{% endif %} +{% if vti_esp.life_packets is vyos_defined %} + life_packets = {{ vti_esp.life_packets }} +{% endif %} + life_time = {{ vti_esp.lifetime }}s + local_ts = 0.0.0.0/0,::/0 + remote_ts = 0.0.0.0/0,::/0 + updown = "/etc/ipsec.d/vti-up-down {{ peer_conf.vti.bind }}" +{# The key defaults to 0 and will match any policies which similarly do not have a lookup key configuration. #} +{# Thus we simply shift the key by one to also support a vti0 interface #} +{% set if_id = peer_conf.vti.bind | replace('vti', '') | int + 1 %} + if_id_in = {{ if_id }} + if_id_out = {{ if_id }} + ipcomp = {{ 'yes' if vti_esp.compression is vyos_defined('enable') else 'no' }} + mode = {{ vti_esp.mode }} +{% if peer[0:1] == '@' %} + start_action = none +{% elif peer_conf.connection_type is not vyos_defined or peer_conf.connection_type is vyos_defined('initiate') %} + start_action = start +{% elif peer_conf.connection_type is vyos_defined('respond') %} + start_action = trap +{% elif peer_conf.connection_type is vyos_defined('none') %} + start_action = none +{% endif %} +{% if ike.dead_peer_detection is vyos_defined %} +{% set dpd_translate = {'clear': 'clear', 'hold': 'trap', 'restart': 'restart'} %} + dpd_action = {{ dpd_translate[ike.dead_peer_detection.action] }} +{% endif %} + close_action = {{ {'none': 'none', 'hold': 'trap', 'restart': 'start'}[ike.close_action] }} + } +{% elif peer_conf.tunnel is vyos_defined %} +{% for tunnel_id, tunnel_conf in peer_conf.tunnel.items() if tunnel_conf.disable is not defined %} +{% set tunnel_esp_name = tunnel_conf.esp_group if tunnel_conf.esp_group is vyos_defined else peer_conf.default_esp_group %} +{% set tunnel_esp = esp_group[tunnel_esp_name] %} +{% set proto = tunnel_conf.protocol if tunnel_conf.protocol is vyos_defined else '' %} +{% set local_port = tunnel_conf.local.port if tunnel_conf.local.port is vyos_defined else '' %} +{% set local_suffix = '[{0}/{1}]'.format(proto, local_port) if proto or local_port else '' %} +{% set remote_port = tunnel_conf.remote.port if tunnel_conf.remote.port is vyos_defined else '' %} +{% set remote_suffix = '[{0}/{1}]'.format(proto, remote_port) if proto or remote_port else '' %} + peer_{{ name }}_tunnel_{{ tunnel_id }} { + esp_proposals = {{ tunnel_esp | get_esp_ike_cipher(ike) | join(',') }} +{% if tunnel_esp.life_bytes is vyos_defined %} + life_bytes = {{ tunnel_esp.life_bytes }} +{% endif %} +{% if tunnel_esp.life_packets is vyos_defined %} + life_packets = {{ tunnel_esp.life_packets }} +{% endif %} + life_time = {{ tunnel_esp.lifetime }}s +{% if tunnel_esp.mode is not defined or tunnel_esp.mode == 'tunnel' %} +{% if tunnel_conf.local.prefix is vyos_defined %} +{% set local_prefix = tunnel_conf.local.prefix if 'any' not in tunnel_conf.local.prefix else ['0.0.0.0/0', '::/0'] %} + local_ts = {{ local_prefix | join(local_suffix + ",") }}{{ local_suffix }} +{% endif %} +{% if tunnel_conf.remote.prefix is vyos_defined %} +{% set remote_prefix = tunnel_conf.remote.prefix if 'any' not in tunnel_conf.remote.prefix else ['0.0.0.0/0', '::/0'] %} + remote_ts = {{ remote_prefix | join(remote_suffix + ",") }}{{ remote_suffix }} +{% endif %} +{% if tunnel_conf.priority is vyos_defined %} + priority = {{ tunnel_conf.priority }} +{% endif %} +{% elif tunnel_esp.mode == 'transport' %} + local_ts = {{ peer_conf.local_address }}{{ local_suffix }} + remote_ts = {{ peer }}{{ remote_suffix }} +{% endif %} + ipcomp = {{ 'yes' if tunnel_esp.compression is vyos_defined('enable') else 'no' }} + mode = {{ tunnel_esp.mode }} +{% if peer[0:1] == '@' %} + start_action = none +{% elif peer_conf.connection_type is not vyos_defined or peer_conf.connection_type is vyos_defined('initiate') %} + start_action = start +{% elif peer_conf.connection_type is vyos_defined('respond') %} + start_action = trap +{% elif peer_conf.connection_type is vyos_defined('none') %} + start_action = none +{% endif %} +{% if ike.dead_peer_detection is vyos_defined %} +{% set dpd_translate = {'clear': 'clear', 'hold': 'trap', 'restart': 'restart'} %} + dpd_action = {{ dpd_translate[ike.dead_peer_detection.action] }} +{% endif %} + close_action = {{ {'none': 'none', 'hold': 'trap', 'restart': 'start'}[ike.close_action] }} +{% if peer_conf.vti.bind is vyos_defined %} +{# The key defaults to 0 and will match any policies which similarly do not have a lookup key configuration. #} +{# Thus we simply shift the key by one to also support a vti0 interface #} +{% set if_id = peer_conf.vti.bind | replace('vti', '') | int + 1 %} + updown = "/etc/ipsec.d/vti-up-down {{ peer_conf.vti.bind }}" + if_id_in = {{ if_id }} + if_id_out = {{ if_id }} +{% endif %} + } +{% if tunnel_conf.passthrough is vyos_defined %} + peer_{{ name }}_tunnel_{{ tunnel_id }}_passthrough { + local_ts = {{ tunnel_conf.passthrough | join(",") }} + remote_ts = {{ tunnel_conf.passthrough | join(",") }} + start_action = trap + mode = pass + } +{% endif %} +{% endfor %} +{% endif %} + } + } +{% endmacro %} diff --git a/data/templates/ipsec/swanctl/peer.tmpl b/data/templates/ipsec/swanctl/peer.tmpl deleted file mode 100644 index 8c3776bf1..000000000 --- a/data/templates/ipsec/swanctl/peer.tmpl +++ /dev/null @@ -1,142 +0,0 @@ -{% macro conn(peer, peer_conf, ike_group, esp_group) %} -{% set name = peer.replace(".", "-").replace("@", "") %} -{# peer needs to reference the global IKE configuration for certain values #} -{% set ike = ike_group[peer_conf.ike_group] %} - peer_{{ name }} { - proposals = {{ ike | get_esp_ike_cipher | join(',') }} - version = {{ ike.key_exchange[4:] if ike is defined and ike.key_exchange is defined else "0" }} - local_addrs = {{ peer_conf.local_address if peer_conf.local_address != 'any' else '0.0.0.0/0' }} # dhcp:{{ peer_conf.dhcp_interface if 'dhcp_interface' in peer_conf else 'no' }} - remote_addrs = {{ peer if peer not in ['any', '0.0.0.0'] and peer[0:1] != '@' else '0.0.0.0/0' }} -{% if peer_conf.authentication is defined and peer_conf.authentication.mode is defined and peer_conf.authentication.mode == 'x509' %} - send_cert = always -{% endif %} -{% if ike.dead_peer_detection is defined %} - dpd_timeout = {{ ike.dead_peer_detection.timeout }} - dpd_delay = {{ ike.dead_peer_detection.interval }} -{% endif %} -{% if ike.key_exchange is defined and ike.key_exchange == "ikev1" and ike.mode is defined and ike.mode == "aggressive" %} - aggressive = yes -{% endif %} - rekey_time = {{ ike.lifetime }}s - mobike = {{ "yes" if ike.mobike is not defined or ike.mobike == "enable" else "no" }} -{% if peer[0:1] == '@' %} - keyingtries = 0 - reauth_time = 0 -{% elif peer_conf.connection_type is not defined or peer_conf.connection_type == 'initiate' %} - keyingtries = 0 -{% elif peer_conf.connection_type is defined and peer_conf.connection_type == 'respond' %} - keyingtries = 1 -{% endif %} -{% if peer_conf.force_encapsulation is defined and peer_conf.force_encapsulation == 'enable' %} - encap = yes -{% endif %} - local { -{% if peer_conf.authentication is defined and peer_conf.authentication.id is defined and peer_conf.authentication.id is not none %} - id = "{{ peer_conf.authentication.id }}" -{% endif %} - auth = {{ 'psk' if peer_conf.authentication.mode == 'pre-shared-secret' else 'pubkey' }} -{% if peer_conf.authentication.mode == 'x509' %} - certs = {{ peer_conf.authentication.x509.certificate }}.pem -{% elif peer_conf.authentication.mode == 'rsa' %} - pubkeys = {{ peer_conf.authentication.rsa.local_key }}.pem -{% endif %} - } - remote { -{% if peer_conf.authentication is defined and peer_conf.authentication.remote_id is defined and peer_conf.authentication.remote_id is not none %} - id = "{{ peer_conf.authentication.remote_id }}" -{% else %} - id = "{{ peer }}" -{% endif %} - auth = {{ 'psk' if peer_conf.authentication.mode == 'pre-shared-secret' else 'pubkey' }} -{% if peer_conf.authentication.mode == 'rsa' %} - pubkeys = {{ peer_conf.authentication.rsa.remote_key }}.pem -{% endif %} - } - children { -{% if peer_conf.vti is defined and peer_conf.vti.bind is defined and peer_conf.tunnel is not defined %} -{% set vti_esp = esp_group[ peer_conf.vti.esp_group ] if peer_conf.vti.esp_group is defined else esp_group[ peer_conf.default_esp_group ] %} - peer_{{ name }}_vti { - esp_proposals = {{ vti_esp | get_esp_ike_cipher(ike) | join(',') }} - life_time = {{ vti_esp.lifetime }}s - local_ts = 0.0.0.0/0,::/0 - remote_ts = 0.0.0.0/0,::/0 - updown = "/etc/ipsec.d/vti-up-down {{ peer_conf.vti.bind }}" - {# The key defaults to 0 and will match any policies which similarly do not have a lookup key configuration. #} - {# Thus we simply shift the key by one to also support a vti0 interface #} -{% set if_id = peer_conf.vti.bind | replace('vti', '') | int +1 %} - if_id_in = {{ if_id }} - if_id_out = {{ if_id }} - ipcomp = {{ 'yes' if vti_esp.compression is defined and vti_esp.compression == 'enable' else 'no' }} - mode = {{ vti_esp.mode }} -{% if peer[0:1] == '@' %} - start_action = none -{% elif peer_conf.connection_type is not defined or peer_conf.connection_type == 'initiate' %} - start_action = start -{% elif peer_conf.connection_type == 'respond' %} - start_action = trap -{% endif %} -{% if ike.dead_peer_detection is defined %} -{% set dpd_translate = {'clear': 'clear', 'hold': 'trap', 'restart': 'start'} %} - dpd_action = {{ dpd_translate[ike.dead_peer_detection.action] }} -{% endif %} - } -{% elif peer_conf.tunnel is defined %} -{% for tunnel_id, tunnel_conf in peer_conf.tunnel.items() if tunnel_conf.disable is not defined %} -{% set tunnel_esp_name = tunnel_conf.esp_group if tunnel_conf.esp_group is defined else peer_conf.default_esp_group %} -{% set tunnel_esp = esp_group[tunnel_esp_name] %} -{% set proto = tunnel_conf.protocol if tunnel_conf.protocol is defined else '' %} -{% set local_port = tunnel_conf.local.port if tunnel_conf.local is defined and tunnel_conf.local.port is defined else '' %} -{% set local_suffix = '[{0}/{1}]'.format(proto, local_port) if proto or local_port else '' %} -{% set remote_port = tunnel_conf.remote.port if tunnel_conf.remote is defined and tunnel_conf.remote.port is defined else '' %} -{% set remote_suffix = '[{0}/{1}]'.format(proto, remote_port) if proto or remote_port else '' %} - peer_{{ name }}_tunnel_{{ tunnel_id }} { - esp_proposals = {{ tunnel_esp | get_esp_ike_cipher(ike) | join(',') }} - life_time = {{ tunnel_esp.lifetime }}s -{% if tunnel_esp.mode is not defined or tunnel_esp.mode == 'tunnel' %} -{% if tunnel_conf.local is defined and tunnel_conf.local.prefix is defined %} -{% set local_prefix = tunnel_conf.local.prefix if 'any' not in tunnel_conf.local.prefix else ['0.0.0.0/0', '::/0'] %} - local_ts = {{ local_prefix | join(local_suffix + ",") }}{{ local_suffix }} -{% endif %} -{% if tunnel_conf.remote is defined and tunnel_conf.remote.prefix is defined %} -{% set remote_prefix = tunnel_conf.remote.prefix if 'any' not in tunnel_conf.remote.prefix else ['0.0.0.0/0', '::/0'] %} - remote_ts = {{ remote_prefix | join(remote_suffix + ",") }}{{ remote_suffix }} -{% endif %} -{% elif tunnel_esp.mode == 'transport' %} - local_ts = {{ peer_conf.local_address }}{{ local_suffix }} - remote_ts = {{ peer }}{{ remote_suffix }} -{% endif %} - ipcomp = {{ 'yes' if tunnel_esp.compression is defined and tunnel_esp.compression == 'enable' else 'no' }} - mode = {{ tunnel_esp.mode }} -{% if peer[0:1] == '@' %} - start_action = none -{% elif peer_conf.connection_type is not defined or peer_conf.connection_type == 'initiate' %} - start_action = start -{% elif peer_conf.connection_type == 'respond' %} - start_action = trap -{% endif %} -{% if ike.dead_peer_detection is defined %} -{% set dpd_translate = {'clear': 'clear', 'hold': 'trap', 'restart': 'start'} %} - dpd_action = {{ dpd_translate[ike.dead_peer_detection.action] }} -{% endif %} -{% if peer_conf.vti is defined and peer_conf.vti.bind is defined %} - updown = "/etc/ipsec.d/vti-up-down {{ peer_conf.vti.bind }}" - {# The key defaults to 0 and will match any policies which similarly do not have a lookup key configuration. #} - {# Thus we simply shift the key by one to also support a vti0 interface #} -{% set if_id = peer_conf.vti.bind | replace('vti', '') | int +1 %} - if_id_in = {{ if_id }} - if_id_out = {{ if_id }} -{% endif %} - } -{% if tunnel_conf.passthrough is defined and tunnel_conf.passthrough %} - peer_{{ name }}_tunnel_{{ tunnel_id }}_passthough { - local_ts = {{ tunnel_conf.passthrough | join(",") }} - remote_ts = {{ tunnel_conf.passthrough | join(",") }} - start_action = trap - mode = pass - } -{% endif %} -{% endfor %} -{% endif %} - } - } -{% endmacro %} diff --git a/data/templates/ipsec/swanctl/profile.tmpl b/data/templates/ipsec/swanctl/profile.j2 index a5cae31c0..d4f417378 100644 --- a/data/templates/ipsec/swanctl/profile.tmpl +++ b/data/templates/ipsec/swanctl/profile.j2 @@ -1,39 +1,39 @@ {% macro conn(name, profile_conf, ike_group, esp_group) %} -{# peer needs to reference the global IKE configuration for certain values #} -{% set ike = ike_group[profile_conf.ike_group] %} -{% set esp = esp_group[profile_conf.esp_group] %} -{% if profile_conf.bind is defined and profile_conf.bind.tunnel is defined %} +{# peer needs to reference the global IKE configuration for certain values #} +{% set ike = ike_group[profile_conf.ike_group] %} +{% set esp = esp_group[profile_conf.esp_group] %} +{% if profile_conf.bind.tunnel is vyos_defined %} {% for interface in profile_conf.bind.tunnel %} dmvpn-{{ name }}-{{ interface }} { proposals = {{ ike_group[profile_conf.ike_group] | get_esp_ike_cipher | join(',') }} - version = {{ ike.key_exchange[4:] if ike is defined and ike.key_exchange is defined else "0" }} + version = {{ ike.key_exchange[4:] if ike.key_exchange is vyos_defined else "0" }} rekey_time = {{ ike.lifetime }}s keyingtries = 0 -{% if profile_conf.authentication is defined and profile_conf.authentication.mode is defined and profile_conf.authentication.mode == 'pre-shared-secret' %} +{% if profile_conf.authentication.mode is vyos_defined('pre-shared-secret') %} local { auth = psk } remote { auth = psk } -{% endif %} +{% endif %} children { dmvpn { - esp_proposals = {{ esp | get_esp_ike_cipher(ike) | join(',') }} + esp_proposals = {{ esp | get_esp_ike_cipher(ike) | join(',') }} rekey_time = {{ esp.lifetime }}s rand_time = 540s local_ts = dynamic[gre] remote_ts = dynamic[gre] mode = {{ esp.mode }} -{% if ike.dead_peer_detection is defined and ike.dead_peer_detection.action is defined %} +{% if ike.dead_peer_detection.action is vyos_defined %} dpd_action = {{ ike.dead_peer_detection.action }} -{% endif %} -{% if esp.compression is defined and esp.compression == 'enable' %} +{% endif %} +{% if esp.compression is vyos_defined('enable') %} ipcomp = yes -{% endif %} +{% endif %} } } } {% endfor %} -{% endif %} +{% endif %} {% endmacro %} diff --git a/data/templates/ipsec/swanctl/remote_access.tmpl b/data/templates/ipsec/swanctl/remote_access.j2 index 6354c60b1..d2760ec1f 100644 --- a/data/templates/ipsec/swanctl/remote_access.tmpl +++ b/data/templates/ipsec/swanctl/remote_access.j2 @@ -1,37 +1,38 @@ {% macro conn(name, rw_conf, ike_group, esp_group) %} -{# peer needs to reference the global IKE configuration for certain values #} -{% set ike = ike_group[rw_conf.ike_group] %} -{% set esp = esp_group[rw_conf.esp_group] %} +{# peer needs to reference the global IKE configuration for certain values #} +{% set ike = ike_group[rw_conf.ike_group] %} +{% set esp = esp_group[rw_conf.esp_group] %} ra-{{ name }} { remote_addrs = %any - local_addrs = {{ rw_conf.local_address if rw_conf.local_address is defined else '%any' }} + local_addrs = {{ rw_conf.local_address if rw_conf.local_address is vyos_defined else '%any' }} proposals = {{ ike_group[rw_conf.ike_group] | get_esp_ike_cipher | join(',') }} - version = {{ ike.key_exchange[4:] if ike is defined and ike.key_exchange is defined else "0" }} + version = {{ ike.key_exchange[4:] if ike.key_exchange is vyos_defined else "0" }} send_certreq = no rekey_time = {{ ike.lifetime }}s keyingtries = 0 -{% if rw_conf.unique is defined and rw_conf.unique is not none %} +{% if rw_conf.unique is vyos_defined %} unique = {{ rw_conf.unique }} -{% endif %} -{% if rw_conf.pool is defined and rw_conf.pool is not none %} +{% endif %} +{% if rw_conf.pool is vyos_defined %} pools = {{ rw_conf.pool | join(',') }} -{% endif %} +{% endif %} local { -{% if rw_conf.authentication.id is defined and rw_conf.authentication.use_x509_id is not defined %} +{% if rw_conf.authentication.id is vyos_defined and rw_conf.authentication.use_x509_id is not vyos_defined %} +{# please use " quotes - else Apple iOS goes crazy #} id = "{{ rw_conf.authentication.id }}" -{% endif %} -{% if rw_conf.authentication.server_mode == 'x509' %} +{% endif %} +{% if rw_conf.authentication.server_mode == 'x509' %} auth = pubkey certs = {{ rw_conf.authentication.x509.certificate }}.pem -{% elif rw_conf.authentication.server_mode == 'pre-shared-secret' %} +{% elif rw_conf.authentication.server_mode == 'pre-shared-secret' %} auth = psk -{% endif %} +{% endif %} } remote { auth = {{ rw_conf.authentication.client_mode }} -{% if rw_conf.authentication.client_mode.startswith("eap") %} +{% if rw_conf.authentication.client_mode.startswith("eap") %} eap_id = %any -{% endif %} +{% endif %} } children { ikev2-vpn { @@ -40,9 +41,9 @@ rand_time = 540s dpd_action = clear inactivity = {{ rw_conf.timeout }} -{% set local_prefix = rw_conf.local.prefix if rw_conf.local is defined and rw_conf.local.prefix is defined else ['0.0.0.0/0', '::/0'] %} -{% set local_port = rw_conf.local.port if rw_conf.local is defined and rw_conf.local.port is defined else '' %} -{% set local_suffix = '[%any/{1}]'.format(local_port) if local_port else '' %} +{% set local_prefix = rw_conf.local.prefix if rw_conf.local.prefix is vyos_defined else ['0.0.0.0/0', '::/0'] %} +{% set local_port = rw_conf.local.port if rw_conf.local.port is vyos_defined else '' %} +{% set local_suffix = '[%any/{1}]'.format(local_port) if local_port else '' %} local_ts = {{ local_prefix | join(local_suffix + ",") }}{{ local_suffix }} } } diff --git a/data/templates/ipsec/windows_profile.tmpl b/data/templates/ipsec/windows_profile.j2 index 8c26944be..8c26944be 100644 --- a/data/templates/ipsec/windows_profile.tmpl +++ b/data/templates/ipsec/windows_profile.j2 diff --git a/data/templates/lcd/LCDd.conf.tmpl b/data/templates/lcd/LCDd.conf.j2 index 2c7ad920f..3631add1d 100644 --- a/data/templates/lcd/LCDd.conf.tmpl +++ b/data/templates/lcd/LCDd.conf.j2 @@ -48,14 +48,14 @@ DriverPath=/usr/lib/x86_64-linux-gnu/lcdproc/ # sed1520, serialPOS, serialVFD, shuttleVFD, sli, stv5730, svga, t6963, # text, tyan, ula200, vlsys_m428, xosd, yard2LCD -{% if model is defined %} -{% if model.startswith('cfa-') %} +{% if model is vyos_defined %} +{% if model.startswith('cfa-') %} Driver=CFontzPacket -{% elif model == 'sdec' %} +{% elif model == 'sdec' %} Driver=sdeclcd -{% elif model == 'hd44780' %} +{% elif model == 'hd44780' %} Driver=hd44780 -{% endif %} +{% endif %} {% endif %} # Tells the driver to bind to the given interface. [default: 127.0.0.1] @@ -115,8 +115,8 @@ Heartbeat=off # set title scrolling speed [default: 10; legal: 0-10] TitleSpeed=10 -{% if model is defined and model is not none %} -{% if model.startswith('cfa-') %} +{% if model is vyos_defined %} +{% if model.startswith('cfa-') %} ## CrystalFontz packet driver (for CFA533, CFA631, CFA633 & CFA635) ## [CFontzPacket] Model={{ model.split('-')[1] }} @@ -126,14 +126,14 @@ Brightness=500 OffBrightness=50 Reboot=yes USB=yes -{% elif model == 'sdec' %} +{% elif model == 'sdec' %} ## SDEC driver for Lanner, Watchguard, Sophos sppliances ## [sdeclcd] # No options -{% elif model == 'hd44780' %} +{% elif model == 'hd44780' %} [hd44780] ConnectionType=ezio Device={{ device }} Size=16x2 -{% endif %} +{% endif %} {% endif %} diff --git a/data/templates/lcd/lcdproc.conf.tmpl b/data/templates/lcd/lcdproc.conf.j2 index c79f3cd0d..c79f3cd0d 100644 --- a/data/templates/lcd/lcdproc.conf.tmpl +++ b/data/templates/lcd/lcdproc.conf.j2 diff --git a/data/templates/lldp/lldpd.j2 b/data/templates/lldp/lldpd.j2 new file mode 100644 index 000000000..3c499197d --- /dev/null +++ b/data/templates/lldp/lldpd.j2 @@ -0,0 +1,2 @@ +### Autogenerated by lldp.py ### +DAEMON_ARGS="-M 4 {{ '-x' if snmp.enable is vyos_defined }} {{ '-c' if legacy_protocols.cdp is vyos_defined }} {{ '-e' if legacy_protocols.edp is vyos_defined }} {{ '-f' if legacy_protocols.fdp is vyos_defined }} {{ '-s' if legacy_protocols.sonmp is vyos_defined }}" diff --git a/data/templates/lldp/lldpd.tmpl b/data/templates/lldp/lldpd.tmpl deleted file mode 100644 index 3db955b48..000000000 --- a/data/templates/lldp/lldpd.tmpl +++ /dev/null @@ -1,3 +0,0 @@ -### Autogenerated by lldp.py ### -DAEMON_ARGS="-M 4{% if options.snmp %} -x{% endif %}{% if options.cdp %} -c{% endif %}{% if options.edp %} -e{% endif %}{% if options.fdp %} -f{% endif %}{% if options.sonmp %} -s{% endif %}" - diff --git a/data/templates/lldp/vyos.conf.j2 b/data/templates/lldp/vyos.conf.j2 new file mode 100644 index 000000000..ec84231d8 --- /dev/null +++ b/data/templates/lldp/vyos.conf.j2 @@ -0,0 +1,25 @@ +### Autogenerated by lldp.py ### + +configure system platform VyOS +configure system description "VyOS {{ version }}" +{% if interface is vyos_defined %} +{% set tmp = [] %} +{% for iface, iface_options in interface.items() if not iface_options.disable %} +{% if iface == 'all' %} +{% set iface = '*' %} +{% endif %} +{% set _ = tmp.append(iface) %} +{% if iface_options.location is vyos_defined %} +{% if iface_options.location.elin is vyos_defined %} +configure ports {{ iface }} med location elin "{{ iface_options.location.elin }}" +{% endif %} +{% if iface_options.location.coordinate_based is vyos_defined %} +configure ports {{ iface }} med location coordinate latitude "{{ iface_options.location.coordinate_based.latitude }}" longitude "{{ iface_options.location.coordinate_based.longitude }}" altitude "{{ iface_options.location.coordinate_based.altitude }}m" datum "{{ iface_options.location.coordinate_based.datum }}" +{% endif %} +{% endif %} +{% endfor %} +configure system interface pattern "{{ tmp | join(",") }}" +{% endif %} +{% if management_address is vyos_defined %} +configure system ip management pattern {{ management_address | join(",") }} +{% endif %} diff --git a/data/templates/lldp/vyos.conf.tmpl b/data/templates/lldp/vyos.conf.tmpl deleted file mode 100644 index 07bbaf604..000000000 --- a/data/templates/lldp/vyos.conf.tmpl +++ /dev/null @@ -1,20 +0,0 @@ -### Autogenerated by lldp.py ### - -configure system platform VyOS -configure system description "VyOS {{ options.description }}" -{% if options.listen_on %} -configure system interface pattern "{{ ( options.listen_on | select('equalto','all') | map('replace','all','*') | list + options.listen_on | select('equalto','!all') | map('replace','!all','!*') | list + options.listen_on | reject('equalto','all') | reject('equalto','!all') | list ) | unique | join(",") }}" -{% endif %} -{% if options.mgmt_addr %} -configure system ip management pattern {{ options.mgmt_addr | join(",") }} -{% endif %} -{% for loc in location %} -{% if loc.elin %} -configure ports {{ loc.name }} med location elin "{{ loc.elin }}" -{% endif %} -{% if loc.coordinate_based %} -configure ports {{ loc.name }} med location coordinate {% if loc.coordinate_based.latitude %}latitude {{ loc.coordinate_based.latitude }}{% endif %} {% if loc.coordinate_based.longitude %}longitude {{ loc.coordinate_based.longitude }}{% endif %} {% if loc.coordinate_based.altitude %}altitude {{ loc.coordinate_based.altitude }} m{% endif %} {% if loc.coordinate_based.datum %}datum {{ loc.coordinate_based.datum }}{% endif %} -{% endif %} - - -{% endfor %} diff --git a/data/templates/login/authorized_keys.j2 b/data/templates/login/authorized_keys.j2 new file mode 100644 index 000000000..aabca47cf --- /dev/null +++ b/data/templates/login/authorized_keys.j2 @@ -0,0 +1,9 @@ +### Automatically generated by system-login.py ### + +{% if authentication.public_keys is vyos_defined %} +{% for key, key_options in authentication.public_keys.items() %} +{# The whitespace after options is wisely chosen #} +{{ key_options.options ~ ' ' if key_options.options is vyos_defined }}{{ key_options.type }} {{ key_options.key }} {{ key }} +{% endfor %} +{% endif %} + diff --git a/data/templates/login/authorized_keys.tmpl b/data/templates/login/authorized_keys.tmpl deleted file mode 100644 index 639a80e1d..000000000 --- a/data/templates/login/authorized_keys.tmpl +++ /dev/null @@ -1,9 +0,0 @@ -### Automatically generated by system-login.py ### - -{% if authentication is defined and authentication.public_keys is defined and authentication.public_keys is not none %} -{% for key, key_options in authentication.public_keys.items() %} -{# The whitespace after options is wisely chosen #} -{{ key_options.options + ' ' if key_options.options is defined }}{{ key_options.type }} {{ key_options.key }} {{ key }} -{% endfor %} -{% endif %} - diff --git a/data/templates/login/pam_radius_auth.conf.j2 b/data/templates/login/pam_radius_auth.conf.j2 new file mode 100644 index 000000000..1105b60e5 --- /dev/null +++ b/data/templates/login/pam_radius_auth.conf.j2 @@ -0,0 +1,36 @@ +# Automatically generated by system-login.py +# RADIUS configuration file + +{% if radius is vyos_defined %} +{# RADIUS IPv6 source address must be specified in [] notation #} +{% set source_address = namespace() %} +{% if radius.source_address is vyos_defined %} +{% for address in radius.source_address %} +{% if address | is_ipv4 %} +{% set source_address.ipv4 = address %} +{% elif address | is_ipv6 %} +{% set source_address.ipv6 = "[" + address + "]" %} +{% endif %} +{% endfor %} +{% endif %} +{% if radius.server is vyos_defined %} +# server[:port] shared_secret timeout source_ip +{# .items() returns a tuple of two elements: key and value. 1 relates to the 2nd element i.e. the value and .priority relates to the key from the internal dict #} +{% for server, options in radius.server.items() | sort(attribute='1.priority') if not options.disabled %} +{# RADIUS IPv6 servers must be specified in [] notation #} +{% if server | is_ipv4 %} +{{ server }}:{{ options.port }} {{ "%-25s" | format(options.key) }} {{ "%-10s" | format(options.timeout) }} {{ source_address.ipv4 if source_address.ipv4 is vyos_defined }} +{% else %} +[{{ server }}]:{{ options.port }} {{ "%-25s" | format(options.key) }} {{ "%-10s" | format(options.timeout) }} {{ source_address.ipv6 if source_address.ipv6 is vyos_defined }} +{% endif %} +{% endfor %} +{% endif %} + +priv-lvl 15 +mapped_priv_user radius_priv_user + +{% if radius.vrf is vyos_defined %} +vrf-name {{ radius.vrf }} +{% endif %} +{% endif %} + diff --git a/data/templates/login/pam_radius_auth.conf.tmpl b/data/templates/login/pam_radius_auth.conf.tmpl deleted file mode 100644 index fad8e7dcb..000000000 --- a/data/templates/login/pam_radius_auth.conf.tmpl +++ /dev/null @@ -1,36 +0,0 @@ -# Automatically generated by system-login.py -# RADIUS configuration file - -{% if radius is defined and radius is not none %} -{# RADIUS IPv6 source address must be specified in [] notation #} -{% set source_address = namespace() %} -{% if radius.source_address is defined and radius.source_address is not none %} -{% for address in radius.source_address %} -{% if address | is_ipv4 %} -{% set source_address.ipv4 = address %} -{% elif address | is_ipv6 %} -{% set source_address.ipv6 = "[" + address + "]" %} -{% endif %} -{% endfor %} -{% endif %} -{% if radius.server is defined and radius.server is not none %} -# server[:port] shared_secret timeout source_ip -{# .items() returns a tuple of two elements: key and value. 1 relates to the 2nd element i.e. the value and .priority relates to the key from the internal dict #} -{% for server, options in radius.server.items() | sort(attribute='1.priority') if not options.disabled %} -{# RADIUS IPv6 servers must be specified in [] notation #} -{% if server | is_ipv4 %} -{{ server }}:{{ options.port }} {{ "%-25s" | format(options.key) }} {{ "%-10s" | format(options.timeout) }} {{ source_address.ipv4 if source_address.ipv4 is defined }} -{% else %} -[{{ server }}]:{{ options.port }} {{ "%-25s" | format(options.key) }} {{ "%-10s" | format(options.timeout) }} {{ source_address.ipv6 if source_address.ipv6 is defined }} -{% endif %} -{% endfor %} -{% endif %} - -priv-lvl 15 -mapped_priv_user radius_priv_user - -{% if radius.vrf is defined and radius.vrf is not none %} -vrf-name {{ radius.vrf }} -{% endif %} -{% endif %} - diff --git a/data/templates/logs/logrotate/vyos-atop.j2 b/data/templates/logs/logrotate/vyos-atop.j2 new file mode 100644 index 000000000..2d078f379 --- /dev/null +++ b/data/templates/logs/logrotate/vyos-atop.j2 @@ -0,0 +1,20 @@ +/var/log/atop/atop.log { + daily + dateext + dateformat _%Y-%m-%d_%H-%M-%S + maxsize {{ max_size }}M + missingok + nocompress + nocreate + nomail + rotate {{ rotate }} + prerotate + # stop the service + systemctl stop atop.service + endscript + postrotate + # start atop service again + systemctl start atop.service + endscript +} + diff --git a/data/templates/logs/logrotate/vyos-rsyslog.j2 b/data/templates/logs/logrotate/vyos-rsyslog.j2 new file mode 100644 index 000000000..f2e4d2ab2 --- /dev/null +++ b/data/templates/logs/logrotate/vyos-rsyslog.j2 @@ -0,0 +1,13 @@ +/var/log/messages { + create + missingok + nomail + notifempty + rotate {{ rotate }} + size {{ max_size }}M + postrotate + # inform rsyslog service about rotation + /usr/lib/rsyslog/rsyslog-rotate + endscript +} + diff --git a/data/templates/macsec/wpa_supplicant.conf.tmpl b/data/templates/macsec/wpa_supplicant.conf.j2 index 5b353def8..0ac7cb860 100644 --- a/data/templates/macsec/wpa_supplicant.conf.tmpl +++ b/data/templates/macsec/wpa_supplicant.conf.j2 @@ -45,10 +45,9 @@ network={ # - the key server has decided to enable MACsec # 0: Encrypt traffic (default) # 1: Integrity only - macsec_integ_only={{ '0' if security is defined and security.encrypt is defined else '1' }} + macsec_integ_only={{ '0' if security.encrypt is vyos_defined else '1' }} -{% if security is defined %} -{% if security.encrypt is defined %} +{% if security.encrypt is vyos_defined %} # mka_cak, mka_ckn, and mka_priority: IEEE 802.1X/MACsec pre-shared key mode # This allows to configure MACsec with a pre-shared key using a (CAK,CKN) pair. # In this mode, instances of wpa_supplicant can act as MACsec peers. The peer @@ -63,9 +62,9 @@ network={ # mka_priority (Priority of MKA Actor) is in 0..255 range with 255 being # default priority mka_priority={{ security.mka.priority }} -{% endif %} +{% endif %} -{% if security.replay_window is defined %} +{% if security.replay_window is vyos_defined %} # macsec_replay_protect: IEEE 802.1X/MACsec replay protection # This setting applies only when MACsec is in use, i.e., # - macsec_policy is enabled @@ -83,7 +82,6 @@ network={ # 0: No replay window, strict check (default) # 1..2^32-1: number of packets that could be misordered macsec_replay_window={{ security.replay_window }} -{% endif %} {% endif %} } diff --git a/data/templates/mdns-repeater/avahi-daemon.tmpl b/data/templates/mdns-repeater/avahi-daemon.j2 index 65bb5a306..65bb5a306 100644 --- a/data/templates/mdns-repeater/avahi-daemon.tmpl +++ b/data/templates/mdns-repeater/avahi-daemon.j2 diff --git a/data/templates/monitoring/override.conf.j2 b/data/templates/monitoring/override.conf.j2 new file mode 100644 index 000000000..f8f150791 --- /dev/null +++ b/data/templates/monitoring/override.conf.j2 @@ -0,0 +1,7 @@ +[Unit] +After=vyos-router.service +ConditionPathExists=/run/telegraf/vyos-telegraf.conf +[Service] +Environment=INFLUX_TOKEN={{ authentication.token }} +CapabilityBoundingSet=CAP_NET_RAW CAP_NET_ADMIN CAP_SYS_ADMIN +AmbientCapabilities=CAP_NET_RAW CAP_NET_ADMIN diff --git a/data/templates/monitoring/syslog_telegraf.j2 b/data/templates/monitoring/syslog_telegraf.j2 new file mode 100644 index 000000000..cdcbd92a4 --- /dev/null +++ b/data/templates/monitoring/syslog_telegraf.j2 @@ -0,0 +1,5 @@ +# Generated by /usr/libexec/vyos/conf_mode/service_monitoring_telegraf.py + +$ModLoad omuxsock +$OMUxSockSocket /run/telegraf/telegraf_syslog.sock +*.notice :omuxsock: diff --git a/data/templates/monitoring/systemd_vyos_telegraf_service.j2 b/data/templates/monitoring/systemd_vyos_telegraf_service.j2 new file mode 100644 index 000000000..234ef5586 --- /dev/null +++ b/data/templates/monitoring/systemd_vyos_telegraf_service.j2 @@ -0,0 +1,16 @@ +[Unit] +Description=The plugin-driven server agent for reporting metrics into InfluxDB +Documentation=https://github.com/influxdata/telegraf +After=network.target + +[Service] +EnvironmentFile=-/etc/default/telegraf +User=telegraf +ExecStart=/usr/bin/telegraf -config /run/telegraf/vyos-telegraf.conf -config-directory /etc/telegraf/telegraf.d $TELEGRAF_OPTS +ExecReload=/bin/kill -HUP $MAINPID +Restart=on-failure +RestartForceExitStatus=SIGPIPE +KillMode=control-group + +[Install] +WantedBy=multi-user.target diff --git a/data/templates/monitoring/telegraf.j2 b/data/templates/monitoring/telegraf.j2 new file mode 100644 index 000000000..a732fb5de --- /dev/null +++ b/data/templates/monitoring/telegraf.j2 @@ -0,0 +1,122 @@ +# Generated by /usr/libexec/vyos/conf_mode/service_monitoring_telegraf.py + +[agent] + interval = "15s" + round_interval = true + metric_batch_size = 1000 + metric_buffer_limit = 10000 + collection_jitter = "5s" + flush_interval = "15s" + flush_jitter = "0s" + precision = "" + debug = false + quiet = false + logfile = "" + hostname = "" + omit_hostname = false +{% if azure_data_explorer is vyos_defined %} +### Azure Data Explorer ### +[[outputs.azure_data_explorer]] + ## The URI property of the Azure Data Explorer resource on Azure + endpoint_url = "{{ azure_data_explorer.url }}" + + ## The Azure Data Explorer database that the metrics will be ingested into. + ## The plugin will NOT generate this database automatically, it's expected that this database already exists before ingestion. + database = "{{ azure_data_explorer.database }}" + metrics_grouping_type = "{{ azure_data_explorer.group_metrics }}" + + ## Name of the single table to store all the metrics (Only needed if metrics_grouping_type is "SingleTable"). +{% if azure_data_explorer.table is vyos_defined and azure_data_explorer.group_metrics == 'SingleTable' %} + table_name = "{{ azure_data_explorer.table }}" +{% endif %} +### End Azure Data Explorer ### +{% endif %} +{% if influxdb_configured is vyos_defined %} +### InfluxDB2 ### +[[outputs.influxdb_v2]] + urls = ["{{ url }}:{{ port }}"] + insecure_skip_verify = true + token = "$INFLUX_TOKEN" + organization = "{{ authentication.organization }}" + bucket = "{{ bucket }}" +### End InfluxDB2 ### +{% endif %} +{% if prometheus_client is vyos_defined %} +### Prometheus ### +[[outputs.prometheus_client]] + ## Address to listen on + listen = "{{ prometheus_client.listen_address if prometheus_client.listen_address is vyos_defined else '' }}:{{ prometheus_client.port }}" + metric_version = {{ prometheus_client.metric_version }} +{% if prometheus_client.authentication.username is vyos_defined and prometheus_client.authentication.password is vyos_defined %} + ## Use HTTP Basic Authentication + basic_username = "{{ prometheus_client.authentication.username }}" + basic_password = "{{ prometheus_client.authentication.password }}" +{% endif %} +{% if prometheus_client.allow_from is vyos_defined %} + ip_range = {{ prometheus_client.allow_from }} +{% endif %} +### End Prometheus ### +{% endif %} +{% if splunk is vyos_defined %} +### Splunk ### +[[outputs.http]] + ## URL is the address to send metrics to + url = "{{ splunk.url }}" + ## Timeout for HTTP message + # timeout = "5s" + ## Use TLS but skip chain & host verification +{% if splunk.authentication.insecure is vyos_defined %} + insecure_skip_verify = true +{% endif %} + ## Data format to output + data_format = "splunkmetric" + ## Provides time, index, source overrides for the HEC + splunkmetric_hec_routing = true + ## Additional HTTP headers + [outputs.http.headers] + # Should be set manually to "application/json" for json data_format + Content-Type = "application/json" + Authorization = "Splunk {{ splunk.authentication.token }}" + X-Splunk-Request-Channel = "{{ splunk.authentication.token }}" +### End Splunk ### +{% endif %} +[[inputs.cpu]] + percpu = true + totalcpu = true + collect_cpu_time = false + report_active = false +[[inputs.disk]] + ignore_fs = ["devtmpfs", "devfs"] +[[inputs.diskio]] +[[inputs.mem]] +[[inputs.net]] +[[inputs.system]] +[[inputs.netstat]] +[[inputs.processes]] +[[inputs.kernel]] +[[inputs.interrupts]] +[[inputs.linux_sysctl_fs]] +[[inputs.systemd_units]] +[[inputs.conntrack]] + files = ["ip_conntrack_count","ip_conntrack_max","nf_conntrack_count","nf_conntrack_max"] + dirs = ["/proc/sys/net/ipv4/netfilter","/proc/sys/net/netfilter"] +[[inputs.ethtool]] + interface_include = {{ interfaces_ethernet }} +[[inputs.ntpq]] + dns_lookup = true +[[inputs.internal]] +[[inputs.nstat]] +[[inputs.syslog]] + server = "unixgram:///run/telegraf/telegraf_syslog.sock" + best_effort = true + syslog_standard = "RFC3164" +{% if influxdb_configured is vyos_defined %} +[[inputs.exec]] + commands = [ + "{{ custom_scripts_dir }}/show_firewall_input_filter.py", + "{{ custom_scripts_dir }}/show_interfaces_input_filter.py", + "{{ custom_scripts_dir }}/vyos_services_input_filter.py" + ] + timeout = "10s" + data_format = "influx" +{% endif %} diff --git a/data/templates/ndppd/ndppd.conf.j2 b/data/templates/ndppd/ndppd.conf.j2 new file mode 100644 index 000000000..120fa0a64 --- /dev/null +++ b/data/templates/ndppd/ndppd.conf.j2 @@ -0,0 +1,44 @@ +######################################################## +# +# autogenerated by nat66.py +# +# The configuration file must define one upstream +# interface. +# +# For some services, such as nat66, because it runs +# stateless, it needs to rely on NDP Proxy to respond +# to NDP requests. +# +# When using nat66 source rules, NDP Proxy needs +# to be enabled +# +######################################################## + +{% set global = namespace(ndppd_interfaces = [],ndppd_prefixs = []) %} +{% if source.rule is vyos_defined %} +{% for rule, config in source.rule.items() if config.disable is not defined %} +{% if config.outbound_interface is vyos_defined %} +{% if config.outbound_interface not in global.ndppd_interfaces %} +{% set global.ndppd_interfaces = global.ndppd_interfaces + [config.outbound_interface] %} +{% endif %} +{% if config.translation.address is vyos_defined and config.translation.address | is_ip_network %} +{% set global.ndppd_prefixs = global.ndppd_prefixs + [{'interface':config.outbound_interface,'rule':config.translation.address}] %} +{% endif %} +{% endif %} +{% endfor %} +{% endif %} + +{% for interface in global.ndppd_interfaces %} +proxy {{ interface }} { + router yes + timeout 500 + ttl 30000 +{% for map in global.ndppd_prefixs %} +{% if map.interface == interface %} + rule {{ map.rule }} { + static + } +{% endif %} +{% endfor %} +} +{% endfor %} diff --git a/data/templates/ndppd/ndppd.conf.tmpl b/data/templates/ndppd/ndppd.conf.tmpl deleted file mode 100644 index 502dab5b8..000000000 --- a/data/templates/ndppd/ndppd.conf.tmpl +++ /dev/null @@ -1,44 +0,0 @@ -######################################################## -# -# autogenerated by nat66.py -# -# The configuration file must define one upstream -# interface. -# -# For some services, such as nat66, because it runs -# stateless, it needs to rely on NDP Proxy to respond -# to NDP requests. -# -# When using nat66 source rules, NDP Proxy needs -# to be enabled -# -######################################################## - -{% set global = namespace(ndppd_interfaces = [],ndppd_prefixs = []) %} -{% if source is defined and source.rule is defined and source.rule is not none %} -{% for rule, config in source.rule.items() if config.disable is not defined %} -{% if config.outbound_interface is defined %} -{% if config.outbound_interface not in global.ndppd_interfaces %} -{% set global.ndppd_interfaces = global.ndppd_interfaces + [config.outbound_interface] %} -{% endif %} -{% if config.translation is defined and config.translation.address is defined and config.translation.address | is_ip_network %} -{% set global.ndppd_prefixs = global.ndppd_prefixs + [{'interface':config.outbound_interface,'rule':config.translation.address}] %} -{% endif %} -{% endif %} -{% endfor %} -{% endif %} - -{% for interface in global.ndppd_interfaces %} -proxy {{ interface }} { - router yes - timeout 500 - ttl 30000 -{% for map in global.ndppd_prefixs %} -{% if map.interface == interface %} - rule {{ map.rule }} { - static - } -{% endif %} -{% endfor %} -} -{% endfor %} diff --git a/data/templates/netflow/uacctd.conf.tmpl b/data/templates/netflow/uacctd.conf.tmpl deleted file mode 100644 index 1c183bb20..000000000 --- a/data/templates/netflow/uacctd.conf.tmpl +++ /dev/null @@ -1,72 +0,0 @@ -# Genereated from VyOS configuration -daemonize: true -promisc: false -pidfile: /var/run/uacctd.pid -uacctd_group: 2 -uacctd_nl_size: 2097152 -snaplen: {{ snaplen }} -{% if templatecfg['enable-egress'] != none %} -aggregate: in_iface,out_iface,src_mac,dst_mac,vlan,src_host,dst_host,src_port,dst_port,proto,tos,flows -{% else %} -aggregate: in_iface,src_mac,dst_mac,vlan,src_host,dst_host,src_port,dst_port,proto,tos,flows -{% endif %} -plugin_pipe_size: {{ templatecfg['plugin_pipe_size'] }} -plugin_buffer_size: {{ templatecfg['plugin_buffer_size'] }} -{% if templatecfg['syslog-facility'] != none %} -syslog: {{ templatecfg['syslog-facility'] }} -{% endif %} -{% if templatecfg['disable-imt'] == none %} -imt_path: /tmp/uacctd.pipe -imt_mem_pools_number: 169 -{% endif %} -plugins: {% if templatecfg['netflow']['servers'] != none %} -{% for server in templatecfg['netflow']['servers'] %} -{% if loop.last %}nfprobe[nf_{{ server['address'] }}]{% else %}nfprobe[nf_{{ server['address'] }}],{% endif %} -{% endfor %} -{% set plugins_presented = true %} -{% endif %} -{% if templatecfg['sflow']['servers'] != none %} -{% if plugins_presented %} -{% for server in templatecfg['sflow']['servers'] %},sfprobe[sf_{{ server['address'] }}]{% endfor %} -{% else %} -{% for server in templatecfg['sflow']['servers'] %} -{% if loop.last %}sfprobe[sf_{{ server['address'] }}]{% else %}sfprobe[sf_{{ server['address'] }}],{% endif %} -{% endfor %} -{% endif %} -{% set plugins_presented = true %} -{% endif %} -{% if templatecfg['disable-imt'] == none %} -{% if plugins_presented %},memory{% else %}memory{% endif %} -{% endif %} - -{% if templatecfg['netflow']['servers'] != none %} -{% for server in templatecfg['netflow']['servers'] %} -nfprobe_receiver[nf_{{ server['address'] }}]: {{ server['address'] }}:{{ server['port'] }} -nfprobe_version[nf_{{ server['address'] }}]: {{ templatecfg['netflow']['version'] }} -{% if templatecfg['netflow']['engine-id'] != none %} -nfprobe_engine[nf_{{ server['address'] }}]: {{ templatecfg['netflow']['engine-id'] }} -{% endif %} -{% if templatecfg['netflow']['max-flows'] != none %} -nfprobe_maxflows[nf_{{ server['address'] }}]: {{ templatecfg['netflow']['max-flows'] }} -{% endif %} -{% if templatecfg['netflow']['sampling-rate'] != none %} -sampling_rate[nf_{{ server['address'] }}]: {{ templatecfg['netflow']['sampling-rate'] }} -{% endif %} -{% if templatecfg['netflow']['source-ip'] != none %} -nfprobe_source_ip[nf_{{ server['address'] }}]: {{ templatecfg['netflow']['source-ip'] }} -{% endif %} -{% if templatecfg['netflow']['timeout_string'] != '' %} -nfprobe_timeouts[nf_{{ server['address'] }}]: {{ templatecfg['netflow']['timeout_string'] }} -{% endif %} -{% endfor %} -{% endif %} - -{% if templatecfg['sflow']['servers'] != none %} -{% for server in templatecfg['sflow']['servers'] %} -sfprobe_receiver[sf_{{ server['address'] }}]: {{ server['address'] }}:{{ server['port'] }} -sfprobe_agentip[sf_{{ server['address'] }}]: {{ templatecfg['sflow']['agent-address'] }} -{% if templatecfg['sflow']['sampling-rate'] != none %} -sampling_rate[sf_{{ server['address'] }}]: {{ templatecfg['sflow']['sampling-rate'] }} -{% endif %} -{% endfor %} -{% endif %} diff --git a/data/templates/nhrp/opennhrp.conf.j2 b/data/templates/nhrp/opennhrp.conf.j2 new file mode 100644 index 000000000..c040a8f14 --- /dev/null +++ b/data/templates/nhrp/opennhrp.conf.j2 @@ -0,0 +1,42 @@ +{# j2lint: disable=jinja-variable-format #} +# Created by VyOS - manual changes will be overwritten + +{% if tunnel is vyos_defined %} +{% for name, tunnel_conf in tunnel.items() %} +{% set type = 'spoke' if tunnel_conf.map is vyos_defined or tunnel_conf.dynamic_map is vyos_defined else 'hub' %} +{% set profile_name = profile_map[name] if profile_map is vyos_defined and name in profile_map else '' %} +interface {{ name }} #{{ type }} {{ profile_name }} +{% if tunnel_conf.map is vyos_defined %} +{% for map, map_conf in tunnel_conf.map.items() %} +{% set cisco = ' cisco' if map_conf.cisco is vyos_defined else '' %} +{% set register = ' register' if map_conf.register is vyos_defined else '' %} + map {{ map }} {{ map_conf.nbma_address }}{{ register }}{{ cisco }} +{% endfor %} +{% endif %} +{% if tunnel_conf.dynamic_map is vyos_defined %} +{% for map, map_conf in tunnel_conf.dynamic_map.items() %} + dynamic-map {{ map }} {{ map_conf.nbma_domain_name }} +{% endfor %} +{% endif %} +{% if tunnel_conf.cisco_authentication is vyos_defined %} + cisco-authentication {{ tunnel_conf.cisco_authentication }} +{% endif %} +{% if tunnel_conf.holding_time is vyos_defined %} + holding-time {{ tunnel_conf.holding_time }} +{% endif %} +{% if tunnel_conf.multicast is vyos_defined %} + multicast {{ tunnel_conf.multicast }} +{% endif %} +{% for key in ['non_caching', 'redirect', 'shortcut', 'shortcut_destination'] %} +{% if key in tunnel_conf %} + {{ key | replace("_", "-") }} +{% endif %} +{% endfor %} +{% if tunnel_conf.shortcut_target is vyos_defined %} +{% for target, shortcut_conf in tunnel_conf.shortcut_target.items() %} + shortcut-target {{ target }}{{ ' holding-time ' + shortcut_conf.holding_time if shortcut_conf.holding_time is vyos_defined }} +{% endfor %} +{% endif %} + +{% endfor %} +{% endif %} diff --git a/data/templates/nhrp/opennhrp.conf.tmpl b/data/templates/nhrp/opennhrp.conf.tmpl deleted file mode 100644 index 948327198..000000000 --- a/data/templates/nhrp/opennhrp.conf.tmpl +++ /dev/null @@ -1,41 +0,0 @@ -# Created by VyOS - manual changes will be overwritten - -{% if tunnel is defined and tunnel is not none %} -{% for name, tunnel_conf in tunnel.items() %} -{% set type = 'spoke' if tunnel_conf.map is defined or tunnel_conf.dynamic_map is defined else 'hub' %} -{% set profile_name = profile_map[name] if profile_map is defined and name in profile_map else '' %} -interface {{ name }} #{{ type }} {{ profile_name }} -{% if tunnel_conf.map is defined and tunnel_conf.map is not none %} -{% for map, map_conf in tunnel_conf.map.items() %} -{% set cisco = ' cisco' if map_conf.cisco is defined else '' %} -{% set register = ' register' if map_conf.register is defined else '' %} - map {{ map }} {{ map_conf.nbma_address }}{{ register }}{{ cisco }} -{% endfor %} -{% endif %} -{% if tunnel_conf.dynamic_map is defined and tunnel_conf.dynamic_map is not none %} -{% for map, map_conf in tunnel_conf.dynamic_map.items() %} - dynamic-map {{ map }} {{ map_conf.nbma_domain_name }} -{% endfor %} -{% endif %} -{% if tunnel_conf.cisco_authentication is defined and tunnel_conf.cisco_authentication is not none %} - cisco-authentication {{ tunnel_conf.cisco_authentication }} -{% endif %} -{% if tunnel_conf.holding_time is defined and tunnel_conf.holding_time is not none %} - holding-time {{ tunnel_conf.holding_time }} -{% endif %} -{% if tunnel_conf.multicast is defined and tunnel_conf.multicast is not none %} - multicast {{ tunnel_conf.multicast }} -{% endif %} -{% for key in ['non_caching', 'redirect', 'shortcut', 'shortcut_destination'] %} -{% if key in tunnel_conf %} - {{ key | replace("_", "-") }} -{% endif %} -{% endfor %} -{% if tunnel_conf.shortcut_target is defined and tunnel_conf.shortcut_target is not none %} -{% for target, shortcut_conf in tunnel_conf.shortcut_target.items() %} - shortcut-target {{ target }} {{ shortcut_conf.holding_time if shortcut_conf.holding_time is defined else '' }} -{% endfor %} -{% endif %} - -{% endfor %} -{% endif %} diff --git a/data/templates/ntp/ntpd.conf.tmpl b/data/templates/ntp/ntpd.conf.j2 index 38e68f24f..da610051e 100644 --- a/data/templates/ntp/ntpd.conf.tmpl +++ b/data/templates/ntp/ntpd.conf.j2 @@ -15,27 +15,28 @@ restrict -6 ::1 # # Configurable section # -{% if server is defined and server is not none %} -{% for server, config in server.items() %} -{% set association = 'server' %} -{% if config.pool is defined %} -{% set association = 'pool' %} -{% endif %} -{{ association }} {{ server | replace('_', '-') }} iburst {{ 'noselect' if config.noselect is defined }} {{ 'preempt' if config.preempt is defined }} {{ 'prefer' if config.prefer is defined }} -{% endfor %} +{% if server is vyos_defined %} +{% for server, config in server.items() %} +{% set association = 'server' %} +{% if config.pool is vyos_defined %} +{% set association = 'pool' %} +{% endif %} +{{ association }} {{ server | replace('_', '-') }} iburst {{ 'noselect' if config.noselect is vyos_defined }} {{ 'preempt' if config.preempt is vyos_defined }} {{ 'prefer' if config.prefer is vyos_defined }} +{% endfor %} {% endif %} -{% if allow_clients is defined and allow_clients.address is defined %} +{% if allow_clients.address is vyos_defined %} # Allowed clients configuration -{% for address in allow_clients.address %} -restrict {{ address|address_from_cidr }} mask {{ address|netmask_from_cidr }} nomodify notrap nopeer -{% endfor %} +restrict default ignore +{% for address in allow_clients.address %} +restrict {{ address | address_from_cidr }} mask {{ address | netmask_from_cidr }} nomodify notrap nopeer +{% endfor %} {% endif %} {% if listen_address %} # NTP should listen on configured addresses only interface ignore wildcard -{% for address in listen_address %} +{% for address in listen_address %} interface listen {{ address }} -{% endfor %} +{% endfor %} {% endif %} diff --git a/data/templates/ntp/override.conf.j2 b/data/templates/ntp/override.conf.j2 new file mode 100644 index 000000000..6fed9d7d2 --- /dev/null +++ b/data/templates/ntp/override.conf.j2 @@ -0,0 +1,14 @@ +{% set vrf_command = 'ip vrf exec ' ~ vrf ~ ' ' if vrf is vyos_defined else '' %} +[Unit] +StartLimitIntervalSec=0 +ConditionPathExists={{ config_file }} +After=vyos-router.service + +[Service] +ExecStart= +ExecStart={{ vrf_command }}/usr/sbin/ntpd -g -p {{ config_file | replace('.conf', '.pid') }} -c {{ config_file }} -u ntp:ntp +PIDFile= +PIDFile={{ config_file | replace('.conf', '.pid') }} +Restart=always +RestartSec=10 + diff --git a/data/templates/ntp/override.conf.tmpl b/data/templates/ntp/override.conf.tmpl deleted file mode 100644 index 28eb61b21..000000000 --- a/data/templates/ntp/override.conf.tmpl +++ /dev/null @@ -1,14 +0,0 @@ -{% set vrf_command = 'ip vrf exec ' + vrf + ' ' if vrf is defined else '' %} -[Unit] -StartLimitIntervalSec=0 -ConditionPathExists={{config_file}} -After=vyos-router.service - -[Service] -ExecStart= -ExecStart={{vrf_command}}/usr/sbin/ntpd -g -p {{config_file | replace('.conf', '.pid') }} -c {{config_file}} -u ntp:ntp -PIDFile= -PIDFile={{config_file | replace('.conf', '.pid') }} -Restart=always -RestartSec=10 - diff --git a/data/templates/ocserv/ocserv_config.tmpl b/data/templates/ocserv/ocserv_config.j2 index 0be805235..8418a2185 100644 --- a/data/templates/ocserv/ocserv_config.tmpl +++ b/data/templates/ocserv/ocserv_config.j2 @@ -8,19 +8,27 @@ run-as-group = daemon {% if "radius" in authentication.mode %} auth = "radius [config=/run/ocserv/radiusclient.conf]" +{% elif "local" in authentication.mode %} +{% if authentication.mode.local == "password-otp" %} +auth = "plain[passwd=/run/ocserv/ocpasswd,otp=/run/ocserv/users.oath]" +{% elif authentication.mode.local == "otp" %} +auth = "plain[otp=/run/ocserv/users.oath]" +{% else %} +auth = "plain[/run/ocserv/ocpasswd]" +{% endif %} {% else %} auth = "plain[/run/ocserv/ocpasswd]" {% endif %} -{% if ssl.certificate is defined %} +{% if ssl.certificate is vyos_defined %} server-cert = /run/ocserv/cert.pem server-key = /run/ocserv/cert.key -{% if ssl.passphrase is defined %} +{% if ssl.passphrase is vyos_defined %} key-pin = {{ ssl.passphrase }} -{% endif %} +{% endif %} {% endif %} -{% if ssl.ca_certificate is defined %} +{% if ssl.ca_certificate is vyos_defined %} ca-cert = /run/ocserv/ca.pem {% endif %} @@ -42,7 +50,8 @@ rekey-method = ssl try-mtu-discovery = true cisco-client-compat = true dtls-legacy = true - +max-ban-score = 80 +ban-reset-time = 300 # The name to use for the tun device device = sslvpn @@ -50,33 +59,33 @@ device = sslvpn # An alternative way of specifying the network: {% if network_settings %} # DNS settings -{% if network_settings.name_server is string %} +{% if network_settings.name_server is string %} dns = {{ network_settings.name_server }} -{% else %} -{% for dns in network_settings.name_server %} +{% else %} +{% for dns in network_settings.name_server %} dns = {{ dns }} -{% endfor %} -{% endif %} +{% endfor %} +{% endif %} # IPv4 network pool -{% if network_settings.client_ip_settings %} -{% if network_settings.client_ip_settings.subnet %} +{% if network_settings.client_ip_settings %} +{% if network_settings.client_ip_settings.subnet %} ipv4-network = {{ network_settings.client_ip_settings.subnet }} +{% endif %} {% endif %} -{% endif %} # IPv6 network pool -{% if network_settings.client_ipv6_pool %} -{% if network_settings.client_ipv6_pool.prefix %} +{% if network_settings.client_ipv6_pool %} +{% if network_settings.client_ipv6_pool.prefix %} ipv6-network = {{ network_settings.client_ipv6_pool.prefix }} ipv6-subnet-prefix = {{ network_settings.client_ipv6_pool.mask }} +{% endif %} {% endif %} -{% endif %} {% endif %} {% if network_settings.push_route is string %} route = {{ network_settings.push_route }} {% else %} -{% for route in network_settings.push_route %} +{% for route in network_settings.push_route %} route = {{ route }} -{% endfor %} +{% endfor %} {% endif %} diff --git a/data/templates/ocserv/ocserv_otp_usr.j2 b/data/templates/ocserv/ocserv_otp_usr.j2 new file mode 100644 index 000000000..b2511ed94 --- /dev/null +++ b/data/templates/ocserv/ocserv_otp_usr.j2 @@ -0,0 +1,8 @@ +#<token_type> <username> <pin> <secret_hex_key> <counter> <lastpass> <time> +{% if username is vyos_defined %} +{% for user, user_config in username.items() %} +{% if user_config.disable is not vyos_defined and user_config.otp is vyos_defined %} +{{ user_config.otp.token_tmpl }} {{ user }} {{ user_config.otp.pin | default("-", true) }} {{ user_config.otp.key }} +{% endif %} +{% endfor %} +{% endif %} diff --git a/data/templates/ocserv/ocserv_passwd.j2 b/data/templates/ocserv/ocserv_passwd.j2 new file mode 100644 index 000000000..30c79d66a --- /dev/null +++ b/data/templates/ocserv/ocserv_passwd.j2 @@ -0,0 +1,8 @@ +#<username>:<group>:<hash> +{% if username is vyos_defined %} +{% for user, user_config in username.items() %} +{% if user_config.disable is not vyos_defined %} +{{ user }}:*:{{ user_config.hash }} +{% endif %} +{% endfor %} +{% endif %}
\ No newline at end of file diff --git a/data/templates/ocserv/ocserv_passwd.tmpl b/data/templates/ocserv/ocserv_passwd.tmpl deleted file mode 100644 index ffadb4860..000000000 --- a/data/templates/ocserv/ocserv_passwd.tmpl +++ /dev/null @@ -1,6 +0,0 @@ -#<username>:<group>:<hash> -{% for user in username if username is defined %} -{% if not "disable" in username[user] %} -{{ user }}:*:{{ username[user].hash }} -{% endif %} -{% endfor %}
\ No newline at end of file diff --git a/data/templates/ocserv/radius_conf.tmpl b/data/templates/ocserv/radius_conf.j2 index 1712d83ef..b6612fee5 100644 --- a/data/templates/ocserv/radius_conf.tmpl +++ b/data/templates/ocserv/radius_conf.j2 @@ -1,13 +1,13 @@ ### generated by vpn_openconnect.py ### nas-identifier VyOS {% for srv in server %} -{% if not "disable" in server[srv] %} -{% if "port" in server[srv] %} -authserver {{ srv }}:{{server[srv]["port"]}} -{% else %} +{% if not "disable" in server[srv] %} +{% if "port" in server[srv] %} +authserver {{ srv }}:{{ server[srv]["port"] }} +{% else %} authserver {{ srv }} +{% endif %} {% endif %} -{% endif %} {% endfor %} radius_timeout {{ timeout }} {% if source_address %} @@ -15,7 +15,7 @@ bindaddr {{ source_address }} {% else %} bindaddr * {% endif %} -servers /run/ocserv/radius_servers +servers /run/ocserv/radius_servers dictionary /etc/radcli/dictionary default_realm radius_retries 3 diff --git a/data/templates/ocserv/radius_servers.j2 b/data/templates/ocserv/radius_servers.j2 new file mode 100644 index 000000000..302e91600 --- /dev/null +++ b/data/templates/ocserv/radius_servers.j2 @@ -0,0 +1,7 @@ +### generated by vpn_openconnect.py ### +# server key +{% for srv in server %} +{% if not "disable" in server[srv] %} +{{ srv }} {{ server[srv].key }} +{% endif %} +{% endfor %} diff --git a/data/templates/ocserv/radius_servers.tmpl b/data/templates/ocserv/radius_servers.tmpl deleted file mode 100644 index 7bacac992..000000000 --- a/data/templates/ocserv/radius_servers.tmpl +++ /dev/null @@ -1,7 +0,0 @@ -### generated by vpn_openconnect.py ### -# server key -{% for srv in server %} -{% if not "disable" in server[srv] %} -{{ srv }} {{ server[srv].key }} -{% endif %} -{% endfor %} diff --git a/data/templates/openvpn/auth.pw.tmpl b/data/templates/openvpn/auth.pw.j2 index 9b20c9742..218121062 100644 --- a/data/templates/openvpn/auth.pw.tmpl +++ b/data/templates/openvpn/auth.pw.j2 @@ -1,5 +1,5 @@ {# Autogenerated by interfaces-openvpn.py #} -{% if authentication is defined and authentication is not none %} +{% if authentication is vyos_defined %} {{ authentication.username }} {{ authentication.password }} {% endif %} diff --git a/data/templates/openvpn/client.conf.tmpl b/data/templates/openvpn/client.conf.j2 index e6e15b6ad..2e327e4d3 100644 --- a/data/templates/openvpn/client.conf.tmpl +++ b/data/templates/openvpn/client.conf.j2 @@ -1,31 +1,31 @@ ### Autogenerated by interfaces-openvpn.py ### -{% if ip %} +{% if ip is vyos_defined %} ifconfig-push {{ ip[0] }} {{ server_subnet[0] | netmask_from_cidr }} {% endif %} -{% if push_route is defined and push_route is not none %} -{% for route in push_route %} +{% if push_route is vyos_defined %} +{% for route in push_route %} push "route {{ route | address_from_cidr }} {{ route | netmask_from_cidr }}" -{% endfor %} +{% endfor %} {% endif %} -{% if subnet is defined and subnet is not none %} -{% for network in subnet %} +{% if subnet is vyos_defined %} +{% for network in subnet %} iroute {{ network | address_from_cidr }} {{ network | netmask_from_cidr }} -{% endfor %} +{% endfor %} {% endif %} {# ipv6_remote is only set when IPv6 server is enabled #} -{% if ipv6_remote %} +{% if ipv6_remote is vyos_defined %} # IPv6 -{% if ipv6_ip %} +{% if ipv6_ip is vyos_defined %} ifconfig-ipv6-push {{ ipv6_ip[0] }} {{ ipv6_remote }} -{% endif %} -{% for route6 in ipv6_push_route %} +{% endif %} +{% for route6 in ipv6_push_route %} push "route-ipv6 {{ route6 }}" -{% endfor %} -{% for net6 in ipv6_subnet %} +{% endfor %} +{% for net6 in ipv6_subnet %} iroute-ipv6 {{ net6 }} -{% endfor %} +{% endfor %} {% endif %} -{% if disable is defined %} +{% if disable is vyos_defined %} disable {% endif %} diff --git a/data/templates/openvpn/server.conf.j2 b/data/templates/openvpn/server.conf.j2 new file mode 100644 index 000000000..6dd4ef88d --- /dev/null +++ b/data/templates/openvpn/server.conf.j2 @@ -0,0 +1,224 @@ +### Autogenerated by interfaces-openvpn.py ### +# +# See https://community.openvpn.net/openvpn/wiki/Openvpn24ManPage +# for individual keyword definition +# +# {{ description if description is vyos_defined }} +# + +verb 3 +dev-type {{ device_type }} +dev {{ ifname }} +persist-key +{% if protocol is vyos_defined('tcp-active') %} +proto tcp-client +{% elif protocol is vyos_defined('tcp-passive') %} +proto tcp-server +{% else %} +proto udp +{% endif %} +{% if local_host is vyos_defined %} +local {{ local_host }} +{% endif %} +{% if mode is vyos_defined('server') and protocol is vyos_defined('udp') and local_host is not vyos_defined %} +multihome +{% endif %} +{% if local_port is vyos_defined %} +lport {{ local_port }} +{% endif %} +{% if remote_port is vyos_defined %} +rport {{ remote_port }} +{% endif %} +{% if remote_host is vyos_defined %} +{% for remote in remote_host %} +remote {{ remote }} +{% endfor %} +{% endif %} +{% if shared_secret_key is vyos_defined %} +secret /run/openvpn/{{ ifname }}_shared.key +{% endif %} +{% if persistent_tunnel is vyos_defined %} +persist-tun +{% endif %} +{% if replace_default_route.local is vyos_defined %} +push "redirect-gateway local def1" +{% elif replace_default_route is vyos_defined %} +push "redirect-gateway def1" +{% endif %} +{% if use_lzo_compression is vyos_defined %} +compress lzo +{% endif %} + +{% if mode is vyos_defined('client') %} +# +# OpenVPN Client mode +# +client +nobind + +{% elif mode is vyos_defined('server') %} +# +# OpenVPN Server mode +# +mode server +tls-server +{% if server is vyos_defined %} +{% if server.subnet is vyos_defined %} +{% if server.topology is vyos_defined('point-to-point') %} +topology p2p +{% elif server.topology is vyos_defined %} +topology {{ server.topology }} +{% endif %} +{% 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 vyos_defined %} +{% 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 vyos_defined }}" +{% 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 vyos_defined('net30') %} +ifconfig-pool {{ subnet | inc_ip('4') }} {{ subnet | last_host_address | dec_ip('1') }} {{ subnet | netmask_from_cidr if device_type == 'tap' else '' }} +{% else %} +{# OpenVPN assigns the first IP address to its local interface so the pool must #} +{# start from the second address and end on the last address #} +ifconfig-pool {{ subnet | first_host_address | inc_ip('1') }} {{ subnet | last_host_address | dec_ip('1') }} {{ subnet | netmask_from_cidr if device_type == 'tun' else '' }} +{% endif %} +{% elif subnet | is_ipv6 %} +server-ipv6 {{ subnet }} +{% endif %} +{% endfor %} +{% endif %} + +{% if server.client_ip_pool is vyos_defined and server.client_ip_pool.disable is not vyos_defined %} +ifconfig-pool {{ server.client_ip_pool.start }} {{ server.client_ip_pool.stop }}{{ server.client_ip_pool.subnet_mask if server.client_ip_pool.subnet_mask is vyos_defined }} +{% endif %} +{% if server.max_connections is vyos_defined %} +max-clients {{ server.max_connections }} +{% endif %} +{% if server.client is vyos_defined %} +client-config-dir /run/openvpn/ccd/{{ ifname }} +{% endif %} +{% endif %} +keepalive {{ keep_alive.interval }} {{ keep_alive.interval | int * keep_alive.failure_count | int }} +management /run/openvpn/openvpn-mgmt-intf unix +{% if server is vyos_defined %} +{% if server.reject_unconfigured_clients is vyos_defined %} +ccd-exclusive +{% endif %} + +{% if server.name_server is vyos_defined %} +{% for nameserver in server.name_server %} +{% if nameserver | is_ipv4 %} +push "dhcp-option DNS {{ nameserver }}" +{% elif nameserver | is_ipv6 %} +push "dhcp-option DNS6 {{ nameserver }}" +{% endif %} +{% endfor %} +{% endif %} +{% if server.domain_name is vyos_defined %} +push "dhcp-option DOMAIN {{ server.domain_name }}" +{% endif %} +{% if server.mfa.totp is vyos_defined %} +{% set totp_config = server.mfa.totp %} +plugin "{{ plugin_dir }}/openvpn-otp.so" "otp_secrets=/config/auth/openvpn/{{ ifname }}-otp-secrets otp_slop={{ totp_config.slop }} totp_t0={{ totp_config.drift }} totp_step={{ totp_config.step }} totp_digits={{ totp_config.digits }} password_is_cr={{ '1' if totp_config.challenge == 'enable' else '0' }}" +{% endif %} +{% endif %} +{% else %} +# +# OpenVPN site-2-site mode +# +ping {{ keep_alive.interval }} +ping-restart {{ keep_alive.failure_count }} + +{% if device_type == 'tap' %} +{% if local_address is vyos_defined %} +{% for laddr, laddr_conf in local_address.items() if laddr | is_ipv4 %} +{% if laddr_conf.subnet_mask is vyos_defined %} +ifconfig {{ laddr }} {{ laddr_conf.subnet_mask }} +{% endif %} +{% endfor %} +{% endif %} +{% else %} +{% for laddr in local_address if laddr | is_ipv4 %} +{% for raddr in remote_address if raddr | is_ipv4 %} +ifconfig {{ laddr }} {{ raddr }} +{% endfor %} +{% endfor %} +{% for laddr in local_address if laddr | is_ipv6 %} +{% for raddr in remote_address if raddr | is_ipv6 %} +ifconfig-ipv6 {{ laddr }} {{ raddr }} +{% endfor %} +{% endfor %} +{% endif %} +{% endif %} + +{% if tls is vyos_defined %} +# TLS options +{% if tls.ca_certificate is vyos_defined %} +ca /run/openvpn/{{ ifname }}_ca.pem +{% endif %} +{% if tls.certificate is vyos_defined %} +cert /run/openvpn/{{ ifname }}_cert.pem +{% endif %} +{% if tls.private_key is vyos_defined %} +key /run/openvpn/{{ ifname }}_cert.key +{% endif %} +{% if tls.crypt_key is vyos_defined %} +tls-crypt /run/openvpn/{{ ifname }}_crypt.key +{% endif %} +{% if tls.crl is vyos_defined %} +crl-verify /run/openvpn/{{ ifname }}_crl.pem +{% endif %} +{% if tls.tls_version_min is vyos_defined %} +tls-version-min {{ tls.tls_version_min }} +{% endif %} +{% if tls.dh_params is vyos_defined %} +dh /run/openvpn/{{ ifname }}_dh.pem +{% elif mode is vyos_defined('server') and tls.private_key is vyos_defined %} +dh none +{% endif %} +{% if tls.auth_key is vyos_defined %} +{% if mode == 'client' %} +tls-auth /run/openvpn/{{ ifname }}_auth.key 1 +{% elif mode == 'server' %} +tls-auth /run/openvpn/{{ ifname }}_auth.key 0 +{% endif %} +{% endif %} +{% if tls.role is vyos_defined('active') %} +tls-client +{% elif tls.role is vyos_defined('passive') %} +tls-server +{% endif %} +{% endif %} + +# Encryption options +{% if encryption is vyos_defined %} +{% if encryption.cipher is vyos_defined %} +cipher {{ encryption.cipher | openvpn_cipher }} +{% if encryption.cipher is vyos_defined('bf128') %} +keysize 128 +{% elif encryption.cipher is vyos_defined('bf256') %} +keysize 256 +{% endif %} +{% endif %} +{% if encryption.ncp_ciphers is vyos_defined %} +data-ciphers {{ encryption.ncp_ciphers | openvpn_ncp_ciphers }} +{% endif %} +{% endif %} + +{% if hash is vyos_defined %} +auth {{ hash }} +{% endif %} + +{% if authentication is vyos_defined %} +auth-user-pass {{ auth_user_pass_file }} +auth-retry nointeract +{% endif %} diff --git a/data/templates/openvpn/server.conf.tmpl b/data/templates/openvpn/server.conf.tmpl deleted file mode 100644 index 7a0470d0e..000000000 --- a/data/templates/openvpn/server.conf.tmpl +++ /dev/null @@ -1,226 +0,0 @@ -### Autogenerated by interfaces-openvpn.py ### -# -# See https://community.openvpn.net/openvpn/wiki/Openvpn24ManPage -# for individual keyword definition -# -# {{ description if description is defined and description is not none }} -# - -verb 3 -dev-type {{ device_type }} -dev {{ ifname }} -persist-key -{% if protocol == 'tcp-active' %} -proto tcp-client -{% elif protocol == 'tcp-passive' %} -proto tcp-server -{% else %} -proto udp -{% endif %} -{% if local_host is defined and local_host is not none %} -local {{ local_host }} -{% endif %} -{% if mode is defined and mode == 'server' and protocol == 'udp' and local_host is not defined %} -multihome -{% endif %} -{% if local_port is defined and local_port is not none %} -lport {{ local_port }} -{% endif %} -{% if remote_port is defined and remote_port is not none %} -rport {{ remote_port }} -{% endif %} -{% if remote_host is defined and remote_host is not none %} -{% for remote in remote_host %} -remote {{ remote }} -{% endfor %} -{% endif %} -{% if shared_secret_key is defined and shared_secret_key is not none %} -secret /run/openvpn/{{ ifname }}_shared.key -{% endif %} -{% if persistent_tunnel is defined %} -persist-tun -{% endif %} -{% if replace_default_route is defined and replace_default_route.local is defined %} -push "redirect-gateway local def1" -{% elif replace_default_route is defined %} -push "redirect-gateway def1" -{% endif %} -{% if use_lzo_compression is defined %} -compress lzo -{% endif %} - -{% if mode == 'client' %} -# -# OpenVPN Client mode -# -client -nobind - -{% elif mode == 'server' %} -# -# OpenVPN Server mode -# -mode server -tls-server -{% if server is defined and server is not none %} -{% if server.subnet is defined and server.subnet is not none %} -{% if server.topology is defined and server.topology == 'point-to-point' %} -topology p2p -{% elif server.topology is defined and server.topology is not none %} -topology {{ server.topology }} -{% endif %} -{% 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 }}{% if route_config.metric is defined %} {{ subnet | first_host_address }} {{ route_config.metric }}{% endif %}" -{% 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' %} -ifconfig-pool {{ subnet | inc_ip('4') }} {{ subnet | last_host_address | dec_ip('1') }} {{ subnet | netmask_from_cidr if device_type == 'tap' else '' }} -{% else %} -{# OpenVPN assigns the first IP address to its local interface so the pool must #} -{# start from the second address and end on the last address #} -ifconfig-pool {{ subnet | first_host_address | inc_ip('1') }} {{ subnet | last_host_address | dec_ip('1') }} {{ subnet | netmask_from_cidr if device_type == 'tun' else '' }} -{% endif %} -{% elif subnet | is_ipv6 %} -server-ipv6 {{ subnet }} -{% endif %} -{% endfor %} -{% endif %} - -{% if server.client_ip_pool is defined and server.client_ip_pool is not none and server.client_ip_pool.disable is not defined %} -ifconfig-pool {{ server.client_ip_pool.start }} {{ server.client_ip_pool.stop }}{{ server.client_ip_pool.subnet_mask if server.client_ip_pool.subnet_mask is defined and server.client_ip_pool.subnet_mask is not none }} -{% endif %} -{% if server.max_connections is defined and server.max_connections is not none %} -max-clients {{ server.max_connections }} -{% endif %} -{% if server.client is defined and server.client is not none %} -client-config-dir /run/openvpn/ccd/{{ ifname }} -{% endif %} -{% endif %} -keepalive {{ keep_alive.interval }} {{ keep_alive.interval|int * keep_alive.failure_count|int }} -management /run/openvpn/openvpn-mgmt-intf unix -{% if server is defined and server is not none %} -{% if server.reject_unconfigured_clients is defined %} -ccd-exclusive -{% endif %} - -{% if server.name_server is defined and server.name_server is not none %} -{% for nameserver in server.name_server %} -{% if nameserver | is_ipv4 %} -push "dhcp-option DNS {{ nameserver }}" -{% elif nameserver | is_ipv6 %} -push "dhcp-option DNS6 {{ nameserver }}" -{% endif %} -{% endfor %} -{% endif %} -{% if server.domain_name is defined and server.domain_name is not none %} -push "dhcp-option DOMAIN {{ server.domain_name }}" -{% endif %} -{% if server.mfa is defined and server.mfa is not none %} -{% if server.mfa.totp is defined and server.mfa.totp is not none %} -{% set totp_config = server.mfa.totp %} -plugin "{{ plugin_dir}}/openvpn-otp.so" "otp_secrets=/config/auth/openvpn/{{ ifname }}-otp-secrets {{ 'otp_slop=' ~ totp_config.slop }} {{ 'totp_t0=' ~ totp_config.drift }} {{ 'totp_step=' ~ totp_config.step }} {{ 'totp_digits=' ~ totp_config.digits }} password_is_cr={{ '1' if totp_config.challenge == 'enable' else '0' }}" -{% endif %} -{% endif %} -{% endif %} -{% else %} -# -# OpenVPN site-2-site mode -# -ping {{ keep_alive.interval }} -ping-restart {{ keep_alive.failure_count }} - -{% if device_type == 'tap' %} -{% for laddr, laddr_conf in local_address.items() if laddr | is_ipv4 %} -{% if laddr_conf is defined and laddr_conf.subnet_mask is defined and laddr_conf.subnet_mask is not none %} -ifconfig {{ laddr }} {{ laddr_conf.subnet_mask }} -{% endif %} -{% endfor %} -{% else %} -{% for laddr in local_address if laddr | is_ipv4 %} -{% for raddr in remote_address if raddr | is_ipv4 %} -ifconfig {{ laddr }} {{ raddr }} -{% endfor %} -{% endfor %} -{% for laddr in local_address if laddr | is_ipv6 %} -{% for raddr in remote_address if raddr | is_ipv6 %} -ifconfig-ipv6 {{ laddr }} {{ raddr }} -{% endfor %} -{% endfor %} -{% endif %} -{% endif %} - -{% if tls is defined and tls is not none %} -# TLS options -{% if tls.ca_certificate is defined and tls.ca_certificate is not none %} -ca /run/openvpn/{{ ifname }}_ca.pem -{% endif %} -{% if tls.certificate is defined and tls.certificate is not none %} -cert /run/openvpn/{{ ifname }}_cert.pem -{% endif %} -{% if tls.private_key is defined %} -key /run/openvpn/{{ ifname }}_cert.key -{% endif %} -{% if tls.crypt_key is defined and tls.crypt_key is not none %} -tls-crypt /run/openvpn/{{ ifname }}_crypt.key -{% endif %} -{% if tls.crl is defined %} -crl-verify /run/openvpn/{{ ifname }}_crl.pem -{% endif %} -{% if tls.tls_version_min is defined and tls.tls_version_min is not none %} -tls-version-min {{ tls.tls_version_min }} -{% endif %} -{% if tls.dh_params is defined and tls.dh_params is not none %} -dh /run/openvpn/{{ ifname }}_dh.pem -{% elif mode == 'server' and tls.private_key is defined %} -dh none -{% endif %} -{% if tls.auth_key is defined and tls.auth_key is not none %} -{% if mode == 'client' %} -tls-auth /run/openvpn/{{ ifname }}_auth.key 1 -{% elif mode == 'server' %} -tls-auth /run/openvpn/{{ ifname }}_auth.key 0 -{% endif %} -{% endif %} -{% if tls.role is defined and tls.role is not none %} -{% if tls.role == 'active' %} -tls-client -{% elif tls.role == 'passive' %} -tls-server -{% endif %} -{% endif %} -{% endif %} - -# Encryption options -{% if encryption is defined and encryption is not none %} -{% if encryption.cipher is defined and encryption.cipher is not none %} -cipher {{ encryption.cipher | openvpn_cipher }} -{% if encryption.cipher == 'bf128' %} -keysize 128 -{% elif encryption.cipher == 'bf256' %} -keysize 256 -{% endif %} -{% endif %} -{% if encryption.ncp_ciphers is defined and encryption.ncp_ciphers is not none %} -data-ciphers {{ encryption.ncp_ciphers | openvpn_ncp_ciphers }} -{% endif %} -{% endif %} - -{% if hash is defined and hash is not none %} -auth {{ hash }} -{% endif %} - -{% if authentication is defined and authentication is not none %} -auth-user-pass {{ auth_user_pass_file }} -auth-retry nointeract -{% endif %} diff --git a/data/templates/openvpn/service-override.conf.j2 b/data/templates/openvpn/service-override.conf.j2 new file mode 100644 index 000000000..616ba3bfc --- /dev/null +++ b/data/templates/openvpn/service-override.conf.j2 @@ -0,0 +1,21 @@ +{% set options = namespace(value='') %} +{% if openvpn_option is vyos_defined %} +{% for option in openvpn_option %} +{# Remove the '--' prefix from variable if it is presented #} +{% if option.startswith('--') %} +{% set option = option.split('--', maxsplit=1)[1] %} +{% endif %} +{# Workaround to pass '--push' options properly. Previously openvpn accepted this option without values in double-quotes #} +{# But now it stopped doing this, so we need to add them for compatibility #} +{# HOWEVER! This is a raw option and we do not promise that this or any other trick will work for all the cases. #} +{# Using 'openvpn-option' you take all responsibility for compatibility for yourself. #} +{% if option.startswith('push') and not (option.startswith('push "') and option.endswith('"')) %} +{% set option = 'push \"%s\"' | format(option.split('push ', maxsplit=1)[1]) %} +{% endif %} +{% set options.value = options.value ~ ' --' ~ option %} +{% endfor %} +{% endif %} +[Service] +ExecStart= +ExecStart=/usr/sbin/openvpn --daemon openvpn-%i --config %i.conf --status %i.status 30 --writepid %i.pid {{ options.value }} + diff --git a/data/templates/openvpn/service-override.conf.tmpl b/data/templates/openvpn/service-override.conf.tmpl deleted file mode 100644 index 069bdbd08..000000000 --- a/data/templates/openvpn/service-override.conf.tmpl +++ /dev/null @@ -1,20 +0,0 @@ -[Service] -ExecStart= -ExecStart=/usr/sbin/openvpn --daemon openvpn-%i --config %i.conf --status %i.status 30 --writepid %i.pid -{%- if openvpn_option is defined and openvpn_option is not none %} -{% for option in openvpn_option %} -{# Remove the '--' prefix from variable if it is presented #} -{% if option.startswith('--') %} -{% set option = option.split('--', maxsplit=1)[1] %} -{% endif %} -{# Workaround to pass '--push' options properly. Previously openvpn accepted this option without values in double-quotes #} -{# But now it stopped doing this, so we need to add them for compatibility #} -{# HOWEVER! This is a raw option and we do not promise that this or any other trick will work for all the cases. #} -{# Using 'openvpn-option' you take all responsibility for compatibility for yourself. #} -{% if option.startswith('push') and not (option.startswith('push "') and option.endswith('"')) %} -{% set option = 'push \"%s\"'|format(option.split('push ', maxsplit=1)[1]) %} -{% endif %} - --{{ option }} -{%- endfor %} -{% endif %} - diff --git a/data/templates/pmacct/override.conf.j2 b/data/templates/pmacct/override.conf.j2 new file mode 100644 index 000000000..213569ddc --- /dev/null +++ b/data/templates/pmacct/override.conf.j2 @@ -0,0 +1,17 @@ +{% set vrf_command = 'ip vrf exec ' ~ vrf ~ ' ' if vrf is vyos_defined else '' %} +[Unit] +After= +After=vyos-router.service +ConditionPathExists= +ConditionPathExists=/run/pmacct/uacctd.conf + +[Service] +EnvironmentFile= +ExecStart= +ExecStart={{ vrf_command }}/usr/sbin/uacctd -f /run/pmacct/uacctd.conf +WorkingDirectory= +WorkingDirectory=/run/pmacct +PIDFile= +PIDFile=/run/pmacct/uacctd.pid +Restart=always +RestartSec=10 diff --git a/data/templates/pmacct/uacctd.conf.j2 b/data/templates/pmacct/uacctd.conf.j2 new file mode 100644 index 000000000..a5016691f --- /dev/null +++ b/data/templates/pmacct/uacctd.conf.j2 @@ -0,0 +1,80 @@ +# Genereated from VyOS configuration +daemonize: true +promisc: false +pidfile: /run/pmacct/uacctd.pid +uacctd_group: 2 +uacctd_nl_size: 2097152 +snaplen: {{ packet_length }} +aggregate: in_iface{{ ',out_iface' if enable_egress is vyos_defined }},src_mac,dst_mac,vlan,src_host,dst_host,src_port,dst_port,proto,tos,flows +{% set pipe_size = buffer_size | int *1024 *1024 %} +plugin_pipe_size: {{ pipe_size }} +{# We need an integer division (//) without any remainder or fraction #} +plugin_buffer_size: {{ pipe_size // 1000 }} +{% if syslog_facility is vyos_defined %} +syslog: {{ syslog_facility }} +{% endif %} +{% if disable_imt is not defined %} +imt_path: /tmp/uacctd.pipe +imt_mem_pools_number: 169 +{% endif %} + +{% set plugin = [] %} +{% if netflow.server is vyos_defined %} +{% for server in netflow.server %} +{% set nf_server_key = 'nf_' ~ server | replace(':', '.') %} +{% set _ = plugin.append('nfprobe['~ nf_server_key ~ ']') %} +{% endfor %} +{% endif %} +{% if sflow.server is vyos_defined %} +{% for server in sflow.server %} +{% set sf_server_key = 'sf_' ~ server | replace(':', '.') %} +{% set _ = plugin.append('sfprobe[' ~ sf_server_key ~ ']') %} +{% endfor %} +{% endif %} +{% if disable_imt is not defined %} +{% set _ = plugin.append('memory') %} +{% endif %} +plugins: {{ plugin | join(',') }} + +{% if netflow.server is vyos_defined %} +# NetFlow servers +{% for server, server_config in netflow.server.items() %} +{# # prevent pmacct syntax error when using IPv6 flow collectors #} +{% set nf_server_key = 'nf_' ~ server | replace(':', '.') %} +nfprobe_receiver[{{ nf_server_key }}]: {{ server | bracketize_ipv6 }}:{{ server_config.port }} +nfprobe_version[{{ nf_server_key }}]: {{ netflow.version }} +{% if netflow.engine_id is vyos_defined %} +nfprobe_engine[{{ nf_server_key }}]: {{ netflow.engine_id }} +{% endif %} +{% if netflow.max_flows is vyos_defined %} +nfprobe_maxflows[{{ nf_server_key }}]: {{ netflow.max_flows }} +{% endif %} +{% if netflow.sampling_rate is vyos_defined %} +sampling_rate[{{ nf_server_key }}]: {{ netflow.sampling_rate }} +{% endif %} +{% if netflow.source_address is vyos_defined %} +nfprobe_source_ip[{{ nf_server_key }}]: {{ netflow.source_address }} +{% endif %} +{% if netflow.timeout is vyos_defined %} +nfprobe_timeouts[{{ nf_server_key }}]: expint={{ netflow.timeout.expiry_interval }}:general={{ netflow.timeout.flow_generic }}:icmp={{ netflow.timeout.icmp }}:maxlife={{ netflow.timeout.max_active_life }}:tcp.fin={{ netflow.timeout.tcp_fin }}:tcp={{ netflow.timeout.tcp_generic }}:tcp.rst={{ netflow.timeout.tcp_rst }}:udp={{ netflow.timeout.udp }} +{% endif %} + +{% endfor %} +{% endif %} + +{% if sflow.server is vyos_defined %} +# sFlow servers +{% for server, server_config in sflow.server.items() %} +{# # prevent pmacct syntax error when using IPv6 flow collectors #} +{% set sf_server_key = 'sf_' ~ server | replace(':', '.') %} +sfprobe_receiver[{{ sf_server_key }}]: {{ server | bracketize_ipv6 }}:{{ server_config.port }} +sfprobe_agentip[{{ sf_server_key }}]: {{ sflow.agent_address }} +{% if sflow.sampling_rate is vyos_defined %} +sampling_rate[{{ sf_server_key }}]: {{ sflow.sampling_rate }} +{% endif %} +{% if sflow.source_address is vyos_defined %} +sfprobe_source_ip[{{ sf_server_key }}]: {{ sflow.source_address }} +{% endif %} + +{% endfor %} +{% endif %} diff --git a/data/templates/pppoe/ip-down.script.tmpl b/data/templates/pppoe/ip-down.script.tmpl deleted file mode 100644 index bac4155d6..000000000 --- a/data/templates/pppoe/ip-down.script.tmpl +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/sh - -# As PPPoE is an "on demand" interface we need to re-configure it when it -# becomes up -if [ "$6" != "{{ ifname }}" ]; then - exit -fi - -# add some info to syslog -DIALER_PID=$(cat /var/run/{{ ifname }}.pid) -logger -t pppd[$DIALER_PID] "executing $0" - -{% if connect_on_demand is not defined %} -# See https://phabricator.vyos.net/T2248. Determine if we are enslaved to a -# VRF, this is needed to properly insert the default route. -VRF_NAME="" -if [ -d /sys/class/net/{{ ifname }}/upper_* ]; then - # Determine upper (VRF) interface - VRF=$(basename $(ls -d /sys/class/net/{{ ifname }}/upper_*)) - # Remove upper_ prefix from result string - VRF=${VRF#"upper_"} - # Populate variable to run in VR context - VRF_NAME="vrf ${VRF_NAME}" -fi - -{% if default_route != 'none' %} -# Always delete default route when interface goes down if we installed it -vtysh -c "conf t" ${VRF_NAME} -c "no ip route 0.0.0.0/0 {{ ifname }} ${VRF_NAME}" -{% if ipv6 is defined and ipv6.address is defined and ipv6.address.autoconf is defined %} -vtysh -c "conf t" ${VRF_NAME} -c "no ipv6 route ::/0 {{ ifname }} ${VRF_NAME}" -{% endif %} -{% endif %} -{% endif %} - -{% if dhcpv6_options is defined and dhcpv6_options.pd is defined %} -# Stop wide dhcpv6 client -systemctl stop dhcp6c@{{ ifname }}.service -{% endif %} diff --git a/data/templates/pppoe/ip-pre-up.script.tmpl b/data/templates/pppoe/ip-pre-up.script.tmpl deleted file mode 100644 index a54e4e9bd..000000000 --- a/data/templates/pppoe/ip-pre-up.script.tmpl +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/sh - -# As PPPoE is an "on demand" interface we need to re-configure it when it -# becomes up -if [ "$6" != "{{ ifname }}" ]; then - exit -fi - -# add some info to syslog -DIALER_PID=$(cat /var/run/{{ ifname }}.pid) -logger -t pppd[$DIALER_PID] "executing $0" - -echo "{{ description }}" > /sys/class/net/{{ ifname }}/ifalias - -{% if vrf %} -logger -t pppd[$DIALER_PID] "configuring dialer interface $6 for VRF {{ vrf }}" -ip link set dev {{ ifname }} master {{ vrf }} -{% endif %} diff --git a/data/templates/pppoe/ip-up.script.tmpl b/data/templates/pppoe/ip-up.script.tmpl deleted file mode 100644 index 302756960..000000000 --- a/data/templates/pppoe/ip-up.script.tmpl +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/sh - -# As PPPoE is an "on demand" interface we need to re-configure it when it -# becomes up -if [ "$6" != "{{ ifname }}" ]; then - exit -fi - -{% if connect_on_demand is not defined %} -# add some info to syslog -DIALER_PID=$(cat /var/run/{{ ifname }}.pid) -logger -t pppd[$DIALER_PID] "executing $0" - -{% if default_route != 'none' %} -# See https://phabricator.vyos.net/T2248 & T2220. Determine if we are enslaved -# to a VRF, this is needed to properly insert the default route. - -SED_OPT="^ip route" -VRF_NAME="" -if [ -d /sys/class/net/{{ ifname }}/upper_* ]; then - # Determine upper (VRF) interface - VRF=$(basename $(ls -d /sys/class/net/{{ ifname }}/upper_*)) - # Remove upper_ prefix from result string - VRF=${VRF#"upper_"} - # generate new SED command - SED_OPT="vrf ${VRF}" - # generate vtysh option - VRF_NAME="vrf ${VRF}" -fi - -{% if default_route == 'auto' %} -# Only insert a new default route if there is no default route configured -routes=$(vtysh -c "show running-config" | sed -n "/${SED_OPT}/,/!/p" | grep 0.0.0.0/0 | wc -l) -if [ "$routes" -ne 0 ]; then - exit 1 -fi - -{% elif default_route == 'force' %} -# Retrieve current static default routes and remove it from the routing table -vtysh -c "show running-config" | sed -n "/${SED_OPT}/,/!/p" | grep 0.0.0.0/0 | while read route ; do - vtysh -c "conf t" ${VTY_OPT} -c "no ${route} ${VRF_NAME}" -done -{% endif %} - -# Add default route to default or VRF routing table -vtysh -c "conf t" ${VTY_OPT} -c "ip route 0.0.0.0/0 {{ ifname }} ${VRF_NAME}" -logger -t pppd[$DIALER_PID] "added default route via {{ ifname }} ${VRF_NAME}" -{% endif %} -{% endif %} diff --git a/data/templates/pppoe/ipv6-up.script.tmpl b/data/templates/pppoe/ipv6-up.script.tmpl deleted file mode 100644 index da73cb4d5..000000000 --- a/data/templates/pppoe/ipv6-up.script.tmpl +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/sh - -# As PPPoE is an "on demand" interface we need to re-configure it when it -# becomes up - -if [ "$6" != "{{ ifname }}" ]; then - exit -fi - - -{% if default_route != 'none' %} -# See https://phabricator.vyos.net/T2248 & T2220. Determine if we are enslaved -# to a VRF, this is needed to properly insert the default route. - -SED_OPT="^ipv6 route" -VRF_NAME="" -if [ -d /sys/class/net/{{ ifname }}/upper_* ]; then - # Determine upper (VRF) interface - VRF=$(basename $(ls -d /sys/class/net/{{ ifname }}/upper_*)) - # Remove upper_ prefix from result string - VRF=${VRF#"upper_"} - # generate new SED command - SED_OPT="vrf ${VRF}" - # generate vtysh option - VRF_NAME="vrf ${VRF}" -fi - -{% if default_route == 'auto' %} -# Only insert a new default route if there is no default route configured -routes=$(vtysh -c "show running-config" | sed -n "/${SED_OPT}/,/!/p" | grep ::/0 | wc -l) -if [ "$routes" -ne 0 ]; then - exit 1 -fi - -{% elif default_route == 'force' %} -# Retrieve current static default routes and remove it from the routing table -vtysh -c "show running-config" | sed -n "/${SED_OPT}/,/!/p" | grep ::/0 | while read route ; do - vtysh -c "conf t" ${VTY_OPT} -c "no ${route} ${VRF_NAME}" -done -{% endif %} - -# Add default route to default or VRF routing table -vtysh -c "conf t" ${VTY_OPT} -c "ipv6 route ::/0 {{ ifname }} ${VRF_NAME}" -logger -t pppd[$DIALER_PID] "added default route via {{ ifname }} ${VRF_NAME}" -{% endif %} - diff --git a/data/templates/pppoe/peer.tmpl b/data/templates/pppoe/peer.j2 index 928ed1238..6221abb9b 100644 --- a/data/templates/pppoe/peer.tmpl +++ b/data/templates/pppoe/peer.j2 @@ -1,5 +1,5 @@ ### Autogenerated by interfaces-pppoe.py ### -{{ '# ' ~ description if description is defined else '' }} +{{ '# ' ~ description if description is vyos_defined else '' }} # Require peer to provide the local IP address if it is not # specified explicitly in the config file. @@ -35,10 +35,10 @@ noproxyarp maxfail 0 plugin rp-pppoe.so {{ source_interface }} -{% if access_concentrator is defined and access_concentrator is not none %} +{% if access_concentrator is vyos_defined %} rp_pppoe_ac '{{ access_concentrator }}' {% endif %} -{% if service_name is defined and service_name is not none %} +{% if service_name is vyos_defined %} rp_pppoe_service '{{ service_name }}' {% endif %} @@ -49,34 +49,34 @@ debug mtu {{ mtu }} mru {{ mtu }} -{% if authentication is defined %} -{{ 'user "' + authentication.user + '"' if authentication.user is defined }} -{{ 'password "' + authentication.password + '"' if authentication.password is defined }} +{% if authentication is vyos_defined %} +{{ 'user "' + authentication.user + '"' if authentication.user is vyos_defined }} +{{ 'password "' + authentication.password + '"' if authentication.password is vyos_defined }} {% endif %} -{{ "usepeerdns" if no_peer_dns is not defined }} +{{ "usepeerdns" if no_peer_dns is not vyos_defined }} -{% if ipv6 is defined %} -+ipv6 {{ 'ipv6cp-use-ipaddr' if ipv6.address is defined and ipv6.address.autoconf is defined }} +{% if ipv6 is vyos_defined %} ++ipv6 {{ 'ipv6cp-use-ipaddr' if ipv6.address.autoconf is vyos_defined }} {% else %} noipv6 {% endif %} -{% if connect_on_demand is defined %} +{% if connect_on_demand is vyos_defined %} demand # See T2249. PPP default route options should only be set when in on-demand # mode. As soon as we are not in on-demand mode the default-route handling is # passed to the ip-up.d/ip-down.s scripts which is required for VRF support. -{% if 'auto' in default_route %} +{% if 'auto' in default_route %} defaultroute -{{ 'defaultroute6' if ipv6 is defined }} -{% elif 'force' in default_route %} +{{ 'defaultroute6' if ipv6 is vyos_defined }} +{% elif 'force' in default_route %} defaultroute replacedefaultroute -{{ 'defaultroute6' if ipv6 is defined }} -{% endif %} +{{ 'defaultroute6' if ipv6 is vyos_defined }} +{% endif %} {% else %} nodefaultroute noreplacedefaultroute -{{ 'nodefaultroute6' if ipv6 is defined }} +{{ 'nodefaultroute6' if ipv6 is vyos_defined }} {% endif %} diff --git a/data/templates/router-advert/radvd.conf.j2 b/data/templates/router-advert/radvd.conf.j2 new file mode 100644 index 000000000..6902dc05a --- /dev/null +++ b/data/templates/router-advert/radvd.conf.j2 @@ -0,0 +1,66 @@ +### Autogenerated by service_router-advert.py ### + +{% if interface is vyos_defined %} +{% for iface, iface_config in interface.items() %} +interface {{ iface }} { + IgnoreIfMissing on; +{% if iface_config.default_preference is vyos_defined %} + AdvDefaultPreference {{ iface_config.default_preference }}; +{% endif %} +{% if iface_config.managed_flag is vyos_defined %} + AdvManagedFlag {{ 'on' if iface_config.managed_flag is vyos_defined else 'off' }}; +{% endif %} +{% if iface_config.interval.max is vyos_defined %} + MaxRtrAdvInterval {{ iface_config.interval.max }}; +{% endif %} +{% if iface_config.interval.min is vyos_defined %} + MinRtrAdvInterval {{ iface_config.interval.min }}; +{% endif %} +{% if iface_config.reachable_time is vyos_defined %} + AdvReachableTime {{ iface_config.reachable_time }}; +{% endif %} + AdvIntervalOpt {{ 'off' if iface_config.no_send_advert is vyos_defined else 'on' }}; + AdvSendAdvert {{ 'off' if iface_config.no_send_advert is vyos_defined else 'on' }}; +{% if iface_config.default_lifetime is vyos_defined %} + AdvDefaultLifetime {{ iface_config.default_lifetime }}; +{% endif %} +{% if iface_config.link_mtu is vyos_defined %} + AdvLinkMTU {{ iface_config.link_mtu }}; +{% endif %} + AdvOtherConfigFlag {{ 'on' if iface_config.other_config_flag is vyos_defined else 'off' }}; + AdvRetransTimer {{ iface_config.retrans_timer }}; + AdvCurHopLimit {{ iface_config.hop_limit }}; +{% if iface_config.route is vyos_defined %} +{% for route, route_options in iface_config.route.items() %} + route {{ route }} { +{% if route_options.valid_lifetime is vyos_defined %} + AdvRouteLifetime {{ route_options.valid_lifetime }}; +{% endif %} +{% if route_options.route_preference is vyos_defined %} + AdvRoutePreference {{ route_options.route_preference }}; +{% endif %} + RemoveRoute {{ 'off' if route_options.no_remove_route is vyos_defined else 'on' }}; + }; +{% endfor %} +{% endif %} +{% if iface_config.prefix is vyos_defined %} +{% for prefix, prefix_options in iface_config.prefix.items() %} + prefix {{ prefix }} { + AdvAutonomous {{ 'off' if prefix_options.no_autonomous_flag is vyos_defined else 'on' }}; + AdvValidLifetime {{ prefix_options.valid_lifetime }}; + AdvOnLink {{ 'off' if prefix_options.no_on_link_flag is vyos_defined else 'on' }}; + AdvPreferredLifetime {{ prefix_options.preferred_lifetime }}; + }; +{% endfor %} +{% endif %} +{% if iface_config.name_server is vyos_defined %} + RDNSS {{ iface_config.name_server | join(" ") }} { + }; +{% endif %} +{% if iface_config.dnssl is vyos_defined %} + DNSSL {{ iface_config.dnssl | join(" ") }} { + }; +{% endif %} +}; +{% endfor %} +{% endif %} diff --git a/data/templates/router-advert/radvd.conf.tmpl b/data/templates/router-advert/radvd.conf.tmpl deleted file mode 100644 index 88d066491..000000000 --- a/data/templates/router-advert/radvd.conf.tmpl +++ /dev/null @@ -1,66 +0,0 @@ -### Autogenerated by service_router-advert.py ### - -{% if interface is defined and interface is not none %} -{% for iface, iface_config in interface.items() %} -interface {{ iface }} { - IgnoreIfMissing on; -{% if iface_config.default_preference is defined and iface_config.default_preference is not none %} - AdvDefaultPreference {{ iface_config.default_preference }}; -{% endif %} -{% if iface_config.managed_flag is defined and iface_config.managed_flag is not none %} - AdvManagedFlag {{ 'on' if iface_config.managed_flag is defined else 'off' }}; -{% endif %} -{% if iface_config.interval.max is defined and iface_config.interval.max is not none %} - MaxRtrAdvInterval {{ iface_config.interval.max }}; -{% endif %} -{% if iface_config.interval.min is defined and iface_config.interval.min is not none %} - MinRtrAdvInterval {{ iface_config.interval.min }}; -{% endif %} -{% if iface_config.reachable_time is defined and iface_config.reachable_time is not none %} - AdvReachableTime {{ iface_config.reachable_time }}; -{% endif %} - AdvIntervalOpt {{ 'off' if iface_config.no_send_advert is defined else 'on' }}; - AdvSendAdvert {{ 'off' if iface_config.no_send_advert is defined else 'on' }}; -{% if iface_config.default_lifetime is defined %} - AdvDefaultLifetime {{ iface_config.default_lifetime }}; -{% endif %} -{% if iface_config.link_mtu is defined %} - AdvLinkMTU {{ iface_config.link_mtu }}; -{% endif %} - AdvOtherConfigFlag {{ 'on' if iface_config.other_config_flag is defined else 'off' }}; - AdvRetransTimer {{ iface_config.retrans_timer }}; - AdvCurHopLimit {{ iface_config.hop_limit }}; -{% if iface_config.route is defined %} -{% for route, route_options in iface_config.route.items() %} - route {{ route }} { -{% if route_options.valid_lifetime is defined %} - AdvRouteLifetime {{ route_options.valid_lifetime }}; -{% endif %} -{% if route_options.route_preference is defined %} - AdvRoutePreference {{ route_options.route_preference }}; -{% endif %} - RemoveRoute {{ 'off' if route_options.no_remove_route is defined else 'on' }}; - }; -{% endfor %} -{% endif %} -{% if iface_config.prefix is defined and iface_config.prefix is not none %} -{% for prefix, prefix_options in iface_config.prefix.items() %} - prefix {{ prefix }} { - AdvAutonomous {{ 'off' if prefix_options.no_autonomous_flag is defined else 'on' }}; - AdvValidLifetime {{ prefix_options.valid_lifetime }}; - AdvOnLink {{ 'off' if prefix_options.no_on_link_flag is defined else 'on' }}; - AdvPreferredLifetime {{ prefix_options.preferred_lifetime }}; - }; -{% endfor %} -{% endif %} -{% if iface_config.name_server is defined %} - RDNSS {{ iface_config.name_server | join(" ") }} { - }; -{% endif %} -{% if iface_config.dnssl is defined %} - DNSSL {{ iface_config.dnssl | join(" ") }} { - }; -{% endif %} -}; -{% endfor %} -{% endif %} diff --git a/data/templates/salt-minion/minion.tmpl b/data/templates/salt-minion/minion.j2 index 99749b57a..f4001db64 100644 --- a/data/templates/salt-minion/minion.tmpl +++ b/data/templates/salt-minion/minion.j2 @@ -32,17 +32,17 @@ log_file: /var/log/salt/minion # ['garbage', 'trace', 'debug'] # # Default: 'warning' -log_level: {{ log_level }} +log_level: warning # Set the location of the salt master server, if the master server cannot be # resolved, then the minion will fail to start. master: {% for host in master %} -- {{ host }} + - {{ host | bracketize_ipv6 }} {% endfor %} # The user to run salt -user: {{ user }} +user: minion # The directory to store the pki information in pki_dir: /config/salt/pki/minion @@ -52,10 +52,16 @@ pki_dir: /config/salt/pki/minion # Since salt uses detached ids it is possible to run multiple minions on the # same machine but with different ids, this can be useful for salt compute # clusters. -id: {{ salt_id }} - +id: {{ id }} # The number of minutes between mine updates. mine_interval: {{ interval }} -verify_master_pubkey_sign: {{ verify_master_pubkey_sign }} +{% if source_interface is vyos_defined %} +# The name of the interface to use when establishing the connection to the Master. +source_interface_name: {{ source_interface }} +{% endif %} + +# Enables verification of the master-public-signature returned by the master +# in auth-replies. +verify_master_pubkey_sign: {{ 'True' if master_key is vyos_defined else 'False' }} diff --git a/data/templates/snmp/etc.snmp.conf.tmpl b/data/templates/snmp/etc.snmp.conf.j2 index 6e4c6f063..8012cf6bb 100644 --- a/data/templates/snmp/etc.snmp.conf.tmpl +++ b/data/templates/snmp/etc.snmp.conf.j2 @@ -1,4 +1,4 @@ ### Autogenerated by snmp.py ### -{% if trap_source %} +{% if trap_source is vyos_defined %} clientaddr {{ trap_source }} {% endif %} diff --git a/data/templates/snmp/etc.snmpd.conf.j2 b/data/templates/snmp/etc.snmpd.conf.j2 new file mode 100644 index 000000000..d7dc0ba5d --- /dev/null +++ b/data/templates/snmp/etc.snmpd.conf.j2 @@ -0,0 +1,182 @@ +### Autogenerated by snmp.py ### + +# non configurable defaults +sysObjectID 1.3.6.1.4.1.44641 +sysServices 14 +master agentx +agentXPerms 0777 0777 +pass .1.3.6.1.2.1.31.1.1.1.18 /opt/vyatta/sbin/if-mib-alias +smuxpeer .1.3.6.1.2.1.83 +smuxpeer .1.3.6.1.2.1.157 +smuxsocket localhost + +# linkUp/Down configure the Event MIB tables to monitor +# the ifTable for network interfaces being taken up or down +# for making internal queries to retrieve any necessary information +iquerySecName {{ vyos_user }} + +# Modified from the default linkUpDownNotification +# to include more OIDs and poll more frequently +notificationEvent linkUpTrap linkUp ifIndex ifDescr ifType ifAdminStatus ifOperStatus +notificationEvent linkDownTrap linkDown ifIndex ifDescr ifType ifAdminStatus ifOperStatus +monitor -r 10 -e linkUpTrap "Generate linkUp" ifOperStatus != 2 +monitor -r 10 -e linkDownTrap "Generate linkDown" ifOperStatus == 2 + +# Remove all old ifTable entries with the same ifName as newly appeared +# interface (with different ifIndex) - this is the case on e.g. ppp interfaces +interface_replace_old yes + +######################## +# configurable section # +######################## + +# Default system description is VyOS version +sysDescr VyOS {{ version }} + +{% if description is vyos_defined %} +# Description +SysDescr {{ description }} +{% endif %} + +# Listen +{% set options = [] %} +{% if listen_address is vyos_defined %} +{% for address, address_options in listen_address.items() %} +{% if address | is_ipv6 %} +{% set protocol = protocol ~ '6' %} +{% endif %} +{% set _ = options.append(protocol ~ ':' ~ address | bracketize_ipv6 ~ ':' ~ address_options.port) %} +{% endfor %} +{% else %} +{% set _ = options.append(protocol ~ ':161') %} +{% set _ = options.append(protocol ~ '6:161') %} +{% endif %} +agentaddress unix:/run/snmpd.socket{{ ',' ~ options | join(',') if options is vyos_defined }} + +# SNMP communities +{% if community is vyos_defined %} +{% for comm, comm_config in community.items() %} +{% if comm_config.client is vyos_defined %} +{% for client in comm_config.client %} +{% if client | is_ipv4 %} +{{ comm_config.authorization }}community {{ comm }} {{ client }} +{% elif client | is_ipv6 %} +{{ comm_config.authorization }}community6 {{ comm }} {{ client }} +{% endif %} +{% endfor %} +{% endif %} +{% if comm_config.network is vyos_defined %} +{% for network in comm_config.network %} +{% if network | is_ipv4 %} +{{ comm_config.authorization }}community {{ comm }} {{ network }} +{% elif client | is_ipv6 %} +{{ comm_config.authorization }}community6 {{ comm }} {{ network }} +{% endif %} +{% endfor %} +{% endif %} +{% if comm_config.client is not vyos_defined and comm_config.network is not vyos_defined %} +{{ comm_config.authorization }}community {{ comm }} +{% endif %} +{% endfor %} +{% endif %} + +{% if contact is vyos_defined %} +# system contact information +SysContact {{ contact }} +{% endif %} + +{% if location is vyos_defined %} +# system location information +SysLocation {{ location }} +{% endif %} + +{% if smux_peer is vyos_defined %} +# additional smux peers +{% for peer in smux_peer %} +smuxpeer {{ peer }} +{% endfor %} +{% endif %} + +{% if trap_target is vyos_defined %} +# if there is a problem - tell someone! +{% for trap, trap_config in trap_target.items() %} +trap2sink {{ trap }}:{{ trap_config.port }} {{ trap_config.community }} +{% endfor %} +{% endif %} + +{% if v3 is vyos_defined %} +# +# SNMPv3 stuff goes here +# +{% if v3.view is vyos_defined %} +# views +{% for view, view_config in v3.view.items() %} +{% if view_config.oid is vyos_defined %} +{% for oid in view_config.oid %} +view {{ view }} included .{{ oid }} +{% endfor %} +{% endif %} +{% endfor %} +{% endif %} + +# access +{% if v3.group is vyos_defined %} +# context sec.model sec.level match read write notif +{% for group, group_config in v3.group.items() %} +access {{ group }} "" usm {{ group_config.seclevel }} exact {{ group_config.view }} {{ 'none' if group_config.mode == 'ro' else group_config.view }} none +{% endfor %} +{% endif %} + +# trap-target +{% if v3.trap_target is vyos_defined %} +{% for trap, trap_config in v3.trap_target.items() %} +{% set options = '' %} +{% if trap_config.type == 'inform' %} +{% set options = options ~ ' -Ci' %} +{% endif %} +{% if v3.engineid is vyos_defined %} +{% set options = options ~ ' -e "' ~ v3.engineid ~ '"' %} +{% endif %} +{% if trap_config.user is vyos_defined %} +{% set options = options ~ ' -u ' ~ trap_config.user %} +{% endif %} +{% if trap_config.auth.plaintext_password is vyos_defined or trap_config.auth.encrypted_password is vyos_defined %} +{% set options = options ~ ' -a ' ~ trap_config.auth.type %} +{% if trap_config.auth.plaintext_password is vyos_defined %} +{% set options = options ~ ' -A ' ~ trap_config.auth.plaintext_password %} +{% elif trap_config.auth.encrypted_password is vyos_defined %} +{% set options = options ~ ' -3m ' ~ trap_config.auth.encrypted_password %} +{% endif %} +{% if trap_config.privacy.plaintext_password is vyos_defined or trap_config.privacy.encrypted_password is vyos_defined %} +{% set options = options ~ ' -x ' ~ trap_config.privacy.type %} +{% if trap_config.privacy.plaintext_password is vyos_defined %} +{% set options = options ~ ' -X ' ~ trap_config.privacy.plaintext_password %} +{% elif trap_config.privacy.encrypted_password is vyos_defined %} +{% set options = options ~ ' -3M ' ~ trap_config.privacy.encrypted_password %} +{% endif %} +{% set options = options ~ ' -l authPriv' %} +{% else %} +{% set options = options ~ ' -l authNoPriv' %} +{% endif %} +{% else %} +{% set options = options ~ ' -l noAuthNoPriv' %} +{% endif %} +trapsess -v 3 {{ options }} {{ trap }}:{{ trap_config.protocol }}:{{ trap_config.port }} +{% endfor %} +{% endif %} + +# group +{% if v3.user is vyos_defined %} +{% for user, user_config in v3.user.items() %} +group {{ user_config.group }} usm {{ user }} +{% endfor %} +{% endif %} +{# SNMPv3 end #} +{% endif %} + +{% if script_extensions.extension_name is vyos_defined %} +# extension scripts +{% for script, script_config in script_extensions.extension_name.items() | sort(attribute=script) %} +extend {{ script }} {{ script_config.script }} +{% endfor %} +{% endif %} diff --git a/data/templates/snmp/etc.snmpd.conf.tmpl b/data/templates/snmp/etc.snmpd.conf.tmpl deleted file mode 100644 index 30806ce8a..000000000 --- a/data/templates/snmp/etc.snmpd.conf.tmpl +++ /dev/null @@ -1,119 +0,0 @@ -### Autogenerated by snmp.py ### - -# non configurable defaults -sysObjectID 1.3.6.1.4.1.44641 -sysServices 14 -master agentx -agentXPerms 0777 0777 -pass .1.3.6.1.2.1.31.1.1.1.18 /opt/vyatta/sbin/if-mib-alias -smuxpeer .1.3.6.1.2.1.83 -smuxpeer .1.3.6.1.2.1.157 -smuxsocket localhost - -# linkUp/Down configure the Event MIB tables to monitor -# the ifTable for network interfaces being taken up or down -# for making internal queries to retrieve any necessary information -iquerySecName {{ vyos_user }} - -# Modified from the default linkUpDownNotification -# to include more OIDs and poll more frequently -notificationEvent linkUpTrap linkUp ifIndex ifDescr ifType ifAdminStatus ifOperStatus -notificationEvent linkDownTrap linkDown ifIndex ifDescr ifType ifAdminStatus ifOperStatus -monitor -r 10 -e linkUpTrap "Generate linkUp" ifOperStatus != 2 -monitor -r 10 -e linkDownTrap "Generate linkDown" ifOperStatus == 2 - -# Remove all old ifTable entries with the same ifName as newly appeared -# interface (with different ifIndex) - this is the case on e.g. ppp interfaces -interface_replace_old yes - -######################## -# configurable section # -######################## - -# Default system description is VyOS version -sysDescr VyOS {{ version }} - -{% if description %} -# Description -SysDescr {{ description }} -{% endif %} - -# Listen -agentaddress unix:/run/snmpd.socket{% if listen_on %}{% for li in listen_on %},{{ li }}{% endfor %}{% else %},{{protocol}}:161{% if ipv6_enabled %},{{protocol}}6:161{% endif %}{% endif %} - -# SNMP communities -{% for c in communities %} -{% if c.network_v4 %} -{% for network in c.network_v4 %} -{{ c.authorization }}community {{ c.name }} {{ network }} -{% endfor %} -{% elif not c.has_source %} -{{ c.authorization }}community {{ c.name }} -{% endif %} -{% if c.network_v6 %} -{% for network in c.network_v6 %} -{{ c.authorization }}community6 {{ c.name }} {{ network }} -{% endfor %} -{% elif not c.has_source %} -{{ c.authorization }}community6 {{ c.name }} -{% endif %} -{% endfor %} - -{% if contact %} -# system contact information -SysContact {{ contact }} -{% endif %} - -{% if location %} -# system location information -SysLocation {{ location }} -{% endif %} - -{% if smux_peers %} -# additional smux peers -{% for sp in smux_peers %} -smuxpeer {{ sp }} -{% endfor %} -{% endif %} - -{% if trap_targets %} -# if there is a problem - tell someone! -{% for trap in trap_targets %} -trap2sink {{ trap.target }}{{ ":" + trap.port if trap.port is defined }} {{ trap.community }} -{% endfor %} -{% endif %} - -{% if v3_enabled %} -# -# SNMPv3 stuff goes here -# -# views -{% for view in v3_views %} -{% for oid in view.oids %} -view {{ view.name }} included .{{ oid.oid }} -{% endfor %} -{% endfor %} - -# access -# context sec.model sec.level match read write notif -{% for group in v3_groups %} -access {{ group.name }} "" usm {{ group.seclevel }} exact {{ group.view }} {% if group.mode == 'ro' %}none{% else %}{{ group.view }}{% endif %} none -{% endfor %} - -# trap-target -{% for t in v3_traps %} -trapsess -v 3 {{ '-Ci' if t.type == 'inform' }} -e {{ v3_engineid }} -u {{ t.secName }} -l {{ t.secLevel }} -a {{ t.authProtocol }} {% if t.authPassword %}-A {{ t.authPassword }}{% elif t.authMasterKey %}-3m {{ t.authMasterKey }}{% endif %} -x {{ t.privProtocol }} {% if t.privPassword %}-X {{ t.privPassword }}{% elif t.privMasterKey %}-3M {{ t.privMasterKey }}{% endif %} {{ t.ipProto }}:{{ t.ipAddr }}:{{ t.ipPort }} -{% endfor %} - -# group -{% for u in v3_users %} -group {{ u.group }} usm {{ u.name }} -{% endfor %} -{% endif %} - -{% if script_ext %} -# extension scripts -{% for ext in script_ext|sort(attribute='name') %} -extend {{ ext.name }} {{ ext.script }} -{% endfor %} -{% endif %} diff --git a/data/templates/snmp/override.conf.j2 b/data/templates/snmp/override.conf.j2 new file mode 100644 index 000000000..5d787de86 --- /dev/null +++ b/data/templates/snmp/override.conf.j2 @@ -0,0 +1,14 @@ +{% set vrf_command = 'ip vrf exec ' ~ vrf ~ ' ' if vrf is vyos_defined else '' %} +{% set oid_route_table = ' ' if oid_enable is vyos_defined('route-table') else '-I -ipCidrRouteTable,inetCidrRouteTable' %} +[Unit] +StartLimitIntervalSec=0 +After=vyos-router.service + +[Service] +Environment= +Environment="MIBDIRS=/usr/share/snmp/mibs:/usr/share/snmp/mibs/iana:/usr/share/snmp/mibs/ietf:/usr/share/vyos/mibs" +ExecStart= +ExecStart={{ vrf_command }}/usr/sbin/snmpd -LS0-5d -Lf /dev/null -u Debian-snmp -g Debian-snmp {{ oid_route_table }} -f -p /run/snmpd.pid +Restart=always +RestartSec=10 + diff --git a/data/templates/snmp/override.conf.tmpl b/data/templates/snmp/override.conf.tmpl deleted file mode 100644 index 2ac45a89f..000000000 --- a/data/templates/snmp/override.conf.tmpl +++ /dev/null @@ -1,14 +0,0 @@ -{% set vrf_command = 'ip vrf exec ' + vrf + ' ' if vrf is defined else '' %} -{% set oid_route_table = ' ' if route_table is sameas true else '-I -ipCidrRouteTable,inetCidrRouteTable' %} -[Unit] -StartLimitIntervalSec=0 -After=vyos-router.service - -[Service] -Environment= -Environment="MIBDIRS=/usr/share/snmp/mibs:/usr/share/snmp/mibs/iana:/usr/share/snmp/mibs/ietf:/usr/share/vyos/mibs" -ExecStart= -ExecStart={{vrf_command}}/usr/sbin/snmpd -LS0-5d -Lf /dev/null -u Debian-snmp -g Debian-snmp {{oid_route_table}} -f -p /run/snmpd.pid -Restart=always -RestartSec=10 - diff --git a/data/templates/snmp/usr.snmpd.conf.j2 b/data/templates/snmp/usr.snmpd.conf.j2 new file mode 100644 index 000000000..a713c1cec --- /dev/null +++ b/data/templates/snmp/usr.snmpd.conf.j2 @@ -0,0 +1,8 @@ +### Autogenerated by snmp.py ### +{% if v3.user is vyos_defined %} +{% for user, user_config in v3.user.items() %} +{{ user_config.mode }}user {{ user }} +{% endfor %} +{% endif %} + +rwuser {{ vyos_user }} diff --git a/data/templates/snmp/usr.snmpd.conf.tmpl b/data/templates/snmp/usr.snmpd.conf.tmpl deleted file mode 100644 index e2c5ec102..000000000 --- a/data/templates/snmp/usr.snmpd.conf.tmpl +++ /dev/null @@ -1,6 +0,0 @@ -### Autogenerated by snmp.py ### -{% for u in v3_users %} -{{ u.mode }}user {{ u.name }} -{% endfor %} - -rwuser {{ vyos_user }} diff --git a/data/templates/snmp/var.snmpd.conf.j2 b/data/templates/snmp/var.snmpd.conf.j2 new file mode 100644 index 000000000..012f33aeb --- /dev/null +++ b/data/templates/snmp/var.snmpd.conf.j2 @@ -0,0 +1,16 @@ +### Autogenerated by snmp.py ### +# user +{% if v3 is vyos_defined %} +{% if v3.user is vyos_defined %} +{% for user, user_config in v3.user.items() %} +usmUser 1 3 0x{{ v3.engineid }} "{{ user }}" "{{ user }}" NULL {{ user_config.auth.type | snmp_auth_oid }} 0x{{ user_config.auth.encrypted_password }} {{ user_config.privacy.type | snmp_auth_oid }} 0x{{ user_config.privacy.encrypted_password }} 0x +{% endfor %} +{% endif %} + +# VyOS default user +createUser {{ vyos_user }} MD5 "{{ vyos_user_pass }}" DES + +{% if v3.engineid is vyos_defined %} +oldEngineID 0x{{ v3.engineid }} +{% endif %} +{% endif %} diff --git a/data/templates/snmp/var.snmpd.conf.tmpl b/data/templates/snmp/var.snmpd.conf.tmpl deleted file mode 100644 index c779587df..000000000 --- a/data/templates/snmp/var.snmpd.conf.tmpl +++ /dev/null @@ -1,14 +0,0 @@ -### Autogenerated by snmp.py ### -# user -{% for u in v3_users %} -{% if u.authOID == 'none' %} -createUser {{ u.name }} -{% else %} -usmUser 1 3 0x{{ v3_engineid }} "{{ u.name }}" "{{ u.name }}" NULL {{ u.authOID }} 0x{{ u.authMasterKey }} {{ u.privOID }} 0x{{ u.privMasterKey }} 0x -{% endif %} -{% endfor %} - -createUser {{ vyos_user }} MD5 "{{ vyos_user_pass }}" DES -{% if v3_engineid %} -oldEngineID 0x{{ v3_engineid }} -{% endif %} diff --git a/data/templates/squid/sg_acl.conf.tmpl b/data/templates/squid/sg_acl.conf.j2 index ce72b173a..ce72b173a 100644 --- a/data/templates/squid/sg_acl.conf.tmpl +++ b/data/templates/squid/sg_acl.conf.j2 diff --git a/data/templates/squid/squid.conf.j2 b/data/templates/squid/squid.conf.j2 new file mode 100644 index 000000000..a0fdeb20e --- /dev/null +++ b/data/templates/squid/squid.conf.j2 @@ -0,0 +1,111 @@ +### generated by service_webproxy.py ### + +acl net src all +acl SSL_ports port 443 +acl Safe_ports port 80 # http +acl Safe_ports port 21 # ftp +acl Safe_ports port 443 # https +acl Safe_ports port 873 # rsync +acl Safe_ports port 70 # gopher +acl Safe_ports port 210 # wais +acl Safe_ports port 1025-65535 # unregistered ports +acl Safe_ports port 280 # http-mgmt +acl Safe_ports port 488 # gss-http +acl Safe_ports port 591 # filemaker +acl Safe_ports port 777 # multiling http +acl CONNECT method CONNECT + +{% if authentication is vyos_defined %} +{% if authentication.children is vyos_defined %} +auth_param basic children {{ authentication.children }} +{% endif %} +{% if authentication.credentials_ttl is vyos_defined %} +auth_param basic credentialsttl {{ authentication.credentials_ttl }} minute +{% endif %} +{% if authentication.realm is vyos_defined %} +auth_param basic realm "{{ authentication.realm }}" +{% endif %} +{# LDAP based Authentication #} +{% if authentication.method is vyos_defined %} +{% if authentication.ldap is vyos_defined and authentication.method is vyos_defined('ldap') %} +auth_param basic program /usr/lib/squid/basic_ldap_auth -v {{ authentication.ldap.version }} -b "{{ authentication.ldap.base_dn }}" {{ '-D "' ~ authentication.ldap.bind_dn ~ '"' if authentication.ldap.bind_dn is vyos_defined }} {{ '-w "' ~ authentication.ldap.password ~ '"' if authentication.ldap.password is vyos_defined }} {{ '-f "' ~ authentication.ldap.filter_expression ~ '"' if authentication.ldap.filter_expression is vyos_defined }} {{ '-u "' ~ authentication.ldap.username_attribute ~ '"' if authentication.ldap.username_attribute is vyos_defined }} -p {{ authentication.ldap.port }} {{ '-ZZ' if authentication.ldap.use_ssl is vyos_defined }} -R -h "{{ authentication.ldap.server }}" +{% endif %} +acl auth proxy_auth REQUIRED +http_access allow auth +{% endif %} +{% endif %} + +http_access allow manager localhost +http_access deny manager +http_access deny !Safe_ports +http_access deny CONNECT !SSL_ports +http_access allow localhost +http_access allow net +http_access deny all + +{% if reply_block_mime is vyos_defined %} +{% for mime_type in reply_block_mime %} +acl BLOCK_MIME rep_mime_type {{ mime_type }} +{% endfor %} +http_reply_access deny BLOCK_MIME +{% endif %} + +{% if cache_size is vyos_defined %} +{% if cache_size | int > 0 %} +cache_dir ufs /var/spool/squid {{ cache_size }} 16 256 +{% else %} +# disabling disk cache +{% endif %} +{% endif %} +{% if mem_cache_size is vyos_defined %} +cache_mem {{ mem_cache_size }} MB +{% endif %} +{% if disable_access_log is vyos_defined %} +access_log none +{% else %} +access_log /var/log/squid/access.log squid +{% endif %} + +{# by default we'll disable the store log #} +cache_store_log none + +{% if append_domain is vyos_defined %} +append_domain {{ append_domain }} +{% endif %} +{% if maximum_object_size is vyos_defined %} +maximum_object_size {{ maximum_object_size }} KB +{% endif %} +{% if minimum_object_size is vyos_defined %} +minimum_object_size {{ minimum_object_size }} KB +{% endif %} +{% if reply_body_max_size is vyos_defined %} +reply_body_max_size {{ reply_body_max_size }} KB +{% endif %} +{% if outgoing_address is vyos_defined %} +tcp_outgoing_address {{ outgoing_address }} +{% endif %} + + +{% if listen_address is vyos_defined %} +{% for address, config in listen_address.items() %} +http_port {{ address | bracketize_ipv6 }}:{{ config.port if config.port is vyos_defined else default_port }} {{ 'intercept' if config.disable_transparent is not vyos_defined }} +{% endfor %} +{% endif %} +http_port 127.0.0.1:{{ default_port }} + +{# NOT insert the client address in X-Forwarded-For header #} +forwarded_for off + +{# SquidGuard #} +{% if url_filtering.disable is not vyos_defined and url_filtering.squidguard is vyos_defined %} +url_rewrite_program /usr/bin/squidGuard -c {{ squidguard_conf }} +url_rewrite_children 8 +url_rewrite_bypass on +{% endif %} + +{% if cache_peer is vyos_defined %} +{% for peer, config in cache_peer.items() %} +cache_peer {{ config.address }} {{ config.type }} {{ config.http_port }} {{ config.icp_port }} {{ config.options }} +{% endfor %} +never_direct allow all +{% endif %} diff --git a/data/templates/squid/squid.conf.tmpl b/data/templates/squid/squid.conf.tmpl deleted file mode 100644 index 80826fc75..000000000 --- a/data/templates/squid/squid.conf.tmpl +++ /dev/null @@ -1,113 +0,0 @@ -### generated by service_webproxy.py ### - -acl net src all -acl SSL_ports port 443 -acl Safe_ports port 80 # http -acl Safe_ports port 21 # ftp -acl Safe_ports port 443 # https -acl Safe_ports port 873 # rsync -acl Safe_ports port 70 # gopher -acl Safe_ports port 210 # wais -acl Safe_ports port 1025-65535 # unregistered ports -acl Safe_ports port 280 # http-mgmt -acl Safe_ports port 488 # gss-http -acl Safe_ports port 591 # filemaker -acl Safe_ports port 777 # multiling http -acl CONNECT method CONNECT - -{% if authentication is defined and authentication is not none %} -{% if authentication.children is defined and authentication.children is not none %} -auth_param basic children {{ authentication.children }} -{% endif %} -{% if authentication.credentials_ttl is defined and authentication.credentials_ttl is not none %} -auth_param basic credentialsttl {{ authentication.credentials_ttl }} minute -{% endif %} -{% if authentication.realm is defined and authentication.realm is not none %} -auth_param basic realm "{{ authentication.realm }}" -{% endif %} -{# LDAP based Authentication #} -{% if authentication.method is defined and authentication.method is not none %} -{% if authentication.ldap is defined and authentication.ldap is not none and authentication.method == 'ldap' %} -auth_param basic program /usr/lib/squid/basic_ldap_auth -v {{ authentication.ldap.version }} -b "{{ authentication.ldap.base_dn }}" {{ '-D "' + authentication.ldap.bind_dn + '"' if authentication.ldap.bind_dn is defined }} {{ '-w "' + authentication.ldap.password + '"' if authentication.ldap.password is defined }} {{ '-f "' + authentication.ldap.filter_expression + '"' if authentication.ldap.filter_expression is defined }} {{ '-u "' + authentication.ldap.username_attribute + '"' if authentication.ldap.username_attribute is defined }} -p {{ authentication.ldap.port }} {{ '-ZZ' if authentication.ldap.use_ssl is defined }} -R -h "{{ authentication.ldap.server }}" -{% endif %} -acl auth proxy_auth REQUIRED -http_access allow auth -{% endif %} -{% endif %} - -http_access allow manager localhost -http_access deny manager -http_access deny !Safe_ports -http_access deny CONNECT !SSL_ports -http_access allow localhost -http_access allow net -http_access deny all - -{% if reply_block_mime is defined and reply_block_mime is not none %} -{% for mime_type in reply_block_mime %} -acl BLOCK_MIME rep_mime_type {{ mime_type }} -{% endfor %} -http_reply_access deny BLOCK_MIME -{% endif %} - -{% if cache_size is defined and cache_size is not none %} -{% if cache_size | int > 0 %} -cache_dir ufs /var/spool/squid {{ cache_size }} 16 256 -{% else %} -# disabling disk cache -{% endif %} -{% endif %} -{% if mem_cache_size is defined and mem_cache_size is not none %} -cache_mem {{ mem_cache_size }} MB -{% endif %} -{% if disable_access_log is defined %} -access_log none -{% else %} -access_log /var/log/squid/access.log squid -{% endif %} - -{# by default we'll disable the store log #} -cache_store_log none - -{% if append_domain is defined and append_domain is not none %} -append_domain {{ append_domain }} -{% endif %} -{% if maximum_object_size is defined and maximum_object_size is not none %} -maximum_object_size {{ maximum_object_size }} KB -{% endif %} -{% if minimum_object_size is defined and minimum_object_size is not none %} -minimum_object_size {{ minimum_object_size }} KB -{% endif %} -{% if reply_body_max_size is defined and reply_body_max_size is not none %} -reply_body_max_size {{ reply_body_max_size }} KB -{% endif %} -{% if outgoing_address is defined and outgoing_address is not none %} -tcp_outgoing_address {{ outgoing_address }} -{% endif %} - - -{% if listen_address is defined and listen_address is not none %} -{% for address, config in listen_address.items() %} -http_port {{ address }}:{{ config.port if config.port is defined else default_port }} {{ 'intercept' if config.disable_transparent is not defined }} -{% endfor %} -{% endif %} -http_port 127.0.0.1:{{ default_port }} - -{# NOT insert the client address in X-Forwarded-For header #} -forwarded_for off - -{# SquidGuard #} -{% if url_filtering is defined and url_filtering.disable is not defined %} -{% if url_filtering.squidguard is defined and url_filtering.squidguard is not none %} -url_rewrite_program /usr/bin/squidGuard -c {{ squidguard_conf }} -url_rewrite_children 8 -url_rewrite_bypass on -{% endif %} -{% endif %} - -{% if cache_peer is defined and cache_peer is not none %} -{% for peer, config in cache_peer.items() %} -cache_peer {{ config.address }} {{ config.type }} {{ config.http_port }} {{ config.icp_port }} {{ config.options }} -{% endfor %} -never_direct allow all -{% endif %} diff --git a/data/templates/squid/squidGuard.conf.j2 b/data/templates/squid/squidGuard.conf.j2 new file mode 100644 index 000000000..1bc4c984f --- /dev/null +++ b/data/templates/squid/squidGuard.conf.j2 @@ -0,0 +1,124 @@ +### generated by service_webproxy.py ### + +{% macro sg_rule(category, log, db_dir) %} +{% set expressions = db_dir + '/' + category + '/expressions' %} +dest {{ category }}-default { + domainlist {{ category }}/domains + urllist {{ category }}/urls +{% if expressions | is_file %} + expressionlist {{ category }}/expressions +{% endif %} +{% if log is vyos_defined %} + log blacklist.log +{% endif %} +} +{% endmacro %} + +{% if url_filtering is vyos_defined and url_filtering.disable is not vyos_defined %} +{% if url_filtering.squidguard is vyos_defined %} +{% set sg_config = url_filtering.squidguard %} +{% set acl = namespace(value='local-ok-default') %} +{% set acl.value = acl.value + ' !in-addr' if sg_config.allow_ipaddr_url is not defined else acl.value %} +dbhome {{ squidguard_db_dir }} +logdir /var/log/squid + +rewrite safesearch { + s@(.*\.google\..*/(custom|search|images|groups|news)?.*q=.*)@\1\&safe=active@i + s@(.*\..*/yandsearch?.*text=.*)@\1\&fyandex=1@i + s@(.*\.yahoo\..*/search.*p=.*)@\1\&vm=r@i + s@(.*\.live\..*/.*q=.*)@\1\&adlt=strict@i + s@(.*\.msn\..*/.*q=.*)@\1\&adlt=strict@i + s@(.*\.bing\..*/search.*q=.*)@\1\&adlt=strict@i + log rewrite.log +} + +{% if sg_config.local_ok is vyos_defined %} +{% set acl.value = acl.value + ' local-ok-default' %} +dest local-ok-default { + domainlist local-ok-default/domains +} +{% endif %} +{% if sg_config.local_ok_url is vyos_defined %} +{% set acl.value = acl.value + ' local-ok-url-default' %} +dest local-ok-url-default { + urllist local-ok-url-default/urls +} +{% endif %} +{% if sg_config.local_block is vyos_defined %} +{% set acl.value = acl.value + ' !local-block-default' %} +dest local-block-default { + domainlist local-block-default/domains +} +{% endif %} +{% if sg_config.local_block_url is vyos_defined %} +{% set acl.value = acl.value + ' !local-block-url-default' %} +dest local-block-url-default { + urllist local-block-url-default/urls +} +{% endif %} +{% if sg_config.local_block_keyword is vyos_defined %} +{% set acl.value = acl.value + ' !local-block-keyword-default' %} +dest local-block-keyword-default { + expressionlist local-block-keyword-default/expressions +} +{% endif %} + +{% if sg_config.block_category is vyos_defined %} +{% for category in sg_config.block_category %} +{{ sg_rule(category, sg_config.log, squidguard_db_dir) }} +{% set acl.value = acl.value + ' !' + category + '-default' %} +{% endfor %} +{% endif %} +{% if sg_config.allow_category is vyos_defined %} +{% for category in sg_config.allow_category %} +{{ sg_rule(category, False, squidguard_db_dir) }} +{% set acl.value = acl.value + ' ' + category + '-default' %} +{% endfor %} +{% endif %} +{% if sg_config.source_group is vyos_defined %} +{% for sgroup, sg_config in sg_config.source_group.items() %} +{% if sg_config.address is vyos_defined %} +src {{ sgroup }} { +{% for address in sg_config.address %} + ip {{ address }} +{% endfor %} +} + +{% endif %} +{% endfor %} +{% endif %} +{% if sg_config.rule is vyos_defined %} +{% for rule, rule_config in sg_config.rule.items() %} +{% for b_category in rule_config.block_category %} +dest {{ b_category }} { + domainlist {{ b_category }}/domains + urllist {{ b_category }}/urls +} +{% endfor %} + +{% endfor %} +{% endif %} +acl { +{% if sg_config.rule is vyos_defined %} +{% for rule, rule_config in sg_config.rule.items() %} + {{ rule_config.source_group }} { +{% for b_category in rule_config.block_category %} + pass local-ok-1 !in-addr !{{ b_category }} all +{% endfor %} + } +{% endfor %} +{% endif %} + + default { +{% if sg_config.enable_safe_search is vyos_defined %} + rewrite safesearch +{% endif %} + pass {{ acl.value }} {{ 'none' if sg_config.default_action is vyos_defined('block') else 'allow' }} + redirect 302:http://{{ sg_config.redirect_url }} +{% if sg_config.log is vyos_defined %} + log blacklist.log +{% endif %} + } +} +{% endif %} +{% endif %} diff --git a/data/templates/squid/squidGuard.conf.tmpl b/data/templates/squid/squidGuard.conf.tmpl deleted file mode 100644 index c59dc901e..000000000 --- a/data/templates/squid/squidGuard.conf.tmpl +++ /dev/null @@ -1,124 +0,0 @@ -### generated by service_webproxy.py ### - -{% macro sg_rule(category, log, db_dir) %} -{% set expressions = db_dir + '/' + category + '/expressions' %} -dest {{ category }}-default { - domainlist {{ category }}/domains - urllist {{ category }}/urls -{% if expressions | is_file %} - expressionlist {{ category }}/expressions -{% endif %} -{% if log is defined %} - log blacklist.log -{% endif %} -} -{% endmacro %} - -{% if url_filtering is defined and url_filtering.disable is not defined %} -{% if url_filtering.squidguard is defined and url_filtering.squidguard is not none %} -{% set sg_config = url_filtering.squidguard %} -{% set acl = namespace(value='local-ok-default') %} -{% set acl.value = acl.value + ' !in-addr' if sg_config.allow_ipaddr_url is not defined else acl.value %} -dbhome {{ squidguard_db_dir }} -logdir /var/log/squid - -rewrite safesearch { - s@(.*\.google\..*/(custom|search|images|groups|news)?.*q=.*)@\1\&safe=active@i - s@(.*\..*/yandsearch?.*text=.*)@\1\&fyandex=1@i - s@(.*\.yahoo\..*/search.*p=.*)@\1\&vm=r@i - s@(.*\.live\..*/.*q=.*)@\1\&adlt=strict@i - s@(.*\.msn\..*/.*q=.*)@\1\&adlt=strict@i - s@(.*\.bing\..*/search.*q=.*)@\1\&adlt=strict@i - log rewrite.log -} - -{% if sg_config.local_ok is defined and sg_config.local_ok is not none %} -{% set acl.value = acl.value + ' local-ok-default' %} -dest local-ok-default { - domainlist local-ok-default/domains -} -{% endif %} -{% if sg_config.local_ok_url is defined and sg_config.local_ok_url is not none %} -{% set acl.value = acl.value + ' local-ok-url-default' %} -dest local-ok-url-default { - urllist local-ok-url-default/urls -} -{% endif %} -{% if sg_config.local_block is defined and sg_config.local_block is not none %} -{% set acl.value = acl.value + ' !local-block-default' %} -dest local-block-default { - domainlist local-block-default/domains -} -{% endif %} -{% if sg_config.local_block_url is defined and sg_config.local_block_url is not none %} -{% set acl.value = acl.value + ' !local-block-url-default' %} -dest local-block-url-default { - urllist local-block-url-default/urls -} -{% endif %} -{% if sg_config.local_block_keyword is defined and sg_config.local_block_keyword is not none %} -{% set acl.value = acl.value + ' !local-block-keyword-default' %} -dest local-block-keyword-default { - expressionlist local-block-keyword-default/expressions -} -{% endif %} - -{% if sg_config.block_category is defined and sg_config.block_category is not none %} -{% for category in sg_config.block_category %} -{{ sg_rule(category, sg_config.log, squidguard_db_dir) }} -{% set acl.value = acl.value + ' !' + category + '-default' %} -{% endfor %} -{% endif %} -{% if sg_config.allow_category is defined and sg_config.allow_category is not none %} -{% for category in sg_config.allow_category %} -{{ sg_rule(category, False, squidguard_db_dir) }} -{% set acl.value = acl.value + ' ' + category + '-default' %} -{% endfor %} -{% endif %} -{% if sg_config.source_group is defined and sg_config.source_group is not none %} -{% for sgroup, sg_config in sg_config.source_group.items() %} -{% if sg_config.address is defined and sg_config.address is not none %} -src {{ sgroup }} { -{% for address in sg_config.address %} - ip {{ address }} -{% endfor %} -} - -{% endif %} -{% endfor %} -{% endif %} -{% if sg_config.rule is defined and sg_config.rule is not none %} -{% for rule, rule_config in sg_config.rule.items() %} -{% for b_category in rule_config.block_category%} -dest {{ b_category }} { - domainlist {{ b_category }}/domains - urllist {{ b_category }}/urls -} -{% endfor %} - -{% endfor %} -{% endif %} -acl { -{% if sg_config.rule is defined and sg_config.rule is not none %} -{% for rule, rule_config in sg_config.rule.items() %} - {{ rule_config.source_group }} { -{% for b_category in rule_config.block_category%} - pass local-ok-1 !in-addr !{{ b_category }} all -{% endfor %} - } -{% endfor %} -{% endif %} - - default { -{% if sg_config.enable_safe_search is defined %} - rewrite safesearch -{% endif %} - pass {{ acl.value }} {{ 'none' if sg_config.default_action is defined and sg_config.default_action == 'block' else 'allow' }} - redirect 302:http://{{ sg_config.redirect_url }} -{% if sg_config.log is defined and sg_config.log is not none %} - log blacklist.log -{% endif %} - } -} -{% endif %} -{% endif %} diff --git a/data/templates/ssh/override.conf.j2 b/data/templates/ssh/override.conf.j2 new file mode 100644 index 000000000..e4d6f51cb --- /dev/null +++ b/data/templates/ssh/override.conf.j2 @@ -0,0 +1,13 @@ +{% set vrf_command = 'ip vrf exec ' ~ vrf ~ ' ' if vrf is vyos_defined else '' %} +[Unit] +StartLimitIntervalSec=0 +After=vyos-router.service +ConditionPathExists={{ config_file }} + +[Service] +ExecStart= +ExecStart={{ vrf_command }}/usr/sbin/sshd -f {{ config_file }} -D $SSHD_OPTS +Restart=always +RestartPreventExitStatus= +RestartSec=10 +RuntimeDirectoryPreserve=yes diff --git a/data/templates/ssh/override.conf.tmpl b/data/templates/ssh/override.conf.tmpl deleted file mode 100644 index 5f8f35e89..000000000 --- a/data/templates/ssh/override.conf.tmpl +++ /dev/null @@ -1,13 +0,0 @@ -{% set vrf_command = 'ip vrf exec ' + vrf + ' ' if vrf is defined else '' %} -[Unit] -StartLimitIntervalSec=0 -After=vyos-router.service -ConditionPathExists={{config_file}} - -[Service] -ExecStart= -ExecStart={{vrf_command}}/usr/sbin/sshd -f {{config_file}} -D $SSHD_OPTS -Restart=always -RestartPreventExitStatus= -RestartSec=10 -RuntimeDirectoryPreserve=yes diff --git a/data/templates/ssh/sshd_config.tmpl b/data/templates/ssh/sshd_config.j2 index 2f2b78a66..e7dbca581 100644 --- a/data/templates/ssh/sshd_config.tmpl +++ b/data/templates/ssh/sshd_config.j2 @@ -29,6 +29,7 @@ UsePAM yes PermitRootLogin no PidFile /run/sshd/sshd.pid AddressFamily any +DebianBanner no # # User configurable section @@ -36,7 +37,7 @@ AddressFamily any # Look up remote host name and check that the resolved host name for the remote IP # address maps back to the very same IP address. -UseDNS {{ "no" if disable_host_validation is defined else "yes" }} +UseDNS {{ "no" if disable_host_validation is vyos_defined else "yes" }} # Specifies the port number that sshd(8) listens on {% for value in port %} @@ -47,61 +48,50 @@ Port {{ value }} LogLevel {{ loglevel | upper }} # Specifies whether password authentication is allowed -PasswordAuthentication {{ "no" if disable_password_authentication is defined else "yes" }} +PasswordAuthentication {{ "no" if disable_password_authentication is vyos_defined else "yes" }} -{% if listen_address is defined and listen_address is not none %} +{% if listen_address is vyos_defined %} # Specifies the local addresses sshd should listen on -{% for address in listen_address %} +{% for address in listen_address %} ListenAddress {{ address }} -{% endfor %} +{% endfor %} {% endif %} -{% if ciphers is defined and ciphers is not none %} +{% if ciphers is vyos_defined %} # Specifies the ciphers allowed for protocol version 2 -{% set value = ciphers if ciphers is string else ciphers | join(',') %} -Ciphers {{ value }} +Ciphers {{ ciphers | join(',') }} {% endif %} -{% if mac is defined and mac is not none %} +{% if mac is vyos_defined %} # Specifies the available MAC (message authentication code) algorithms -{% set value = mac if mac is string else mac | join(',') %} -MACs {{ value }} +MACs {{ mac | join(',') }} {% endif %} -{% if key_exchange is defined and key_exchange is not none %} +{% if key_exchange is vyos_defined %} # Specifies the available Key Exchange algorithms -{% set value = key_exchange if key_exchange is string else key_exchange | join(',') %} -KexAlgorithms {{ value }} +KexAlgorithms {{ key_exchange | join(',') }} {% endif %} -{% if access_control is defined and access_control is not none %} -{% if access_control.allow is defined and access_control.allow is not none %} -{% if access_control.allow.user is defined %} +{% if access_control is vyos_defined %} +{% if access_control.allow.user is vyos_defined %} # If specified, login is allowed only for user names that match -{% set value = access_control.allow.user if access_control.allow.user is string else access_control.allow.user | join(' ') %} -AllowUsers {{ value }} +AllowUsers {{ access_control.allow.user | join(' ') }} {% endif %} -{% if access_control.allow.group is defined %} +{% if access_control.allow.group is vyos_defined %} # If specified, login is allowed only for users whose primary group or supplementary group list matches -{% set value = access_control.allow.group if access_control.allow.group is string else access_control.allow.group | join(' ') %} -AllowGroups {{ value }} +AllowGroups {{ access_control.allow.group | join(' ') }} {% endif %} -{% endif %} -{% if access_control.deny is defined and access_control.deny is not none %} -{% if access_control.deny.user is defined %} +{% if access_control.deny.user is vyos_defined %} # Login is disallowed for user names that match -{% set value = access_control.deny.user if access_control.deny.user is string else access_control.deny.user | join(' ') %} -DenyUsers {{ value }} +DenyUsers {{ access_control.deny.user | join(' ') }} {% endif %} -{% if access_control.deny.group is defined %} +{% if access_control.deny.group is vyos_defined %} # Login is disallowed for users whose primary group or supplementary group list matches -{% set value = access_control.deny.group if access_control.deny.group is string else access_control.deny.group | join(' ') %} -DenyGroups {{ value }} +DenyGroups {{ access_control.deny.group | join(' ') }} {% endif %} -{% endif %} {% endif %} -{% if client_keepalive_interval is defined and client_keepalive_interval is not none %} +{% if client_keepalive_interval is vyos_defined %} # Sets a timeout interval in seconds after which if no data has been received from the client, # sshd(8) will send a message through the encrypted channel to request a response from the client ClientAliveInterval {{ client_keepalive_interval }} diff --git a/data/templates/ssh/sshguard_config.j2 b/data/templates/ssh/sshguard_config.j2 new file mode 100644 index 000000000..58c6ad48d --- /dev/null +++ b/data/templates/ssh/sshguard_config.j2 @@ -0,0 +1,27 @@ +### Autogenerated by ssh.py ### + +{% if dynamic_protection is vyos_defined %} +# Full path to backend executable (required, no default) +BACKEND="/usr/libexec/sshguard/sshg-fw-nft-sets" + +# Shell command that provides logs on standard output. (optional, no default) +# Example 1: ssh and sendmail from systemd journal: +LOGREADER="LANG=C journalctl -afb -p info -n1 -t sshd -o cat" + +#### OPTIONS #### +# Block attackers when their cumulative attack score exceeds THRESHOLD. +# Most attacks have a score of 10. (optional, default 30) +THRESHOLD={{ dynamic_protection.threshold }} + +# Block attackers for initially BLOCK_TIME seconds after exceeding THRESHOLD. +# Subsequent blocks increase by a factor of 1.5. (optional, default 120) +BLOCK_TIME={{ dynamic_protection.block_time }} + +# Remember potential attackers for up to DETECTION_TIME seconds before +# resetting their score. (optional, default 1800) +DETECTION_TIME={{ dynamic_protection.detect_time }} + +# IP addresses listed in the WHITELIST_FILE are considered to be +# friendlies and will never be blocked. +WHITELIST_FILE=/etc/sshguard/whitelist +{% endif %} diff --git a/data/templates/ssh/sshguard_whitelist.j2 b/data/templates/ssh/sshguard_whitelist.j2 new file mode 100644 index 000000000..47a950a2b --- /dev/null +++ b/data/templates/ssh/sshguard_whitelist.j2 @@ -0,0 +1,7 @@ +### Autogenerated by ssh.py ### + +{% if dynamic_protection.allow_from is vyos_defined %} +{% for address in dynamic_protection.allow_from %} +{{ address }} +{% endfor %} +{% endif %} diff --git a/data/templates/syslog/logrotate.j2 b/data/templates/syslog/logrotate.j2 new file mode 100644 index 000000000..c1b951e8b --- /dev/null +++ b/data/templates/syslog/logrotate.j2 @@ -0,0 +1,11 @@ +{{ config_render['log-file'] }} { + missingok + notifempty + create + rotate {{ config_render['max-files'] }} + size={{ config_render['max-size'] // 1024 }}k + postrotate + invoke-rc.d rsyslog rotate > /dev/null + endscript +} + diff --git a/data/templates/syslog/logrotate.tmpl b/data/templates/syslog/logrotate.tmpl deleted file mode 100644 index f758265e4..000000000 --- a/data/templates/syslog/logrotate.tmpl +++ /dev/null @@ -1,12 +0,0 @@ -{% for file in files %} -{{files[file]['log-file']}} { - missingok - notifempty - create - rotate {{files[file]['max-files']}} - size={{files[file]['max-size']//1024}}k - postrotate - invoke-rc.d rsyslog rotate > /dev/null - endscript -} -{% endfor %} diff --git a/data/templates/syslog/rsyslog.conf.j2 b/data/templates/syslog/rsyslog.conf.j2 new file mode 100644 index 000000000..4445d568b --- /dev/null +++ b/data/templates/syslog/rsyslog.conf.j2 @@ -0,0 +1,54 @@ +## generated by syslog.py ## +## file based logging +{% if files['global']['marker'] %} +$ModLoad immark +{% if files['global']['marker-interval'] %} +$MarkMessagePeriod {{ files['global']['marker-interval'] }} +{% endif %} +{% endif %} +{% if files['global']['preserver_fqdn'] %} +$PreserveFQDN on +{% endif %} +{% 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 is defined and console is not none %} +## console logging +{% for con, con_options in console.items() %} +{{ con_options['selectors'] }} /dev/console +{% endfor %} +{% endif %} +{% if hosts is defined and hosts is not none %} +## remote logging +{% 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 | bracketize_ipv6 }}:{{ host_options.port }};RSYSLOG_SyslogProtocol23Format +{% else %} +{{ host_options.selectors }} @@{{ host | bracketize_ipv6 }}:{{ host_options.port }} +{% endif %} +{% else %} +{{ host_options.selectors }} @@{{ host | bracketize_ipv6 }} +{% endif %} +{% elif host_options.proto == 'udp' %} +{% if host_options.port is defined %} +{{ host_options.selectors }} @{{ host | bracketize_ipv6 }}:{{ host_options.port }}{{ ';RSYSLOG_SyslogProtocol23Format' if host_options.oct_count is sameas true }} +{% else %} +{{ host_options.selectors }} @{{ host | bracketize_ipv6 }} +{% endif %} +{% else %} +{% if host_options['port'] %} +{{ host_options.selectors }} @{{ host | bracketize_ipv6 }}:{{ host_options.port }} +{% else %} +{{ host_options.selectors }} @{{ host | bracketize_ipv6 }} +{% endif %} +{% endif %} +{% endfor %} +{% endif %} +{% 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/data/templates/syslog/rsyslog.conf.tmpl b/data/templates/syslog/rsyslog.conf.tmpl deleted file mode 100644 index e25ef48d4..000000000 --- a/data/templates/syslog/rsyslog.conf.tmpl +++ /dev/null @@ -1,48 +0,0 @@ -## generated by syslog.py ## -## file based logging -{% if files['global']['marker'] %} -$ModLoad immark -{% if files['global']['marker-interval'] %} -$MarkMessagePeriod {{files['global']['marker-interval']}} -{% endif %} -{% endif %} -{% if files['global']['preserver_fqdn'] %} -$PreserveFQDN on -{% endif %} -{% 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 is defined and console is not none %} -## console logging -{% for con, con_options in console.items() %} -{{ con_options['selectors'] }} /dev/console -{% endfor %} -{% endif %} -{% if hosts is defined and hosts is not none %} -## remote logging -{% 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 %} -{{ host_options.selectors }} @@{{ host }} -{% endif %} -{% else %} -{% if host_options['port'] %} -{{ host_options.selectors }} @{{ host | bracketize_ipv6 }}:{{ host_options.port }} -{% else %} -{{ host_options.selectors }} @{{ host | bracketize_ipv6 }} -{% endif %} -{% endif %} -{% endfor %} -{% endif %} -{% 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/data/templates/system/curlrc.j2 b/data/templates/system/curlrc.j2 new file mode 100644 index 000000000..be4efe8ba --- /dev/null +++ b/data/templates/system/curlrc.j2 @@ -0,0 +1,6 @@ +{% if http_client.source_interface is vyos_defined %} +--interface "{{ http_client.source_interface }}" +{% endif %} +{% if http_client.source_address is vyos_defined %} +--interface "{{ http_client.source_address }}" +{% endif %} diff --git a/data/templates/system/curlrc.tmpl b/data/templates/system/curlrc.tmpl deleted file mode 100644 index 3e5ce801c..000000000 --- a/data/templates/system/curlrc.tmpl +++ /dev/null @@ -1,8 +0,0 @@ -{% if http_client is defined %} -{% if http_client.source_interface is defined %} ---interface "{{ http_client.source_interface }}" -{% endif %} -{% if http_client.source_address is defined %} ---interface "{{ http_client.source_address }}" -{% endif %} -{% endif %} diff --git a/data/templates/system/proxy.j2 b/data/templates/system/proxy.j2 new file mode 100644 index 000000000..215c4c5c2 --- /dev/null +++ b/data/templates/system/proxy.j2 @@ -0,0 +1,7 @@ +# generated by system-proxy.py +{% if url is vyos_defined and port is vyos_defined %} +{# remove http:// prefix so we can inject a username/password if present #} +export http_proxy=http://{{ username ~ ':' ~ password ~ '@' if username is vyos_defined and password is vyos_defined }}{{ url | replace('http://', '') }}:{{ port }} +export https_proxy=$http_proxy +export ftp_proxy=$http_proxy +{% endif %} diff --git a/data/templates/system/ssh_config.j2 b/data/templates/system/ssh_config.j2 new file mode 100644 index 000000000..1449f95b1 --- /dev/null +++ b/data/templates/system/ssh_config.j2 @@ -0,0 +1,3 @@ +{% if ssh_client.source_address is vyos_defined %} +BindAddress {{ ssh_client.source_address }} +{% endif %} diff --git a/data/templates/system/ssh_config.tmpl b/data/templates/system/ssh_config.tmpl deleted file mode 100644 index abc03f069..000000000 --- a/data/templates/system/ssh_config.tmpl +++ /dev/null @@ -1,3 +0,0 @@ -{% if ssh_client is defined and ssh_client.source_address is defined and ssh_client.source_address is not none %} -BindAddress {{ ssh_client.source_address }} -{% endif %} diff --git a/data/templates/system/sysctl.conf.j2 b/data/templates/system/sysctl.conf.j2 new file mode 100644 index 000000000..59a19e157 --- /dev/null +++ b/data/templates/system/sysctl.conf.j2 @@ -0,0 +1,7 @@ +# autogenerated by system_sysctl.py
+
+{% if parameter is vyos_defined %}
+{% for k, v in parameter.items() %}
+{{ k }} = {{ v.value }}
+{% endfor %}
+{% endif %}
diff --git a/data/templates/system/sysctl.conf.tmpl b/data/templates/system/sysctl.conf.tmpl deleted file mode 100644 index 72af82ee5..000000000 --- a/data/templates/system/sysctl.conf.tmpl +++ /dev/null @@ -1,7 +0,0 @@ -# autogenerated by system_sysctl.py
-
-{% if parameter is defined and parameter is not none %}
-{% for k, v in parameter.items() %}
-{{ k }} = {{ v.value }}
-{% endfor %}
-{% endif %}
diff --git a/data/templates/tftp-server/default.j2 b/data/templates/tftp-server/default.j2 new file mode 100644 index 000000000..b2676e0aa --- /dev/null +++ b/data/templates/tftp-server/default.j2 @@ -0,0 +1,8 @@ +{# j2lint: disable=jinja-variable-format #} +### Autogenerated by tftp_server.py ### +DAEMON_ARGS="--listen --user tftp --address {{ listen_address }} {{ "--create --umask 000" if allow_upload is vyos_defined }} --secure {{ directory }}" +{% if vrf is vyos_defined %} +VRF_ARGS="ip vrf exec {{ vrf }}" +{% else %} +VRF_ARGS="" +{% endif %} diff --git a/data/templates/tftp-server/default.tmpl b/data/templates/tftp-server/default.tmpl deleted file mode 100644 index 6b2d6a903..000000000 --- a/data/templates/tftp-server/default.tmpl +++ /dev/null @@ -1,2 +0,0 @@ -### Autogenerated by tftp_server.py ### -DAEMON_ARGS="--listen --user tftp --address {{ listen_address }} {{ "--create --umask 000" if allow_upload is defined }} --secure {{ directory }}" diff --git a/data/templates/vrf/vrf.conf.j2 b/data/templates/vrf/vrf.conf.j2 new file mode 100644 index 000000000..d31d23574 --- /dev/null +++ b/data/templates/vrf/vrf.conf.j2 @@ -0,0 +1,9 @@ +### Autogenerated by vrf.py ### +# +# Routing table ID to name mapping reference +# id vrf name comment +{% if name is vyos_defined %} +{% for vrf, vrf_config in name.items() %} +{{ "%-10s" | format(vrf_config.table) }} {{ "%-16s" | format(vrf) }} {{ '# ' ~ vrf_config.description if vrf_config.description is vyos_defined }} +{% endfor %} +{% endif %} diff --git a/data/templates/vrf/vrf.conf.tmpl b/data/templates/vrf/vrf.conf.tmpl deleted file mode 100644 index 29c0ba08d..000000000 --- a/data/templates/vrf/vrf.conf.tmpl +++ /dev/null @@ -1,9 +0,0 @@ -### Autogenerated by vrf.py ### -# -# Routing table ID to name mapping reference -# id vrf name comment -{% if name is defined and name is not none %} -{% for vrf, vrf_config in name.items() %} -{{ "%-10s" | format(vrf_config.table) }} {{ "%-16s" | format(vrf) }} {{ '# ' + vrf_config.description if vrf_config.description is defined and vrf_config.description is not none }} -{% endfor %} -{% endif %} diff --git a/data/templates/vrrp/keepalived.conf.tmpl b/data/templates/vrrp/keepalived.conf.tmpl deleted file mode 100644 index b4824a994..000000000 --- a/data/templates/vrrp/keepalived.conf.tmpl +++ /dev/null @@ -1,106 +0,0 @@ -# Autogenerated by VyOS -# Do not edit this file, all your changes will be lost -# on next commit or reboot - -global_defs { - dynamic_interfaces - script_user root - # Don't run scripts configured to be run as root if any part of the path - # is writable by a non-root user. - enable_script_security - notify_fifo /run/keepalived/keepalived_notify_fifo - notify_fifo_script /usr/libexec/vyos/system/keepalived-fifo.py -} - -{% if group is defined and group is not none %} -{% for name, group_config in group.items() if group_config.disable is not defined %} -{% if group_config.health_check is defined and group_config.health_check.script is defined and group_config.health_check.script is not none %} -vrrp_script healthcheck_{{ name }} { - script "{{ group_config.health_check.script }}" - interval {{ group_config.health_check.interval }} - fall {{ group_config.health_check.failure_count }} - rise 1 -} -{% endif %} -vrrp_instance {{ name }} { -{% if group_config.description is defined and group_config.description is not none %} - # {{ group_config.description }} -{% endif %} - state BACKUP - interface {{ group_config.interface }} - virtual_router_id {{ group_config.vrid }} - priority {{ group_config.priority }} - advert_int {{ group_config.advertise_interval }} -{% if group_config.no_preempt is not defined and group_config.preempt_delay is defined and group_config.preempt_delay is not none %} - preempt_delay {{ group_config.preempt_delay }} -{% elif group_config.no_preempt is defined %} - nopreempt -{% endif %} -{% if group_config.peer_address is defined and group_config.peer_address is not none %} - unicast_peer { {{ group_config.peer_address }} } -{% endif %} -{% if group_config.hello_source_address is defined and group_config.hello_source_address is not none %} -{% if group_config.peer_address is defined and group_config.peer_address is not none %} - unicast_src_ip {{ group_config.hello_source_address }} -{% else %} - mcast_src_ip {{ group_config.hello_source_address }} -{% endif %} -{% endif %} -{% if group_config.rfc3768_compatibility is defined and group_config.peer_address is defined %} - use_vmac {{ group_config.interface }}v{{ group_config.vrid }} - vmac_xmit_base -{% elif group_config.rfc3768_compatibility is defined %} - use_vmac {{ group_config.interface }}v{{ group_config.vrid }} -{% endif %} -{% if group_config.authentication is defined and group_config.authentication is not none %} - authentication { - auth_pass "{{ group_config.authentication.password }}" -{% if group_config.authentication.type == 'plaintext-password' %} - auth_type PASS -{% else %} - auth_type {{ group_config.authentication.type | upper }} -{% endif %} - } -{% endif %} -{% if group_config.address is defined and group_config.address is not none %} - virtual_ipaddress { -{% for addr in group_config.address %} - {{ addr }} -{% endfor %} - } -{% endif %} -{% if group_config.excluded_address is defined and group_config.excluded_address is not none %} - virtual_ipaddress_excluded { -{% for addr in group_config.excluded_address %} - {{ addr }} -{% endfor %} - } -{% endif %} -{% if group_config.health_check is defined and group_config.health_check.script is defined and group_config.health_check.script is not none %} - track_script { - healthcheck_{{ name }} - } -{% endif %} -} -{% endfor %} -{% endif %} - -{% if sync_group is defined and sync_group is not none %} -{% for name, group_config in sync_group.items() if group_config.disable is not defined %} -vrrp_sync_group {{ name }} { - group { -{% if group_config.member is defined and group_config.member is not none %} -{% for member in group_config.member %} - {{ member }} -{% endfor %} -{% endif %} - } -{% if conntrack_sync_group is defined and conntrack_sync_group == name %} -{% set vyos_helper = "/usr/libexec/vyos/vyos-vrrp-conntracksync.sh" %} - notify_master "{{ vyos_helper }} master {{ name }}" - notify_backup "{{ vyos_helper }} backup {{ name }}" - notify_fault "{{ vyos_helper }} fault {{ name }}" -{% endif %} -} -{% endfor %} -{% endif %} diff --git a/data/templates/vyos-hostsd/hosts.tmpl b/data/templates/vyos-hostsd/hosts.j2 index 03662d562..5cad983b4 100644 --- a/data/templates/vyos-hostsd/hosts.tmpl +++ b/data/templates/vyos-hostsd/hosts.j2 @@ -1,3 +1,4 @@ +{# j2lint: disable=single-statement-per-line #} ### Autogenerated by VyOS ### ### Do not edit, your changes will get overwritten ### @@ -12,14 +13,14 @@ ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters -{% if hosts is defined and hosts is not none %} +{% if hosts is vyos_defined %} # From 'system static-host-mapping' and DHCP server -{% for tag, taghosts in hosts.items() %} +{% for tag, taghosts in hosts.items() %} # {{ tag }} -{% for host, hostprops in taghosts.items() if hostprops.address is defined %} -{% for addr in hostprops.address %} -{{ "%-15s" | format(addr) }} {{ host }} {{ hostprops.aliases|join(' ') if hostprops.aliases is defined }} -{% endfor %} +{% for host, hostprops in taghosts.items() if hostprops.address is vyos_defined %} +{% for addr in hostprops.address %} +{{ "%-15s" | format(addr) }} {{ host }} {{ hostprops.aliases | join(' ') if hostprops.aliases is vyos_defined }} +{% endfor %} +{% endfor %} {% endfor %} -{% endfor %} {% endif %} diff --git a/data/templates/vyos-hostsd/resolv.conf.tmpl b/data/templates/vyos-hostsd/resolv.conf.j2 index 58a5f9312..5f651f1a1 100644 --- a/data/templates/vyos-hostsd/resolv.conf.tmpl +++ b/data/templates/vyos-hostsd/resolv.conf.j2 @@ -5,12 +5,12 @@ {# the order of tags, then by the order of nameservers within that tag #} {% for tag in name_server_tags_system %} -{% if tag in name_servers %} +{% if tag in name_servers %} # {{ tag }} -{% for ns in name_servers[tag] %} +{% for ns in name_servers[tag] %} nameserver {{ ns }} -{% endfor %} -{% endif %} +{% endfor %} +{% endif %} {% endfor %} {% if domain_name %} @@ -18,8 +18,8 @@ domain {{ domain_name }} {% endif %} {% for tag in name_server_tags_system %} -{% if tag in search_domains %} +{% if tag in search_domains %} # {{ tag }} -search {{ search_domains[tag]|join(' ') }} -{% endif %} +search {{ search_domains[tag] | join(' ') }} +{% endif %} {% endfor %} diff --git a/data/templates/wifi/cfg80211.conf.tmpl b/data/templates/wifi/cfg80211.conf.tmpl deleted file mode 100644 index 91df57aab..000000000 --- a/data/templates/wifi/cfg80211.conf.tmpl +++ /dev/null @@ -1 +0,0 @@ -{{ 'options cfg80211 ieee80211_regdom=' + regdom if regdom is defined }} diff --git a/data/templates/wifi/crda.tmpl b/data/templates/wifi/crda.tmpl deleted file mode 100644 index 6cd125e37..000000000 --- a/data/templates/wifi/crda.tmpl +++ /dev/null @@ -1 +0,0 @@ -{{ 'REGDOMAIN=' + regdom if regdom is defined }} diff --git a/data/templates/wifi/hostapd.conf.tmpl b/data/templates/wifi/hostapd.conf.j2 index 433e1d36f..f2312d2d4 100644 --- a/data/templates/wifi/hostapd.conf.tmpl +++ b/data/templates/wifi/hostapd.conf.j2 @@ -1,5 +1,6 @@ +{# j2lint: disable=operator-enclosed-by-spaces #} ### Autogenerated by interfaces-wireless.py ### -{% if description %} +{% if description is vyos_defined %} # Description: {{ description }} # User-friendly description of device; up to 32 octets encoded in UTF-8 device_name={{ description | truncate(32, True) }} @@ -11,7 +12,7 @@ device_name={{ description | truncate(32, True) }} # command line parameter. interface={{ ifname }} -{% if is_bridge_member is defined %} +{% if is_bridge_member is vyos_defined %} # In case of atheros and nl80211 driver interfaces, an additional # configuration parameter, bridge, may be used to notify hostapd if the # interface is included in a bridge. This parameter is not used with Host AP @@ -24,9 +25,9 @@ interface={{ ifname }} # has been started to change the interface mode). If needed, the bridge # interface is also created. {# as there can only be one bridge interface it is save to loop #} -{% for bridge in is_bridge_member %} +{% for bridge in is_bridge_member %} bridge={{ bridge }} -{% endfor %} +{% endfor %} {% endif %} # Driver interface type (hostap/wired/none/nl80211/bsd); @@ -72,7 +73,7 @@ ssid={{ ssid }} channel={{ channel }} {% endif %} -{% if mode is defined and mode is not none %} +{% if mode is vyos_defined %} # Operation mode (a = IEEE 802.11a (5 GHz), b = IEEE 802.11b (2.4 GHz), # g = IEEE 802.11g (2.4 GHz), ad = IEEE 802.11ad (60 GHz); a/g options are used # with IEEE 802.11n (HT), too, to specify band). For IEEE 802.11ac (VHT), this @@ -81,15 +82,15 @@ channel={{ channel }} # special value "any" can be used to indicate that any support band can be used. # This special case is currently supported only with drivers with which # offloaded ACS is used. -{% if mode == 'n' %} +{% if mode is vyos_defined('n') %} hw_mode=g -{% elif mode == 'ac' %} +{% elif mode is vyos_defined('ac') %} hw_mode=a ieee80211h=1 ieee80211ac=1 -{% else %} +{% else %} hw_mode={{ mode }} -{% endif %} +{% endif %} {% endif %} # ieee80211w: Whether management frame protection (MFP) is enabled @@ -104,7 +105,7 @@ ieee80211w=1 ieee80211w=2 {% endif %} -{% if capabilities is defined and capabilities.ht is defined %} +{% if capabilities is vyos_defined %} # ht_capab: HT capabilities (list of flags) # LDPC coding capability: [LDPC] = supported # Supported channel width set: [HT40-] = both 20 MHz and 40 MHz with secondary @@ -138,70 +139,70 @@ ieee80211w=2 # DSSS/CCK Mode in 40 MHz: [DSSS_CCK-40] = allowed (not allowed if not set) # 40 MHz intolerant [40-INTOLERANT] (not advertised if not set) # L-SIG TXOP protection support: [LSIG-TXOP-PROT] (disabled if not set) -{% set output = namespace(value='') %} - -{% if capabilities.ht.fourtymhz_incapable is defined %} -{% set output.value = output.value + '[40-INTOLERANT]' %} -{% endif %} -{% if capabilities.ht.delayed_block_ack is defined %} -{% set output.value = output.value + '[DELAYED-BA]' %} -{% endif %} -{% if capabilities.ht.dsss_cck_40 is defined %} -{% set output.value = output.value + '[DSSS_CCK-40]' %} -{% endif %} -{% if capabilities.ht.greenfield is defined %} -{% set output.value = output.value + '[GF]' %} -{% endif %} -{% if capabilities.ht.ldpc is defined %} -{% set output.value = output.value + '[LDPC]' %} -{% endif %} -{% if capabilities.ht.lsig_protection is defined %} -{% set output.value = output.value + '[LSIG-TXOP-PROT]' %} -{% endif %} -{% if capabilities.ht.stbc is defined and capabilities.ht.stbc.tx is defined %} -{% set output.value = output.value + '[TX-STBC]' %} -{% endif %} -{% if capabilities.ht.stbc is defined and capabilities.ht.stbc.rx is defined %} -{% set output.value = output.value + '[RX-STBC-' + capabilities.ht.stbc.rx | upper + ']' %} -{% endif %} -{% if capabilities.ht.max_amsdu is defined %} -{% set output.value = output.value + '[MAX-AMSDU-' + capabilities.ht.max_amsdu + ']' %} -{% endif %} -{% if capabilities.ht.smps is defined %} -{% set output.value = output.value + '[SMPS-' + capabilities.ht.smps | upper + ']' %} -{% endif %} - -{% if capabilities.ht.channel_set_width is defined %} -{% for csw in capabilities.ht.channel_set_width %} -{% set output.value = output.value + '[' + csw | upper + ']' %} -{% endfor %} -{% endif %} +{% set output = namespace(value='') %} -{% if capabilities.ht.short_gi is defined %} -{% for short_gi in capabilities.ht.short_gi %} -{% set output.value = output.value + '[SHORT-GI-' + short_gi | upper + ']' %} -{% endfor %} -{% endif %} +{% if capabilities.ht.fourtymhz_incapable is vyos_defined %} +{% set output.value = output.value ~ '[40-INTOLERANT]' %} +{% endif %} +{% if capabilities.ht.delayed_block_ack is vyos_defined %} +{% set output.value = output.value ~ '[DELAYED-BA]' %} +{% endif %} +{% if capabilities.ht.dsss_cck_40 is vyos_defined %} +{% set output.value = output.value ~ '[DSSS_CCK-40]' %} +{% endif %} +{% if capabilities.ht.greenfield is vyos_defined %} +{% set output.value = output.value ~ '[GF]' %} +{% endif %} +{% if capabilities.ht.ldpc is vyos_defined %} +{% set output.value = output.value ~ '[LDPC]' %} +{% endif %} +{% if capabilities.ht.lsig_protection is vyos_defined %} +{% set output.value = output.value ~ '[LSIG-TXOP-PROT]' %} +{% endif %} +{% if capabilities.ht.stbc.tx is vyos_defined %} +{% set output.value = output.value ~ '[TX-STBC]' %} +{% endif %} +{% if capabilities.ht.stbc.rx is vyos_defined %} +{% set output.value = output.value ~ '[RX-STBC-' ~ capabilities.ht.stbc.rx | upper ~ ']' %} +{% endif %} +{% if capabilities.ht.max_amsdu is vyos_defined %} +{% set output.value = output.value ~ '[MAX-AMSDU-' ~ capabilities.ht.max_amsdu ~ ']' %} +{% endif %} +{% if capabilities.ht.smps is vyos_defined %} +{% set output.value = output.value ~ '[SMPS-' ~ capabilities.ht.smps | upper ~ ']' %} +{% endif %} + +{% if capabilities.ht.channel_set_width is vyos_defined %} +{% for csw in capabilities.ht.channel_set_width %} +{% set output.value = output.value ~ '[' ~ csw | upper ~ ']' %} +{% endfor %} +{% endif %} + +{% if capabilities.ht.short_gi is vyos_defined %} +{% for short_gi in capabilities.ht.short_gi %} +{% set output.value = output.value ~ '[SHORT-GI-' ~ short_gi | upper ~ ']' %} +{% endfor %} +{% endif %} ht_capab={{ output.value }} -{% if capabilities.ht.auto_powersave is defined %} +{% if capabilities.ht.auto_powersave is vyos_defined %} # WMM-PS Unscheduled Automatic Power Save Delivery [U-APSD] # Enable this flag if U-APSD supported outside hostapd (eg., Firmware/driver) uapsd_advertisement_enabled=1 -{% endif %} +{% endif %} {% endif %} # Required for full HT and VHT functionality wme_enabled=1 -{% if capabilities is defined and capabilities.require_ht is defined %} +{% if capabilities.require_ht is vyos_defined %} # Require stations to support HT PHY (reject association if they do not) require_ht=1 {% endif %} -{% if capabilities is defined and capabilities.vht is defined %} +{% if capabilities.vht is vyos_defined %} # vht_capab: VHT capabilities (list of flags) # # vht_max_mpdu_len: [MAX-MPDU-7991] [MAX-MPDU-11454] @@ -297,7 +298,7 @@ require_ht=1 # Indicates the maximum length of A-MPDU pre-EOF padding that the STA can recv # This field is an integer in the range of 0 to 7. # The length defined by this field is equal to -# 2 pow(13 + Maximum A-MPDU Length Exponent) -1 octets +# 2 pow(13 ~ Maximum A-MPDU Length Exponent) -1 octets # # VHT Link Adaptation Capable: [VHT-LINK-ADAPT2] [VHT-LINK-ADAPT3] # Indicates whether or not the STA supports link adaptation using VHT variant @@ -320,87 +321,86 @@ require_ht=1 # 0 = Tx antenna pattern might change during the lifetime of an association # 1 = Tx antenna pattern does not change during the lifetime of an -{% if capabilities.vht.center_channel_freq is defined and capabilities.vht.center_channel_freq.freq_1 is defined %} -# center freq = 5 GHz + (5 * index) +{% if capabilities.vht.center_channel_freq.freq_1 is vyos_defined %} +# center freq = 5 GHz ~ (5 * index) # So index 42 gives center freq 5.210 GHz # which is channel 42 in 5G band vht_oper_centr_freq_seg0_idx={{ capabilities.vht.center_channel_freq.freq_1 }} -{% endif %} +{% endif %} -{% if capabilities.vht.center_channel_freq is defined and capabilities.vht.center_channel_freq.freq_2 is defined %} -# center freq = 5 GHz + (5 * index) +{% if capabilities.vht.center_channel_freq.freq_2 is vyos_defined %} +# center freq = 5 GHz ~ (5 * index) # So index 159 gives center freq 5.795 GHz # which is channel 159 in 5G band vht_oper_centr_freq_seg1_idx={{ capabilities.vht.center_channel_freq.freq_2 }} -{% endif %} +{% endif %} -{% if capabilities.vht.channel_set_width is defined %} +{% if capabilities.vht.channel_set_width is vyos_defined %} vht_oper_chwidth={{ capabilities.vht.channel_set_width }} -{% endif %} - -{% set output = namespace(value='') %} -{% if capabilities.vht.stbc is defined and capabilities.vht.stbc.tx is defined %} -{% set output.value = output.value + '[TX-STBC-2BY1]' %} -{% endif %} -{% if capabilities.vht.stbc is defined and capabilities.vht.stbc.rx is defined %} -{% set output.value = output.value + '[RX-STBC-' + capabilities.vht.stbc.rx + ']' %} -{% endif %} -{% if capabilities.vht.ldpc is defined %} -{% set output.value = output.value + '[RXLDPC]' %} -{% endif %} -{% if capabilities.vht.tx_powersave is defined %} -{% set output.value = output.value + '[VHT-TXOP-PS]' %} -{% endif %} -{% if capabilities.vht.vht_cf is defined %} -{% set output.value = output.value + '[HTC-VHT]' %} -{% endif %} -{% if capabilities.vht.antenna_pattern_fixed is defined %} -{% set output.value = output.value + '[RX-ANTENNA-PATTERN][TX-ANTENNA-PATTERN]' %} -{% endif %} -{% if capabilities.vht.max_mpdu is defined %} -{% set output.value = output.value + '[MAX-MPDU-' + capabilities.vht.max_mpdu + ']' %} -{% endif %} -{% if capabilities.vht.max_mpdu_exp is defined %} -{% set output.value = output.value + '[MAX-A-MPDU-LEN-EXP-' + capabilities.vht.max_mpdu_exp + ']' %} -{% endif %} -{% if capabilities.vht.max_mpdu_exp is defined and capabilities.vht.max_mpdu_exp == '2' %} -{% set output.value = output.value + '[VHT160]' %} -{% endif %} -{% if capabilities.vht.max_mpdu_exp is defined and capabilities.vht.max_mpdu_exp == '3' %} -{% set output.value = output.value + '[VHT160-80PLUS80]' %} -{% endif %} -{% if capabilities.vht.link_adaptation is defined and capabilities.vht.link_adaptation == 'unsolicited' %} -{% set output.value = output.value + '[VHT-LINK-ADAPT2]' %} -{% endif %} -{% if capabilities.vht.link_adaptation is defined and capabilities.vht.link_adaptation == 'both' %} -{% set output.value = output.value + '[VHT-LINK-ADAPT3]' %} -{% endif %} - -{% for short_gi in capabilities.vht.short_gi if capabilities.vht.short_gi is defined %} -{% set output.value = output.value + '[SHORT-GI-' + short_gi | upper + ']' %} -{% endfor %} - -{% for beamform in capabilities.vht.beamform if capabilities.vht.beamform is defined %} -{% set output.value = output.value + '[SU-BEAMFORMER]' if beamform == 'single-user-beamformer' else '' %} -{% set output.value = output.value + '[SU-BEAMFORMEE]' if beamform == 'single-user-beamformee' else '' %} -{% set output.value = output.value + '[MU-BEAMFORMER]' if beamform == 'multi-user-beamformer' else '' %} -{% set output.value = output.value + '[MU-BEAMFORMEE]' if beamform == 'multi-user-beamformee' else '' %} -{% endfor %} - -{% if capabilities.vht.antenna_count is defined and capabilities.vht.antenna_count|int > 1 %} -{% if capabilities.vht.beamform %} -{% if beamform == 'single-user-beamformer' %} -{% if capabilities.vht.antenna_count is defined and capabilities.vht.antenna_count|int > 1 and capabilities.vht.antenna_count|int < 6 %} -{% set output.value = output.value + '[BF-ANTENNA-' + capabilities.vht.antenna_count|int -1 + ']' %} -{% set output.value = output.value + '[SOUNDING-DIMENSION-' + capabilities.vht.antenna_count|int -1 + ']' %} +{% endif %} + +{% set output = namespace(value='') %} +{% if capabilities.vht.stbc.tx is vyos_defined %} +{% set output.value = output.value ~ '[TX-STBC-2BY1]' %} +{% endif %} +{% if capabilities.vht.stbc.rx is vyos_defined %} +{% set output.value = output.value ~ '[RX-STBC-' ~ capabilities.vht.stbc.rx ~ ']' %} +{% endif %} +{% if capabilities.vht.ldpc is vyos_defined %} +{% set output.value = output.value ~ '[RXLDPC]' %} +{% endif %} +{% if capabilities.vht.tx_powersave is vyos_defined %} +{% set output.value = output.value ~ '[VHT-TXOP-PS]' %} +{% endif %} +{% if capabilities.vht.vht_cf is vyos_defined %} +{% set output.value = output.value ~ '[HTC-VHT]' %} +{% endif %} +{% if capabilities.vht.antenna_pattern_fixed is vyos_defined %} +{% set output.value = output.value ~ '[RX-ANTENNA-PATTERN][TX-ANTENNA-PATTERN]' %} +{% endif %} +{% if capabilities.vht.max_mpdu is vyos_defined %} +{% set output.value = output.value ~ '[MAX-MPDU-' ~ capabilities.vht.max_mpdu ~ ']' %} +{% endif %} +{% if capabilities.vht.max_mpdu_exp is vyos_defined %} +{% set output.value = output.value ~ '[MAX-A-MPDU-LEN-EXP-' ~ capabilities.vht.max_mpdu_exp ~ ']' %} +{% if capabilities.vht.max_mpdu_exp is vyos_defined('2') %} +{% set output.value = output.value ~ '[VHT160]' %} +{% endif %} +{% if capabilities.vht.max_mpdu_exp is vyos_defined('3') %} +{% set output.value = output.value ~ '[VHT160-80PLUS80]' %} +{% endif %} +{% endif %} +{% if capabilities.vht.link_adaptation is vyos_defined('unsolicited') %} +{% set output.value = output.value ~ '[VHT-LINK-ADAPT2]' %} +{% elif capabilities.vht.link_adaptation is vyos_defined('both') %} +{% set output.value = output.value ~ '[VHT-LINK-ADAPT3]' %} +{% endif %} + +{% for short_gi in capabilities.vht.short_gi if capabilities.vht.short_gi is vyos_defined %} +{% set output.value = output.value ~ '[SHORT-GI-' ~ short_gi | upper ~ ']' %} +{% endfor %} + +{% for beamform in capabilities.vht.beamform if capabilities.vht.beamform is vyos_defined %} +{% set output.value = output.value ~ '[SU-BEAMFORMER]' if beamform is vyos_defined('single-user-beamformer') else '' %} +{% set output.value = output.value ~ '[SU-BEAMFORMEE]' if beamform is vyos_defined('single-user-beamformee') else '' %} +{% set output.value = output.value ~ '[MU-BEAMFORMER]' if beamform is vyos_defined('multi-user-beamformer') else '' %} +{% set output.value = output.value ~ '[MU-BEAMFORMEE]' if beamform is vyos_defined('multi-user-beamformee') else '' %} +{% endfor %} + +{% if capabilities.vht.antenna_count is vyos_defined and capabilities.vht.antenna_count | int > 1 %} +{% if capabilities.vht.beamform is vyos_defined %} +{% if capabilities.vht.beamform == 'single-user-beamformer' %} +{% if capabilities.vht.antenna_count is vyos_defined and capabilities.vht.antenna_count | int > 1 and capabilities.vht.antenna_count | int < 6 %} +{% set output.value = output.value ~ '[BF-ANTENNA-' ~ capabilities.vht.antenna_count | int -1 ~ ']' %} +{% set output.value = output.value ~ '[SOUNDING-DIMENSION-' ~ capabilities.vht.antenna_count | int -1 ~ ']' %} +{% endif %} +{% endif %} +{% if capabilities.vht.antenna_count is vyos_defined and capabilities.vht.antenna_count | int > 1 and capabilities.vht.antenna_count | int < 5 %} +{% set output.value = output.value ~ '[BF-ANTENNA-' ~ capabilities.vht.antenna_count ~ ']' %} +{% set output.value = output.value ~ '[SOUNDING-DIMENSION-' ~ capabilities.vht.antenna_count ~ ']' %} +{% endif %} {% endif %} -{% endif %} -{% if capabilities.vht.antenna_count is defined and capabilities.vht.antenna_count|int > 1 and capabilities.vht.antenna_count|int < 5 %} -{% set output.value = output.value + '[BF-ANTENNA-' + capabilities.vht.antenna_count + ']' %} -{% set output.value = output.value + '[SOUNDING-DIMENSION-' + capabilities.vht.antenna_count+ ']' %} -{% endif %} {% endif %} -{% endif %} vht_capab={{ output.value }} {% endif %} @@ -410,19 +410,15 @@ vht_capab={{ output.value }} # 1 = enabled # Note: You will also need to enable WMM for full HT functionality. # Note: hw_mode=g (2.4 GHz) and hw_mode=a (5 GHz) is used to specify the band. -{% if capabilities is defined and capabilities.require_vht is defined %} +{% if capabilities.require_vht is vyos_defined %} ieee80211n=0 # Require stations to support VHT PHY (reject association if they do not) require_vht=1 {% else %} -{% if 'n' in mode or 'ac' in mode %} -ieee80211n=1 -{% else %} -ieee80211n=0 -{% endif %} +ieee80211n={{ '1' if 'n' in mode or 'ac' in mode else '0' }} {% endif %} -{% if disable_broadcast_ssid is defined %} +{% if disable_broadcast_ssid is vyos_defined %} # Send empty SSID in beacons and ignore probe request frames that do not # specify full SSID, i.e., require stations to know SSID. # default: disabled (0) @@ -443,7 +439,7 @@ ignore_broadcast_ssid=1 # 2 = use external RADIUS server (accept/deny lists are searched first) macaddr_acl=0 -{% if max_stations is defined %} +{% if max_stations is vyos_defined %} # Maximum number of stations allowed in station table. New stations will be # rejected after the station table is full. IEEE 802.11 has a limit of 2007 # different association IDs, so this number should not be larger than that. @@ -451,13 +447,13 @@ macaddr_acl=0 max_num_sta={{ max_stations }} {% endif %} -{% if isolate_stations is defined %} +{% if isolate_stations is vyos_defined %} # Client isolation can be used to prevent low-level bridging of frames between # associated stations in the BSS. By default, this bridging is allowed. ap_isolate=1 {% endif %} -{% if reduce_transmit_power is defined %} +{% if reduce_transmit_power is vyos_defined %} # Add Power Constraint element to Beacon and Probe Response frames # This config option adds Power Constraint element when applicable and Country # element is added. Power Constraint element is required by Transmit Power @@ -466,7 +462,7 @@ ap_isolate=1 local_pwr_constraint={{ reduce_transmit_power }} {% endif %} -{% if expunge_failing_stations is defined %} +{% if expunge_failing_stations is vyos_defined %} # Disassociate stations based on excessive transmission failures or other # indications of connection loss. This depends on the driver capabilities and # may not be available with all drivers. @@ -474,7 +470,7 @@ disassoc_low_ack=1 {% endif %} -{% if security is defined and security.wep is defined %} +{% if security.wep is vyos_defined %} # IEEE 802.11 specifies two authentication algorithms. hostapd can be # configured to allow both of these or only one. Open system authentication # should be used with IEEE 802.1X. @@ -503,14 +499,14 @@ wep_default_key=0 # digits, depending on whether 40-bit (64-bit), 104-bit (128-bit), or # 128-bit (152-bit) WEP is used. # Only the default key must be supplied; the others are optional. -{% if security.wep.key is defined %} -{% for key in sec_wep_key %} +{% if security.wep.key is vyos_defined %} +{% for key in sec_wep_key %} wep_key{{ loop.index -1 }}={{ security.wep.key }} -{% endfor %} -{% endif %} +{% endfor %} +{% endif %} -{% elif security is defined and security.wpa is defined %} +{% elif security.wpa is vyos_defined %} ##### WPA/IEEE 802.11i configuration ########################################## # Enable WPA. Setting this variable configures the AP to require WPA (either @@ -527,17 +523,15 @@ wep_key{{ loop.index -1 }}={{ security.wep.key }} # Note that WPA3 is also configured with bit1 since it uses RSN just like WPA2. # In other words, for WPA3, wpa 2 is used the configuration (and # wpa_key_mgmt=SAE for WPA3-Personal instead of wpa_key_mgmt=WPA-PSK). -{% if security.wpa.mode is defined %} -{% if security.wpa.mode == 'wpa+wpa2' %} +{% if security.wpa.mode is vyos_defined('wpa+wpa2') %} wpa=3 -{% elif security.wpa.mode == 'wpa2' or security.wpa.mode == 'wpa3' %} +{% elif security.wpa.mode is vyos_defined('wpa2') or security.wpa.mode is vyos_defined('wpa3') %} wpa=2 -{% elif security.wpa.mode == 'wpa' %} +{% elif security.wpa.mode is vyos_defined('wpa') %} wpa=1 {% endif %} -{% endif %} -{% if security.wpa.cipher is defined %} +{% if security.wpa.cipher is vyos_defined %} # Set of accepted cipher suites (encryption algorithms) for pairwise keys # (unicast packets). This is a space separated list of algorithms: # CCMP = AES in Counter mode with CBC-MAC (CCMP-128) @@ -551,16 +545,16 @@ wpa=1 # TKIP will be used as the group cipher. The optional group_cipher parameter can # be used to override this automatic selection. -{% if security.wpa.mode is defined and security.wpa.mode == 'wpa2' %} +{% if security.wpa.mode is vyos_defined('wpa2') %} # Pairwise cipher for RSN/WPA2 (default: use wpa_pairwise value) rsn_pairwise={{ security.wpa.cipher | join(" ") }} -{% else %} +{% else %} # Pairwise cipher for WPA (v1) (default: TKIP) wpa_pairwise={{ security.wpa.cipher | join(" ") }} +{% endif %} {% endif %} -{% endif %} -{% if security.wpa.group_cipher is defined %} +{% if security.wpa.group_cipher is vyos_defined %} # Optional override for automatic group cipher selection # This can be used to select a specific group cipher regardless of which # pairwise ciphers were enabled for WPA and RSN. It should be noted that @@ -568,9 +562,9 @@ wpa_pairwise={{ security.wpa.cipher | join(" ") }} # interoperability issues and in general, this parameter is mainly used for # testing purposes. group_cipher={{ security.wpa.group_cipher | join(" ") }} -{% endif %} +{% endif %} -{% if security.wpa.passphrase is defined %} +{% if security.wpa.passphrase is vyos_defined %} # IEEE 802.11 specifies two authentication algorithms. hostapd can be # configured to allow both of these or only one. Open system authentication # should be used with IEEE 802.1X. @@ -594,13 +588,13 @@ wpa_passphrase={{ security.wpa.passphrase }} # WPA-EAP-SHA256 = WPA2-Enterprise using SHA256 # SAE = SAE (WPA3-Personal) # WPA-EAP-SUITE-B-192 = WPA3-Enterprise with 192-bit security/CNSA suite -{% if security.wpa.mode is defined and security.wpa.mode == 'wpa3' %} +{% if security.wpa.mode is vyos_defined('wpa3') %} wpa_key_mgmt=SAE -{% else %} +{% else %} wpa_key_mgmt=WPA-PSK WPA-PSK-SHA256 -{% endif %} +{% endif %} -{% elif security.wpa.radius is defined %} +{% elif security.wpa.radius is vyos_defined %} ##### IEEE 802.1X-2004 related configuration ################################## # Require IEEE 802.1X authorization ieee8021x=1 @@ -614,43 +608,43 @@ ieee8021x=1 # WPA-EAP-SHA256 = WPA2-Enterprise using SHA256 # SAE = SAE (WPA3-Personal) # WPA-EAP-SUITE-B-192 = WPA3-Enterprise with 192-bit security/CNSA suite -{% if security.wpa.mode is defined and security.wpa.mode == 'wpa3' %} +{% if security.wpa.mode is vyos_defined('wpa3') %} wpa_key_mgmt=WPA-EAP-SUITE-B-192 -{% else %} +{% else %} wpa_key_mgmt=WPA-EAP WPA-EAP-SHA256 -{% endif %} +{% endif %} -{% if security.wpa.radius.server is defined %} +{% if security.wpa.radius.server is vyos_defined %} # RADIUS client forced local IP address for the access point # Normally the local IP address is determined automatically based on configured # IP addresses, but this field can be used to force a specific address to be # used, e.g., when the device has multiple IP addresses. # The own IP address of the access point (used as NAS-IP-Address) -{% if security.wpa.radius.source_address is defined %} +{% if security.wpa.radius.source_address is vyos_defined %} radius_client_addr={{ security.wpa.radius.source_address }} own_ip_addr={{ security.wpa.radius.source_address }} -{% else %} +{% else %} own_ip_addr=127.0.0.1 -{% endif %} +{% endif %} -{% for radius in security.wpa.radius.server if not radius.disabled %} +{% for radius in security.wpa.radius.server if not radius.disabled %} # RADIUS authentication server auth_server_addr={{ radius.server }} auth_server_port={{ radius.port }} auth_server_shared_secret={{ radius.key }} -{% if radius.acc_port %} +{% if radius.acc_port %} # RADIUS accounting server acct_server_addr={{ radius.server }} acct_server_port={{ radius.acc_port }} acct_server_shared_secret={{ radius.key }} -{% endif %} -{% endfor %} -{% else %} +{% endif %} +{% endfor %} +{% else %} # Open system auth_algs=1 +{% endif %} {% endif %} -{% endif %} {% endif %} # TX queue parameters (EDCF / bursting) diff --git a/data/templates/wifi/wpa_supplicant.conf.tmpl b/data/templates/wifi/wpa_supplicant.conf.j2 index 20b4f7976..01e0d632f 100644 --- a/data/templates/wifi/wpa_supplicant.conf.tmpl +++ b/data/templates/wifi/wpa_supplicant.conf.j2 @@ -18,7 +18,7 @@ network={ # this will add latency to scanning, so enable this only when needed) scan_ssid=1 -{% if security is defined and security.wpa is defined and security.wpa.passphrase is defined %} +{% if security.wpa.passphrase is vyos_defined %} # ieee80211w: whether management frame protection is enabled # 0 = disabled (default unless changed with the global pmf parameter) # 1 = optional @@ -59,11 +59,11 @@ network={ # OWE = Opportunistic Wireless Encryption (a.k.a. Enhanced Open) # DPP = Device Provisioning Protocol # If not set, this defaults to: WPA-PSK WPA-EAP -{% if security.wpa.mode is defined and security.wpa.mode == 'wpa3' %} +{% if security.wpa.mode is vyos_defined('wpa3') %} key_mgmt=SAE -{% else %} +{% else %} key_mgmt=WPA-PSK WPA-PSK-SHA256 -{% endif %} +{% endif %} # psk: WPA preshared key; 256-bit pre-shared key # The key used in WPA-PSK mode can be entered either as 64 hex-digits, i.e., diff --git a/data/templates/zone_policy/nftables.j2 b/data/templates/zone_policy/nftables.j2 new file mode 100644 index 000000000..e4c4dd7da --- /dev/null +++ b/data/templates/zone_policy/nftables.j2 @@ -0,0 +1,113 @@ +#!/usr/sbin/nft -f + +{% if cleanup_commands is vyos_defined %} +{% for command in cleanup_commands %} +{{ command }} +{% endfor %} +{% endif %} + +{% if zone is vyos_defined %} +table ip filter { +{% for zone_name, zone_conf in zone.items() if zone_conf.ipv4 %} +{% if zone_conf.local_zone is vyos_defined %} + chain VZONE_{{ zone_name }}_IN { + iifname lo counter return +{% for from_zone, from_conf in zone_conf.from.items() if from_conf.firewall.name is vyos_defined %} + iifname { {{ zone[from_zone].interface | join(",") }} } counter jump NAME_{{ from_conf.firewall.name }} + iifname { {{ zone[from_zone].interface | join(",") }} } counter return +{% endfor %} + counter {{ zone_conf.default_action }} + } + chain VZONE_{{ zone_name }}_OUT { + oifname lo counter return +{% for from_zone, from_conf in zone_conf.from_local.items() if from_conf.firewall.name is vyos_defined %} + oifname { {{ zone[from_zone].interface | join(",") }} } counter jump NAME_{{ from_conf.firewall.name }} + oifname { {{ zone[from_zone].interface | join(",") }} } counter return +{% endfor %} + counter {{ zone_conf.default_action }} + } +{% else %} + chain VZONE_{{ zone_name }} { + iifname { {{ zone_conf.interface | join(",") }} } counter {{ zone_conf | nft_intra_zone_action(ipv6=False) }} +{% if zone_conf.intra_zone_filtering is vyos_defined %} + iifname { {{ zone_conf.interface | join(",") }} } counter return +{% endif %} +{% for from_zone, from_conf in zone_conf.from.items() if from_conf.firewall.name is vyos_defined %} +{% if zone[from_zone].local_zone is not defined %} + iifname { {{ zone[from_zone].interface | join(",") }} } counter jump NAME_{{ from_conf.firewall.name }} + iifname { {{ zone[from_zone].interface | join(",") }} } counter return +{% endif %} +{% endfor %} + counter {{ zone_conf.default_action }} + } +{% endif %} +{% endfor %} +} + +table ip6 filter { +{% for zone_name, zone_conf in zone.items() if zone_conf.ipv6 %} +{% if zone_conf.local_zone is vyos_defined %} + chain VZONE6_{{ zone_name }}_IN { + iifname lo counter return +{% for from_zone, from_conf in zone_conf.from.items() if from_conf.firewall.ipv6_name is vyos_defined %} + iifname { {{ zone[from_zone].interface | join(",") }} } counter jump NAME6_{{ from_conf.firewall.ipv6_name }} + iifname { {{ zone[from_zone].interface | join(",") }} } counter return +{% endfor %} + counter {{ zone_conf.default_action }} + } + chain VZONE6_{{ zone_name }}_OUT { + oifname lo counter return +{% for from_zone, from_conf in zone_conf.from_local.items() if from_conf.firewall.ipv6_name is vyos_defined %} + oifname { {{ zone[from_zone].interface | join(",") }} } counter jump NAME6_{{ from_conf.firewall.ipv6_name }} + oifname { {{ zone[from_zone].interface | join(",") }} } counter return +{% endfor %} + counter {{ zone_conf.default_action }} + } +{% else %} + chain VZONE6_{{ zone_name }} { + iifname { {{ zone_conf.interface | join(",") }} } counter {{ zone_conf | nft_intra_zone_action(ipv6=True) }} +{% if zone_conf.intra_zone_filtering is vyos_defined %} + iifname { {{ zone_conf.interface | join(",") }} } counter return +{% endif %} +{% for from_zone, from_conf in zone_conf.from.items() if from_conf.firewall.ipv6_name is vyos_defined %} +{% if zone[from_zone].local_zone is not defined %} + iifname { {{ zone[from_zone].interface | join(",") }} } counter jump NAME6_{{ from_conf.firewall.ipv6_name }} + iifname { {{ zone[from_zone].interface | join(",") }} } counter return +{% endif %} +{% endfor %} + counter {{ zone_conf.default_action }} + } +{% endif %} +{% endfor %} +} + +{% for zone_name, zone_conf in zone.items() %} +{% if zone_conf.ipv4 %} +{% if 'local_zone' in zone_conf %} +insert rule ip filter VYOS_FW_LOCAL counter jump VZONE_{{ zone_name }}_IN +insert rule ip filter VYOS_FW_OUTPUT counter jump VZONE_{{ zone_name }}_OUT +{% else %} +insert rule ip filter VYOS_FW_FORWARD oifname { {{ zone_conf.interface | join(',') }} } counter jump VZONE_{{ zone_name }} +{% endif %} +{% endif %} +{% if zone_conf.ipv6 %} +{% if 'local_zone' in zone_conf %} +insert rule ip6 filter VYOS_FW6_LOCAL counter jump VZONE6_{{ zone_name }}_IN +insert rule ip6 filter VYOS_FW6_OUTPUT counter jump VZONE6_{{ zone_name }}_OUT +{% else %} +insert rule ip6 filter VYOS_FW6_FORWARD oifname { {{ zone_conf.interface | join(',') }} } counter jump VZONE6_{{ zone_name }} +{% endif %} +{% endif %} +{% endfor %} + +{# Ensure that state-policy rule is first in the chain #} +{% if firewall.state_policy is vyos_defined %} +{% for chain in ['VYOS_FW_FORWARD', 'VYOS_FW_OUTPUT', 'VYOS_FW_LOCAL'] %} +insert rule ip filter {{ chain }} jump VYOS_STATE_POLICY +{% endfor %} +{% for chain in ['VYOS_FW6_FORWARD', 'VYOS_FW6_OUTPUT', 'VYOS_FW6_LOCAL'] %} +insert rule ip6 filter {{ chain }} jump VYOS_STATE_POLICY6 +{% endfor %} +{% endif %} + +{% endif %} |