[chassis] Add templates and code to support VoQ chassis iBGP peers (#5622)

This commit has following changes:

* Add templates and code to support VoQ chassis iBGP peers

* Add support to convert a new VoQChassisInternal element in the
   BGPSession element of the minigraph to a new BGP_VOQ_CHASSIS_NEIGHBOR 
   table in CONFIG_DB.
* Add a new set of "voq_chassis" templates to docker-fpm-frr
* Add a new BGP peer manager to bgpcfgd to add neighbors from the
  BGP_VOQ_CHASSIS_NEIGHBOR table using the voq_chassis templates.
* Add a test case for minigraph.py, making sure the VoQChassisInternal
  element creates a BGP_VOQ_CHASSIS_NEIGHBOR entry, but not if its
  value is "false".
* Add a set of test cases for the new voq_chassis templates in
  sonic-bgpcfgd tests.

Note that the templates expect the new
"bgp bestpath peer-type multipath-relax" bgpd configuration to be
available.

Signed-off-by: Joanne Mikkelson <jmmikkel@arista.com>
This commit is contained in:
jmmikkel 2021-04-16 11:11:32 -07:00 committed by GitHub
parent 534a5b8093
commit 43342b33b8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 478 additions and 43 deletions

View File

@ -0,0 +1,35 @@
!
! template: bgpd/templates/voq_chassis/instance.conf.j2
!
bgp bestpath as-path multipath-relax
bgp bestpath peer-type multipath-relax
!
neighbor {{ neighbor_addr }} peer-group VOQ_CHASSIS_PEER
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'] | default("60") }} {{ bgp_session['holdtime'] | default("180") }}
{% endif %}
!
{% if 'admin_status' in bgp_session and bgp_session['admin_status'] == 'down' or 'admin_status' not in bgp_session and 'default_bgp_status' in CONFIG_DB__DEVICE_METADATA['localhost'] and CONFIG_DB__DEVICE_METADATA['localhost']['default_bgp_status'] == 'down' %}
neighbor {{ neighbor_addr }} shutdown
{% endif %}
!
address-family ipv4
{% if constants.bgp.maximum_paths.enabled is defined and constants.bgp.maximum_paths.enabled %}
maximum-paths ibgp {{ constants.bgp.maximum_paths.ipv4 | default(64) }}
{% endif %}
!
exit-address-family
!
address-family ipv6
{% if constants.bgp.maximum_paths.enabled is defined and constants.bgp.maximum_paths.enabled %}
maximum-paths ibgp {{ constants.bgp.maximum_paths.ipv6 | default(64) }}
{% endif %}
!
exit-address-family
!
! end of template: bgpd/templates/voq_chassis/instance.conf.j2
!

View File

@ -0,0 +1,23 @@
!
! template: bgpd/templates/voq_chassis/peer-group.conf.j2
!
neighbor VOQ_CHASSIS_PEER peer-group
address-family ipv4
{% if CONFIG_DB__DEVICE_METADATA['localhost']['type'] == 'ToRRouter' %}
neighbor VOQ_CHASSIS_PEER allowas-in 1
{% endif %}
neighbor VOQ_CHASSIS_PEER activate
neighbor VOQ_CHASSIS_PEER addpath-tx-all-paths
neighbor VOQ_CHASSIS_PEER soft-reconfiguration inbound
exit-address-family
address-family ipv6
{% if CONFIG_DB__DEVICE_METADATA['localhost']['type'] == 'ToRRouter' %}
neighbor VOQ_CHASSIS_PEER allowas-in 1
{% endif %}
neighbor VOQ_CHASSIS_PEER activate
neighbor VOQ_CHASSIS_PEER addpath-tx-all-paths
neighbor VOQ_CHASSIS_PEER soft-reconfiguration inbound
exit-address-family
!
! end of template: bgpd/templates/voq_chassis/peer-group.conf.j2
!

View File

@ -0,0 +1,7 @@
!
! template: bgpd/templates/voq_chassis/policies.conf.j2
!
!
!
! end of template: bgpd/templates/voq_chassis/policies.conf.j2
!

View File

@ -54,3 +54,7 @@ constants:
db_table: "BGP_PEER_RANGE" db_table: "BGP_PEER_RANGE"
peer_group: "BGP_SPEAKER" peer_group: "BGP_SPEAKER"
template_dir: "dynamic" template_dir: "dynamic"
voq_chassis: # peer_type
enabled: true
db_table: "BGP_VOQ_CHASSIS_NEIGHBOR"
template_dir: "voq_chassis"

View File

@ -43,6 +43,7 @@ def do_work():
InterfaceMgr(common_objs, "CONFIG_DB", swsscommon.CFG_LOOPBACK_INTERFACE_TABLE_NAME), InterfaceMgr(common_objs, "CONFIG_DB", swsscommon.CFG_LOOPBACK_INTERFACE_TABLE_NAME),
InterfaceMgr(common_objs, "CONFIG_DB", swsscommon.CFG_VLAN_INTF_TABLE_NAME), InterfaceMgr(common_objs, "CONFIG_DB", swsscommon.CFG_VLAN_INTF_TABLE_NAME),
InterfaceMgr(common_objs, "CONFIG_DB", swsscommon.CFG_LAG_INTF_TABLE_NAME), InterfaceMgr(common_objs, "CONFIG_DB", swsscommon.CFG_LAG_INTF_TABLE_NAME),
InterfaceMgr(common_objs, "CONFIG_DB", swsscommon.CFG_VOQ_INBAND_INTERFACE_TABLE_NAME),
# State DB managers # State DB managers
ZebraSetSrc(common_objs, "STATE_DB", swsscommon.STATE_INTERFACE_TABLE_NAME), ZebraSetSrc(common_objs, "STATE_DB", swsscommon.STATE_INTERFACE_TABLE_NAME),
# Peer Managers # Peer Managers
@ -50,6 +51,7 @@ def do_work():
BGPPeerMgrBase(common_objs, "CONFIG_DB", swsscommon.CFG_BGP_INTERNAL_NEIGHBOR_TABLE_NAME, "internal", False), BGPPeerMgrBase(common_objs, "CONFIG_DB", swsscommon.CFG_BGP_INTERNAL_NEIGHBOR_TABLE_NAME, "internal", False),
BGPPeerMgrBase(common_objs, "CONFIG_DB", "BGP_MONITORS", "monitors", False), BGPPeerMgrBase(common_objs, "CONFIG_DB", "BGP_MONITORS", "monitors", False),
BGPPeerMgrBase(common_objs, "CONFIG_DB", "BGP_PEER_RANGE", "dynamic", False), BGPPeerMgrBase(common_objs, "CONFIG_DB", "BGP_PEER_RANGE", "dynamic", False),
BGPPeerMgrBase(common_objs, "CONFIG_DB", "BGP_VOQ_CHASSIS_NEIGHBOR", "voq_chassis", False),
# AllowList Managers # AllowList Managers
BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES"), BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES"),
# BBR Manager # BBR Manager

