From a8b68a4be29be2ba5c04fbbc2322d83cfb9e766f Mon Sep 17 00:00:00 2001 From: zegan Date: Tue, 30 Apr 2019 15:30:18 +0800 Subject: [PATCH 1/3] [evpn]: Change frr template to support evpn - Add extension "do" action to jinja environment in sonic-cfggen - Change frr.conf.j2 to support evpn Signed-off-by: zegan --- dockers/docker-fpm-frr/frr.conf.j2 | 77 ++++++++++++++++++++++++++++ src/sonic-config-engine/sonic-cfggen | 2 +- 2 files changed, 78 insertions(+), 1 deletion(-) diff --git a/dockers/docker-fpm-frr/frr.conf.j2 b/dockers/docker-fpm-frr/frr.conf.j2 index d4fdec897da2..115b790c197c 100644 --- a/dockers/docker-fpm-frr/frr.conf.j2 +++ b/dockers/docker-fpm-frr/frr.conf.j2 @@ -79,6 +79,59 @@ route-map FROM_BGP_SPEAKER_V4 permit 10 ! route-map TO_BGP_SPEAKER_V4 deny 10 ! +! Vnet BGP instance +{% for vnet_name, vnet_metadata in VNET.iteritems() %} +router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} vrf {{ vnet_name }} + no bgp default ipv4-unicast +{% for (name, prefix) in LOOPBACK_INTERFACE %} +{% if prefix | ipv4 and name == 'Loopback0' %} + bgp router-id {{ prefix | ip }} +{% endif %} +{% endfor %} +{# got interfaces that belong this vnet #} +{% set interfaces_in_vnet = [] %} +{% for ((name, prefix), metadata) in INTERFACE.iteritems() %} +{% if metadata.has_key("vnet_name") and metadata["vnet_name"] == vnet_name %} +{% do interfaces_in_vnet.append( prefix | ip ) %} +{% endif %} +{% endfor %} +{% for neighbor_addr, bgp_session in BGP_NEIGHBOR.iteritems() %} +{% if bgp_session.has_key("local_addr") and bgp_session["local_addr"] in interfaces_in_vnet %} +{% if bgp_session['asn'] | int != 0 %} + neighbor {{ neighbor_addr }} remote-as {{ bgp_session['asn'] }} + neighbor {{ neighbor_addr }} description {{ bgp_session['name'] }} +{# set the bgp neighbor timers if they have not default values #} +{% if (bgp_session['keepalive'] is defined and bgp_session['keepalive'] | int != 60) + or (bgp_session['holdtime'] is defined and bgp_session['holdtime'] | int != 180) %} + neighbor {{ neighbor_addr }} timers {{ bgp_session['keepalive'] }} {{ bgp_session['holdtime'] }} +{% endif %} +{% if bgp_session.has_key('admin_status') and bgp_session['admin_status'] == 'down' or not bgp_session.has_key('admin_status') and DEVICE_METADATA['localhost'].has_key('default_bgp_status') and DEVICE_METADATA['localhost']['default_bgp_status'] == 'down' %} + neighbor {{ neighbor_addr }} shutdown +{% endif %} +{% if neighbor_addr | ipv4 %} + address-family ipv4 +{% if DEVICE_METADATA['localhost']['type'] == 'ToRRouter' %} + neighbor {{ neighbor_addr }} allowas-in 1 +{% endif %} + neighbor {{ neighbor_addr }} activate + neighbor {{ neighbor_addr }} soft-reconfiguration inbound +{% if bgp_session['rrclient'] | int != 0 %} + neighbor {{ neighbor_addr }} route-reflector-client +{% endif %} +{% if bgp_session['nhopself'] | int != 0 %} + neighbor {{ neighbor_addr }} next-hop-self +{% endif %} + maximum-paths 64 + exit-address-family +{% endif %} +{% endif %} +{% endif %} +{% endfor %} + address-family l2vpn evpn + advertise ipv4 unicast + exit-address-family +{% endfor %} +! router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} bgp log-neighbor-changes bgp bestpath as-path multipath-relax @@ -116,10 +169,22 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} {% endfor %} {% endblock vlan_advertisement %} {% block bgp_sessions %} +{# got interfaces that belong vnet #} +{% set interfaces_in_vnet = [] %} +{% for ((name, prefix), metadata) in INTERFACE.iteritems() %} +{% if metadata.has_key("vnet_name") %} +{% do interfaces_in_vnet.append( prefix | ip ) %} +{% endif %} +{% endfor %} {% for neighbor_addr, bgp_session in BGP_NEIGHBOR.iteritems() %} + +{% if not bgp_session.has_key("local_addr") or bgp_session["local_addr"] not in interfaces_in_vnet %} {% if bgp_session['asn'] | int != 0 %} neighbor {{ neighbor_addr }} remote-as {{ bgp_session['asn'] }} neighbor {{ neighbor_addr }} description {{ bgp_session['name'] }} +{% if bgp_session.has_key("local_addr") %} + neighbor {{ neighbor_addr }} update-source {{ bgp_session["local_addr"]}} +{%endif %} {# set the bgp neighbor timers if they have not default values #} {% if (bgp_session['keepalive'] is defined and bgp_session['keepalive'] | int != 60) or (bgp_session['holdtime'] is defined and bgp_session['holdtime'] | int != 180) %} @@ -128,10 +193,13 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} {% if bgp_session.has_key('admin_status') and bgp_session['admin_status'] == 'down' or not bgp_session.has_key('admin_status') and DEVICE_METADATA['localhost'].has_key('default_bgp_status') and DEVICE_METADATA['localhost']['default_bgp_status'] == 'down' %} neighbor {{ neighbor_addr }} shutdown {% endif %} +{% if not bgp_session.has_key("address-family") or bgp_session["address-family"] == "ip" %} {% if neighbor_addr | ipv4 %} address-family ipv4 {% if DEVICE_METADATA['localhost']['type'] == 'ToRRouter' %} neighbor {{ neighbor_addr }} allowas-in 1 +{% elif bgp_session.has_key("allowas-in") %} + neighbor {{ neighbor_addr }} allowas-in {{ bgp_session["allowas-in"] }} {% endif %} neighbor {{ neighbor_addr }} activate neighbor {{ neighbor_addr }} soft-reconfiguration inbound @@ -148,6 +216,8 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} address-family ipv6 {% if DEVICE_METADATA['localhost']['type'] == 'ToRRouter' %} neighbor {{ neighbor_addr }} allowas-in 1 +{% elif bgp_session.has_key("allowas-in") %} + neighbor {{ neighbor_addr }} allowas-in {{ bgp_session["allowas-in"] }} {% endif %} neighbor {{ neighbor_addr }} activate neighbor {{ neighbor_addr }} soft-reconfiguration inbound @@ -163,6 +233,13 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} maximum-paths 64 exit-address-family {% endif %} +{% elif bgp_session["address-family"] == "evpn" %} + address-family l2vpn evpn + neighbor {{ neighbor_addr }} activate + advertise-all-vni + exit-address-family +{% endif %} +{% endif %} {% endif %} {% endfor %} {% endblock bgp_sessions %} diff --git a/src/sonic-config-engine/sonic-cfggen b/src/sonic-config-engine/sonic-cfggen index f923cc4bc6c2..5597abc64f95 100755 --- a/src/sonic-config-engine/sonic-cfggen +++ b/src/sonic-config-engine/sonic-cfggen @@ -229,7 +229,7 @@ def main(): paths = ['/', '/usr/share/sonic/templates', os.path.dirname(template_file)] loader = jinja2.FileSystemLoader(paths) - env = jinja2.Environment(loader=loader, trim_blocks=True) + env = jinja2.Environment(loader=loader, trim_blocks=True, extensions=['jinja2.ext.do']) env.filters['sort_by_port_index'] = sort_by_port_index env.filters['ipv4'] = is_ipv4 env.filters['ipv6'] = is_ipv6 From 6e716ced3064ecbcb1871037a114dd6366df5ed3 Mon Sep 17 00:00:00 2001 From: zegan Date: Tue, 30 Apr 2019 16:25:30 +0800 Subject: [PATCH 2/3] [Fixbug]: Crash if VNET isn't defined in config db Signed-off-by: zegan --- dockers/docker-fpm-frr/frr.conf.j2 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dockers/docker-fpm-frr/frr.conf.j2 b/dockers/docker-fpm-frr/frr.conf.j2 index 115b790c197c..e2ffed20e6bc 100644 --- a/dockers/docker-fpm-frr/frr.conf.j2 +++ b/dockers/docker-fpm-frr/frr.conf.j2 @@ -80,6 +80,8 @@ route-map FROM_BGP_SPEAKER_V4 permit 10 route-map TO_BGP_SPEAKER_V4 deny 10 ! ! Vnet BGP instance +{% block vnet_bgp_instance %} +{% if VNET is defined %} {% for vnet_name, vnet_metadata in VNET.iteritems() %} router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} vrf {{ vnet_name }} no bgp default ipv4-unicast @@ -131,6 +133,8 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} vrf {{ vnet_name }} advertise ipv4 unicast exit-address-family {% endfor %} +{% endif %} +{% endblock vnet_bgp_instance %} ! router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} bgp log-neighbor-changes From 336827d216594e606a43bd737ead579f34456bd0 Mon Sep 17 00:00:00 2001 From: zegan Date: Tue, 30 Apr 2019 18:46:08 +0800 Subject: [PATCH 3/3] [Fixbug]: Not print "VNET bgp instance" if VNET doesn't existed. Signed-off-by: zegan --- dockers/docker-fpm-frr/frr.conf.j2 | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/dockers/docker-fpm-frr/frr.conf.j2 b/dockers/docker-fpm-frr/frr.conf.j2 index e2ffed20e6bc..e5633c622d62 100644 --- a/dockers/docker-fpm-frr/frr.conf.j2 +++ b/dockers/docker-fpm-frr/frr.conf.j2 @@ -79,9 +79,9 @@ route-map FROM_BGP_SPEAKER_V4 permit 10 ! route-map TO_BGP_SPEAKER_V4 deny 10 ! -! Vnet BGP instance {% block vnet_bgp_instance %} {% if VNET is defined %} +! Vnet BGP instance {% for vnet_name, vnet_metadata in VNET.iteritems() %} router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} vrf {{ vnet_name }} no bgp default ipv4-unicast @@ -135,7 +135,6 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} vrf {{ vnet_name }} {% endfor %} {% endif %} {% endblock vnet_bgp_instance %} -! router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} bgp log-neighbor-changes bgp bestpath as-path multipath-relax @@ -181,14 +180,10 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} {% endif %} {% endfor %} {% for neighbor_addr, bgp_session in BGP_NEIGHBOR.iteritems() %} - {% if not bgp_session.has_key("local_addr") or bgp_session["local_addr"] not in interfaces_in_vnet %} {% if bgp_session['asn'] | int != 0 %} neighbor {{ neighbor_addr }} remote-as {{ bgp_session['asn'] }} neighbor {{ neighbor_addr }} description {{ bgp_session['name'] }} -{% if bgp_session.has_key("local_addr") %} - neighbor {{ neighbor_addr }} update-source {{ bgp_session["local_addr"]}} -{%endif %} {# set the bgp neighbor timers if they have not default values #} {% if (bgp_session['keepalive'] is defined and bgp_session['keepalive'] | int != 60) or (bgp_session['holdtime'] is defined and bgp_session['holdtime'] | int != 180) %}