Skip to content

Commit

Permalink
[build]: Adding support for Free-Range-Routing stack. (#510)
Browse files Browse the repository at this point in the history
- Extending SONiC building infrastructure to provide users
           with greater flexibility, by allowing them to elect a
           routing-stack different than the default one (quagga). The desired
           routing-stack will be defined in rules/config file.

         - As part of these changes I'm adding support for
           Free-Range-Routing (FRR) stack. Quagga will continue to be
           the default routing-stack.

Signed-off-by: Rodny Molina <rodny@linkedin.com>
  • Loading branch information
rodnymolina authored and lguohan committed Apr 20, 2017
1 parent ea51e1c commit d30fbf1
Show file tree
Hide file tree
Showing 36 changed files with 511 additions and 22 deletions.
32 changes: 32 additions & 0 deletions dockers/docker-fpm-frr/Dockerfile.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
FROM docker-config-engine

## Make apt-get non-interactive
ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get update

RUN apt-get install -y libdbus-1-3 libdaemon0 libjansson4 libc-ares2 iproute

COPY \
{% for deb in docker_fpm_frr_debs.split(' ') -%}
debs/{{ deb }}{{' '}}
{%- endfor -%}
debs/

RUN dpkg -i \
{% for deb in docker_fpm_frr_debs.split(' ') -%}
debs/{{ deb }}{{' '}}
{%- endfor %}

## Clean up
RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y
RUN rm -rf /debs

COPY ["*.j2", "/usr/share/sonic/templates/"]
COPY ["start.sh", "config.sh", "/usr/bin/"]
COPY ["daemons", "/etc/frr/"]
COPY ["debian.conf", "/etc/frr/"]

ENTRYPOINT /usr/bin/config.sh \
&& /usr/bin/start.sh \
&& /bin/bash
File renamed without changes.
64 changes: 64 additions & 0 deletions dockers/docker-fpm-frr/bgpd.conf.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
!
{% block banner %}
! =========== Managed by sonic-cfggen DO NOT edit manually! ====================
! generated by templates/quagga/bgpd.conf.j2 using minigraph_facts.py
! file: bgpd.conf
!
{% endblock banner %}
!
{% block system_init %}
hostname {{ inventory_hostname }}
password zebra
log syslog informational
log facility local4
! enable password {# {{ en_passwd }} TODO: param needed #}
{% endblock system_init %}
!
{% block bgp_init %}
!
! bgp multiple-instance
!
router bgp {{ minigraph_bgp_asn }}
bgp log-neighbor-changes
bgp bestpath as-path multipath-relax
{# TODO: use lo[0] for backward compatibility, will revisit the case with multiple lo interfaces #}
bgp router-id {{ minigraph_lo_interfaces[0]['addr'] }}
{# advertise loopback #}
{% for lo in minigraph_lo_interfaces %}
{% if lo['addr'] | ipv4 %}
network {{ lo['addr'] }}/32
{% elif lo['addr'] | ipv6 %}
address-family ipv6
network {{ lo['addr'] }}/128
exit-address-family
{% endif %}
{% endfor %}
{% endblock bgp_init %}
{% block vlan_advertisement %}
{% for vlan_interface in minigraph_vlan_interfaces %}
network {{ vlan_interface['subnet'] }}
{% endfor %}
{% endblock vlan_advertisement %}
{% block bgp_sessions %}
{% for bgp_session in minigraph_bgp %}
{% if bgp_session['asn'] != 0 %}
neighbor {{ bgp_session['addr'] }} remote-as {{ bgp_session['asn'] }}
neighbor {{ bgp_session['addr'] }} description {{ bgp_session['name'] }}
{% if minigraph_devices[inventory_hostname]['type'] == 'ToRRouter' %}
neighbor {{ bgp_session['addr'] }} allowas-in 1
{% endif %}
{% if bgp_session['addr'] | ipv6 %}
address-family ipv6
neighbor {{ bgp_session['addr'] }} activate
maximum-paths 64
exit-address-family
{% endif %}
{% endif %}
{% endfor %}
{% endblock bgp_sessions %}
!
maximum-paths 64
!
route-map ISOLATE permit 10
set as-path prepend {{ minigraph_bgp_asn }}
!
17 changes: 17 additions & 0 deletions dockers/docker-fpm-frr/config.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/bin/bash

mkdir -p /etc/frr
sonic-cfggen -m /etc/sonic/minigraph.xml -t /usr/share/sonic/templates/bgpd.conf.j2 >/etc/frr/bgpd.conf
sonic-cfggen -m /etc/sonic/minigraph.xml -t /usr/share/sonic/templates/zebra.conf.j2 >/etc/frr/zebra.conf

sonic-cfggen -m /etc/sonic/minigraph.xml -t /usr/share/sonic/templates/isolate.j2 >/usr/sbin/bgp-isolate
chown root:root /usr/sbin/bgp-isolate
chmod 0755 /usr/sbin/bgp-isolate

sonic-cfggen -m /etc/sonic/minigraph.xml -t /usr/share/sonic/templates/unisolate.j2 >/usr/sbin/bgp-unisolate
chown root:root /usr/sbin/bgp-unisolate
chmod 0755 /usr/sbin/bgp-unisolate

mkdir -p /var/sonic
echo "# Config files managed by sonic-config-engine" >/var/sonic/config_status

File renamed without changes.
20 changes: 20 additions & 0 deletions dockers/docker-fpm-frr/debian.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#
# If this option is set the /etc/init.d/frr script automatically loads
# the config via "vtysh -b" when the servers are started.
# Check /etc/pam.d/frr if you intend to use "vtysh"!
#
vtysh_enable=yes
zebra_options=" -s 90000000 --daemon -A 127.0.0.1 -M fpm"
bgpd_options=" --daemon -A 127.0.0.1"
ospfd_options=" --daemon -A 127.0.0.1"
ospf6d_options=" --daemon -A ::1"
ripd_options=" --daemon -A 127.0.0.1"
ripngd_options=" --daemon -A ::1"
isisd_options=" --daemon -A 127.0.0.1"
pimd_options=" --daemon -A 127.0.0.1"
ldpd_options=" --daemon -A 127.0.0.1"
nhrpd_options=" --daemon -A 127.0.0.1"

# The list of daemons to watch is automatically generated by the init script.
watchfrr_enable=yes
watchfrr_options=(-adz -r /usr/sbin/servicebBfrrbBrestartbB%s -s /usr/sbin/servicebBfrrbBstartbB%s -k /usr/sbin/servicebBfrrbBstopbB%s -b bB -t 30)
File renamed without changes.
6 changes: 6 additions & 0 deletions dockers/docker-fpm-frr/start.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/bash

rm -f /var/run/rsyslogd.pid
service rsyslog start
service frr start
fpmsyncd &
File renamed without changes.
66 changes: 66 additions & 0 deletions dockers/docker-fpm-frr/zebra.conf.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
!
{% block banner %}
! =========== Managed by sonic-cfggen DO NOT edit manually! ====================
! generated by templates/quagga/zebra.conf.j2 using minigraph_facts.py
! file: zebra.conf
!
{% endblock banner %}
!
{% block sys_init %}
hostname {{ inventory_hostname }}
password zebra
enable password zebra
{% endblock sys_init %}
!
{% block interfaces %}
! Enable link-detect (default disabled)
{% for interface in minigraph_interfaces %}
interface {{ interface['alias'] }}
link-detect
!
{% endfor %}
{% for interface in minigraph_portchannel_interfaces %}
interface {{ interface['name'] }}
link-detect
!
{% endfor %}
{% endblock interfaces %}
!
{% block default_route %}
! set static default route to mgmt gateway as a backup to learned default
ip route 0.0.0.0/0 {{ minigraph_mgmt_interface['gwaddr'] }} 200
{% endblock default_route %}
!
{% block source_loopback %}
! Set ip source to loopback for bgp learned routes
route-map RM_SET_SRC permit 10
set src {{ minigraph_lo_interfaces[0]['addr'] }}
!
{% set lo_ipv6_addrs = [] %}
{% if minigraph_lo_interfaces is defined %}
{% for interface in minigraph_lo_interfaces %}
{% if interface['addr'] is defined and interface['addr']|ipv6 %}
{% if lo_ipv6_addrs.append(interface['addr']) %}
{% endif %}
{% endif %}
{% endfor %}
{% endif %}
{% if lo_ipv6_addrs|length > 0 %}
route-map RM_SET_SRC6 permit 10
set src {{ lo_ipv6_addrs[0] }}
!
{% endif %}
ip protocol bgp route-map RM_SET_SRC
!
{% if lo_ipv6_addrs|length > 0 %}
ipv6 protocol bgp route-map RM_SET_SRC6
!
{% endif %}
{% endblock source_loopback %}
!
{% block logging %}
log syslog informational
log facility local4
{% endblock logging %}
!

2 changes: 1 addition & 1 deletion dockers/docker-fpm-gobgp/Dockerfile.j2
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM docker-fpm
FROM docker-fpm-quagga

## Make apt-get non-interactive
ENV DEBIAN_FRONTEND=noninteractive
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ RUN apt-get update
RUN apt-get install -y libdbus-1-3 libdaemon0 libjansson4

COPY \
{% for deb in docker_fpm_debs.split(' ') -%}
{% for deb in docker_fpm_quagga_debs.split(' ') -%}
debs/{{ deb }}{{' '}}
{%- endfor -%}
debs/

RUN dpkg -i \
{% for deb in docker_fpm_debs.split(' ') -%}
{% for deb in docker_fpm_quagga_debs.split(' ') -%}
debs/{{ deb }}{{' '}}
{%- endfor %}

Expand Down
2 changes: 2 additions & 0 deletions dockers/docker-fpm-quagga/base_image_files/vtysh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/bin/bash
docker exec -i bgp vtysh "$@"
File renamed without changes.
File renamed without changes.
31 changes: 31 additions & 0 deletions dockers/docker-fpm-quagga/daemons
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# This file tells the quagga package which daemons to start.
#
# Entries are in the format: <daemon>=(yes|no|priority)
# 0, "no" = disabled
# 1, "yes" = highest priority
# 2 .. 10 = lower priorities
# Read /usr/share/doc/quagga/README.Debian for details.
#
# Sample configurations for these daemons can be found in
# /usr/share/doc/quagga/examples/.
#
# ATTENTION:
#
# When activation a daemon at the first time, a config file, even if it is
# empty, has to be present *and* be owned by the user and group "quagga", else
# the daemon will not be started by /etc/init.d/quagga. The permissions should
# be u=rw,g=r,o=.
# When using "vtysh" such a config file is also needed. It should be owned by
# group "quaggavty" and set to ug=rw,o= though. Check /etc/pam.d/quagga, too.
#
# The watchquagga daemon is always started. Per default in monitoring-only but
# that can be changed via /etc/quagga/debian.conf.
#
zebra=yes
bgpd=yes
ospfd=no
ospf6d=no
ripd=no
ripngd=no
isisd=no
babeld=no
20 changes: 20 additions & 0 deletions dockers/docker-fpm-quagga/isolate.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/bin/bash
## vtysh only accepts script in stdin, so cannot be directly used in shebang
## Cut the tail of this script and feed vtysh stdin
sed -n -e '9,$p' < "$0" | vtysh "$@"
## Exit with vtysh return code
exit $?

## vtysh script start from next line, which line number MUST eqaul in 'sed' command above

configure terminal
router bgp {{ minigraph_bgp_asn }}
{% for bgp_session in minigraph_bgp %}
neighbor {{ bgp_session['addr'] }} route-map ISOLATE out
{% endfor %}
exit
exit

{% for bgp_session in minigraph_bgp %}
clear ip bgp {{ bgp_session['addr'] }} soft out
{% endfor %}
File renamed without changes.
20 changes: 20 additions & 0 deletions dockers/docker-fpm-quagga/unisolate.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/bin/bash
## vtysh only accepts script in stdin, so cannot be directly used in shebang
## Cut the tail of this script and feed vtysh stdin
sed -n -e '9,$p' < "$0" | vtysh "$@"
## Exit with vtysh return code
exit $?

## vtysh script start from next line, which line number MUST eqaul in 'sed' command above

configure terminal
router bgp {{ minigraph_bgp_asn }}
{% for bgp_session in minigraph_bgp %}
no neighbor {{ bgp_session['addr'] }} route-map ISOLATE out
{% endfor %}
exit
exit

{% for bgp_session in minigraph_bgp %}
clear ip bgp {{ bgp_session['addr'] }} soft out
{% endfor %}
File renamed without changes.
2 changes: 1 addition & 1 deletion platform/broadcom/rules.mk
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ $(DSSERVE)_URL = "https://sonicstorage.blob.core.windows.net/packages/dsserve?sv
SONIC_ONLINE_FILES += $(BCMCMD) $(DSSERVE)

SONIC_ALL += $(SONIC_ONE_IMAGE) $(SONIC_ONE_ABOOT_IMAGE) \
$(DOCKER_FPM_GOBGP) \
$(DOCKER_FPM) \
$(DOCKER_SYNCD_BRCM_RPC)

# Inject brcm sai into sairedis
Expand Down
2 changes: 1 addition & 1 deletion platform/cavium/rules.mk
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ include $(PLATFORM_PATH)/libsaithrift-dev.mk
include $(PLATFORM_PATH)/python-saithrift.mk

SONIC_ALL += $(SONIC_ONE_IMAGE) \
$(DOCKER_FPM_GOBGP)
$(DOCKER_FPM)

# Inject cavium sai into sairedis
$(LIBSAIREDIS)_DEPENDS += $(CAVM_SAI) $(CAVM_LIBSAI)
Expand Down
2 changes: 1 addition & 1 deletion platform/mellanox/rules.mk
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ include $(PLATFORM_PATH)/libsaithrift-dev.mk
include $(PLATFORM_PATH)/python-saithrift.mk

SONIC_ALL += $(SONIC_ONE_IMAGE) \
$(DOCKER_FPM_GOBGP) \
$(DOCKER_FPM) \
$(DOCKER_SYNCD_MLNX_RPC)

# Inject mlnx sai into sairedis
Expand Down
11 changes: 10 additions & 1 deletion platform/p4/docker-sonic-p4.mk
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@

DOCKER_SONIC_P4 = docker-sonic-p4.gz
$(DOCKER_SONIC_P4)_PATH = $(PLATFORM_PATH)/docker-sonic-p4
$(DOCKER_SONIC_P4)_DEPENDS += $(SWSS) $(SYNCD) $(P4_SWITCH) $(REDIS_SERVER) $(REDIS_TOOLS) $(QUAGGA) $(LIBTEAMDCT) $(LIBTEAM_UTILS)
$(DOCKER_SONIC_P4)_DEPENDS += $(SWSS) $(SYNCD) $(P4_SWITCH) $(REDIS_SERVER) $(REDIS_TOOLS) $(LIBTEAMDCT) $(LIBTEAM_UTILS)

ifeq ($(ROUTING_STACK), quagga)
$(DOCKER_SONIC_P4)_DEPENDS += $(QUAGGA)
else ifeq ($(ROUTING_STACK), frr)
$(DOCKER_SONIC_P4)_DEPENDS += $(FRR)
else
$(DOCKER_SONIC_P4)_DEPENDS += $(GOBGP)
endif

$(DOCKER_SONIC_P4)_LOAD_DOCKERS += $(DOCKER_BASE)
SONIC_DOCKER_IMAGES += $(DOCKER_SONIC_P4)
2 changes: 1 addition & 1 deletion platform/p4/docker-sonic-p4/Dockerfile.j2
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get update

RUN apt-get install -y net-tools ethtool tcpdump ifupdown bridge-utils python-ply libqt5core5a libqt5network5 libboost-program-options1.55.0 libboost-system1.55.0 libboost-thread1.55.0 libgmp10 libjudydebian1 libnanomsg0 libdaemon0 libjansson4 libjemalloc1 openssh-client openssh-server
RUN apt-get install -y net-tools ethtool tcpdump ifupdown bridge-utils python-ply libqt5core5a libqt5network5 libboost-program-options1.55.0 libboost-system1.55.0 libboost-thread1.55.0 libgmp10 libjudydebian1 libnanomsg0 libdaemon0 libjansson4 libjemalloc1 openssh-client openssh-server libc-ares2 iproute

COPY \
{% for deb in docker_sonic_p4_debs.split(' ') -%}
Expand Down
5 changes: 5 additions & 0 deletions rules/config
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,8 @@ DEFAULT_PASSWORD = YourPaSsWoRd
# SONIC_CONFIG_DEBUG - install debug packages
# Uncomment next line to enable:
# SONIC_CONFIG_DEBUG = y

# SONIC_ROUTING_STACK - specify the routing-stack being elected to drive SONiC's control-plane.
# Quagga will be the default routing-stack for all the SONiC platforms. Other supported
# routing-stacks: frr, gobgp.
SONIC_ROUTING_STACK = quagga
14 changes: 14 additions & 0 deletions rules/docker-fpm-frr.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# docker image for fpm-frr

DOCKER_FPM_FRR = docker-fpm-frr.gz
$(DOCKER_FPM_FRR)_PATH = $(DOCKERS_PATH)/docker-fpm-frr
$(DOCKER_FPM_FRR)_DEPENDS += $(FRR) $(SWSS)
$(DOCKER_FPM_FRR)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE)
SONIC_DOCKER_IMAGES += $(DOCKER_FPM_FRR)

$(DOCKER_FPM_FRR)_CONTAINER_NAME = bgp
$(DOCKER_FPM_FRR)_RUN_OPT += --net=host --privileged -t
$(DOCKER_FPM_FRR)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro

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

2 changes: 1 addition & 1 deletion rules/docker-fpm-gobgp.mk
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
DOCKER_FPM_GOBGP = docker-fpm-gobgp.gz
$(DOCKER_FPM_GOBGP)_PATH = $(DOCKERS_PATH)/docker-fpm-gobgp
$(DOCKER_FPM_GOBGP)_DEPENDS += $(GOBGP)
$(DOCKER_FPM_GOBGP)_LOAD_DOCKERS += $(DOCKER_FPM)
$(DOCKER_FPM_GOBGP)_LOAD_DOCKERS += $(DOCKER_FPM_QUAGGA)
SONIC_DOCKER_IMAGES += $(DOCKER_FPM_GOBGP)

$(DOCKER_FPM_GOBGP)_CONTAINER_NAME = bgp
Expand Down
Loading

0 comments on commit d30fbf1

Please sign in to comment.