summaryrefslogtreecommitdiff
path: root/data/templates/frr
diff options
context:
space:
mode:
Diffstat (limited to 'data/templates/frr')
-rw-r--r--data/templates/frr/bfdd.frr.j258
-rw-r--r--data/templates/frr/bfdd.frr.tmpl44
-rw-r--r--data/templates/frr/bgpd.frr.j2533
-rw-r--r--data/templates/frr/bgpd.frr.tmpl528
-rw-r--r--data/templates/frr/igmp.frr.j241
-rw-r--r--data/templates/frr/igmp.frr.tmpl41
-rw-r--r--data/templates/frr/isisd.frr.j2197
-rw-r--r--data/templates/frr/isisd.frr.tmpl198
-rw-r--r--data/templates/frr/ldpd.frr.j2149
-rw-r--r--data/templates/frr/ldpd.frr.tmpl187
-rw-r--r--data/templates/frr/ospf6d.frr.j295
-rw-r--r--data/templates/frr/ospf6d.frr.tmpl92
-rw-r--r--data/templates/frr/ospfd.frr.j2189
-rw-r--r--data/templates/frr/ospfd.frr.tmpl192
-rw-r--r--data/templates/frr/pimd.frr.j2 (renamed from data/templates/frr/pimd.frr.tmpl)16
-rw-r--r--data/templates/frr/policy.frr.j2331
-rw-r--r--data/templates/frr/policy.frr.tmpl322
-rw-r--r--data/templates/frr/rip_ripng.frr.j242
-rw-r--r--data/templates/frr/ripd.frr.j292
-rw-r--r--data/templates/frr/ripd.frr.tmpl96
-rw-r--r--data/templates/frr/ripngd.frr.j257
-rw-r--r--data/templates/frr/ripngd.frr.tmpl60
-rw-r--r--data/templates/frr/rpki.frr.j2 (renamed from data/templates/frr/rpki.frr.tmpl)17
-rw-r--r--data/templates/frr/static_mcast.frr.j2 (renamed from data/templates/frr/static_mcast.frr.tmpl)20
-rw-r--r--data/templates/frr/static_routes_macro.j229
-rw-r--r--data/templates/frr/staticd.frr.j264
-rw-r--r--data/templates/frr/staticd.frr.tmpl58
-rw-r--r--data/templates/frr/vrf-vni.frr.j29
-rw-r--r--data/templates/frr/vrf-vni.frr.tmpl9
-rw-r--r--data/templates/frr/vrf.route-map.frr.j210
-rw-r--r--data/templates/frr/vrf.route-map.frr.tmpl10
31 files changed, 1889 insertions, 1897 deletions
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 %}
-!