Skip to content

Commit

Permalink
[bgp]: Implement Universal Traffic Shift for SONiC (#3209)
Browse files Browse the repository at this point in the history
* [bgp]: Implement Universal Traffic Shift for SONiC

* Fix issue with ipv6 loopback match

* Add tests
  • Loading branch information
pavel-shirshov authored Jul 26, 2019
1 parent 1860dd5 commit b4517b9
Show file tree
Hide file tree
Showing 12 changed files with 299 additions and 1 deletion.
6 changes: 6 additions & 0 deletions dockers/docker-fpm-frr/Dockerfile.j2
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,11 @@ COPY ["bgpcfgd", "start.sh", "/usr/bin/"]
COPY ["*.j2", "/usr/share/sonic/templates/"]
COPY ["supervisord.conf", "/etc/supervisor/conf.d/"]
COPY ["snmp.conf", "/etc/snmp/frr.conf"]
COPY ["TSA", "/usr/bin/TSA"]
COPY ["TSB", "/usr/bin/TSB"]
COPY ["TSC", "/usr/bin/TSC"]
RUN chmod a+x /usr/bin/TSA && \
chmod a+x /usr/bin/TSB && \
chmod a+x /usr/bin/TSC

ENTRYPOINT ["/usr/bin/supervisord"]
23 changes: 23 additions & 0 deletions dockers/docker-fpm-frr/TSA
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/bin/bash

c=0
config=$(vtysh -c "show run")
echo "$config" | grep -q "route-map TO_BGP_PEER_V4 permit 2"
c=$(($c+$?))
echo "$config" | grep -q "route-map TO_BGP_PEER_V4 deny 3"
c=$(($c+$?))
echo "$config" | grep -q "route-map TO_BGP_PEER_V6 permit 2"
c=$(($c+$?))
echo "$config" | grep -q "route-map TO_BGP_PEER_V6 deny 3"
c=$(($c+$?))

if [[ $c -eq 4 ]];
then
vtysh -c "configure terminal" -c "route-map TO_BGP_PEER_V4 permit 2" -c "match ip address prefix-list PL_LoopbackV4"
vtysh -c "configure terminal" -c "route-map TO_BGP_PEER_V4 deny 3"
vtysh -c "configure terminal" -c "route-map TO_BGP_PEER_V6 permit 2" -c "match ipv6 address prefix-list PL_LoopbackV6"
vtysh -c "configure terminal" -c "route-map TO_BGP_PEER_V6 deny 3"
echo "System Mode: Normal -> Maintenance"
else
echo "System is already in Maintenance mode"
fi
24 changes: 24 additions & 0 deletions dockers/docker-fpm-frr/TSB
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/bin/bash

c=0
config=$(vtysh -c "show run")
echo "$config" | grep -q "route-map TO_BGP_PEER_V4 permit 2"
c=$(($c+$?))
echo "$config" | grep -q "route-map TO_BGP_PEER_V4 deny 3"
c=$(($c+$?))
echo "$config" | grep -q "route-map TO_BGP_PEER_V6 permit 2"
c=$(($c+$?))
echo "$config" | grep -q "route-map TO_BGP_PEER_V6 deny 3"
c=$(($c+$?))

if [[ $c -eq 0 ]];
then
vtysh -c "configure terminal" -c "no route-map TO_BGP_PEER_V4 deny 3"
vtysh -c "configure terminal" -c "no route-map TO_BGP_PEER_V4 permit 2"
vtysh -c "configure terminal" -c "no route-map TO_BGP_PEER_V6 deny 3"
vtysh -c "configure terminal" -c "no route-map TO_BGP_PEER_V6 permit 2"

echo "System Mode: Maintenance -> Normal"
else
echo "System is already in Normal mode"
fi
25 changes: 25 additions & 0 deletions dockers/docker-fpm-frr/TSC
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/bin/bash

echo "Traffic Shift Check:"
c=0
config=$(vtysh -c "show run")
echo "$config" | grep -q "route-map TO_BGP_PEER_V4 permit 2"
c=$(($c+$?))
echo "$config" | grep -q "route-map TO_BGP_PEER_V4 deny 3"
c=$(($c+$?))
echo "$config" | grep -q "route-map TO_BGP_PEER_V6 permit 2"
c=$(($c+$?))
echo "$config" | grep -q "route-map TO_BGP_PEER_V6 deny 3"
c=$(($c+$?))

if [[ $c -eq 4 ]];
then
echo "System Mode: Normal"
elif [[ $c -eq 0 ]];
then
echo "System Mode: Maintenance"
else
echo "System Mode: Not consistent"
fi

echo
3 changes: 3 additions & 0 deletions dockers/docker-fpm-frr/base_image_files/TSA
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/bash

docker exec -i bgp /usr/bin/TSA
3 changes: 3 additions & 0 deletions dockers/docker-fpm-frr/base_image_files/TSB
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/bash

docker exec -i bgp /usr/bin/TSB
5 changes: 5 additions & 0 deletions dockers/docker-fpm-frr/base_image_files/TSC
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/bash

docker exec -i bgp /usr/bin/TSC

/usr/bin/portstat -p 5
21 changes: 21 additions & 0 deletions dockers/docker-fpm-frr/bgpd.conf.default.j2
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,21 @@ route-map FROM_BGP_SPEAKER_V4 permit 10
!
route-map TO_BGP_SPEAKER_V4 deny 10
!
{# generate loopback prefix-lists #}
{% for (name, prefix) in LOOPBACK_INTERFACE|pfx_filter %}
{% if prefix | ipv4 and name == 'Loopback0' %}
ip prefix-list PL_LoopbackV4 permit {{ prefix | ip }}/32
{% elif prefix | ipv6 and name == 'Loopback0' %}
ipv6 prefix-list PL_LoopbackV6 permit {{ prefix | ip }}/64
{% endif %}
{% endfor %}
!
{# generate default peer route-maps #}
!
route-map TO_BGP_PEER_V4 permit 100
!
route-map TO_BGP_PEER_V6 permit 100
!
router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }}
bgp log-neighbor-changes
bgp bestpath as-path multipath-relax
Expand Down Expand Up @@ -57,6 +72,10 @@ 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 %}
{# Apply default route-map for v4 peers #}
{% if neighbor_addr | ipv4 %}
neighbor {{ neighbor_addr }} route-map TO_BGP_PEER_V4 out
{% endif %}
{% if neighbor_addr | ipv4 %}
address-family ipv4
{% if DEVICE_METADATA['localhost']['type'] == 'ToRRouter' %}
Expand Down Expand Up @@ -89,6 +108,8 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }}
{% if bgp_session['asn'] != DEVICE_METADATA['localhost']['bgp_asn'] %}
neighbor {{ neighbor_addr }} route-map set-next-hop-global-v6 in
{% endif %}
{# Apply default route-map for v6 peers #}
neighbor {{ neighbor_addr }} route-map TO_BGP_PEER_V6 out
maximum-paths 64
exit-address-family
{% endif %}
Expand Down
4 changes: 3 additions & 1 deletion rules/docker-fpm-frr.mk
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,6 @@ $(DOCKER_FPM_FRR)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro
$(DOCKER_FPM_FRR)_RUN_OPT += -v /etc/sonic/frr:/etc/frr:rw

$(DOCKER_FPM_FRR)_BASE_IMAGE_FILES += vtysh:/usr/bin/vtysh

$(DOCKER_FPM_FRR)_BASE_IMAGE_FILES += TSA:/usr/bin/TSA
$(DOCKER_FPM_FRR)_BASE_IMAGE_FILES += TSB:/usr/bin/TSB
$(DOCKER_FPM_FRR)_BASE_IMAGE_FILES += TSC:/usr/bin/TSC
125 changes: 125 additions & 0 deletions src/sonic-config-engine/tests/sample_output/bgpd_frr.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
!
! =========== Managed by sonic-cfggen DO NOT edit manually! ====================
! generated by templates/quagga/bgpd.conf.j2 with config DB data
! file: bgpd.conf
!
!
hostname switch-t0
password zebra
log syslog informational
log facility local4
agentx
! enable password !
!
! bgp multiple-instance
!
route-map FROM_BGP_SPEAKER_V4 permit 10
!
route-map TO_BGP_SPEAKER_V4 deny 10
!
ip prefix-list PL_LoopbackV4 permit 10.1.0.32/32
ipv6 prefix-list PL_LoopbackV6 permit fc00:1::32/64
!
!
route-map TO_BGP_PEER_V4 permit 100
!
route-map TO_BGP_PEER_V6 permit 100
!
router bgp 65100
bgp log-neighbor-changes
bgp bestpath as-path multipath-relax
no bgp default ipv4-unicast
bgp graceful-restart restart-time 240
bgp graceful-restart
bgp graceful-restart preserve-fw-state
bgp router-id 10.1.0.32
network 10.1.0.32/32
address-family ipv6
network fc00:1::32/64
exit-address-family
network 192.168.0.1/27
neighbor 10.0.0.57 remote-as 64600
neighbor 10.0.0.57 description ARISTA01T1
neighbor 10.0.0.57 route-map TO_BGP_PEER_V4 out
address-family ipv4
neighbor 10.0.0.57 allowas-in 1
neighbor 10.0.0.57 activate
neighbor 10.0.0.57 soft-reconfiguration inbound
maximum-paths 64
exit-address-family
neighbor 10.0.0.59 remote-as 64600
neighbor 10.0.0.59 description ARISTA02T1
neighbor 10.0.0.59 route-map TO_BGP_PEER_V4 out
address-family ipv4
neighbor 10.0.0.59 allowas-in 1
neighbor 10.0.0.59 activate
neighbor 10.0.0.59 soft-reconfiguration inbound
maximum-paths 64
exit-address-family
neighbor 10.0.0.61 remote-as 64600
neighbor 10.0.0.61 description ARISTA03T1
neighbor 10.0.0.61 route-map TO_BGP_PEER_V4 out
address-family ipv4
neighbor 10.0.0.61 allowas-in 1
neighbor 10.0.0.61 activate
neighbor 10.0.0.61 soft-reconfiguration inbound
maximum-paths 64
exit-address-family
neighbor 10.0.0.63 remote-as 64600
neighbor 10.0.0.63 description ARISTA04T1
neighbor 10.0.0.63 route-map TO_BGP_PEER_V4 out
address-family ipv4
neighbor 10.0.0.63 allowas-in 1
neighbor 10.0.0.63 activate
neighbor 10.0.0.63 soft-reconfiguration inbound
maximum-paths 64
exit-address-family
neighbor fc00::7a remote-as 64600
neighbor fc00::7a description ARISTA03T1
address-family ipv6
neighbor fc00::7a allowas-in 1
neighbor fc00::7a activate
neighbor fc00::7a soft-reconfiguration inbound
neighbor fc00::7a route-map set-next-hop-global-v6 in
neighbor fc00::7a route-map TO_BGP_PEER_V6 out
maximum-paths 64
exit-address-family
neighbor fc00::7e remote-as 64600
neighbor fc00::7e description ARISTA04T1
address-family ipv6
neighbor fc00::7e allowas-in 1
neighbor fc00::7e activate
neighbor fc00::7e soft-reconfiguration inbound
neighbor fc00::7e route-map set-next-hop-global-v6 in
neighbor fc00::7e route-map TO_BGP_PEER_V6 out
maximum-paths 64
exit-address-family
neighbor fc00::72 remote-as 64600
neighbor fc00::72 description ARISTA01T1
address-family ipv6
neighbor fc00::72 allowas-in 1
neighbor fc00::72 activate
neighbor fc00::72 soft-reconfiguration inbound
neighbor fc00::72 route-map set-next-hop-global-v6 in
neighbor fc00::72 route-map TO_BGP_PEER_V6 out
maximum-paths 64
exit-address-family
neighbor fc00::76 remote-as 64600
neighbor fc00::76 description ARISTA02T1
address-family ipv6
neighbor fc00::76 allowas-in 1
neighbor fc00::76 activate
neighbor fc00::76 soft-reconfiguration inbound
neighbor fc00::76 route-map set-next-hop-global-v6 in
neighbor fc00::76 route-map TO_BGP_PEER_V6 out
maximum-paths 64
exit-address-family
!!
maximum-paths 64
!
route-map ISOLATE permit 10
set as-path prepend 65100
!
route-map set-next-hop-global-v6 permit 10
set ipv6 next-hop prefer-global
!
44 changes: 44 additions & 0 deletions src/sonic-config-engine/tests/sample_output/zebra_frr.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
!
! =========== Managed by sonic-cfggen DO NOT edit manually! ====================
! generated by templates/quagga/zebra.conf.j2 using config DB data
! file: zebra.conf
!
!
hostname switch-t0
password zebra
enable password zebra
!
! Enable link-detect (default disabled)
interface PortChannel01
link-detect
!
interface PortChannel02
link-detect
!
interface PortChannel03
link-detect
!
interface PortChannel04
link-detect
!
!
! set static default route to mgmt gateway as a backup to learned default
ip route 0.0.0.0/0 10.0.0.1 200
!
! Set ip source to loopback for bgp learned routes
route-map RM_SET_SRC permit 10
set src 10.1.0.32
!

route-map RM_SET_SRC6 permit 10
set src fc00:1::32
!
ip protocol bgp route-map RM_SET_SRC
!
ipv6 protocol bgp route-map RM_SET_SRC6
!
!
log syslog informational
log facility local4
!

17 changes: 17 additions & 0 deletions src/sonic-config-engine/tests/test_j2files.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,23 @@ def test_config_frr(self):
self.run_script(argument)
self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', 'frr.conf'), self.output_file))


def test_bgpd_frr(self):
conf_template = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-fpm-frr', 'bgpd.conf.j2')
argument = '-m ' + self.t0_minigraph + ' -p ' + self.t0_port_config + ' -t ' + conf_template + ' > ' + self.output_file
self.run_script(argument)
original_filename = os.path.join(self.test_dir, 'sample_output', 'bgpd_frr.conf')
r = filecmp.cmp(original_filename, self.output_file)
diff_output = self.run_diff(original_filename, self.output_file) if not r else ""
self.assertTrue(r, "Diff:\n" + diff_output)

def test_zebra_frr(self):
conf_template = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-fpm-quagga', 'zebra.conf.j2')
argument = '-m ' + self.t0_minigraph + ' -p ' + self.t0_port_config + ' -t ' + conf_template + ' > ' + self.output_file
self.run_script(argument)
self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', 'zebra_frr.conf'), self.output_file))


def test_ipinip(self):
ipinip_file = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-orchagent', 'ipinip.json.j2')
argument = '-m ' + self.t0_minigraph + ' -p ' + self.t0_port_config + ' -t ' + ipinip_file + ' > ' + self.output_file
Expand Down

0 comments on commit b4517b9

Please sign in to comment.