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

Additions to vs docker to support teamd, bgp and configuring interfaces. #1962

Closed
wants to merge 18 commits into from
Closed
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
12 changes: 11 additions & 1 deletion platform/vs/docker-sonic-vs/Dockerfile.j2
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ RUN apt-get install -y net-tools \
python-tabulate \
bash-completion \
libelf1 \
libmnl0
libmnl0 \
lldpd

RUN pip install setuptools
RUN pip install py2_ipaddress
Expand Down Expand Up @@ -84,6 +85,15 @@ COPY ["supervisord.conf", "/etc/supervisor/conf.d/"]
COPY ["files/configdb-load.sh", "/usr/bin/"]
COPY ["files/arp_update", "/usr/bin"]

COPY ["interfaces.j2", "/usr/share/sonic/templates/"]
COPY ["deployment_id_asn_map.yml", "/etc/sonic/"]
COPY ["teamd.sh", "/usr/bin/"]
COPY ["teamd.j2", "/usr/share/sonic/templates/"]
COPY ["bgpcfgd", "/usr/bin/"]
COPY ["sonic_version.yml", "/etc/sonic/sonic_version.yml"]
COPY ["*.j2", "/usr/share/sonic/templates/"]
COPY ["minigraph.xml", "/etc/sonic/"]

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copied files. Keep them in sync with the latest by adding it to the makefile/rules.mk

RUN echo "docker-sonic-vs" > /etc/hostname
RUN touch /etc/quagga/zebra.conf

Expand Down
65 changes: 65 additions & 0 deletions platform/vs/docker-sonic-vs/bgpcfgd
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#!/usr/bin/env python

import sys
import redis
import subprocess
import syslog
from swsssdk import ConfigDBConnector

class BGPConfigDaemon:

def __init__(self):
self.config_db = ConfigDBConnector()
self.config_db.connect()
self.bgp_asn = self.config_db.get_entry('DEVICE_METADATA', 'localhost')['bgp_asn']
self.bgp_neighbor = self.config_db.get_table('BGP_NEIGHBOR')

def __run_command(self, command):
# print command
p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
stdout = p.communicate()[0]
p.wait()
if p.returncode != 0:
syslog.syslog(syslog.LOG_ERR, '[bgp cfgd] command execution returned {}. Command: "{}", stdout: "{}"'.format(p.returncode, command, stdout))

def metadata_handler(self, key, data):
if key == 'localhost' and data.has_key('bgp_asn'):
if data['bgp_asn'] != self.bgp_asn:
syslog.syslog(syslog.LOG_INFO, '[bgp cfgd] ASN changed to {} from {}, restart BGP...'.format(data['bgp_asn'], self.bgp_asn))
self.__run_command("supervisorctl restart start.sh")
self.__run_command("service quagga restart")
self.bgp_asn = data['bgp_asn']

def bgp_handler(self, key, data):
syslog.syslog(syslog.LOG_INFO, '[bgp cfgd] value for {} changed to {}'.format(key, data))
if not data:
# Neighbor is deleted
command = "vtysh -c 'configure terminal' -c 'router bgp {}' -c 'no neighbor {}'".format(self.bgp_asn, key)
self.__run_command(command)
self.bgp_neighbor.pop(key)
else:
command = "vtysh -c 'configure terminal' -c 'router bgp {}' -c 'neighbor {} remote-as {}'".format(self.bgp_asn, key, data['asn'])
self.__run_command(command)
if data.has_key('name'):
command = "vtysh -c 'configure terminal' -c 'router bgp {}' -c 'neighbor {} description {}'".format(self.bgp_asn, key, data['name'])
self.__run_command(command)
if data.has_key('admin_status'):
command_mod = 'no ' if data['admin_status'] == 'up' else ''
command = "vtysh -c 'configure terminal' -c 'router bgp {}' -c '{}neighbor {} shutdown'".format(self.bgp_asn, command_mod, key)
self.__run_command(command)
self.bgp_neighbor[key] = data

def start(self):
self.config_db.subscribe('BGP_NEIGHBOR',
lambda table, key, data: self.bgp_handler(key, data))
self.config_db.subscribe('DEVICE_METADATA',
lambda table, key, data: self.metadata_handler(key, data))
self.config_db.listen()


def main():
daemon = BGPConfigDaemon()
daemon.start()

if __name__ == "__main__":
main()
134 changes: 134 additions & 0 deletions platform/vs/docker-sonic-vs/bgpd.conf.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
!
{% block banner %}
! =========== Managed by sonic-cfggen DO NOT edit manually! ====================
! generated by templates/quagga/bgpd.conf.j2 with config DB data
! file: bgpd.conf
!
{% endblock banner %}
!
{% block system_init %}
hostname {{ DEVICE_METADATA['localhost']['hostname'] }}
password zebra
log syslog informational
log facility local4
! enable password {# {{ en_passwd }} TODO: param needed #}
{% endblock system_init %}
!
{% if DEVICE_METADATA['localhost'].has_key('bgp_asn') %}
{% block bgp_init %}
!
! bgp multiple-instance
!
route-map FROM_BGP_SPEAKER_V4 permit 10
!
route-map TO_BGP_SPEAKER_V4 deny 10
!
router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }}
bgp log-neighbor-changes
bgp bestpath as-path multipath-relax
no bgp default ipv4-unicast
{# Advertise graceful restart capability for ToR #}
{% if DEVICE_METADATA['localhost']['type'] == 'ToRRouter' %}
bgp graceful-restart
{% endif %}
{% for (name, prefix) in LOOPBACK_INTERFACE %}
{% if prefix | ipv4 and name == 'Loopback0' %}
bgp router-id {{ prefix | ip }}
{% endif %}
{% endfor %}
{# advertise loopback #}
{% for (name, prefix) in LOOPBACK_INTERFACE %}
{% if prefix | ipv4 and name == 'Loopback0' %}
network {{ prefix | ip }}/32
{% elif prefix | ipv6 and name == 'Loopback0' %}
address-family ipv6
network {{ prefix | ip }}/64
exit-address-family
{% endif %}
{% endfor %}
{% endblock bgp_init %}
{% endif %}
{% block vlan_advertisement %}
{% for (name, prefix) in VLAN_INTERFACE %}
{% if prefix | ipv4 %}
network {{ prefix }}
{% elif prefix | ipv6 %}
address-family ipv6
network {{ prefix }}
exit-address-family
{% endif %}
{% endfor %}
{% endblock vlan_advertisement %}
{% block bgp_sessions %}
{% for neighbor_addr, bgp_session in BGP_NEIGHBOR.iteritems() %}
{% 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
maximum-paths 64
exit-address-family
{% endif %}
{% if neighbor_addr | ipv6 %}
address-family ipv6
{% if DEVICE_METADATA['localhost']['type'] == 'ToRRouter' %}
neighbor {{ neighbor_addr }} allowas-in 1
{% endif %}
neighbor {{ neighbor_addr }} activate
neighbor {{ neighbor_addr }} soft-reconfiguration inbound
maximum-paths 64
exit-address-family
{% endif %}
{% endif %}
{% endfor %}
{% endblock bgp_sessions %}
{% block bgp_peers_with_range %}
{% if BGP_PEER_RANGE %}
{% for bgp_peer in BGP_PEER_RANGE.values() %}
neighbor {{ bgp_peer['name'] }} peer-group
neighbor {{ bgp_peer['name'] }} passive
neighbor {{ bgp_peer['name'] }} remote-as {{ deployment_id_asn_map[DEVICE_METADATA['localhost']['deployment_id']] }}
neighbor {{ bgp_peer['name'] }} ebgp-multihop 255
neighbor {{ bgp_peer['name'] }} soft-reconfiguration inbound
{% for (name, prefix) in LOOPBACK_INTERFACE %}
{% if name == 'Loopback1' %}
neighbor {{ bgp_peer['name'] }} update-source {{ prefix | ip }}
{% endif %}
{% endfor %}
neighbor {{ bgp_peer['name'] }} route-map FROM_BGP_SPEAKER_V4 in
neighbor {{ bgp_peer['name'] }} route-map TO_BGP_SPEAKER_V4 out
{% for ip_range in bgp_peer['ip_range'] %}
bgp listen range {{ip_range}} peer-group {{ bgp_peer['name'] }}
{% endfor %}
address-family ipv4
neighbor {{ bgp_peer['name'] }} activate
maximum-paths 64
exit-address-family
address-family ipv6
neighbor {{ bgp_peer['name'] }} activate
maximum-paths 64
exit-address-family
{% endfor %}
{% endif %}
{% endblock bgp_peers_with_range %}
!
{% if DEVICE_METADATA['localhost'].has_key('bgp_asn') %}
maximum-paths 64
!
route-map ISOLATE permit 10
set as-path prepend {{ DEVICE_METADATA['localhost']['bgp_asn'] }}
{% endif %}
!
2 changes: 2 additions & 0 deletions platform/vs/docker-sonic-vs/deployment_id_asn_map.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
deployment_id_asn_map:
"1" : 65432
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Find out what file to use instead of this dummy one.

66 changes: 66 additions & 0 deletions platform/vs/docker-sonic-vs/interfaces.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#
{% block banner %}
# =============== Managed by SONiC Config Engine DO NOT EDIT! ===============
# generated from /usr/share/sonic/templates/interfaces.j2 using sonic-cfggen
# file: /etc/network/interfaces
#
{% endblock banner %}
{% block loopback %}
# The loopback network interface
auto lo
iface lo inet loopback
# Use command 'ip addr list dev lo' to check all addresses
{% for (name, prefix) in LOOPBACK_INTERFACE %}
iface lo {{ 'inet' if prefix | ipv4 else 'inet6' }} static
address {{ prefix | ip }}
netmask {{ prefix | netmask if prefix | ipv4 else prefix | prefixlen }}
#
{% endfor %}
{% endblock loopback %}
{% block mgmt_interface %}

# The management network interface
auto eth0
{% if MGMT_INTERFACE %}
{% for (name, prefix) in MGMT_INTERFACE %}
iface eth0 {{ 'inet' if prefix | ipv4 else 'inet6' }} static
address {{ prefix | ip }}
netmask {{ prefix | netmask if prefix | ipv4 else prefix | prefixlen }}
########## management network policy routing rules
# management port up rules
up ip {{ '-4' if prefix | ipv4 else '-6' }} route add default via {{ MGMT_INTERFACE[(name, prefix)]['gwaddr'] }} dev eth0 table default
up ip {{ '-4' if prefix | ipv4 else '-6' }} route add {{ prefix | network }}/{{ prefix | prefixlen }} dev eth0 table default
up ip {{ '-4' if prefix | ipv4 else '-6' }} rule add from {{ prefix | ip }}/{{ '32' if prefix | ipv4 else '128' }} table default
{% for route in MGMT_INTERFACE[(name, prefix)]['forced_mgmt_routes'] %}
up ip rule add to {{ route }} table default
{% endfor %}
# management port down rules
down ip {{ '-4' if prefix | ipv4 else '-6' }} route delete default via {{ MGMT_INTERFACE[(name, prefix)]['gwaddr'] }} dev eth0 table default
down ip {{ '-4' if prefix | ipv4 else '-6' }} route delete {{ prefix | network }}/{{ prefix | prefixlen }} dev eth0 table default
down ip {{ '-4' if prefix | ipv4 else '-6' }} rule delete from {{ prefix | ip }}/{{ '32' if prefix | ipv4 else '128' }} table default
{% for route in MGMT_INTERFACE[(name, prefix)]['forced_mgmt_routes'] %}
down ip rule delete to {{ route }} table default
{% endfor %}
{# TODO: COPP policy type rules #}
{% endfor %}
{% else %}
iface eth0 inet dhcp
{% endif %}
#
{% endblock mgmt_interface %}
{% block front_panel_interfaces %}
{% if PORTCHANNEL %}
# "|| true" is added to suppress the error when interface is already a member of LAG
# "ip link show | grep -q master" is added to ensure interface is enslaved
{% for pc in PORTCHANNEL.keys()|sort %}
{% for member in PORTCHANNEL[pc]['members'] %}
allow-hotplug {{ member }}
iface {{ member }} inet manual
pre-up teamdctl {{ pc }} port add {{ member }} || true
post-up ip link show {{ member }} | grep -q master && ifconfig {{ member }} up
post-down ifconfig {{ member }} down
#
{% endfor %}
{% endfor %}
{% endif %}
{% endblock front_panel_interfaces %}
20 changes: 20 additions & 0 deletions platform/vs/docker-sonic-vs/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 equal in 'sed' command above

configure terminal
router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }}
{% for neighbor_addr in BGP_NEIGHBOR %}
neighbor {{ neighbor_addr }} route-map ISOLATE out
{% endfor %}
exit
exit

{% for neighbor_addr in BGP_NEIGHBOR %}
clear ip bgp {{ neighbor_addr }} soft out
{% endfor %}
Empty file.
8 changes: 8 additions & 0 deletions platform/vs/docker-sonic-vs/sonic_version.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
ld_version: 'refs_tags_20180324.02'
debian_version: '8.10'
kernel_version: '3.16.0-5-amd64'
asic_type: broadcom
commit_id: 'f12620c'
build_date: Tue Mar 27 01:53:07 UTC 2018
build_number: 353
built_by: sonicbld@jenkins-slave-phx-2
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generat this off the main branch. Don't check it in.

Loading