diff options
Diffstat (limited to 'data/templates/frr')
25 files changed, 2701 insertions, 0 deletions
diff --git a/data/templates/frr/babeld.frr.j2 b/data/templates/frr/babeld.frr.j2 new file mode 100644 index 0000000..344a5f9 --- /dev/null +++ b/data/templates/frr/babeld.frr.j2 @@ -0,0 +1,85 @@ +{% from 'frr/distribute_list_macro.j2' import render_distribute_list %} +{% from 'frr/ipv6_distribute_list_macro.j2' import render_ipv6_distribute_list %} +! +{# Interface specific configuration #} +{% if interface is vyos_defined %} +{% for iface, iface_config in interface.items() %} +interface {{ iface }} +{% if iface_config.type is vyos_defined('wired') or iface_config.type is vyos_defined('wireless') %} + babel {{ iface_config.type }} +{% endif %} +{% if iface_config.split_horizon is vyos_defined("enable") %} + babel split-horizon +{% elif iface_config.split_horizon is vyos_defined("disable") %} + no babel split-horizon +{% endif %} +{% if iface_config.hello_interval is vyos_defined %} + babel hello-interval {{ iface_config.hello_interval }} +{% endif %} +{% if iface_config.update_interval is vyos_defined %} + babel update-interval {{ iface_config.update_interval }} +{% endif %} +{% if iface_config.rxcost is vyos_defined %} + babel rxcost {{ iface_config.rxcost }} +{% endif %} +{% if iface_config.rtt_decay is vyos_defined %} + babel rtt-decay {{ iface_config.rtt_decay }} +{% endif %} +{% if iface_config.rtt_min is vyos_defined %} + babel rtt-min {{ iface_config.rtt_min }} +{% endif %} +{% if iface_config.rtt_max is vyos_defined %} + babel rtt-max {{ iface_config.rtt_max }} +{% endif %} +{% if iface_config.max_rtt_penalty is vyos_defined %} + babel max-rtt-penalty {{ iface_config.max_rtt_penalty }} +{% endif %} +{% if iface_config.enable_timestamps is vyos_defined %} + babel enable-timestamps +{% endif %} +{% if iface_config.channel is vyos_defined %} + babel channel {{ iface_config.channel | replace("non-interfering", "noninterfering") }} +{% endif %} +exit +! +{% endfor %} +{% endif %} +! +{# Babel configuration #} +router babel +{% if parameters.diversity is vyos_defined %} + babel diversity +{% endif %} +{% if parameters.diversity_factor is vyos_defined %} + babel diversity-factor {{ parameters.diversity_factor }} +{% endif %} +{% if parameters.resend_delay is vyos_defined %} + babel resend-delay {{ parameters.resend_delay }} +{% endif %} +{% if parameters.smoothing_half_life is vyos_defined %} + babel smoothing-half-life {{ parameters.smoothing_half_life }} +{% endif %} +{% if interface is vyos_defined %} +{% for iface, iface_config in interface.items() %} + network {{ iface }} +{% endfor %} +{% endif %} +{% if redistribute is vyos_defined %} +{% for address_family in redistribute %} +{% for protocol, protocol_config in redistribute[address_family].items() %} +{% if protocol is vyos_defined('ospfv3') %} +{% set protocol = 'ospf6' %} +{% endif %} + redistribute {{ address_family }} {{ protocol }} +{% endfor %} +{% endfor %} +{% endif %} +{% if distribute_list.ipv4 is vyos_defined %} +{{ render_distribute_list(distribute_list.ipv4) }} +{% endif %} +{% if distribute_list.ipv6 is vyos_defined %} +{{ render_ipv6_distribute_list(distribute_list.ipv6) }} +{% endif %} +exit +! +end diff --git a/data/templates/frr/bfdd.frr.j2 b/data/templates/frr/bfdd.frr.j2 new file mode 100644 index 0000000..f3303e4 --- /dev/null +++ b/data/templates/frr/bfdd.frr.j2 @@ -0,0 +1,64 @@ +{% 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.minimum_ttl is vyos_defined %} + minimum-ttl {{ profile_config.minimum_ttl }} +{% 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.minimum_ttl is vyos_defined %} + minimum-ttl {{ peer_config.minimum_ttl }} +{% 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/bgpd.frr.j2 b/data/templates/frr/bgpd.frr.j2 new file mode 100644 index 0000000..e5bfad5 --- /dev/null +++ b/data/templates/frr/bgpd.frr.j2 @@ -0,0 +1,664 @@ +{### 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.local_role is vyos_defined %} +{% for role, strict in config.local_role.items() %} + neighbor {{ neighbor }} local-role {{ role }} {{ 'strict-mode' if strict }} +{% endfor %} +{% 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.dynamic is vyos_defined %} + neighbor {{ neighbor }} capability dynamic +{% endif %} +{% if config.capability.extended_nexthop is vyos_defined %} + neighbor {{ neighbor }} capability extended-nexthop +{% endif %} +{% if config.capability.software_version is vyos_defined %} + neighbor {{ neighbor }} capability software-version +{% 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.disable_connected_check is vyos_defined %} + neighbor {{ neighbor }} disable-connected-check +{% 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.path_attribute.discard is vyos_defined %} + neighbor {{ neighbor }} path-attribute discard {{ config.path_attribute.discard | join(' ') }} +{% endif %} +{% if config.path_attribute.treat_as_withdraw is vyos_defined %} + neighbor {{ neighbor }} path-attribute treat-as-withdraw {{ config.path_attribute.treat_as_withdraw }} +{% 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.enforce_first_as is vyos_defined %} + neighbor {{ neighbor }} enforce-first-as +{% 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 {{ 'all' if afi_config.remove_private_as.all is vyos_defined }} +{% 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 {{ system_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://vyos.dev/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 }} {{ 'route-map ' ~ aggregate_config.route_map if aggregate_config.route_map is vyos_defined }} +{% 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.label.vpn.allocation_mode.per_nexthop is vyos_defined %} + label vpn export allocation-mode per-nexthop +{% 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.default_originate.ipv4 is vyos_defined %} + default-originate ipv4 +{% endif %} +{% if afi_config.default_originate.ipv6 is vyos_defined %} + default-originate ipv6 +{% endif %} +{% if afi_config.disable_ead_evi_rx is vyos_defined %} + disable-ead-evi-rx +{% endif %} +{% if afi_config.disable_ead_evi_tx is vyos_defined %} + disable-ead-evi-tx +{% endif %} +{% if afi_config.ead_es_frag.evi_limit is vyos_defined %} + ead-es-frag evi-limit {{ afi_config.ead_es_frag.evi_limit }} +{% endif %} +{% if afi_config.ead_es_route_target.export is vyos_defined %} +{% for route_target in afi_config.ead_es_route_target.export %} + ead-es-route-target export {{ route_target }} +{% endfor %} +{% 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.mac_vrf.soo is vyos_defined %} + mac-vrf soo {{ afi_config.mac_vrf.soo }} +{% endif %} +{% if afi_config.nexthop.vpn.export is vyos_defined %} + nexthop vpn export {{ afi_config.nexthop.vpn.export }} +{% 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 %} +{% for route_target in afi_config.route_target.both %} + route-target both {{ route_target }} +{% endfor %} +{% endif %} +{% if afi_config.route_target.export is vyos_defined %} +{% for route_target in afi_config.route_target.export %} + route-target export {{ route_target }} +{% endfor %} +{% endif %} +{% if afi_config.route_target.import is vyos_defined %} +{% for route_target in afi_config.route_target.import %} + route-target import {{ route_target }} +{% endfor %} +{% 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.sid.vpn.export is vyos_defined %} + sid vpn export {{ afi_config.sid.vpn.export }} +{% 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 %} +{% for route_target in vni_config.route_target.both %} + route-target both {{ route_target }} +{% endfor %} +{% endif %} +{% if vni_config.route_target.export is vyos_defined %} +{% for route_target in vni_config.route_target.export %} + route-target export {{ route_target }} +{% endfor %} +{% endif %} +{% if vni_config.route_target.import is vyos_defined %} +{% for route_target in vni_config.route_target.import %} + route-target import {{ route_target }} +{% endfor %} +{% endif %} + exit-vni +{% endfor %} +{% endif %} + exit-address-family + ! +{% endfor %} +{% endif %} + ! +{% if bmp is vyos_defined %} +{% if bmp.mirror_buffer_limit is vyos_defined %} + bmp mirror buffer-limit {{ bmp.mirror_buffer_limit }} + ! +{% endif %} +{% if bmp.target is vyos_defined %} +{% for bmp, bmp_config in bmp.target.items() %} + bmp targets {{ bmp }} +{% if bmp_config.mirror is vyos_defined %} + bmp mirror +{% endif %} +{% if bmp_config.monitor is vyos_defined %} +{% if bmp_config.monitor.ipv4_unicast.pre_policy is vyos_defined %} + bmp monitor ipv4 unicast pre-policy +{% endif %} +{% if bmp_config.monitor.ipv4_unicast.post_policy is vyos_defined %} + bmp monitor ipv4 unicast post-policy +{% endif %} +{% if bmp_config.monitor.ipv6_unicast.pre_policy is vyos_defined %} + bmp monitor ipv6 unicast pre-policy +{% endif %} +{% if bmp_config.monitor.ipv6_unicast.post_policy is vyos_defined %} + bmp monitor ipv6 unicast post-policy +{% endif %} +{% endif %} +{% if bmp_config.address is vyos_defined %} + bmp connect {{ bmp_config.address }} port {{ bmp_config.port }} min-retry {{ bmp_config.min_retry }} max-retry {{ bmp_config.max_retry }} +{% endif %} +{% endfor %} + exit +{% endif %} +{% 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.allow_martian_nexthop is vyos_defined %} + bgp allow-martian-nexthop +{% endif %} +{% if parameters.disable_ebgp_connected_route_check is vyos_defined %} + bgp disable-ebgp-connected-route-check +{% 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 {{ parameters.bestpath.med | join(' ') | replace('_', '-') }} +{% endif %} +{% if parameters.bestpath.peer_type is vyos_defined %} + bgp bestpath peer-type {{ 'multipath-relax' if parameters.bestpath.peer_type.multipath_relax 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.no_hard_administrative_reset is vyos_defined %} + no bgp hard-administrative-reset +{% endif %} +{% if parameters.labeled_unicast is vyos_defined %} + bgp labeled-unicast {{ parameters.labeled_unicast }} +{% 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.route_reflector_allow_outbound_policy is vyos_defined %} +bgp route-reflector allow-outbound-policy +{% 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 parameters.tcp_keepalive.idle is vyos_defined and parameters.tcp_keepalive.interval is vyos_defined and parameters.tcp_keepalive.probes is vyos_defined %} + bgp tcp-keepalive {{ parameters.tcp_keepalive.idle }} {{ parameters.tcp_keepalive.interval }} {{ parameters.tcp_keepalive.probes }} +{% endif %} +{% if srv6.locator is vyos_defined %} + segment-routing srv6 + locator {{ srv6.locator }} + exit +{% endif %} +{% if sid.vpn.per_vrf.export is vyos_defined %} + sid vpn per-vrf export {{ sid.vpn.per_vrf.export }} +{% endif %} +{% if timers.keepalive is vyos_defined and timers.holdtime is vyos_defined %} + timers bgp {{ timers.keepalive }} {{ timers.holdtime }} +{% endif %} +exit +! +{% if interface is vyos_defined %} +{% for iface, iface_config in interface.items() %} +interface {{ iface }} +{% if iface_config.mpls.forwarding is vyos_defined %} + mpls bgp forwarding +{% endif %} +exit +! +{% endfor %} +{% endif %} diff --git a/data/templates/frr/daemons.frr.tmpl b/data/templates/frr/daemons.frr.tmpl new file mode 100644 index 0000000..339b4e5 --- /dev/null +++ b/data/templates/frr/daemons.frr.tmpl @@ -0,0 +1,113 @@ +# +# The watchfrr, zebra, mgmtd and staticd daemons are always started. +# +# Note: The following FRR-services must be kept disabled because they are replaced by other packages in VyOS: +# +# pimd Replaced by package igmpproxy. +# nhrpd Replaced by package opennhrp. +# pbrd Replaced by PBR in nftables. +# vrrpd Replaced by package keepalived. +# +# And these must be disabled aswell since they are currently missing a VyOS CLI: +# +# eigrp +# sharpd +# fabricd +# pathd +# +# The zebra, mgmtd and staticd daemons are always started and can not be disabled +# +#zebra=yes +#mgmtd=yes +#staticd=yes + +bgpd=yes +ospfd=yes +ospf6d=yes +ripd=yes +ripngd=yes +isisd=yes +pimd=no +pim6d=yes +ldpd=yes +nhrpd=no +eigrpd=no +babeld=yes +sharpd=no +pbrd=no +bfdd=yes +fabricd=no +vrrpd=no +pathd=no + +# +# Define defaults for all services even those who shall be kept disabled. +# + +zebra_options=" --daemon -A 127.0.0.1 -s 90000000{{ ' -M snmp' if snmp.zebra is vyos_defined }}{{ ' -M irdp' if irdp is vyos_defined }}" +mgmtd_options=" --daemon -A 127.0.0.1" +staticd_options="--daemon -A 127.0.0.1" +bgpd_options=" --daemon -A 127.0.0.1 -M rpki{{ ' -M snmp' if snmp.bgpd is vyos_defined }}{{ ' -M bmp' if bmp is vyos_defined }}" +ospfd_options=" --daemon -A 127.0.0.1{{ ' -M snmp' if snmp.ospfd is vyos_defined }}" +ospf6d_options=" --daemon -A ::1{{ ' -M snmp' if snmp.ospf6d is vyos_defined }}" +ripd_options=" --daemon -A 127.0.0.1{{ ' -M snmp' if snmp.ripd is vyos_defined }}" +ripngd_options=" --daemon -A ::1" +isisd_options=" --daemon -A 127.0.0.1{{ ' -M snmp' if snmp.isisd is vyos_defined }}" +pimd_options=" --daemon -A 127.0.0.1" +pim6d_options=" --daemon -A ::1" +ldpd_options=" --daemon -A 127.0.0.1{{ ' -M snmp' if snmp.ldpd is vyos_defined }}" +nhrpd_options=" --daemon -A 127.0.0.1" +eigrpd_options=" --daemon -A 127.0.0.1" +babeld_options=" --daemon -A 127.0.0.1" +sharpd_options=" --daemon -A 127.0.0.1" +pbrd_options=" --daemon -A 127.0.0.1" +bfdd_options=" --daemon -A 127.0.0.1" +fabricd_options="--daemon -A 127.0.0.1" +vrrpd_options=" --daemon -A 127.0.0.1" +pathd_options=" --daemon -A 127.0.0.1" + +#frr_global_options="" + +#zebra_wrap="" +#mgmtd_wrap="" +#staticd_wrap="" +#bgpd_wrap="" +#ospfd_wrap="" +#ospf6d_wrap="" +#ripd_wrap="" +#ripngd_wrap="" +#isisd_wrap="" +#pimd_wrap="" +#pim6d_wrap="" +#ldpd_wrap="" +#nhrpd_wrap="" +#eigrpd_wrap="" +#babeld_wrap="" +#sharpd_wrap="" +#pbrd_wrap="" +#bfdd_wrap="" +#fabricd_wrap="" +#vrrpd_wrap="" +#pathd_wrap="" + +#all_wrap="" + +# +# Other options. +# +# For more information see: +# https://github.com/FRRouting/frr/blob/stable/9.0/tools/etc/frr/daemons +# https://docs.frrouting.org/en/stable-9.0/setup.html +# + +vtysh_enable=yes +watchfrr_enable=yes +valgrind_enable=no + +#watchfrr_options="" + +frr_profile="traditional" + +MAX_FDS={{ descriptors }} + +#FRR_NO_ROOT="yes" diff --git a/data/templates/frr/distribute_list_macro.j2 b/data/templates/frr/distribute_list_macro.j2 new file mode 100644 index 0000000..c10bf73 --- /dev/null +++ b/data/templates/frr/distribute_list_macro.j2 @@ -0,0 +1,30 @@ +{% macro render_distribute_list(distribute_list) %} +{% 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 %} +{% endmacro %} diff --git a/data/templates/frr/eigrpd.frr.j2 b/data/templates/frr/eigrpd.frr.j2 new file mode 100644 index 0000000..d16963a --- /dev/null +++ b/data/templates/frr/eigrpd.frr.j2 @@ -0,0 +1,31 @@ +! +router eigrp {{ system_as }} {{ 'vrf ' ~ vrf if vrf is vyos_defined }} +{% if maximum_paths is vyos_defined %} + maximum-paths {{ maximum_paths }} +{% endif %} +{% if metric.weights is vyos_defined %} + metric weights {{ metric.weights }} +{% endif %} +{% if network is vyos_defined %} +{% for net in network %} + network {{ net }} +{% endfor %} +{% endif %} +{% if passive_interface is vyos_defined %} +{% for interface in passive_interface %} + passive-interface {{ interface }} +{% endfor %} +{% endif %} +{% if redistribute is vyos_defined %} +{% for protocol in redistribute %} + redistribute {{ protocol }} +{% endfor %} +{% endif %} +{% if router_id is vyos_defined %} + eigrp router-id {{ router_id }} +{% endif %} +{% if variance is vyos_defined %} + variance {{ variance }} +{% endif %} +exit +! diff --git a/data/templates/frr/evpn.mh.frr.j2 b/data/templates/frr/evpn.mh.frr.j2 new file mode 100644 index 0000000..03aaac4 --- /dev/null +++ b/data/templates/frr/evpn.mh.frr.j2 @@ -0,0 +1,16 @@ +! +interface {{ ifname }} +{% if evpn.es_df_pref is vyos_defined %} + evpn mh es-df-pref {{ evpn.es_df_pref }} +{% endif %} +{% if evpn.es_id is vyos_defined %} + evpn mh es-id {{ evpn.es_id }} +{% endif %} +{% if evpn.es_sys_mac is vyos_defined %} + evpn mh es-sys-mac {{ evpn.es_sys_mac }} +{% endif %} +{% if evpn.uplink is vyos_defined %} + evpn mh uplink +{% endif %} +exit +! diff --git a/data/templates/frr/ipv6_distribute_list_macro.j2 b/data/templates/frr/ipv6_distribute_list_macro.j2 new file mode 100644 index 0000000..c365fbd --- /dev/null +++ b/data/templates/frr/ipv6_distribute_list_macro.j2 @@ -0,0 +1,30 @@ +{% macro render_ipv6_distribute_list(distribute_list) %} +{% 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 %} +{% endmacro %} diff --git a/data/templates/frr/isisd.frr.j2 b/data/templates/frr/isisd.frr.j2 new file mode 100644 index 0000000..1e1cc3c --- /dev/null +++ b/data/templates/frr/isisd.frr.j2 @@ -0,0 +1,242 @@ +! +{% 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.ldp_sync.disable is vyos_defined %} + no isis mpls ldp-sync +{% elif iface_config.ldp_sync.holddown is vyos_defined %} + isis mpls ldp-sync + isis mpls ldp-sync holddown {{ iface_config.ldp_sync.holddown }} +{% 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 advertise_high_metrics is vyos_defined %} +advertise-high-metrics +{% endif %} +{% if advertise_passive_only is vyos_defined %} +advertise-passive-only +{% endif %} +{% 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 ldp_sync.holddown is vyos_defined %} + mpls ldp-sync holddown {{ ldp_sync.holddown }} +{% elif ldp_sync is vyos_defined %} + mpls ldp-sync +{% 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.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 {{ prefix }} absolute {{ prefix_config.absolute.value }} {{ 'explicit-null' if prefix_config.absolute.explicit_null is vyos_defined }} {{ 'no-php-flag' if prefix_config.absolute.no_php_flag is vyos_defined }} +{% endif %} +{% endif %} +{% if prefix_config.index is vyos_defined %} +{% if prefix_config.index.value is vyos_defined %} + segment-routing prefix {{ prefix }} index {{ prefix_config.index.value }} {{ 'explicit-null' if prefix_config.index.explicit_null is vyos_defined }} {{ 'no-php-flag' if prefix_config.index.no_php_flag is vyos_defined }} +{% endif %} +{% endif %} +{% endfor %} +{% endif %} + segment-routing on +{% 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 fast_reroute.lfa is vyos_defined %} +{% if fast_reroute.lfa.local is vyos_defined %} +{% if fast_reroute.lfa.local.load_sharing.disable.level_1 is vyos_defined %} + fast-reroute load-sharing disable level-1 +{% elif fast_reroute.lfa.local.load_sharing.disable.level_2 is vyos_defined %} + fast-reroute load-sharing disable level-2 +{% elif fast_reroute.lfa.local.load_sharing.disable is vyos_defined %} + fast-reroute load-sharing disable +{% endif %} +{% if fast_reroute.lfa.local.priority_limit is vyos_defined %} +{% for priority, priority_limit_options in fast_reroute.lfa.local.priority_limit.items() %} +{% for level in priority_limit_options %} + fast-reroute priority-limit {{ priority }} {{ level | replace('_', '-') }} +{% endfor %} +{% endfor %} +{% endif %} +{% if fast_reroute.lfa.local.tiebreaker is vyos_defined %} +{% for tiebreaker, tiebreaker_options in fast_reroute.lfa.local.tiebreaker.items() %} +{% for index, index_options in tiebreaker_options.items() %} +{% for index_value, index_value_options in index_options.items() %} +{% for level in index_value_options %} + fast-reroute lfa tiebreaker {{ tiebreaker | replace('_', '-') }} index {{ index_value }} {{ level | replace('_', '-') }} +{% endfor %} +{% endfor %} +{% endfor %} +{% endfor %} +{% endif %} +{% endif %} +{% if fast_reroute.lfa.remote.prefix_list is vyos_defined %} +{% for prefix_list, prefix_list_options in fast_reroute.lfa.remote.prefix_list.items() %} +{% if prefix_list_options.level_1 is vyos_defined %} +fast-reroute remote-lfa prefix-list {{ prefix_list }} level-1 +{% endif %} +{% if prefix_list_options.level_2 is vyos_defined %} +fast-reroute remote-lfa prefix-list {{ prefix_list }} level-2 +{% endif %} +{% if prefix_list is vyos_defined and prefix_list_options.level_1 is not vyos_defined and prefix_list_options.level_2 is not vyos_defined %} +fast-reroute remote-lfa prefix-list {{ prefix_list }} +{% endif %} +{% endfor %} +{% endif %} +{% 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 +! diff --git a/data/templates/frr/ldpd.frr.j2 b/data/templates/frr/ldpd.frr.j2 new file mode 100644 index 0000000..9a893cc --- /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.items() %} +{% if neighbor_config.password is vyos_defined %} + neighbor {{ neighbor }} password {{ neighbor_config.password }} +{% endif %} +{% if neighbor_config.ttl_security is vyos_defined %} +{% if neighbor_config.ttl_security.disable is vyos_defined %} + neighbor {{ neighbor }} ttl-security disable +{% else %} + neighbor {{ neighbor }} ttl-security hops {{ neighbor_config.ttl_security }} +{% endif %} +{% endif %} +{% if neighbor_config.session_holdtime is vyos_defined %} + neighbor {{ neighbor }} 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/ospf6d.frr.j2 b/data/templates/frr/ospf6d.frr.j2 new file mode 100644 index 0000000..5f758f9 --- /dev/null +++ b/data/templates/frr/ospf6d.frr.j2 @@ -0,0 +1,116 @@ +! +{% 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 graceful_restart is vyos_defined %} +{% if graceful_restart.grace_period is vyos_defined %} + graceful-restart grace-period {{ graceful_restart.grace_period }} +{% endif %} +{% if graceful_restart.helper.enable.router_id is vyos_defined %} +{% for router_id in graceful_restart.helper.enable.router_id %} + graceful-restart helper enable {{ router_id }} +{% endfor %} +{% elif graceful_restart.helper.enable is vyos_defined %} + graceful-restart helper enable +{% endif %} +{% if graceful_restart.helper.planned_only is vyos_defined %} + graceful-restart helper planned-only +{% endif %} +{% if graceful_restart.helper.lsa_check_disable is vyos_defined %} + graceful-restart helper lsa-check-disable +{% endif %} +{% if graceful_restart.helper.supported_grace_time is vyos_defined %} + graceful-restart helper supported-grace-time {{ graceful_restart.helper.supported_grace_time }} +{% endif %} +{% 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 }} {{ 'metric ' ~ options.metric if options.metric is vyos_defined }} {{ 'metric-type ' ~ options.metric_type if options.metric_type is vyos_defined }} {{ 'route-map ' ~ options.route_map if options.route_map is vyos_defined }} +{% endfor %} +{% endif %} +exit +! diff --git a/data/templates/frr/ospfd.frr.j2 b/data/templates/frr/ospfd.frr.j2 new file mode 100644 index 0000000..ab074b6 --- /dev/null +++ b/data/templates/frr/ospfd.frr.j2 @@ -0,0 +1,262 @@ +! +{% 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.ldp_sync.disable is vyos_defined %} + no ip ospf mpls ldp-sync +{% elif iface_config.ldp_sync.holddown is vyos_defined %} + ip ospf mpls ldp-sync + ip ospf mpls ldp-sync holddown {{ iface_config.ldp_sync.holddown }} +{% 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 aggregation.timer is vyos_defined %} + aggregation timer {{ aggregation.timer }} +{% 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.not_advertise is vyos_defined %} + area {{ area_id }} range {{ range }} not-advertise +{% else %} + area {{ area_id }} range {{ range }} +{% endif %} +{% if range_config.cost is vyos_defined %} + area {{ area_id }} range {{ range }} cost {{ range_config.cost }} +{% 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 capability.opaque is vyos_defined %} + capability opaque +{% 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 ldp_sync.holddown is vyos_defined %} + mpls ldp-sync holddown {{ ldp_sync.holddown }} +{% elif ldp_sync is vyos_defined %} + mpls ldp-sync +{% 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 graceful_restart is vyos_defined %} +{% if graceful_restart.grace_period is vyos_defined %} + graceful-restart grace-period {{ graceful_restart.grace_period }} +{% endif %} +{% if graceful_restart.helper.enable.router_id is vyos_defined %} +{% for router_id in graceful_restart.helper.enable.router_id %} + graceful-restart helper enable {{ router_id }} +{% endfor %} +{% elif graceful_restart.helper.enable is vyos_defined %} + graceful-restart helper enable +{% endif %} +{% if graceful_restart.helper.planned_only is vyos_defined %} + graceful-restart helper planned-only +{% endif %} +{% if graceful_restart.helper.no_strict_lsa_checking is vyos_defined %} + no graceful-restart helper strict-lsa-checking +{% endif %} +{% if graceful_restart.helper.supported_grace_time is vyos_defined %} + graceful-restart helper supported-grace-time {{ graceful_restart.helper.supported_grace_time }} +{% endif %} +{% 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.opaque_lsa is vyos_defined %} + ospf opaque-lsa +{% endif %} +{% if parameters.rfc1583_compatibility is vyos_defined %} + ospf rfc1583compatibility +{% endif %} +{% if parameters.router_id is vyos_defined %} + ospf router-id {{ parameters.router_id }} +{% endif %} +{% if passive_interface is vyos_defined('default') %} + passive-interface default +{% endif %} +{% if redistribute is vyos_defined %} +{% for protocol, options in redistribute.items() %} +{% if protocol == 'table' %} +{% for table, table_options in 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 ' ~ options.metric if options.metric is vyos_defined }} {{ 'metric-type ' ~ options.metric_type if options.metric_type is vyos_defined }} {{ 'route-map ' ~ options.route_map if options.route_map is vyos_defined }} +{% endif %} +{% endfor %} +{% endif %} +{% if refresh.timers is vyos_defined %} + refresh timer {{ refresh.timers }} +{% endif %} +{% if summary_address is vyos_defined %} +{% for prefix, prefix_options in summary_address.items() %} + summary-address {{ prefix }} {{ 'tag ' + prefix_options.tag if prefix_options.tag is vyos_defined }}{{ 'no-advertise' if prefix_options.no_advertise is vyos_defined }} +{% endfor %} +{% endif %} +{% if segment_routing is vyos_defined %} +{% if segment_routing.maximum_label_depth is vyos_defined %} + segment-routing node-msd {{ segment_routing.maximum_label_depth }} +{% endif %} +{% if segment_routing.global_block is 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.index is vyos_defined %} +{% if prefix_config.index.value is vyos_defined %} + segment-routing prefix {{ prefix }} index {{ prefix_config.index.value }} {{ 'explicit-null' if prefix_config.index.explicit_null is vyos_defined }} {{ 'no-php-flag' if prefix_config.index.no_php_flag is vyos_defined }} +{% endif %} +{% endif %} +{% endfor %} +{% endif %} + segment-routing on +{% 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/pim6d.frr.j2 b/data/templates/frr/pim6d.frr.j2 new file mode 100644 index 0000000..bac716f --- /dev/null +++ b/data/templates/frr/pim6d.frr.j2 @@ -0,0 +1,81 @@ +! +{% if interface is vyos_defined %} +{% for iface, iface_config in interface.items() %} +! +interface {{ iface }} + ipv6 pim +{% if iface_config.no_bsm is vyos_defined %} + no ipv6 pim bsm +{% endif %} +{% if iface_config.dr_priority is vyos_defined %} + ipv6 pim drpriority {{ iface_config.dr_priority }} +{% endif %} +{% if iface_config.hello is vyos_defined %} + ipv6 pim hello {{ iface_config.hello }} +{% endif %} +{% if iface_config.no_unicast_bsm is vyos_defined %} + no ipv6 pim unicast-bsm +{% endif %} +{% if iface_config.passive is vyos_defined %} + ipv6 pim passive +{% endif %} +{% if iface_config.mld is vyos_defined and iface_config.mld.disable is not vyos_defined %} + ipv6 mld +{% if iface_config.mld.version is vyos_defined %} + ipv6 mld version {{ iface_config.mld.version }} +{% endif %} +{% if iface_config.mld.interval is vyos_defined %} + ipv6 mld query-interval {{ iface_config.mld.interval }} +{% endif %} +{% if iface_config.mld.max_response_time is vyos_defined %} + ipv6 mld query-max-response-time {{ iface_config.mld.max_response_time // 100 }} +{% endif %} +{% if iface_config.mld.last_member_query_count is vyos_defined %} + ipv6 mld last-member-query-count {{ iface_config.mld.last_member_query_count }} +{% endif %} +{% if iface_config.mld.last_member_query_interval is vyos_defined %} + ipv6 mld last-member-query-interval {{ iface_config.mld.last_member_query_interval // 100 }} +{% endif %} +{% if iface_config.mld.join is vyos_defined %} +{% for group, group_config in iface_config.mld.join.items() %} +{% if group_config.source is vyos_defined %} +{% for source in group_config.source %} + ipv6 mld join {{ group }} {{ source }} +{% endfor %} +{% else %} + ipv6 mld join {{ group }} +{% endif %} +{% endfor %} +{% endif %} +{% endif %} +exit +{% endfor %} +{% endif %} +! +{% if join_prune_interval is vyos_defined %} +ipv6 pim join-prune-interval {{ join_prune_interval }} +{% endif %} +{% if keep_alive_timer is vyos_defined %} +ipv6 pim keep-alive-timer {{ keep_alive_timer }} +{% endif %} +{% if packets is vyos_defined %} +ipv6 pim packets {{ packets }} +{% endif %} +{% if register_suppress_time is vyos_defined %} +ipv6 pim register-suppress-time {{ register_suppress_time }} +{% endif %} +{% if rp.address is vyos_defined %} +{% for address, address_config in rp.address.items() %} +{% if address_config.group is vyos_defined %} +{% for group in address_config.group %} +ipv6 pim rp {{ address }} {{ group }} +{% endfor %} +{% endif %} +{% if address_config.prefix_list6 is vyos_defined %} +ipv6 pim rp {{ address }} prefix-list {{ address_config.prefix_list6 }} +{% endif %} +{% endfor %} +{% endif %} +{% if rp.keep_alive_timer is vyos_defined %} +ipv6 pim rp keep-alive-timer {{ rp.keep_alive_timer }} +{% endif %} diff --git a/data/templates/frr/pimd.frr.j2 b/data/templates/frr/pimd.frr.j2 new file mode 100644 index 0000000..68edf4a --- /dev/null +++ b/data/templates/frr/pimd.frr.j2 @@ -0,0 +1,95 @@ +{% if interface is vyos_defined %} +{% for iface, iface_config in interface.items() %} +! +interface {{ iface }} + ip pim +{% if iface_config.bfd is vyos_defined %} + ip pim bfd {{ 'profile ' ~ iface_config.bfd.profile if iface_config.bfd.profile is vyos_defined }} +{% endif %} +{% if iface_config.no_bsm is vyos_defined %} + no ip pim bsm +{% endif %} +{% if iface_config.dr_priority is vyos_defined %} + ip pim drpriority {{ iface_config.dr_priority }} +{% endif %} +{% if iface_config.hello is vyos_defined %} + ip pim hello {{ iface_config.hello }} +{% endif %} +{% if iface_config.no_unicast_bsm is vyos_defined %} + no ip pim unicast-bsm +{% endif %} +{% if iface_config.passive is vyos_defined %} + ip pim passive +{% endif %} +{% if iface_config.source_address is vyos_defined %} + ip pim use-source {{ iface_config.source_address }} +{% endif %} +{% if iface_config.igmp is vyos_defined and iface_config.igmp.disable is not vyos_defined %} + ip igmp +{% if iface_config.igmp.query_interval %} + ip igmp query-interval {{ iface_config.igmp.query_interval }} +{% endif %} +{% if iface_config.igmp.query_max_response_time %} + ip igmp query-max-response-time {{ iface_config.igmp.query_max_response_time }} +{% endif %} +{% if iface_config.igmp.version is vyos_defined %} + ip igmp version {{ iface_config.igmp.version }} +{% endif %} +{% if iface_config.igmp.join is vyos_defined %} +{% for join, join_config in iface_config.igmp.join.items() %} +{% if join_config.source_address is vyos_defined %} +{% for source_address in join_config.source_address %} + ip igmp join {{ join }} {{ source_address }} +{% endfor %} +{% else %} + ip igmp join {{ join }} +{% endif %} +{% endfor %} +{% endif %} +{% endif %} +exit +{% endfor %} +{% endif %} +! +{% if ecmp is vyos_defined %} +ip pim ecmp {{ 'rebalance' if ecmp.rebalance is vyos_defined }} +{% endif %} +{% if join_prune_interval is vyos_defined %} +ip pim join-prune-interval {{ join_prune_interval }} +{% endif %} +{% if keep_alive_timer is vyos_defined %} +ip pim keep-alive-timer {{ keep_alive_timer }} +{% endif %} +{% if packets is vyos_defined %} +ip pim packets {{ packets }} +{% endif %} +{% if register_accept_list.prefix_list is vyos_defined %} +ip pim register-accept-list {{ register_accept_list.prefix_list }} +{% endif %} +{% if register_suppress_time is vyos_defined %} +ip pim register-suppress-time {{ register_suppress_time }} +{% endif %} +{% if rp.address is vyos_defined %} +{% for address, address_config in rp.address.items() %} +{% for group in address_config.group %} +ip pim rp {{ address }} {{ group }} +{% endfor %} +{% endfor %} +{% endif %} +{% if rp.keep_alive_timer is vyos_defined %} +ip pim rp keep-alive-timer {{ rp.keep_alive_timer }} +{% endif %} +{% if no_v6_secondary is vyos_defined %} +no ip pim send-v6-secondary +{% endif %} +{% if spt_switchover.infinity_and_beyond is vyos_defined %} +ip pim spt-switchover infinity-and-beyond {{ 'prefix-list ' ~ spt_switchover.infinity_and_beyond.prefix_list if spt_switchover.infinity_and_beyond.prefix_list is defined }} +{% endif %} +{% if ssm.prefix_list is vyos_defined %} +ip pim ssm prefix-list {{ ssm.prefix_list }} +{% endif %} +! +{% if igmp.watermark_warning is vyos_defined %} +ip igmp watermark-warn {{ igmp.watermark_warning }} +{% endif %} +! diff --git a/data/templates/frr/policy.frr.j2 b/data/templates/frr/policy.frr.j2 new file mode 100644 index 0000000..ed5876a --- /dev/null +++ b/data/templates/frr/policy.frr.j2 @@ -0,0 +1,377 @@ +{% 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.address.prefix_len is vyos_defined %} + match ip address prefix-len {{ rule_config.match.ip.address.prefix_len }} +{% 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.address is vyos_defined %} + match ip next-hop address {{ rule_config.match.ip.nexthop.address }} +{% endif %} +{% if rule_config.match.ip.nexthop.prefix_len is vyos_defined %} + match ip next-hop prefix-len {{ rule_config.match.ip.nexthop.prefix_len }} +{% 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.nexthop.type is vyos_defined %} + match ip next-hop type {{ rule_config.match.ip.nexthop.type }} +{% 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.address.prefix_len is vyos_defined %} + match ipv6 address prefix-len {{ rule_config.match.ipv6.address.prefix_len }} +{% endif %} +{% if rule_config.match.ipv6.nexthop.address is vyos_defined %} + match ipv6 next-hop address {{ rule_config.match.ipv6.nexthop.address }} +{% endif %} +{% if rule_config.match.ipv6.nexthop.access_list is vyos_defined %} + match ipv6 next-hop {{ rule_config.match.ipv6.nexthop.access_list }} +{% endif %} +{% if rule_config.match.ipv6.nexthop.prefix_list is vyos_defined %} + match ipv6 next-hop prefix-list {{ rule_config.match.ipv6.nexthop.prefix_list }} +{% endif %} +{% if rule_config.match.ipv6.nexthop.type is vyos_defined %} + match ipv6 next-hop type {{ rule_config.match.ipv6.nexthop.type }} +{% 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.protocol is vyos_defined %} +{% set source_protocol = 'ospf6' if rule_config.match.protocol == 'ospfv3' else rule_config.match.protocol %} + match source-protocol {{ source_protocol }} +{% 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.community.delete is vyos_defined %} + set comm-list {{ rule_config.set.community.delete }} delete +{% endif %} +{% if rule_config.set.community.replace is vyos_defined %} + set community {{ rule_config.set.community.replace | join(' ') | replace("local-as" , "local-AS") }} +{% endif %} +{% if rule_config.set.community.add is vyos_defined %} + set community {{ rule_config.set.community.add | join(' ') | replace("local-as" , "local-AS") }} additive +{% endif %} +{% if rule_config.set.community.none is vyos_defined %} + set community none +{% 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 }} {{ 'non-transitive' if rule_config.set.extcommunity.bandwidth_non_transitive is vyos_defined }} +{% endif %} +{% if rule_config.set.extcommunity.rt is vyos_defined %} + set extcommunity rt {{ rule_config.set.extcommunity.rt | join(' ') }} +{% endif %} +{% if rule_config.set.extcommunity.soo is vyos_defined %} + set extcommunity soo {{ rule_config.set.extcommunity.soo | join(' ') }} +{% endif %} +{% if rule_config.set.extcommunity.none is vyos_defined %} + set extcommunity none +{% 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.l3vpn_nexthop.encapsulation.gre is vyos_defined %} +set l3vpn next-hop encapsulation gre +{% endif %} +{% if rule_config.set.large_community.replace is vyos_defined %} + set large-community {{ rule_config.set.large_community.replace | join(' ') }} +{% endif %} +{% if rule_config.set.large_community.add is vyos_defined %} + set large-community {{ rule_config.set.large_community.add | join(' ') }} additive +{% endif %} +{% if rule_config.set.large_community.none is vyos_defined %} + set large-community none +{% endif %} +{% if rule_config.set.large_community.delete is vyos_defined %} + set large-comm-list {{ rule_config.set.large_community.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/rip_ripng.frr.j2 b/data/templates/frr/rip_ripng.frr.j2 new file mode 100644 index 0000000..dd547bb --- /dev/null +++ b/data/templates/frr/rip_ripng.frr.j2 @@ -0,0 +1,36 @@ +{% if default_information is vyos_defined %} + default-information originate +{% endif %} +{% if default_metric is vyos_defined %} + default-metric {{ default_metric }} +{% endif %} +{% if passive_interface is vyos_defined %} +{% for interface in passive_interface %} + passive-interface {{ interface }} +{% endfor %} +{% endif %} +{% if network is vyos_defined %} +{% for prefix in network %} + network {{ prefix }} +{% endfor %} +{% endif %} +{% if interface is vyos_defined %} +{% for ifname in interface %} + network {{ ifname }} +{% endfor %} +{% endif %} +{% if route is vyos_defined %} +{% for prefix in route %} + route {{ prefix }} +{% endfor %} +{% endif %} +{# timers have default values #} + timers basic {{ timers['update'] }} {{ timers.timeout }} {{ timers.garbage_collection }} +{% if redistribute is 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 0000000..1445bf9 --- /dev/null +++ b/data/templates/frr/ripd.frr.j2 @@ -0,0 +1,75 @@ +{% from 'frr/distribute_list_macro.j2' import render_distribute_list %} +{# 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 %} +{% if iface_config.receive.version is vyos_defined %} + ip rip receive version {{ iface_config.receive.version }} +{% endif %} +{% if iface_config.send.version is vyos_defined %} + ip rip send version {{ iface_config.send.version }} +{% 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 %} +{{ render_distribute_list(distribute_list) }} +{% endif %} +{% include 'frr/rip_ripng.frr.j2' %} +{% if version is vyos_defined %} + version {{ version }} +{% endif %} +exit +! +{% if route_map is vyos_defined %} +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 0000000..e857e94 --- /dev/null +++ b/data/templates/frr/ripngd.frr.j2 @@ -0,0 +1,31 @@ +{% from 'frr/ipv6_distribute_list_macro.j2' import render_ipv6_distribute_list %} +{# 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 %} +{{ render_ipv6_distribute_list(distribute_list) }} +{% 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/rpki.frr.j2 b/data/templates/frr/rpki.frr.j2 new file mode 100644 index 0000000..5972410 --- /dev/null +++ b/data/templates/frr/rpki.frr.j2 @@ -0,0 +1,24 @@ +! +{# as FRR does not support deleting the entire rpki section we leave it in place even when it's empty #} +rpki +{% 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 }} preference {{ peer_config.preference }} +{% else %} + rpki cache {{ peer | replace('_', '-') }} {{ peer_config.port }} preference {{ peer_config.preference }} +{% endif %} +{% endfor %} +{% endif %} +{% if expire_interval is vyos_defined %} + rpki expire_interval {{ expire_interval }} +{% endif %} +{% if polling_period is vyos_defined %} + rpki polling_period {{ polling_period }} +{% endif %} +{% if retry_interval is vyos_defined %} + rpki retry_interval {{ retry_interval }} +{% endif %} +exit +! diff --git a/data/templates/frr/static_mcast.frr.j2 b/data/templates/frr/static_mcast.frr.j2 new file mode 100644 index 0000000..491d4b5 --- /dev/null +++ b/data/templates/frr/static_mcast.frr.j2 @@ -0,0 +1,20 @@ +! +{% for route_gr in old_mroute %} +{% 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 %} +no ip mroute {{ route_gr }} {{ nh }} +{% endif %} +{% endfor %} +{% endfor %} +{% for route_gr in mroute %} +{% for nh in mroute[route_gr] %} +{% if mroute[route_gr][nh] %} +ip mroute {{ route_gr }} {{ nh }} {{ mroute[route_gr][nh] }} +{% else %} +ip mroute {{ route_gr }} {{ nh }} +{% endif %} +{% endfor %} +{% endfor %} +! diff --git a/data/templates/frr/static_routes_macro.j2 b/data/templates/frr/static_routes_macro.j2 new file mode 100644 index 0000000..cf80469 --- /dev/null +++ b/data/templates/frr/static_routes_macro.j2 @@ -0,0 +1,29 @@ +{% macro static_routes(ip_ipv6, prefix, prefix_config, table=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 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 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 vyos_defined }} {{ 'nexthop-vrf ' ~ interface_config.vrf if interface_config.vrf is vyos_defined }} {{ 'segments ' ~ interface_config.segments if interface_config.segments is vyos_defined }} {{ 'table ' ~ table if table is vyos_defined }} +{% endfor %} +{% 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 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 }} {{ 'bfd profile ' ~ next_hop_config.bfd.profile if next_hop_config.bfd.profile is vyos_defined }} {{ 'segments ' ~ next_hop_config.segments if next_hop_config.segments is vyos_defined }} {{ 'table ' ~ table if table is vyos_defined }} +{% if next_hop_config.bfd.multi_hop.source is vyos_defined %} +{% for source, source_config in next_hop_config.bfd.multi_hop.source.items() %} +{{ ip_ipv6 }} route {{ prefix }} {{ next_hop }} bfd multi-hop source {{ source }} profile {{ source_config.profile }} +{% endfor %} +{% endif %} +{% endfor %} +{% endif %} +{% endmacro %} diff --git a/data/templates/frr/staticd.frr.j2 b/data/templates/frr/staticd.frr.j2 new file mode 100644 index 0000000..992a043 --- /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() if interface_config.dhcp_options.no_default_route is not vyos_defined %} +{% 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() if interface_config.no_default_route is not vyos_defined %} +{{ 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/zebra.route-map.frr.j2 b/data/templates/frr/zebra.route-map.frr.j2 new file mode 100644 index 0000000..669d583 --- /dev/null +++ b/data/templates/frr/zebra.route-map.frr.j2 @@ -0,0 +1,14 @@ +! +{% if nht.no_resolve_via_default is vyos_defined %} +no {{ afi }} nht resolve-via-default +{% endif %} +! +{% if protocol is vyos_defined %} +{% for protocol_name, protocol_config in protocol.items() %} +{% if protocol_name is vyos_defined('ospfv3') %} +{% set protocol_name = 'ospf6' %} +{% endif %} +{{ afi }} protocol {{ protocol_name }} route-map {{ protocol_config.route_map }} +{% endfor %} +{% endif %} +! diff --git a/data/templates/frr/zebra.segment_routing.frr.j2 b/data/templates/frr/zebra.segment_routing.frr.j2 new file mode 100644 index 0000000..7b12fcd --- /dev/null +++ b/data/templates/frr/zebra.segment_routing.frr.j2 @@ -0,0 +1,23 @@ +! +{% if srv6.locator is vyos_defined %} +segment-routing + srv6 + locators +{% for locator, locator_config in srv6.locator.items() %} + locator {{ locator }} +{% if locator_config.prefix is vyos_defined %} + prefix {{ locator_config.prefix }} block-len {{ locator_config.block_len }} node-len {{ locator_config.node_len }} func-bits {{ locator_config.func_bits }} +{% endif %} +{% if locator_config.behavior_usid is vyos_defined %} + behavior usid +{% endif %} + exit + ! +{% endfor %} + exit + ! +exit +! +exit +! +{% endif %} diff --git a/data/templates/frr/zebra.vrf.route-map.frr.j2 b/data/templates/frr/zebra.vrf.route-map.frr.j2 new file mode 100644 index 0000000..8ebb825 --- /dev/null +++ b/data/templates/frr/zebra.vrf.route-map.frr.j2 @@ -0,0 +1,30 @@ +! +{% if name is vyos_defined %} +{% for vrf, vrf_config in name.items() %} +vrf {{ vrf }} +{% if vrf_config.ip.nht.no_resolve_via_default is vyos_defined %} + no ip nht resolve-via-default +{% endif %} +{% if vrf_config.ipv6.nht.no_resolve_via_default is vyos_defined %} + no ipv6 nht resolve-via-default +{% endif %} +{% if vrf_config.ip.protocol is vyos_defined %} +{% for protocol_name, protocol_config in vrf_config.ip.protocol.items() %} + ip protocol {{ protocol_name }} route-map {{ protocol_config.route_map }} +{% endfor %} +{% endif %} +{% if vrf_config.ipv6.protocol is vyos_defined %} +{% for protocol_name, protocol_config in vrf_config.ipv6.protocol.items() %} +{% if protocol_name is vyos_defined('ospfv3') %} +{% set protocol_name = 'ospf6' %} +{% endif %} + ipv6 protocol {{ protocol_name }} route-map {{ protocol_config.route_map }} +{% endfor %} +{% endif %} +{% if vrf_config.vni is vyos_defined %} + vni {{ vrf_config.vni }} +{% endif %} +exit-vrf +{% endfor %} +! +{% endif %} |