From 57d37c4c93a152a25d31fd86b04295628587e42d Mon Sep 17 00:00:00 2001 From: "Bing Wang (SONIC)" Date: Fri, 13 Feb 2026 05:34:43 +0000 Subject: [PATCH 1/2] Merged PR 18893: [internal] [Disagg T2] Test infra changes for BGP confed Merged PR 16507: [Disagg T2] Test infra changes for BGP confed This pull request implements test infrastructure changes to enable BGP confederation support for disaggregated T2 devices. The pull request updates Ansible modules, templates, and topology configurations to incorporate BGP confederation parameters and support a new ut2 device configuration. Key changes include: - `ansible/library/generate_golden_config_db.py`: Added the `generate_ut2_golden_config_db` method and adjusted config generation logic based on topology names. - `ansible/library/topo_facts.py`: Modified the BGP peer extraction to use a new `peer_in_bgp_confed` flag and select the appropriate ASN. - `ansible/roles/eos/templates/t2-leaf.j2` and `t1-lag-spine.j2`: Updated templates to conditionally include BGP confederation identifier and peer settings. - Topology YAML files (e.g., `ansible/vars/topo_lt2-p32o64.yml` and `ansible/vars/topo_t2_single_node_max.yml`): Revised ASNs and introduced confederation parameters (`confed_asn`, `confed_peers`) along with the `peer_in_bgp_confed` flag. - `ansible/config_sonic_basedon_testbed.yml`: Added the `num_asics` parameter to support configurations for devices with multiple ASICs. ---- This pull request implements test infrastructure changes to support BGP confederation in disaggregated T2 and related platforms. The PR enhances golden configuration generation, device templates, and test utilities to include BGP confederation settings by introducing new parameters and logic for processing BGP confederation ASN and peers. - **`ansible/library/generate_golden_config_db.py`**: Adds a new function for UT2 devices and updates existing functions to incorporate `bgp_confd_asn` and `bgp_confd_peers` for embedding BGP confederation configurations into the golden config JSON. - **`ansible/config_sonic_basedon_testbed.yml`**: Updates playbook tasks to pass new BGP confed parameters and copy necessary templates and profile files for t2 devices. - **EOS Templates (`ansible/roles/eos/templates/*.j2`)**: Modifies multiple device templates to conditionally render BGP confederation settings when related parameters are defined. - **BGP Test and Helper Modules**: Updates in files such as `tests/common/helpers/bgp.py`, `ansible/library/bgp_facts.py`, `ansible/library/topo_facts.py`, and route checkers adjust parsing and validation logic to correctly handle confederation peers. Signed-off-by: bingwang --- ansible/config_sonic_basedon_testbed.yml | 32 ++++++ ansible/library/bgp_facts.py | 6 ++ ansible/library/generate_golden_config_db.py | 106 ++++++++++++++----- ansible/library/topo_facts.py | 8 +- ansible/module_utils/port_utils.py | 11 +- ansible/roles/eos/templates/t0-leaf.j2 | 9 +- ansible/roles/eos/templates/t1-64-lag-tor.j2 | 5 + ansible/roles/eos/templates/t1-lag-spine.j2 | 7 +- ansible/roles/eos/templates/t2-leaf.j2 | 6 ++ tests/bgp/conftest.py | 3 + tests/bgp/route_checker.py | 14 ++- tests/common/helpers/bgp.py | 11 +- 12 files changed, 183 insertions(+), 35 deletions(-) diff --git a/ansible/config_sonic_basedon_testbed.yml b/ansible/config_sonic_basedon_testbed.yml index 9d13a28d37..22b5a7660c 100644 --- a/ansible/config_sonic_basedon_testbed.yml +++ b/ansible/config_sonic_basedon_testbed.yml @@ -448,6 +448,11 @@ - name: Load variables from topology file for topo_{{ topo }}.yml include_vars: "vars/topo_{{ topo }}.yml" + - name: set BGP confd ASN facts + set_fact: + bgp_confd_asn: "{{ hostvars[inventory_hostname]['configuration_properties']['common']['dut_confed_asn'] | default(None) }}" + bgp_confd_peers: "{{ hostvars[inventory_hostname]['configuration_properties']['common']['dut_confed_peers'] | default(None) }}" + - name: saved original minigraph file in SONiC DUT(ignore errors when file does not exist) shell: mv /etc/sonic/minigraph.xml /etc/sonic/minigraph.xml.orig become: true @@ -611,6 +616,9 @@ topo_name: "{{ topo }}" port_index_map: "{{ port_index_map | default({}) }}" hwsku: "{{ hwsku }}" + num_asics: "{{ num_asics }}" + bgp_confd_asn: "{{ bgp_confd_asn }}" + bgp_confd_peers: "{{ bgp_confd_peers }}" become: true when: enable_macsec is not defined @@ -631,6 +639,30 @@ topo_name: "{{ topo }}" macsec_profile: "{{ macsec_profile }}" num_asics: "{{ num_asics }}" + bgp_confd_asn: "{{ bgp_confd_asn }}" + bgp_confd_peers: "{{ bgp_confd_peers }}" + become: true + when: "('t2' in topo) and (enable_macsec is defined)" + + - name: Copy macsec profile json to dut + copy: src=../tests/common/macsec/profile.json + dest=/tmp/profile.json + become: true + when: "('t2' in topo) and (enable_macsec is defined)" + + - name: Copy golden_config_db_t2 template to DUT + copy: src=templates/golden_config_db_t2.j2 + dest=/tmp/golden_config_db_t2.j2 + become: true + when: "('t2' in topo) and (enable_macsec is defined)" + + - name: Generate golden_config_db.json for t2 + generate_golden_config_db: + topo_name: "{{ topo }}" + macsec_profile: "{{ macsec_profile }}" + num_asics: "{{ num_asics }}" + bgp_confd_asn: "{{ bgp_confd_asn }}" + bgp_confd_peers: "{{ bgp_confd_peers }}" become: true when: "('t2' in topo) and (enable_macsec is defined)" diff --git a/ansible/library/bgp_facts.py b/ansible/library/bgp_facts.py index 41a22b96ed..88316e7e7c 100644 --- a/ansible/library/bgp_facts.py +++ b/ansible/library/bgp_facts.py @@ -120,6 +120,7 @@ def parse_summary(self): def parse_neighbors(self): regex_ipv4 = re.compile( r'^BGP neighbor is \*?(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})') + regex_confed_link = re.compile(r'^BGP neighbor is .*(confed-(?:internal|external) link)') regex_ipv6 = re.compile(r'^BGP neighbor is \*?([0-9a-fA-F:]+)') regex_remote_as = re.compile(r'.*remote AS (\d+)') regex_local_as = re.compile(r'.*local AS (\d+)') @@ -165,6 +166,11 @@ def parse_neighbors(self): neighbor_ip = None for line in lines: + if regex_confed_link.match(line): + neighbor['confed_peer'] = True + if neighbor['confed_peer']: + confed_peer_type = regex_confed_link.match(line).group(1) + neighbor['confed_peer_type'] = 'external' if confed_peer_type == 'confed-external link' else 'internal' # noqa: E501 if regex_ipv4.match(line): neighbor_ip = regex_ipv4.match(line).group(1) neighbor['ip_version'] = 4 diff --git a/ansible/library/generate_golden_config_db.py b/ansible/library/generate_golden_config_db.py index 8f6f9eb591..094e3c9b4a 100644 --- a/ansible/library/generate_golden_config_db.py +++ b/ansible/library/generate_golden_config_db.py @@ -54,13 +54,19 @@ def __init__(self): port_index_map=dict(require=False, type='dict', default=None), macsec_profile=dict(require=False, type='str', default=None), num_asics=dict(require=False, type='int', default=1), - hwsku=dict(require=False, type='str', default=None)), + hwsku=dict(require=False, type='str', default=None), + bgp_confd_asn=dict(require=False, type='str', default=None), + bgp_confd_peers=dict(require=False, type='str', default=None)), supports_check_mode=True) self.topo_name = self.module.params['topo_name'] self.port_index_map = self.module.params['port_index_map'] self.hwsku = self.module.params['hwsku'] self.macsec_profile = self.module.params['macsec_profile'] self.num_asics = self.module.params['num_asics'] + self.platform, _ = device_info.get_platform_and_hwsku() + + self.bgp_confd_asn = self.module.params['bgp_confd_asn'] + self.bgp_confd_peers = self.module.params['bgp_confd_peers'] def generate_mgfx_golden_config_db(self): rc, out, err = self.module.run_command("sonic-cfggen -H -m -j /etc/sonic/init_cfg.json --print-data") @@ -253,43 +259,86 @@ def generate_smartswitch_golden_config_db(self): gold_config_db.update(smartswitch_config_obj) return json.dumps(gold_config_db, indent=4) + def generate_ut2_golden_config_db(self): + rendered_json = {} + if self.macsec_profile: + with open(MACSEC_PROFILE_PATH) as f: + macsec_profiles = json.load(f) + + profile = macsec_profiles.get(self.macsec_profile) + if profile: + profile['macsec_profile'] = self.macsec_profile + + # Update the profile context with the asic count + profile['asic_cnt'] = self.num_asics + + def safe_open_template(template_path): + with open(template_path) as template_file: + return Template(template_file.read()) + + # Render the template using the profile + rendered_json = safe_open_template(GOLDEN_CONFIG_TEMPLATE_PATH).render(profile) + + if self.num_asics > 1: + if "localhost" not in rendered_json: + rendered_json["localhost"] = {} + for asic in range(0, self.num_asics): + namespace = "asic{}".format(asic) + if namespace not in rendered_json: + rendered_json[namespace] = {} + rendered_json[namespace] = {"BGP_DEVICE_GLOBAL": {"CONFED": {"asn": "65100", "peers": "65300"}}} + else: + if "BGP_DEVICE_GLOBAL" not in rendered_json: + rendered_json["BGP_DEVICE_GLOBAL"] = {} + rendered_json["BGP_DEVICE_GLOBAL"]["CONFED"] = {"asn": "65100", "peers": "65300"} + return json.dumps(rendered_json, indent=4) + + def generate_t2_golden_config_db(self): + rendered_json = {} + if self.macsec_profile: + with open(MACSEC_PROFILE_PATH) as f: + macsec_profiles = json.load(f) + + profile = macsec_profiles.get(self.macsec_profile) + if profile: + profile['macsec_profile'] = self.macsec_profile + + # Update the profile context with the asic count + profile['asic_cnt'] = self.num_asics + + def safe_open_template(template_path): + with open(template_path) as template_file: + return Template(template_file.read()) + + # Render the template using the profile + rendered_json = safe_open_template(GOLDEN_CONFIG_TEMPLATE_PATH).render(profile) + + return rendered_json + def generate_lt2_ft2_golden_config_db(self): """ - Generate golden_config for FT2 to enable FEC. - **Only PORT table is updated**. + Generate golden_config for FT2 to enable FEC and set BGP confed. """ SUPPORTED_TOPO = ["ft2-64", "lt2-p32o64", "lt2-o128"] if self.topo_name not in SUPPORTED_TOPO: return "{}" SUPPORTED_PORT_SPEED = ["200000", "400000", "800000"] ori_config = json.loads(self.get_config_from_minigraph()) - port_config = ori_config.get("PORT", {}) - for name, config in port_config.items(): + golden_config = ori_config + golden_config["PORT"] = ori_config.get("PORT", {}) + for _, config in golden_config["PORT"].items(): # Enable FEC for ports with supported speed if config["speed"] in SUPPORTED_PORT_SPEED and "fec" not in config: config["fec"] = "rs" - return json.dumps({"PORT": port_config}, indent=4) - - def generate_t2_golden_config_db(self): - with open(MACSEC_PROFILE_PATH) as f: - macsec_profiles = json.load(f) - - profile = macsec_profiles.get(self.macsec_profile) - if profile: - profile['macsec_profile'] = self.macsec_profile - - # Update the profile context with the asic count - profile['asic_cnt'] = self.num_asics + # Add BGP confederation config + if self.bgp_confd_asn and self.bgp_confd_peers: + golden_config["BGP_DEVICE_GLOBAL"] = ori_config.get("BGP_DEVICE_GLOBAL", {}) + # Replace space in confg_peers with ; to align with NDM + golden_config["BGP_DEVICE_GLOBAL"]["CONFED"] = \ + {"asn": str(self.bgp_confd_asn), "peers": str(self.bgp_confd_peers).replace(' ', ';')} - def safe_open_template(template_path): - with open(template_path) as template_file: - return Template(template_file.read()) - - # Render the template using the profile - rendered_json = safe_open_template(GOLDEN_CONFIG_TEMPLATE_PATH).render(profile) - - return rendered_json + return json.dumps(golden_config, indent=4) def generate(self): module_msg = "Success to generate golden_config_db.json" @@ -304,7 +353,12 @@ def generate(self): module_msg = module_msg + " for smartswitch" elif "ft2" in self.topo_name or "lt2" in self.topo_name: config = self.generate_lt2_ft2_golden_config_db() - elif "t2" in self.topo_name and self.macsec_profile: + elif "t2_single_node" in self.topo_name: + config = self.generate_ut2_golden_config_db() + self.module.run_command("sudo rm -f {}".format(MACSEC_PROFILE_PATH)) + self.module.run_command("sudo rm -f {}".format(GOLDEN_CONFIG_TEMPLATE_PATH)) + module_msg = module_msg + " for ut2 device" + elif "t2" in self.topo_name: config = self.generate_t2_golden_config_db() self.module.run_command("sudo rm -f {}".format(MACSEC_PROFILE_PATH)) self.module.run_command("sudo rm -f {}".format(GOLDEN_CONFIG_TEMPLATE_PATH)) diff --git a/ansible/library/topo_facts.py b/ansible/library/topo_facts.py index c34b62e9b1..c6a0a24e06 100644 --- a/ansible/library/topo_facts.py +++ b/ansible/library/topo_facts.py @@ -188,8 +188,12 @@ def parse_topo_defintion(self, topo_definition, po_map, dut_num, neigh_type='VMs # bgp vmconfig[vm]['bgp_asn'] = topo_definition['configuration'][vm]['bgp']['asn'] - dut_asn = topo_definition['configuration_properties']['common']['dut_asn'] - for ipstr in topo_definition['configuration'][vm]['bgp']['peers'][dut_asn]: + peer_in_bgp_confed = topo_definition['configuration'][vm]['bgp'].get('peer_in_bgp_confed', False) + if peer_in_bgp_confed: + peer_asn = topo_definition['configuration_properties']['common']['dut_confed_asn'] + else: + peer_asn = topo_definition['configuration_properties']['common']['dut_asn'] + for ipstr in topo_definition['configuration'][vm]['bgp']['peers'][peer_asn]: ip_mask = None if '/' in ipstr: (ipstr, ip_mask) = ipstr.split('/') diff --git a/ansible/module_utils/port_utils.py b/ansible/module_utils/port_utils.py index 7babddaf3e..a52ec5c033 100644 --- a/ansible/module_utils/port_utils.py +++ b/ansible/module_utils/port_utils.py @@ -296,7 +296,16 @@ def get_port_alias_to_name_map(hwsku, asic_name=None): "Arista-7800R3A-36DM2-D36"]: for i in range(1, 37): sonic_name = "Ethernet%d" % ((i - 1) * 8) - port_alias_to_name_map["Ethernet{}/{}".format(i, 1)] = sonic_name + port_alias_to_name_map["etp{}".format(i)] = sonic_name + elif hwsku in ["Arista-7280R4-32QF-32DF-64O", + "Arista-7280R4K-32QF-32DF-64O"]: + portNum = 0 + for i in range(1, 65): + port_alias_to_name_map["Ethernet{}/{}".format(i, 1)] = "Ethernet%d" % portNum + if i > 16 and i < 49: + portNum += 4 + else: + portNum += 8 elif hwsku == "Arista-7800R3A-36DM2-C72" or\ hwsku == "Arista-7800R3A-36D-C72" or\ hwsku == "Arista-7800R3A-36P-C72" or\ diff --git a/ansible/roles/eos/templates/t0-leaf.j2 b/ansible/roles/eos/templates/t0-leaf.j2 index 5f553453a5..179e5b1cfe 100644 --- a/ansible/roles/eos/templates/t0-leaf.j2 +++ b/ansible/roles/eos/templates/t0-leaf.j2 @@ -102,13 +102,18 @@ interface {{ bp_ifname }} router bgp {{ host['bgp']['asn'] }} router-id {{ host['bgp']['router-id'] if host['bgp']['router-id'] is defined else host['interfaces']['Loopback0']['ipv4'] | ansible.utils.ipaddr('address') }} ! +{% if host['bgp']['confed_asn'] is defined and host['bgp']['confed_peers'] is defined %} + bgp confederation identifier {{ host['bgp']['confed_asn'] }} + bgp confederation peers {{ host['bgp']['confed_peers'] }} + ! +{% endif %} {% for asn, remote_ips in host['bgp']['peers'].items() %} -{% for remote_ip in remote_ips %} + {% for remote_ip in remote_ips %} neighbor {{ remote_ip }} remote-as {{ asn }} neighbor {{ remote_ip }} description {{ asn }} neighbor {{ remote_ip }} next-hop-self {# set LT2/FT2 as reflector to advertise route to DUT #} -{% if props.swrole is defined and props.swrole in ("lowerspine", "fabricspine") %} +{% if props.swrole is defined and props.swrole in ("lowerspine", "fabricspine") and host['bgp']['confed_asn'] is not defined %} neighbor {{ remote_ip }} route-reflector-client neighbor {{ remote_ip }} additional-paths send any {% endif %} diff --git a/ansible/roles/eos/templates/t1-64-lag-tor.j2 b/ansible/roles/eos/templates/t1-64-lag-tor.j2 index fff5482335..758cb9a82e 100644 --- a/ansible/roles/eos/templates/t1-64-lag-tor.j2 +++ b/ansible/roles/eos/templates/t1-64-lag-tor.j2 @@ -106,6 +106,11 @@ router bgp {{ host['bgp']['asn'] }} graceful-restart restart-time {{ bgp_gr_timer }} graceful-restart ! +{% if host['bgp']['confed_asn'] is defined and host['bgp']['confed_peers'] is defined %} + bgp confederation identifier {{ host['bgp']['confed_asn'] }} + bgp confederation peers {{ host['bgp']['confed_peers'] }} +! +{% endif %} {% for asn, remote_ips in host['bgp']['peers'].items() %} {% for remote_ip in remote_ips %} neighbor {{ remote_ip }} remote-as {{ asn }} diff --git a/ansible/roles/eos/templates/t1-lag-spine.j2 b/ansible/roles/eos/templates/t1-lag-spine.j2 index d7459fe33b..8764e34480 100644 --- a/ansible/roles/eos/templates/t1-lag-spine.j2 +++ b/ansible/roles/eos/templates/t1-lag-spine.j2 @@ -102,8 +102,13 @@ interface {{ bp_ifname }} router bgp {{ host['bgp']['asn'] }} router-id {{ host['bgp']['router-id'] if host['bgp']['router-id'] is defined else host['interfaces']['Loopback0']['ipv4'] | ansible.utils.ipaddr('address') }} ! +{% if host['bgp']['confed_asn'] is defined and host['bgp']['confed_peers'] is defined %} + bgp confederation identifier {{ host['bgp']['confed_asn'] }} + bgp confederation peers {{ host['bgp']['confed_peers'] }} +! +{% endif %} {% for asn, remote_ips in host['bgp']['peers'].items() %} -{% for remote_ip in remote_ips %} + {% for remote_ip in remote_ips %} neighbor {{ remote_ip }} remote-as {{ asn }} neighbor {{ remote_ip }} description {{ asn }} neighbor {{ remote_ip }} next-hop-self diff --git a/ansible/roles/eos/templates/t2-leaf.j2 b/ansible/roles/eos/templates/t2-leaf.j2 index cdb746f639..d115e4f53f 100644 --- a/ansible/roles/eos/templates/t2-leaf.j2 +++ b/ansible/roles/eos/templates/t2-leaf.j2 @@ -108,6 +108,12 @@ interface {{ bp_ifname }} router bgp {{ host['bgp']['asn'] }} router-id {{ host['interfaces']['Loopback0']['ipv4'] | ansible.utils.ipaddr('address') }} ! +{% if host['bgp']['confed_asn'] is defined and host['bgp']['confed_peers'] is defined %} + bgp confederation identifier {{ host['bgp']['confed_asn'] }} + bgp confederation peers {{ host['bgp']['confed_peers'] }} + ! + {% endif %} + {% for asn, remote_ips in host['bgp']['peers'].items() %} {% for remote_ip in remote_ips %} neighbor {{ remote_ip }} remote-as {{ asn }} diff --git a/tests/bgp/conftest.py b/tests/bgp/conftest.py index a90980c2dd..f79366a34a 100644 --- a/tests/bgp/conftest.py +++ b/tests/bgp/conftest.py @@ -553,6 +553,9 @@ def bgpmon_setup_teardown(ptfhost, duthosts, enum_rand_one_per_hwsku_frontend_ho peer_addr = connection['neighbor_addr'].split("/")[0] mg_facts = duthost.minigraph_facts(host=duthost.hostname)['ansible_facts'] asn = mg_facts['minigraph_bgp_asn'] + confed_asn = duthost.get_bgp_confed_asn() + if confed_asn: + asn = confed_asn # TODO: Add a common method to load BGPMON config for test_bgpmon and test_traffic_shift logger.info("Configuring bgp monitor session on DUT") bgpmon_args = { diff --git a/tests/bgp/route_checker.py b/tests/bgp/route_checker.py index d04b6f05d3..57c857854e 100644 --- a/tests/bgp/route_checker.py +++ b/tests/bgp/route_checker.py @@ -63,7 +63,8 @@ def parse_routes_on_eos(dut_host, neigh_hosts, ip_ver, exp_community=[]): """ mg_facts = dut_host.minigraph_facts( host=dut_host.hostname)['ansible_facts'] - asn = mg_facts['minigraph_bgp_asn'] + confed_asn = dut_host.get_bgp_confed_asn() + all_routes = {} BGP_ENTRY_HEADING = r"BGP routing table entry for " BGP_COMMUNITY_HEADING = r"Community: " @@ -83,6 +84,10 @@ def parse_routes_process(node=None, results=None, my_community=exp_community): # get hostname('ARISTA11T0') by VM name('VM0122') hostname = host_name_map[node['host'].hostname] host = node['host'] + peer_in_bgp_confed = node['conf']['bgp'].get('peer_in_bgp_confed', False) + asn = mg_facts['minigraph_bgp_asn'] + if peer_in_bgp_confed: + asn = confed_asn peer_ips = node['conf']['bgp']['peers'][asn] for ip in peer_ips: if ipaddress.IPNetwork(ip).version == 4: @@ -154,7 +159,7 @@ def parse_routes_process(node=None, results=None, my_community=exp_community): def parse_routes_on_vsonic(dut_host, neigh_hosts, ip_ver): mg_facts = dut_host.minigraph_facts( host=dut_host.hostname)['ansible_facts'] - asn = mg_facts['minigraph_bgp_asn'] + confed_asn = dut_host.get_bgp_confed_asn() all_routes = {} host_name_map = {} @@ -164,6 +169,11 @@ def parse_routes_on_vsonic(dut_host, neigh_hosts, ip_ver): def parse_routes_process_vsonic(node=None, results=None): hostname = host_name_map[node['host'].hostname] host = node['host'] + peer_in_bgp_confed = node['conf']['bgp'].get('peer_in_bgp_confed', False) + asn = mg_facts['minigraph_bgp_asn'] + if peer_in_bgp_confed: + asn = confed_asn + peer_ips = node['conf']['bgp']['peers'][asn] peer_ips = node['conf']['bgp']['peers'][asn] for ip in peer_ips: diff --git a/tests/common/helpers/bgp.py b/tests/common/helpers/bgp.py index c9970453b5..d00a7fdab4 100644 --- a/tests/common/helpers/bgp.py +++ b/tests/common/helpers/bgp.py @@ -66,11 +66,20 @@ def run_bgp_facts(duthost, enum_asic_index): namespace = duthost.get_namespace_from_asic_id(enum_asic_index) config_facts = duthost.config_facts(host=duthost.hostname, source="running", namespace=namespace)['ansible_facts'] sonic_db_cmd = "sonic-db-cli {}".format("-n " + namespace if namespace else "") + bgp_confed_asn = config_facts.get('BGP_DEVICE_GLOBAL', {}).get('CONFED', {}).get('asn', None) + bgp_asn = int(config_facts['DEVICE_METADATA']['localhost']['bgp_asn'].encode().decode("utf-8")) for k, v in list(bgp_facts['bgp_neighbors'].items()): # Verify bgp sessions are established assert v['state'] == 'established' # Verify local ASNs in bgp sessions - assert v['local AS'] == int(config_facts['DEVICE_METADATA']['localhost']['bgp_asn'].encode().decode("utf-8")) + confed_peer = v.get('confed_peer', False) + if bgp_confed_asn: + if confed_peer: + assert v['local AS'] == int(bgp_asn) + else: + assert v['local AS'] == int(bgp_confed_asn) + else: + assert v['local AS'] == bgp_asn # Check bgpmon functionality by validate STATE DB contains this neighbor as well state_fact = duthost.shell('{} STATE_DB HGET "NEIGH_STATE_TABLE|{}" "state"' .format(sonic_db_cmd, k), module_ignore_errors=False)['stdout_lines'] From 42075ed2d99b25df011d2964b18e34a74e7b72ea Mon Sep 17 00:00:00 2001 From: bingwang Date: Sat, 14 Feb 2026 00:37:52 +0000 Subject: [PATCH 2/2] Remove duplicated code Signed-off-by: bingwang --- tests/bgp/route_checker.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/bgp/route_checker.py b/tests/bgp/route_checker.py index 57c857854e..9d29a1f0ec 100644 --- a/tests/bgp/route_checker.py +++ b/tests/bgp/route_checker.py @@ -174,7 +174,6 @@ def parse_routes_process_vsonic(node=None, results=None): if peer_in_bgp_confed: asn = confed_asn peer_ips = node['conf']['bgp']['peers'][asn] - peer_ips = node['conf']['bgp']['peers'][asn] for ip in peer_ips: if ipaddress.IPNetwork(ip).version == 4: