Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Srlinux template updates #372

Merged
merged 4 commits into from
Sep 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
149 changes: 62 additions & 87 deletions netsim/ansible/templates/bgp/srlinux.macro.j2
Original file line number Diff line number Diff line change
Expand Up @@ -51,69 +51,7 @@
export-reject-all: False
import-reject-all: False

{#
Configure BGP Groups
#}
group:
{% for g in ['ibgp-ipv4','ibgp-ipv6','ebgp','ebgp-unnumbered'] %}
{% set _type = g[:4] %}
- group-name: {{ g }}
admin-state: enable
import-policy: {{ import_policy if 'ebgp' in g else 'accept_all' }}
export-policy: {{ export_policy if 'ebgp' in g else 'accept_all' }}
timers:
connect-retry: 10
_annotate_connect-retry: "Reduce default 120s to 10s"
minimum-advertisement-interval: 1

{# BGP communities #}
{% if bgp.community[ _type ]|default([]) %}
{% set list = bgp.community[ _type ] %}
send-community:
standard: {{ 'standard' in list or 'both' in list }}
large: {{ 'large' in list }}
{% endif %}

{# iBGP #}
{% if g in ['ibgp-ipv4','ibgp-ipv6'] %}
peer-as: {{ _as }}
ipv4-unicast:
admin-state: {{ 'enable' if g == 'ibgp-ipv4' and 'ipv4' in bgp.address_families['ibgp'] else 'disable' }}
ipv6-unicast:
admin-state: {{ 'enable' if g == 'ibgp-ipv6' or 'ipv6' in bgp.address_families['ibgp'] else 'disable' }}
evpn:
admin-state: {{ 'enable' if evpn is defined and 'ibgp' in evpn.session|default([]) else 'disable' }}
{% if g[5:] in loopback %}
transport:
local-address: {{ loopback[ g[5:] ]|default('')|ipaddr('address') }}
{% endif %}
{% if vrf_bgp.rr|default(0) %}
route-reflector:
cluster-id: {{ vrf_bgp.rr_cluster_id|default(False) or router_id }}
client: True
{% endif %}
{% else %}

{# eBGP #}
next-hop-self: {{ 'True' if bgp.next_hop_self|default(False) else 'False' }}
{% if g == 'ebgp-unnumbered' %}
local-as:
- as-number: {{ bgp.underlay_as|default(_as) }}
prepend-global-as: false
ipv4-unicast:
advertise-ipv6-next-hops: true
receive-ipv6-next-hops: true
{% else %}
ipv4-unicast:
{% endif %}
admin-state: {{ 'enable' if 'ipv4' in bgp.address_families['ebgp'] else 'disable' }}
ipv6-unicast:
admin-state: {{ 'enable' if 'ipv6' in bgp.address_families['ebgp'] else 'disable' }}
{% endif %}

{% endfor %}

{# Configure BGP address families #}
{# Configure BGP address families globally #}
{% for af in ['ipv4','ipv6'] if vrf_bgp[af]|default(0) %}
{{ af }}-unicast:
admin-state: enable
Expand All @@ -133,29 +71,83 @@

{% endfor %}

{% macro bgp_peer_group(name,type,neighbor,transport_ip) %}
- path: network-instance[name={{vrf}}]/protocols/bgp/group[group-name={{name}}]
val:
admin-state: enable
ipv4-unicast:
admin-state: {{ 'enable' if 'ipv4' in neighbor.activate and neighbor.activate['ipv4'] else 'disable' }}
ipv6-unicast:
admin-state: {{ 'enable' if 'ipv6' in neighbor.activate and neighbor.activate['ipv6'] else 'disable' }}
import-policy: {{ import_policy if 'ebgp' in type else 'accept_all' }}
export-policy: {{ export_policy if 'ebgp' in type else 'accept_all' }}
timers:
connect-retry: 10
_annotate_connect-retry: "Reduce default 120s to 10s"
minimum-advertisement-interval: 1
{% if vrf_bgp.community[ type ]|default([]) %}
{% set list = vrf_bgp.community[ type ] %}
send-community:
standard: {{ 'standard' in list }}
large: {{ 'extended' in list }}
{% endif %}
{% if transport_ip %}
transport:
local-address: {{ transport_ip }}
{% endif %}
{% if 'ibgp' in type %}
next-hop-self: {{ vrf_bgp.next_hop_self|default(False) }}
peer-as: {{ neighbor.as }}
{% if vrf_bgp.rr|default(0) %}
route-reflector:
cluster-id: {{ vrf_bgp.rr_cluster_id|default(False) or router_id }}
client: True
{% endif %}
{% endif %}
{% endmacro %}

{#
Define IPv4 and IPv6 BGP neighbors
#}
{% for n in vrf_bgp.neighbors %}
{% for af in ['ipv4','ipv6'] if n[af] is defined %}

{% if n[af] is string %}
{# (Re)create peer group #}
{% set peer_group = 'ebgp' if n.type=='ebgp' else 'ibgp-local-as' if n.type=='localas_ibgp' else ('ibgp-'+af) %}
{% set transport_ip = loopback[af]|ipaddr('address') if af in loopback and n.type=='ibgp' else None %}
{{ bgp_peer_group(peer_group,'ibgp' if 'ibgp' in n.type else 'ebgp',n,transport_ip) }}

- path: network-instance[name={{vrf}}]/protocols/bgp/neighbor[peer-address={{n[af]}}]
val:
description: {{ n.name }}
peer-group: {{ 'ebgp' if n.type=='ebgp' else ('ibgp-'+af) }}
{% if n.type != 'ibgp' %}
peer-group: {{ peer_group }}
{% if 'ebgp' in n.type %}
peer-as: {{ n.as }}
{% elif vrf_bgp.rr|default(False) and n.rr|default(False) %}
route-reflector:
client: False # Don't reflect routes between ibgp route reflectors
{% endif %}
{% if n.local_as is defined %}
local-as:
- as-number: {{ n.local_as }}
{% if n.type == 'ebgp' %}
prepend-global-as: False # Don't include iBGP AS in eBGP advertisements
{% endif %}
prepend-global-as: {{ not n.replace_global_as|default(True) }} # Don't include iBGP global AS in eBGP advertisements
{% endif %}
{% elif n[af]==True and af=='ipv6' %}
{# BGP unnumbered for IPv6 LLA #}

{% elif n[af]==True and af=='ipv6' and n.type == 'ebgp' %}
{# BGP unnumbered for IPv6 LLA, only supported for EBGP peers #}
{% set peer_group = "ebgp-unnumbered" + (('-' + n.local_as|string()) if n.local_as is defined else '') %}
{{ bgp_peer_group(peer_group,'ebgp',n,None) }}
{% if n.local_as is defined %}
local-as:
- as-number: {{ n.local_as }}
prepend-global-as: {{ not n.replace_global_as|default(True) }} # Don't include iBGP AS in eBGP advertisements
{% endif %}
{% if 'ipv4' in n.activate|default([]) and n.activate[ 'ipv4' ] %}
ipv4-unicast:
advertise-ipv6-next-hops: true
receive-ipv6-next-hops: true
{% endif %}

- path: network-instance[name={{vrf}}]/ip-forwarding
val:
Expand All @@ -171,23 +163,6 @@
peer-group: "{{ peer_group }}"
allowed-peer-as: [ {{ n.as }}..{{ n.as }} ]

{% if peer_group != "ebgp-unnumbered" %}
- path: network-instance[name={{vrf}}]/protocols/bgp/group[group-name={{peer_group}}]
val:
admin-state: enable
import-policy: accept_all
export-policy: accept_all
timers:
connect-retry: 10
_annotate_connect-retry: "Reduce default 120s to 10s"
minimum-advertisement-interval: 1
local-as:
- as-number: {{ n.local_as }}
prepend-global-as: false
ipv4-unicast:
advertise-ipv6-next-hops: true
receive-ipv6-next-hops: true
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}
Expand Down
3 changes: 3 additions & 0 deletions netsim/ansible/templates/evpn/srlinux.j2
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ updates:
- group-name: {{ 'ibgp-ipv4' if type=='ibgp' else 'ebgp' }} # Could create a dedicated group for EVPN only?
evpn:
admin-state: enable
{% if bgp.rr|default(0) %}
next-hop-self: False
{% endif %}
evpn:
rapid-update: True
{% endfor %}
16 changes: 9 additions & 7 deletions netsim/ansible/templates/initial/srlinux.j2
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ updates:
val:
{{ ip_addresses(loopback,False,True) }}

{% for l in interfaces|default([]) if (l.type in ['lan','vlan_member','svi'] or l.vlan is not defined) %}
{% for l in interfaces|default([]) %}
{% set if_name_index = l.ifname.split('.') %}
{% set if_name = if_name_index[0] %}
{% set if_index = if_name_index[1] if if_name_index|length > 1 else l.vlan.access_id|default(0) if l.vlan is defined else '0' %}
Expand Down Expand Up @@ -83,25 +83,27 @@ updates:
{% set if_name_index = l.ifname.split('.') %}
{% set if_name = if_name_index[0] %}
{% set if_index = if_name_index[1] if if_name_index|length > 1 else '0' %}
- path: network-instance[name={{ vrf }}]
val:
type: {{ 'default' if vrf=='default' else 'ip-vrf' }}
interface:
- name: {{ if_name }}.{{ if_index }}
{% endfor %}
{% endmacro %}

{# Make sure the default VRF is called 'default' #}
{# Make sure the default VRF is called 'default', and has system0.0 interface #}
- path: network-instance[name=default]
val:
type: default
interface:
- name: system0.0

{{ list_interfaces('default') }}

{% if vrfs is defined %}
{% for vname,vdata in vrfs.items() %}
- path: network-instance[name={{ vname }}]
val:
type: ip-vrf
# TODO: vdata.rd, vdata.import/export, vdata.af
interface:

# TODO: vdata.rd, vdata.import/export, vdata.af
{{ list_interfaces(vname) }}

{% endfor %}
Expand Down
13 changes: 6 additions & 7 deletions netsim/topology-defaults.yml
Original file line number Diff line number Diff line change
Expand Up @@ -607,8 +607,6 @@ devices:
ansible_network_os: cumulus
ansible_connection: paramiko
features:
bgp:
activate_af: True
initial:
ipv4:
unnumbered: True
Expand Down Expand Up @@ -676,10 +674,6 @@ devices:
srgb_range_start: 500000
srgb_range_size: 1000
ipv6_sid_offset: 100
bgp:
address_families:
ibgp: [ ipv4, ipv6 ]
ebgp: [ ipv4, ipv6 ]
bfd: # SR Linux supports lower BFD timers than the global default
min_tx: 100
min_rx: 100
Expand All @@ -704,8 +698,13 @@ devices:
svi_interface_name: "irb0.{vlan}"
subif_name: "{ifname}.{vlan.access_id}"
mixed_trunk: True
bgp:
local_as: True
vrf_local_as: True
local_as_ibgp: True
activate_af: True
vxlan:
requires: [ evpn ]
requires: [ evpn, vrf ]
ospf:
unnumbered: False
isis:
Expand Down
3 changes: 0 additions & 3 deletions tests/topology/expected/device-module-defaults.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,6 @@ nodes:
ipv4: true
bgp:
address_families:
ebgp:
- ipv4
- ipv6
ibgp:
- ipv4
advertise_loopback: true
Expand Down