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

[ConfigDB] Move all BGP configuration into DB #861

Merged
merged 5 commits into from
Aug 8, 2017
Merged
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
16 changes: 8 additions & 8 deletions dockers/docker-fpm-frr/bgpd.conf.j2
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ log facility local4
!
! bgp multiple-instance
!
router bgp {{ minigraph_bgp_asn }}
router bgp {{ DEVICE_METADATA['localhost']['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 #}
Expand Down Expand Up @@ -46,16 +46,16 @@ router bgp {{ minigraph_bgp_asn }}
{% endfor %}
{% endblock vlan_advertisement %}
{% block bgp_sessions %}
{% for bgp_session in minigraph_bgp %}
{% for neighbor_addr, bgp_session in BGP_NEIGHBOR.iteritems() %}
{% if bgp_session['asn'] != 0 %}
neighbor {{ bgp_session['addr'] }} remote-as {{ bgp_session['asn'] }}
neighbor {{ bgp_session['addr'] }} description {{ bgp_session['name'] }}
neighbor {{ neighbor_addr }} remote-as {{ bgp_session['asn'] }}
neighbor {{ neighbor_addr }} description {{ bgp_session['name'] }}
{% if minigraph_devices[inventory_hostname]['type'] == 'ToRRouter' %}
neighbor {{ bgp_session['addr'] }} allowas-in 1
neighbor {{ neighbor_addr }} allowas-in 1
{% endif %}
{% if bgp_session['addr'] | ipv6 %}
{% if neighbor_addr | ipv6 %}
address-family ipv6
neighbor {{ bgp_session['addr'] }} activate
neighbor {{ neighbor_addr }} activate
maximum-paths 64
exit-address-family
{% endif %}
Expand All @@ -66,5 +66,5 @@ router bgp {{ minigraph_bgp_asn }}
maximum-paths 64
!
route-map ISOLATE permit 10
set as-path prepend {{ minigraph_bgp_asn }}
set as-path prepend {{ DEVICE_METADATA['localhost']['bgp_asn'] }}
!
10 changes: 5 additions & 5 deletions dockers/docker-fpm-frr/isolate.j2
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ 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
router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }}
{% for neighbor_addr in BGP_NEIGHBOR %}
neighbor {{ neighbor_addr }} route-map ISOLATE out
{% endfor %}
exit
exit

{% for bgp_session in minigraph_bgp %}
clear ip bgp {{ bgp_session['addr'] }} soft out
{% for neighbor_addr in BGP_NEIGHBOR %}
clear ip bgp {{ neighbor_addr }} soft out
{% endfor %}
10 changes: 5 additions & 5 deletions dockers/docker-fpm-frr/unisolate.j2
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ 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
router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }}
{% for neighbor_ip in BGP_NEIGHBOR %}
no neighbor {{ neighbor_ip }} route-map ISOLATE out
{% endfor %}
exit
exit

{% for bgp_session in minigraph_bgp %}
clear ip bgp {{ bgp_session['addr'] }} soft out
{% for neighbor_ip in BGP_NEIGHBOR %}
clear ip bgp {{ neighbor_ip }} soft out
{% endfor %}
8 changes: 4 additions & 4 deletions dockers/docker-fpm-gobgp/gobgpd.conf.j2
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
[global.config]
as = {{ minigraph_bgp_asn }}
as = {{ DEVICE_METADATA['localhost']['bgp_asn'] }}
router-id = "{{ minigraph_lo_interfaces[0]['addr'] }}"
{% for bgp_session in minigraph_bgp %}
{% for neighbor_addr, bgp_session in BGP_NEIGHBOR.iteritems() %}
{% if bgp_session['asn'] != 0 %}
[[neighbors]]
[neighbors.config]
peer-as = {{ bgp_session['asn'] }}
neighbor-address = "{{ bgp_session['addr'] }}"
neighbor-address = "{{ neighbor_addr }}"
[neighbors.graceful-restart.config]
enabled = true
[[neighbors.afi-safis]]
[neighbors.afi-safis.config]
{% if bgp_session['addr'] | ipv6 %}
{% if neighbor_addr | ipv6 %}
afi-safi-name = "ipv6-unicast"
{% else %}
afi-safi-name = "ipv4-unicast"
Expand Down
20 changes: 0 additions & 20 deletions dockers/docker-fpm-gobgp/isolate.j2
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,3 @@

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 %}
19 changes: 0 additions & 19 deletions dockers/docker-fpm-gobgp/unisolate.j2
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,3 @@
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 %}
77 changes: 50 additions & 27 deletions dockers/docker-fpm-quagga/bgpcfgd
Original file line number Diff line number Diff line change
Expand Up @@ -6,37 +6,60 @@ import subprocess
import syslog
from swsssdk import ConfigDBConnector

