From bac738f91f785f2db84d5e754214b2e328008f81 Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Thu, 2 Mar 2017 11:33:46 -0800 Subject: [PATCH] Add bgp container with gobgp (#358) * Add go-1.7 into docker-slave * Create container docker-fpm-gobgp with gobgpd inside --- dockers/docker-fpm-gobgp/Dockerfile.j2 | 31 ++++++++++++ dockers/docker-fpm-gobgp/config.sh | 17 +++++++ dockers/docker-fpm-gobgp/daemons | 31 ++++++++++++ dockers/docker-fpm-gobgp/gobgpd.conf.j2 | 28 +++++++++++ dockers/docker-fpm-gobgp/isolate.j2 | 24 +++++++++ dockers/docker-fpm-gobgp/start.sh | 5 ++ dockers/docker-fpm-gobgp/supervisord.conf | 6 +++ dockers/docker-fpm-gobgp/unisolate.j2 | 24 +++++++++ dockers/docker-fpm-gobgp/zebra.conf.j2 | 61 +++++++++++++++++++++++ rules/docker-fpm-gobgp.mk | 14 ++++++ rules/gobgp.mk | 5 ++ sonic-slave/Dockerfile | 4 ++ src/gobgp/Makefile | 23 +++++++++ src/gobgp/debian/changelog | 5 ++ src/gobgp/debian/compat | 1 + src/gobgp/debian/control | 12 +++++ src/gobgp/debian/gobgp.dirs | 1 + src/gobgp/debian/gobgp.init.d | 50 +++++++++++++++++++ src/gobgp/debian/gobgp.service | 16 ++++++ src/gobgp/debian/rules | 3 ++ src/gobgp/gobgpd.conf.sample | 21 ++++++++ 21 files changed, 382 insertions(+) create mode 100644 dockers/docker-fpm-gobgp/Dockerfile.j2 create mode 100755 dockers/docker-fpm-gobgp/config.sh create mode 100644 dockers/docker-fpm-gobgp/daemons create mode 100644 dockers/docker-fpm-gobgp/gobgpd.conf.j2 create mode 100755 dockers/docker-fpm-gobgp/isolate.j2 create mode 100755 dockers/docker-fpm-gobgp/start.sh create mode 100644 dockers/docker-fpm-gobgp/supervisord.conf create mode 100755 dockers/docker-fpm-gobgp/unisolate.j2 create mode 100644 dockers/docker-fpm-gobgp/zebra.conf.j2 create mode 100644 rules/docker-fpm-gobgp.mk create mode 100644 rules/gobgp.mk create mode 100644 src/gobgp/Makefile create mode 100644 src/gobgp/debian/changelog create mode 100644 src/gobgp/debian/compat create mode 100644 src/gobgp/debian/control create mode 100644 src/gobgp/debian/gobgp.dirs create mode 100644 src/gobgp/debian/gobgp.init.d create mode 100644 src/gobgp/debian/gobgp.service create mode 100755 src/gobgp/debian/rules create mode 100644 src/gobgp/gobgpd.conf.sample diff --git a/dockers/docker-fpm-gobgp/Dockerfile.j2 b/dockers/docker-fpm-gobgp/Dockerfile.j2 new file mode 100644 index 0000000000..3d89999d97 --- /dev/null +++ b/dockers/docker-fpm-gobgp/Dockerfile.j2 @@ -0,0 +1,31 @@ +FROM docker-fpm + +## Make apt-get non-interactive +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update && apt-get install -y supervisor + +COPY \ +{% for deb in docker_fpm_gobgp_debs.split(' ') -%} +debs/{{ deb }}{{' '}} +{%- endfor -%} +debs/ + +RUN dpkg -i \ +{% for deb in docker_fpm_gobgp_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/quagga/"] +COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf + +ENTRYPOINT /usr/bin/config.sh \ + && /usr/bin/start.sh \ + && /usr/bin/supervisord \ + && /bin/bash diff --git a/dockers/docker-fpm-gobgp/config.sh b/dockers/docker-fpm-gobgp/config.sh new file mode 100755 index 0000000000..07aa8c33ee --- /dev/null +++ b/dockers/docker-fpm-gobgp/config.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +mkdir -p /etc/quagga +sonic-cfggen -m /etc/sonic/minigraph.xml -t /usr/share/sonic/templates/gobgpd.conf.j2 >/etc/gobgp/gobgpd.conf +sonic-cfggen -m /etc/sonic/minigraph.xml -t /usr/share/sonic/templates/zebra.conf.j2 >/etc/quagga/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 + diff --git a/dockers/docker-fpm-gobgp/daemons b/dockers/docker-fpm-gobgp/daemons new file mode 100644 index 0000000000..6832c3db78 --- /dev/null +++ b/dockers/docker-fpm-gobgp/daemons @@ -0,0 +1,31 @@ +# This file tells the quagga package which daemons to start. +# +# Entries are in the format: =(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=no +ospfd=no +ospf6d=no +ripd=no +ripngd=no +isisd=no +babeld=no diff --git a/dockers/docker-fpm-gobgp/gobgpd.conf.j2 b/dockers/docker-fpm-gobgp/gobgpd.conf.j2 new file mode 100644 index 0000000000..adbc063cfc --- /dev/null +++ b/dockers/docker-fpm-gobgp/gobgpd.conf.j2 @@ -0,0 +1,28 @@ +[global.config] + as = {{ minigraph_bgp_asn }} + router-id = "{{ minigraph_lo_interfaces[0]['addr'] }}" +{% for bgp_session in minigraph_bgp %} +{% if bgp_session['asn'] != 0 %} +[[neighbors]] + [neighbors.config] + peer-as = {{ bgp_session['asn'] }} + neighbor-address = "{{ bgp_session['addr'] }}" + [neighbors.graceful-restart.config] + enabled = true + [[neighbors.afi-safis]] + [neighbors.afi-safis.config] +{% if bgp_session['addr'] | ipv6 %} + afi-safi-name = "ipv6-unicast" +{% else %} + afi-safi-name = "ipv4-unicast" +{% endif %} + [neighbors.afi-safis.mp-graceful-restart.config] + enabled = true +{% endif %} +{% endfor %} +[zebra] + [zebra.config] + enabled = true + url = "unix:/var/run/quagga/zserv.api" + redistribute-route-type-list = ["connect"] + diff --git a/dockers/docker-fpm-gobgp/isolate.j2 b/dockers/docker-fpm-gobgp/isolate.j2 new file mode 100755 index 0000000000..e587623e98 --- /dev/null +++ b/dockers/docker-fpm-gobgp/isolate.j2 @@ -0,0 +1,24 @@ +#!/bin/bash + +echo Not implemented yet +exit + +## 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 %} diff --git a/dockers/docker-fpm-gobgp/start.sh b/dockers/docker-fpm-gobgp/start.sh new file mode 100755 index 0000000000..90a1d515fa --- /dev/null +++ b/dockers/docker-fpm-gobgp/start.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +service rsyslog start +service quagga start +fpmsyncd & diff --git a/dockers/docker-fpm-gobgp/supervisord.conf b/dockers/docker-fpm-gobgp/supervisord.conf new file mode 100644 index 0000000000..793fc5434f --- /dev/null +++ b/dockers/docker-fpm-gobgp/supervisord.conf @@ -0,0 +1,6 @@ +[supervisord] +nodaemon=true + +[program:gobgpd] +command=/usr/sbin/gobgpd -p -f /etc/gobgp/gobgpd.conf -r +priority=1 diff --git a/dockers/docker-fpm-gobgp/unisolate.j2 b/dockers/docker-fpm-gobgp/unisolate.j2 new file mode 100755 index 0000000000..d1310114d9 --- /dev/null +++ b/dockers/docker-fpm-gobgp/unisolate.j2 @@ -0,0 +1,24 @@ +#!/bin/bash + +echo Not implemented yet +exit + +## 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 %} diff --git a/dockers/docker-fpm-gobgp/zebra.conf.j2 b/dockers/docker-fpm-gobgp/zebra.conf.j2 new file mode 100644 index 0000000000..ad05dcbe4e --- /dev/null +++ b/dockers/docker-fpm-gobgp/zebra.conf.j2 @@ -0,0 +1,61 @@ +! +{% 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 %} +{% 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 %} +! + diff --git a/rules/docker-fpm-gobgp.mk b/rules/docker-fpm-gobgp.mk new file mode 100644 index 0000000000..eb9406ec0b --- /dev/null +++ b/rules/docker-fpm-gobgp.mk @@ -0,0 +1,14 @@ +# docker image for fpm-gobgp + +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) +SONIC_DOCKER_IMAGES += $(DOCKER_FPM_GOBGP) +SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_FPM_GOBGP) + +$(DOCKER_FPM_GOBGP)_CONTAINER_NAME = bgp +$(DOCKER_FPM_GOBGP)_RUN_OPT += --net=host --privileged -t +$(DOCKER_FPM_GOBGP)_RUN_OPT += --volumes-from database +$(DOCKER_FPM_GOBGP)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro + diff --git a/rules/gobgp.mk b/rules/gobgp.mk new file mode 100644 index 0000000000..5ce566f7b6 --- /dev/null +++ b/rules/gobgp.mk @@ -0,0 +1,5 @@ +# gobgp package + +GOBGP = gobgp_1.16-01_amd64.deb +$(GOBGP)_SRC_PATH = $(SRC_PATH)/gobgp +SONIC_DPKG_DEBS += $(GOBGP) diff --git a/sonic-slave/Dockerfile b/sonic-slave/Dockerfile index 03f38a06c2..b436c5199d 100644 --- a/sonic-slave/Dockerfile +++ b/sonic-slave/Dockerfile @@ -6,6 +6,7 @@ RUN echo "deb http://debian-archive.trafficmanager.net/debian/ jessie main contr RUN echo "deb-src http://debian-archive.trafficmanager.net/debian/ jessie main contrib non-free" >> /etc/apt/sources.list RUN echo "deb http://debian-archive.trafficmanager.net/debian-security/ jessie/updates main contrib non-free" >> /etc/apt/sources.list RUN echo "deb-src http://debian-archive.trafficmanager.net/debian-security/ jessie/updates main contrib non-free" >> /etc/apt/sources.list +RUN echo 'deb http://debian-archive.trafficmanager.net/debian jessie-backports main' >> /etc/apt/sources.list ## Make apt-get non-interactive ENV DEBIAN_FRONTEND=noninteractive @@ -70,6 +71,9 @@ RUN apt-get update && apt-get install -y dkms # For python3.5 build RUN apt-get update && apt-get install -y sharutils libncursesw5-dev libbz2-dev liblzma-dev libgdbm-dev tk-dev blt-dev libmpdec-dev libbluetooth-dev locales libsqlite3-dev libgpm2 time net-tools xvfb python-sphinx python3-sphinx +# For gobgp build +RUN apt-get -yt jessie-backports install golang-go + RUN mkdir /var/run/sshd EXPOSE 22 diff --git a/src/gobgp/Makefile b/src/gobgp/Makefile new file mode 100644 index 0000000000..ec0bdc74f0 --- /dev/null +++ b/src/gobgp/Makefile @@ -0,0 +1,23 @@ +export GOPATH=/tmp/go + +INSTALL := /usr/bin/install + +all: gobgp gobgpd + +gobgpd: + go get -v github.com/osrg/gobgp/gobgpd + +gobgp: + go get -v github.com/osrg/gobgp/gobgp + +install: + $(INSTALL) -D ${GOPATH}/bin/gobgp $(DESTDIR)/usr/bin/gobgp + $(INSTALL) -D ${GOPATH}/bin/gobgpd $(DESTDIR)/usr/sbin/gobgpd + $(INSTALL) -D gobgpd.conf.sample $(DESTDIR)/etc/gobgp/gobgpd.conf.sample + +deinstall: + rm $(DESTDIR)/usr/bin/gobgp + rm $(DESTDIR)/usr/sbin/gobgpd + +clean: + rm -fr ${GOPATH} diff --git a/src/gobgp/debian/changelog b/src/gobgp/debian/changelog new file mode 100644 index 0000000000..ba412cc45e --- /dev/null +++ b/src/gobgp/debian/changelog @@ -0,0 +1,5 @@ +gobgp (1.16-01) UNRELEASED; urgency=low + + * Initial release. + + -- Pavel Shirshov Sat, 25 Feb 2017 00:25:19 +0000 diff --git a/src/gobgp/debian/compat b/src/gobgp/debian/compat new file mode 100644 index 0000000000..ec635144f6 --- /dev/null +++ b/src/gobgp/debian/compat @@ -0,0 +1 @@ +9 diff --git a/src/gobgp/debian/control b/src/gobgp/debian/control new file mode 100644 index 0000000000..7d534852a3 --- /dev/null +++ b/src/gobgp/debian/control @@ -0,0 +1,12 @@ +Source: gobgp +Maintainer: Pavel Shirshov +Build-Depends: debhelper (>= 8.0.0), + dh-systemd +Standards-Version: 3.9.3 +Section: net + +Package: gobgp +Priority: extra +Architecture: amd64 +Depends: ${shlibs:Depends}, ${misc:Depends} +Description: gobgp BGP daemon diff --git a/src/gobgp/debian/gobgp.dirs b/src/gobgp/debian/gobgp.dirs new file mode 100644 index 0000000000..3e9f1c594d --- /dev/null +++ b/src/gobgp/debian/gobgp.dirs @@ -0,0 +1 @@ +etc/gobgp diff --git a/src/gobgp/debian/gobgp.init.d b/src/gobgp/debian/gobgp.init.d new file mode 100644 index 0000000000..189fdad056 --- /dev/null +++ b/src/gobgp/debian/gobgp.init.d @@ -0,0 +1,50 @@ +#!/bin/bash +# +### BEGIN INIT INFO +# Provides: gobgp +# Required-Start: $local_fs $network $remote_fs $syslog +# Required-Stop: $local_fs $network $remote_fs $syslog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: start and stop the gobgpd +# Description: gobgpd is an implementation of bgp daemon in Go +### END INIT INFO +# + +PATH=/bin:/usr/bin:/sbin:/usr/sbin +D_PATH=/usr/sbin +C_PATH=/etc/gobgp + +. /lib/lsb/init-functions + +######################################################### +# Main program # +######################################################### + +case "$1" in + start) + if [ -f /etc/gobgp/gobgpd.conf ] + then + /usr/sbin/gobgpd -f /etc/gobgp/gobgpd.conf -r + echo $! > /var/run/gobgpd.pid + else + echo /etc/gobgp/gobgpd.conf not found + fi + ;; + + stop) + kill -9 $(echo /var/run/gobgpd.pid) + ;; + + restart|force-reload) + $0 stop $2 + sleep 1 + $0 start $2 + ;; + *) + echo "Usage: /etc/init.d/gobgp {start|stop|restart|force-reload}" + exit 1 + ;; +esac + +exit 0 diff --git a/src/gobgp/debian/gobgp.service b/src/gobgp/debian/gobgp.service new file mode 100644 index 0000000000..68a0b595aa --- /dev/null +++ b/src/gobgp/debian/gobgp.service @@ -0,0 +1,16 @@ +[Unit] +Description=gobgp service +After=network.target +ConditionPathExists=/etc/gobgp/gobgpd.yml + +[Service] +EnvironmentFile=-/etc/default/gobgp +ExecStart=/usr/sbin/gobgpd $DAEMON_ARGS +#ExecReload=/bin/kill -HUP $MAINPID +KillMode=process +Restart=on-failure + +[Install] +WantedBy=multi-user.target +Alias=gobgpd.service + diff --git a/src/gobgp/debian/rules b/src/gobgp/debian/rules new file mode 100755 index 0000000000..b6bee2ee4e --- /dev/null +++ b/src/gobgp/debian/rules @@ -0,0 +1,3 @@ +#!/usr/bin/make -f +%: + dh $@ --with systemd diff --git a/src/gobgp/gobgpd.conf.sample b/src/gobgp/gobgpd.conf.sample new file mode 100644 index 0000000000..c308df15be --- /dev/null +++ b/src/gobgp/gobgpd.conf.sample @@ -0,0 +1,21 @@ +[global.config] + as = 65501 + router-id = "192.168.0.1" +[[neighbors]] + [neighbors.config] + peer-as = 65502 + neighbor-address = "192.168.0.2" + [neighbors.graceful-restart.config] + enabled = true + restart-time = 120 + [[neighbors.afi-safis]] + [neighbors.afi-safis.config] + afi-safi-name = "ipv4-unicast" + [neighbors.afi-safis.mp-graceful-restart.config] + enabled = true + +[zebra] + [zebra.config] + enabled = true + url = "unix:/var/run/quagga/zserv.api" + redistribute-route-type-list = ["connect"]