From 7257a128633cf0a247e3ed2ace6c15edf37f86af Mon Sep 17 00:00:00 2001 From: Mukul Chodhary Date: Wed, 29 Jan 2025 07:20:24 +0000 Subject: [PATCH 01/10] Added Anchor prefix support Following files were altered or added: 1. Cli support to add a prefix - dockers/docker-fpm-fr/base_image_files/prefix_list - rules/docker-fpm-frr.mk 2. Manager to add appropriate prefix using jinja templates Signed-off-by: Mukul Chodhary <70460358+Muckthebuck@users.noreply.github.com> --- .../base_image_files/prefix_list | 180 ++++++++++++++++++ .../frr/bgpd/radian/add_radian.conf.j2 | 11 ++ .../frr/bgpd/radian/del_radian.conf.j2 | 10 + rules/docker-fpm-frr.mk | 1 + src/sonic-bgpcfgd/bgpcfgd/main.py | 5 +- .../bgpcfgd/managers_prefix_list.py | 105 ++++++++++ 6 files changed, 311 insertions(+), 1 deletion(-) create mode 100644 dockers/docker-fpm-frr/base_image_files/prefix_list create mode 100644 dockers/docker-fpm-frr/frr/bgpd/radian/add_radian.conf.j2 create mode 100644 dockers/docker-fpm-frr/frr/bgpd/radian/del_radian.conf.j2 create mode 100644 src/sonic-bgpcfgd/bgpcfgd/managers_prefix_list.py diff --git a/dockers/docker-fpm-frr/base_image_files/prefix_list b/dockers/docker-fpm-frr/base_image_files/prefix_list new file mode 100644 index 000000000000..f27212f49c4d --- /dev/null +++ b/dockers/docker-fpm-frr/base_image_files/prefix_list @@ -0,0 +1,180 @@ +#!/bin/bash + +# Function to display help message +display_help() { + echo "Usage: sudo prefix-list " + echo "" + echo "Commands:" + echo " add Add a prefix with prefix type and network." + echo " Requires: , ." + echo "" + echo " remove Remove a prefix with prefix type and network." + echo " Requires: , ." + echo "" + echo " status Display current prefix lists." + echo " No additional parameters required." + echo "" + echo "Arguments:" + echo " Type of prefix list. Allowed values: {$(IFS='|'; echo "${supported_prefix_types[*]}")}." + echo " Network in CIDR format." + echo "" + echo "Options:" + echo " -h, --help Display this help message." + exit 0 +} + + +# Function to check if the user has root privileges +check_root_privileges() { + if [ "$EUID" -ne 0 ] ; then + echo "Root privileges are needed for this operation" + exit 1 + fi +} + +# Function to check if the command is supported on spine routers +check_spine_router() { + if [[ "$(sonic-cfggen -d -v DEVICE_METADATA.localhost.type)" != *"SpineRouter"* ]] ; then + echo "Operation is not supported on this platform" + exit 1 + fi +} + +# Function to skip operation on chassis supervisor +skip_chassis_supervisor() { + if [ -f /etc/sonic/chassisdb.conf ]; then + echo "Skipping Operation on chassis supervisor" + exit 0 + fi +} + +# Function to validate the operation and prefix type parameters +validate_operation() { + local valid_operation=false + local valid_prefix_type=false + + for operation in "${prefix_list_operations[@]}"; do + if [[ "$1" == "$operation" ]]; then + valid_operation=true + break + fi + done + + if [ $valid_operation == false ]; then + echo "Invalid parameter $1, Operation not supported" + echo "" + display_help + exit 0 + fi + + # Check if the prefix type is supported or not if the operation is not status + if [ $1 != "status" ]; then + for prefix_type in "${supported_prefix_types[@]}"; do + if [[ "$2" == "$prefix_type" ]]; then + valid_prefix_type=true + break + fi + done + + if [ $valid_prefix_type == false ]; then + echo "Invalid parameter $2, Prefix type not supported" + echo "" + display_help + exit 0 + fi + fi +} + +# Function to handle prefix list operations for a specific ASIC +handle_prefix_list_asic() { + local asic=$1 + local operation=$2 + local PREFIX_TYPE=$3 + local network=$4 + local namespace_prefix='asic' + + if [ $operation == 'status' ] ; then + echo "BGP$asic: Current prefix lists:" + sonic-cfggen -d -v PREFIX_LIST -n $namespace_prefix$asic + else + if [ $operation == 'add' ]; then + local prefix_list_entry="{\"PREFIX_LIST\":{\"$PREFIX_TYPE|$network\":{}}}" + sonic-cfggen -a "$prefix_list_entry" -w -n $namespace_prefix$asic + logger -t $operation -p user.info "Added prefix list: $PREFIX_TYPE with network: $network" + echo "BGP$asic: Added prefix list: $PREFIX_TYPE with network: $network" + elif [ $operation == 'remove' ]; then + sonic-db-cli -n $namespace_prefix$asic CONFIG_DB DEL "PREFIX_LIST|$PREFIX_TYPE|$network" + logger -t $operation -p user.info "Removed prefix list: $PREFIX_TYPE with network: $network" + echo "BGP$asic: Removed prefix list: $PREFIX_TYPE with network: $network" + fi + fi +} + +# Function to handle prefix list operations for a single ASIC +handle_prefix_list_single() { + local operation=$1 + local PREFIX_TYPE=$2 + local network=$3 + + if [ $operation == 'status' ] ; then + echo "Current prefix lists:" + sonic-cfggen -d -v PREFIX_LIST + else + if [ $operation == 'add' ]; then + local prefix_list_entry="{\"PREFIX_LIST\":{\"$PREFIX_TYPE|$network\":{}}}" + sonic-cfggen -a "$prefix_list_entry" -w + logger -t $operation -p user.info "Added prefix list: $PREFIX_TYPE with network: $network" + echo "Added prefix list: $PREFIX_TYPE with network: $network" + elif [ $operation == 'remove' ]; then + sonic-db-cli CONFIG_DB DEL "PREFIX_LIST|$PREFIX_TYPE|$network" + logger -t $operation -p user.info "Removed prefix list: $PREFIX_TYPE with network: $network" + echo "Removed prefix list: $PREFIX_TYPE with network: $network" + fi + fi +} + +prefix_list_operations=("add" "remove" "status") +supported_prefix_types=("ANCHOR_PREFIX") +# Main script execution +if [[ "$1" == "-h" || "$1" == "--help" ]]; then + display_help +fi + +check_root_privileges +check_spine_router +skip_chassis_supervisor + +validate_operation $1 $2 + +# Read SONiC immutable variables +[ -f /etc/sonic/sonic-environment ] && . /etc/sonic/sonic-environment + +PLATFORM=${PLATFORM:-`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform`} + +# Parse the device specific asic conf file, if it exists +ASIC_CONF=/usr/share/sonic/device/$PLATFORM/asic.conf +[ -f $ASIC_CONF ] && . $ASIC_CONF + +if [[ ($NUM_ASIC -gt 1) ]]; then + asic=0 + while [ $asic -lt $NUM_ASIC ] + do + sub_role=`sonic-cfggen -d -v "DEVICE_METADATA['localhost']['sub_role']" -n asic$asic` + subtype=`sonic-cfggen -d -v "DEVICE_METADATA['localhost']['subtype']" -n asic$asic` + if [ $sub_role == 'FrontEnd' ] ; then + if [ $subtype == 'UpstreamLC' ] ; then + handle_prefix_list_asic $asic $1 $2 $3 + fi + fi + asic=$((asic+1)) + done +else + subtype=`sonic-cfggen -d -v "DEVICE_METADATA['localhost']['subtype']"` + if [ $subtype == 'UpstreamLC' ] ; then + handle_prefix_list_single $1 $2 $3 + fi +fi + +if [ $1 != 'status' ]; then + echo "Please execute 'sudo config save' to preserve prefix list after reboot or config reload" +fi diff --git a/dockers/docker-fpm-frr/frr/bgpd/radian/add_radian.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/radian/add_radian.conf.j2 new file mode 100644 index 000000000000..b17de1808427 --- /dev/null +++ b/dockers/docker-fpm-frr/frr/bgpd/radian/add_radian.conf.j2 @@ -0,0 +1,11 @@ +{{ data.ipv }} prefix-list ANCHOR_CONTRIBUTING_ROUTES permit {{ data.prefix }} ge 48 +{# #} +router bgp {{ data.bgp_asn }} +{% if data.ipv == 'ip' -%} + address-family ipv4 unicast +{% else -%} + address-family ipv6 unicast +{% endif %} + aggregate-address {{ data.prefix }} route-map TAG_ANCHOR_COMMUNITY + exit +exit \ No newline at end of file diff --git a/dockers/docker-fpm-frr/frr/bgpd/radian/del_radian.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/radian/del_radian.conf.j2 new file mode 100644 index 000000000000..77374be9ae9e --- /dev/null +++ b/dockers/docker-fpm-frr/frr/bgpd/radian/del_radian.conf.j2 @@ -0,0 +1,10 @@ +no {{ data.ipv }} prefix-list ANCHOR_CONTRIBUTING_ROUTES permit {{ data.prefix }} ge 48 +router bgp {{ data.bgp_asn }} +{% if data.ipv == 'ip' -%} + address-family ipv4 unicast +{% else %} + address-family ipv6 unicast +{% endif -%} + no aggregate-address {{ data.prefix }} route-map TAG_ANCHOR_COMMUNITY + exit +exit \ No newline at end of file diff --git a/rules/docker-fpm-frr.mk b/rules/docker-fpm-frr.mk index e81105caaec2..c914dbff1da6 100644 --- a/rules/docker-fpm-frr.mk +++ b/rules/docker-fpm-frr.mk @@ -41,6 +41,7 @@ $(DOCKER_FPM_FRR)_BASE_IMAGE_FILES += TSB:/usr/bin/TSB $(DOCKER_FPM_FRR)_BASE_IMAGE_FILES += TSC:/usr/bin/TSC $(DOCKER_FPM_FRR)_BASE_IMAGE_FILES += TS:/usr/bin/TS $(DOCKER_FPM_FRR)_BASE_IMAGE_FILES += idf_isolation:/usr/bin/idf_isolation +$(DOCKER_FPM_FRR)_BASE_IMAGE_FILES += prefix_list:/usr/bin/prefix_list SONIC_BOOKWORM_DOCKERS += $(DOCKER_FPM_FRR) SONIC_BOOKWORM_DBG_DOCKERS += $(DOCKER_FPM_FRR_DBG) diff --git a/src/sonic-bgpcfgd/bgpcfgd/main.py b/src/sonic-bgpcfgd/bgpcfgd/main.py index bc50f22161c7..a39080bcfdc0 100644 --- a/src/sonic-bgpcfgd/bgpcfgd/main.py +++ b/src/sonic-bgpcfgd/bgpcfgd/main.py @@ -24,6 +24,7 @@ from .managers_chassis_app_db import ChassisAppDbMgr from .managers_bfd import BfdMgr from .managers_srv6 import SRv6Mgr +from .managers_prefix_list import PrefixListMgr from .static_rt_timer import StaticRouteTimer from .runner import Runner, signal_handler from .template import TemplateFabric @@ -79,7 +80,9 @@ def do_work(): DeviceGlobalCfgMgr(common_objs, "CONFIG_DB", swsscommon.CFG_BGP_DEVICE_GLOBAL_TABLE_NAME), # SRv6 Manager SRv6Mgr(common_objs, "CONFIG_DB", "SRV6_MY_SIDS"), - SRv6Mgr(common_objs, "CONFIG_DB", "SRV6_MY_LOCATORS") + SRv6Mgr(common_objs, "CONFIG_DB", "SRV6_MY_LOCATORS"), + # Prefix List Manager + PrefixListMgr(common_objs, "CONFIG_DB", "PREFIX_LIST") ] if device_info.is_chassis(): diff --git a/src/sonic-bgpcfgd/bgpcfgd/managers_prefix_list.py b/src/sonic-bgpcfgd/bgpcfgd/managers_prefix_list.py new file mode 100644 index 000000000000..40b55f6b3485 --- /dev/null +++ b/src/sonic-bgpcfgd/bgpcfgd/managers_prefix_list.py @@ -0,0 +1,105 @@ +from .manager import Manager +from .log import log_debug, log_warn, log_info +from swsscommon import swsscommon +import netaddr + +class PrefixListMgr(Manager): + """This class responds to changes in the PREFIX_LIST table""" + + def __init__(self, common_objs, db, table): + """ + Initialize the object + :param common_objs: common object dictionary + :param db: name of the db + :param table: name of the table in the db + """ + self.directory = common_objs['directory'] + self.cfg_mgr = common_objs['cfg_mgr'] + self.constants = common_objs['constants'] + self.templates = { + "add_radian": common_objs['tf'].from_file("bgpd/radian/add_radian.conf.j2"), + "del_radian": common_objs['tf'].from_file("bgpd/radian/del_radian.conf.j2"), + } + super(PrefixListMgr, self).__init__( + common_objs, + [], + db, + table, + ) + + def generate_prefix_list_config(self, data, add): + """ + Generate the prefix list configuration from the template + :param data: data from the PREFIX_LIST table + :return: rendered configuration + """ + cmd = "\n" + bgp_asn = self.directory.get_slot("CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME)["localhost"]["bgp_asn"] + localhost_type = self.directory.get_slot("CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME)["localhost"]["type"] + subtype = self.directory.get_slot("CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME)["localhost"]["subtype"] + if data["prefix_list_name"] == "ANCHOR_PREFIX" and localhost_type == "SpineRouter" and subtype == "UpstreamLC": + # Add the anchor prefix to the radian configuration` + data["bgp_asn"] = bgp_asn + if add: + # add some way of getting this asn list from the database in the future + cmd += self.templates["add_radian"].render(data=data) + log_debug("PrefixListMgr:: Anchor prefix %s added to radian configuration" % data["prefix"]) + else: + cmd += self.templates["del_radian"].render(data=data) + log_debug("PrefixListMgr:: Anchor prefix %s removed from radian configuration" % data["prefix"]) + self.cfg_mgr.push(cmd) + + + + def set_handler(self, key, data): + log_debug("PrefixListMgr:: set handler") + if '|' in key: + prefix_list_name, prefix_str = key.split('|', 1) + try: + prefix = netaddr.IPNetwork(str(prefix_str)) + except (netaddr.NotRegisteredError, netaddr.AddrFormatError, netaddr.AddrConversionError): + log_warn("PrefixListMgr:: Prefix '%s' format is wrong for prefix list '%s'" % (prefix_str, prefix_list_name)) + return True + data["prefix_list_name"] = prefix_list_name + data["prefix"] = str(prefix.cidr) + data["ipv"] = self.get_ip_type(prefix) + # Generate the prefix list configuration + self.generate_prefix_list_config(data, add=True) + log_info("PrefixListMgr:: %s %s configuration generated" % (prefix_list_name, data["prefix"])) + + self.directory.put(self.db_name, self.table_name, key, data) + log_info("PrefixListMgr:: set %s" % key) + return True + + def del_handler(self, key): + log_debug("PrefixListMgr:: del handler") + if '|' in key: + prefix_list_name, prefix_str = key.split('|', 1) + try: + prefix = netaddr.IPNetwork(str(prefix_str)) + except (netaddr.NotRegisteredError, netaddr.AddrFormatError, netaddr.AddrConversionError): + log_warn("PrefixListMgr:: Prefix '%s' format is wrong for prefix list '%s'" % (prefix_str, prefix_list_name)) + return True + data = {} + data["prefix_list_name"] = prefix_list_name + data["prefix"] = str(prefix.cidr) + data["ipv"] = self.get_ip_type(prefix) + self.generate_prefix_list_config(data, add=False) + log_info("PrefixListMgr:: %s %s configuration deleted" % (prefix_list_name, data["prefix"])) + self.directory.remove(self.db_name, self.table_name, key) + log_info("PrefixListMgr:: deleted %s" % key) + # Implement deletion logic if necessary + return True + + def get_ip_type(self, prefix: netaddr.IPNetwork): + """ + Determine the IP type (IPv4 or IPv6) of a prefix. + :param prefix: The prefix to check (e.g., "192.168.1.0/24" or "2001:db8::/32") + :return: "ip" if the prefix is an IPv4 address, "ipv6" if it is an IPv6 address, None if invalid + """ + if prefix.version == 4: + return "ip" + elif prefix.version == 6: + return "ipv6" + else: + return None \ No newline at end of file From d214e4996e5c5dee549f81b589c0e593ac872bf4 Mon Sep 17 00:00:00 2001 From: Mukul Chodhary Date: Tue, 4 Feb 2025 22:34:14 +0000 Subject: [PATCH 02/10] Moved radian route-maps to msft general, Added config gen tests Signed-off-by: Mukul Chodhary <70460358+Muckthebuck@users.noreply.github.com> --- .../templates/voq_chassis/policies.conf.j2 | 7 ++ files/image_config/constants/constants.yml | 1 + .../data/sonic-cfggen/radian/add_radian.conf | 6 ++ .../data/sonic-cfggen/radian/add_radian.json | 7 ++ .../data/sonic-cfggen/radian/del_radian.conf | 6 ++ .../data/sonic-cfggen/radian/del_radian.json | 7 ++ .../voq_chassis/policies.conf/param_base.json | 7 +- .../policies.conf/result_base.conf | 9 ++- src/sonic-bgpcfgd/tests/test_prefix_list.py | 70 +++++++++++++++++++ src/sonic-bgpcfgd/tests/test_sonic-cfggen.py | 12 ++++ 10 files changed, 128 insertions(+), 4 deletions(-) create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/radian/add_radian.conf create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/radian/add_radian.json create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/radian/del_radian.conf create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/radian/del_radian.json create mode 100644 src/sonic-bgpcfgd/tests/test_prefix_list.py 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 index 961587c6ebb7..b1ad80c53a3d 100644 --- 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 @@ -1,6 +1,7 @@ ! ! template: bgpd/templates/voq_chassis/policies.conf.j2 ! +bgp community-list standard LOCAL_ANCHOR_ROUTE_COMMUNITY permit {{ constants.bgp.local_anchor_route_community }} bgp community-list standard DEVICE_INTERNAL_COMMUNITY permit {{ constants.bgp.internal_community }} bgp community-list standard DEVICE_INTERNAL_FALLBACK_COMMUNITY permit {{ constants.bgp.internal_fallback_community }} bgp community-list standard NO_EXPORT permit no-export @@ -31,6 +32,9 @@ route-map TO_VOQ_CHASSIS_V4_PEER permit 1 match ip address prefix-list PL_LoopbackV4 set community {{ constants.bgp.internal_community }} ! +route-map TO_VOQ_CHASSIS_V4_PEER deny 15 + match community LOCAL_ANCHOR_ROUTE_COMMUNITY +! route-map TO_VOQ_CHASSIS_V4_PEER permit 100 ! route-map FROM_VOQ_CHASSIS_V6_PEER permit 1 @@ -63,6 +67,9 @@ route-map TO_VOQ_CHASSIS_V6_PEER permit 1 match ipv6 address prefix-list PL_LoopbackV6 set community {{ constants.bgp.internal_community }} ! +route-map TO_VOQ_CHASSIS_V6_PEER deny 15 + match community LOCAL_ANCHOR_ROUTE_COMMUNITY +! route-map TO_VOQ_CHASSIS_V6_PEER permit 100 ! ! 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 781055ba49b2..44a0698e7dfb 100644 --- a/files/image_config/constants/constants.yml +++ b/files/image_config/constants/constants.yml @@ -8,6 +8,7 @@ constants: internal_fallback_community: 22222:22222 sentinel_community: 12345:12346 internal_community_match_tag: 201 + local_anchor_route_community: 12345:555 route_do_not_send_appdb_tag: 202 route_eligible_for_fallback_to_default_tag: 203 families: diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/radian/add_radian.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/radian/add_radian.conf new file mode 100644 index 000000000000..56158fe170a2 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/radian/add_radian.conf @@ -0,0 +1,6 @@ +ipv6 prefix-list ANCHOR_CONTRIBUTING_ROUTES permit ffff::/64 ge 48 +router bgp 1234 +address-family ipv6 unicast + aggregate-address ffff::/64 route-map TAG_ANCHOR_COMMUNITY + exit +exit \ No newline at end of file diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/radian/add_radian.json b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/radian/add_radian.json new file mode 100644 index 000000000000..d8e992aa8ae4 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/radian/add_radian.json @@ -0,0 +1,7 @@ +{ + "data": { + "ipv": "ipv6", + "prefix": "ffff::/64", + "bgp_asn": 1234 + } +} diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/radian/del_radian.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/radian/del_radian.conf new file mode 100644 index 000000000000..165976815187 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/radian/del_radian.conf @@ -0,0 +1,6 @@ +no ipv6 prefix-list ANCHOR_CONTRIBUTING_ROUTES permit ffff::/64 ge 48 +router bgp 1234 + address-family ipv6 unicast +no aggregate-address ffff::/64 route-map TAG_ANCHOR_COMMUNITY + exit +exit \ No newline at end of file diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/radian/del_radian.json b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/radian/del_radian.json new file mode 100644 index 000000000000..d8e992aa8ae4 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/radian/del_radian.json @@ -0,0 +1,7 @@ +{ + "data": { + "ipv": "ipv6", + "prefix": "ffff::/64", + "bgp_asn": 1234 + } +} 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 index 1d2f80eed337..fd0aaf54580a 100644 --- 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 @@ -3,14 +3,15 @@ "localhost": { "type": "SpineRouter", "subtype": "DownstreamLC" - } + } }, "constants": { "bgp": { "internal_community": "12345:556", - "internal_community_match_tag": "101", + "internal_community_match_tag": "101", "route_eligible_for_fallback_to_default_tag": "203", - "internal_fallback_community": "1111:2222" + "internal_fallback_community": "1111:2222", + "local_anchor_route_community": "12345:555" } } } 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 index 10fe3c832655..f63593b85d5c 100644 --- 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 @@ -1,6 +1,7 @@ ! ! template: bgpd/templates/voq_chassis/policies.conf.j2 ! +bgp community-list standard LOCAL_ANCHOR_ROUTE_COMMUNITY permit 12345:555 bgp community-list standard DEVICE_INTERNAL_COMMUNITY permit 12345:556 bgp community-list standard DEVICE_INTERNAL_FALLBACK_COMMUNITY permit 1111:2222 bgp community-list standard NO_EXPORT permit no-export @@ -26,6 +27,9 @@ route-map TO_VOQ_CHASSIS_V4_PEER permit 1 match ip address prefix-list PL_LoopbackV4 set community 12345:556 ! +route-map TO_VOQ_CHASSIS_V4_PEER deny 15 + match community LOCAL_ANCHOR_ROUTE_COMMUNITY +! route-map TO_VOQ_CHASSIS_V4_PEER permit 100 ! route-map FROM_VOQ_CHASSIS_V6_PEER permit 1 @@ -53,7 +57,10 @@ route-map TO_VOQ_CHASSIS_V6_PEER permit 1 match ipv6 address prefix-list PL_LoopbackV6 set community 12345:556 ! +route-map TO_VOQ_CHASSIS_V6_PEER deny 15 + match community LOCAL_ANCHOR_ROUTE_COMMUNITY +! route-map TO_VOQ_CHASSIS_V6_PEER permit 100 ! ! end of template: bgpd/templates/voq_chassis/policies.conf.j2 -! +! \ No newline at end of file diff --git a/src/sonic-bgpcfgd/tests/test_prefix_list.py b/src/sonic-bgpcfgd/tests/test_prefix_list.py new file mode 100644 index 000000000000..9f1ef6a48c99 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/test_prefix_list.py @@ -0,0 +1,70 @@ +from unittest.mock import MagicMock, patch + +import os +from bgpcfgd.directory import Directory +from bgpcfgd.template import TemplateFabric +from . import swsscommon_test +from swsscommon import swsscommon + +from bgpcfgd.managers_prefix_list import PrefixListMgr + +TEMPLATE_PATH = os.path.abspath('../../dockers/docker-fpm-frr/frr') + +def constructor(): + cfg_mgr = MagicMock() + common_objs = { + 'directory': Directory(), + 'cfg_mgr': cfg_mgr, + 'tf': TemplateFabric(TEMPLATE_PATH), + 'constants': {}, + } + + m = PrefixListMgr(common_objs, "CONFIG_DB", "PREFIX_LIST") + m.directory.put("CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME, "localhost", {"bgp_asn": "65100", "type": "SpineRouter", "subtype": "UpstreamLC"}) + + return m + +def set_handler_test(manager, key, value): + res = manager.set_handler(key, value) + assert res, "Returns always True" + +def del_handler_test(manager, key): + res = manager.del_handler(key) + assert res, "Returns always True" + +# test if the ipv4 radian configs are set correctly +@patch('bgpcfgd.managers_prefix_list.log_debug') +def test_generate_prefix_list_config_ipv4(mocked_log_debug): + m = constructor() + set_handler_test(m, "ANCHOR_PREFIX|192.168.0.0/24", {}) + mocked_log_debug.assert_called_with("PrefixListMgr:: Anchor prefix 192.168.0.0/24 added to radian configuration") + +# test if the ipv6 radian configs are set correctly +@patch('bgpcfgd.managers_prefix_list.log_debug') +def test_generate_prefix_list_config_ipv6(mocked_log_debug): + m = constructor() + set_handler_test(m, "ANCHOR_PREFIX|fc02:100::/64", {}) + mocked_log_debug.assert_called_with("PrefixListMgr:: Anchor prefix fc02:100::/64 added to radian configuration") + +# test if invalid prefix is handled correctly +@patch('bgpcfgd.managers_prefix_list.log_warn') +def test_generate_prefix_list_config_invalid_prefix(mocked_log_warn): + m = constructor() + set_handler_test(m, "ANCHOR_PREFIX|invalid_prefix", {}) + mocked_log_warn.assert_called_with("PrefixListMgr:: Prefix 'invalid_prefix' format is wrong for prefix list 'ANCHOR_PREFIX'") + +# test if the ipv4 radian configs are deleted correctly +@patch('bgpcfgd.managers_prefix_list.log_debug') +def test_del_handler_ipv4(mocked_log_debug): + m = constructor() + set_handler_test(m, "ANCHOR_PREFIX|192.168.0.0/24", {}) + del_handler_test(m, "ANCHOR_PREFIX|192.168.0.0/24") + mocked_log_debug.assert_called_with("PrefixListMgr:: Anchor prefix 192.168.0.0/24 removed from radian configuration") + +# test if the ipv6 radian configs are deleted correctly +@patch('bgpcfgd.managers_prefix_list.log_debug') +def test_del_handler_ipv6(mocked_log_debug): + m = constructor() + set_handler_test(m, "ANCHOR_PREFIX|fc02:100::/64", {}) + del_handler_test(m, "ANCHOR_PREFIX|fc02:100::/64") + mocked_log_debug.assert_called_with("PrefixListMgr:: Anchor prefix fc02:100::/64 removed from radian configuration") \ No newline at end of file diff --git a/src/sonic-bgpcfgd/tests/test_sonic-cfggen.py b/src/sonic-bgpcfgd/tests/test_sonic-cfggen.py index 908c4d802e54..b259f41baf1a 100644 --- a/src/sonic-bgpcfgd/tests/test_sonic-cfggen.py +++ b/src/sonic-bgpcfgd/tests/test_sonic-cfggen.py @@ -206,3 +206,15 @@ def test_bgpd_main_conf_defaults_router_id(): "bgpd/bgpd.main.conf.j2", "bgpd.main.conf.j2/defaults_router_id.json", "bgpd.main.conf.j2/defaults_router_id.conf") + +def test_prefix_list_add_radian(): + run_test("Add radian configuration", + "bgpd/radian/add_radian.conf.j2", + "radian/add_radian.json", + "radian/add_radian.conf") + +def test_prefix_list_del_radian(): + run_test("Del radian configuration", + "bgpd/radian/del_radian.conf.j2", + "radian/del_radian.json", + "radian/del_radian.conf") \ No newline at end of file From 6b16ebaa0ab78f2016fc8ff32077b4f0bc6c106b Mon Sep 17 00:00:00 2001 From: Mukul Chodhary Date: Wed, 5 Feb 2025 05:33:13 +0000 Subject: [PATCH 03/10] Yang model changes for Anchor prefix Files modified/added 1. setup.py: added the bgp_prefix_list.yang to the setup list 2. sonic-bgp-prefix-list.yang: new yang model for the prefix list which is added in configdb through cli 3. test files to test the yang model Signed-off-by: Mukul Chodhary <70460358+Muckthebuck@users.noreply.github.com> --- src/sonic-yang-models/doc/Configuration.md | 13 ++++ src/sonic-yang-models/setup.py | 1 + .../tests/files/sample_config_db.json | 4 ++ .../tests/bgp_prefix_list.json | 13 ++++ .../tests_config/bgp_prefix_list.json | 40 ++++++++++++ .../yang-models/sonic-bgp-prefix-list.yang | 63 +++++++++++++++++++ 6 files changed, 134 insertions(+) create mode 100644 src/sonic-yang-models/tests/yang_model_tests/tests/bgp_prefix_list.json create mode 100644 src/sonic-yang-models/tests/yang_model_tests/tests_config/bgp_prefix_list.json create mode 100644 src/sonic-yang-models/yang-models/sonic-bgp-prefix-list.yang diff --git a/src/sonic-yang-models/doc/Configuration.md b/src/sonic-yang-models/doc/Configuration.md index 14a90731cd60..8196c7079b75 100644 --- a/src/sonic-yang-models/doc/Configuration.md +++ b/src/sonic-yang-models/doc/Configuration.md @@ -94,6 +94,7 @@ * [Static DNS](#static-dns) * [ASIC_SENSORS](#asic_sensors) * [SRv6](#srv6) + * [Prefix List](#prefix-list) * [For Developers](#for-developers) * [Generating Application Config by Jinja2 Template](#generating-application-config-by-jinja2-template) * [Incremental Configuration by Subscribing to ConfigDB](#incremental-configuration-by-subscribing-to-configdb) @@ -2913,6 +2914,18 @@ An example is as follows: } ``` +### Prefix List +Prefix list table stores a list of prefixes with type and prefix separated by `|`. The specific configuration for the prefix type are then rendered by the PrefixListMgr. Currently ANCHOR_PREFIX is supported to add RADIAN configuration. + +An example is as follows: +```json +{ + "PREFIX_LIST": { + "ANCHOR_PREFIX|fc00::/48": {} + } +} +``` + ### FIPS The FIPS table introduces FIPS configuration. diff --git a/src/sonic-yang-models/setup.py b/src/sonic-yang-models/setup.py index 02668030182c..ac670d49c1fe 100644 --- a/src/sonic-yang-models/setup.py +++ b/src/sonic-yang-models/setup.py @@ -205,6 +205,7 @@ def run(self): './yang-models/sonic-system-port.yang', './yang-models/sonic-macsec.yang', './yang-models/sonic-bgp-sentinel.yang', + './yang-models/sonic-bgp-prefix-list.yang', './yang-models/sonic-asic-sensors.yang', './yang-models/sonic-bmp.yang', './yang-models/sonic-xcvrd-log.yang', diff --git a/src/sonic-yang-models/tests/files/sample_config_db.json b/src/sonic-yang-models/tests/files/sample_config_db.json index 6a4ca851e76b..710151ef6662 100644 --- a/src/sonic-yang-models/tests/files/sample_config_db.json +++ b/src/sonic-yang-models/tests/files/sample_config_db.json @@ -2852,6 +2852,10 @@ "action": "uN", "decap_dscp_mode": "pipe" } + }, + "PREFIX_LIST": { + "ANCHOR_PREFIX|10.0.0.0/8" : {}, + "ANCHOR_PREFIX|FC00::/48" : {} } }, "SAMPLE_CONFIG_DB_UNKNOWN": { diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests/bgp_prefix_list.json b/src/sonic-yang-models/tests/yang_model_tests/tests/bgp_prefix_list.json new file mode 100644 index 000000000000..85d3f7956a2b --- /dev/null +++ b/src/sonic-yang-models/tests/yang_model_tests/tests/bgp_prefix_list.json @@ -0,0 +1,13 @@ +{ + "BGP_PREFIX_LIST_WITH_VALID_IPV4_PREFIX": { + "desc": "Load BGP prefix list table with a valid IPv4 prefix" + }, + "BGP_PREFIX_LIST_WITH_VALID_IPV6_PREFIX": { + "desc": "Load BGP prefix list table with a valid IPv6 prefix" + }, + "BGP_PREFIX_LIST_WITH_INVALID_PREFIX": { + "desc": "Load BGP prefix list table with an invalid prefix", + "eStrKey": "InvalidValue", + "eStr": ["prefix"] + } +} diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests_config/bgp_prefix_list.json b/src/sonic-yang-models/tests/yang_model_tests/tests_config/bgp_prefix_list.json new file mode 100644 index 000000000000..5447f13e98eb --- /dev/null +++ b/src/sonic-yang-models/tests/yang_model_tests/tests_config/bgp_prefix_list.json @@ -0,0 +1,40 @@ +{ + "BGP_PREFIX_LIST_WITH_VALID_IPV4_PREFIX": { + "sonic-bgp-prefix-list:sonic-bgp-prefix-list": { + "sonic-bgp-prefix-list:PREFIX_LIST": { + "PREFIX_LIST_LIST": [ + { + "name": "ANCHOR_PREFIX", + "ip-prefix": "10.0.0.0/8" + } + ] + } + } + }, + "BGP_PREFIX_LIST_WITH_VALID_IPV6_PREFIX": { + "sonic-bgp-prefix-list:sonic-bgp-prefix-list": { + "sonic-bgp-prefix-list:PREFIX_LIST": { + "PREFIX_LIST_LIST": [ + { + "name": "ANCHOR_PREFIX", + "ip-prefix": "fc00::/48" + } + ] + } + } + }, + "BGP_PREFIX_LIST_WITH_INVALID_PREFIX": { + "sonic-bgp-prefix-list:sonic-bgp-prefix-list": { + "sonic-bgp-prefix-list:PREFIX_LIST": { + "PREFIX_LIST_LIST": [ + { + "name": "ANCHOR_PREFIX", + "ip-prefix": "invalid_prefix" + } + ] + } + }, + "eStrKey": "InvalidValue", + "eStr": ["prefix"] + } +} \ No newline at end of file diff --git a/src/sonic-yang-models/yang-models/sonic-bgp-prefix-list.yang b/src/sonic-yang-models/yang-models/sonic-bgp-prefix-list.yang new file mode 100644 index 000000000000..0a0fda1856f5 --- /dev/null +++ b/src/sonic-yang-models/yang-models/sonic-bgp-prefix-list.yang @@ -0,0 +1,63 @@ + +module sonic-bgp-prefix-list { + + yang-version 1.1; + + namespace "http://github.com/sonic-net/sonic-bgp-prefix-list"; + prefix bgppl; + + import sonic-types { + prefix stypes; + } + + import sonic-extension { + prefix ext; + } + + description "SONIC Device-specfifc BGP prefix lists data"; + + revision 2025-02-05 { + description "Initial revision."; + } + + container sonic-bgp-prefix-list { + + container PREFIX_LIST { + + description "PREFIX_LIST part of config_db.json"; + + list PREFIX_LIST_LIST { + + description "PREFIX_LIST part of config_db.json with prefix"; + + key "name ip-prefix"; + + leaf name { + type string; + description "Name of the prefix list"; + } + + leaf ip-prefix { + type union { + type stypes:sonic-ip4-prefix; + type stypes:sonic-ip6-prefix; + } + } + + leaf family { + + /* family leaf needed for backward compatibility + Both ip4 and ip6 address are string in IETF RFC 6021, + so must statement can check based on : or ., family + should be IPv4 or IPv6 according. + */ + + must "(contains(../ip-prefix, ':') and current()='IPv6') or + (contains(../ip-prefix, '.') and current()='IPv4')"; + type stypes:ip-family; + } + } + } + /* end of PREFIX_LIST */ + } +} From 3e0b7f8cbd61e5f775b28ee2a77416a1b8dce733 Mon Sep 17 00:00:00 2001 From: Mukul Chodhary <70460358+Muckthebuck@users.noreply.github.com> Date: Fri, 14 Feb 2025 21:45:37 +1100 Subject: [PATCH 04/10] Modified prefix_list and manager err check logic added correct check for UpstreamLC and stderr statements Signed-off-by: Mukul Chodhary <70460358+Muckthebuck@users.noreply.github.com> --- .../base_image_files/prefix_list | 30 ++++++++-------- .../bgpcfgd/managers_prefix_list.py | 34 ++++++++++++------- 2 files changed, 35 insertions(+), 29 deletions(-) diff --git a/dockers/docker-fpm-frr/base_image_files/prefix_list b/dockers/docker-fpm-frr/base_image_files/prefix_list index f27212f49c4d..a90e6ac6a80b 100644 --- a/dockers/docker-fpm-frr/base_image_files/prefix_list +++ b/dockers/docker-fpm-frr/base_image_files/prefix_list @@ -27,15 +27,19 @@ display_help() { # Function to check if the user has root privileges check_root_privileges() { if [ "$EUID" -ne 0 ] ; then - echo "Root privileges are needed for this operation" + echo "Root privileges are needed for this operation." >&2 exit 1 fi } -# Function to check if the command is supported on spine routers +# Function to check if the device is supported device with type spine routers and subtype UpstreamLC check_spine_router() { - if [[ "$(sonic-cfggen -d -v DEVICE_METADATA.localhost.type)" != *"SpineRouter"* ]] ; then - echo "Operation is not supported on this platform" + type=$(sonic-cfggen -d -v DEVICE_METADATA.localhost.type) + sub_type=$(sonic-cfggen -d -v DEVICE_METADATA.localhost.sub_type) + + # only supported on spine routers and UpstreamLC + if [[ "$type" != "SpineRouter" || "$sub_type" != "UpstreamLC" ]]; then + echo "Operation is only supported on UpstreamLC of SpineRouter." >&2 exit 1 fi } @@ -61,10 +65,10 @@ validate_operation() { done if [ $valid_operation == false ]; then - echo "Invalid parameter $1, Operation not supported" + echo "Invalid parameter $1, Operation not supported" >&2 echo "" display_help - exit 0 + exit 1 fi # Check if the prefix type is supported or not if the operation is not status @@ -77,10 +81,10 @@ validate_operation() { done if [ $valid_prefix_type == false ]; then - echo "Invalid parameter $2, Prefix type not supported" + echo "Invalid parameter $2, Prefix type not supported" >&2 echo "" display_help - exit 0 + exit 1 fi fi } @@ -160,19 +164,13 @@ if [[ ($NUM_ASIC -gt 1) ]]; then while [ $asic -lt $NUM_ASIC ] do sub_role=`sonic-cfggen -d -v "DEVICE_METADATA['localhost']['sub_role']" -n asic$asic` - subtype=`sonic-cfggen -d -v "DEVICE_METADATA['localhost']['subtype']" -n asic$asic` - if [ $sub_role == 'FrontEnd' ] ; then - if [ $subtype == 'UpstreamLC' ] ; then - handle_prefix_list_asic $asic $1 $2 $3 - fi + if [ $sub_role == 'FrontEnd' ]; then + handle_prefix_list_asic $asic $1 $2 $3 fi asic=$((asic+1)) done else - subtype=`sonic-cfggen -d -v "DEVICE_METADATA['localhost']['subtype']"` - if [ $subtype == 'UpstreamLC' ] ; then handle_prefix_list_single $1 $2 $3 - fi fi if [ $1 != 'status' ]; then diff --git a/src/sonic-bgpcfgd/bgpcfgd/managers_prefix_list.py b/src/sonic-bgpcfgd/bgpcfgd/managers_prefix_list.py index 40b55f6b3485..0b97f04e92ce 100644 --- a/src/sonic-bgpcfgd/bgpcfgd/managers_prefix_list.py +++ b/src/sonic-bgpcfgd/bgpcfgd/managers_prefix_list.py @@ -34,19 +34,27 @@ def generate_prefix_list_config(self, data, add): :return: rendered configuration """ cmd = "\n" - bgp_asn = self.directory.get_slot("CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME)["localhost"]["bgp_asn"] - localhost_type = self.directory.get_slot("CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME)["localhost"]["type"] - subtype = self.directory.get_slot("CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME)["localhost"]["subtype"] - if data["prefix_list_name"] == "ANCHOR_PREFIX" and localhost_type == "SpineRouter" and subtype == "UpstreamLC": - # Add the anchor prefix to the radian configuration` - data["bgp_asn"] = bgp_asn - if add: - # add some way of getting this asn list from the database in the future - cmd += self.templates["add_radian"].render(data=data) - log_debug("PrefixListMgr:: Anchor prefix %s added to radian configuration" % data["prefix"]) - else: - cmd += self.templates["del_radian"].render(data=data) - log_debug("PrefixListMgr:: Anchor prefix %s removed from radian configuration" % data["prefix"]) + metadata = self.directory.get_slot("CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME)["localhost"] + bgp_asn = metadata["bgp_asn"] + localhost_type = metadata["type"] + subtype = metadata["subtype"] + + if data["prefix_list_name"] != "ANCHOR_PREFIX": + log_warn("PrefixListMgr:: Prefix list %s is not supported" % data["prefix_list_name"]) + return + if localhost_type != "SpineRouter" or subtype != "UpstreamLC": + log_warn("PrefixListMgr:: Prefix list %s is only supported on UpstreamLC of SpineRouter" % data["prefix_list_name"]) + return + + # Add the anchor prefix to the radian configuration + data["bgp_asn"] = bgp_asn + if add: + # add some way of getting this asn list from the database in the future + cmd += self.templates["add_radian"].render(data=data) + log_debug("PrefixListMgr:: Anchor prefix %s added to radian configuration" % data["prefix"]) + else: + cmd += self.templates["del_radian"].render(data=data) + log_debug("PrefixListMgr:: Anchor prefix %s removed from radian configuration" % data["prefix"]) self.cfg_mgr.push(cmd) From fd26d878bcce2e272e13d1cbc62f489fc50c31be Mon Sep 17 00:00:00 2001 From: Mukul Chodhary <70460358+Muckthebuck@users.noreply.github.com> Date: Mon, 17 Feb 2025 09:36:10 +1100 Subject: [PATCH 05/10] Updated prefix-list yang model desc Signed-off-by: Mukul Chodhary <70460358+Muckthebuck@users.noreply.github.com> --- .../tests_config/bgp_prefix_list.json | 6 +++--- .../yang-models/sonic-bgp-prefix-list.yang | 14 +++++++++----- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests_config/bgp_prefix_list.json b/src/sonic-yang-models/tests/yang_model_tests/tests_config/bgp_prefix_list.json index 5447f13e98eb..5191ba7e8511 100644 --- a/src/sonic-yang-models/tests/yang_model_tests/tests_config/bgp_prefix_list.json +++ b/src/sonic-yang-models/tests/yang_model_tests/tests_config/bgp_prefix_list.json @@ -4,7 +4,7 @@ "sonic-bgp-prefix-list:PREFIX_LIST": { "PREFIX_LIST_LIST": [ { - "name": "ANCHOR_PREFIX", + "prefix_type": "ANCHOR_PREFIX", "ip-prefix": "10.0.0.0/8" } ] @@ -16,7 +16,7 @@ "sonic-bgp-prefix-list:PREFIX_LIST": { "PREFIX_LIST_LIST": [ { - "name": "ANCHOR_PREFIX", + "prefix_type": "ANCHOR_PREFIX", "ip-prefix": "fc00::/48" } ] @@ -28,7 +28,7 @@ "sonic-bgp-prefix-list:PREFIX_LIST": { "PREFIX_LIST_LIST": [ { - "name": "ANCHOR_PREFIX", + "prefix_type": "ANCHOR_PREFIX", "ip-prefix": "invalid_prefix" } ] diff --git a/src/sonic-yang-models/yang-models/sonic-bgp-prefix-list.yang b/src/sonic-yang-models/yang-models/sonic-bgp-prefix-list.yang index 0a0fda1856f5..78441450addc 100644 --- a/src/sonic-yang-models/yang-models/sonic-bgp-prefix-list.yang +++ b/src/sonic-yang-models/yang-models/sonic-bgp-prefix-list.yang @@ -16,6 +16,10 @@ module sonic-bgp-prefix-list { description "SONIC Device-specfifc BGP prefix lists data"; + revision 2025-02-17 { + description "Updated description and leafs for PREFIX_LIST_LIST"; + } + revision 2025-02-05 { description "Initial revision."; } @@ -24,17 +28,17 @@ module sonic-bgp-prefix-list { container PREFIX_LIST { - description "PREFIX_LIST part of config_db.json"; + description "PREFIX_LIST container consumed in BGP"; list PREFIX_LIST_LIST { - description "PREFIX_LIST part of config_db.json with prefix"; + description "PREFIX_LIST part of config_db.json with prefix_type and ip-prefix"; - key "name ip-prefix"; + key "prefix_type ip-prefix"; - leaf name { + leaf prefix_type { type string; - description "Name of the prefix list"; + description "Prefix type"; } leaf ip-prefix { From 949ebeeddcb7f40970b1d3062f7355c3ad7b4da3 Mon Sep 17 00:00:00 2001 From: Mukul Chodhary <70460358+Muckthebuck@users.noreply.github.com> Date: Thu, 20 Feb 2025 15:31:02 +1100 Subject: [PATCH 06/10] General route-maps and prefix_list manager fix Signed-off-by: Mukul Chodhary <70460358+Muckthebuck@users.noreply.github.com> --- .../bgpd/templates/general/peer-group.conf.j2 | 4 ++ .../bgpd/templates/general/policies.conf.j2 | 39 ++++++++++++++++ files/image_config/constants/constants.yml | 2 + .../bgpcfgd/managers_prefix_list.py | 32 +++++++------ .../policies.conf/param_all_chassis_pkt.json | 11 +++-- .../general/policies.conf/param_all_voq.json | 11 +++-- .../policies.conf/result_all_chassis_pkt.conf | 46 ++++++++++++++++++- .../general/policies.conf/result_all_voq.conf | 44 +++++++++++++++++- 8 files changed, 165 insertions(+), 24 deletions(-) diff --git a/dockers/docker-fpm-frr/frr/bgpd/templates/general/peer-group.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/general/peer-group.conf.j2 index 2617cc94c2d2..7b4b16941810 100644 --- a/dockers/docker-fpm-frr/frr/bgpd/templates/general/peer-group.conf.j2 +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/general/peer-group.conf.j2 @@ -26,6 +26,10 @@ neighbor PEER_V6 soft-reconfiguration inbound neighbor PEER_V6 route-map FROM_BGP_PEER_V6 in neighbor PEER_V6 route-map TO_BGP_PEER_V6 out +{% if CONFIG_DB__DEVICE_METADATA['localhost']['type'] == 'SpineRouter' %} + table-map SELECTIVE_ROUTE_DOWNLOAD_V4 + table-map SELECTIVE_ROUTE_DOWNLOAD_V6 +{% endif %} exit-address-family ! ! end of template: bgpd/templates/general/peer-group.conf.j2 diff --git a/dockers/docker-fpm-frr/frr/bgpd/templates/general/policies.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/general/policies.conf.j2 index 8db76a69f848..b2f677a438c0 100644 --- a/dockers/docker-fpm-frr/frr/bgpd/templates/general/policies.conf.j2 +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/general/policies.conf.j2 @@ -97,5 +97,44 @@ route-map TO_BGP_PEER_V6 permit 100 ! route-map CHECK_IDF_ISOLATION permit 10 ! +! +! +{% if CONFIG_DB__DEVICE_METADATA and 'localhost' in CONFIG_DB__DEVICE_METADATA and 'type' in CONFIG_DB__DEVICE_METADATA['localhost'] and 'subtype' in CONFIG_DB__DEVICE_METADATA['localhost'] %} +{% if CONFIG_DB__DEVICE_METADATA['localhost']['type'] == 'SpineRouter' and CONFIG_DB__DEVICE_METADATA['localhost']['subtype'] == 'UpstreamLC' %} +bgp community-list standard ANCHOR_ROUTE_COMMUNITY permit {{ constants.bgp.anchor_route_community }} +bgp community-list standard LOCAL_ANCHOR_ROUTE_COMMUNITY permit {{ constants.bgp.local_anchor_route_community }} +bgp community-list standard ANCHOR_CONTRIBUTING_ROUTE_COMMUNITY permit {{ constants.bgp.anchor_contributing_route_community }} +! +route-map SELECTIVE_ROUTE_DOWNLOAD_V4 deny 10 + match community LOCAL_ANCHOR_ROUTE_COMMUNITY +! +route-map SELECTIVE_ROUTE_DOWNLOAD_V4 permit 1000 +! +route-map SELECTIVE_ROUTE_DOWNLOAD_V6 deny 10 + match community LOCAL_ANCHOR_ROUTE_COMMUNITY +! +route-map SELECTIVE_ROUTE_DOWNLOAD_V6 permit 1000 +! +route-map TAG_ANCHOR_COMMUNITY permit 10 + set community {{ constants.bgp.local_anchor_route_community }} {{ constants.bgp.anchor_route_community }} additive +! +route-map TO_BGP_PEER_V6 permit 30 + match ipv6 address prefix-list ANCHOR_CONTRIBUTING_ROUTES + set community {{ constants.bgp.anchor_contributing_route_community }} additive + on-match next +! +route-map TO_BGP_PEER_V6 permit 40 + set comm-list LOCAL_ANCHOR_ROUTE_COMMUNITY delete +! +route-map TO_BGP_PEER_V4 permit 30 + match ipv6 address prefix-list ANCHOR_CONTRIBUTING_ROUTES + set community {{ constants.bgp.anchor_contributing_route_community }} additive + on-match next +! +route-map TO_BGP_PEER_V4 permit 40 + set comm-list LOCAL_ANCHOR_ROUTE_COMMUNITY delete +! +{% endif %} +{% endif %} ! end of template: bgpd/templates/general/policies.conf.j2 ! diff --git a/files/image_config/constants/constants.yml b/files/image_config/constants/constants.yml index 44a0698e7dfb..61c28d8be466 100644 --- a/files/image_config/constants/constants.yml +++ b/files/image_config/constants/constants.yml @@ -9,6 +9,8 @@ constants: sentinel_community: 12345:12346 internal_community_match_tag: 201 local_anchor_route_community: 12345:555 + anchor_route_community: 12345:666 + anchor_contributing_route_community: 12345:777 route_do_not_send_appdb_tag: 202 route_eligible_for_fallback_to_default_tag: 203 families: diff --git a/src/sonic-bgpcfgd/bgpcfgd/managers_prefix_list.py b/src/sonic-bgpcfgd/bgpcfgd/managers_prefix_list.py index 0b97f04e92ce..965dea9ff247 100644 --- a/src/sonic-bgpcfgd/bgpcfgd/managers_prefix_list.py +++ b/src/sonic-bgpcfgd/bgpcfgd/managers_prefix_list.py @@ -35,16 +35,20 @@ def generate_prefix_list_config(self, data, add): """ cmd = "\n" metadata = self.directory.get_slot("CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME)["localhost"] - bgp_asn = metadata["bgp_asn"] - localhost_type = metadata["type"] - subtype = metadata["subtype"] + try: + bgp_asn = metadata["bgp_asn"] + localhost_type = metadata["type"] + subtype = metadata["subtype"] + except KeyError as e: + log_warn(f"PrefixListMgr:: Missing metadata key: {e}") + return False if data["prefix_list_name"] != "ANCHOR_PREFIX": log_warn("PrefixListMgr:: Prefix list %s is not supported" % data["prefix_list_name"]) - return + return False if localhost_type != "SpineRouter" or subtype != "UpstreamLC": log_warn("PrefixListMgr:: Prefix list %s is only supported on UpstreamLC of SpineRouter" % data["prefix_list_name"]) - return + return False # Add the anchor prefix to the radian configuration data["bgp_asn"] = bgp_asn @@ -56,6 +60,7 @@ def generate_prefix_list_config(self, data, add): cmd += self.templates["del_radian"].render(data=data) log_debug("PrefixListMgr:: Anchor prefix %s removed from radian configuration" % data["prefix"]) self.cfg_mgr.push(cmd) + return True @@ -72,11 +77,11 @@ def set_handler(self, key, data): data["prefix"] = str(prefix.cidr) data["ipv"] = self.get_ip_type(prefix) # Generate the prefix list configuration - self.generate_prefix_list_config(data, add=True) - log_info("PrefixListMgr:: %s %s configuration generated" % (prefix_list_name, data["prefix"])) + if self.generate_prefix_list_config(data, add=True): + log_info("PrefixListMgr:: %s %s configuration generated" % (prefix_list_name, data["prefix"])) - self.directory.put(self.db_name, self.table_name, key, data) - log_info("PrefixListMgr:: set %s" % key) + self.directory.put(self.db_name, self.table_name, key, data) + log_info("PrefixListMgr:: set %s" % key) return True def del_handler(self, key): @@ -92,10 +97,11 @@ def del_handler(self, key): data["prefix_list_name"] = prefix_list_name data["prefix"] = str(prefix.cidr) data["ipv"] = self.get_ip_type(prefix) - self.generate_prefix_list_config(data, add=False) - log_info("PrefixListMgr:: %s %s configuration deleted" % (prefix_list_name, data["prefix"])) - self.directory.remove(self.db_name, self.table_name, key) - log_info("PrefixListMgr:: deleted %s" % key) + # remove the prefix list configuration + if self.generate_prefix_list_config(data, add=False): + log_info("PrefixListMgr:: %s %s configuration deleted" % (prefix_list_name, data["prefix"])) + self.directory.remove(self.db_name, self.table_name, key) + log_info("PrefixListMgr:: deleted %s" % key) # Implement deletion logic if necessary return True diff --git a/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_all_chassis_pkt.json b/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_all_chassis_pkt.json index 0a96a1cacfd6..420577ef399e 100644 --- a/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_all_chassis_pkt.json +++ b/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_all_chassis_pkt.json @@ -5,10 +5,13 @@ "allow_list": { "enabled": true, "drop_community": "12345:12345" - }, - "route_eligible_for_fallback_to_default_tag": "203", - "route_do_not_send_appdb_tag" : "202", - "internal_fallback_community": "1111:2222" + }, + "route_eligible_for_fallback_to_default_tag": "203", + "route_do_not_send_appdb_tag" : "202", + "internal_fallback_community": "1111:2222", + "local_anchor_route_community": "12345:555", + "anchor_route_community": "12345:666", + "anchor_contributing_route_community": "12345:777" } }, "allow_list_default_action": "permit", diff --git a/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_all_voq.json b/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_all_voq.json index a940effc8463..f4e0f9447f1f 100644 --- a/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_all_voq.json +++ b/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_all_voq.json @@ -5,10 +5,13 @@ "allow_list": { "enabled": true, "drop_community": "12345:12345" - }, - "route_eligible_for_fallback_to_default_tag": "203", - "route_do_not_send_appdb_tag" : "202", - "internal_fallback_community": "1111:2222" + }, + "route_eligible_for_fallback_to_default_tag": "203", + "route_do_not_send_appdb_tag" : "202", + "internal_fallback_community": "1111:2222", + "local_anchor_route_community": "12345:555", + "anchor_route_community": "12345:666", + "anchor_contributing_route_community": "12345:777" } }, "allow_list_default_action": "permit", diff --git a/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_all_chassis_pkt.conf b/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_all_chassis_pkt.conf index 7262a0c857d1..448abc01fb37 100644 --- a/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_all_chassis_pkt.conf +++ b/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_all_chassis_pkt.conf @@ -1,13 +1,17 @@ ! ! template: bgpd/templates/general/policies.conf.j2 ! +! ip prefix-list DEFAULT_IPV4 permit 0.0.0.0/0 ipv6 prefix-list DEFAULT_IPV6 permit ::/0 ! +! +! ! please don't remove. 65535 entries are default rules ! which works when allow_list is enabled, but new configuration ! is not applied ! +! route-map ALLOW_LIST_DEPLOYMENT_ID_0_V4 permit 65535 set community 12345:12345 additive ! @@ -45,13 +49,16 @@ route-map FROM_BGP_PEER_V6 permit 12 ! route-map FROM_BGP_PEER_V6 permit 13 set tag 203 - set community 1111:2222 additive + set community 1111:2222 additive ! +! +! ! route-map FROM_BGP_PEER_V4 permit 100 ! route-map TO_BGP_PEER_V4 permit 100 call CHECK_IDF_ISOLATION ! +! route-map FROM_BGP_PEER_V6 permit 1 on-match next set ipv6 next-hop prefer-global @@ -63,5 +70,40 @@ route-map TO_BGP_PEER_V6 permit 100 ! route-map CHECK_IDF_ISOLATION permit 10 ! -! end of template: bgpd/templates/general/policies.conf.j2 ! +! +bgp community-list standard ANCHOR_ROUTE_COMMUNITY permit 12345:666 +bgp community-list standard LOCAL_ANCHOR_ROUTE_COMMUNITY permit 12345:555 +bgp community-list standard ANCHOR_CONTRIBUTING_ROUTE_COMMUNITY permit 12345:777 +! +route-map SELECTIVE_ROUTE_DOWNLOAD_V4 deny 10 + match community LOCAL_ANCHOR_ROUTE_COMMUNITY +! +route-map SELECTIVE_ROUTE_DOWNLOAD_V4 permit 1000 +! +route-map SELECTIVE_ROUTE_DOWNLOAD_V6 deny 10 + match community LOCAL_ANCHOR_ROUTE_COMMUNITY +! +route-map SELECTIVE_ROUTE_DOWNLOAD_V6 permit 1000 +! +route-map TAG_ANCHOR_COMMUNITY permit 10 + set community 12345:555 12345:666 additive +! +route-map TO_BGP_PEER_V6 permit 30 + match ipv6 address prefix-list ANCHOR_CONTRIBUTING_ROUTES + set community 12345:777 additive + on-match next +! +route-map TO_BGP_PEER_V6 permit 40 + set comm-list LOCAL_ANCHOR_ROUTE_COMMUNITY delete +! +route-map TO_BGP_PEER_V4 permit 30 + match ipv6 address prefix-list ANCHOR_CONTRIBUTING_ROUTES + set community 12345:777 additive + on-match next +! +route-map TO_BGP_PEER_V4 permit 40 + set comm-list LOCAL_ANCHOR_ROUTE_COMMUNITY delete +! +! end of template: bgpd/templates/general/policies.conf.j2 +! \ No newline at end of file diff --git a/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_all_voq.conf b/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_all_voq.conf index 9c6b1fc28422..c746f30dd0a3 100644 --- a/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_all_voq.conf +++ b/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_all_voq.conf @@ -1,13 +1,17 @@ ! ! template: bgpd/templates/general/policies.conf.j2 ! +! ip prefix-list DEFAULT_IPV4 permit 0.0.0.0/0 ipv6 prefix-list DEFAULT_IPV6 permit ::/0 ! +! +! ! please don't remove. 65535 entries are default rules ! which works when allow_list is enabled, but new configuration ! is not applied ! +! route-map ALLOW_LIST_DEPLOYMENT_ID_0_V4 permit 65535 set community 12345:12345 additive ! @@ -45,13 +49,16 @@ route-map FROM_BGP_PEER_V6 permit 12 ! route-map FROM_BGP_PEER_V6 permit 13 set tag 202 - set community 1111:2222 additive + set community 1111:2222 additive ! +! +! ! route-map FROM_BGP_PEER_V4 permit 100 ! route-map TO_BGP_PEER_V4 permit 100 call CHECK_IDF_ISOLATION ! +! route-map FROM_BGP_PEER_V6 permit 1 on-match next set ipv6 next-hop prefer-global @@ -63,5 +70,40 @@ route-map TO_BGP_PEER_V6 permit 100 ! route-map CHECK_IDF_ISOLATION permit 10 ! +! +! +bgp community-list standard ANCHOR_ROUTE_COMMUNITY permit 12345:666 +bgp community-list standard LOCAL_ANCHOR_ROUTE_COMMUNITY permit 12345:555 +bgp community-list standard ANCHOR_CONTRIBUTING_ROUTE_COMMUNITY permit 12345:777 +! +route-map SELECTIVE_ROUTE_DOWNLOAD_V4 deny 10 + match community LOCAL_ANCHOR_ROUTE_COMMUNITY +! +route-map SELECTIVE_ROUTE_DOWNLOAD_V4 permit 1000 +! +route-map SELECTIVE_ROUTE_DOWNLOAD_V6 deny 10 + match community LOCAL_ANCHOR_ROUTE_COMMUNITY +! +route-map SELECTIVE_ROUTE_DOWNLOAD_V6 permit 1000 +! +route-map TAG_ANCHOR_COMMUNITY permit 10 + set community 12345:555 12345:666 additive +! +route-map TO_BGP_PEER_V6 permit 30 + match ipv6 address prefix-list ANCHOR_CONTRIBUTING_ROUTES + set community 12345:777 additive + on-match next +! +route-map TO_BGP_PEER_V6 permit 40 + set comm-list LOCAL_ANCHOR_ROUTE_COMMUNITY delete +! +route-map TO_BGP_PEER_V4 permit 30 + match ipv6 address prefix-list ANCHOR_CONTRIBUTING_ROUTES + set community 12345:777 additive + on-match next +! +route-map TO_BGP_PEER_V4 permit 40 + set comm-list LOCAL_ANCHOR_ROUTE_COMMUNITY delete +! ! end of template: bgpd/templates/general/policies.conf.j2 ! From 92ad09d313e5de666a5f3bcf294d17ce692ca04d Mon Sep 17 00:00:00 2001 From: Mukul Chodhary <70460358+Muckthebuck@users.noreply.github.com> Date: Fri, 21 Feb 2025 10:17:38 +1100 Subject: [PATCH 07/10] General policy tests with new config changes Signed-off-by: Mukul Chodhary <70460358+Muckthebuck@users.noreply.github.com> --- .../frr/bgpd/templates/general/policies.conf.j2 | 3 ++- .../general/policies.conf/param_all_chassis_pkt_down.json | 4 ++-- .../tests/data/general/policies.conf/param_all_voq_down.json | 4 ++-- .../data/general/policies.conf/result_all_chassis_pkt.conf | 3 ++- .../tests/data/general/policies.conf/result_all_voq.conf | 3 ++- 5 files changed, 10 insertions(+), 7 deletions(-) diff --git a/dockers/docker-fpm-frr/frr/bgpd/templates/general/policies.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/general/policies.conf.j2 index b2f677a438c0..07cea2e22e96 100644 --- a/dockers/docker-fpm-frr/frr/bgpd/templates/general/policies.conf.j2 +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/general/policies.conf.j2 @@ -73,7 +73,8 @@ route-map FROM_BGP_PEER_V6 permit 13 {% else %} set tag {{ constants.bgp.route_eligible_for_fallback_to_default_tag }} {% endif %} - set community {{ constants.bgp.internal_fallback_community }} additive {% endif %} + set community {{ constants.bgp.internal_fallback_community }} additive +{% endif %} {% endif %} ! {% endif %} diff --git a/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_all_chassis_pkt_down.json b/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_all_chassis_pkt_down.json index 103e5a1fdcac..d8ef3a0c9071 100644 --- a/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_all_chassis_pkt_down.json +++ b/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_all_chassis_pkt_down.json @@ -5,10 +5,10 @@ "allow_list": { "enabled": true, "drop_community": "12345:12345" - }, + }, "route_eligible_for_fallback_to_default_tag": "203", "route_do_not_send_appdb_tag" : "202", - "internal_fallback_community": "1111:2222" + "internal_fallback_community": "1111:2222" } }, "allow_list_default_action": "permit", diff --git a/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_all_voq_down.json b/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_all_voq_down.json index 9671b7fcf25c..67aa23c92ff1 100644 --- a/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_all_voq_down.json +++ b/src/sonic-bgpcfgd/tests/data/general/policies.conf/param_all_voq_down.json @@ -5,10 +5,10 @@ "allow_list": { "enabled": true, "drop_community": "12345:12345" - }, + }, "route_eligible_for_fallback_to_default_tag": "203", "route_do_not_send_appdb_tag" : "202", - "internal_fallback_community": "1111:2222" + "internal_fallback_community": "1111:2222" } }, "allow_list_default_action": "permit", diff --git a/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_all_chassis_pkt.conf b/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_all_chassis_pkt.conf index 448abc01fb37..842b75ed47e7 100644 --- a/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_all_chassis_pkt.conf +++ b/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_all_chassis_pkt.conf @@ -49,7 +49,8 @@ route-map FROM_BGP_PEER_V6 permit 12 ! route-map FROM_BGP_PEER_V6 permit 13 set tag 203 - set community 1111:2222 additive ! + set community 1111:2222 additive +! ! ! ! diff --git a/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_all_voq.conf b/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_all_voq.conf index c746f30dd0a3..1697cb0fd8ea 100644 --- a/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_all_voq.conf +++ b/src/sonic-bgpcfgd/tests/data/general/policies.conf/result_all_voq.conf @@ -49,7 +49,8 @@ route-map FROM_BGP_PEER_V6 permit 12 ! route-map FROM_BGP_PEER_V6 permit 13 set tag 202 - set community 1111:2222 additive ! + set community 1111:2222 additive +! ! ! ! From 400620b004b70a5e5badf58f02569a842b918831 Mon Sep 17 00:00:00 2001 From: Mukul Chodhary <70460358+Muckthebuck@users.noreply.github.com> Date: Fri, 21 Feb 2025 10:32:50 +1100 Subject: [PATCH 08/10] prefix_list permission changes Signed-off-by: Mukul Chodhary <70460358+Muckthebuck@users.noreply.github.com> --- dockers/docker-fpm-frr/base_image_files/prefix_list | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 dockers/docker-fpm-frr/base_image_files/prefix_list diff --git a/dockers/docker-fpm-frr/base_image_files/prefix_list b/dockers/docker-fpm-frr/base_image_files/prefix_list old mode 100644 new mode 100755 From 5972ab3577b71db56e29d7067655c5952d7ea879 Mon Sep 17 00:00:00 2001 From: Mukul Chodhary <70460358+Muckthebuck@users.noreply.github.com> Date: Fri, 21 Feb 2025 11:08:05 +1100 Subject: [PATCH 09/10] prefix_list script update replace IFS in help message with printf Signed-off-by: Mukul Chodhary <70460358+Muckthebuck@users.noreply.github.com> --- dockers/docker-fpm-frr/base_image_files/prefix_list | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dockers/docker-fpm-frr/base_image_files/prefix_list b/dockers/docker-fpm-frr/base_image_files/prefix_list index a90e6ac6a80b..a3d09f140f27 100755 --- a/dockers/docker-fpm-frr/base_image_files/prefix_list +++ b/dockers/docker-fpm-frr/base_image_files/prefix_list @@ -15,7 +15,7 @@ display_help() { echo " No additional parameters required." echo "" echo "Arguments:" - echo " Type of prefix list. Allowed values: {$(IFS='|'; echo "${supported_prefix_types[*]}")}." + echo " Type of prefix list. Allowed values: {$(printf "%s" "${supported_prefix_types[*]}" | tr ' ' '|')}." echo " Network in CIDR format." echo "" echo "Options:" From 941e74e0429082b3bcce203f64b1cc04c85f7148 Mon Sep 17 00:00:00 2001 From: mchodhary Date: Fri, 21 Feb 2025 23:29:31 +1100 Subject: [PATCH 10/10] peer-group fix put the table map in correct spot for v4 Signed-off-by: Mukul Chodhary <70460358+Muckthebuck@users.noreply.github.com> --- .../frr/bgpd/templates/general/peer-group.conf.j2 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dockers/docker-fpm-frr/frr/bgpd/templates/general/peer-group.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/general/peer-group.conf.j2 index 7b4b16941810..69477cda2e3b 100644 --- a/dockers/docker-fpm-frr/frr/bgpd/templates/general/peer-group.conf.j2 +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/general/peer-group.conf.j2 @@ -14,6 +14,9 @@ neighbor PEER_V4 soft-reconfiguration inbound neighbor PEER_V4 route-map FROM_BGP_PEER_V4 in neighbor PEER_V4 route-map TO_BGP_PEER_V4 out +{% if CONFIG_DB__DEVICE_METADATA['localhost']['type'] == 'SpineRouter' %} + table-map SELECTIVE_ROUTE_DOWNLOAD_V4 +{% endif %} exit-address-family address-family ipv6 {% if CONFIG_DB__DEVICE_METADATA['localhost']['type'] == 'ToRRouter' %} @@ -27,7 +30,6 @@ neighbor PEER_V6 route-map FROM_BGP_PEER_V6 in neighbor PEER_V6 route-map TO_BGP_PEER_V6 out {% if CONFIG_DB__DEVICE_METADATA['localhost']['type'] == 'SpineRouter' %} - table-map SELECTIVE_ROUTE_DOWNLOAD_V4 table-map SELECTIVE_ROUTE_DOWNLOAD_V6 {% endif %} exit-address-family