# Returns BGP ASN as a string
def _get_bgp_asn_from_minigraph():
# Get BGP ASN from minigraph
proc = subprocess.Popen(
['sonic-cfggen', '-m', '/etc/sonic/minigraph.xml', '-v', 'minigraph_bgp_asn'],
stdout=subprocess.PIPE,
shell=False,
stderr=subprocess.STDOUT)
stdout = proc.communicate()[0]
proc.wait()
return stdout.rstrip('\n')

def bgp_config(asn, ip, config):
syslog.syslog(syslog.LOG_INFO, '[bgp cfgd] value for {} changed to {}'.format(ip, config))
# Currently dynamic config is supported only for bgp admin status
if config.has_key('admin_status'):
command_mod = 'no ' if config['admin_status'] == 'up' else ''
command = "vtysh -c 'configure terminal' -c 'router bgp {}' -c '{}neighbor {} shutdown'".format(asn, command_mod, ip)

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():
sub = ConfigDBConnector()
bgp_asn = _get_bgp_asn_from_minigraph()
handler = lambda table, key, data: bgp_config(bgp_asn, key, data)
sub.subscribe('BGP_NEIGHBOR', handler)
sub.connect()
sub.listen()

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

if __name__ == "__main__":
main()
30 changes: 15 additions & 15 deletions dockers/docker-fpm-quagga/bgpd.conf.j2
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ log facility local4
! enable password {# {{ en_passwd }} TODO: param needed #}
{% endblock system_init %}
!
{% if minigraph_bgp_asn is not none %}
{% if DEVICE_METADATA['localhost'].has_key('bgp_asn') %}
{% block bgp_init %}
!
! bgp multiple-instance
Expand All @@ -23,7 +23,7 @@ route-map FROM_BGP_SPEAKER_V4 permit 10
!
route-map TO_BGP_SPEAKER_V4 deny 10
!
router bgp {{ minigraph_bgp_asn }}
router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }}
bgp log-neighbor-changes
bgp bestpath as-path multipath-relax
{# Advertise graceful restart capability for ToR #}
Expand All @@ -50,32 +50,32 @@ router bgp {{ minigraph_bgp_asn }}
{% endfor %}
{% endblock vlan_advertisement %}
{% block bgp_sessions %}
{% for bgp_session in minigraph_bgp %}
{% for neighbor_addr, bgp_session in BGP_NEIGHBOR.iteritems() %}
{% if bgp_session['asn'] != 0 %}
neighbor {{ bgp_session['addr'] }} remote-as {{ bgp_session['asn'] }}
neighbor {{ bgp_session['addr'] }} description {{ bgp_session['name'] }}
{% if bgp_admin_state and bgp_admin_state.has_key(bgp_session['addr']) and bgp_admin_state[bgp_session['addr']]==False or bgp_admin_state and not bgp_admin_state.has_key(bgp_session['addr']) and bgp_admin_state.has_key('all') and bgp_admin_state['all']==False %}
neighbor {{ bgp_session['addr'] }} shutdown
neighbor {{ neighbor_addr }} remote-as {{ bgp_session['asn'] }}
neighbor {{ neighbor_addr }} description {{ bgp_session['name'] }}
{% 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 bgp_session['addr'] | ipv4 %}
{% if neighbor_addr | ipv4 %}
{% if minigraph_devices[inventory_hostname]['type'] == 'ToRRouter' %}
neighbor {{ bgp_session['addr'] }} allowas-in 1
neighbor {{ neighbor_addr }} allowas-in 1
{% endif %}
{% endif %}
{% if bgp_session['addr'] | ipv6 %}
{% if neighbor_addr | ipv6 %}
address-family ipv6
{% if minigraph_devices[inventory_hostname]['type'] == 'ToRRouter' %}
neighbor {{ bgp_session['addr'] }} allowas-in 1
neighbor {{ neighbor_addr }} allowas-in 1
{% endif %}
neighbor {{ bgp_session['addr'] }} activate
neighbor {{ neighbor_addr }} activate
maximum-paths 64
exit-address-family
{% endif %}
{% endif %}
{% endfor %}
{% endblock bgp_sessions %}
{% block bgp_peers_with_range %}
{% for bgp_peer in minigraph_bgp_peers_with_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[deployment_id] }}
Expand All @@ -90,10 +90,10 @@ router bgp {{ minigraph_bgp_asn }}
{% endfor %}
{% endblock bgp_peers_with_range %}
!
{% if minigraph_bgp_asn is not none %}
{% if DEVICE_METADATA['localhost'].has_key('bgp_asn') %}
maximum-paths 64
!
route-map ISOLATE permit 10
set as-path prepend {{ minigraph_bgp_asn }}
set as-path prepend {{ DEVICE_METADATA['localhost']['bgp_asn'] }}
{% endif %}
!
10 changes: 5 additions & 5 deletions dockers/docker-fpm-quagga/isolate.j2
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ 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
router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }}
{% for neighbor_addr in BGP_NEIGHBOR %}
neighbor {{ neighbor_addr }} route-map ISOLATE out
{% endfor %}
exit
exit