View File

@ -0,0 +1,22 @@
{
"CONFIG_DB__DEVICE_METADATA": {
"localhost": {}
},
"neighbor_addr": "10.10.10.10",
"bgp_session": {
"asn": "555",
"name": "internal1",
"keepalive": "5",
"holdtime": "30",
"admin_status": "down"
},
"constants": {
"bgp": {
"maximum_paths": {
"enabled": "true",
"ipv4": "32",
"ipv6": "24"
}
}
}
}

View File

@ -0,0 +1,17 @@
{
"CONFIG_DB__DEVICE_METADATA": {
"localhost": {}
},
"neighbor_addr": "10.10.10.10",
"bgp_session": {
"asn": "555",
"name": "internal1"
},
"constants": {
"bgp": {
"maximum_paths": {
"enabled": "true"
}
}
}
}

View File

@ -0,0 +1,19 @@
{
"CONFIG_DB__DEVICE_METADATA": {
"localhost": {
"default_bgp_status": "down"
}
},
"neighbor_addr": "10.10.10.10",
"bgp_session": {
"asn": "555",
"name": "internal1"
},
"constants": {
"bgp": {
"maximum_paths": {
"enabled": "true"
}
}
}
}

View File

@ -0,0 +1,19 @@
{
"CONFIG_DB__DEVICE_METADATA": {
"localhost": {
"default_bgp_status": "up"
}
},
"neighbor_addr": "10.10.10.10",
"bgp_session": {
"asn": "555",
"name": "internal1"
},
"constants": {
"bgp": {
"maximum_paths": {
"enabled": "true"
}
}
}
}

View File

@ -0,0 +1,18 @@
{
"CONFIG_DB__DEVICE_METADATA": {
"localhost": {}
},
"neighbor_addr": "10.10.10.10",
"bgp_session": {
"asn": "555",
"name": "internal1",
"keepalive": "5"
},
"constants": {
"bgp": {
"maximum_paths": {
"enabled": "true"
}
}
}
}

View File

@ -0,0 +1,18 @@
{
"CONFIG_DB__DEVICE_METADATA": {
"localhost": {}
},
"neighbor_addr": "10.10.10.10",
"bgp_session": {
"asn": "555",
"name": "internal1",
"holdtime": "240"
},
"constants": {
"bgp": {
"maximum_paths": {
"enabled": "true"
}
}
}
}

View File

@ -0,0 +1,23 @@
!
! template: bgpd/templates/voq_chassis/instance.conf.j2
!
bgp bestpath as-path multipath-relax
bgp bestpath peer-type multipath-relax
!
neighbor 10.10.10.10 peer-group VOQ_CHASSIS_PEER
neighbor 10.10.10.10 remote-as 555
neighbor 10.10.10.10 description internal1
neighbor 10.10.10.10 timers 5 30
neighbor 10.10.10.10 shutdown
address-family ipv4
maximum-paths ibgp 32
!
exit-address-family
!
address-family ipv6
maximum-paths ibgp 24
!
exit-address-family
!
! end of template: bgpd/templates/voq_chassis/instance.conf.j2
!

View File

@ -0,0 +1,21 @@
!
! template: bgpd/templates/voq_chassis/instance.conf.j2
!
bgp bestpath as-path multipath-relax
bgp bestpath peer-type multipath-relax
!
neighbor 10.10.10.10 peer-group VOQ_CHASSIS_PEER
neighbor 10.10.10.10 remote-as 555
neighbor 10.10.10.10 description internal1
address-family ipv4
maximum-paths ibgp 64
!
exit-address-family
!
address-family ipv6
maximum-paths ibgp 64
!
exit-address-family
!
! end of template: bgpd/templates/voq_chassis/instance.conf.j2
!

View File

@ -0,0 +1,22 @@
!
! template: bgpd/templates/voq_chassis/instance.conf.j2
!
bgp bestpath as-path multipath-relax
bgp bestpath peer-type multipath-relax
!
neighbor 10.10.10.10 peer-group VOQ_CHASSIS_PEER
neighbor 10.10.10.10 remote-as 555
neighbor 10.10.10.10 description internal1
neighbor 10.10.10.10 shutdown
address-family ipv4
maximum-paths ibgp 64
!
exit-address-family
!
address-family ipv6
maximum-paths ibgp 64
!
exit-address-family
!
! end of template: bgpd/templates/voq_chassis/instance.conf.j2
!

View File

@ -0,0 +1,21 @@
!
! template: bgpd/templates/voq_chassis/instance.conf.j2
!
bgp bestpath as-path multipath-relax
bgp bestpath peer-type multipath-relax
!
neighbor 10.10.10.10 peer-group VOQ_CHASSIS_PEER
neighbor 10.10.10.10 remote-as 555
neighbor 10.10.10.10 description internal1
address-family ipv4
maximum-paths ibgp 64
!
exit-address-family
!
address-family ipv6
maximum-paths ibgp 64
!
exit-address-family
!
! end of template: bgpd/templates/voq_chassis/instance.conf.j2
!

View File

@ -0,0 +1,22 @@
!
! template: bgpd/templates/voq_chassis/instance.conf.j2
!
bgp bestpath as-path multipath-relax
bgp bestpath peer-type multipath-relax
!
neighbor 10.10.10.10 peer-group VOQ_CHASSIS_PEER
neighbor 10.10.10.10 remote-as 555
neighbor 10.10.10.10 description internal1
neighbor 10.10.10.10 timers 5 180
address-family ipv4
maximum-paths ibgp 64
!
exit-address-family
!
address-family ipv6
maximum-paths ibgp 64
!
exit-address-family
!
! end of template: bgpd/templates/voq_chassis/instance.conf.j2
!

View File

@ -0,0 +1,22 @@
!
! template: bgpd/templates/voq_chassis/instance.conf.j2
!
bgp bestpath as-path multipath-relax
bgp bestpath peer-type multipath-relax
!
neighbor 10.10.10.10 peer-group VOQ_CHASSIS_PEER
neighbor 10.10.10.10 remote-as 555
neighbor 10.10.10.10 description internal1
neighbor 10.10.10.10 timers 60 240
address-family ipv4
maximum-paths ibgp 64
!
exit-address-family
!
address-family ipv6
maximum-paths ibgp 64
!
exit-address-family
!
! end of template: bgpd/templates/voq_chassis/instance.conf.j2
!

View File

@ -0,0 +1,7 @@
{
"CONFIG_DB__DEVICE_METADATA": {
"localhost": {
"type": "ToRRouter"
}
}
}

View File

@ -0,0 +1,5 @@
{
"CONFIG_DB__DEVICE_METADATA": {
"localhost": {}
}
}

View File

@ -0,0 +1,19 @@
!
! template: bgpd/templates/voq_chassis/peer-group.conf.j2
!
neighbor VOQ_CHASSIS_PEER peer-group
address-family ipv4
neighbor VOQ_CHASSIS_PEER allowas-in 1
neighbor VOQ_CHASSIS_PEER activate
neighbor VOQ_CHASSIS_PEER addpath-tx-all-paths
neighbor VOQ_CHASSIS_PEER soft-reconfiguration inbound
exit-address-family
address-family ipv6
neighbor VOQ_CHASSIS_PEER allowas-in 1
neighbor VOQ_CHASSIS_PEER activate
neighbor VOQ_CHASSIS_PEER addpath-tx-all-paths
neighbor VOQ_CHASSIS_PEER soft-reconfiguration inbound
exit-address-family
!
! end of template: bgpd/templates/voq_chassis/peer-group.conf.j2
!

View File

@ -0,0 +1,17 @@
!
! template: bgpd/templates/voq_chassis/peer-group.conf.j2
!
neighbor VOQ_CHASSIS_PEER peer-group
address-family ipv4
neighbor VOQ_CHASSIS_PEER activate
neighbor VOQ_CHASSIS_PEER addpath-tx-all-paths
neighbor VOQ_CHASSIS_PEER soft-reconfiguration inbound
exit-address-family
address-family ipv6
neighbor VOQ_CHASSIS_PEER activate
neighbor VOQ_CHASSIS_PEER addpath-tx-all-paths
neighbor VOQ_CHASSIS_PEER soft-reconfiguration inbound
exit-address-family
!
! end of template: bgpd/templates/voq_chassis/peer-group.conf.j2
!

View File

@ -0,0 +1,5 @@
{
"CONFIG_DB__DEVICE_METADATA": {
"localhost": {}
}
}

View File

