[bgpcfgd]: Generate set src configuration dynamically (#4273)
* [bgpcfgd]: Generate set src configuration dynamically Sometimes zebra starts faster then swss configures Loopback0 In this case "set src" inside of the route map will not be inserted to the configuration because zebra doesn't see Loopback ips in the list of available ip addresses. I've added extra logic to push the "set src" configuration only when Loopback has been configured by swss.
This commit is contained in:
parent
6c48a3f113
commit
a881a23908
@ -78,6 +78,8 @@ class BGPConfigManager(object):
|
|||||||
def __init__(self, daemon):
|
def __init__(self, daemon):
|
||||||
self.bgp_asn = None
|
self.bgp_asn = None
|
||||||
self.meta = None
|
self.meta = None
|
||||||
|
self.lo_ipv4 = None
|
||||||
|
self.lo_ipv6 = None
|
||||||
self.neig_meta = {}
|
self.neig_meta = {}
|
||||||
self.bgp_messages = []
|
self.bgp_messages = []
|
||||||
self.peers = self.load_peers() # we can have bgp monitors peers here. it could be fixed by adding support for it here
|
self.peers = self.load_peers() # we can have bgp monitors peers here. it could be fixed by adding support for it here
|
||||||
@ -86,9 +88,11 @@ class BGPConfigManager(object):
|
|||||||
self.bgp_peer_del_template = fabric.from_string('no neighbor {{ neighbor_addr }}')
|
self.bgp_peer_del_template = fabric.from_string('no neighbor {{ neighbor_addr }}')
|
||||||
self.bgp_peer_shutdown = fabric.from_string('neighbor {{ neighbor_addr }} shutdown')
|
self.bgp_peer_shutdown = fabric.from_string('neighbor {{ neighbor_addr }} shutdown')
|
||||||
self.bgp_peer_no_shutdown = fabric.from_string('no neighbor {{ neighbor_addr }} shutdown')
|
self.bgp_peer_no_shutdown = fabric.from_string('no neighbor {{ neighbor_addr }} shutdown')
|
||||||
|
self.zebra_set_src_template = fabric.from_file('zebra.set_src.conf.j2')
|
||||||
daemon.add_manager(swsscommon.CONFIG_DB, swsscommon.CFG_DEVICE_METADATA_TABLE_NAME, self.__metadata_handler)
|
daemon.add_manager(swsscommon.CONFIG_DB, swsscommon.CFG_DEVICE_METADATA_TABLE_NAME, self.__metadata_handler)
|
||||||
daemon.add_manager(swsscommon.CONFIG_DB, swsscommon.CFG_DEVICE_NEIGHBOR_METADATA_TABLE_NAME, self.__neighbor_metadata_handler)
|
daemon.add_manager(swsscommon.CONFIG_DB, swsscommon.CFG_DEVICE_NEIGHBOR_METADATA_TABLE_NAME, self.__neighbor_metadata_handler)
|
||||||
daemon.add_manager(swsscommon.CONFIG_DB, swsscommon.CFG_BGP_NEIGHBOR_TABLE_NAME, self.__bgp_handler)
|
daemon.add_manager(swsscommon.CONFIG_DB, swsscommon.CFG_BGP_NEIGHBOR_TABLE_NAME, self.__bgp_handler)
|
||||||
|
daemon.add_manager(swsscommon.STATE_DB, swsscommon.STATE_INTERFACE_TABLE_NAME, self.__if_handler)
|
||||||
|
|
||||||
def load_peers(self):
|
def load_peers(self):
|
||||||
peers = set()
|
peers = set()
|
||||||
@ -136,6 +140,35 @@ class BGPConfigManager(object):
|
|||||||
syslog.syslog(syslog.LOG_ERR,"Wrong operation '%s' for neighbor metadata handler" % op)
|
syslog.syslog(syslog.LOG_ERR,"Wrong operation '%s' for neighbor metadata handler" % op)
|
||||||
self.__update_bgp()
|
self.__update_bgp()
|
||||||
|
|
||||||
|
def __if_handler(self, key, op, data):
|
||||||
|
cmds = []
|
||||||
|
if op == swsscommon.SET_COMMAND and key.startswith("Loopback0|") and "state" in data and data["state"] == "ok":
|
||||||
|
ip_addr_w_mask = key.replace("Loopback0|", "")
|
||||||
|
slash_pos = ip_addr_w_mask.rfind("/")
|
||||||
|
if slash_pos == -1:
|
||||||
|
syslog.syslog(syslog.LOG_ERR, "Wrong Loopback0 ip address'%s'" % ip_addr_w_mask)
|
||||||
|
return
|
||||||
|
ip_addr = ip_addr_w_mask[:slash_pos]
|
||||||
|
try:
|
||||||
|
if TemplateFabric.is_ipv4(ip_addr) and self.lo_ipv4 is None:
|
||||||
|
self.lo_ipv4 = ip_addr
|
||||||
|
txt = self.zebra_set_src_template.render(rm_name="RM_SET_SRC", lo_ip=ip_addr, ip_proto="")
|
||||||
|
elif TemplateFabric.is_ipv6(ip_addr) and self.lo_ipv6 is None:
|
||||||
|
self.lo_ipv6 = ip_addr
|
||||||
|
txt = self.zebra_set_src_template.render(rm_name="RM_SET_SRC6", lo_ip=ip_addr, ip_proto="v6")
|
||||||
|
else:
|
||||||
|
syslog.syslog(syslog.LOG_ERR, "Got ambigous ip addres '%s'" % ip_addr)
|
||||||
|
except:
|
||||||
|
syslog.syslog(syslog.LOG_ERR, "Error while rendering set src template" % ip_addr)
|
||||||
|
else:
|
||||||
|
cmds.append(txt)
|
||||||
|
syslog.syslog(syslog.LOG_INFO, "Generate set src configuration with Loopback0 ipv4 '%s'" % ip_addr)
|
||||||
|
elif op == swsscommon.DEL_COMMAND:
|
||||||
|
syslog.syslog(syslog.LOG_INFO, "Delete command is not supported for set src templates" % ip_addr)
|
||||||
|
|
||||||
|
for cmd in cmds:
|
||||||
|
self.__apply_cmd(cmd, zebra=True)
|
||||||
|
|
||||||
def __update_bgp(self):
|
def __update_bgp(self):
|
||||||
cmds = []
|
cmds = []
|
||||||
new_bgp_messages = []
|
new_bgp_messages = []
|
||||||
@ -180,7 +213,7 @@ class BGPConfigManager(object):
|
|||||||
for cmd in cmds:
|
for cmd in cmds:
|
||||||
self.__apply_cmd(cmd)
|
self.__apply_cmd(cmd)
|
||||||
|
|
||||||
def __apply_cmd(self, cmd):
|
def __apply_cmd(self, cmd, zebra=False):
|
||||||
lines = [line for line in cmd.split("\n") if not line.startswith('!') and line.strip() != ""]
|
lines = [line for line in cmd.split("\n") if not line.startswith('!') and line.strip() != ""]
|
||||||
if len(lines) == 0:
|
if len(lines) == 0:
|
||||||
return
|
return
|
||||||
@ -198,7 +231,11 @@ class BGPConfigManager(object):
|
|||||||
chunks.pop()
|
chunks.pop()
|
||||||
chunks.append(line.strip())
|
chunks.append(line.strip())
|
||||||
|
|
||||||
command = ["vtysh", "-c", "conf t", "-c", "router bgp %s" % self.bgp_asn]
|
command = ["vtysh", "-c", "conf t"]
|
||||||
|
if not zebra:
|
||||||
|
command.append("-c")
|
||||||
|
command.append("router bgp %s" % self.bgp_asn)
|
||||||
|
|
||||||
for chunk in chunks:
|
for chunk in chunks:
|
||||||
command.append("-c")
|
command.append("-c")
|
||||||
command.append(chunk)
|
command.append(chunk)
|
||||||
@ -213,7 +250,7 @@ class BGPConfigManager(object):
|
|||||||
|
|
||||||
class Daemon(object):
|
class Daemon(object):
|
||||||
SELECT_TIMEOUT = 1000
|
SELECT_TIMEOUT = 1000
|
||||||
DATABASE_LIST = [ swsscommon.CONFIG_DB ]
|
DATABASE_LIST = [ swsscommon.CONFIG_DB, swsscommon.STATE_DB ]
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.db_connectors = { db : swsscommon.DBConnector(db, swsscommon.DBConnector.DEFAULT_UNIXSOCKET, 0) for db in Daemon.DATABASE_LIST }
|
self.db_connectors = { db : swsscommon.DBConnector(db, swsscommon.DBConnector.DEFAULT_UNIXSOCKET, 0) for db in Daemon.DATABASE_LIST }
|
||||||
|
@ -35,41 +35,6 @@ ip route 0.0.0.0/0 {{ MGMT_INTERFACE[(name, prefix)]['gwaddr'] }} 200
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endblock default_route %}
|
{% endblock default_route %}
|
||||||
!
|
!
|
||||||
{% block source_loopback %}
|
|
||||||
{% set lo_ipv4_addrs = [] %}
|
|
||||||
{% set lo_ipv6_addrs = [] %}
|
|
||||||
{% if LOOPBACK_INTERFACE %}
|
|
||||||
{% for (name, prefix) in LOOPBACK_INTERFACE %}
|
|
||||||
{% if name == 'Loopback0' %}
|
|
||||||
{% if prefix | ipv6 %}
|
|
||||||
{% if lo_ipv6_addrs.append(prefix) %}
|
|
||||||
{% endif %}
|
|
||||||
{% else %}
|
|
||||||
{% if lo_ipv4_addrs.append(prefix) %}
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
{% endif %}
|
|
||||||
! Set ip source to loopback for bgp learned routes
|
|
||||||
{% if lo_ipv4_addrs|length > 0 -%}
|
|
||||||
route-map RM_SET_SRC permit 10
|
|
||||||
set src {{ lo_ipv4_addrs[0] | ip }}
|
|
||||||
!
|
|
||||||
{% endif %}
|
|
||||||
{% if lo_ipv6_addrs|length > 0 %}
|
|
||||||
route-map RM_SET_SRC6 permit 10
|
|
||||||
set src {{ lo_ipv6_addrs[0] | ip }}
|
|
||||||
!
|
|
||||||
{% 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 %}
|
{% block logging %}
|
||||||
log syslog informational
|
log syslog informational
|
||||||
log facility local4
|
log facility local4
|
||||||
|
8
dockers/docker-fpm-quagga/zebra.set_src.conf.j2
Normal file
8
dockers/docker-fpm-quagga/zebra.set_src.conf.j2
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
!
|
||||||
|
! Set ip source to loopback for bgp learned routes
|
||||||
|
!
|
||||||
|
route-map {{ rm_name }} permit 10
|
||||||
|
set src {{ lo_ip }}
|
||||||
|
!
|
||||||
|
ip{{ ip_proto }} protocol bgp route-map {{ rm_name }}
|
||||||
|
!
|
@ -25,19 +25,6 @@ link-detect
|
|||||||
! set static default route to mgmt gateway as a backup to learned default
|
! 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
|
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 syslog informational
|
||||||
log facility local4
|
log facility local4
|
||||||
!
|
!
|
||||||
|
Loading…
Reference in New Issue
Block a user