From be58309a276c12fc7aa993e20a1b2846a226fd92 Mon Sep 17 00:00:00 2001 From: jmmikkel <71102623+jmmikkel@users.noreply.github.com> Date: Fri, 16 Apr 2021 11:11:32 -0700 Subject: [PATCH] [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 --- .../templates/voq_chassis/instance.conf.j2 | 35 ++++++++ .../templates/voq_chassis/peer-group.conf.j2 | 23 +++++ .../templates/voq_chassis/policies.conf.j2 | 7 ++ files/image_config/constants/constants.yml | 4 + src/sonic-bgpcfgd/bgpcfgd/main.py | 2 + .../voq_chassis/instance.conf/param_all.json | 22 +++++ .../voq_chassis/instance.conf/param_base.json | 17 ++++ .../instance.conf/param_shutdown_1.json | 19 ++++ .../instance.conf/param_shutdown_2.json | 19 ++++ .../instance.conf/param_timers_1.json | 18 ++++ .../instance.conf/param_timers_2.json | 18 ++++ .../voq_chassis/instance.conf/result_all.conf | 23 +++++ .../instance.conf/result_base.conf | 21 +++++ .../instance.conf/result_shutdown_1.conf | 22 +++++ .../instance.conf/result_shutdown_2.conf | 21 +++++ .../instance.conf/result_timers_1.conf | 22 +++++ .../instance.conf/result_timers_2.conf | 22 +++++ .../peer-group.conf/param_all.json | 7 ++ .../peer-group.conf/param_base.json | 5 ++ .../peer-group.conf/result_all.conf | 19 ++++ .../peer-group.conf/result_base.conf | 17 ++++ .../voq_chassis/policies.conf/param_base.json | 5 ++ .../policies.conf/result_base.conf | 7 ++ src/sonic-bgpcfgd/tests/test_templates.py | 12 +++ src/sonic-config-engine/minigraph.py | 89 ++++++++++--------- .../tests/simple-sample-graph.xml | 32 +++++++ src/sonic-config-engine/tests/test_cfggen.py | 13 +++ 27 files changed, 478 insertions(+), 43 deletions(-) create mode 100644 dockers/docker-fpm-frr/frr/bgpd/templates/voq_chassis/instance.conf.j2 create mode 100644 dockers/docker-fpm-frr/frr/bgpd/templates/voq_chassis/peer-group.conf.j2 create mode 100644 dockers/docker-fpm-frr/frr/bgpd/templates/voq_chassis/policies.conf.j2 create mode 100644 src/sonic-bgpcfgd/tests/data/voq_chassis/instance.conf/param_all.json create mode 100644 src/sonic-bgpcfgd/tests/data/voq_chassis/instance.conf/param_base.json create mode 100644 src/sonic-bgpcfgd/tests/data/voq_chassis/instance.conf/param_shutdown_1.json create mode 100644 src/sonic-bgpcfgd/tests/data/voq_chassis/instance.conf/param_shutdown_2.json create mode 100644 src/sonic-bgpcfgd/tests/data/voq_chassis/instance.conf/param_timers_1.json create mode 100644 src/sonic-bgpcfgd/tests/data/voq_chassis/instance.conf/param_timers_2.json create mode 100644 src/sonic-bgpcfgd/tests/data/voq_chassis/instance.conf/result_all.conf create mode 100644 src/sonic-bgpcfgd/tests/data/voq_chassis/instance.conf/result_base.conf create mode 100644 src/sonic-bgpcfgd/tests/data/voq_chassis/instance.conf/result_shutdown_1.conf create mode 100644 src/sonic-bgpcfgd/tests/data/voq_chassis/instance.conf/result_shutdown_2.conf create mode 100644 src/sonic-bgpcfgd/tests/data/voq_chassis/instance.conf/result_timers_1.conf create mode 100644 src/sonic-bgpcfgd/tests/data/voq_chassis/instance.conf/result_timers_2.conf create mode 100644 src/sonic-bgpcfgd/tests/data/voq_chassis/peer-group.conf/param_all.json create mode 100644 src/sonic-bgpcfgd/tests/data/voq_chassis/peer-group.conf/param_base.json create mode 100644 src/sonic-bgpcfgd/tests/data/voq_chassis/peer-group.conf/result_all.conf create mode 100644 src/sonic-bgpcfgd/tests/data/voq_chassis/peer-group.conf/result_base.conf create mode 100644 src/sonic-bgpcfgd/tests/data/voq_chassis/policies.conf/param_base.json create mode 100644 src/sonic-bgpcfgd/tests/data/voq_chassis/policies.conf/result_base.conf diff --git a/dockers/docker-fpm-frr/frr/bgpd/templates/voq_chassis/instance.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/voq_chassis/instance.conf.j2 new file mode 100644 index 000000000000..e4ee9bf2eefd --- /dev/null +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/voq_chassis/instance.conf.j2 @@ -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 +! diff --git a/dockers/docker-fpm-frr/frr/bgpd/templates/voq_chassis/peer-group.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/voq_chassis/peer-group.conf.j2 new file mode 100644 index 000000000000..8266c0c82d7f --- /dev/null +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/voq_chassis/peer-group.conf.j2 @@ -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 +! diff --git a/dockers/docker-fpm-frr/frr/bgpd/templates/voq_chassis/policies.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/voq_chassis/policies.conf.j2 new file mode 100644 index 000000000000..4c853d4f3220 --- /dev/null +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/voq_chassis/policies.conf.j2 @@ -0,0 +1,7 @@ +! +! template: bgpd/templates/voq_chassis/policies.conf.j2 +! +! +! +! end of template: bgpd/templates/voq_chassis/policies.conf.j2 +! diff --git a/files/image_config/constants/constants.yml b/files/image_config/constants/constants.yml index 86179aee430e..94f3d0e9706c 100644 --- a/files/image_config/constants/constants.yml +++ b/files/image_config/constants/constants.yml @@ -54,3 +54,7 @@ constants: db_table: "BGP_PEER_RANGE" peer_group: "BGP_SPEAKER" template_dir: "dynamic" + voq_chassis: # peer_type + enabled: true + db_table: "BGP_VOQ_CHASSIS_NEIGHBOR" + template_dir: "voq_chassis" diff --git a/src/sonic-bgpcfgd/bgpcfgd/main.py b/src/sonic-bgpcfgd/bgpcfgd/main.py index 64d2edbed174..8b0fe0fb3b56 100644 --- a/src/sonic-bgpcfgd/bgpcfgd/main.py +++ b/src/sonic-bgpcfgd/bgpcfgd/main.py @@ -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_VLAN_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 ZebraSetSrc(common_objs, "STATE_DB", swsscommon.STATE_INTERFACE_TABLE_NAME), # 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", "BGP_MONITORS", "monitors", 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 BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES"), # BBR Manager diff --git a/src/sonic-bgpcfgd/tests/data/voq_chassis/instance.conf/param_all.json b/src/sonic-bgpcfgd/tests/data/voq_chassis/instance.conf/param_all.json new file mode 100644 index 000000000000..09f3274cc7d9 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/voq_chassis/instance.conf/param_all.json @@ -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" + } + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/voq_chassis/instance.conf/param_base.json b/src/sonic-bgpcfgd/tests/data/voq_chassis/instance.conf/param_base.json new file mode 100644 index 000000000000..53ad6ba68ead --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/voq_chassis/instance.conf/param_base.json @@ -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" + } + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/voq_chassis/instance.conf/param_shutdown_1.json b/src/sonic-bgpcfgd/tests/data/voq_chassis/instance.conf/param_shutdown_1.json new file mode 100644 index 000000000000..920c92dde708 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/voq_chassis/instance.conf/param_shutdown_1.json @@ -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" + } + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/voq_chassis/instance.conf/param_shutdown_2.json b/src/sonic-bgpcfgd/tests/data/voq_chassis/instance.conf/param_shutdown_2.json new file mode 100644 index 000000000000..872f5f7d3905 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/voq_chassis/instance.conf/param_shutdown_2.json @@ -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" + } + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/voq_chassis/instance.conf/param_timers_1.json b/src/sonic-bgpcfgd/tests/data/voq_chassis/instance.conf/param_timers_1.json new file mode 100644 index 000000000000..642aafcc69bf --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/voq_chassis/instance.conf/param_timers_1.json @@ -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" + } + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/voq_chassis/instance.conf/param_timers_2.json b/src/sonic-bgpcfgd/tests/data/voq_chassis/instance.conf/param_timers_2.json new file mode 100644 index 000000000000..48a046c34735 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/voq_chassis/instance.conf/param_timers_2.json @@ -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" + } + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/voq_chassis/instance.conf/result_all.conf b/src/sonic-bgpcfgd/tests/data/voq_chassis/instance.conf/result_all.conf new file mode 100644 index 000000000000..0f15d2f7f3e9 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/voq_chassis/instance.conf/result_all.conf @@ -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 +! diff --git a/src/sonic-bgpcfgd/tests/data/voq_chassis/instance.conf/result_base.conf b/src/sonic-bgpcfgd/tests/data/voq_chassis/instance.conf/result_base.conf new file mode 100644 index 000000000000..c15098c782a9 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/voq_chassis/instance.conf/result_base.conf @@ -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 +! diff --git a/src/sonic-bgpcfgd/tests/data/voq_chassis/instance.conf/result_shutdown_1.conf b/src/sonic-bgpcfgd/tests/data/voq_chassis/instance.conf/result_shutdown_1.conf new file mode 100644 index 000000000000..6b929baf8759 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/voq_chassis/instance.conf/result_shutdown_1.conf @@ -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 +! diff --git a/src/sonic-bgpcfgd/tests/data/voq_chassis/instance.conf/result_shutdown_2.conf b/src/sonic-bgpcfgd/tests/data/voq_chassis/instance.conf/result_shutdown_2.conf new file mode 100644 index 000000000000..c15098c782a9 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/voq_chassis/instance.conf/result_shutdown_2.conf @@ -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 +! diff --git a/src/sonic-bgpcfgd/tests/data/voq_chassis/instance.conf/result_timers_1.conf b/src/sonic-bgpcfgd/tests/data/voq_chassis/instance.conf/result_timers_1.conf new file mode 100644 index 000000000000..f7feab971f8a --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/voq_chassis/instance.conf/result_timers_1.conf @@ -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 +! diff --git a/src/sonic-bgpcfgd/tests/data/voq_chassis/instance.conf/result_timers_2.conf b/src/sonic-bgpcfgd/tests/data/voq_chassis/instance.conf/result_timers_2.conf new file mode 100644 index 000000000000..8e773c113b3d --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/voq_chassis/instance.conf/result_timers_2.conf @@ -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 +! diff --git a/src/sonic-bgpcfgd/tests/data/voq_chassis/peer-group.conf/param_all.json b/src/sonic-bgpcfgd/tests/data/voq_chassis/peer-group.conf/param_all.json new file mode 100644 index 000000000000..293ccc7990dc --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/voq_chassis/peer-group.conf/param_all.json @@ -0,0 +1,7 @@ +{ + "CONFIG_DB__DEVICE_METADATA": { + "localhost": { + "type": "ToRRouter" + } + } +} \ No newline at end of file diff --git a/src/sonic-bgpcfgd/tests/data/voq_chassis/peer-group.conf/param_base.json b/src/sonic-bgpcfgd/tests/data/voq_chassis/peer-group.conf/param_base.json new file mode 100644 index 000000000000..7ef21c181d7e --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/voq_chassis/peer-group.conf/param_base.json @@ -0,0 +1,5 @@ +{ + "CONFIG_DB__DEVICE_METADATA": { + "localhost": {} + } +} diff --git a/src/sonic-bgpcfgd/tests/data/voq_chassis/peer-group.conf/result_all.conf b/src/sonic-bgpcfgd/tests/data/voq_chassis/peer-group.conf/result_all.conf new file mode 100644 index 000000000000..031884499aaa --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/voq_chassis/peer-group.conf/result_all.conf @@ -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 +! diff --git a/src/sonic-bgpcfgd/tests/data/voq_chassis/peer-group.conf/result_base.conf b/src/sonic-bgpcfgd/tests/data/voq_chassis/peer-group.conf/result_base.conf new file mode 100644 index 000000000000..d4a6f381a224 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/voq_chassis/peer-group.conf/result_base.conf @@ -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 +! diff --git a/src/sonic-bgpcfgd/tests/data/voq_chassis/policies.conf/param_base.json b/src/sonic-bgpcfgd/tests/data/voq_chassis/policies.conf/param_base.json new file mode 100644 index 000000000000..7ef21c181d7e --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/voq_chassis/policies.conf/param_base.json @@ -0,0 +1,5 @@ +{ + "CONFIG_DB__DEVICE_METADATA": { + "localhost": {} + } +} diff --git a/src/sonic-bgpcfgd/tests/data/voq_chassis/policies.conf/result_base.conf b/src/sonic-bgpcfgd/tests/data/voq_chassis/policies.conf/result_base.conf new file mode 100644 index 000000000000..4c853d4f3220 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/voq_chassis/policies.conf/result_base.conf @@ -0,0 +1,7 @@ +! +! template: bgpd/templates/voq_chassis/policies.conf.j2 +! +! +! +! end of template: bgpd/templates/voq_chassis/policies.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/test_templates.py b/src/sonic-bgpcfgd/tests/test_templates.py index 7d3bc773ad16..23ada1aaf3f6 100644 --- a/src/sonic-bgpcfgd/tests/test_templates.py +++ b/src/sonic-bgpcfgd/tests/test_templates.py @@ -140,3 +140,15 @@ def test_monitors_pg(): def test_monitors_instance(): test_data = load_tests("monitors", "instance.conf") 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) diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 26fdc12126ff..8c5b21fe1437 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -681,6 +681,7 @@ def parse_host_loopback(dpg, hname): def parse_cpg(cpg, hname, local_devices=[]): bgp_sessions = {} bgp_internal_sessions = {} + bgp_voq_chassis_sessions = {} myasn = None bgp_peers_with_range = {} for child in cpg: @@ -702,46 +703,40 @@ def parse_cpg(cpg, hname, local_devices=[]): keepalive = 60 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() in local_devices and start_router.lower() in local_devices: - bgp_internal_sessions[start_peer.lower()] = { - 'name': start_router, - 'local_addr': end_peer.lower(), - 'rrclient': rrclient, - 'holdtime': holdtime, - 'keepalive': keepalive, - 'nhopself': nhopself, - 'admin_status': 'up' - } - else: - bgp_sessions[start_peer.lower()] = { - 'name': start_router, - 'local_addr': end_peer.lower(), - 'rrclient': rrclient, - 'holdtime': holdtime, - 'keepalive': keepalive, - 'nhopself': nhopself - } + table[start_peer.lower()] = { + 'name': start_router, + 'local_addr': end_peer.lower(), + 'rrclient': rrclient, + 'holdtime': holdtime, + 'keepalive': keepalive, + 'nhopself': nhopself + } + if admin_status: + table[start_peer.lower()]['admin_status'] = admin_status elif start_router.lower() == hname.lower(): - if end_router.lower() in local_devices and start_router.lower() in local_devices: - bgp_internal_sessions[end_peer.lower()] = { - 'name': end_router, - 'local_addr': start_peer.lower(), - 'rrclient': rrclient, - 'holdtime': holdtime, - 'keepalive': keepalive, - 'nhopself': nhopself, - 'admin_status': 'up' - } - else: - bgp_sessions[end_peer.lower()] = { - 'name': end_router, - 'local_addr': start_peer.lower(), - 'rrclient': rrclient, - 'holdtime': holdtime, - 'keepalive': keepalive, - 'nhopself': nhopself - } + table[end_peer.lower()] = { + 'name': end_router, + 'local_addr': start_peer.lower(), + 'rrclient': rrclient, + 'holdtime': holdtime, + 'keepalive': keepalive, + 'nhopself': nhopself + } + if admin_status: + table[end_peer.lower()]['admin_status'] = admin_status elif child.tag == str(QName(ns, "Routers")): for router in child.findall(str(QName(ns1, "BGPRouterDeclaration"))): 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] if hostname.lower() == bgp_internal_session['name'].lower(): 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_sessions = { key: bgp_sessions[key] for key in bgp_sessions if 'asn' in bgp_sessions[key] and int(bgp_sessions[key]['asn']) != 0 } - 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 } + def filter_bad_asn(table): + 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): @@ -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")): (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")): - (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")): (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")): @@ -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) host_lo_intfs = parse_host_loopback(child, hostname) 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")): (neighbors, devices, port_speed_png) = parse_asic_png(child, asic_name, hostname) 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_PEER_RANGE'] = bgp_peers_with_range results['BGP_INTERNAL_NEIGHBOR'] = bgp_internal_sessions + results['BGP_VOQ_CHASSIS_NEIGHBOR'] = bgp_voq_chassis_sessions if mgmt_routes: # TODO: differentiate v4 and v6 next(iter(mgmt_intf.values()))['forced_mgmt_routes'] = mgmt_routes diff --git a/src/sonic-config-engine/tests/simple-sample-graph.xml b/src/sonic-config-engine/tests/simple-sample-graph.xml index 0ac08a3fff04..662544d20f51 100644 --- a/src/sonic-config-engine/tests/simple-sample-graph.xml +++ b/src/sonic-config-engine/tests/simple-sample-graph.xml @@ -20,6 +20,7 @@ 1 180 60 + false switch-t0 @@ -49,6 +50,26 @@ 180 60 + + switch-t0 + FC00::75 + ARISTA02T1 + FC00::76 + 1 + 180 + 60 + + + false + switch-t0 + 10.2.0.20 + CHASSIS_PEER + 10.2.0.21 + 1 + 180 + 60 + true + @@ -82,6 +103,12 @@ + +
10.2.0.21
+ + + +
@@ -105,6 +132,11 @@ ARISTA04T1 + + 65100 + CHASSIS_PEER + +
diff --git a/src/sonic-config-engine/tests/test_cfggen.py b/src/sonic-config-engine/tests/test_cfggen.py index 6a40019765c7..9e1a8f8523ba 100644 --- a/src/sonic-config-engine/tests/test_cfggen.py +++ b/src/sonic-config-engine/tests/test_cfggen.py @@ -586,6 +586,19 @@ def test_minigraph_bgp_mon(self): 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): try: print('\n Change device type to %s' % (BACKEND_TOR_ROUTER))