@ -0,0 +1,7 @@
!
! template: bgpd/templates/voq_chassis/policies.conf.j2
!
!
!
! end of template: bgpd/templates/voq_chassis/policies.conf.j2
!

View File

@ -140,3 +140,15 @@ def test_monitors_pg():
def test_monitors_instance(): def test_monitors_instance():
test_data = load_tests("monitors", "instance.conf") test_data = load_tests("monitors", "instance.conf")
run_tests("monitors_instance", *test_data) run_tests("monitors_instance", *test_data)
def test_voq_chassis_policies():
test_data = load_tests("voq_chassis", "policies.conf")
run_tests("voq_chassis_policies", *test_data)
def test_voq_chassis_pg():
test_data = load_tests("voq_chassis", "peer-group.conf")
run_tests("voq_chassis_pg", *test_data)
def test_voq_chassis_instance():
test_data = load_tests("voq_chassis", "instance.conf")
run_tests("voq_chassis_instance", *test_data)

View File

@ -681,6 +681,7 @@ def parse_host_loopback(dpg, hname):
def parse_cpg(cpg, hname, local_devices=[]): def parse_cpg(cpg, hname, local_devices=[]):
bgp_sessions = {} bgp_sessions = {}
bgp_internal_sessions = {} bgp_internal_sessions = {}
bgp_voq_chassis_sessions = {}
myasn = None myasn = None
bgp_peers_with_range = {} bgp_peers_with_range = {}
for child in cpg: for child in cpg:
@ -702,46 +703,40 @@ def parse_cpg(cpg, hname, local_devices=[]):
keepalive = 60 keepalive = 60
nhopself = 1 if session.find(str(QName(ns, "NextHopSelf"))) is not None else 0 nhopself = 1 if session.find(str(QName(ns, "NextHopSelf"))) is not None else 0
# choose the right table and admin_status for the peer
voq_chassis = session.find(str(QName(ns, "VoQChassisInternal")))
if voq_chassis is not None and voq_chassis.text == "true":
table = bgp_voq_chassis_sessions
admin_status = 'up'
elif end_router.lower() in local_devices and start_router.lower() in local_devices:
table = bgp_internal_sessions
admin_status = 'up'
else:
table = bgp_sessions
admin_status = None
if end_router.lower() == hname.lower(): if end_router.lower() == hname.lower():
if end_router.lower() in local_devices and start_router.lower() in local_devices: table[start_peer.lower()] = {
bgp_internal_sessions[start_peer.lower()] = { 'name': start_router,
'name': start_router, 'local_addr': end_peer.lower(),
'local_addr': end_peer.lower(), 'rrclient': rrclient,
'rrclient': rrclient, 'holdtime': holdtime,
'holdtime': holdtime, 'keepalive': keepalive,
'keepalive': keepalive, 'nhopself': nhopself
'nhopself': nhopself, }
'admin_status': 'up' if admin_status:
} table[start_peer.lower()]['admin_status'] = admin_status
else:
bgp_sessions[start_peer.lower()] = {
'name': start_router,
'local_addr': end_peer.lower(),
'rrclient': rrclient,
'holdtime': holdtime,
'keepalive': keepalive,
'nhopself': nhopself
}
elif start_router.lower() == hname.lower(): elif start_router.lower() == hname.lower():
if end_router.lower() in local_devices and start_router.lower() in local_devices: table[end_peer.lower()] = {
bgp_internal_sessions[end_peer.lower()] = { 'name': end_router,
'name': end_router, 'local_addr': start_peer.lower(),
'local_addr': start_peer.lower(), 'rrclient': rrclient,
'rrclient': rrclient, 'holdtime': holdtime,
'holdtime': holdtime, 'keepalive': keepalive,
'keepalive': keepalive, 'nhopself': nhopself
'nhopself': nhopself, }
'admin_status': 'up' if admin_status:
} table[end_peer.lower()]['admin_status'] = admin_status
else:
bgp_sessions[end_peer.lower()] = {
'name': end_router,
'local_addr': start_peer.lower(),
'rrclient': rrclient,
'holdtime': holdtime,
'keepalive': keepalive,
'nhopself': nhopself
}
elif child.tag == str(QName(ns, "Routers")): elif child.tag == str(QName(ns, "Routers")):
for router in child.findall(str(QName(ns1, "BGPRouterDeclaration"))): for router in child.findall(str(QName(ns1, "BGPRouterDeclaration"))):
asn = router.find(str(QName(ns1, "ASN"))).text asn = router.find(str(QName(ns1, "ASN"))).text
@ -772,12 +767,19 @@ def parse_cpg(cpg, hname, local_devices=[]):
bgp_internal_session = bgp_internal_sessions[peer] bgp_internal_session = bgp_internal_sessions[peer]
if hostname.lower() == bgp_internal_session['name'].lower(): if hostname.lower() == bgp_internal_session['name'].lower():
bgp_internal_session['asn'] = asn bgp_internal_session['asn'] = asn
for peer in bgp_voq_chassis_sessions:
bgp_session = bgp_voq_chassis_sessions[peer]
if hostname.lower() == bgp_session['name'].lower():
bgp_session['asn'] = asn
bgp_monitors = { key: bgp_sessions[key] for key in bgp_sessions if 'asn' in bgp_sessions[key] and bgp_sessions[key]['name'] == 'BGPMonitor' } bgp_monitors = { key: bgp_sessions[key] for key in bgp_sessions if 'asn' in bgp_sessions[key] and bgp_sessions[key]['name'] == 'BGPMonitor' }
bgp_sessions = { key: bgp_sessions[key] for key in bgp_sessions if 'asn' in bgp_sessions[key] and int(bgp_sessions[key]['asn']) != 0 } def filter_bad_asn(table):
bgp_internal_sessions = { key: bgp_internal_sessions[key] for key in bgp_internal_sessions if 'asn' in bgp_internal_sessions[key] and int(bgp_internal_sessions[key]['asn']) != 0 } return { key: table[key] for key in table if 'asn' in table[key] and int(table[key]['asn']) != 0 }
bgp_sessions = filter_bad_asn(bgp_sessions)
bgp_internal_sessions = filter_bad_asn(bgp_internal_sessions)
bgp_voq_chassis_sessions = filter_bad_asn(bgp_voq_chassis_sessions)
return bgp_sessions, bgp_internal_sessions, myasn, bgp_peers_with_range, bgp_monitors return bgp_sessions, bgp_internal_sessions, bgp_voq_chassis_sessions, myasn, bgp_peers_with_range, bgp_monitors
def parse_meta(meta, hname): def parse_meta(meta, hname):
@ -1153,7 +1155,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw
if child.tag == str(QName(ns, "DpgDec")): if child.tag == str(QName(ns, "DpgDec")):
(intfs, lo_intfs, mvrf, mgmt_intf, vlans, vlan_members, pcs, pc_members, acls, vni, tunnel_intfs, dpg_ecmp_content) = parse_dpg(child, hostname) (intfs, lo_intfs, mvrf, mgmt_intf, vlans, vlan_members, pcs, pc_members, acls, vni, tunnel_intfs, dpg_ecmp_content) = parse_dpg(child, hostname)
elif child.tag == str(QName(ns, "CpgDec")): elif child.tag == str(QName(ns, "CpgDec")):
(bgp_sessions, bgp_internal_sessions, bgp_asn, bgp_peers_with_range, bgp_monitors) = parse_cpg(child, hostname) (bgp_sessions, bgp_internal_sessions, bgp_voq_chassis_sessions, bgp_asn, bgp_peers_with_range, bgp_monitors) = parse_cpg(child, hostname)
elif child.tag == str(QName(ns, "PngDec")): elif child.tag == str(QName(ns, "PngDec")):
(neighbors, devices, console_dev, console_port, mgmt_dev, mgmt_port, port_speed_png, console_ports, mux_cable_ports, is_storage_device, png_ecmp_content) = parse_png(child, hostname, dpg_ecmp_content) (neighbors, devices, console_dev, console_port, mgmt_dev, mgmt_port, port_speed_png, console_ports, mux_cable_ports, is_storage_device, png_ecmp_content) = parse_png(child, hostname, dpg_ecmp_content)
elif child.tag == str(QName(ns, "UngDec")): elif child.tag == str(QName(ns, "UngDec")):
@ -1169,7 +1171,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw
(intfs, lo_intfs, mvrf, mgmt_intf, vlans, vlan_members, pcs, pc_members, acls, vni, tunnel_intfs, dpg_ecmp_content) = parse_dpg(child, asic_name) (intfs, lo_intfs, mvrf, mgmt_intf, vlans, vlan_members, pcs, pc_members, acls, vni, tunnel_intfs, dpg_ecmp_content) = parse_dpg(child, asic_name)
host_lo_intfs = parse_host_loopback(child, hostname) host_lo_intfs = parse_host_loopback(child, hostname)
elif child.tag == str(QName(ns, "CpgDec")): elif child.tag == str(QName(ns, "CpgDec")):
(bgp_sessions, bgp_internal_sessions, bgp_asn, bgp_peers_with_range, bgp_monitors) = parse_cpg(child, asic_name, local_devices) (bgp_sessions, bgp_internal_sessions, bgp_voq_chassis_sessions, bgp_asn, bgp_peers_with_range, bgp_monitors) = parse_cpg(child, asic_name, local_devices)
elif child.tag == str(QName(ns, "PngDec")): elif child.tag == str(QName(ns, "PngDec")):
(neighbors, devices, port_speed_png) = parse_asic_png(child, asic_name, hostname) (neighbors, devices, port_speed_png) = parse_asic_png(child, asic_name, hostname)
elif child.tag == str(QName(ns, "MetadataDeclaration")): elif child.tag == str(QName(ns, "MetadataDeclaration")):
@ -1241,6 +1243,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw
results['BGP_MONITORS'] = bgp_monitors results['BGP_MONITORS'] = bgp_monitors
results['BGP_PEER_RANGE'] = bgp_peers_with_range results['BGP_PEER_RANGE'] = bgp_peers_with_range
results['BGP_INTERNAL_NEIGHBOR'] = bgp_internal_sessions results['BGP_INTERNAL_NEIGHBOR'] = bgp_internal_sessions
results['BGP_VOQ_CHASSIS_NEIGHBOR'] = bgp_voq_chassis_sessions
if mgmt_routes: if mgmt_routes:
# TODO: differentiate v4 and v6 # TODO: differentiate v4 and v6
next(iter(mgmt_intf.values()))['forced_mgmt_routes'] = mgmt_routes next(iter(mgmt_intf.values()))['forced_mgmt_routes'] = mgmt_routes

View File

@ -20,6 +20,7 @@
<Multihop>1</Multihop> <Multihop>1</Multihop>
<HoldTime>180</HoldTime> <HoldTime>180</HoldTime>
<KeepAliveTime>60</KeepAliveTime> <KeepAliveTime>60</KeepAliveTime>
<VoQChassisInternal>false</VoQChassisInternal>
</BGPSession> </BGPSession>
<BGPSession> <BGPSession>
<StartRouter>switch-t0</StartRouter> <StartRouter>switch-t0</StartRouter>
@ -49,6 +50,26 @@
<HoldTime>180</HoldTime> <HoldTime>180</HoldTime>
<KeepAliveTime>60</KeepAliveTime> <KeepAliveTime>60</KeepAliveTime>
</BGPSession> </BGPSession>
<BGPSession>
<StartRouter>switch-t0</StartRouter>
<StartPeer>FC00::75</StartPeer>
<EndRouter>ARISTA02T1</EndRouter>
<EndPeer>FC00::76</EndPeer>
<Multihop>1</Multihop>
<HoldTime>180</HoldTime>
<KeepAliveTime>60</KeepAliveTime>
</BGPSession>
<BGPSession>
<MacSec>false</MacSec>
<StartRouter>switch-t0</StartRouter>
<StartPeer>10.2.0.20</StartPeer>
<EndRouter>CHASSIS_PEER</EndRouter>
<EndPeer>10.2.0.21</EndPeer>
<Multihop>1</Multihop>
<HoldTime>180</HoldTime>
<KeepAliveTime>60</KeepAliveTime>
<VoQChassisInternal>true</VoQChassisInternal>
</BGPSession>
</PeeringSessions> </PeeringSessions>
<Routers xmlns:a="http://schemas.datacontract.org/2004/07/Microsoft.Search.Autopilot.Evolution"> <Routers xmlns:a="http://schemas.datacontract.org/2004/07/Microsoft.Search.Autopilot.Evolution">
<a:BGPRouterDeclaration> <a:BGPRouterDeclaration>
@ -82,6 +103,12 @@
<RouteMapOut i:nil="true"/> <RouteMapOut i:nil="true"/>
<Vrf i:nil="true"/> <Vrf i:nil="true"/>
</BGPPeer> </BGPPeer>
<BGPPeer>
<Address>10.2.0.21</Address>
<RouteMapIn i:nil="true"/>
<RouteMapOut i:nil="true"/>
<Vrf i:nil="true"/>
</BGPPeer>
</a:Peers> </a:Peers>
<a:RouteMaps/> <a:RouteMaps/>
</a:BGPRouterDeclaration> </a:BGPRouterDeclaration>
@ -105,6 +132,11 @@
<a:Hostname>ARISTA04T1</a:Hostname> <a:Hostname>ARISTA04T1</a:Hostname>
<a:RouteMaps/> <a:RouteMaps/>
</a:BGPRouterDeclaration> </a:BGPRouterDeclaration>
<a:BGPRouterDeclaration>
<a:ASN>65100</a:ASN>
<a:Hostname>CHASSIS_PEER</a:Hostname>
<a:RouteMaps/>
</a:BGPRouterDeclaration>
</Routers> </Routers>
</CpgDec> </CpgDec>
<DpgDec> <DpgDec>