{% for bgp_session in minigraph_bgp %}
clear ip bgp {{ bgp_session['addr'] }} soft out
{% for neighbor_addr in BGP_NEIGHBOR %}
clear ip bgp {{ neighbor_addr }} soft out
{% endfor %}
6 changes: 3 additions & 3 deletions dockers/docker-fpm-quagga/start.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
mkdir -p /etc/quagga
sonic-cfggen -m -d -y /etc/sonic/deployment_id_asn_map.yml -t /usr/share/sonic/templates/bgpd.conf.j2 > /etc/quagga/bgpd.conf

sonic-cfggen -m /etc/sonic/minigraph.xml -t /usr/share/sonic/templates/zebra.conf.j2 > /etc/quagga/zebra.conf
sonic-cfggen -m -d -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
sonic-cfggen -m -d -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
sonic-cfggen -m -d -t /usr/share/sonic/templates/unisolate.j2 > /usr/sbin/bgp-unisolate
chown root:root /usr/sbin/bgp-unisolate
chmod 0755 /usr/sbin/bgp-unisolate

Expand Down
10 changes: 5 additions & 5 deletions dockers/docker-fpm-quagga/unisolate.j2
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ 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
router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }}
{% for neighbor_ip in BGP_NEIGHBOR %}
no neighbor {{ neighbor_ip }} route-map ISOLATE out
{% endfor %}
exit
exit

{% for bgp_session in minigraph_bgp %}
clear ip bgp {{ bgp_session['addr'] }} soft out
{% for neighbor_ip in BGP_NEIGHBOR %}
clear ip bgp {{ neighbor_ip }} soft out
{% endfor %}
2 changes: 1 addition & 1 deletion files/build_templates/sonic_debian_extension.j2
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ sudo bash -c "echo dhcp_as_static=true >> $FILESYSTEM_ROOT/etc/sonic/updategraph
sudo bash -c "echo enabled=false > $FILESYSTEM_ROOT/etc/sonic/updategraph.conf"
{% endif %}
{% if shutdown_bgp_on_start == "y" %}
sudo bash -c "echo '{ \"bgp_admin_state\": { \"all\": false } }' >> $FILESYSTEM_ROOT/etc/sonic/config_db.json"
sudo bash -c "echo '{ \"DEVICE_METADATA\": { \"localhost\": { \"default_bgp_status\": \"down\" } } }' >> $FILESYSTEM_ROOT/etc/sonic/init_cfg.json"
{% endif %}
# Copy SNMP configuration files
sudo cp $IMAGE_CONFIGS/snmp/snmp.yml $FILESYSTEM_ROOT/etc/sonic/
Expand Down
12 changes: 12 additions & 0 deletions files/image_config/platform/rc.local
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,20 @@ if [ -f /host/image-$sonic_version/platform/firsttime ]; then
mv -f /host/old_config/* /etc/sonic/
elif [ -f /host/minigraph.xml ]; then
mv /host/minigraph.xml /etc/sonic/
# Combine information in minigraph and init_cfg.json to form initiate config DB dump file.
# TODO: After moving all information from minigraph to DB, sample config DB dump should be provide
if [ -f /etc/sonic/init_cfg.json ]; then
sonic-cfggen -m -j /etc/sonic/init_cfg.json --print-data > /etc/sonic/config_db.json
else
sonic-cfggen -m --print-data > /etc/sonic/config_db.json
fi
else
cp /usr/share/sonic/device/$platform/minigraph.xml /etc/sonic/
if [ -f /etc/sonic/init_cfg.json ]; then
sonic-cfggen -m -j /etc/sonic/init_cfg.json --print-data > /etc/sonic/config_db.json
else
sonic-cfggen -m --print-data > /etc/sonic/config_db.json
fi
fi

if [ -d /host/image-$sonic_version/platform/$platform ]; then
Expand Down
Loading