View File

@ -586,6 +586,19 @@ class TestCfgGen(TestCase):
utils.to_dict("{'10.20.30.40': {'rrclient': 0, 'name': 'BGPMonitor', 'local_addr': '10.1.0.32', 'nhopself': 0, 'holdtime': '10', 'asn': '0', 'keepalive': '3'}}") utils.to_dict("{'10.20.30.40': {'rrclient': 0, 'name': 'BGPMonitor', 'local_addr': '10.1.0.32', 'nhopself': 0, 'holdtime': '10', 'asn': '0', 'keepalive': '3'}}")
) )
def test_minigraph_bgp_voq_chassis_peer(self):
argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "BGP_VOQ_CHASSIS_NEIGHBOR[\'10.2.0.21\']"'
output = self.run_script(argument)
self.assertEqual(
utils.to_dict(output.strip()),
utils.to_dict("{'rrclient': 0, 'name': 'CHASSIS_PEER', 'local_addr': '10.2.0.20', 'nhopself': 0, 'holdtime': '180', 'asn': '65100', 'keepalive': '60', 'admin_status': 'up'}")
)
# make sure VoQChassisInternal value of false is honored
argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "BGP_VOQ_CHASSIS_NEIGHBOR[\'10.0.0.57\']"'
output = self.run_script(argument)
self.assertEqual(output.strip(), "")
def test_minigraph_sub_port_interfaces(self, check_stderr=True): def test_minigraph_sub_port_interfaces(self, check_stderr=True):
try: try:
print('\n Change device type to %s' % (BACKEND_TOR_ROUTER)) print('\n Change device type to %s' % (BACKEND_TOR_ROUTER))