From 0edbf44b2014aafc8c024e4bb439ea357e171295 Mon Sep 17 00:00:00 2001 From: Automation Date: Fri, 19 Feb 2021 19:32:44 +0530 Subject: [PATCH 01/12] adding bgp-tencent tests --- tests/common/ixia/ixia_fixtures.py | 81 +++++++ tests/ixia/bgp/files/__init__.py | 1 + tests/ixia/bgp/files/helper.py | 346 +++++++++++++++++++++++++++ tests/ixia/bgp/test_bgp_community.py | 42 ++++ 4 files changed, 470 insertions(+) create mode 100644 tests/ixia/bgp/files/__init__.py create mode 100644 tests/ixia/bgp/files/helper.py create mode 100644 tests/ixia/bgp/test_bgp_community.py diff --git a/tests/common/ixia/ixia_fixtures.py b/tests/common/ixia/ixia_fixtures.py index 5b04c2f7783..1b74c9b7e73 100644 --- a/tests/common/ixia/ixia_fixtures.py +++ b/tests/common/ixia/ixia_fixtures.py @@ -11,6 +11,7 @@ from tests.common.ixia.common_helpers import get_vlan_subnet, get_addrs_in_subnet,\ get_peer_ixia_chassis from tests.common.ixia.ixia_helpers import IxiaFanoutManager, get_tgen_location +import snappi try: from abstract_open_traffic_generator.port import Port @@ -294,3 +295,83 @@ def ixia_testbed(conn_graph_facts, config.devices.append(device) return config + + +@pytest.fixture(scope='session') +def api(ixia_api_serv_ip, + ixia_api_serv_port): + # TODO: this is specific to IxNetwork, handle in more + # dynamic way + host = "https://" + ixia_api_serv_ip + ":" + ixia_api_serv_port + api = snappi.api(host=host, ext="ixnetwork") + yield api + + if api.assistant is not None: + api.assistant.Session.remove() + + +@pytest.fixture(scope="function") +def tgen_ports(duthost, + conn_graph_facts, + fanout_graph_facts): + + """ + Return: + [{'card_id': '1', + 'ip': '21.1.1.2', + 'location': '10.36.78.238;1;2', + 'prefix': u'24', + 'peer_ip': u'21.1.1.1', + 'peer_device': 'example-s6100-dut-1', + 'peer_port': 'Ethernet0', + 'port_id': '2', + 'speed': '400000'}, + {'card_id': '1', + 'ip': '22.1.1.2', + 'location': '10.36.78.238;1;1', + 'prefix': u'24', + 'peer_ip': u'22.1.1.1', + 'peer_device': 'example-s6100-dut-1', + 'peer_port': 'Ethernet8', + 'port_id': '1', + 'speed': '400000'}] + """ + + speed_type = {'50000': 'speed_50_gbps', + '100000': 'speed_100_gbps', + '200000': 'speed_200_gbps', + '400000': 'speed_400_gbps'} + + ixia_fanout = get_peer_ixia_chassis(conn_data=conn_graph_facts, + dut_hostname=duthost.hostname) + ixia_fanout_id = list(fanout_graph_facts.keys()).index(ixia_fanout) + ixia_fanout_list = IxiaFanoutManager(fanout_graph_facts) + ixia_fanout_list.get_fanout_device_details(device_number=ixia_fanout_id) + ixia_ports = ixia_fanout_list.get_ports(peer_device=duthost.hostname) + port_speed = None + + for i in range(len(ixia_ports)): + if port_speed is None: + port_speed = int(ixia_ports[i]['speed']) + + elif port_speed != int(ixia_ports[i]['speed']): + """ All the ports should have the same bandwidth """ + return None + + config_facts = duthost.config_facts(host=duthost.hostname, + source="running")['ansible_facts'] + + for port in ixia_ports: + port['location'] = get_tgen_location(port) + port['speed'] = speed_type[port['speed']] + + for port in ixia_ports: + peer_port = port['peer_port'] + subnet = config_facts['INTERFACE'][peer_port].keys()[0] + if not subnet: + raise Exception("IP is not configured on the interface {}" + .format(peer_port)) + port['peer_ip'], port['prefix'] = subnet.split("/") + port['ip'] = get_addrs_in_subnet(subnet, 1)[0] + + return ixia_ports diff --git a/tests/ixia/bgp/files/__init__.py b/tests/ixia/bgp/files/__init__.py new file mode 100644 index 00000000000..65d74fc0a6b --- /dev/null +++ b/tests/ixia/bgp/files/__init__.py @@ -0,0 +1 @@ +# Local library for BGP tests. \ No newline at end of file diff --git a/tests/ixia/bgp/files/helper.py b/tests/ixia/bgp/files/helper.py new file mode 100644 index 00000000000..fa72489a291 --- /dev/null +++ b/tests/ixia/bgp/files/helper.py @@ -0,0 +1,346 @@ +from tests.common.helpers.assertions import pytest_assert +from tests.common.utilities import wait_until + +DUT_AS_NUM = 65100 +TGEN1_AS_NUM = 501 +TGEN2_AS_NUM = 502 +BGP_TYPE = 'ebgp' +PACKETS = 100000 + + +def run_bgp_community_test(api, + duthost, + tgen_ports): + """ + Run BGP Community test + """ + # Create bgp config on dut + __duthost_bgp_config(duthost, + tgen_ports) + + # Create bgp config on TGEN + tgen_bgp_config = __tgen_bgp_config(api, + tgen_ports) + + # Create BGP community configuration on DUT and TGEN + tgen_community_config = __bgp_community_config(duthost, + tgen_bgp_config) + + # Verity test results + __verify_test(duthost, + api, + tgen_community_config) + + __cleanup_config(duthost, + tgen_ports) + + +def __duthost_bgp_config(duthost, + tgen_ports): + """ + BGP Config on duthost + """ + intf1_config = ( + "vtysh " + "-c 'configure terminal' " + "-c 'interface %s' " + "-c 'ip address %s/%s' " + ) + intf1_config %= (tgen_ports[0]['peer_port'], + tgen_ports[0]['peer_ip'], + tgen_ports[0]['prefix']) + duthost.shell(intf1_config) + + bgp_config_501 = ( + "vtysh " + "-c 'configure terminal' " + "-c 'router bgp %s' " + "-c 'neighbor LC501 peer-group' " + "-c 'neighbor LC501 remote-as %s' " + "-c 'neighbor %s peer-group LC501' " + "-c 'address-family ipv4 unicast' " + "-c 'neighbor %s activate' " + ) + bgp_config_501 %= (DUT_AS_NUM, + TGEN1_AS_NUM, + tgen_ports[0]['ip'], + tgen_ports[0]['ip']) + duthost.shell(bgp_config_501) + + intf2_config = ( + "vtysh " + "-c 'configure terminal' " + "-c 'interface %s' " + "-c 'ip address %s/%s' " + ) + intf2_config %= (tgen_ports[1]['peer_port'], + tgen_ports[1]['peer_ip'], + tgen_ports[1]['prefix']) + duthost.shell(intf2_config) + + bgp_config_502 = ( + "vtysh " + "-c 'configure terminal' " + "-c 'router bgp %s' " + "-c 'neighbor LC502 peer-group' " + "-c 'neighbor LC502 remote-as %s' " + "-c 'neighbor %s peer-group LC502' " + "-c 'address-family ipv4 unicast' " + "-c 'neighbor %s activate' " + ) + bgp_config_502 %= (DUT_AS_NUM, + TGEN2_AS_NUM, + tgen_ports[1]['ip'], + tgen_ports[1]['ip']) + duthost.shell(bgp_config_502) + + +def __tgen_bgp_config(api, + tgen_ports): + """ + BGP & Config on TGEN + """ + config = api.config() + + tx, rx = ( + config.ports + .port(name='tx', location=tgen_ports[0]['location']) + .port(name='rx', location=tgen_ports[1]['location']) + ) + + ly = config.layer1.layer1()[-1] + ly.name = 'ly' + ly.port_names = [tx.name, rx.name] + ly.speed = tgen_ports[0]['speed'] + ly.auto_negotiate = False + + # Device Config + d1, d2 = config.devices.device(name='d501').device(name='d502') + d1.container_name = tx.name + d2.container_name = rx.name + eth1, eth2 = d1.ethernet, d2.ethernet + eth1.name, eth2.name = "eth1", "eth2" + ip1, ip2 = eth1.ipv4, eth2.ipv4 + ip1.name, ip2.name = "ip1", "ip2" + bgp501, bgp502 = ip1.bgpv4, ip2.bgpv4 + bgp501.name, bgp502.name = "bgp501", "bgp502" + + ip1.address.value = tgen_ports[0]['ip'] + ip1.gateway.value = tgen_ports[0]['peer_ip'] + ip1.prefix.value = tgen_ports[0]['prefix'] + + ip2.address.value = tgen_ports[1]['ip'] + ip2.gateway.value = tgen_ports[1]['peer_ip'] + ip2.prefix.value = tgen_ports[1]['prefix'] + + bgp501.dut_ipv4_address.value = tgen_ports[0]['peer_ip'] + bgp501.as_number.value = TGEN1_AS_NUM + bgp501.as_type = BGP_TYPE + + bgp502.dut_ipv4_address.value = tgen_ports[1]['peer_ip'] + bgp502.as_number.value = TGEN2_AS_NUM + bgp502.as_type = BGP_TYPE + + return config + + +def __bgp_community_config(duthost, + config): + """ + BGP Community Config on duthost and TGEN + """ + + bgp501 = config.devices[0].ethernet.ipv4.bgpv4 + bgp502 = config.devices[1].ethernet.ipv4.bgpv4 + + # Route Range Config + bgp501_rr_with_community, bgp501_rr2 = ( + bgp501.bgpv4_route_ranges + .bgpv4routerange() + .bgpv4routerange() + ) + bgp502_rr1 = bgp502.bgpv4_route_ranges.bgpv4routerange()[-1] + + # Advertise one route range("200.1.0.0") from AS 501 with community 1:2 + bgp501_rr_with_community.name = "bgp501_rr_with_community" + bgp501_rr_with_community.address.value = "200.1.0.0" + bgp501_rr_with_community.prefix.value = "16" + manual_as_community = bgp501_rr_with_community.community.bgpcommunity()[-1] + manual_as_community.community_type = manual_as_community.MANUAL_AS_NUMBER + manual_as_community.as_number.value = "1" + manual_as_community.as_custom.value = "2" + + # Advertise another route range("20.1.0.0") from AS 501 without + bgp501_rr2.name = "bgp501_rr2" + bgp501_rr2.address.value = "20.1.0.0" + bgp501_rr2.prefix.value = "16" + + # Advertise route range("100.1.0.0" from AS 502) + bgp502_rr1.name = "bgp502_rr1" + bgp502_rr1.address.value = "100.1.0.0" + bgp502_rr1.prefix.value = "16" + + # Create two flows Permit(Traffic with Community list) & Deny + permit, deny = config.flows.flow(name='permit').flow(name='deny') + permit.rate.percentage = 1 + permit.duration.fixed_packets.packets = PACKETS + deny.rate.percentage = 1 + deny.duration.fixed_packets.packets = PACKETS + + permit.tx_rx.device.tx_names = [bgp502_rr1.name] + permit.tx_rx.device.rx_names = [bgp501_rr_with_community.name] + + deny.tx_rx.device.tx_names = [bgp502_rr1.name] + deny.tx_rx.device.rx_names = [bgp501_rr2.name] + + community_config = ( + "vtysh " + "-c 'configure terminal' " + "-c 'bgp community-list 10 permit 1:2' " + "-c 'route-map LA permit 30' " + "-c 'match community 10'" + ) + duthost.shell(community_config) + + return config + + +def __verify_test(duthost, + api, + config): + """ + Test Verification + """ + api.set_config(config) + + # unconfigure route-map if exists already + route_map = ( + "vtysh " + "-c 'configure terminal' " + "-c 'router bgp %s' " + "-c 'address-family ipv4 unicast' " + "-c 'no neighbor LC501 route-map LA in' " + ) + route_map %= (DUT_AS_NUM) + duthost.shell(route_map) + + # Start traffic + ts = api.transmit_state() + ts.state = ts.START + api.set_transmit_state(ts) + + # Check there is no traffic loss for 'permit' & 'deny' + pytest_assert(wait_until(60, 2, + lambda: __check_for_no_loss(api, + ['permit', 'deny'], + PACKETS * 2)), + 'No loss expected') + + # Add route-map to permit only routes with community + route_map = ( + "vtysh " + "-c 'configure terminal' " + "-c 'router bgp %s' " + "-c 'address-family ipv4 unicast' " + "-c 'neighbor LC501 route-map LA in' " + ) + route_map %= (DUT_AS_NUM) + duthost.shell(route_map) + + # Start traffic + ts = api.transmit_state() + ts.state = ts.START + api.set_transmit_state(ts) + + # Check there is no traffic loss for 'permit' flow + pytest_assert(wait_until(60, 2, + lambda: __check_for_no_loss(api, + ['permit'], + PACKETS)), + 'No loss expected') + + # Check 100% traffic loss for 'deny' flow + pytest_assert(wait_until(60, 2, + lambda: __check_for_total_loss(api, ['deny'])), + 'total loss expected') + + +def __check_for_no_loss(api, flow_names, expected): + """ + Returns True if there is no traffic loss else False + """ + request = api.metrics_request() + request.flow.flow_names = flow_names + flow_results = api.get_metrics(request).flow_metrics + flow_rx = sum([f.frames_rx for f in flow_results]) + return flow_rx == expected + + +def __check_for_total_loss(api, flow_names): + """ + Returns True if there is 100% traffic loss else False + """ + request = api.metrics_request() + request.flow.flow_names = flow_names + flow_results = api.get_metrics(request).flow_metrics + flow_rx = sum([f.frames_rx for f in flow_results]) + return flow_rx == 0 + + +def __cleanup_config(duthost, + tgen_ports): + """ + BGP Config on duthost + """ + # Remove community config + community_config = ( + "vtysh " + "-c 'configure terminal' " + "-c 'no bgp community-list 10 permit 1:2' " + "-c 'no route-map LA permit 30' " + ) + duthost.shell(community_config) + + # Remove bgp neighbor config + bgp_config_501 = ( + "vtysh " + "-c 'configure terminal' " + "-c 'router bgp %s' " + "-c 'no neighbor LC501 peer-group' " + ) + bgp_config_501 %= (DUT_AS_NUM) + duthost.shell(bgp_config_501) + + bgp_config_502 = ( + "vtysh " + "-c 'configure terminal' " + "-c 'router bgp %s' " + "-c 'no neighbor LC502 peer-group' " + ) + bgp_config_502 %= (DUT_AS_NUM) + duthost.shell(bgp_config_502) + + # Remove interface ip config + intf1_config = ( + "vtysh " + "-c 'configure terminal' " + "-c 'interface %s' " + "-c 'no ip address %s/%s' " + ) + intf1_config %= (tgen_ports[0]['peer_port'], + tgen_ports[0]['peer_ip'], + tgen_ports[0]['prefix']) + duthost.shell(intf1_config) + + intf2_config = ( + "vtysh " + "-c 'configure terminal' " + "-c 'interface %s' " + "-c 'no ip address %s/%s' " + ) + intf2_config %= (tgen_ports[1]['peer_port'], + tgen_ports[1]['peer_ip'], + tgen_ports[1]['prefix']) + duthost.shell(intf2_config) + + diff --git a/tests/ixia/bgp/test_bgp_community.py b/tests/ixia/bgp/test_bgp_community.py new file mode 100644 index 00000000000..6a80f4104ef --- /dev/null +++ b/tests/ixia/bgp/test_bgp_community.py @@ -0,0 +1,42 @@ +from tests.common.ixia.ixia_fixtures import api +from tests.common.ixia.ixia_fixtures import tgen_ports +from files.helper import run_bgp_community_test +from tests.common.fixtures.conn_graph_facts import conn_graph_facts,\ + fanout_graph_facts +import logging + + +logger = logging.getLogger(__name__) + +def test_bgp_community(api, + duthost, + tgen_ports, + conn_graph_facts, + fanout_graph_facts): + """ + Topo: + TGEN1 --- DUT --- TGEN2 + + Steps: + 1) Create BGP config on DUT and TGEN respectively + 2) Generate two routes from TGEN1 + route1 -- "200.1.0.0" with community 1:2 + route2 -- "20.1.0.0" + 3) Create community list in DUT + "ip community-list 10 permit 1:2" + 4) Create two flows from TGEN2 to TGEN1 + a) 'permit' -- TGEN2("100.1.0.0") to TGEN1("200.1.0.0") + b) 'deny' -- TGEN2("100.1.0.0") to TGEN1("20.1.0.0") + + Verification: + 1) Send traffic without applying route-map + Result: Should not observe traffic loss in 'permit' & 'deny' + 2) Apply route-map + Result: Should observe traffic loss in 'deny' + """ + # We are going to use first two ports for this test + tgen_ports = tgen_ports[0:2] + + run_bgp_community_test(api, + duthost, + tgen_ports) From b4c547e99aacffa07ea023ea3be4e126064e4b5b Mon Sep 17 00:00:00 2001 From: Anish Date: Sat, 20 Feb 2021 15:22:44 +0000 Subject: [PATCH 02/12] adding bgp-tencent tests --- tests/common/ixia/ixia_fixtures.py | 25 +++-- tests/ixia/bgp/files/helper.py | 156 ++++++++++++++------------- tests/ixia/bgp/test_bgp_community.py | 33 +++--- 3 files changed, 119 insertions(+), 95 deletions(-) mode change 100644 => 100755 tests/common/ixia/ixia_fixtures.py mode change 100644 => 100755 tests/ixia/bgp/files/helper.py mode change 100644 => 100755 tests/ixia/bgp/test_bgp_community.py diff --git a/tests/common/ixia/ixia_fixtures.py b/tests/common/ixia/ixia_fixtures.py old mode 100644 new mode 100755 index 1b74c9b7e73..c5371746b6c --- a/tests/common/ixia/ixia_fixtures.py +++ b/tests/common/ixia/ixia_fixtures.py @@ -297,13 +297,19 @@ def ixia_testbed(conn_graph_facts, return config -@pytest.fixture(scope='session') -def api(ixia_api_serv_ip, - ixia_api_serv_port): - # TODO: this is specific to IxNetwork, handle in more - # dynamic way - host = "https://" + ixia_api_serv_ip + ":" + ixia_api_serv_port +@pytest.fixture(scope='module') +def snappi_api(ixia_api_serv_ip, + ixia_api_serv_port): + """ + Snappi session fixture for snappi Tgen API + + Args: + ixia_api_serv_ip (pytest fixture): ixia_api_serv_ip fixture + ixia_api_serv_port (pytest fixture): ixia_api_serv_port fixture. + """ + host = "https://" + ixia_api_serv_ip + ":" + str(ixia_api_serv_port) api = snappi.api(host=host, ext="ixnetwork") + yield api if api.assistant is not None: @@ -316,6 +322,13 @@ def tgen_ports(duthost, fanout_graph_facts): """ + Populate tgen ports info of T0 testbed and returns as a list + + Args: + duthost (pytest fixture): duthost fixture + conn_graph_facts (pytest fixture): connection graph + fanout_graph_facts (pytest fixture): fanout graph + Return: [{'card_id': '1', 'ip': '21.1.1.2', diff --git a/tests/ixia/bgp/files/helper.py b/tests/ixia/bgp/files/helper.py old mode 100644 new mode 100755 index fa72489a291..0db21dd172a --- a/tests/ixia/bgp/files/helper.py +++ b/tests/ixia/bgp/files/helper.py @@ -2,24 +2,28 @@ from tests.common.utilities import wait_until DUT_AS_NUM = 65100 -TGEN1_AS_NUM = 501 -TGEN2_AS_NUM = 502 +TGEN_AS_NUM = 501 BGP_TYPE = 'ebgp' PACKETS = 100000 -def run_bgp_community_test(api, +def run_bgp_community_test(snappi_api, duthost, tgen_ports): """ Run BGP Community test + + Args: + snappi_api (pytest fixture): Snappi API + duthost (pytest fixture): duthost fixture + tgen_ports (pytest fixture): Ports mapping info of T0 testbed """ # Create bgp config on dut __duthost_bgp_config(duthost, tgen_ports) # Create bgp config on TGEN - tgen_bgp_config = __tgen_bgp_config(api, + tgen_bgp_config = __tgen_bgp_config(snappi_api, tgen_ports) # Create BGP community configuration on DUT and TGEN @@ -28,7 +32,7 @@ def run_bgp_community_test(api, # Verity test results __verify_test(duthost, - api, + snappi_api, tgen_community_config) __cleanup_config(duthost, @@ -39,6 +43,10 @@ def __duthost_bgp_config(duthost, tgen_ports): """ BGP Config on duthost + + Args: + duthost (pytest fixture): duthost fixture + tgen_ports (pytest fixture): Ports mapping info of T0 testbed """ intf1_config = ( "vtysh " @@ -62,7 +70,7 @@ def __duthost_bgp_config(duthost, "-c 'neighbor %s activate' " ) bgp_config_501 %= (DUT_AS_NUM, - TGEN1_AS_NUM, + TGEN_AS_NUM, tgen_ports[0]['ip'], tgen_ports[0]['ip']) duthost.shell(bgp_config_501) @@ -78,29 +86,16 @@ def __duthost_bgp_config(duthost, tgen_ports[1]['prefix']) duthost.shell(intf2_config) - bgp_config_502 = ( - "vtysh " - "-c 'configure terminal' " - "-c 'router bgp %s' " - "-c 'neighbor LC502 peer-group' " - "-c 'neighbor LC502 remote-as %s' " - "-c 'neighbor %s peer-group LC502' " - "-c 'address-family ipv4 unicast' " - "-c 'neighbor %s activate' " - ) - bgp_config_502 %= (DUT_AS_NUM, - TGEN2_AS_NUM, - tgen_ports[1]['ip'], - tgen_ports[1]['ip']) - duthost.shell(bgp_config_502) - -def __tgen_bgp_config(api, +def __tgen_bgp_config(snappi_api, tgen_ports): """ BGP & Config on TGEN + Args: + snappi_api (pytest fixture): Snappi API + tgen_ports (pytest fixture): Ports mapping info of T0 testbed """ - config = api.config() + config = snappi_api.config() tx, rx = ( config.ports @@ -108,6 +103,7 @@ def __tgen_bgp_config(api, .port(name='rx', location=tgen_ports[1]['location']) ) + # L1 Config ly = config.layer1.layer1()[-1] ly.name = 'ly' ly.port_names = [tx.name, rx.name] @@ -115,15 +111,15 @@ def __tgen_bgp_config(api, ly.auto_negotiate = False # Device Config - d1, d2 = config.devices.device(name='d501').device(name='d502') + d1, d2 = config.devices.device(name='d1').device(name='d2') d1.container_name = tx.name d2.container_name = rx.name + eth1, eth2 = d1.ethernet, d2.ethernet eth1.name, eth2.name = "eth1", "eth2" + ip1, ip2 = eth1.ipv4, eth2.ipv4 ip1.name, ip2.name = "ip1", "ip2" - bgp501, bgp502 = ip1.bgpv4, ip2.bgpv4 - bgp501.name, bgp502.name = "bgp501", "bgp502" ip1.address.value = tgen_ports[0]['ip'] ip1.gateway.value = tgen_ports[0]['peer_ip'] @@ -133,14 +129,12 @@ def __tgen_bgp_config(api, ip2.gateway.value = tgen_ports[1]['peer_ip'] ip2.prefix.value = tgen_ports[1]['prefix'] + bgp501 = ip1.bgpv4 + bgp501.name = "bgp501" bgp501.dut_ipv4_address.value = tgen_ports[0]['peer_ip'] - bgp501.as_number.value = TGEN1_AS_NUM + bgp501.as_number.value = TGEN_AS_NUM bgp501.as_type = BGP_TYPE - bgp502.dut_ipv4_address.value = tgen_ports[1]['peer_ip'] - bgp502.as_number.value = TGEN2_AS_NUM - bgp502.as_type = BGP_TYPE - return config @@ -148,10 +142,12 @@ def __bgp_community_config(duthost, config): """ BGP Community Config on duthost and TGEN + Args: + snappi_api (pytest fixture): Snappi API + config : tgen config """ bgp501 = config.devices[0].ethernet.ipv4.bgpv4 - bgp502 = config.devices[1].ethernet.ipv4.bgpv4 # Route Range Config bgp501_rr_with_community, bgp501_rr2 = ( @@ -159,7 +155,6 @@ def __bgp_community_config(duthost, .bgpv4routerange() .bgpv4routerange() ) - bgp502_rr1 = bgp502.bgpv4_route_ranges.bgpv4routerange()[-1] # Advertise one route range("200.1.0.0") from AS 501 with community 1:2 bgp501_rr_with_community.name = "bgp501_rr_with_community" @@ -170,28 +165,25 @@ def __bgp_community_config(duthost, manual_as_community.as_number.value = "1" manual_as_community.as_custom.value = "2" - # Advertise another route range("20.1.0.0") from AS 501 without + # Advertise another route range("20.1.0.0") from AS 501 without community bgp501_rr2.name = "bgp501_rr2" bgp501_rr2.address.value = "20.1.0.0" bgp501_rr2.prefix.value = "16" - # Advertise route range("100.1.0.0" from AS 502) - bgp502_rr1.name = "bgp502_rr1" - bgp502_rr1.address.value = "100.1.0.0" - bgp502_rr1.prefix.value = "16" - # Create two flows Permit(Traffic with Community list) & Deny - permit, deny = config.flows.flow(name='permit').flow(name='deny') - permit.rate.percentage = 1 - permit.duration.fixed_packets.packets = PACKETS - deny.rate.percentage = 1 - deny.duration.fixed_packets.packets = PACKETS + flow_permit, flow_deny = config.flows.flow(name='permit').flow(name='deny') - permit.tx_rx.device.tx_names = [bgp502_rr1.name] - permit.tx_rx.device.rx_names = [bgp501_rr_with_community.name] + flow_permit.rate.percentage = 1 + flow_permit.duration.fixed_packets.packets = PACKETS - deny.tx_rx.device.tx_names = [bgp502_rr1.name] - deny.tx_rx.device.rx_names = [bgp501_rr2.name] + flow_deny.rate.percentage = 1 + flow_deny.duration.fixed_packets.packets = PACKETS + + flow_permit.tx_rx.device.tx_names = [config.devices[1].name] + flow_permit.tx_rx.device.rx_names = [bgp501_rr_with_community.name] + + flow_deny.tx_rx.device.tx_names = [config.devices[1].name] + flow_deny.tx_rx.device.rx_names = [bgp501_rr2.name] community_config = ( "vtysh " @@ -206,14 +198,20 @@ def __bgp_community_config(duthost, def __verify_test(duthost, - api, + snappi_api, config): """ Test Verification + + Args: + duthost (pytest fixture): duthost fixture + snappi_api (pytest fixture): Snappi API + config: tgen_config """ - api.set_config(config) - # unconfigure route-map if exists already + snappi_api.set_config(config) + + # unconfigure applied route-map if exists already route_map = ( "vtysh " "-c 'configure terminal' " @@ -225,18 +223,18 @@ def __verify_test(duthost, duthost.shell(route_map) # Start traffic - ts = api.transmit_state() + ts = snappi_api.transmit_state() ts.state = ts.START - api.set_transmit_state(ts) + snappi_api.set_transmit_state(ts) # Check there is no traffic loss for 'permit' & 'deny' pytest_assert(wait_until(60, 2, - lambda: __check_for_no_loss(api, + lambda: __check_for_no_loss(snappi_api, ['permit', 'deny'], PACKETS * 2)), 'No loss expected') - # Add route-map to permit only routes with community + # Apply route-map to permit only routes with community route_map = ( "vtysh " "-c 'configure terminal' " @@ -248,41 +246,53 @@ def __verify_test(duthost, duthost.shell(route_map) # Start traffic - ts = api.transmit_state() + ts = snappi_api.transmit_state() ts.state = ts.START - api.set_transmit_state(ts) + snappi_api.set_transmit_state(ts) # Check there is no traffic loss for 'permit' flow pytest_assert(wait_until(60, 2, - lambda: __check_for_no_loss(api, + lambda: __check_for_no_loss(snappi_api, ['permit'], PACKETS)), 'No loss expected') # Check 100% traffic loss for 'deny' flow pytest_assert(wait_until(60, 2, - lambda: __check_for_total_loss(api, ['deny'])), + lambda: __check_for_total_loss(snappi_api, ['deny'])), 'total loss expected') -def __check_for_no_loss(api, flow_names, expected): +def __check_for_no_loss(snappi_api, + flow_names, + expected): """ Returns True if there is no traffic loss else False + + Args: + snappi_api (pytest fixture): Snappi API + flow_names: List of flow_names to check for validation + expected: Expected Packets Count """ - request = api.metrics_request() + request = snappi_api.metrics_request() request.flow.flow_names = flow_names - flow_results = api.get_metrics(request).flow_metrics + flow_results = snappi_api.get_metrics(request).flow_metrics flow_rx = sum([f.frames_rx for f in flow_results]) return flow_rx == expected -def __check_for_total_loss(api, flow_names): +def __check_for_total_loss(snappi_api, + flow_names): """ Returns True if there is 100% traffic loss else False + + Args: + snappi_api (pytest fixture): Snappi API + flow_names: List of flow_names to check for validation """ - request = api.metrics_request() + request = snappi_api.metrics_request() request.flow.flow_names = flow_names - flow_results = api.get_metrics(request).flow_metrics + flow_results = snappi_api.get_metrics(request).flow_metrics flow_rx = sum([f.frames_rx for f in flow_results]) return flow_rx == 0 @@ -291,6 +301,10 @@ def __cleanup_config(duthost, tgen_ports): """ BGP Config on duthost + + Args: + duthost (pytest fixture): duthost fixture + tgen_ports (pytest fixture): Ports mapping info of T0 testbed """ # Remove community config community_config = ( @@ -311,15 +325,6 @@ def __cleanup_config(duthost, bgp_config_501 %= (DUT_AS_NUM) duthost.shell(bgp_config_501) - bgp_config_502 = ( - "vtysh " - "-c 'configure terminal' " - "-c 'router bgp %s' " - "-c 'no neighbor LC502 peer-group' " - ) - bgp_config_502 %= (DUT_AS_NUM) - duthost.shell(bgp_config_502) - # Remove interface ip config intf1_config = ( "vtysh " @@ -343,4 +348,3 @@ def __cleanup_config(duthost, tgen_ports[1]['prefix']) duthost.shell(intf2_config) - diff --git a/tests/ixia/bgp/test_bgp_community.py b/tests/ixia/bgp/test_bgp_community.py old mode 100644 new mode 100755 index 6a80f4104ef..85994faf10d --- a/tests/ixia/bgp/test_bgp_community.py +++ b/tests/ixia/bgp/test_bgp_community.py @@ -1,14 +1,14 @@ -from tests.common.ixia.ixia_fixtures import api -from tests.common.ixia.ixia_fixtures import tgen_ports +from tests.common.ixia.ixia_fixtures import snappi_api +from tests.common.ixia.ixia_fixtures import ( + ixia_api_serv_ip, ixia_api_serv_port, tgen_ports) from files.helper import run_bgp_community_test -from tests.common.fixtures.conn_graph_facts import conn_graph_facts,\ - fanout_graph_facts -import logging +from tests.common.fixtures.conn_graph_facts import ( + conn_graph_facts, fanout_graph_facts) +import pytest -logger = logging.getLogger(__name__) - -def test_bgp_community(api, +@pytest.mark.topology("tgen") +def test_bgp_community(snappi_api, duthost, tgen_ports, conn_graph_facts, @@ -22,21 +22,28 @@ def test_bgp_community(api, 2) Generate two routes from TGEN1 route1 -- "200.1.0.0" with community 1:2 route2 -- "20.1.0.0" - 3) Create community list in DUT + 3) Create community list in DUT to permit only "200.1.0.0" "ip community-list 10 permit 1:2" 4) Create two flows from TGEN2 to TGEN1 - a) 'permit' -- TGEN2("100.1.0.0") to TGEN1("200.1.0.0") - b) 'deny' -- TGEN2("100.1.0.0") to TGEN1("20.1.0.0") + a) 'permit' -- TGEN2 to TGEN1("200.1.0.0") + b) 'deny' -- TGEN2 to TGEN1("20.1.0.0") Verification: 1) Send traffic without applying route-map Result: Should not observe traffic loss in 'permit' & 'deny' 2) Apply route-map - Result: Should observe traffic loss in 'deny' + Result: Should observe 100% traffic loss in 'deny' + + Args: + snappi_api (pytest fixture): Snappi API + duthost (pytest fixture): duthost fixture + tgen_ports (pytest fixture): Ports mapping info of T0 testbed + conn_graph_facts (pytest fixture): connection graph + fanout_graph_facts (pytest fixture): fanout graph """ # We are going to use first two ports for this test tgen_ports = tgen_ports[0:2] - run_bgp_community_test(api, + run_bgp_community_test(snappi_api, duthost, tgen_ports) From 143858ae7fc34b7605cfc40a3102b8f0a76b6b29 Mon Sep 17 00:00:00 2001 From: Anish Date: Fri, 5 Mar 2021 16:25:14 +0000 Subject: [PATCH 03/12] align with new model --- tests/ixia/bgp/files/helper.py | 347 ++++++++++++++++-- ...munity.py => test_bgp_routing_policies.py} | 46 ++- 2 files changed, 352 insertions(+), 41 deletions(-) rename tests/ixia/bgp/{test_bgp_community.py => test_bgp_routing_policies.py} (50%) diff --git a/tests/ixia/bgp/files/helper.py b/tests/ixia/bgp/files/helper.py index 0db21dd172a..9fbe78f4148 100755 --- a/tests/ixia/bgp/files/helper.py +++ b/tests/ixia/bgp/files/helper.py @@ -1,6 +1,7 @@ from tests.common.helpers.assertions import pytest_assert from tests.common.utilities import wait_until +# TODO: Try to get DUT bgp AS number if already configured DUT_AS_NUM = 65100 TGEN_AS_NUM = 501 BGP_TYPE = 'ebgp' @@ -35,7 +36,45 @@ def run_bgp_community_test(snappi_api, snappi_api, tgen_community_config) - __cleanup_config(duthost, + # Cleanup + __cleanup_community_config(duthost) + + __common_cleanup(duthost, + tgen_ports) + + +def run_bgp_group_as_path_modified(snappi_api, + duthost, + tgen_ports): + """ + Run BGP Community test + + Args: + snappi_api (pytest fixture): Snappi API + duthost (pytest fixture): duthost fixture + tgen_ports (pytest fixture): Ports mapping info of T0 testbed + """ + # Create bgp config on dut + __duthost_bgp_config(duthost, + tgen_ports) + + # Create bgp config on TGEN + tgen_bgp_config = __tgen_bgp_config(snappi_api, + tgen_ports) + + # Create BGP community configuration on DUT and TGEN + as_path_modified_config = __bgp_as_path_modified_config(duthost, + tgen_bgp_config) + + # Verity test results + __verify_test(duthost, + snappi_api, + as_path_modified_config) + + # Cleanup + __cleanup_as_path_config(duthost) + + __common_cleanup(duthost, tgen_ports) @@ -86,6 +125,45 @@ def __duthost_bgp_config(duthost, tgen_ports[1]['prefix']) duthost.shell(intf2_config) + # ipv6 config + intf1_v6_config = ( + "vtysh " + "-c 'configure terminal' " + "-c 'interface %s' " + "-c 'ipv6 address %s/%s' " + ) + intf1_v6_config %= (tgen_ports[0]['peer_port'], + tgen_ports[0]['peer_ipv6'], + tgen_ports[0]['ipv6_prefix']) + duthost.shell(intf1_v6_config) + + bgpv6_config_501 = ( + "vtysh " + "-c 'configure terminal' " + "-c 'router bgp %s' " + "-c 'neighbor LC501v6 peer-group' " + "-c 'neighbor LC501v6 remote-as %s' " + "-c 'neighbor %s peer-group LC501v6' " + "-c 'address-family ipv6 unicast' " + "-c 'neighbor %s activate' " + ) + bgpv6_config_501 %= (DUT_AS_NUM, + TGEN_AS_NUM, + tgen_ports[0]['ipv6'], + tgen_ports[0]['ipv6']) + duthost.shell(bgpv6_config_501) + + intf2_v6_config = ( + "vtysh " + "-c 'configure terminal' " + "-c 'interface %s' " + "-c 'ipv6 address %s/%s' " + ) + intf2_v6_config %= (tgen_ports[1]['peer_port'], + tgen_ports[1]['peer_ipv6'], + tgen_ports[1]['ipv6_prefix']) + duthost.shell(intf2_v6_config) + def __tgen_bgp_config(snappi_api, tgen_ports): @@ -97,23 +175,24 @@ def __tgen_bgp_config(snappi_api, """ config = snappi_api.config() - tx, rx = ( + tgen1, tgen2 = ( config.ports - .port(name='tx', location=tgen_ports[0]['location']) - .port(name='rx', location=tgen_ports[1]['location']) + .port(name='tgen1', location=tgen_ports[0]['location']) + .port(name='tgen2', location=tgen_ports[1]['location']) ) # L1 Config + config.options.port_options.location_preemption = True ly = config.layer1.layer1()[-1] ly.name = 'ly' - ly.port_names = [tx.name, rx.name] + ly.port_names = [tgen1.name, tgen2.name] ly.speed = tgen_ports[0]['speed'] ly.auto_negotiate = False # Device Config d1, d2 = config.devices.device(name='d1').device(name='d2') - d1.container_name = tx.name - d2.container_name = rx.name + d1.container_name = tgen1.name + d2.container_name = tgen2.name eth1, eth2 = d1.ethernet, d2.ethernet eth1.name, eth2.name = "eth1", "eth2" @@ -121,20 +200,38 @@ def __tgen_bgp_config(snappi_api, ip1, ip2 = eth1.ipv4, eth2.ipv4 ip1.name, ip2.name = "ip1", "ip2" - ip1.address.value = tgen_ports[0]['ip'] - ip1.gateway.value = tgen_ports[0]['peer_ip'] - ip1.prefix.value = tgen_ports[0]['prefix'] + ip1.address = tgen_ports[0]['ip'] + ip1.gateway = tgen_ports[0]['peer_ip'] + ip1.prefix = tgen_ports[0]['prefix'] - ip2.address.value = tgen_ports[1]['ip'] - ip2.gateway.value = tgen_ports[1]['peer_ip'] - ip2.prefix.value = tgen_ports[1]['prefix'] + ip2.address = tgen_ports[1]['ip'] + ip2.gateway = tgen_ports[1]['peer_ip'] + ip2.prefix = tgen_ports[1]['prefix'] bgp501 = ip1.bgpv4 bgp501.name = "bgp501" - bgp501.dut_ipv4_address.value = tgen_ports[0]['peer_ip'] - bgp501.as_number.value = TGEN_AS_NUM + bgp501.dut_address = tgen_ports[0]['peer_ip'] + bgp501.as_number = TGEN_AS_NUM bgp501.as_type = BGP_TYPE + # v6 config + ip1v6, ip2v6 = eth1.ipv6, eth2.ipv6 + ip1v6.name, ip2v6.name = "ip1v6", "ip2v6" + + ip1v6.address = tgen_ports[0]['ipv6'] + ip1v6.gateway = tgen_ports[0]['peer_ipv6'] + ip1v6.prefix = tgen_ports[0]['ipv6_prefix'] + + ip2v6.address = tgen_ports[1]['ipv6'] + ip2v6.gateway = tgen_ports[1]['peer_ipv6'] + ip2v6.prefix = tgen_ports[1]['ipv6_prefix'] + + bgp501v6 = ip1v6.bgpv6 + bgp501v6.name = "bgp501v6" + bgp501v6.dut_address = tgen_ports[0]['peer_ipv6'] + bgp501v6.as_number = TGEN_AS_NUM + bgp501v6.as_type = BGP_TYPE + return config @@ -151,39 +248,81 @@ def __bgp_community_config(duthost, # Route Range Config bgp501_rr_with_community, bgp501_rr2 = ( - bgp501.bgpv4_route_ranges - .bgpv4routerange() - .bgpv4routerange() + bgp501.bgpv4_routes + .bgpv4route(name="bgp501_rr_with_community") + .bgpv4route(name="bgp501_rr2") ) # Advertise one route range("200.1.0.0") from AS 501 with community 1:2 - bgp501_rr_with_community.name = "bgp501_rr_with_community" - bgp501_rr_with_community.address.value = "200.1.0.0" - bgp501_rr_with_community.prefix.value = "16" - manual_as_community = bgp501_rr_with_community.community.bgpcommunity()[-1] + bgp501_rr_with_community.addresses.bgpv4routeaddress(address="200.1.0.0", + prefix="16") + + manual_as_community = ( + bgp501_rr_with_community.communities.bgpcommunity()[-1]) manual_as_community.community_type = manual_as_community.MANUAL_AS_NUMBER - manual_as_community.as_number.value = "1" - manual_as_community.as_custom.value = "2" + manual_as_community.as_number = 1 + manual_as_community.as_custom = 2 # Advertise another route range("20.1.0.0") from AS 501 without community - bgp501_rr2.name = "bgp501_rr2" - bgp501_rr2.address.value = "20.1.0.0" - bgp501_rr2.prefix.value = "16" + bgp501_rr2.addresses.bgpv4routeaddress(address="20.1.0.0", + prefix="16") + + # ipv6 + bgp501v6 = config.devices[0].ethernet.ipv6.bgpv6 + + # Route Range Config + bgp501v6_rr_with_community, bgp501v6_rr2 = ( + bgp501v6.bgpv6_routes + .bgpv6route(name="bgp501v6_rr_with_community") + .bgpv6route(name="bgp501v6_rr2") + ) + + # Advertise one route range("4000::1") from AS 501 with community 1:2 + bgp501v6_rr_with_community.addresses.bgpv6routeaddress(address="4000::1", + prefix="64") + + manual_as_community = ( + bgp501v6_rr_with_community.communities.bgpcommunity()[-1]) + manual_as_community.community_type = manual_as_community.MANUAL_AS_NUMBER + manual_as_community.as_number = 1 + manual_as_community.as_custom = 2 + + # Advertise another route range("6000::1") from AS 501 without community + bgp501v6_rr2.addresses.bgpv6routeaddress(address="6000::1", + prefix="64") # Create two flows Permit(Traffic with Community list) & Deny - flow_permit, flow_deny = config.flows.flow(name='permit').flow(name='deny') + permit, deny, permit_ipv6, deny_ipv6 = ( + config.flows + .flow(name='permit') + .flow(name='deny') + .flow(name='permit_ipv6') + .flow(name='deny_ipv6') + ) + + permit.tx_rx.device.tx_names = [config.devices[1].ethernet.ipv4.name] + permit.tx_rx.device.rx_names = [bgp501_rr_with_community.name] + + deny.tx_rx.device.tx_names = [config.devices[1].ethernet.ipv4.name] + deny.tx_rx.device.rx_names = [bgp501_rr2.name] - flow_permit.rate.percentage = 1 - flow_permit.duration.fixed_packets.packets = PACKETS + permit.rate.percentage = 1 + permit.duration.fixed_packets.packets = PACKETS - flow_deny.rate.percentage = 1 - flow_deny.duration.fixed_packets.packets = PACKETS + deny.rate.percentage = 1 + deny.duration.fixed_packets.packets = PACKETS - flow_permit.tx_rx.device.tx_names = [config.devices[1].name] - flow_permit.tx_rx.device.rx_names = [bgp501_rr_with_community.name] + permit_ipv6.tx_rx.device.tx_names = [config.devices[1].ethernet.ipv6.name] + permit_ipv6.tx_rx.device.rx_names = [bgp501v6_rr_with_community.name] - flow_deny.tx_rx.device.tx_names = [config.devices[1].name] - flow_deny.tx_rx.device.rx_names = [bgp501_rr2.name] + deny_ipv6.tx_rx.device.tx_names = [config.devices[1].ethernet.ipv6.name] + deny_ipv6.tx_rx.device.rx_names = [bgp501v6_rr2.name] + + permit_ipv6.rate.percentage = 1 + permit_ipv6.duration.fixed_packets.packets = PACKETS + + deny_ipv6.rate.percentage = 1 + deny_ipv6.duration.fixed_packets.packets = PACKETS community_config = ( "vtysh " @@ -197,6 +336,106 @@ def __bgp_community_config(duthost, return config +def __bgp_as_path_modified_config(duthost, + config): + """ + BGP group AS config on duthost and TGEN + Args: + snappi_api (pytest fixture): Snappi API + config : tgen config + """ + + bgp501 = config.devices[0].ethernet.ipv4.bgpv4 + + bgp501 = config.devices[0].ethernet.ipv4.bgpv4 + + # Route Range Config + bgp501_rr_with_as_100, bgp501_rr2 = ( + bgp501.bgpv4_routes + .bgpv4route(name="bgp501_rr_with_as_100") + .bgpv4route(name="bgp501_rr2") + ) + + # Advertise one route range("200.1.0.0") from AS 501 with additional AS 100 + bgp501_rr_with_as_100.addresses.bgpv4routeaddress(address="200.1.0.0", + prefix="16") + + as_path = bgp501_rr_with_as_100.as_path + as_path_segment = as_path.as_path_segments.bgpaspathsegment()[-1] + as_path_segment.segment_type = as_path_segment.AS_SEQ + as_path_segment.as_numbers = [100] + + # Advertise another route range("20.1.0.0") + bgp501_rr2.addresses.bgpv4routeaddress(address="20.1.0.0", + prefix="16") + + # ipv6 + bgp501v6 = config.devices[0].ethernet.ipv6.bgpv6 + + # Route Range Config + bgp501v6_rr_with_as_100, bgp501v6_rr2 = ( + bgp501v6.bgpv6_routes + .bgpv6route(name="bgp501v6_rr_with_as_100") + .bgpv6route(name="bgp501v6_rr2") + ) + + # Advertise one route range("4000::1") from AS 501 with additional AS 100 + bgp501v6_rr_with_as_100.addresses.bgpv6routeaddress(address="4000::1", + prefix="64") + + as_path = bgp501v6_rr_with_as_100.as_path + as_path_segment = as_path.as_path_segments.bgpaspathsegment()[-1] + as_path_segment.segment_type = as_path_segment.AS_SEQ + as_path_segment.as_numbers = [100] + + # Advertise another route range("6000::1") + bgp501v6_rr2.addresses.bgpv6routeaddress(address="6000::1", + prefix="64") + + permit, deny, permit_ipv6, deny_ipv6 = ( + config.flows + .flow(name='permit') + .flow(name='deny') + .flow(name='permit_ipv6') + .flow(name='deny_ipv6') + ) + + permit.tx_rx.device.tx_names = [config.devices[1].ethernet.ipv4.name] + permit.tx_rx.device.rx_names = [bgp501_rr_with_as_100.name] + + deny.tx_rx.device.tx_names = [config.devices[1].ethernet.ipv4.name] + deny.tx_rx.device.rx_names = [bgp501_rr2.name] + + permit.rate.percentage = 1 + permit.duration.fixed_packets.packets = PACKETS + + deny.rate.percentage = 1 + deny.duration.fixed_packets.packets = PACKETS + + permit_ipv6.tx_rx.device.tx_names = [config.devices[1].ethernet.ipv6.name] + permit_ipv6.tx_rx.device.rx_names = [bgp501v6_rr_with_as_100.name] + + deny_ipv6.tx_rx.device.tx_names = [config.devices[1].ethernet.ipv6.name] + deny_ipv6.tx_rx.device.rx_names = [bgp501v6_rr2.name] + + permit_ipv6.rate.percentage = 1 + permit_ipv6.duration.fixed_packets.packets = PACKETS + + deny_ipv6.rate.percentage = 1 + deny_ipv6.duration.fixed_packets.packets = PACKETS + + community_config = ( + "vtysh " + "-c 'configure terminal' " + "-c 'bgp as-path access-list permit_100 permit 100' " + "-c 'route-map LA permit 30' " + "-c 'match as-path permit_100'" + ) + duthost.shell(community_config) + + return config + + def __verify_test(duthost, snappi_api, config): @@ -297,8 +536,7 @@ def __check_for_total_loss(snappi_api, return flow_rx == 0 -def __cleanup_config(duthost, - tgen_ports): +def __cleanup_community_config(duthost): """ BGP Config on duthost @@ -315,12 +553,35 @@ def __cleanup_config(duthost, ) duthost.shell(community_config) + +def __cleanup_as_path_config(duthost): + """ + BGP Config on duthost + + Args: + duthost (pytest fixture): duthost fixture + tgen_ports (pytest fixture): Ports mapping info of T0 testbed + """ + # Remove community config + community_config = ( + "vtysh " + "-c 'configure terminal' " + "-c 'no bgp as-path access-list permit_100 permit 100' " + "-c 'no route-map LA permit 30' " + ) + duthost.shell(community_config) + + +def __common_cleanup(duthost, + tgen_ports): + # Remove bgp neighbor config bgp_config_501 = ( "vtysh " "-c 'configure terminal' " "-c 'router bgp %s' " "-c 'no neighbor LC501 peer-group' " + "-c 'no neighbor LC501v6 peer-group' " ) bgp_config_501 %= (DUT_AS_NUM) duthost.shell(bgp_config_501) @@ -331,10 +592,13 @@ def __cleanup_config(duthost, "-c 'configure terminal' " "-c 'interface %s' " "-c 'no ip address %s/%s' " + "-c 'no ipv6 address %s/%s' " ) intf1_config %= (tgen_ports[0]['peer_port'], tgen_ports[0]['peer_ip'], - tgen_ports[0]['prefix']) + tgen_ports[0]['prefix'], + tgen_ports[0]['peer_ipv6'], + tgen_ports[0]['ipv6_prefix']) duthost.shell(intf1_config) intf2_config = ( @@ -342,9 +606,12 @@ def __cleanup_config(duthost, "-c 'configure terminal' " "-c 'interface %s' " "-c 'no ip address %s/%s' " + "-c 'no ipv6 address %s/%s' " ) intf2_config %= (tgen_ports[1]['peer_port'], tgen_ports[1]['peer_ip'], - tgen_ports[1]['prefix']) + tgen_ports[1]['prefix'], + tgen_ports[0]['peer_ipv6'], + tgen_ports[0]['ipv6_prefix']) duthost.shell(intf2_config) diff --git a/tests/ixia/bgp/test_bgp_community.py b/tests/ixia/bgp/test_bgp_routing_policies.py similarity index 50% rename from tests/ixia/bgp/test_bgp_community.py rename to tests/ixia/bgp/test_bgp_routing_policies.py index 85994faf10d..d547e8e18ac 100755 --- a/tests/ixia/bgp/test_bgp_community.py +++ b/tests/ixia/bgp/test_bgp_routing_policies.py @@ -1,7 +1,8 @@ from tests.common.ixia.ixia_fixtures import snappi_api from tests.common.ixia.ixia_fixtures import ( ixia_api_serv_ip, ixia_api_serv_port, tgen_ports) -from files.helper import run_bgp_community_test +from files.helper import ( + run_bgp_community_test, run_bgp_group_as_path_modified) from tests.common.fixtures.conn_graph_facts import ( conn_graph_facts, fanout_graph_facts) import pytest @@ -47,3 +48,46 @@ def test_bgp_community(snappi_api, run_bgp_community_test(snappi_api, duthost, tgen_ports) + + +@pytest.mark.topology("tgen") +def test_bgp_group_as_path_modified(snappi_api, + duthost, + tgen_ports, + conn_graph_facts, + fanout_graph_facts): + """ + # TODO: update the description + Topo: + TGEN1 --- DUT --- TGEN2 + + Steps: + 1) Create BGP config on DUT and TGEN respectively + 2) Generate two routes from TGEN1 + route1 -- "200.1.0.0" with community 1:2 + route2 -- "20.1.0.0" + 3) Create community list in DUT to permit only "200.1.0.0" + "ip community-list 10 permit 1:2" + 4) Create two flows from TGEN2 to TGEN1 + a) 'permit' -- TGEN2 to TGEN1("200.1.0.0") + b) 'deny' -- TGEN2 to TGEN1("20.1.0.0") + + Verification: + 1) Send traffic without applying route-map + Result: Should not observe traffic loss in 'permit' & 'deny' + 2) Apply route-map + Result: Should observe 100% traffic loss in 'deny' + + Args: + snappi_api (pytest fixture): Snappi API + duthost (pytest fixture): duthost fixture + tgen_ports (pytest fixture): Ports mapping info of T0 testbed + conn_graph_facts (pytest fixture): connection graph + fanout_graph_facts (pytest fixture): fanout graph + """ + # We are going to use first two ports for this test + tgen_ports = tgen_ports[0:2] + + run_bgp_group_as_path_modified(snappi_api, + duthost, + tgen_ports) From 547d66319c806a12308a0803d472d0d687c014bb Mon Sep 17 00:00:00 2001 From: Anish Date: Fri, 12 Mar 2021 10:55:26 +0000 Subject: [PATCH 04/12] updating bgp tencent tests --- tests/common/ixia/common_helpers.py | 28 + tests/common/ixia/ixia_fixtures.py | 55 +- tests/ixia/bgp/files/helper.py | 1265 +++++++++++++++---- tests/ixia/bgp/test_bgp_routing_policies.py | 270 +++- 4 files changed, 1312 insertions(+), 306 deletions(-) diff --git a/tests/common/ixia/common_helpers.py b/tests/common/ixia/common_helpers.py index b38d4beb9cb..a2a2e5e017d 100644 --- a/tests/common/ixia/common_helpers.py +++ b/tests/common/ixia/common_helpers.py @@ -13,6 +13,8 @@ import ipaddr from netaddr import IPNetwork +from ipaddress import IPv6Network, IPv6Address +from random import getrandbits from tests.common.mellanox_data import is_mellanox_device as isMellanoxDevice def increment_ip_address (ip, incr=1) : @@ -119,6 +121,32 @@ def get_addrs_in_subnet(subnet, number_of_ip): return ip_addrs[:number_of_ip] + +def get_ipv6_addrs_in_subnet(subnet, number_of_ip): + """ + Get N IPv6 addresses in a subnet. + + Args: + subnet (str): IPv6 subnet, e.g., '2001::1/64' + number_of_ip (int): Number of IP addresses to get + + Return: + Return n IPv6 addresses in this subnet in a list. + """ + + subnet = str(IPNetwork(subnet).network) + "/" + str(subnet.split("/")[1]) + subnet = unicode(subnet, "utf-8") + ipv6_list = [] + for i in range(number_of_ip): + network = IPv6Network(subnet) + address = IPv6Address( + network.network_address + getrandbits( + network.max_prefixlen - network.prefixlen)) + ipv6_list.append(str(address)) + + return ipv6_list + + def get_peer_ixia_chassis(conn_data, dut_hostname): """ Get the IXIA chassis connected to the DUT diff --git a/tests/common/ixia/ixia_fixtures.py b/tests/common/ixia/ixia_fixtures.py index c5371746b6c..91cca96d01e 100755 --- a/tests/common/ixia/ixia_fixtures.py +++ b/tests/common/ixia/ixia_fixtures.py @@ -9,7 +9,7 @@ from tests.common.fixtures.conn_graph_facts import conn_graph_facts,\ fanout_graph_facts from tests.common.ixia.common_helpers import get_vlan_subnet, get_addrs_in_subnet,\ - get_peer_ixia_chassis + get_peer_ixia_chassis, get_ipv6_addrs_in_subnet from tests.common.ixia.ixia_helpers import IxiaFanoutManager, get_tgen_location import snappi @@ -316,7 +316,7 @@ def snappi_api(ixia_api_serv_ip, api.assistant.Session.remove() -@pytest.fixture(scope="function") +@pytest.fixture(scope="module") def tgen_ports(duthost, conn_graph_facts, fanout_graph_facts): @@ -330,24 +330,30 @@ def tgen_ports(duthost, fanout_graph_facts (pytest fixture): fanout graph Return: - [{'card_id': '1', - 'ip': '21.1.1.2', + [{'card_id': '1', + 'ip': '22.1.1.2', + 'ipv6': '3001::2', + 'ipv6_prefix': u'64', 'location': '10.36.78.238;1;2', - 'prefix': u'24', - 'peer_ip': u'21.1.1.1', - 'peer_device': 'example-s6100-dut-1', - 'peer_port': 'Ethernet0', + 'peer_device': 'sonic-s6100-dut', + 'peer_ip': u'22.1.1.1', + 'peer_ipv6': u'3001::1', + 'peer_port': 'Ethernet8', 'port_id': '2', - 'speed': '400000'}, + 'prefix': u'24', + 'speed': 'speed_400_gbps'}, {'card_id': '1', - 'ip': '22.1.1.2', + 'ip': '21.1.1.2', + 'ipv6': '2001::2', + 'ipv6_prefix': u'64', 'location': '10.36.78.238;1;1', - 'prefix': u'24', - 'peer_ip': u'22.1.1.1', - 'peer_device': 'example-s6100-dut-1', - 'peer_port': 'Ethernet8', + 'peer_device': 'sonic-s6100-dut', + 'peer_ip': u'21.1.1.1', + 'peer_ipv6': u'2001::1', + 'peer_port': 'Ethernet0', 'port_id': '1', - 'speed': '400000'}] + 'prefix': u'24', + 'speed': 'speed_400_gbps'}] """ speed_type = {'50000': 'speed_50_gbps', @@ -379,12 +385,21 @@ def tgen_ports(duthost, port['speed'] = speed_type[port['speed']] for port in ixia_ports: + peer_port = port['peer_port'] - subnet = config_facts['INTERFACE'][peer_port].keys()[0] - if not subnet: - raise Exception("IP is not configured on the interface {}" + int_addrs = config_facts['INTERFACE'][peer_port].keys() + ipv4_subnet = [ele for ele in int_addrs if "." in ele][0] + ipv6_subnet = [ele for ele in int_addrs if ":" in ele][0] + if not ipv4_subnet: + raise Exception("IPv4 is not configured on the interface {}" + .format(peer_port)) + port['peer_ip'], port['prefix'] = ipv4_subnet.split("/") + port['ip'] = get_addrs_in_subnet(ipv4_subnet, 1)[0] + + if not ipv6_subnet: + raise Exception("IPv6 is not configured on the interface {}" .format(peer_port)) - port['peer_ip'], port['prefix'] = subnet.split("/") - port['ip'] = get_addrs_in_subnet(subnet, 1)[0] + port['peer_ipv6'], port['ipv6_prefix'] = ipv6_subnet.split("/") + port['ipv6'] = get_ipv6_addrs_in_subnet(ipv6_subnet, 1)[0] return ixia_ports diff --git a/tests/ixia/bgp/files/helper.py b/tests/ixia/bgp/files/helper.py index 9fbe78f4148..e286e748a9c 100755 --- a/tests/ixia/bgp/files/helper.py +++ b/tests/ixia/bgp/files/helper.py @@ -1,297 +1,837 @@ from tests.common.helpers.assertions import pytest_assert from tests.common.utilities import wait_until +import logging -# TODO: Try to get DUT bgp AS number if already configured -DUT_AS_NUM = 65100 +logger = logging.getLogger(__name__) + +DUT_AS_NUM = 10086 TGEN_AS_NUM = 501 BGP_TYPE = 'ebgp' PACKETS = 100000 +LINE_RATE = 1 +COMMUNITY = "1:2" +MED = 50 +GROUP_AS = [100] + + +def config_setup(duthost, + tgen_ports): + """ + BGP Config on duthost + + Args: + duthost (pytest fixture): duthost fixture + tgen_ports (pytest fixture): Ports mapping info of T0 testbed + """ + logger.info("|--Remove Any Existing BGP Process on DUT--|") + try: + duthost.shell( + "vtysh " + "-c 'configure terminal' " + "-c 'no router bgp' " + ) + except Exception: + logger.info("No BGP process is configured") + + logger.info("|--Interface Configuration On DUT--|") + intf1_config = ( + "vtysh " + "-c 'configure terminal' " + "-c 'interface %s' " + "-c 'ip address %s/%s' " + ) + intf1_config %= (tgen_ports[0]['peer_port'], + tgen_ports[0]['peer_ip'], + tgen_ports[0]['prefix']) + duthost.shell(intf1_config) + + intf2_config = ( + "vtysh " + "-c 'configure terminal' " + "-c 'interface %s' " + "-c 'ip address %s/%s' " + ) + intf2_config %= (tgen_ports[1]['peer_port'], + tgen_ports[1]['peer_ip'], + tgen_ports[1]['prefix']) + duthost.shell(intf2_config) + + # ipv6 interface config + intf1_v6_config = ( + "vtysh " + "-c 'configure terminal' " + "-c 'interface %s' " + "-c 'ipv6 address %s/%s' " + ) + intf1_v6_config %= (tgen_ports[0]['peer_port'], + tgen_ports[0]['peer_ipv6'], + tgen_ports[0]['ipv6_prefix']) + duthost.shell(intf1_v6_config) + + intf2_v6_config = ( + "vtysh " + "-c 'configure terminal' " + "-c 'interface %s' " + "-c 'ipv6 address %s/%s' " + ) + intf2_v6_config %= (tgen_ports[1]['peer_port'], + tgen_ports[1]['peer_ipv6'], + tgen_ports[1]['ipv6_prefix']) + duthost.shell(intf2_v6_config) + + logger.info("|--BGP Configuration On DUT--|") + bgp_config_501 = ( + "vtysh " + "-c 'configure terminal' " + "-c 'router bgp %s' " + "-c 'no bgp default ipv4-unicast' " + "-c 'no bgp ebgp-requires-policy' " + "-c 'neighbor LC501 peer-group' " + "-c 'neighbor LC501 remote-as %s' " + "-c 'neighbor %s peer-group LC501' " + "-c 'address-family ipv4 unicast' " + "-c 'neighbor %s activate' " + ) + bgp_config_501 %= (DUT_AS_NUM, + TGEN_AS_NUM, + tgen_ports[0]['ip'], + tgen_ports[0]['ip']) + duthost.shell(bgp_config_501) + + bgpv6_config_501 = ( + "vtysh " + "-c 'configure terminal' " + "-c 'router bgp %s' " + "-c 'neighbor LC501v6 peer-group' " + "-c 'neighbor LC501v6 remote-as %s' " + "-c 'neighbor %s peer-group LC501v6' " + "-c 'address-family ipv6 unicast' " + "-c 'neighbor %s activate' " + ) + bgpv6_config_501 %= (DUT_AS_NUM, + TGEN_AS_NUM, + tgen_ports[0]['ipv6'], + tgen_ports[0]['ipv6']) + duthost.shell(bgpv6_config_501) + + # ipv6 next hop route-map + next_hop = ( + "vtysh " + "-c 'configure terminal' " + "-c 'route-map NEXTHOP permit 1' " + "-c 'on-match next' " + "-c 'set ipv6 next-hop prefer-global' " + "-c 'router bgp %s' " + "-c 'address-family ipv6 unicast' " + "-c 'neighbor LC501v6 route-map NEXTHOP in' " + ) + next_hop %= (DUT_AS_NUM) + duthost.shell(next_hop) + + +def run_bgp_peer_routing_policies_test(snappi_api, + duthost, + tgen_ports): + """ + Run BGP Peer Routing Policies Test + + Args: + snappi_api (pytest fixture): Snappi API + duthost (pytest fixture): duthost fixture + tgen_ports (pytest fixture): Ports mapping info of T0 testbed + """ + logger.info("|--Create BGP TGEN Configuration--|") + tgen_bgp_config = __tgen_bgp_config(snappi_api, + tgen_ports) + + logger.info("|--Updating TGEN Config with BGP Route Attributes--|") + tgen_bgp_policies_config = __tgen_bgp_policies_config(tgen_bgp_config) + + logger.info("|--BGP Policy Route Map Configuration on DUT--|") + __bgp_policies_route_map_config(duthost) + + logger.info("|--Verify Test--|") + __verify_test(duthost, + snappi_api, + tgen_bgp_policies_config) def run_bgp_community_test(snappi_api, duthost, tgen_ports): """ - Run BGP Community test + Run BGP Community List Filtering Test Args: snappi_api (pytest fixture): Snappi API duthost (pytest fixture): duthost fixture tgen_ports (pytest fixture): Ports mapping info of T0 testbed """ - # Create bgp config on dut - __duthost_bgp_config(duthost, - tgen_ports) + logger.info("|--Create BGP TGEN Configuration--|") + tgen_bgp_config = __tgen_bgp_config(snappi_api, + tgen_ports) + + logger.info("|--Updating TGEN Config with BGP Community Attribute--|") + tgen_bgp_community_config = __tgen_bgp_community_config(tgen_bgp_config) + + logger.info("|--BGP Community Route Map Configuration on DUT--|") + __bgp_community_route_map_config(duthost) + + logger.info("|--Verify Test--|") + __verify_test(duthost, + snappi_api, + tgen_bgp_community_config) - # Create bgp config on TGEN + +def run_bgp_prefix_list_test(snappi_api, + duthost, + tgen_ports): + """ + Run BGP Prefix List Filtering Test + + Args: + snappi_api (pytest fixture): Snappi API + duthost (pytest fixture): duthost fixture + tgen_ports (pytest fixture): Ports mapping info of T0 testbed + """ + logger.info("|--Create BGP TGEN Configuration--|") tgen_bgp_config = __tgen_bgp_config(snappi_api, tgen_ports) - # Create BGP community configuration on DUT and TGEN - tgen_community_config = __bgp_community_config(duthost, - tgen_bgp_config) + logger.info("|--Updating TGEN Config with with Prefix Lists--|") + tgen_bgp_prefix_list_config = __tgen_bgp_prefix_list_config( + tgen_bgp_config) - # Verity test results + logger.info("|--BGP Prefix List Route Map Configuration on DUT--|") + __bgp_prefix_list_route_map_config(duthost) + + logger.info("|--Verify Test--|") __verify_test(duthost, snappi_api, - tgen_community_config) + tgen_bgp_prefix_list_config) - # Cleanup - __cleanup_community_config(duthost) - __common_cleanup(duthost, - tgen_ports) +def run_bgp_metric_filter(snappi_api, + duthost, + tgen_ports): + """ + Run BGP Metric Filter Test + + Args: + snappi_api (pytest fixture): Snappi API + duthost (pytest fixture): duthost fixture + tgen_ports (pytest fixture): Ports mapping info of T0 testbed + """ + + logger.info("|--Create BGP TGEN Configuration--|") + tgen_bgp_config = __tgen_bgp_config(snappi_api, + tgen_ports) + + logger.info("|--Updating TGEN Config with Metric/MED Attribute--|") + tgen_bgp_metric_config = __tgen_bgp_metric_config(tgen_bgp_config) + + logger.info("|--BGP Metric Route Map Configuration on DUT--|") + __bgp_metric_route_map_config(duthost) + + logger.info("|--Verify Test--|") + __verify_test(duthost, + snappi_api, + tgen_bgp_metric_config) def run_bgp_group_as_path_modified(snappi_api, duthost, tgen_ports): """ - Run BGP Community test + Run BGP group-as-path Modified Test Args: snappi_api (pytest fixture): Snappi API duthost (pytest fixture): duthost fixture tgen_ports (pytest fixture): Ports mapping info of T0 testbed """ - # Create bgp config on dut - __duthost_bgp_config(duthost, - tgen_ports) + logger.info("|--Create BGP TGEN Configuration--|") + tgen_bgp_config = __tgen_bgp_config(snappi_api, + tgen_ports) - # Create bgp config on TGEN + logger.info("|--Updating TGEN Config with Group AS-PATH Attribute--|") + tgen_as_path_modified_config = __tgen_bgp_as_path_modified_config( + tgen_bgp_config) + + logger.info("|--BGP AS-PATH Route Map Configuration on DUT--|") + __bgp_as_path_route_map_config(duthost) + + logger.info("|--Verify Test--|") + __verify_test(duthost, + snappi_api, + tgen_as_path_modified_config) + + +def run_bgp_origin_code_modification(snappi_api, + duthost, + tgen_ports): + """ + Run BGP Origin Code Modification Test + + Args: + snappi_api (pytest fixture): Snappi API + duthost (pytest fixture): duthost fixture + tgen_ports (pytest fixture): Ports mapping info of T0 testbed + """ + logger.info("|--Create BGP TGEN Configuration--|") tgen_bgp_config = __tgen_bgp_config(snappi_api, tgen_ports) - # Create BGP community configuration on DUT and TGEN - as_path_modified_config = __bgp_as_path_modified_config(duthost, - tgen_bgp_config) + logger.info("|--Updating TGEN Config with Origin Attribute--|") + tgen_bgp_origin_config = __tgen_bgp_origin_config(tgen_bgp_config) + + logger.info("|--BGP Origin Route Map Configuration on DUT--|") + __bgp_origin_route_map_config(duthost) - # Verity test results + logger.info("|--Verify Test--|") __verify_test(duthost, snappi_api, - as_path_modified_config) + tgen_bgp_origin_config) - # Cleanup - __cleanup_as_path_config(duthost) - __common_cleanup(duthost, - tgen_ports) +# Common TGEN BGP Config +def __tgen_bgp_config(snappi_api, + tgen_ports): + """ + BGP Config on TGEN + Args: + snappi_api (pytest fixture): Snappi API + tgen_ports (pytest fixture): Ports mapping info of T0 testbed + """ + config = snappi_api.config() + tgen1, tgen2 = ( + config.ports + .port(name='tgen1', location=tgen_ports[0]['location']) + .port(name='tgen2', location=tgen_ports[1]['location']) + ) -def __duthost_bgp_config(duthost, - tgen_ports): + # L1 Config + config.options.port_options.location_preemption = True + ly = config.layer1.layer1()[-1] + ly.name = 'ly' + ly.port_names = [tgen1.name, tgen2.name] + ly.speed = tgen_ports[0]['speed'] + ly.auto_negotiate = False + + # Device Config + d1, d2 = config.devices.device(name='d1').device(name='d2') + d1.container_name = tgen1.name + d2.container_name = tgen2.name + + eth1, eth2 = d1.ethernet, d2.ethernet + eth1.name, eth2.name = "eth1", "eth2" + + ip1, ip2 = eth1.ipv4, eth2.ipv4 + ip1.name, ip2.name = "ip1", "ip2" + + ip1.address = tgen_ports[0]['ip'] + ip1.gateway = tgen_ports[0]['peer_ip'] + ip1.prefix = tgen_ports[0]['prefix'] + + ip2.address = tgen_ports[1]['ip'] + ip2.gateway = tgen_ports[1]['peer_ip'] + ip2.prefix = tgen_ports[1]['prefix'] + + # BGPv4 + bgp501 = ip1.bgpv4 + bgp501.name = "bgp501" + bgp501.dut_address = tgen_ports[0]['peer_ip'] + bgp501.as_number = TGEN_AS_NUM + bgp501.as_type = BGP_TYPE + + # v6 config + ip1v6, ip2v6 = eth1.ipv6, eth2.ipv6 + ip1v6.name, ip2v6.name = "ip1v6", "ip2v6" + + ip1v6.address = tgen_ports[0]['ipv6'] + ip1v6.gateway = tgen_ports[0]['peer_ipv6'] + ip1v6.prefix = tgen_ports[0]['ipv6_prefix'] + + ip2v6.address = tgen_ports[1]['ipv6'] + ip2v6.gateway = tgen_ports[1]['peer_ipv6'] + ip2v6.prefix = tgen_ports[1]['ipv6_prefix'] + + # BGPv6 + bgp501v6 = ip1v6.bgpv6 + bgp501v6.name = "bgp501v6" + bgp501v6.dut_address = tgen_ports[0]['peer_ipv6'] + bgp501v6.as_number = TGEN_AS_NUM + bgp501v6.as_type = BGP_TYPE + + return config + + +def __tgen_bgp_policies_config(config): """ - BGP Config on duthost + BGP Attributes Config on TGEN + Args: + config : tgen config + """ + + bgp501 = config.devices[0].ethernet.ipv4.bgpv4 + # Routes Config + bgp501_rr_with_policies, bgp501_rr2 = ( + bgp501.bgpv4_routes + .bgpv4route(name="bgp501_rr_with_policies") + .bgpv4route(name="bgp501_rr2") + ) + + # Advertise one route("200.1.0.0") from AS 501 attributes + bgp501_rr_with_policies.addresses.bgpv4routeaddress(address="200.1.0.0", + prefix=16) + + # Community + manual_as_community = ( + bgp501_rr_with_policies.communities.bgpcommunity()[-1]) + manual_as_community.community_type = manual_as_community.MANUAL_AS_NUMBER + manual_as_community.as_number = int(COMMUNITY.split(":")[0]) + manual_as_community.as_custom = int(COMMUNITY.split(":")[1]) + # Metric + bgp501_rr_with_policies.advanced.multi_exit_discriminator = MED + # AS PATH + as_path = bgp501_rr_with_policies.as_path + as_path_segment = as_path.as_path_segments.bgpaspathsegment()[-1] + as_path_segment.segment_type = as_path_segment.AS_SEQ + as_path_segment.as_numbers = GROUP_AS + # Origin + bgp501_rr_with_policies.advanced.origin = ( + bgp501_rr_with_policies.advanced.EGP) + + # Advertise another route("20.1.0.0") from AS 501 + bgp501_rr2.addresses.bgpv4routeaddress(address="20.1.0.0", + prefix=16) + + # ipv6 + bgp501v6 = config.devices[0].ethernet.ipv6.bgpv6 + + # Routes Config + bgp501v6_rr_with_policies, bgp501v6_rr2 = ( + bgp501v6.bgpv6_routes + .bgpv6route(name="bgp501v6_rr_with_policies") + .bgpv6route(name="bgp501v6_rr2") + ) + + # Advertise one route("4000::1") from AS 501 with Attributes + bgp501v6_rr_with_policies.addresses.bgpv6routeaddress(address="4000::1", + prefix=64) + + # Community + manual_as_community = ( + bgp501v6_rr_with_policies.communities.bgpcommunity()[-1]) + manual_as_community.community_type = manual_as_community.MANUAL_AS_NUMBER + manual_as_community.as_number = int(COMMUNITY.split(":")[0]) + manual_as_community.as_custom = int(COMMUNITY.split(":")[1]) + # Metric + bgp501v6_rr_with_policies.advanced.multi_exit_discriminator = MED + # AS PATH + as_path = bgp501v6_rr_with_policies.as_path + as_path_segment = as_path.as_path_segments.bgpaspathsegment()[-1] + as_path_segment.segment_type = as_path_segment.AS_SEQ + as_path_segment.as_numbers = GROUP_AS + # Origin + bgp501v6_rr_with_policies.advanced.origin = ( + bgp501v6_rr_with_policies.advanced.EGP) + + # Advertise another route("6000::1") from AS 501 + bgp501v6_rr2.addresses.bgpv6routeaddress(address="6000::1", + prefix=64) + + # Create four flows + permit, deny, permit_ipv6, deny_ipv6 = ( + config.flows + .flow(name='permit') + .flow(name='deny') + .flow(name='permit_ipv6') + .flow(name='deny_ipv6') + ) + + permit.tx_rx.device.tx_names = [config.devices[1].ethernet.ipv4.name] + permit.tx_rx.device.rx_names = [bgp501_rr_with_policies.name] + + deny.tx_rx.device.tx_names = [config.devices[1].ethernet.ipv4.name] + deny.tx_rx.device.rx_names = [bgp501_rr2.name] + + permit.rate.percentage = LINE_RATE + permit.duration.fixed_packets.packets = PACKETS + + deny.rate.percentage = LINE_RATE + deny.duration.fixed_packets.packets = PACKETS + + permit_ipv6.tx_rx.device.tx_names = [config.devices[1].ethernet.ipv6.name] + permit_ipv6.tx_rx.device.rx_names = [bgp501v6_rr_with_policies.name] + + deny_ipv6.tx_rx.device.tx_names = [config.devices[1].ethernet.ipv6.name] + deny_ipv6.tx_rx.device.rx_names = [bgp501v6_rr2.name] + + permit_ipv6.rate.percentage = LINE_RATE + permit_ipv6.duration.fixed_packets.packets = PACKETS + + deny_ipv6.rate.percentage = LINE_RATE + deny_ipv6.duration.fixed_packets.packets = PACKETS + + return config + + +def __bgp_policies_route_map_config(duthost): + """ + BGP Policy Route MAP Config on duthost Args: - duthost (pytest fixture): duthost fixture - tgen_ports (pytest fixture): Ports mapping info of T0 testbed + duthost : duthost fixture """ - intf1_config = ( + # Remove route_map if exists already + duthost.shell( + "vtysh " + "-c 'configure terminal' " + "-c 'no route-map LA' " + "-c 'no route-map LAv6' " + ) + + as_path_access_list = ( "vtysh " "-c 'configure terminal' " - "-c 'interface %s' " - "-c 'ip address %s/%s' " + "-c 'no bgp as-path access-list PERMIT_100' " ) - intf1_config %= (tgen_ports[0]['peer_port'], - tgen_ports[0]['peer_ip'], - tgen_ports[0]['prefix']) - duthost.shell(intf1_config) + try: + duthost.shell(as_path_access_list) + except Exception: + pass - bgp_config_501 = ( + community = ( "vtysh " "-c 'configure terminal' " - "-c 'router bgp %s' " - "-c 'neighbor LC501 peer-group' " - "-c 'neighbor LC501 remote-as %s' " - "-c 'neighbor %s peer-group LC501' " - "-c 'address-family ipv4 unicast' " - "-c 'neighbor %s activate' " + "-c 'no bgp community-list 10' " ) - bgp_config_501 %= (DUT_AS_NUM, - TGEN_AS_NUM, - tgen_ports[0]['ip'], - tgen_ports[0]['ip']) - duthost.shell(bgp_config_501) + try: + duthost.shell(community) + except Exception: + pass - intf2_config = ( + # Configure route_map + policy_route_map_config = ( "vtysh " "-c 'configure terminal' " - "-c 'interface %s' " - "-c 'ip address %s/%s' " + "-c 'bgp community-list 10 permit 1:2' " + "-c 'bgp as-path access-list PERMIT_100 permit 100' " + "-c 'route-map LA permit 30' " + "-c 'match community 10' " + "-c 'match as-path PERMIT_100' " + "-c 'match metric 50' " + "-c 'match origin egp' " + "-c 'route-map LAv6 permit 30' " + "-c 'match community 10' " + "-c 'match as-path PERMIT_100' " + "-c 'match metric 50' " + "-c 'match origin egp' " ) - intf2_config %= (tgen_ports[1]['peer_port'], - tgen_ports[1]['peer_ip'], - tgen_ports[1]['prefix']) - duthost.shell(intf2_config) + duthost.shell(policy_route_map_config) - # ipv6 config - intf1_v6_config = ( - "vtysh " - "-c 'configure terminal' " - "-c 'interface %s' " - "-c 'ipv6 address %s/%s' " + +def __tgen_bgp_community_config(config): + """ + BGP Community Config on TGEN + Args: + config : tgen config + """ + + bgp501 = config.devices[0].ethernet.ipv4.bgpv4 + + # Routes Config + bgp501_rr_with_community, bgp501_rr2 = ( + bgp501.bgpv4_routes + .bgpv4route(name="bgp501_rr_with_community") + .bgpv4route(name="bgp501_rr2") ) - intf1_v6_config %= (tgen_ports[0]['peer_port'], - tgen_ports[0]['peer_ipv6'], - tgen_ports[0]['ipv6_prefix']) - duthost.shell(intf1_v6_config) - bgpv6_config_501 = ( + # Advertise one route("200.1.0.0") from AS 501 with community 1:2 + bgp501_rr_with_community.addresses.bgpv4routeaddress(address="200.1.0.0", + prefix=16) + + manual_as_community = ( + bgp501_rr_with_community.communities.bgpcommunity()[-1]) + manual_as_community.community_type = manual_as_community.MANUAL_AS_NUMBER + manual_as_community.as_number = int(COMMUNITY.split(":")[0]) + manual_as_community.as_custom = int(COMMUNITY.split(":")[1]) + + # Advertise another route("20.1.0.0") from AS 501 without community + bgp501_rr2.addresses.bgpv4routeaddress(address="20.1.0.0", + prefix=16) + + # ipv6 + bgp501v6 = config.devices[0].ethernet.ipv6.bgpv6 + + # Routes Config + bgp501v6_rr_with_community, bgp501v6_rr2 = ( + bgp501v6.bgpv6_routes + .bgpv6route(name="bgp501v6_rr_with_community") + .bgpv6route(name="bgp501v6_rr2") + ) + + # Advertise one route("4000::1") from AS 501 with community 1:2 + bgp501v6_rr_with_community.addresses.bgpv6routeaddress(address="4000::1", + prefix=64) + + manual_as_community = ( + bgp501v6_rr_with_community.communities.bgpcommunity()[-1]) + manual_as_community.community_type = manual_as_community.MANUAL_AS_NUMBER + manual_as_community.as_number = int(COMMUNITY.split(":")[0]) + manual_as_community.as_custom = int(COMMUNITY.split(":")[1]) + + # Advertise another route("6000::1") from AS 501 without community + bgp501v6_rr2.addresses.bgpv6routeaddress(address="6000::1", + prefix=64) + + # Create four flows + permit, deny, permit_ipv6, deny_ipv6 = ( + config.flows + .flow(name='permit') + .flow(name='deny') + .flow(name='permit_ipv6') + .flow(name='deny_ipv6') + ) + + permit.tx_rx.device.tx_names = [config.devices[1].ethernet.ipv4.name] + permit.tx_rx.device.rx_names = [bgp501_rr_with_community.name] + + deny.tx_rx.device.tx_names = [config.devices[1].ethernet.ipv4.name] + deny.tx_rx.device.rx_names = [bgp501_rr2.name] + + permit.rate.percentage = LINE_RATE + permit.duration.fixed_packets.packets = PACKETS + + deny.rate.percentage = LINE_RATE + deny.duration.fixed_packets.packets = PACKETS + + permit_ipv6.tx_rx.device.tx_names = [config.devices[1].ethernet.ipv6.name] + permit_ipv6.tx_rx.device.rx_names = [bgp501v6_rr_with_community.name] + + deny_ipv6.tx_rx.device.tx_names = [config.devices[1].ethernet.ipv6.name] + deny_ipv6.tx_rx.device.rx_names = [bgp501v6_rr2.name] + + permit_ipv6.rate.percentage = LINE_RATE + permit_ipv6.duration.fixed_packets.packets = PACKETS + + deny_ipv6.rate.percentage = LINE_RATE + deny_ipv6.duration.fixed_packets.packets = PACKETS + + return config + + +def __bgp_community_route_map_config(duthost): + """ + BGP Community Route MAP Config on duthost + Args: + duthost : duthost fixture + """ + # Remove route_map if exists already + remove_route_map = ( "vtysh " "-c 'configure terminal' " "-c 'router bgp %s' " - "-c 'neighbor LC501v6 peer-group' " - "-c 'neighbor LC501v6 remote-as %s' " - "-c 'neighbor %s peer-group LC501v6' " + "-c 'address-family ipv4 unicast' " + "-c 'no neighbor LC501 route-map LA in' " "-c 'address-family ipv6 unicast' " - "-c 'neighbor %s activate' " + "-c 'no neighbor LC501v6 route-map LAv6 in' " + "-c 'neighbor LC501v6 route-map NEXTHOP in' " + "-c 'no route-map LA' " + "-c 'no route-map LAv6' " ) - bgpv6_config_501 %= (DUT_AS_NUM, - TGEN_AS_NUM, - tgen_ports[0]['ipv6'], - tgen_ports[0]['ipv6']) - duthost.shell(bgpv6_config_501) + remove_route_map %= (DUT_AS_NUM) + duthost.shell(remove_route_map) - intf2_v6_config = ( + community = ( "vtysh " "-c 'configure terminal' " - "-c 'interface %s' " - "-c 'ipv6 address %s/%s' " + "-c 'no bgp community-list 10' " ) - intf2_v6_config %= (tgen_ports[1]['peer_port'], - tgen_ports[1]['peer_ipv6'], - tgen_ports[1]['ipv6_prefix']) - duthost.shell(intf2_v6_config) + try: + duthost.shell(community) + except Exception: + pass + + # Configure route_map + community_config = ( + "vtysh " + "-c 'configure terminal' " + "-c 'bgp community-list 10 permit 1:2' " + "-c 'route-map LA permit 30' " + "-c 'match community 10' " + "-c 'route-map LAv6 permit 30' " + "-c 'match community 10' " + ) + duthost.shell(community_config) -def __tgen_bgp_config(snappi_api, - tgen_ports): +def __tgen_bgp_prefix_list_config(config): """ - BGP & Config on TGEN + BGP Prefix Config on TGEN Args: - snappi_api (pytest fixture): Snappi API - tgen_ports (pytest fixture): Ports mapping info of T0 testbed + config : tgen config """ - config = snappi_api.config() - tgen1, tgen2 = ( - config.ports - .port(name='tgen1', location=tgen_ports[0]['location']) - .port(name='tgen2', location=tgen_ports[1]['location']) + bgp501 = config.devices[0].ethernet.ipv4.bgpv4 + + # Routes Config + bgp501_rr1, bgp501_rr2 = ( + bgp501.bgpv4_routes + .bgpv4route(name="bgp501_rr1") + .bgpv4route(name="bgp501_rr2") + ) + + # Advertise one route("200.1.0.0") + bgp501_rr1.addresses.bgpv4routeaddress(address="200.1.0.0", + prefix=16) + + # Advertise another route("20.1.0.0") + bgp501_rr2.addresses.bgpv4routeaddress(address="20.1.0.0", + prefix=16) + + # ipv6 + bgp501v6 = config.devices[0].ethernet.ipv6.bgpv6 + + # Routes Config + bgp501v6_rr1, bgp501v6_rr2 = ( + bgp501v6.bgpv6_routes + .bgpv6route(name="bgp501v6_rr1") + .bgpv6route(name="bgp501v6_rr2") + ) + + # Advertise one route("4000::1") + bgp501v6_rr1.addresses.bgpv6routeaddress(address="4000::1", + prefix=64) + + # Advertise another route("6000::1") + bgp501v6_rr2.addresses.bgpv6routeaddress(address="6000::1", + prefix=64) + + # Create four flows + permit, deny, permit_ipv6, deny_ipv6 = ( + config.flows + .flow(name='permit') + .flow(name='deny') + .flow(name='permit_ipv6') + .flow(name='deny_ipv6') ) - # L1 Config - config.options.port_options.location_preemption = True - ly = config.layer1.layer1()[-1] - ly.name = 'ly' - ly.port_names = [tgen1.name, tgen2.name] - ly.speed = tgen_ports[0]['speed'] - ly.auto_negotiate = False + permit.tx_rx.device.tx_names = [config.devices[1].ethernet.ipv4.name] + permit.tx_rx.device.rx_names = [bgp501_rr1.name] - # Device Config - d1, d2 = config.devices.device(name='d1').device(name='d2') - d1.container_name = tgen1.name - d2.container_name = tgen2.name + deny.tx_rx.device.tx_names = [config.devices[1].ethernet.ipv4.name] + deny.tx_rx.device.rx_names = [bgp501_rr2.name] - eth1, eth2 = d1.ethernet, d2.ethernet - eth1.name, eth2.name = "eth1", "eth2" + permit.rate.percentage = LINE_RATE + permit.duration.fixed_packets.packets = PACKETS - ip1, ip2 = eth1.ipv4, eth2.ipv4 - ip1.name, ip2.name = "ip1", "ip2" + deny.rate.percentage = LINE_RATE + deny.duration.fixed_packets.packets = PACKETS - ip1.address = tgen_ports[0]['ip'] - ip1.gateway = tgen_ports[0]['peer_ip'] - ip1.prefix = tgen_ports[0]['prefix'] + permit_ipv6.tx_rx.device.tx_names = [config.devices[1].ethernet.ipv6.name] + permit_ipv6.tx_rx.device.rx_names = [bgp501v6_rr1.name] - ip2.address = tgen_ports[1]['ip'] - ip2.gateway = tgen_ports[1]['peer_ip'] - ip2.prefix = tgen_ports[1]['prefix'] + deny_ipv6.tx_rx.device.tx_names = [config.devices[1].ethernet.ipv6.name] + deny_ipv6.tx_rx.device.rx_names = [bgp501v6_rr2.name] - bgp501 = ip1.bgpv4 - bgp501.name = "bgp501" - bgp501.dut_address = tgen_ports[0]['peer_ip'] - bgp501.as_number = TGEN_AS_NUM - bgp501.as_type = BGP_TYPE + permit_ipv6.rate.percentage = LINE_RATE + permit_ipv6.duration.fixed_packets.packets = PACKETS - # v6 config - ip1v6, ip2v6 = eth1.ipv6, eth2.ipv6 - ip1v6.name, ip2v6.name = "ip1v6", "ip2v6" + deny_ipv6.rate.percentage = LINE_RATE + deny_ipv6.duration.fixed_packets.packets = PACKETS - ip1v6.address = tgen_ports[0]['ipv6'] - ip1v6.gateway = tgen_ports[0]['peer_ipv6'] - ip1v6.prefix = tgen_ports[0]['ipv6_prefix'] + return config - ip2v6.address = tgen_ports[1]['ipv6'] - ip2v6.gateway = tgen_ports[1]['peer_ipv6'] - ip2v6.prefix = tgen_ports[1]['ipv6_prefix'] - bgp501v6 = ip1v6.bgpv6 - bgp501v6.name = "bgp501v6" - bgp501v6.dut_address = tgen_ports[0]['peer_ipv6'] - bgp501v6.as_number = TGEN_AS_NUM - bgp501v6.as_type = BGP_TYPE +def __bgp_prefix_list_route_map_config(duthost): + """ + BGP Prefix List Route MAP Config on duthost + Args: + duthost : duthost fixture + """ - return config + # Remove route_map if exists already + remove_route_map = ( + "vtysh " + "-c 'configure terminal' " + "-c 'router bgp %s' " + "-c 'address-family ipv4 unicast' " + "-c 'no neighbor LC501 route-map LA in' " + "-c 'address-family ipv6 unicast' " + "-c 'no neighbor LC501v6 route-map LAv6 in' " + "-c 'neighbor LC501v6 route-map NEXTHOP in' " + "-c 'no route-map LA' " + "-c 'no route-map LAv6' " + ) + remove_route_map %= (DUT_AS_NUM) + duthost.shell(remove_route_map) + + # Configure route_map + prefix_list_config = ( + "vtysh " + "-c 'configure terminal' " + "-c 'no ip prefix-list PERMIT_IP' " + "-c 'no ipv6 prefix-list PERMIT_IPV6' " + "-c 'ip prefix-list PERMIT_IP permit 200.1.0.0/16' " + "-c 'ipv6 prefix-list PERMIT_IPV6 permit 4000::1/64' " + "-c 'route-map LA permit 30' " + "-c 'match ip address prefix-list PERMIT_IP' " + "-c 'route-map LAv6 permit 30' " + "-c 'match ipv6 address prefix-list PERMIT_IPV6' " + ) + duthost.shell(prefix_list_config) -def __bgp_community_config(duthost, - config): +def __tgen_bgp_metric_config(config): """ - BGP Community Config on duthost and TGEN + BGP Metric config on TGEN Args: - snappi_api (pytest fixture): Snappi API config : tgen config """ bgp501 = config.devices[0].ethernet.ipv4.bgpv4 - # Route Range Config - bgp501_rr_with_community, bgp501_rr2 = ( + # Routes Config + bgp501_rr_metric_100, bgp501_rr2 = ( bgp501.bgpv4_routes - .bgpv4route(name="bgp501_rr_with_community") + .bgpv4route(name="bgp501_rr_metric_100") .bgpv4route(name="bgp501_rr2") ) - # Advertise one route range("200.1.0.0") from AS 501 with community 1:2 - bgp501_rr_with_community.addresses.bgpv4routeaddress(address="200.1.0.0", - prefix="16") + # Advertise one route("200.1.0.0") from AS 501 with metric/MED 100 + bgp501_rr_metric_100.addresses.bgpv4routeaddress(address="200.1.0.0", + prefix=16) - manual_as_community = ( - bgp501_rr_with_community.communities.bgpcommunity()[-1]) - manual_as_community.community_type = manual_as_community.MANUAL_AS_NUMBER - manual_as_community.as_number = 1 - manual_as_community.as_custom = 2 + bgp501_rr_metric_100.advanced.multi_exit_discriminator = MED - # Advertise another route range("20.1.0.0") from AS 501 without community + # Advertise another route("20.1.0.0") bgp501_rr2.addresses.bgpv4routeaddress(address="20.1.0.0", - prefix="16") + prefix=16) # ipv6 bgp501v6 = config.devices[0].ethernet.ipv6.bgpv6 - # Route Range Config - bgp501v6_rr_with_community, bgp501v6_rr2 = ( + # Routes Config + bgp501v6_rr_metric_100, bgp501v6_rr2 = ( bgp501v6.bgpv6_routes - .bgpv6route(name="bgp501v6_rr_with_community") + .bgpv6route(name="bgp501v6_rr_metric_100") .bgpv6route(name="bgp501v6_rr2") ) - # Advertise one route range("4000::1") from AS 501 with community 1:2 - bgp501v6_rr_with_community.addresses.bgpv6routeaddress(address="4000::1", - prefix="64") + # Advertise one route("4000::1") from AS 501 with additional AS 100 + bgp501v6_rr_metric_100.addresses.bgpv6routeaddress(address="4000::1", + prefix=64) - manual_as_community = ( - bgp501v6_rr_with_community.communities.bgpcommunity()[-1]) - manual_as_community.community_type = manual_as_community.MANUAL_AS_NUMBER - manual_as_community.as_number = 1 - manual_as_community.as_custom = 2 + bgp501v6_rr_metric_100.advanced.multi_exit_discriminator = MED - # Advertise another route range("6000::1") from AS 501 without community + # Advertise another route("6000::1") bgp501v6_rr2.addresses.bgpv6routeaddress(address="6000::1", - prefix="64") + prefix=64) - # Create two flows Permit(Traffic with Community list) & Deny + # Create four flows permit, deny, permit_ipv6, deny_ipv6 = ( config.flows .flow(name='permit') @@ -301,97 +841,119 @@ def __bgp_community_config(duthost, ) permit.tx_rx.device.tx_names = [config.devices[1].ethernet.ipv4.name] - permit.tx_rx.device.rx_names = [bgp501_rr_with_community.name] + permit.tx_rx.device.rx_names = [bgp501_rr_metric_100.name] deny.tx_rx.device.tx_names = [config.devices[1].ethernet.ipv4.name] deny.tx_rx.device.rx_names = [bgp501_rr2.name] - permit.rate.percentage = 1 + permit.rate.percentage = LINE_RATE permit.duration.fixed_packets.packets = PACKETS - deny.rate.percentage = 1 + deny.rate.percentage = LINE_RATE deny.duration.fixed_packets.packets = PACKETS permit_ipv6.tx_rx.device.tx_names = [config.devices[1].ethernet.ipv6.name] - permit_ipv6.tx_rx.device.rx_names = [bgp501v6_rr_with_community.name] + permit_ipv6.tx_rx.device.rx_names = [bgp501v6_rr_metric_100.name] deny_ipv6.tx_rx.device.tx_names = [config.devices[1].ethernet.ipv6.name] deny_ipv6.tx_rx.device.rx_names = [bgp501v6_rr2.name] - permit_ipv6.rate.percentage = 1 + permit_ipv6.rate.percentage = LINE_RATE permit_ipv6.duration.fixed_packets.packets = PACKETS - deny_ipv6.rate.percentage = 1 + deny_ipv6.rate.percentage = LINE_RATE deny_ipv6.duration.fixed_packets.packets = PACKETS - community_config = ( + return config + + +def __bgp_metric_route_map_config(duthost): + """ + BGP Metric Route MAP Config on duthost + Args: + duthost : duthost fixture + """ + # Remove route_map if exists already + remove_route_map = ( "vtysh " "-c 'configure terminal' " - "-c 'bgp community-list 10 permit 1:2' " - "-c 'route-map LA permit 30' " - "-c 'match community 10'" + "-c 'router bgp %s' " + "-c 'address-family ipv4 unicast' " + "-c 'no neighbor LC501 route-map LA in' " + "-c 'address-family ipv6 unicast' " + "-c 'no neighbor LC501v6 route-map LAv6 in' " + "-c 'neighbor LC501v6 route-map NEXTHOP in' " + "-c 'no route-map LA' " + "-c 'no route-map LAv6' " ) - duthost.shell(community_config) + remove_route_map %= (DUT_AS_NUM) + duthost.shell(remove_route_map) - return config + # Configure route_map + metric_config = ( + "vtysh " + "-c 'configure terminal' " + "-c 'route-map LA permit 30' " + "-c 'match metric 50' " + "-c 'route-map LAv6 permit 30' " + "-c 'match metric 50' " + ) + duthost.shell(metric_config) -def __bgp_as_path_modified_config(duthost, - config): +def __tgen_bgp_as_path_modified_config(config): """ BGP group AS config on duthost and TGEN Args: - snappi_api (pytest fixture): Snappi API config : tgen config """ bgp501 = config.devices[0].ethernet.ipv4.bgpv4 - bgp501 = config.devices[0].ethernet.ipv4.bgpv4 - - # Route Range Config + # Routes Config bgp501_rr_with_as_100, bgp501_rr2 = ( bgp501.bgpv4_routes .bgpv4route(name="bgp501_rr_with_as_100") .bgpv4route(name="bgp501_rr2") ) - # Advertise one route range("200.1.0.0") from AS 501 with additional AS 100 + # Advertise one route("200.1.0.0") from AS 501 with additional AS 100 bgp501_rr_with_as_100.addresses.bgpv4routeaddress(address="200.1.0.0", - prefix="16") + prefix=16) as_path = bgp501_rr_with_as_100.as_path as_path_segment = as_path.as_path_segments.bgpaspathsegment()[-1] as_path_segment.segment_type = as_path_segment.AS_SEQ - as_path_segment.as_numbers = [100] + as_path_segment.as_numbers = GROUP_AS - # Advertise another route range("20.1.0.0") + # Advertise another route("20.1.0.0") bgp501_rr2.addresses.bgpv4routeaddress(address="20.1.0.0", - prefix="16") + prefix=16) # ipv6 bgp501v6 = config.devices[0].ethernet.ipv6.bgpv6 - # Route Range Config + # Routes Config bgp501v6_rr_with_as_100, bgp501v6_rr2 = ( bgp501v6.bgpv6_routes .bgpv6route(name="bgp501v6_rr_with_as_100") .bgpv6route(name="bgp501v6_rr2") ) - # Advertise one route range("4000::1") from AS 501 with additional AS 100 + # Advertise one route("4000::1") from AS 501 with additional AS 100 bgp501v6_rr_with_as_100.addresses.bgpv6routeaddress(address="4000::1", - prefix="64") + prefix=64) as_path = bgp501v6_rr_with_as_100.as_path as_path_segment = as_path.as_path_segments.bgpaspathsegment()[-1] as_path_segment.segment_type = as_path_segment.AS_SEQ - as_path_segment.as_numbers = [100] + as_path_segment.as_numbers = GROUP_AS - # Advertise another route range("6000::1") + # Advertise another route("6000::1") bgp501v6_rr2.addresses.bgpv6routeaddress(address="6000::1", - prefix="64") + prefix=64) + # Create four flows permit, deny, permit_ipv6, deny_ipv6 = ( config.flows .flow(name='permit') @@ -406,10 +968,10 @@ def __bgp_as_path_modified_config(duthost, deny.tx_rx.device.tx_names = [config.devices[1].ethernet.ipv4.name] deny.tx_rx.device.rx_names = [bgp501_rr2.name] - permit.rate.percentage = 1 + permit.rate.percentage = LINE_RATE permit.duration.fixed_packets.packets = PACKETS - deny.rate.percentage = 1 + deny.rate.percentage = LINE_RATE deny.duration.fixed_packets.packets = PACKETS permit_ipv6.tx_rx.device.tx_names = [config.devices[1].ethernet.ipv6.name] @@ -418,24 +980,178 @@ def __bgp_as_path_modified_config(duthost, deny_ipv6.tx_rx.device.tx_names = [config.devices[1].ethernet.ipv6.name] deny_ipv6.tx_rx.device.rx_names = [bgp501v6_rr2.name] - permit_ipv6.rate.percentage = 1 + permit_ipv6.rate.percentage = LINE_RATE permit_ipv6.duration.fixed_packets.packets = PACKETS - deny_ipv6.rate.percentage = 1 + deny_ipv6.rate.percentage = LINE_RATE deny_ipv6.duration.fixed_packets.packets = PACKETS - community_config = ( + return config + + +def __bgp_as_path_route_map_config(duthost): + """ + BGP AS PATH Route MAP Config on duthost + Args: + duthost : duthost fixture + """ + # Remove route_map if exists already + remove_route_map = ( + "vtysh " + "-c 'configure terminal' " + "-c 'router bgp %s' " + "-c 'address-family ipv4 unicast' " + "-c 'no neighbor LC501 route-map LA in' " + "-c 'address-family ipv6 unicast' " + "-c 'no neighbor LC501v6 route-map LAv6 in' " + "-c 'neighbor LC501v6 route-map NEXTHOP in' " + "-c 'no route-map LA' " + "-c 'no route-map LAv6' " + ) + remove_route_map %= (DUT_AS_NUM) + duthost.shell(remove_route_map) + + remove_as_path = ( + "vtysh " + "-c 'configure terminal' " + "-c 'no bgp as-path access-list PERMIT_100' " + ) + try: + duthost.shell(remove_as_path) + except Exception: + pass + + # Configure route_map + as_path_route_map = ( "vtysh " "-c 'configure terminal' " - "-c 'bgp as-path access-list permit_100 permit 100' " + "-c 'bgp as-path access-list PERMIT_100 permit 100' " "-c 'route-map LA permit 30' " - "-c 'match as-path permit_100'" + "-c 'match as-path PERMIT_100' " + "-c 'route-map LAv6 permit 30' " + "-c 'match as-path PERMIT_100' " ) - duthost.shell(community_config) + duthost.shell(as_path_route_map) + + +def __tgen_bgp_origin_config(config): + """ + BGP Origin config on TGEN + Args: + config : tgen config + """ + + bgp501 = config.devices[0].ethernet.ipv4.bgpv4 + + # Routes Config + bgp501_rr_origin_egp, bgp501_rr2 = ( + bgp501.bgpv4_routes + .bgpv4route(name="bgp501_rr_origin_egp") + .bgpv4route(name="bgp501_rr2") + ) + + # Advertise one route("200.1.0.0") from AS 501 with ORIGIN EGP + bgp501_rr_origin_egp.addresses.bgpv4routeaddress(address="200.1.0.0", + prefix=16) + + bgp501_rr_origin_egp.advanced.origin = bgp501_rr_origin_egp.advanced.EGP + + # Advertise another route("20.1.0.0") + bgp501_rr2.addresses.bgpv4routeaddress(address="20.1.0.0", + prefix=16) + + # ipv6 + bgp501v6 = config.devices[0].ethernet.ipv6.bgpv6 + + # Routes Config + bgp501v6_rr_origin_egp, bgp501v6_rr2 = ( + bgp501v6.bgpv6_routes + .bgpv6route(name="bgp501v6_rr_origin_egp") + .bgpv6route(name="bgp501v6_rr2") + ) + + # Advertise one route("4000::1") from AS 501 with ORIGIN EGP + bgp501v6_rr_origin_egp.addresses.bgpv6routeaddress(address="4000::1", + prefix=64) + + bgp501v6_rr_origin_egp.advanced.origin = ( + bgp501v6_rr_origin_egp.advanced.EGP) + + # Advertise another route("6000::1") + bgp501v6_rr2.addresses.bgpv6routeaddress(address="6000::1", + prefix=64) + + # Create four flows + permit, deny, permit_ipv6, deny_ipv6 = ( + config.flows + .flow(name='permit') + .flow(name='deny') + .flow(name='permit_ipv6') + .flow(name='deny_ipv6') + ) + + permit.tx_rx.device.tx_names = [config.devices[1].ethernet.ipv4.name] + permit.tx_rx.device.rx_names = [bgp501_rr_origin_egp.name] + + deny.tx_rx.device.tx_names = [config.devices[1].ethernet.ipv4.name] + deny.tx_rx.device.rx_names = [bgp501_rr2.name] + + permit.rate.percentage = LINE_RATE + permit.duration.fixed_packets.packets = PACKETS + + deny.rate.percentage = LINE_RATE + deny.duration.fixed_packets.packets = PACKETS + + permit_ipv6.tx_rx.device.tx_names = [config.devices[1].ethernet.ipv6.name] + permit_ipv6.tx_rx.device.rx_names = [bgp501v6_rr_origin_egp.name] + + deny_ipv6.tx_rx.device.tx_names = [config.devices[1].ethernet.ipv6.name] + deny_ipv6.tx_rx.device.rx_names = [bgp501v6_rr2.name] + + permit_ipv6.rate.percentage = LINE_RATE + permit_ipv6.duration.fixed_packets.packets = PACKETS + + deny_ipv6.rate.percentage = LINE_RATE + deny_ipv6.duration.fixed_packets.packets = PACKETS return config +def __bgp_origin_route_map_config(duthost): + """ + BGP Origin Route MAP Config on duthost + Args: + duthost : duthost fixture + """ + + # Remove route_map if exists already + remove_route_map = ( + "vtysh " + "-c 'configure terminal' " + "-c 'router bgp %s' " + "-c 'address-family ipv4 unicast' " + "-c 'no neighbor LC501 route-map LA in' " + "-c 'address-family ipv6 unicast' " + "-c 'no neighbor LC501v6 route-map LAv6 in' " + "-c 'neighbor LC501v6 route-map NEXTHOP in' " + "-c 'no route-map LA' " + "-c 'no route-map LAv6' " + ) + remove_route_map %= (DUT_AS_NUM) + duthost.shell(remove_route_map) + + # Configure route_map + origin_route_map = ( + "vtysh " + "-c 'configure terminal' " + "-c 'route-map LA permit 30' " + "-c 'match origin egp' " + "-c 'route-map LAv6 permit 30' " + "-c 'match origin egp' " + ) + duthost.shell(origin_route_map) + + def __verify_test(duthost, snappi_api, config): @@ -447,60 +1163,68 @@ def __verify_test(duthost, snappi_api (pytest fixture): Snappi API config: tgen_config """ - + logger.info("|--Apply TGEN Config--|") snappi_api.set_config(config) - # unconfigure applied route-map if exists already - route_map = ( - "vtysh " - "-c 'configure terminal' " - "-c 'router bgp %s' " - "-c 'address-family ipv4 unicast' " - "-c 'no neighbor LC501 route-map LA in' " - ) - route_map %= (DUT_AS_NUM) - duthost.shell(route_map) - # Start traffic + logger.info("|--Start Traffic--|") ts = snappi_api.transmit_state() ts.state = ts.START snappi_api.set_transmit_state(ts) - # Check there is no traffic loss for 'permit' & 'deny' + # Check there is no loss for 'permit', 'permit_ipv6', 'deny' & deny_ipv6 + logger.info( + "|--Asserting No Loss For All Flows Before Applying Route-Map--|") pytest_assert(wait_until(60, 2, lambda: __check_for_no_loss(snappi_api, - ['permit', 'deny'], - PACKETS * 2)), + ['permit', 'permit_ipv6', + 'deny', 'deny_ipv6'], + PACKETS * 4)), 'No loss expected') - # Apply route-map to permit only routes with community + logger.info("|--Apply Route-Map--|") + # Apply route-map to permit only expected routes route_map = ( "vtysh " "-c 'configure terminal' " "-c 'router bgp %s' " "-c 'address-family ipv4 unicast' " "-c 'neighbor LC501 route-map LA in' " + "-c 'address-family ipv6 unicast' " + "-c 'neighbor LC501v6 route-map LAv6 in' " ) route_map %= (DUT_AS_NUM) duthost.shell(route_map) # Start traffic + logger.info("|--Start Traffic--|") ts = snappi_api.transmit_state() ts.state = ts.START snappi_api.set_transmit_state(ts) - # Check there is no traffic loss for 'permit' flow + # Check there is no traffic loss for 'permit' and 'permit_ipv6' flow + logger.info( + "|--Assert No Loss For Flows With Permit--|") pytest_assert(wait_until(60, 2, lambda: __check_for_no_loss(snappi_api, - ['permit'], - PACKETS)), + ['permit', 'permit_ipv6'], + PACKETS * 2)), 'No loss expected') - # Check 100% traffic loss for 'deny' flow + # Check 100% traffic loss for 'deny' and 'deny_ipv6' flow + logger.info( + "|--Assert 100 Percent Loss For Flows Without Permit--|") pytest_assert(wait_until(60, 2, - lambda: __check_for_total_loss(snappi_api, ['deny'])), + lambda: __check_for_total_loss( + snappi_api, ['deny', 'deny_ipv6'])), 'total loss expected') + # Stop traffic + logger.info("|--Stopping Traffic After Test--|") + ts = snappi_api.transmit_state() + ts.state = ts.STOP + snappi_api.set_transmit_state(ts) + def __check_for_no_loss(snappi_api, flow_names, @@ -536,55 +1260,68 @@ def __check_for_total_loss(snappi_api, return flow_rx == 0 -def __cleanup_community_config(duthost): - """ - BGP Config on duthost +def config_cleanup(duthost, + tgen_ports): - Args: - duthost (pytest fixture): duthost fixture - tgen_ports (pytest fixture): Ports mapping info of T0 testbed - """ - # Remove community config - community_config = ( + # Remove bgp neighbor config + bgp_config = ( "vtysh " "-c 'configure terminal' " - "-c 'no bgp community-list 10 permit 1:2' " - "-c 'no route-map LA permit 30' " + "-c 'no router bgp' " ) - duthost.shell(community_config) - + duthost.shell(bgp_config) -def __cleanup_as_path_config(duthost): - """ - BGP Config on duthost + # Remove any leftover config if not removed + route_map = ( + "vtysh " + "-c 'configure terminal' " + "-c 'no bgp community-list 10' " + ) + try: + duthost.shell(route_map) + except Exception: + pass - Args: - duthost (pytest fixture): duthost fixture - tgen_ports (pytest fixture): Ports mapping info of T0 testbed - """ - # Remove community config - community_config = ( + route_map = ( "vtysh " "-c 'configure terminal' " - "-c 'no bgp as-path access-list permit_100 permit 100' " - "-c 'no route-map LA permit 30' " + "-c 'no bgp as-path access-list PERMIT_100' " ) - duthost.shell(community_config) + try: + duthost.shell(route_map) + except Exception: + pass + route_map = ( + "vtysh " + "-c 'configure terminal' " + "-c 'no ip prefix-list PERMIT_IP' " + ) + try: + duthost.shell(route_map) + except Exception: + pass -def __common_cleanup(duthost, - tgen_ports): + route_map = ( + "vtysh " + "-c 'configure terminal' " + "-c 'no ipv6 prefix-list PERMIT_IPV6' " + ) + try: + duthost.shell(route_map) + except Exception: + pass - # Remove bgp neighbor config - bgp_config_501 = ( + route_map = ( "vtysh " "-c 'configure terminal' " - "-c 'router bgp %s' " - "-c 'no neighbor LC501 peer-group' " - "-c 'no neighbor LC501v6 peer-group' " + "-c 'no route-map LA permit 30' " + "-c 'no route-map LAv6 permit 30' " ) - bgp_config_501 %= (DUT_AS_NUM) - duthost.shell(bgp_config_501) + try: + duthost.shell(route_map) + except Exception: + pass # Remove interface ip config intf1_config = ( @@ -611,7 +1348,7 @@ def __common_cleanup(duthost, intf2_config %= (tgen_ports[1]['peer_port'], tgen_ports[1]['peer_ip'], tgen_ports[1]['prefix'], - tgen_ports[0]['peer_ipv6'], - tgen_ports[0]['ipv6_prefix']) + tgen_ports[1]['peer_ipv6'], + tgen_ports[1]['ipv6_prefix']) duthost.shell(intf2_config) diff --git a/tests/ixia/bgp/test_bgp_routing_policies.py b/tests/ixia/bgp/test_bgp_routing_policies.py index d547e8e18ac..4c2aabdca9a 100755 --- a/tests/ixia/bgp/test_bgp_routing_policies.py +++ b/tests/ixia/bgp/test_bgp_routing_policies.py @@ -1,39 +1,117 @@ +import pytest +import logging from tests.common.ixia.ixia_fixtures import snappi_api from tests.common.ixia.ixia_fixtures import ( ixia_api_serv_ip, ixia_api_serv_port, tgen_ports) from files.helper import ( - run_bgp_community_test, run_bgp_group_as_path_modified) + run_bgp_peer_routing_policies_test, run_bgp_community_test, + run_bgp_prefix_list_test, run_bgp_metric_filter, + run_bgp_group_as_path_modified, run_bgp_origin_code_modification, + config_setup, config_cleanup) from tests.common.fixtures.conn_graph_facts import ( conn_graph_facts, fanout_graph_facts) -import pytest +logger = logging.getLogger(__name__) + + +@pytest.fixture(scope="module") +def setup_and_teardown(duthost, + tgen_ports): + """ + Setup and Teardown + """ + # We are going to use first two ports for all these tests + tgen_ports = tgen_ports[0:2] + logger.info("|--Common Setup Configuration--|") + config_setup(duthost, + tgen_ports) + yield + logger.info("|--Common Cleanup--|") + config_cleanup(duthost, + tgen_ports) + + +# Test 1 +@pytest.mark.topology("tgen") +def test_bgp_peer_routing_policies(snappi_api, + duthost, + tgen_ports, + conn_graph_facts, + fanout_graph_facts, + setup_and_teardown): + """ + Topo: + TGEN1 --- DUT --- TGEN2 + + Steps: + 1) Create BGP config on DUT and TGEN respectively + 2) Generate 2 ipv4 routes & 2 ipv6 routes from TGEN1 + -- "200.1.0.0" & "4000::1" with Attributes + a) community-list 1:2 + b) as-path append AS 100 + c) Origin ebgp + d) Metric 50 + -- "20.1.0.0" & "6000::1" + 3) Create route policy in DUT to permit only "200.1.0.0" + & "4000::1" based on BGP Attributes + 4) Create two flows from TGEN2 to TGEN1 + a) 'permit' -- TGEN2 to TGEN1("200.1.0.0") + b) 'permit_ipv6' -- TGEN2 to TGEN1("4000::1") + c) 'deny' -- TGEN2 to TGEN1("20.1.0.0") + d) 'deny_ipv6' -- TGEN2 to TGEN1("6000::1") + + Verification: + 1) Send traffic without applying route-map + Result: Should not observe traffic loss in 'permit' & 'deny' + 'permit_ipv6' & 'deny_ipv6' + 2) Apply route-map + Result: Should observe 100% traffic loss in 'deny' & 'deny_ipv6' + + Args: + snappi_api (pytest fixture): Snappi API + duthost (pytest fixture): duthost fixture + tgen_ports (pytest fixture): Ports mapping info of T0 testbed + conn_graph_facts (pytest fixture): connection graph + fanout_graph_facts (pytest fixture): fanout graph + """ + + tgen_ports = tgen_ports[0:2] + logger.info("|--BGP Peer Policies Test--|") + run_bgp_peer_routing_policies_test(snappi_api, + duthost, + tgen_ports) +# Test 2 @pytest.mark.topology("tgen") def test_bgp_community(snappi_api, duthost, tgen_ports, conn_graph_facts, - fanout_graph_facts): + fanout_graph_facts, + setup_and_teardown): """ Topo: TGEN1 --- DUT --- TGEN2 Steps: 1) Create BGP config on DUT and TGEN respectively - 2) Generate two routes from TGEN1 - route1 -- "200.1.0.0" with community 1:2 - route2 -- "20.1.0.0" - 3) Create community list in DUT to permit only "200.1.0.0" - "ip community-list 10 permit 1:2" + 2) Generate 2 ipv4 routes & 2 ipv6 routes from TGEN1 + -- "200.1.0.0" & "4000::1" with Community Attribute 1:2 + -- "20.1.0.0" & "6000::1" + 3) Create route policy in DUT to permit only "200.1.0.0" + & "4000::1" based on Community Attribute 4) Create two flows from TGEN2 to TGEN1 a) 'permit' -- TGEN2 to TGEN1("200.1.0.0") - b) 'deny' -- TGEN2 to TGEN1("20.1.0.0") + b) 'permit_ipv6' -- TGEN2 to TGEN1("4000::1") + c) 'deny' -- TGEN2 to TGEN1("20.1.0.0") + d) 'deny_ipv6' -- TGEN2 to TGEN1("6000::1") Verification: 1) Send traffic without applying route-map Result: Should not observe traffic loss in 'permit' & 'deny' + 'permit_ipv6' & 'deny_ipv6' 2) Apply route-map - Result: Should observe 100% traffic loss in 'deny' + Result: Should observe 100% traffic loss in 'deny' & 'deny_ipv6' Args: snappi_api (pytest fixture): Snappi API @@ -42,20 +120,117 @@ def test_bgp_community(snappi_api, conn_graph_facts (pytest fixture): connection graph fanout_graph_facts (pytest fixture): fanout graph """ - # We are going to use first two ports for this test - tgen_ports = tgen_ports[0:2] + tgen_ports = tgen_ports[0:2] + logger.info("|--BGP Community List Filtering Test--|") run_bgp_community_test(snappi_api, duthost, tgen_ports) +# Test 3 +@pytest.mark.topology("tgen") +def test_bgp_prefix_list_filter(snappi_api, + duthost, + tgen_ports, + conn_graph_facts, + fanout_graph_facts, + setup_and_teardown): + """ + Topo: + TGEN1 --- DUT --- TGEN2 + + Steps: + 1) Create BGP config on DUT and TGEN respectively + 2) Generate 2 ipv4 routes & 2 ipv6 routes from TGEN1 + -- "200.1.0.0" & "4000::1" + -- "20.1.0.0" & "6000::1" + 3) Create Prefix-list route map in DUT to permit + only "200.1.0.0" & "4000::1" + 4) Create two flows from TGEN2 to TGEN1 + a) 'permit' -- TGEN2 to TGEN1("200.1.0.0") + b) 'permit_ipv6' -- TGEN2 to TGEN1("4000::1") + c) 'deny' -- TGEN2 to TGEN1("20.1.0.0") + d) 'deny_ipv6' -- TGEN2 to TGEN1("6000::1") + + Verification: + 1) Send traffic without applying route-map + Result: Should not observe traffic loss in 'permit' & 'deny' + 'permit_ipv6' & 'deny_ipv6' + 2) Apply route-map + Result: Should observe 100% traffic loss in 'deny' & 'deny_ipv6' + + Args: + snappi_api (pytest fixture): Snappi API + duthost (pytest fixture): duthost fixture + tgen_ports (pytest fixture): Ports mapping info of T0 testbed + conn_graph_facts (pytest fixture): connection graph + fanout_graph_facts (pytest fixture): fanout graph + """ + + tgen_ports = tgen_ports[0:2] + logger.info("|--BGP Prefix List Filtering Test--|") + run_bgp_prefix_list_test(snappi_api, + duthost, + tgen_ports) + + +# Test 4 +@pytest.mark.topology("tgen") +def test_bgp_metric_filter(snappi_api, + duthost, + tgen_ports, + conn_graph_facts, + fanout_graph_facts, + setup_and_teardown): + """ + # TODO: update the description + Topo: + TGEN1 --- DUT --- TGEN2 + + Steps: + 1) Create BGP config on DUT and TGEN respectively + 2) Generate 2 ipv4 routes & 2 ipv6 routes from TGEN1 + -- "200.1.0.0" & "4000::1" with Metric 50 + -- "20.1.0.0" & "6000::1" + 3) Create route policy in DUT to permit only "200.1.0.0" + & "4000::1" based on Metric + 4) Create two flows from TGEN2 to TGEN1 + a) 'permit' -- TGEN2 to TGEN1("200.1.0.0") + b) 'permit_ipv6' -- TGEN2 to TGEN1("4000::1") + c) 'deny' -- TGEN2 to TGEN1("20.1.0.0") + d) 'deny_ipv6' -- TGEN2 to TGEN1("6000::1") + + Verification: + 1) Send traffic without applying route-map + Result: Should not observe traffic loss in 'permit' & 'deny' + 'permit_ipv6' & 'deny_ipv6' + 2) Apply route-map + Result: Should observe 100% traffic loss in 'deny' & 'deny_ipv6' + + Args: + snappi_api (pytest fixture): Snappi API + duthost (pytest fixture): duthost fixture + tgen_ports (pytest fixture): Ports mapping info of T0 testbed + conn_graph_facts (pytest fixture): connection graph + fanout_graph_facts (pytest fixture): fanout graph + """ + + tgen_ports = tgen_ports[0:2] + logger.info("|--BGP Metric Filter Test--|") + run_bgp_metric_filter(snappi_api, + duthost, + tgen_ports) + + +# Test 5 @pytest.mark.topology("tgen") def test_bgp_group_as_path_modified(snappi_api, duthost, tgen_ports, conn_graph_facts, - fanout_graph_facts): + fanout_graph_facts, + setup_and_teardown): """ # TODO: update the description Topo: @@ -63,20 +238,23 @@ def test_bgp_group_as_path_modified(snappi_api, Steps: 1) Create BGP config on DUT and TGEN respectively - 2) Generate two routes from TGEN1 - route1 -- "200.1.0.0" with community 1:2 - route2 -- "20.1.0.0" - 3) Create community list in DUT to permit only "200.1.0.0" - "ip community-list 10 permit 1:2" + 2) Generate 2 ipv4 routes & 2 ipv6 routes from TGEN1 + -- "200.1.0.0" & "4000::1" with group AS + -- "20.1.0.0" & "6000::1" + 3) Create route policy in DUT to permit only "200.1.0.0" + & "4000::1" based on group AS 4) Create two flows from TGEN2 to TGEN1 a) 'permit' -- TGEN2 to TGEN1("200.1.0.0") - b) 'deny' -- TGEN2 to TGEN1("20.1.0.0") + b) 'permit_ipv6' -- TGEN2 to TGEN1("4000::1") + c) 'deny' -- TGEN2 to TGEN1("20.1.0.0") + d) 'deny_ipv6' -- TGEN2 to TGEN1("6000::1") Verification: 1) Send traffic without applying route-map Result: Should not observe traffic loss in 'permit' & 'deny' + 'permit_ipv6' & 'deny_ipv6' 2) Apply route-map - Result: Should observe 100% traffic loss in 'deny' + Result: Should observe 100% traffic loss in 'deny' & 'deny_ipv6' Args: snappi_api (pytest fixture): Snappi API @@ -85,9 +263,57 @@ def test_bgp_group_as_path_modified(snappi_api, conn_graph_facts (pytest fixture): connection graph fanout_graph_facts (pytest fixture): fanout graph """ - # We are going to use first two ports for this test - tgen_ports = tgen_ports[0:2] + tgen_ports = tgen_ports[0:2] + logger.info("|--BGP group-as-path modified Test--|") run_bgp_group_as_path_modified(snappi_api, duthost, tgen_ports) + + +# Test 6 +@pytest.mark.topology("tgen") +def test_bgp_origin_code_modification(snappi_api, + duthost, + tgen_ports, + conn_graph_facts, + fanout_graph_facts, + setup_and_teardown): + """ + # TODO: update the description + Topo: + TGEN1 --- DUT --- TGEN2 + + Steps: + 1) Create BGP config on DUT and TGEN respectively + 2) Generate 2 ipv4 routes & 2 ipv6 routes from TGEN1 + -- "200.1.0.0" & "4000::1" with Origin 'egp' + -- "20.1.0.0" & "6000::1" + 3) Create route policy in DUT to permit only "200.1.0.0" + & "4000::1" based on Origin 'egp' + 4) Create two flows from TGEN2 to TGEN1 + a) 'permit' -- TGEN2 to TGEN1("200.1.0.0") + b) 'permit_ipv6' -- TGEN2 to TGEN1("4000::1") + c) 'deny' -- TGEN2 to TGEN1("20.1.0.0") + d) 'deny_ipv6' -- TGEN2 to TGEN1("6000::1") + + Verification: + 1) Send traffic without applying route-map + Result: Should not observe traffic loss in 'permit' & 'deny' + 'permit_ipv6' & 'deny_ipv6' + 2) Apply route-map + Result: Should observe 100% traffic loss in 'deny' & 'deny_ipv6' + + Args: + snappi_api (pytest fixture): Snappi API + duthost (pytest fixture): duthost fixture + tgen_ports (pytest fixture): Ports mapping info of T0 testbed + conn_graph_facts (pytest fixture): connection graph + fanout_graph_facts (pytest fixture): fanout graph + """ + + tgen_ports = tgen_ports[0:2] + logger.info("|--BGP Group-Origin Code Modifcation Test--|") + run_bgp_origin_code_modification(snappi_api, + duthost, + tgen_ports) \ No newline at end of file From 31b3f5d7a195920cf62434a52a72afdb30e0d235 Mon Sep 17 00:00:00 2001 From: Anish Date: Sun, 14 Mar 2021 09:18:41 +0000 Subject: [PATCH 05/12] merging common part --- tests/ixia/bgp/files/helper.py | 637 ++++++++------------------------- 1 file changed, 158 insertions(+), 479 deletions(-) diff --git a/tests/ixia/bgp/files/helper.py b/tests/ixia/bgp/files/helper.py index e286e748a9c..d421e810f98 100755 --- a/tests/ixia/bgp/files/helper.py +++ b/tests/ixia/bgp/files/helper.py @@ -80,39 +80,39 @@ def config_setup(duthost, duthost.shell(intf2_v6_config) logger.info("|--BGP Configuration On DUT--|") - bgp_config_501 = ( + bgp_config = ( "vtysh " "-c 'configure terminal' " "-c 'router bgp %s' " "-c 'no bgp default ipv4-unicast' " "-c 'no bgp ebgp-requires-policy' " - "-c 'neighbor LC501 peer-group' " - "-c 'neighbor LC501 remote-as %s' " - "-c 'neighbor %s peer-group LC501' " + "-c 'neighbor LC peer-group' " + "-c 'neighbor LC remote-as %s' " + "-c 'neighbor %s peer-group LC' " "-c 'address-family ipv4 unicast' " "-c 'neighbor %s activate' " ) - bgp_config_501 %= (DUT_AS_NUM, - TGEN_AS_NUM, - tgen_ports[0]['ip'], - tgen_ports[0]['ip']) - duthost.shell(bgp_config_501) + bgp_config %= (DUT_AS_NUM, + TGEN_AS_NUM, + tgen_ports[0]['ip'], + tgen_ports[0]['ip']) + duthost.shell(bgp_config) - bgpv6_config_501 = ( + bgpv6_config = ( "vtysh " "-c 'configure terminal' " "-c 'router bgp %s' " - "-c 'neighbor LC501v6 peer-group' " - "-c 'neighbor LC501v6 remote-as %s' " - "-c 'neighbor %s peer-group LC501v6' " + "-c 'neighbor LCv6 peer-group' " + "-c 'neighbor LCv6 remote-as %s' " + "-c 'neighbor %s peer-group LCv6' " "-c 'address-family ipv6 unicast' " "-c 'neighbor %s activate' " ) - bgpv6_config_501 %= (DUT_AS_NUM, - TGEN_AS_NUM, - tgen_ports[0]['ipv6'], - tgen_ports[0]['ipv6']) - duthost.shell(bgpv6_config_501) + bgpv6_config %= (DUT_AS_NUM, + TGEN_AS_NUM, + tgen_ports[0]['ipv6'], + tgen_ports[0]['ipv6']) + duthost.shell(bgpv6_config) # ipv6 next hop route-map next_hop = ( @@ -123,7 +123,7 @@ def config_setup(duthost, "-c 'set ipv6 next-hop prefer-global' " "-c 'router bgp %s' " "-c 'address-family ipv6 unicast' " - "-c 'neighbor LC501v6 route-map NEXTHOP in' " + "-c 'neighbor LCv6 route-map NEXTHOP in' " ) next_hop %= (DUT_AS_NUM) duthost.shell(next_hop) @@ -198,17 +198,13 @@ def run_bgp_prefix_list_test(snappi_api, tgen_bgp_config = __tgen_bgp_config(snappi_api, tgen_ports) - logger.info("|--Updating TGEN Config with with Prefix Lists--|") - tgen_bgp_prefix_list_config = __tgen_bgp_prefix_list_config( - tgen_bgp_config) - logger.info("|--BGP Prefix List Route Map Configuration on DUT--|") __bgp_prefix_list_route_map_config(duthost) logger.info("|--Verify Test--|") __verify_test(duthost, snappi_api, - tgen_bgp_prefix_list_config) + tgen_bgp_config) def run_bgp_metric_filter(snappi_api, @@ -339,11 +335,11 @@ def __tgen_bgp_config(snappi_api, ip2.prefix = tgen_ports[1]['prefix'] # BGPv4 - bgp501 = ip1.bgpv4 - bgp501.name = "bgp501" - bgp501.dut_address = tgen_ports[0]['peer_ip'] - bgp501.as_number = TGEN_AS_NUM - bgp501.as_type = BGP_TYPE + bgp = ip1.bgpv4 + bgp.name = "bgp" + bgp.dut_address = tgen_ports[0]['peer_ip'] + bgp.as_number = TGEN_AS_NUM + bgp.as_type = BGP_TYPE # v6 config ip1v6, ip2v6 = eth1.ipv6, eth2.ipv6 @@ -358,89 +354,40 @@ def __tgen_bgp_config(snappi_api, ip2v6.prefix = tgen_ports[1]['ipv6_prefix'] # BGPv6 - bgp501v6 = ip1v6.bgpv6 - bgp501v6.name = "bgp501v6" - bgp501v6.dut_address = tgen_ports[0]['peer_ipv6'] - bgp501v6.as_number = TGEN_AS_NUM - bgp501v6.as_type = BGP_TYPE - - return config - - -def __tgen_bgp_policies_config(config): - """ - BGP Attributes Config on TGEN - Args: - config : tgen config - """ - - bgp501 = config.devices[0].ethernet.ipv4.bgpv4 + bgpv6 = ip1v6.bgpv6 + bgpv6.name = "bgpv6" + bgpv6.dut_address = tgen_ports[0]['peer_ipv6'] + bgpv6.as_number = TGEN_AS_NUM + bgpv6.as_type = BGP_TYPE # Routes Config - bgp501_rr_with_policies, bgp501_rr2 = ( - bgp501.bgpv4_routes - .bgpv4route(name="bgp501_rr_with_policies") - .bgpv4route(name="bgp501_rr2") + bgp_route1, bgp_route2 = ( + bgp.bgpv4_routes + .bgpv4route(name="bgp_route1") + .bgpv4route(name="bgp_route2") ) - # Advertise one route("200.1.0.0") from AS 501 attributes - bgp501_rr_with_policies.addresses.bgpv4routeaddress(address="200.1.0.0", - prefix=16) - - # Community - manual_as_community = ( - bgp501_rr_with_policies.communities.bgpcommunity()[-1]) - manual_as_community.community_type = manual_as_community.MANUAL_AS_NUMBER - manual_as_community.as_number = int(COMMUNITY.split(":")[0]) - manual_as_community.as_custom = int(COMMUNITY.split(":")[1]) - # Metric - bgp501_rr_with_policies.advanced.multi_exit_discriminator = MED - # AS PATH - as_path = bgp501_rr_with_policies.as_path - as_path_segment = as_path.as_path_segments.bgpaspathsegment()[-1] - as_path_segment.segment_type = as_path_segment.AS_SEQ - as_path_segment.as_numbers = GROUP_AS - # Origin - bgp501_rr_with_policies.advanced.origin = ( - bgp501_rr_with_policies.advanced.EGP) - - # Advertise another route("20.1.0.0") from AS 501 - bgp501_rr2.addresses.bgpv4routeaddress(address="20.1.0.0", + # Advertise one route("200.1.0.0") + bgp_route1.addresses.bgpv4routeaddress(address="200.1.0.0", prefix=16) - # ipv6 - bgp501v6 = config.devices[0].ethernet.ipv6.bgpv6 + # Advertise another route("20.1.0.0") + bgp_route2.addresses.bgpv4routeaddress(address="20.1.0.0", + prefix=16) # Routes Config - bgp501v6_rr_with_policies, bgp501v6_rr2 = ( - bgp501v6.bgpv6_routes - .bgpv6route(name="bgp501v6_rr_with_policies") - .bgpv6route(name="bgp501v6_rr2") + bgpv6_route1, bgpv6_route2 = ( + bgpv6.bgpv6_routes + .bgpv6route(name="bgpv6_route1") + .bgpv6route(name="bgpv6_route2") ) - # Advertise one route("4000::1") from AS 501 with Attributes - bgp501v6_rr_with_policies.addresses.bgpv6routeaddress(address="4000::1", - prefix=64) - - # Community - manual_as_community = ( - bgp501v6_rr_with_policies.communities.bgpcommunity()[-1]) - manual_as_community.community_type = manual_as_community.MANUAL_AS_NUMBER - manual_as_community.as_number = int(COMMUNITY.split(":")[0]) - manual_as_community.as_custom = int(COMMUNITY.split(":")[1]) - # Metric - bgp501v6_rr_with_policies.advanced.multi_exit_discriminator = MED - # AS PATH - as_path = bgp501v6_rr_with_policies.as_path - as_path_segment = as_path.as_path_segments.bgpaspathsegment()[-1] - as_path_segment.segment_type = as_path_segment.AS_SEQ - as_path_segment.as_numbers = GROUP_AS - # Origin - bgp501v6_rr_with_policies.advanced.origin = ( - bgp501v6_rr_with_policies.advanced.EGP) + # Advertise one route("4000::1") with Attributes + bgpv6_route1.addresses.bgpv6routeaddress(address="4000::1", + prefix=64) - # Advertise another route("6000::1") from AS 501 - bgp501v6_rr2.addresses.bgpv6routeaddress(address="6000::1", + # Advertise another route("6000::1") + bgpv6_route2.addresses.bgpv6routeaddress(address="6000::1", prefix=64) # Create four flows @@ -452,11 +399,11 @@ def __tgen_bgp_policies_config(config): .flow(name='deny_ipv6') ) - permit.tx_rx.device.tx_names = [config.devices[1].ethernet.ipv4.name] - permit.tx_rx.device.rx_names = [bgp501_rr_with_policies.name] + permit.tx_rx.device.tx_names = [ip2.name] + permit.tx_rx.device.rx_names = [bgp_route1.name] - deny.tx_rx.device.tx_names = [config.devices[1].ethernet.ipv4.name] - deny.tx_rx.device.rx_names = [bgp501_rr2.name] + deny.tx_rx.device.tx_names = [ip2.name] + deny.tx_rx.device.rx_names = [bgp_route2.name] permit.rate.percentage = LINE_RATE permit.duration.fixed_packets.packets = PACKETS @@ -464,11 +411,11 @@ def __tgen_bgp_policies_config(config): deny.rate.percentage = LINE_RATE deny.duration.fixed_packets.packets = PACKETS - permit_ipv6.tx_rx.device.tx_names = [config.devices[1].ethernet.ipv6.name] - permit_ipv6.tx_rx.device.rx_names = [bgp501v6_rr_with_policies.name] + permit_ipv6.tx_rx.device.tx_names = [ip2v6.name] + permit_ipv6.tx_rx.device.rx_names = [bgpv6_route1.name] - deny_ipv6.tx_rx.device.tx_names = [config.devices[1].ethernet.ipv6.name] - deny_ipv6.tx_rx.device.rx_names = [bgp501v6_rr2.name] + deny_ipv6.tx_rx.device.tx_names = [ip2v6.name] + deny_ipv6.tx_rx.device.rx_names = [bgpv6_route2.name] permit_ipv6.rate.percentage = LINE_RATE permit_ipv6.duration.fixed_packets.packets = PACKETS @@ -479,6 +426,58 @@ def __tgen_bgp_policies_config(config): return config +def __tgen_bgp_policies_config(config): + """ + BGP Attributes Config on TGEN + Args: + config : tgen config + """ + + # update route("200.1.0.0") with attributes + bgp_route_with_policies = ( + config.devices[0].ethernet.ipv4.bgpv4.bgpv4_routes[0]) + + # Community + manual_as_community = ( + bgp_route_with_policies.communities.bgpcommunity()[-1]) + manual_as_community.community_type = manual_as_community.MANUAL_AS_NUMBER + manual_as_community.as_number = int(COMMUNITY.split(":")[0]) + manual_as_community.as_custom = int(COMMUNITY.split(":")[1]) + # Metric + bgp_route_with_policies.advanced.multi_exit_discriminator = MED + # AS PATH + as_path = bgp_route_with_policies.as_path + as_path_segment = as_path.as_path_segments.bgpaspathsegment()[-1] + as_path_segment.segment_type = as_path_segment.AS_SEQ + as_path_segment.as_numbers = GROUP_AS + # Origin + bgp_route_with_policies.advanced.origin = ( + bgp_route_with_policies.advanced.EGP) + + # update route("4000::1") with attributes + bgpv6_route_with_policies = ( + config.devices[0].ethernet.ipv6.bgpv6.bgpv6_routes[0]) + + # Community + manual_as_community = ( + bgpv6_route_with_policies.communities.bgpcommunity()[-1]) + manual_as_community.community_type = manual_as_community.MANUAL_AS_NUMBER + manual_as_community.as_number = int(COMMUNITY.split(":")[0]) + manual_as_community.as_custom = int(COMMUNITY.split(":")[1]) + # Metric + bgpv6_route_with_policies.advanced.multi_exit_discriminator = MED + # AS PATH + as_path = bgpv6_route_with_policies.as_path + as_path_segment = as_path.as_path_segments.bgpaspathsegment()[-1] + as_path_segment.segment_type = as_path_segment.AS_SEQ + as_path_segment.as_numbers = GROUP_AS + # Origin + bgpv6_route_with_policies.advanced.origin = ( + bgpv6_route_with_policies.advanced.EGP) + + return config + + def __bgp_policies_route_map_config(duthost): """ BGP Policy Route MAP Config on duthost @@ -540,86 +539,26 @@ def __tgen_bgp_community_config(config): config : tgen config """ - bgp501 = config.devices[0].ethernet.ipv4.bgpv4 - - # Routes Config - bgp501_rr_with_community, bgp501_rr2 = ( - bgp501.bgpv4_routes - .bgpv4route(name="bgp501_rr_with_community") - .bgpv4route(name="bgp501_rr2") - ) - - # Advertise one route("200.1.0.0") from AS 501 with community 1:2 - bgp501_rr_with_community.addresses.bgpv4routeaddress(address="200.1.0.0", - prefix=16) + # update route("200.1.0.0") with community 1:2 + bgp_route_with_community = ( + config.devices[0].ethernet.ipv4.bgpv4.bgpv4_routes[0]) manual_as_community = ( - bgp501_rr_with_community.communities.bgpcommunity()[-1]) + bgp_route_with_community.communities.bgpcommunity()[-1]) manual_as_community.community_type = manual_as_community.MANUAL_AS_NUMBER manual_as_community.as_number = int(COMMUNITY.split(":")[0]) manual_as_community.as_custom = int(COMMUNITY.split(":")[1]) - # Advertise another route("20.1.0.0") from AS 501 without community - bgp501_rr2.addresses.bgpv4routeaddress(address="20.1.0.0", - prefix=16) - - # ipv6 - bgp501v6 = config.devices[0].ethernet.ipv6.bgpv6 - - # Routes Config - bgp501v6_rr_with_community, bgp501v6_rr2 = ( - bgp501v6.bgpv6_routes - .bgpv6route(name="bgp501v6_rr_with_community") - .bgpv6route(name="bgp501v6_rr2") - ) - - # Advertise one route("4000::1") from AS 501 with community 1:2 - bgp501v6_rr_with_community.addresses.bgpv6routeaddress(address="4000::1", - prefix=64) + # update route("4000::1") with community 1:2 + bgpv6_route_with_community = ( + config.devices[0].ethernet.ipv6.bgpv6.bgpv6_routes[0]) manual_as_community = ( - bgp501v6_rr_with_community.communities.bgpcommunity()[-1]) + bgpv6_route_with_community.communities.bgpcommunity()[-1]) manual_as_community.community_type = manual_as_community.MANUAL_AS_NUMBER manual_as_community.as_number = int(COMMUNITY.split(":")[0]) manual_as_community.as_custom = int(COMMUNITY.split(":")[1]) - # Advertise another route("6000::1") from AS 501 without community - bgp501v6_rr2.addresses.bgpv6routeaddress(address="6000::1", - prefix=64) - - # Create four flows - permit, deny, permit_ipv6, deny_ipv6 = ( - config.flows - .flow(name='permit') - .flow(name='deny') - .flow(name='permit_ipv6') - .flow(name='deny_ipv6') - ) - - permit.tx_rx.device.tx_names = [config.devices[1].ethernet.ipv4.name] - permit.tx_rx.device.rx_names = [bgp501_rr_with_community.name] - - deny.tx_rx.device.tx_names = [config.devices[1].ethernet.ipv4.name] - deny.tx_rx.device.rx_names = [bgp501_rr2.name] - - permit.rate.percentage = LINE_RATE - permit.duration.fixed_packets.packets = PACKETS - - deny.rate.percentage = LINE_RATE - deny.duration.fixed_packets.packets = PACKETS - - permit_ipv6.tx_rx.device.tx_names = [config.devices[1].ethernet.ipv6.name] - permit_ipv6.tx_rx.device.rx_names = [bgp501v6_rr_with_community.name] - - deny_ipv6.tx_rx.device.tx_names = [config.devices[1].ethernet.ipv6.name] - deny_ipv6.tx_rx.device.rx_names = [bgp501v6_rr2.name] - - permit_ipv6.rate.percentage = LINE_RATE - permit_ipv6.duration.fixed_packets.packets = PACKETS - - deny_ipv6.rate.percentage = LINE_RATE - deny_ipv6.duration.fixed_packets.packets = PACKETS - return config @@ -635,10 +574,10 @@ def __bgp_community_route_map_config(duthost): "-c 'configure terminal' " "-c 'router bgp %s' " "-c 'address-family ipv4 unicast' " - "-c 'no neighbor LC501 route-map LA in' " + "-c 'no neighbor LC route-map LA in' " "-c 'address-family ipv6 unicast' " - "-c 'no neighbor LC501v6 route-map LAv6 in' " - "-c 'neighbor LC501v6 route-map NEXTHOP in' " + "-c 'no neighbor LCv6 route-map LAv6 in' " + "-c 'neighbor LCv6 route-map NEXTHOP in' " "-c 'no route-map LA' " "-c 'no route-map LAv6' " ) @@ -668,84 +607,6 @@ def __bgp_community_route_map_config(duthost): duthost.shell(community_config) -def __tgen_bgp_prefix_list_config(config): - """ - BGP Prefix Config on TGEN - Args: - config : tgen config - """ - - bgp501 = config.devices[0].ethernet.ipv4.bgpv4 - - # Routes Config - bgp501_rr1, bgp501_rr2 = ( - bgp501.bgpv4_routes - .bgpv4route(name="bgp501_rr1") - .bgpv4route(name="bgp501_rr2") - ) - - # Advertise one route("200.1.0.0") - bgp501_rr1.addresses.bgpv4routeaddress(address="200.1.0.0", - prefix=16) - - # Advertise another route("20.1.0.0") - bgp501_rr2.addresses.bgpv4routeaddress(address="20.1.0.0", - prefix=16) - - # ipv6 - bgp501v6 = config.devices[0].ethernet.ipv6.bgpv6 - - # Routes Config - bgp501v6_rr1, bgp501v6_rr2 = ( - bgp501v6.bgpv6_routes - .bgpv6route(name="bgp501v6_rr1") - .bgpv6route(name="bgp501v6_rr2") - ) - - # Advertise one route("4000::1") - bgp501v6_rr1.addresses.bgpv6routeaddress(address="4000::1", - prefix=64) - - # Advertise another route("6000::1") - bgp501v6_rr2.addresses.bgpv6routeaddress(address="6000::1", - prefix=64) - - # Create four flows - permit, deny, permit_ipv6, deny_ipv6 = ( - config.flows - .flow(name='permit') - .flow(name='deny') - .flow(name='permit_ipv6') - .flow(name='deny_ipv6') - ) - - permit.tx_rx.device.tx_names = [config.devices[1].ethernet.ipv4.name] - permit.tx_rx.device.rx_names = [bgp501_rr1.name] - - deny.tx_rx.device.tx_names = [config.devices[1].ethernet.ipv4.name] - deny.tx_rx.device.rx_names = [bgp501_rr2.name] - - permit.rate.percentage = LINE_RATE - permit.duration.fixed_packets.packets = PACKETS - - deny.rate.percentage = LINE_RATE - deny.duration.fixed_packets.packets = PACKETS - - permit_ipv6.tx_rx.device.tx_names = [config.devices[1].ethernet.ipv6.name] - permit_ipv6.tx_rx.device.rx_names = [bgp501v6_rr1.name] - - deny_ipv6.tx_rx.device.tx_names = [config.devices[1].ethernet.ipv6.name] - deny_ipv6.tx_rx.device.rx_names = [bgp501v6_rr2.name] - - permit_ipv6.rate.percentage = LINE_RATE - permit_ipv6.duration.fixed_packets.packets = PACKETS - - deny_ipv6.rate.percentage = LINE_RATE - deny_ipv6.duration.fixed_packets.packets = PACKETS - - return config - - def __bgp_prefix_list_route_map_config(duthost): """ BGP Prefix List Route MAP Config on duthost @@ -759,10 +620,10 @@ def __bgp_prefix_list_route_map_config(duthost): "-c 'configure terminal' " "-c 'router bgp %s' " "-c 'address-family ipv4 unicast' " - "-c 'no neighbor LC501 route-map LA in' " + "-c 'no neighbor LC route-map LA in' " "-c 'address-family ipv6 unicast' " - "-c 'no neighbor LC501v6 route-map LAv6 in' " - "-c 'neighbor LC501v6 route-map NEXTHOP in' " + "-c 'no neighbor LCv6 route-map LAv6 in' " + "-c 'neighbor LCv6 route-map NEXTHOP in' " "-c 'no route-map LA' " "-c 'no route-map LAv6' " ) @@ -792,77 +653,15 @@ def __tgen_bgp_metric_config(config): config : tgen config """ - bgp501 = config.devices[0].ethernet.ipv4.bgpv4 - - # Routes Config - bgp501_rr_metric_100, bgp501_rr2 = ( - bgp501.bgpv4_routes - .bgpv4route(name="bgp501_rr_metric_100") - .bgpv4route(name="bgp501_rr2") - ) - - # Advertise one route("200.1.0.0") from AS 501 with metric/MED 100 - bgp501_rr_metric_100.addresses.bgpv4routeaddress(address="200.1.0.0", - prefix=16) - - bgp501_rr_metric_100.advanced.multi_exit_discriminator = MED - - # Advertise another route("20.1.0.0") - bgp501_rr2.addresses.bgpv4routeaddress(address="20.1.0.0", - prefix=16) - - # ipv6 - bgp501v6 = config.devices[0].ethernet.ipv6.bgpv6 - - # Routes Config - bgp501v6_rr_metric_100, bgp501v6_rr2 = ( - bgp501v6.bgpv6_routes - .bgpv6route(name="bgp501v6_rr_metric_100") - .bgpv6route(name="bgp501v6_rr2") - ) - - # Advertise one route("4000::1") from AS 501 with additional AS 100 - bgp501v6_rr_metric_100.addresses.bgpv6routeaddress(address="4000::1", - prefix=64) - - bgp501v6_rr_metric_100.advanced.multi_exit_discriminator = MED - - # Advertise another route("6000::1") - bgp501v6_rr2.addresses.bgpv6routeaddress(address="6000::1", - prefix=64) - - # Create four flows - permit, deny, permit_ipv6, deny_ipv6 = ( - config.flows - .flow(name='permit') - .flow(name='deny') - .flow(name='permit_ipv6') - .flow(name='deny_ipv6') - ) - - permit.tx_rx.device.tx_names = [config.devices[1].ethernet.ipv4.name] - permit.tx_rx.device.rx_names = [bgp501_rr_metric_100.name] - - deny.tx_rx.device.tx_names = [config.devices[1].ethernet.ipv4.name] - deny.tx_rx.device.rx_names = [bgp501_rr2.name] - - permit.rate.percentage = LINE_RATE - permit.duration.fixed_packets.packets = PACKETS - - deny.rate.percentage = LINE_RATE - deny.duration.fixed_packets.packets = PACKETS - - permit_ipv6.tx_rx.device.tx_names = [config.devices[1].ethernet.ipv6.name] - permit_ipv6.tx_rx.device.rx_names = [bgp501v6_rr_metric_100.name] - - deny_ipv6.tx_rx.device.tx_names = [config.devices[1].ethernet.ipv6.name] - deny_ipv6.tx_rx.device.rx_names = [bgp501v6_rr2.name] - - permit_ipv6.rate.percentage = LINE_RATE - permit_ipv6.duration.fixed_packets.packets = PACKETS + # update route("200.1.0.0") with metric/MED 100 + bgp_route_metric_100 = ( + config.devices[0].ethernet.ipv4.bgpv4.bgpv4_routes[0]) + bgp_route_metric_100.advanced.multi_exit_discriminator = MED - deny_ipv6.rate.percentage = LINE_RATE - deny_ipv6.duration.fixed_packets.packets = PACKETS + # update route("4000::1") with metric/MED 100 + bgpv6_route_metric_100 = ( + config.devices[0].ethernet.ipv6.bgpv6.bgpv6_routes[0]) + bgpv6_route_metric_100.advanced.multi_exit_discriminator = MED return config @@ -879,10 +678,10 @@ def __bgp_metric_route_map_config(duthost): "-c 'configure terminal' " "-c 'router bgp %s' " "-c 'address-family ipv4 unicast' " - "-c 'no neighbor LC501 route-map LA in' " + "-c 'no neighbor LC route-map LA in' " "-c 'address-family ipv6 unicast' " - "-c 'no neighbor LC501v6 route-map LAv6 in' " - "-c 'neighbor LC501v6 route-map NEXTHOP in' " + "-c 'no neighbor LCv6 route-map LAv6 in' " + "-c 'neighbor LCv6 route-map NEXTHOP in' " "-c 'no route-map LA' " "-c 'no route-map LAv6' " ) @@ -908,84 +707,24 @@ def __tgen_bgp_as_path_modified_config(config): config : tgen config """ - bgp501 = config.devices[0].ethernet.ipv4.bgpv4 + # update route("200.1.0.0") with additional AS 100 + bgp_route_with_as_100 = ( + config.devices[0].ethernet.ipv4.bgpv4.bgpv4_routes[0]) - # Routes Config - bgp501_rr_with_as_100, bgp501_rr2 = ( - bgp501.bgpv4_routes - .bgpv4route(name="bgp501_rr_with_as_100") - .bgpv4route(name="bgp501_rr2") - ) - - # Advertise one route("200.1.0.0") from AS 501 with additional AS 100 - bgp501_rr_with_as_100.addresses.bgpv4routeaddress(address="200.1.0.0", - prefix=16) - - as_path = bgp501_rr_with_as_100.as_path + as_path = bgp_route_with_as_100.as_path as_path_segment = as_path.as_path_segments.bgpaspathsegment()[-1] as_path_segment.segment_type = as_path_segment.AS_SEQ as_path_segment.as_numbers = GROUP_AS - # Advertise another route("20.1.0.0") - bgp501_rr2.addresses.bgpv4routeaddress(address="20.1.0.0", - prefix=16) - - # ipv6 - bgp501v6 = config.devices[0].ethernet.ipv6.bgpv6 - - # Routes Config - bgp501v6_rr_with_as_100, bgp501v6_rr2 = ( - bgp501v6.bgpv6_routes - .bgpv6route(name="bgp501v6_rr_with_as_100") - .bgpv6route(name="bgp501v6_rr2") - ) - - # Advertise one route("4000::1") from AS 501 with additional AS 100 - bgp501v6_rr_with_as_100.addresses.bgpv6routeaddress(address="4000::1", - prefix=64) + # update route("4000::1") with additional AS 100 + bgpv6_route_with_as_100 = ( + config.devices[0].ethernet.ipv6.bgpv6.bgpv6_routes[0]) - as_path = bgp501v6_rr_with_as_100.as_path + as_path = bgpv6_route_with_as_100.as_path as_path_segment = as_path.as_path_segments.bgpaspathsegment()[-1] as_path_segment.segment_type = as_path_segment.AS_SEQ as_path_segment.as_numbers = GROUP_AS - # Advertise another route("6000::1") - bgp501v6_rr2.addresses.bgpv6routeaddress(address="6000::1", - prefix=64) - - # Create four flows - permit, deny, permit_ipv6, deny_ipv6 = ( - config.flows - .flow(name='permit') - .flow(name='deny') - .flow(name='permit_ipv6') - .flow(name='deny_ipv6') - ) - - permit.tx_rx.device.tx_names = [config.devices[1].ethernet.ipv4.name] - permit.tx_rx.device.rx_names = [bgp501_rr_with_as_100.name] - - deny.tx_rx.device.tx_names = [config.devices[1].ethernet.ipv4.name] - deny.tx_rx.device.rx_names = [bgp501_rr2.name] - - permit.rate.percentage = LINE_RATE - permit.duration.fixed_packets.packets = PACKETS - - deny.rate.percentage = LINE_RATE - deny.duration.fixed_packets.packets = PACKETS - - permit_ipv6.tx_rx.device.tx_names = [config.devices[1].ethernet.ipv6.name] - permit_ipv6.tx_rx.device.rx_names = [bgp501v6_rr_with_as_100.name] - - deny_ipv6.tx_rx.device.tx_names = [config.devices[1].ethernet.ipv6.name] - deny_ipv6.tx_rx.device.rx_names = [bgp501v6_rr2.name] - - permit_ipv6.rate.percentage = LINE_RATE - permit_ipv6.duration.fixed_packets.packets = PACKETS - - deny_ipv6.rate.percentage = LINE_RATE - deny_ipv6.duration.fixed_packets.packets = PACKETS - return config @@ -1001,10 +740,10 @@ def __bgp_as_path_route_map_config(duthost): "-c 'configure terminal' " "-c 'router bgp %s' " "-c 'address-family ipv4 unicast' " - "-c 'no neighbor LC501 route-map LA in' " + "-c 'no neighbor LC route-map LA in' " "-c 'address-family ipv6 unicast' " - "-c 'no neighbor LC501v6 route-map LAv6 in' " - "-c 'neighbor LC501v6 route-map NEXTHOP in' " + "-c 'no neighbor LCv6 route-map LAv6 in' " + "-c 'neighbor LCv6 route-map NEXTHOP in' " "-c 'no route-map LA' " "-c 'no route-map LAv6' " ) @@ -1041,78 +780,18 @@ def __tgen_bgp_origin_config(config): config : tgen config """ - bgp501 = config.devices[0].ethernet.ipv4.bgpv4 - - # Routes Config - bgp501_rr_origin_egp, bgp501_rr2 = ( - bgp501.bgpv4_routes - .bgpv4route(name="bgp501_rr_origin_egp") - .bgpv4route(name="bgp501_rr2") - ) - - # Advertise one route("200.1.0.0") from AS 501 with ORIGIN EGP - bgp501_rr_origin_egp.addresses.bgpv4routeaddress(address="200.1.0.0", - prefix=16) - - bgp501_rr_origin_egp.advanced.origin = bgp501_rr_origin_egp.advanced.EGP - - # Advertise another route("20.1.0.0") - bgp501_rr2.addresses.bgpv4routeaddress(address="20.1.0.0", - prefix=16) - - # ipv6 - bgp501v6 = config.devices[0].ethernet.ipv6.bgpv6 - - # Routes Config - bgp501v6_rr_origin_egp, bgp501v6_rr2 = ( - bgp501v6.bgpv6_routes - .bgpv6route(name="bgp501v6_rr_origin_egp") - .bgpv6route(name="bgp501v6_rr2") - ) - - # Advertise one route("4000::1") from AS 501 with ORIGIN EGP - bgp501v6_rr_origin_egp.addresses.bgpv6routeaddress(address="4000::1", - prefix=64) - - bgp501v6_rr_origin_egp.advanced.origin = ( - bgp501v6_rr_origin_egp.advanced.EGP) - - # Advertise another route("6000::1") - bgp501v6_rr2.addresses.bgpv6routeaddress(address="6000::1", - prefix=64) - - # Create four flows - permit, deny, permit_ipv6, deny_ipv6 = ( - config.flows - .flow(name='permit') - .flow(name='deny') - .flow(name='permit_ipv6') - .flow(name='deny_ipv6') - ) - - permit.tx_rx.device.tx_names = [config.devices[1].ethernet.ipv4.name] - permit.tx_rx.device.rx_names = [bgp501_rr_origin_egp.name] - - deny.tx_rx.device.tx_names = [config.devices[1].ethernet.ipv4.name] - deny.tx_rx.device.rx_names = [bgp501_rr2.name] - - permit.rate.percentage = LINE_RATE - permit.duration.fixed_packets.packets = PACKETS - - deny.rate.percentage = LINE_RATE - deny.duration.fixed_packets.packets = PACKETS + # update route("200.1.0.0") with ORIGIN EGP + bgp_route_origin_egp = ( + config.devices[0].ethernet.ipv4.bgpv4.bgpv4_routes[0]) - permit_ipv6.tx_rx.device.tx_names = [config.devices[1].ethernet.ipv6.name] - permit_ipv6.tx_rx.device.rx_names = [bgp501v6_rr_origin_egp.name] + bgp_route_origin_egp.advanced.origin = bgp_route_origin_egp.advanced.EGP - deny_ipv6.tx_rx.device.tx_names = [config.devices[1].ethernet.ipv6.name] - deny_ipv6.tx_rx.device.rx_names = [bgp501v6_rr2.name] + # update route("4000::1") with with ORIGIN EGP + bgpv6_route_origin_egp = ( + config.devices[0].ethernet.ipv6.bgpv6.bgpv6_routes[0]) - permit_ipv6.rate.percentage = LINE_RATE - permit_ipv6.duration.fixed_packets.packets = PACKETS - - deny_ipv6.rate.percentage = LINE_RATE - deny_ipv6.duration.fixed_packets.packets = PACKETS + bgpv6_route_origin_egp.advanced.origin = ( + bgpv6_route_origin_egp.advanced.EGP) return config @@ -1130,10 +809,10 @@ def __bgp_origin_route_map_config(duthost): "-c 'configure terminal' " "-c 'router bgp %s' " "-c 'address-family ipv4 unicast' " - "-c 'no neighbor LC501 route-map LA in' " + "-c 'no neighbor LC route-map LA in' " "-c 'address-family ipv6 unicast' " - "-c 'no neighbor LC501v6 route-map LAv6 in' " - "-c 'neighbor LC501v6 route-map NEXTHOP in' " + "-c 'no neighbor LCv6 route-map LAv6 in' " + "-c 'neighbor LCv6 route-map NEXTHOP in' " "-c 'no route-map LA' " "-c 'no route-map LAv6' " ) @@ -1189,9 +868,9 @@ def __verify_test(duthost, "-c 'configure terminal' " "-c 'router bgp %s' " "-c 'address-family ipv4 unicast' " - "-c 'neighbor LC501 route-map LA in' " + "-c 'neighbor LC route-map LA in' " "-c 'address-family ipv6 unicast' " - "-c 'neighbor LC501v6 route-map LAv6 in' " + "-c 'neighbor LCv6 route-map LAv6 in' " ) route_map %= (DUT_AS_NUM) duthost.shell(route_map) From da0be8933dbcd5dacb96352ec232b698c9f5c660 Mon Sep 17 00:00:00 2001 From: Anish Date: Mon, 15 Mar 2021 14:30:09 +0000 Subject: [PATCH 06/12] ixia/bgp/test_bgp_routing_policies.py --- docs/testplan/routing_policies.md | 245 ++++++++++++++++++ tests/ixia/bgp/files/helper.py | 88 +++---- tests/ixia/bgp/test_routing_policies.py | 316 ++++++++++++++++++++++++ 3 files changed, 605 insertions(+), 44 deletions(-) create mode 100644 docs/testplan/routing_policies.md create mode 100755 tests/ixia/bgp/test_routing_policies.py diff --git a/docs/testplan/routing_policies.md b/docs/testplan/routing_policies.md new file mode 100644 index 00000000000..ffe7abfa6ce --- /dev/null +++ b/docs/testplan/routing_policies.md @@ -0,0 +1,245 @@ +# Routing policies test plan + +- [Routing Policies testplan](#bgp-routing-policies-testplan) + - [Overview](#Overview) + - [Scope](#Scope) + - [Testbed](#Keysight-Testbed) + - [Topology](#Topology) + - [Test methodology](#Test-methodology) + - [Test cases](#Test-cases) + - [Test case # 1 – Peer Routing Policies](#test-case--1--peer-routing-policies) + - [Test objective](#Test-objective) + - [Test steps](#Test-steps) + - [Test results](#Test-results) + - [Test case # 2 – Community List Filtering](#test-case--2--community-list-filtering) + - [Test objective](#Test-objective-1) + - [Test steps](#Test-steps-1) + - [Test results](#Test-results-1) + - [Test case # 3 – Prefix List Filtering](#test-case--3--prefix-list-filtering) + - [Test objective](#Test-objective-2) + - [Test steps](#Test-steps-2) + - [Test results](#Test-results-2) + - [Test case # 4 – Metric Filter](#test-case--4--metric-filter) + - [Test objective](#Test-objective-3) + - [Test steps](#Test-steps-3) + - [Test results](#Test-results-3) + - [Test case # 5 – Group-As-Path Modified](#test-case--5--group-as-path-modified) + - [Test objective](#Test-objective-4) + - [Test steps](#Test-steps-4) + - [Test results](#Test-results-4) + - [Test case # 6 – Group Origin Code Modification](#test-case--6--group-origin-code-modification) + - [Test objective](#Test-objective-5) + - [Test steps](#Test-steps-5) + - [Test results](#Test-results-5) + + +## Overview +The purpose of these tests is to evaluate the BGP Routing Policies Using Match Conditions and Actions. The routing policy consists of multiple terms. Each term consists of match conditions and actions to apply to matching routes. + +### Scope +These tests are targeted on fully functioning SONiC system. The purpose of these tests are to evaluate the BGP Routing Policies Using Match Conditions and Actions. + +### Keysight Testbed +The tests will run on following testbeds: +* t0 + +![Single DUT Topology ](Img/Single_DUT_Topology.png) + +## Topology + +``` + _________ + | | +IXIA TGEN1 -------- | DUT |------ IXIA TGEN2 + |_________| +``` + +## Test Methodology +Following test methodology will be used to evaluate routing policies. +* Traffic generator will be used to configure ebgp peering between TGEN1 and SONiC DUT by advertising IPv4/IPv6, dual-stack routes. +* Advertise 2 IPv4 and 2 IPv6 routes from TGEN1. +* Create four flows from TGEN2 to TGEN1 + 1. `permit` -- TGEN2 to TGEN1("200.1.0.0") + 2. `permit_ipv6` -- TGEN2 to TGEN1("4000::1") + 3. `deny` -- TGEN2 to TGEN1("20.1.0.0") + 4. `deny_ipv6` -- TGEN2 to TGEN1("6000::1") +* update the BGP attributes as per route policy for route in `permit` & `permit_ipv6` +and validate the actions applied to match routes. + + +## Test cases +### Test case # 1 – Peer Routing Policies +#### Test objective +Routing policy in the DUT match conditions with BGP attributes (community, as-path, metric, origin) and permit the routes. + + +#### Test steps +1. Configure BGP between DUT and TGEN1. +2. Generate 2 ipv4 routes & 2 ipv6 routes from TGEN1 via BGP. + + 1. "200.1.0.0" & "4000::1" with Attributes + a) community-list 1:2 + b) as-path append AS 100 + c) Origin ebgp + d) Metric 50 + 2. "20.1.0.0" & "6000::1" without Attributes +3. Create route-map in DUT to permit only `200.1.0.0` + & `4000::1` based on BGP Attributes +4. Create four flows from TGEN2 to TGEN1 + + 1) permit -- TGEN2 to TGEN1("200.1.0.0") + 2) permit_ipv6 -- TGEN2 to TGEN1("4000::1") + 3) deny -- TGEN2 to TGEN1("20.1.0.0") + 4) deny_ipv6 -- TGEN2 to TGEN1("6000::1") + +#### Test results +1. Send traffic without applying route-map + + Result: Should not observe traffic loss in the flows 'permit','deny','permit_ipv6' & 'deny_ipv6' +2. Apply route-map + + Result: Should observe 100% traffic loss in the flows 'deny' & 'deny_ipv6' + + +### Test case # 2 – Community List Filtering +#### Test objective +Routing policy in the DUT match conditions with BGP Community and permit the routes with Community. + + +#### Test steps +1. Configure BGP between DUT and TGEN1. +2. Generate 2 ipv4 routes & 2 ipv6 routes from TGEN1 via BGP. + + 1. "200.1.0.0" & "4000::1" with Community List + 2. "20.1.0.0" & "6000::1" without Community List +3. Create route-map in DUT to permit only `200.1.0.0` + & `4000::1` based on BGP Community List +4. Create four flows from TGEN2 to TGEN1 + + 1) permit -- TGEN2 to TGEN1("200.1.0.0") + 2) permit_ipv6 -- TGEN2 to TGEN1("4000::1") + 3) deny -- TGEN2 to TGEN1("20.1.0.0") + 4) deny_ipv6 -- TGEN2 to TGEN1("6000::1") + +#### Test results +1. Send traffic without applying route-map + + Result: Should not observe traffic loss in the flows 'permit', 'deny', 'permit_ipv6' & 'deny_ipv6' +2. Apply route-map + + Result: Should observe 100% traffic loss in the flows 'deny' & 'deny_ipv6' + +### Test case # 3 – Prefix List Filtering +#### Test objective +Routing policy in the DUT match conditions with Prefix-list and permit based on Prefix List Filtering. + + +#### Test steps +1. Configure BGP between DUT and TGEN1. +2. Generate 2 ipv4 routes & 2 ipv6 routes from TGEN1 via BGP. + + 1. "200.1.0.0" & "4000::1" + 2. "20.1.0.0" & "6000::1" +3. Create Prefix-list route-map in DUT to permit only `200.1.0.0` + & `4000::1` +4. Create four flows from TGEN2 to TGEN1 + + 1) permit -- TGEN2 to TGEN1("200.1.0.0") + 2) permit_ipv6 -- TGEN2 to TGEN1("4000::1") + 3) deny -- TGEN2 to TGEN1("20.1.0.0") + 4) deny_ipv6 -- TGEN2 to TGEN1("6000::1") + +#### Test results +1. Send traffic without applying route-map + + Result: Should not observe traffic loss in the flows 'permit','deny','permit_ipv6' & 'deny_ipv6' +2. Apply route-map + + Result: Should observe 100% traffic loss in the flows 'deny' & 'deny_ipv6' + + +### Test case # 4 – Metric Filter +#### Test objective +Routing policy in the DUT match conditions with Metric and permit based on Metric Filtering. + + +#### Test steps +1. Configure BGP between DUT and TGEN1. +2. Generate 2 ipv4 routes & 2 ipv6 routes from TGEN1 via BGP. + + 1."200.1.0.0" & "4000::1" with Metric 50 + 2."20.1.0.0" & "6000::1" with default Metric +3. Create route-map in DUT to permit only `200.1.0.0` + & `4000::1` with Metric 50 +4. Create four flows from TGEN2 to TGEN1 + + 1) permit -- TGEN2 to TGEN1("200.1.0.0") + 2) permit_ipv6 -- TGEN2 to TGEN1("4000::1") + 3) deny -- TGEN2 to TGEN1("20.1.0.0") + 4) deny_ipv6 -- TGEN2 to TGEN1("6000::1") + +#### Test results +1. Send traffic without applying route-map + + Result: Should not observe traffic loss in the flows 'permit','deny','permit_ipv6' & 'deny_ipv6' +2. Apply route-map + + Result: Should observe 100% traffic loss in the flows 'deny' & 'deny_ipv6' + + +### Test case # 5 – Group-As-Path Modified +#### Test objective +Routing policy in the DUT match conditions with group-as-path and permit based on group-as-path Modification. + + +#### Test steps +1. Configure BGP between DUT and TGEN1. +2. Generate 2 ipv4 routes & 2 ipv6 routes from TGEN1 via BGP. + + 1."200.1.0.0" & "4000::1" with group AS 100 + 2."20.1.0.0" & "6000::1" without group AS 100 +3. Create route-map in DUT to permit only `200.1.0.0` + & `4000::1` with group AS 100 +4. Create four flows from TGEN2 to TGEN1 + + 1) permit -- TGEN2 to TGEN1("200.1.0.0") + 2) permit_ipv6 -- TGEN2 to TGEN1("4000::1") + 3) deny -- TGEN2 to TGEN1("20.1.0.0") + 4) deny_ipv6 -- TGEN2 to TGEN1("6000::1") + +#### Test results +1. Send traffic without applying route-map + + Result: Should not observe traffic loss in the flows 'permit','deny','permit_ipv6' & 'deny_ipv6' +2. Apply route-map + + Result: Should observe 100% traffic loss in the flows 'deny' & 'deny_ipv6' + + +### Test case # 6 – Group Origin Code Modification +#### Test objective +Routing policy in the DUT match conditions with Origin and permit based on Origin + + +#### Test steps +1. Configure BGP between DUT and TGEN1. +2. Generate 2 ipv4 routes & 2 ipv6 routes from TGEN1 via BGP. + + 1."200.1.0.0" & "4000::1" with Origin 'egp' + 2."20.1.0.0" & "6000::1" +3. Create route-map in DUT to permit only `200.1.0.0` + & `4000::1` with Origin 'egp' +4. Create four flows from TGEN2 to TGEN1 + + 1) permit -- TGEN2 to TGEN1("200.1.0.0") + 2) permit_ipv6 -- TGEN2 to TGEN1("4000::1") + 3) deny -- TGEN2 to TGEN1("20.1.0.0") + 4) deny_ipv6 -- TGEN2 to TGEN1("6000::1") + +#### Test results +1. Send traffic without applying route-map + + Result: Should not observe traffic loss in the flows 'permit','deny','permit_ipv6' & 'deny_ipv6' +2. Apply route-map + + Result: Should observe 100% traffic loss in the flows 'deny' & 'deny_ipv6' diff --git a/tests/ixia/bgp/files/helper.py b/tests/ixia/bgp/files/helper.py index d421e810f98..d80a0d87e9c 100755 --- a/tests/ixia/bgp/files/helper.py +++ b/tests/ixia/bgp/files/helper.py @@ -129,9 +129,9 @@ def config_setup(duthost, duthost.shell(next_hop) -def run_bgp_peer_routing_policies_test(snappi_api, - duthost, - tgen_ports): +def run_peer_routing_policies_test(snappi_api, + duthost, + tgen_ports): """ Run BGP Peer Routing Policies Test @@ -145,20 +145,20 @@ def run_bgp_peer_routing_policies_test(snappi_api, tgen_ports) logger.info("|--Updating TGEN Config with BGP Route Attributes--|") - tgen_bgp_policies_config = __tgen_bgp_policies_config(tgen_bgp_config) + tgen_policies_config = __tgen_policies_config(tgen_bgp_config) logger.info("|--BGP Policy Route Map Configuration on DUT--|") - __bgp_policies_route_map_config(duthost) + __policies_route_map_config(duthost) logger.info("|--Verify Test--|") __verify_test(duthost, snappi_api, - tgen_bgp_policies_config) + tgen_policies_config) -def run_bgp_community_test(snappi_api, - duthost, - tgen_ports): +def run_community_list_filtering_test(snappi_api, + duthost, + tgen_ports): """ Run BGP Community List Filtering Test @@ -172,20 +172,20 @@ def run_bgp_community_test(snappi_api, tgen_ports) logger.info("|--Updating TGEN Config with BGP Community Attribute--|") - tgen_bgp_community_config = __tgen_bgp_community_config(tgen_bgp_config) + tgen_community_config = __tgen_community_config(tgen_bgp_config) logger.info("|--BGP Community Route Map Configuration on DUT--|") - __bgp_community_route_map_config(duthost) + __community_route_map_config(duthost) logger.info("|--Verify Test--|") __verify_test(duthost, snappi_api, - tgen_bgp_community_config) + tgen_community_config) -def run_bgp_prefix_list_test(snappi_api, - duthost, - tgen_ports): +def run_prefix_list_filtering_test(snappi_api, + duthost, + tgen_ports): """ Run BGP Prefix List Filtering Test @@ -199,7 +199,7 @@ def run_bgp_prefix_list_test(snappi_api, tgen_ports) logger.info("|--BGP Prefix List Route Map Configuration on DUT--|") - __bgp_prefix_list_route_map_config(duthost) + __prefix_list_route_map_config(duthost) logger.info("|--Verify Test--|") __verify_test(duthost, @@ -207,9 +207,9 @@ def run_bgp_prefix_list_test(snappi_api, tgen_bgp_config) -def run_bgp_metric_filter(snappi_api, - duthost, - tgen_ports): +def run_test_metric_filter(snappi_api, + duthost, + tgen_ports): """ Run BGP Metric Filter Test @@ -224,20 +224,20 @@ def run_bgp_metric_filter(snappi_api, tgen_ports) logger.info("|--Updating TGEN Config with Metric/MED Attribute--|") - tgen_bgp_metric_config = __tgen_bgp_metric_config(tgen_bgp_config) + tgen_metric_config = __tgen_metric_config(tgen_bgp_config) logger.info("|--BGP Metric Route Map Configuration on DUT--|") - __bgp_metric_route_map_config(duthost) + __metric_route_map_config(duthost) logger.info("|--Verify Test--|") __verify_test(duthost, snappi_api, - tgen_bgp_metric_config) + tgen_metric_config) -def run_bgp_group_as_path_modified(snappi_api, - duthost, - tgen_ports): +def run_group_as_path_modified(snappi_api, + duthost, + tgen_ports): """ Run BGP group-as-path Modified Test @@ -251,11 +251,11 @@ def run_bgp_group_as_path_modified(snappi_api, tgen_ports) logger.info("|--Updating TGEN Config with Group AS-PATH Attribute--|") - tgen_as_path_modified_config = __tgen_bgp_as_path_modified_config( + tgen_as_path_modified_config = __tgen_as_path_modified_config( tgen_bgp_config) logger.info("|--BGP AS-PATH Route Map Configuration on DUT--|") - __bgp_as_path_route_map_config(duthost) + __as_path_route_map_config(duthost) logger.info("|--Verify Test--|") __verify_test(duthost, @@ -263,9 +263,9 @@ def run_bgp_group_as_path_modified(snappi_api, tgen_as_path_modified_config) -def run_bgp_origin_code_modification(snappi_api, - duthost, - tgen_ports): +def run_origin_code_modification(snappi_api, + duthost, + tgen_ports): """ Run BGP Origin Code Modification Test @@ -279,15 +279,15 @@ def run_bgp_origin_code_modification(snappi_api, tgen_ports) logger.info("|--Updating TGEN Config with Origin Attribute--|") - tgen_bgp_origin_config = __tgen_bgp_origin_config(tgen_bgp_config) + tgen_origin_config = __tgen_origin_config(tgen_bgp_config) logger.info("|--BGP Origin Route Map Configuration on DUT--|") - __bgp_origin_route_map_config(duthost) + __origin_route_map_config(duthost) logger.info("|--Verify Test--|") __verify_test(duthost, snappi_api, - tgen_bgp_origin_config) + tgen_origin_config) # Common TGEN BGP Config @@ -426,7 +426,7 @@ def __tgen_bgp_config(snappi_api, return config -def __tgen_bgp_policies_config(config): +def __tgen_policies_config(config): """ BGP Attributes Config on TGEN Args: @@ -478,7 +478,7 @@ def __tgen_bgp_policies_config(config): return config -def __bgp_policies_route_map_config(duthost): +def __policies_route_map_config(duthost): """ BGP Policy Route MAP Config on duthost Args: @@ -532,7 +532,7 @@ def __bgp_policies_route_map_config(duthost): duthost.shell(policy_route_map_config) -def __tgen_bgp_community_config(config): +def __tgen_community_config(config): """ BGP Community Config on TGEN Args: @@ -562,7 +562,7 @@ def __tgen_bgp_community_config(config): return config -def __bgp_community_route_map_config(duthost): +def __community_route_map_config(duthost): """ BGP Community Route MAP Config on duthost Args: @@ -607,7 +607,7 @@ def __bgp_community_route_map_config(duthost): duthost.shell(community_config) -def __bgp_prefix_list_route_map_config(duthost): +def __prefix_list_route_map_config(duthost): """ BGP Prefix List Route MAP Config on duthost Args: @@ -646,7 +646,7 @@ def __bgp_prefix_list_route_map_config(duthost): duthost.shell(prefix_list_config) -def __tgen_bgp_metric_config(config): +def __tgen_metric_config(config): """ BGP Metric config on TGEN Args: @@ -666,7 +666,7 @@ def __tgen_bgp_metric_config(config): return config -def __bgp_metric_route_map_config(duthost): +def __metric_route_map_config(duthost): """ BGP Metric Route MAP Config on duthost Args: @@ -700,7 +700,7 @@ def __bgp_metric_route_map_config(duthost): duthost.shell(metric_config) -def __tgen_bgp_as_path_modified_config(config): +def __tgen_as_path_modified_config(config): """ BGP group AS config on duthost and TGEN Args: @@ -728,7 +728,7 @@ def __tgen_bgp_as_path_modified_config(config): return config -def __bgp_as_path_route_map_config(duthost): +def __as_path_route_map_config(duthost): """ BGP AS PATH Route MAP Config on duthost Args: @@ -773,7 +773,7 @@ def __bgp_as_path_route_map_config(duthost): duthost.shell(as_path_route_map) -def __tgen_bgp_origin_config(config): +def __tgen_origin_config(config): """ BGP Origin config on TGEN Args: @@ -796,7 +796,7 @@ def __tgen_bgp_origin_config(config): return config -def __bgp_origin_route_map_config(duthost): +def __origin_route_map_config(duthost): """ BGP Origin Route MAP Config on duthost Args: diff --git a/tests/ixia/bgp/test_routing_policies.py b/tests/ixia/bgp/test_routing_policies.py new file mode 100755 index 00000000000..1c937489e00 --- /dev/null +++ b/tests/ixia/bgp/test_routing_policies.py @@ -0,0 +1,316 @@ +import pytest +import logging +from tests.common.ixia.ixia_fixtures import snappi_api +from tests.common.ixia.ixia_fixtures import ( + ixia_api_serv_ip, ixia_api_serv_port, tgen_ports) +from files.helper import ( + run_peer_routing_policies_test, run_community_list_filtering_test, + run_prefix_list_filtering_test, run_test_metric_filter, + run_group_as_path_modified, run_origin_code_modification, + config_setup, config_cleanup) +from tests.common.fixtures.conn_graph_facts import ( + conn_graph_facts, fanout_graph_facts) +logger = logging.getLogger(__name__) + + +@pytest.fixture(scope="module") +def setup_and_teardown(duthost, + tgen_ports): + """ + Setup and Teardown + """ + # We are going to use first two ports for all these tests + tgen_ports = tgen_ports[0:2] + logger.info("|--Common Setup Configuration--|") + config_setup(duthost, + tgen_ports) + yield + logger.info("|--Common Cleanup--|") + config_cleanup(duthost, + tgen_ports) + + +# Test 1 +@pytest.mark.topology("tgen") +def test_peer_routing_policies(snappi_api, + duthost, + tgen_ports, + conn_graph_facts, + fanout_graph_facts, + setup_and_teardown): + """ + Topo: + TGEN1 --- DUT --- TGEN2 + + Steps: + 1) Create BGP config on DUT and TGEN respectively + 2) Generate 2 ipv4 routes & 2 ipv6 routes from TGEN1 + -- "200.1.0.0" & "4000::1" with Attributes + a) community-list 1:2 + b) as-path append AS 100 + c) Origin ebgp + d) Metric 50 + -- "20.1.0.0" & "6000::1" + 3) Create route-map in DUT to permit only "200.1.0.0" + & "4000::1" based on BGP Attributes + 4) Create four flows from TGEN2 to TGEN1 + a) 'permit' -- TGEN2 to TGEN1("200.1.0.0") + b) 'permit_ipv6' -- TGEN2 to TGEN1("4000::1") + c) 'deny' -- TGEN2 to TGEN1("20.1.0.0") + d) 'deny_ipv6' -- TGEN2 to TGEN1("6000::1") + + Verification: + 1) Send traffic without applying route-map + Result: Should not observe traffic loss in 'permit' & 'deny' + 'permit_ipv6' & 'deny_ipv6' + 2) Apply route-map + Result: Should observe 100% traffic loss in 'deny' & 'deny_ipv6' + + Args: + snappi_api (pytest fixture): Snappi API + duthost (pytest fixture): duthost fixture + tgen_ports (pytest fixture): Ports mapping info of T0 testbed + conn_graph_facts (pytest fixture): connection graph + fanout_graph_facts (pytest fixture): fanout graph + """ + + tgen_ports = tgen_ports[0:2] + logger.info("|--BGP Peer Policies Test--|") + run_peer_routing_policies_test(snappi_api, + duthost, + tgen_ports) + + +# Test 2 +@pytest.mark.topology("tgen") +def test_community_list_filtering(snappi_api, + duthost, + tgen_ports, + conn_graph_facts, + fanout_graph_facts, + setup_and_teardown): + """ + Topo: + TGEN1 --- DUT --- TGEN2 + + Steps: + 1) Create BGP config on DUT and TGEN respectively + 2) Generate 2 ipv4 routes & 2 ipv6 routes from TGEN1 + -- "200.1.0.0" & "4000::1" with Community Attribute 1:2 + -- "20.1.0.0" & "6000::1" + 3) Create route-map in DUT to permit only "200.1.0.0" + & "4000::1" based on Community Attribute + 4) Create four flows from TGEN2 to TGEN1 + a) 'permit' -- TGEN2 to TGEN1("200.1.0.0") + b) 'permit_ipv6' -- TGEN2 to TGEN1("4000::1") + c) 'deny' -- TGEN2 to TGEN1("20.1.0.0") + d) 'deny_ipv6' -- TGEN2 to TGEN1("6000::1") + + Verification: + 1) Send traffic without applying route-map + Result: Should not observe traffic loss in 'permit' & 'deny' + 'permit_ipv6' & 'deny_ipv6' + 2) Apply route-map + Result: Should observe 100% traffic loss in 'deny' & 'deny_ipv6' + + Args: + snappi_api (pytest fixture): Snappi API + duthost (pytest fixture): duthost fixture + tgen_ports (pytest fixture): Ports mapping info of T0 testbed + conn_graph_facts (pytest fixture): connection graph + fanout_graph_facts (pytest fixture): fanout graph + """ + + tgen_ports = tgen_ports[0:2] + logger.info("|--BGP Community List Filtering Test--|") + run_community_list_filtering_test(snappi_api, + duthost, + tgen_ports) + + +# Test 3 +@pytest.mark.topology("tgen") +def test_prefix_list_filtering(snappi_api, + duthost, + tgen_ports, + conn_graph_facts, + fanout_graph_facts, + setup_and_teardown): + """ + Topo: + TGEN1 --- DUT --- TGEN2 + + Steps: + 1) Create BGP config on DUT and TGEN respectively + 2) Generate 2 ipv4 routes & 2 ipv6 routes from TGEN1 + -- "200.1.0.0" & "4000::1" + -- "20.1.0.0" & "6000::1" + 3) Create Prefix-list route-map in DUT to permit + only "200.1.0.0" & "4000::1" + 4) Create four flows from TGEN2 to TGEN1 + a) 'permit' -- TGEN2 to TGEN1("200.1.0.0") + b) 'permit_ipv6' -- TGEN2 to TGEN1("4000::1") + c) 'deny' -- TGEN2 to TGEN1("20.1.0.0") + d) 'deny_ipv6' -- TGEN2 to TGEN1("6000::1") + + Verification: + 1) Send traffic without applying route-map + Result: Should not observe traffic loss in 'permit' & 'deny' + 'permit_ipv6' & 'deny_ipv6' + 2) Apply route-map + Result: Should observe 100% traffic loss in 'deny' & 'deny_ipv6' + + Args: + snappi_api (pytest fixture): Snappi API + duthost (pytest fixture): duthost fixture + tgen_ports (pytest fixture): Ports mapping info of T0 testbed + conn_graph_facts (pytest fixture): connection graph + fanout_graph_facts (pytest fixture): fanout graph + """ + + tgen_ports = tgen_ports[0:2] + logger.info("|--BGP Prefix List Filtering Test--|") + run_prefix_list_filtering_test(snappi_api, + duthost, + tgen_ports) + + +# Test 4 +@pytest.mark.topology("tgen") +def test_metric_filter(snappi_api, + duthost, + tgen_ports, + conn_graph_facts, + fanout_graph_facts, + setup_and_teardown): + """ + Topo: + TGEN1 --- DUT --- TGEN2 + + Steps: + 1) Create BGP config on DUT and TGEN respectively + 2) Generate 2 ipv4 routes & 2 ipv6 routes from TGEN1 + -- "200.1.0.0" & "4000::1" with Metric 50 + -- "20.1.0.0" & "6000::1" + 3) Create route-map in DUT to permit only "200.1.0.0" + & "4000::1" based on Metric + 4) Create four flows from TGEN2 to TGEN1 + a) 'permit' -- TGEN2 to TGEN1("200.1.0.0") + b) 'permit_ipv6' -- TGEN2 to TGEN1("4000::1") + c) 'deny' -- TGEN2 to TGEN1("20.1.0.0") + d) 'deny_ipv6' -- TGEN2 to TGEN1("6000::1") + + Verification: + 1) Send traffic without applying route-map + Result: Should not observe traffic loss in 'permit' & 'deny' + 'permit_ipv6' & 'deny_ipv6' + 2) Apply route-map + Result: Should observe 100% traffic loss in 'deny' & 'deny_ipv6' + + Args: + snappi_api (pytest fixture): Snappi API + duthost (pytest fixture): duthost fixture + tgen_ports (pytest fixture): Ports mapping info of T0 testbed + conn_graph_facts (pytest fixture): connection graph + fanout_graph_facts (pytest fixture): fanout graph + """ + + tgen_ports = tgen_ports[0:2] + logger.info("|--BGP Metric Filter Test--|") + run_test_metric_filter(snappi_api, + duthost, + tgen_ports) + + +# Test 5 +@pytest.mark.topology("tgen") +def test_group_as_path_modified(snappi_api, + duthost, + tgen_ports, + conn_graph_facts, + fanout_graph_facts, + setup_and_teardown): + """ + Topo: + TGEN1 --- DUT --- TGEN2 + + Steps: + 1) Create BGP config on DUT and TGEN respectively + 2) Generate 2 ipv4 routes & 2 ipv6 routes from TGEN1 + -- "200.1.0.0" & "4000::1" with group AS + -- "20.1.0.0" & "6000::1" + 3) Create route-map in DUT to permit only "200.1.0.0" + & "4000::1" based on group AS + 4) Create four flows from TGEN2 to TGEN1 + a) 'permit' -- TGEN2 to TGEN1("200.1.0.0") + b) 'permit_ipv6' -- TGEN2 to TGEN1("4000::1") + c) 'deny' -- TGEN2 to TGEN1("20.1.0.0") + d) 'deny_ipv6' -- TGEN2 to TGEN1("6000::1") + + Verification: + 1) Send traffic without applying route-map + Result: Should not observe traffic loss in 'permit' & 'deny' + 'permit_ipv6' & 'deny_ipv6' + 2) Apply route-map + Result: Should observe 100% traffic loss in 'deny' & 'deny_ipv6' + + Args: + snappi_api (pytest fixture): Snappi API + duthost (pytest fixture): duthost fixture + tgen_ports (pytest fixture): Ports mapping info of T0 testbed + conn_graph_facts (pytest fixture): connection graph + fanout_graph_facts (pytest fixture): fanout graph + """ + + tgen_ports = tgen_ports[0:2] + logger.info("|--BGP group-as-path modified Test--|") + run_group_as_path_modified(snappi_api, + duthost, + tgen_ports) + + +# Test 6 +@pytest.mark.topology("tgen") +def test_origin_code_modification(snappi_api, + duthost, + tgen_ports, + conn_graph_facts, + fanout_graph_facts, + setup_and_teardown): + """ + Topo: + TGEN1 --- DUT --- TGEN2 + + Steps: + 1) Create BGP config on DUT and TGEN respectively + 2) Generate 2 ipv4 routes & 2 ipv6 routes from TGEN1 + -- "200.1.0.0" & "4000::1" with Origin 'egp' + -- "20.1.0.0" & "6000::1" + 3) Create route-map in DUT to permit only "200.1.0.0" + & "4000::1" based on Origin 'egp' + 4) Create four flows from TGEN2 to TGEN1 + a) 'permit' -- TGEN2 to TGEN1("200.1.0.0") + b) 'permit_ipv6' -- TGEN2 to TGEN1("4000::1") + c) 'deny' -- TGEN2 to TGEN1("20.1.0.0") + d) 'deny_ipv6' -- TGEN2 to TGEN1("6000::1") + + Verification: + 1) Send traffic without applying route-map + Result: Should not observe traffic loss in 'permit' & 'deny' + 'permit_ipv6' & 'deny_ipv6' + 2) Apply route-map + Result: Should observe 100% traffic loss in 'deny' & 'deny_ipv6' + + Args: + snappi_api (pytest fixture): Snappi API + duthost (pytest fixture): duthost fixture + tgen_ports (pytest fixture): Ports mapping info of T0 testbed + conn_graph_facts (pytest fixture): connection graph + fanout_graph_facts (pytest fixture): fanout graph + """ + + tgen_ports = tgen_ports[0:2] + logger.info("|--BGP Group-Origin Code Modifcation Test--|") + run_origin_code_modification(snappi_api, + duthost, + tgen_ports) \ No newline at end of file From fc415fdb05c41c077cf9a10c0fe7e31edb84e5e1 Mon Sep 17 00:00:00 2001 From: ANISH-GOTTAPU <48308607+ANISH-GOTTAPU@users.noreply.github.com> Date: Mon, 15 Mar 2021 20:04:13 +0530 Subject: [PATCH 07/12] Delete test_bgp_routing_policies.py updating the name --- tests/ixia/bgp/test_bgp_routing_policies.py | 319 -------------------- 1 file changed, 319 deletions(-) delete mode 100755 tests/ixia/bgp/test_bgp_routing_policies.py diff --git a/tests/ixia/bgp/test_bgp_routing_policies.py b/tests/ixia/bgp/test_bgp_routing_policies.py deleted file mode 100755 index 4c2aabdca9a..00000000000 --- a/tests/ixia/bgp/test_bgp_routing_policies.py +++ /dev/null @@ -1,319 +0,0 @@ -import pytest -import logging -from tests.common.ixia.ixia_fixtures import snappi_api -from tests.common.ixia.ixia_fixtures import ( - ixia_api_serv_ip, ixia_api_serv_port, tgen_ports) -from files.helper import ( - run_bgp_peer_routing_policies_test, run_bgp_community_test, - run_bgp_prefix_list_test, run_bgp_metric_filter, - run_bgp_group_as_path_modified, run_bgp_origin_code_modification, - config_setup, config_cleanup) -from tests.common.fixtures.conn_graph_facts import ( - conn_graph_facts, fanout_graph_facts) -logger = logging.getLogger(__name__) - - -@pytest.fixture(scope="module") -def setup_and_teardown(duthost, - tgen_ports): - """ - Setup and Teardown - """ - # We are going to use first two ports for all these tests - tgen_ports = tgen_ports[0:2] - logger.info("|--Common Setup Configuration--|") - config_setup(duthost, - tgen_ports) - yield - logger.info("|--Common Cleanup--|") - config_cleanup(duthost, - tgen_ports) - - -# Test 1 -@pytest.mark.topology("tgen") -def test_bgp_peer_routing_policies(snappi_api, - duthost, - tgen_ports, - conn_graph_facts, - fanout_graph_facts, - setup_and_teardown): - """ - Topo: - TGEN1 --- DUT --- TGEN2 - - Steps: - 1) Create BGP config on DUT and TGEN respectively - 2) Generate 2 ipv4 routes & 2 ipv6 routes from TGEN1 - -- "200.1.0.0" & "4000::1" with Attributes - a) community-list 1:2 - b) as-path append AS 100 - c) Origin ebgp - d) Metric 50 - -- "20.1.0.0" & "6000::1" - 3) Create route policy in DUT to permit only "200.1.0.0" - & "4000::1" based on BGP Attributes - 4) Create two flows from TGEN2 to TGEN1 - a) 'permit' -- TGEN2 to TGEN1("200.1.0.0") - b) 'permit_ipv6' -- TGEN2 to TGEN1("4000::1") - c) 'deny' -- TGEN2 to TGEN1("20.1.0.0") - d) 'deny_ipv6' -- TGEN2 to TGEN1("6000::1") - - Verification: - 1) Send traffic without applying route-map - Result: Should not observe traffic loss in 'permit' & 'deny' - 'permit_ipv6' & 'deny_ipv6' - 2) Apply route-map - Result: Should observe 100% traffic loss in 'deny' & 'deny_ipv6' - - Args: - snappi_api (pytest fixture): Snappi API - duthost (pytest fixture): duthost fixture - tgen_ports (pytest fixture): Ports mapping info of T0 testbed - conn_graph_facts (pytest fixture): connection graph - fanout_graph_facts (pytest fixture): fanout graph - """ - - tgen_ports = tgen_ports[0:2] - logger.info("|--BGP Peer Policies Test--|") - run_bgp_peer_routing_policies_test(snappi_api, - duthost, - tgen_ports) - - -# Test 2 -@pytest.mark.topology("tgen") -def test_bgp_community(snappi_api, - duthost, - tgen_ports, - conn_graph_facts, - fanout_graph_facts, - setup_and_teardown): - """ - Topo: - TGEN1 --- DUT --- TGEN2 - - Steps: - 1) Create BGP config on DUT and TGEN respectively - 2) Generate 2 ipv4 routes & 2 ipv6 routes from TGEN1 - -- "200.1.0.0" & "4000::1" with Community Attribute 1:2 - -- "20.1.0.0" & "6000::1" - 3) Create route policy in DUT to permit only "200.1.0.0" - & "4000::1" based on Community Attribute - 4) Create two flows from TGEN2 to TGEN1 - a) 'permit' -- TGEN2 to TGEN1("200.1.0.0") - b) 'permit_ipv6' -- TGEN2 to TGEN1("4000::1") - c) 'deny' -- TGEN2 to TGEN1("20.1.0.0") - d) 'deny_ipv6' -- TGEN2 to TGEN1("6000::1") - - Verification: - 1) Send traffic without applying route-map - Result: Should not observe traffic loss in 'permit' & 'deny' - 'permit_ipv6' & 'deny_ipv6' - 2) Apply route-map - Result: Should observe 100% traffic loss in 'deny' & 'deny_ipv6' - - Args: - snappi_api (pytest fixture): Snappi API - duthost (pytest fixture): duthost fixture - tgen_ports (pytest fixture): Ports mapping info of T0 testbed - conn_graph_facts (pytest fixture): connection graph - fanout_graph_facts (pytest fixture): fanout graph - """ - - tgen_ports = tgen_ports[0:2] - logger.info("|--BGP Community List Filtering Test--|") - run_bgp_community_test(snappi_api, - duthost, - tgen_ports) - - -# Test 3 -@pytest.mark.topology("tgen") -def test_bgp_prefix_list_filter(snappi_api, - duthost, - tgen_ports, - conn_graph_facts, - fanout_graph_facts, - setup_and_teardown): - """ - Topo: - TGEN1 --- DUT --- TGEN2 - - Steps: - 1) Create BGP config on DUT and TGEN respectively - 2) Generate 2 ipv4 routes & 2 ipv6 routes from TGEN1 - -- "200.1.0.0" & "4000::1" - -- "20.1.0.0" & "6000::1" - 3) Create Prefix-list route map in DUT to permit - only "200.1.0.0" & "4000::1" - 4) Create two flows from TGEN2 to TGEN1 - a) 'permit' -- TGEN2 to TGEN1("200.1.0.0") - b) 'permit_ipv6' -- TGEN2 to TGEN1("4000::1") - c) 'deny' -- TGEN2 to TGEN1("20.1.0.0") - d) 'deny_ipv6' -- TGEN2 to TGEN1("6000::1") - - Verification: - 1) Send traffic without applying route-map - Result: Should not observe traffic loss in 'permit' & 'deny' - 'permit_ipv6' & 'deny_ipv6' - 2) Apply route-map - Result: Should observe 100% traffic loss in 'deny' & 'deny_ipv6' - - Args: - snappi_api (pytest fixture): Snappi API - duthost (pytest fixture): duthost fixture - tgen_ports (pytest fixture): Ports mapping info of T0 testbed - conn_graph_facts (pytest fixture): connection graph - fanout_graph_facts (pytest fixture): fanout graph - """ - - tgen_ports = tgen_ports[0:2] - logger.info("|--BGP Prefix List Filtering Test--|") - run_bgp_prefix_list_test(snappi_api, - duthost, - tgen_ports) - - -# Test 4 -@pytest.mark.topology("tgen") -def test_bgp_metric_filter(snappi_api, - duthost, - tgen_ports, - conn_graph_facts, - fanout_graph_facts, - setup_and_teardown): - """ - # TODO: update the description - Topo: - TGEN1 --- DUT --- TGEN2 - - Steps: - 1) Create BGP config on DUT and TGEN respectively - 2) Generate 2 ipv4 routes & 2 ipv6 routes from TGEN1 - -- "200.1.0.0" & "4000::1" with Metric 50 - -- "20.1.0.0" & "6000::1" - 3) Create route policy in DUT to permit only "200.1.0.0" - & "4000::1" based on Metric - 4) Create two flows from TGEN2 to TGEN1 - a) 'permit' -- TGEN2 to TGEN1("200.1.0.0") - b) 'permit_ipv6' -- TGEN2 to TGEN1("4000::1") - c) 'deny' -- TGEN2 to TGEN1("20.1.0.0") - d) 'deny_ipv6' -- TGEN2 to TGEN1("6000::1") - - Verification: - 1) Send traffic without applying route-map - Result: Should not observe traffic loss in 'permit' & 'deny' - 'permit_ipv6' & 'deny_ipv6' - 2) Apply route-map - Result: Should observe 100% traffic loss in 'deny' & 'deny_ipv6' - - Args: - snappi_api (pytest fixture): Snappi API - duthost (pytest fixture): duthost fixture - tgen_ports (pytest fixture): Ports mapping info of T0 testbed - conn_graph_facts (pytest fixture): connection graph - fanout_graph_facts (pytest fixture): fanout graph - """ - - tgen_ports = tgen_ports[0:2] - logger.info("|--BGP Metric Filter Test--|") - run_bgp_metric_filter(snappi_api, - duthost, - tgen_ports) - - -# Test 5 -@pytest.mark.topology("tgen") -def test_bgp_group_as_path_modified(snappi_api, - duthost, - tgen_ports, - conn_graph_facts, - fanout_graph_facts, - setup_and_teardown): - """ - # TODO: update the description - Topo: - TGEN1 --- DUT --- TGEN2 - - Steps: - 1) Create BGP config on DUT and TGEN respectively - 2) Generate 2 ipv4 routes & 2 ipv6 routes from TGEN1 - -- "200.1.0.0" & "4000::1" with group AS - -- "20.1.0.0" & "6000::1" - 3) Create route policy in DUT to permit only "200.1.0.0" - & "4000::1" based on group AS - 4) Create two flows from TGEN2 to TGEN1 - a) 'permit' -- TGEN2 to TGEN1("200.1.0.0") - b) 'permit_ipv6' -- TGEN2 to TGEN1("4000::1") - c) 'deny' -- TGEN2 to TGEN1("20.1.0.0") - d) 'deny_ipv6' -- TGEN2 to TGEN1("6000::1") - - Verification: - 1) Send traffic without applying route-map - Result: Should not observe traffic loss in 'permit' & 'deny' - 'permit_ipv6' & 'deny_ipv6' - 2) Apply route-map - Result: Should observe 100% traffic loss in 'deny' & 'deny_ipv6' - - Args: - snappi_api (pytest fixture): Snappi API - duthost (pytest fixture): duthost fixture - tgen_ports (pytest fixture): Ports mapping info of T0 testbed - conn_graph_facts (pytest fixture): connection graph - fanout_graph_facts (pytest fixture): fanout graph - """ - - tgen_ports = tgen_ports[0:2] - logger.info("|--BGP group-as-path modified Test--|") - run_bgp_group_as_path_modified(snappi_api, - duthost, - tgen_ports) - - -# Test 6 -@pytest.mark.topology("tgen") -def test_bgp_origin_code_modification(snappi_api, - duthost, - tgen_ports, - conn_graph_facts, - fanout_graph_facts, - setup_and_teardown): - """ - # TODO: update the description - Topo: - TGEN1 --- DUT --- TGEN2 - - Steps: - 1) Create BGP config on DUT and TGEN respectively - 2) Generate 2 ipv4 routes & 2 ipv6 routes from TGEN1 - -- "200.1.0.0" & "4000::1" with Origin 'egp' - -- "20.1.0.0" & "6000::1" - 3) Create route policy in DUT to permit only "200.1.0.0" - & "4000::1" based on Origin 'egp' - 4) Create two flows from TGEN2 to TGEN1 - a) 'permit' -- TGEN2 to TGEN1("200.1.0.0") - b) 'permit_ipv6' -- TGEN2 to TGEN1("4000::1") - c) 'deny' -- TGEN2 to TGEN1("20.1.0.0") - d) 'deny_ipv6' -- TGEN2 to TGEN1("6000::1") - - Verification: - 1) Send traffic without applying route-map - Result: Should not observe traffic loss in 'permit' & 'deny' - 'permit_ipv6' & 'deny_ipv6' - 2) Apply route-map - Result: Should observe 100% traffic loss in 'deny' & 'deny_ipv6' - - Args: - snappi_api (pytest fixture): Snappi API - duthost (pytest fixture): duthost fixture - tgen_ports (pytest fixture): Ports mapping info of T0 testbed - conn_graph_facts (pytest fixture): connection graph - fanout_graph_facts (pytest fixture): fanout graph - """ - - tgen_ports = tgen_ports[0:2] - logger.info("|--BGP Group-Origin Code Modifcation Test--|") - run_bgp_origin_code_modification(snappi_api, - duthost, - tgen_ports) \ No newline at end of file From 2c021f143512a6bd20e9c3093a1671ee2a154de2 Mon Sep 17 00:00:00 2001 From: "ruijie.com.cn" Date: Thu, 29 Apr 2021 14:40:23 +0800 Subject: [PATCH 08/12] Revert "Routing Policy Tests" --- docs/testplan/routing_policies.md | 245 ------ tests/common/ixia/common_helpers.py | 28 - tests/common/ixia/ixia_fixtures.py | 111 +-- tests/ixia/bgp/files/__init__.py | 1 - tests/ixia/bgp/files/helper.py | 1033 ----------------------- tests/ixia/bgp/test_routing_policies.py | 316 ------- 6 files changed, 1 insertion(+), 1733 deletions(-) delete mode 100644 docs/testplan/routing_policies.md mode change 100755 => 100644 tests/common/ixia/ixia_fixtures.py delete mode 100644 tests/ixia/bgp/files/__init__.py delete mode 100755 tests/ixia/bgp/files/helper.py delete mode 100755 tests/ixia/bgp/test_routing_policies.py diff --git a/docs/testplan/routing_policies.md b/docs/testplan/routing_policies.md deleted file mode 100644 index ffe7abfa6ce..00000000000 --- a/docs/testplan/routing_policies.md +++ /dev/null @@ -1,245 +0,0 @@ -# Routing policies test plan - -- [Routing Policies testplan](#bgp-routing-policies-testplan) - - [Overview](#Overview) - - [Scope](#Scope) - - [Testbed](#Keysight-Testbed) - - [Topology](#Topology) - - [Test methodology](#Test-methodology) - - [Test cases](#Test-cases) - - [Test case # 1 – Peer Routing Policies](#test-case--1--peer-routing-policies) - - [Test objective](#Test-objective) - - [Test steps](#Test-steps) - - [Test results](#Test-results) - - [Test case # 2 – Community List Filtering](#test-case--2--community-list-filtering) - - [Test objective](#Test-objective-1) - - [Test steps](#Test-steps-1) - - [Test results](#Test-results-1) - - [Test case # 3 – Prefix List Filtering](#test-case--3--prefix-list-filtering) - - [Test objective](#Test-objective-2) - - [Test steps](#Test-steps-2) - - [Test results](#Test-results-2) - - [Test case # 4 – Metric Filter](#test-case--4--metric-filter) - - [Test objective](#Test-objective-3) - - [Test steps](#Test-steps-3) - - [Test results](#Test-results-3) - - [Test case # 5 – Group-As-Path Modified](#test-case--5--group-as-path-modified) - - [Test objective](#Test-objective-4) - - [Test steps](#Test-steps-4) - - [Test results](#Test-results-4) - - [Test case # 6 – Group Origin Code Modification](#test-case--6--group-origin-code-modification) - - [Test objective](#Test-objective-5) - - [Test steps](#Test-steps-5) - - [Test results](#Test-results-5) - - -## Overview -The purpose of these tests is to evaluate the BGP Routing Policies Using Match Conditions and Actions. The routing policy consists of multiple terms. Each term consists of match conditions and actions to apply to matching routes. - -### Scope -These tests are targeted on fully functioning SONiC system. The purpose of these tests are to evaluate the BGP Routing Policies Using Match Conditions and Actions. - -### Keysight Testbed -The tests will run on following testbeds: -* t0 - -![Single DUT Topology ](Img/Single_DUT_Topology.png) - -## Topology - -``` - _________ - | | -IXIA TGEN1 -------- | DUT |------ IXIA TGEN2 - |_________| -``` - -## Test Methodology -Following test methodology will be used to evaluate routing policies. -* Traffic generator will be used to configure ebgp peering between TGEN1 and SONiC DUT by advertising IPv4/IPv6, dual-stack routes. -* Advertise 2 IPv4 and 2 IPv6 routes from TGEN1. -* Create four flows from TGEN2 to TGEN1 - 1. `permit` -- TGEN2 to TGEN1("200.1.0.0") - 2. `permit_ipv6` -- TGEN2 to TGEN1("4000::1") - 3. `deny` -- TGEN2 to TGEN1("20.1.0.0") - 4. `deny_ipv6` -- TGEN2 to TGEN1("6000::1") -* update the BGP attributes as per route policy for route in `permit` & `permit_ipv6` -and validate the actions applied to match routes. - - -## Test cases -### Test case # 1 – Peer Routing Policies -#### Test objective -Routing policy in the DUT match conditions with BGP attributes (community, as-path, metric, origin) and permit the routes. - - -#### Test steps -1. Configure BGP between DUT and TGEN1. -2. Generate 2 ipv4 routes & 2 ipv6 routes from TGEN1 via BGP. - - 1. "200.1.0.0" & "4000::1" with Attributes - a) community-list 1:2 - b) as-path append AS 100 - c) Origin ebgp - d) Metric 50 - 2. "20.1.0.0" & "6000::1" without Attributes -3. Create route-map in DUT to permit only `200.1.0.0` - & `4000::1` based on BGP Attributes -4. Create four flows from TGEN2 to TGEN1 - - 1) permit -- TGEN2 to TGEN1("200.1.0.0") - 2) permit_ipv6 -- TGEN2 to TGEN1("4000::1") - 3) deny -- TGEN2 to TGEN1("20.1.0.0") - 4) deny_ipv6 -- TGEN2 to TGEN1("6000::1") - -#### Test results -1. Send traffic without applying route-map - - Result: Should not observe traffic loss in the flows 'permit','deny','permit_ipv6' & 'deny_ipv6' -2. Apply route-map - - Result: Should observe 100% traffic loss in the flows 'deny' & 'deny_ipv6' - - -### Test case # 2 – Community List Filtering -#### Test objective -Routing policy in the DUT match conditions with BGP Community and permit the routes with Community. - - -#### Test steps -1. Configure BGP between DUT and TGEN1. -2. Generate 2 ipv4 routes & 2 ipv6 routes from TGEN1 via BGP. - - 1. "200.1.0.0" & "4000::1" with Community List - 2. "20.1.0.0" & "6000::1" without Community List -3. Create route-map in DUT to permit only `200.1.0.0` - & `4000::1` based on BGP Community List -4. Create four flows from TGEN2 to TGEN1 - - 1) permit -- TGEN2 to TGEN1("200.1.0.0") - 2) permit_ipv6 -- TGEN2 to TGEN1("4000::1") - 3) deny -- TGEN2 to TGEN1("20.1.0.0") - 4) deny_ipv6 -- TGEN2 to TGEN1("6000::1") - -#### Test results -1. Send traffic without applying route-map - - Result: Should not observe traffic loss in the flows 'permit', 'deny', 'permit_ipv6' & 'deny_ipv6' -2. Apply route-map - - Result: Should observe 100% traffic loss in the flows 'deny' & 'deny_ipv6' - -### Test case # 3 – Prefix List Filtering -#### Test objective -Routing policy in the DUT match conditions with Prefix-list and permit based on Prefix List Filtering. - - -#### Test steps -1. Configure BGP between DUT and TGEN1. -2. Generate 2 ipv4 routes & 2 ipv6 routes from TGEN1 via BGP. - - 1. "200.1.0.0" & "4000::1" - 2. "20.1.0.0" & "6000::1" -3. Create Prefix-list route-map in DUT to permit only `200.1.0.0` - & `4000::1` -4. Create four flows from TGEN2 to TGEN1 - - 1) permit -- TGEN2 to TGEN1("200.1.0.0") - 2) permit_ipv6 -- TGEN2 to TGEN1("4000::1") - 3) deny -- TGEN2 to TGEN1("20.1.0.0") - 4) deny_ipv6 -- TGEN2 to TGEN1("6000::1") - -#### Test results -1. Send traffic without applying route-map - - Result: Should not observe traffic loss in the flows 'permit','deny','permit_ipv6' & 'deny_ipv6' -2. Apply route-map - - Result: Should observe 100% traffic loss in the flows 'deny' & 'deny_ipv6' - - -### Test case # 4 – Metric Filter -#### Test objective -Routing policy in the DUT match conditions with Metric and permit based on Metric Filtering. - - -#### Test steps -1. Configure BGP between DUT and TGEN1. -2. Generate 2 ipv4 routes & 2 ipv6 routes from TGEN1 via BGP. - - 1."200.1.0.0" & "4000::1" with Metric 50 - 2."20.1.0.0" & "6000::1" with default Metric -3. Create route-map in DUT to permit only `200.1.0.0` - & `4000::1` with Metric 50 -4. Create four flows from TGEN2 to TGEN1 - - 1) permit -- TGEN2 to TGEN1("200.1.0.0") - 2) permit_ipv6 -- TGEN2 to TGEN1("4000::1") - 3) deny -- TGEN2 to TGEN1("20.1.0.0") - 4) deny_ipv6 -- TGEN2 to TGEN1("6000::1") - -#### Test results -1. Send traffic without applying route-map - - Result: Should not observe traffic loss in the flows 'permit','deny','permit_ipv6' & 'deny_ipv6' -2. Apply route-map - - Result: Should observe 100% traffic loss in the flows 'deny' & 'deny_ipv6' - - -### Test case # 5 – Group-As-Path Modified -#### Test objective -Routing policy in the DUT match conditions with group-as-path and permit based on group-as-path Modification. - - -#### Test steps -1. Configure BGP between DUT and TGEN1. -2. Generate 2 ipv4 routes & 2 ipv6 routes from TGEN1 via BGP. - - 1."200.1.0.0" & "4000::1" with group AS 100 - 2."20.1.0.0" & "6000::1" without group AS 100 -3. Create route-map in DUT to permit only `200.1.0.0` - & `4000::1` with group AS 100 -4. Create four flows from TGEN2 to TGEN1 - - 1) permit -- TGEN2 to TGEN1("200.1.0.0") - 2) permit_ipv6 -- TGEN2 to TGEN1("4000::1") - 3) deny -- TGEN2 to TGEN1("20.1.0.0") - 4) deny_ipv6 -- TGEN2 to TGEN1("6000::1") - -#### Test results -1. Send traffic without applying route-map - - Result: Should not observe traffic loss in the flows 'permit','deny','permit_ipv6' & 'deny_ipv6' -2. Apply route-map - - Result: Should observe 100% traffic loss in the flows 'deny' & 'deny_ipv6' - - -### Test case # 6 – Group Origin Code Modification -#### Test objective -Routing policy in the DUT match conditions with Origin and permit based on Origin - - -#### Test steps -1. Configure BGP between DUT and TGEN1. -2. Generate 2 ipv4 routes & 2 ipv6 routes from TGEN1 via BGP. - - 1."200.1.0.0" & "4000::1" with Origin 'egp' - 2."20.1.0.0" & "6000::1" -3. Create route-map in DUT to permit only `200.1.0.0` - & `4000::1` with Origin 'egp' -4. Create four flows from TGEN2 to TGEN1 - - 1) permit -- TGEN2 to TGEN1("200.1.0.0") - 2) permit_ipv6 -- TGEN2 to TGEN1("4000::1") - 3) deny -- TGEN2 to TGEN1("20.1.0.0") - 4) deny_ipv6 -- TGEN2 to TGEN1("6000::1") - -#### Test results -1. Send traffic without applying route-map - - Result: Should not observe traffic loss in the flows 'permit','deny','permit_ipv6' & 'deny_ipv6' -2. Apply route-map - - Result: Should observe 100% traffic loss in the flows 'deny' & 'deny_ipv6' diff --git a/tests/common/ixia/common_helpers.py b/tests/common/ixia/common_helpers.py index a2a2e5e017d..b38d4beb9cb 100644 --- a/tests/common/ixia/common_helpers.py +++ b/tests/common/ixia/common_helpers.py @@ -13,8 +13,6 @@ import ipaddr from netaddr import IPNetwork -from ipaddress import IPv6Network, IPv6Address -from random import getrandbits from tests.common.mellanox_data import is_mellanox_device as isMellanoxDevice def increment_ip_address (ip, incr=1) : @@ -121,32 +119,6 @@ def get_addrs_in_subnet(subnet, number_of_ip): return ip_addrs[:number_of_ip] - -def get_ipv6_addrs_in_subnet(subnet, number_of_ip): - """ - Get N IPv6 addresses in a subnet. - - Args: - subnet (str): IPv6 subnet, e.g., '2001::1/64' - number_of_ip (int): Number of IP addresses to get - - Return: - Return n IPv6 addresses in this subnet in a list. - """ - - subnet = str(IPNetwork(subnet).network) + "/" + str(subnet.split("/")[1]) - subnet = unicode(subnet, "utf-8") - ipv6_list = [] - for i in range(number_of_ip): - network = IPv6Network(subnet) - address = IPv6Address( - network.network_address + getrandbits( - network.max_prefixlen - network.prefixlen)) - ipv6_list.append(str(address)) - - return ipv6_list - - def get_peer_ixia_chassis(conn_data, dut_hostname): """ Get the IXIA chassis connected to the DUT diff --git a/tests/common/ixia/ixia_fixtures.py b/tests/common/ixia/ixia_fixtures.py old mode 100755 new mode 100644 index 91cca96d01e..5b04c2f7783 --- a/tests/common/ixia/ixia_fixtures.py +++ b/tests/common/ixia/ixia_fixtures.py @@ -9,9 +9,8 @@ from tests.common.fixtures.conn_graph_facts import conn_graph_facts,\ fanout_graph_facts from tests.common.ixia.common_helpers import get_vlan_subnet, get_addrs_in_subnet,\ - get_peer_ixia_chassis, get_ipv6_addrs_in_subnet + get_peer_ixia_chassis from tests.common.ixia.ixia_helpers import IxiaFanoutManager, get_tgen_location -import snappi try: from abstract_open_traffic_generator.port import Port @@ -295,111 +294,3 @@ def ixia_testbed(conn_graph_facts, config.devices.append(device) return config - - -@pytest.fixture(scope='module') -def snappi_api(ixia_api_serv_ip, - ixia_api_serv_port): - """ - Snappi session fixture for snappi Tgen API - - Args: - ixia_api_serv_ip (pytest fixture): ixia_api_serv_ip fixture - ixia_api_serv_port (pytest fixture): ixia_api_serv_port fixture. - """ - host = "https://" + ixia_api_serv_ip + ":" + str(ixia_api_serv_port) - api = snappi.api(host=host, ext="ixnetwork") - - yield api - - if api.assistant is not None: - api.assistant.Session.remove() - - -@pytest.fixture(scope="module") -def tgen_ports(duthost, - conn_graph_facts, - fanout_graph_facts): - - """ - Populate tgen ports info of T0 testbed and returns as a list - - Args: - duthost (pytest fixture): duthost fixture - conn_graph_facts (pytest fixture): connection graph - fanout_graph_facts (pytest fixture): fanout graph - - Return: - [{'card_id': '1', - 'ip': '22.1.1.2', - 'ipv6': '3001::2', - 'ipv6_prefix': u'64', - 'location': '10.36.78.238;1;2', - 'peer_device': 'sonic-s6100-dut', - 'peer_ip': u'22.1.1.1', - 'peer_ipv6': u'3001::1', - 'peer_port': 'Ethernet8', - 'port_id': '2', - 'prefix': u'24', - 'speed': 'speed_400_gbps'}, - {'card_id': '1', - 'ip': '21.1.1.2', - 'ipv6': '2001::2', - 'ipv6_prefix': u'64', - 'location': '10.36.78.238;1;1', - 'peer_device': 'sonic-s6100-dut', - 'peer_ip': u'21.1.1.1', - 'peer_ipv6': u'2001::1', - 'peer_port': 'Ethernet0', - 'port_id': '1', - 'prefix': u'24', - 'speed': 'speed_400_gbps'}] - """ - - speed_type = {'50000': 'speed_50_gbps', - '100000': 'speed_100_gbps', - '200000': 'speed_200_gbps', - '400000': 'speed_400_gbps'} - - ixia_fanout = get_peer_ixia_chassis(conn_data=conn_graph_facts, - dut_hostname=duthost.hostname) - ixia_fanout_id = list(fanout_graph_facts.keys()).index(ixia_fanout) - ixia_fanout_list = IxiaFanoutManager(fanout_graph_facts) - ixia_fanout_list.get_fanout_device_details(device_number=ixia_fanout_id) - ixia_ports = ixia_fanout_list.get_ports(peer_device=duthost.hostname) - port_speed = None - - for i in range(len(ixia_ports)): - if port_speed is None: - port_speed = int(ixia_ports[i]['speed']) - - elif port_speed != int(ixia_ports[i]['speed']): - """ All the ports should have the same bandwidth """ - return None - - config_facts = duthost.config_facts(host=duthost.hostname, - source="running")['ansible_facts'] - - for port in ixia_ports: - port['location'] = get_tgen_location(port) - port['speed'] = speed_type[port['speed']] - - for port in ixia_ports: - - peer_port = port['peer_port'] - int_addrs = config_facts['INTERFACE'][peer_port].keys() - ipv4_subnet = [ele for ele in int_addrs if "." in ele][0] - ipv6_subnet = [ele for ele in int_addrs if ":" in ele][0] - if not ipv4_subnet: - raise Exception("IPv4 is not configured on the interface {}" - .format(peer_port)) - port['peer_ip'], port['prefix'] = ipv4_subnet.split("/") - port['ip'] = get_addrs_in_subnet(ipv4_subnet, 1)[0] - - if not ipv6_subnet: - raise Exception("IPv6 is not configured on the interface {}" - .format(peer_port)) - port['peer_ipv6'], port['ipv6_prefix'] = ipv6_subnet.split("/") - port['ipv6'] = get_ipv6_addrs_in_subnet(ipv6_subnet, 1)[0] - - return ixia_ports diff --git a/tests/ixia/bgp/files/__init__.py b/tests/ixia/bgp/files/__init__.py deleted file mode 100644 index 65d74fc0a6b..00000000000 --- a/tests/ixia/bgp/files/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# Local library for BGP tests. \ No newline at end of file diff --git a/tests/ixia/bgp/files/helper.py b/tests/ixia/bgp/files/helper.py deleted file mode 100755 index d80a0d87e9c..00000000000 --- a/tests/ixia/bgp/files/helper.py +++ /dev/null @@ -1,1033 +0,0 @@ -from tests.common.helpers.assertions import pytest_assert -from tests.common.utilities import wait_until -import logging - -logger = logging.getLogger(__name__) - -DUT_AS_NUM = 10086 -TGEN_AS_NUM = 501 -BGP_TYPE = 'ebgp' -PACKETS = 100000 -LINE_RATE = 1 -COMMUNITY = "1:2" -MED = 50 -GROUP_AS = [100] - - -def config_setup(duthost, - tgen_ports): - """ - BGP Config on duthost - - Args: - duthost (pytest fixture): duthost fixture - tgen_ports (pytest fixture): Ports mapping info of T0 testbed - """ - logger.info("|--Remove Any Existing BGP Process on DUT--|") - try: - duthost.shell( - "vtysh " - "-c 'configure terminal' " - "-c 'no router bgp' " - ) - except Exception: - logger.info("No BGP process is configured") - - logger.info("|--Interface Configuration On DUT--|") - intf1_config = ( - "vtysh " - "-c 'configure terminal' " - "-c 'interface %s' " - "-c 'ip address %s/%s' " - ) - intf1_config %= (tgen_ports[0]['peer_port'], - tgen_ports[0]['peer_ip'], - tgen_ports[0]['prefix']) - duthost.shell(intf1_config) - - intf2_config = ( - "vtysh " - "-c 'configure terminal' " - "-c 'interface %s' " - "-c 'ip address %s/%s' " - ) - intf2_config %= (tgen_ports[1]['peer_port'], - tgen_ports[1]['peer_ip'], - tgen_ports[1]['prefix']) - duthost.shell(intf2_config) - - # ipv6 interface config - intf1_v6_config = ( - "vtysh " - "-c 'configure terminal' " - "-c 'interface %s' " - "-c 'ipv6 address %s/%s' " - ) - intf1_v6_config %= (tgen_ports[0]['peer_port'], - tgen_ports[0]['peer_ipv6'], - tgen_ports[0]['ipv6_prefix']) - duthost.shell(intf1_v6_config) - - intf2_v6_config = ( - "vtysh " - "-c 'configure terminal' " - "-c 'interface %s' " - "-c 'ipv6 address %s/%s' " - ) - intf2_v6_config %= (tgen_ports[1]['peer_port'], - tgen_ports[1]['peer_ipv6'], - tgen_ports[1]['ipv6_prefix']) - duthost.shell(intf2_v6_config) - - logger.info("|--BGP Configuration On DUT--|") - bgp_config = ( - "vtysh " - "-c 'configure terminal' " - "-c 'router bgp %s' " - "-c 'no bgp default ipv4-unicast' " - "-c 'no bgp ebgp-requires-policy' " - "-c 'neighbor LC peer-group' " - "-c 'neighbor LC remote-as %s' " - "-c 'neighbor %s peer-group LC' " - "-c 'address-family ipv4 unicast' " - "-c 'neighbor %s activate' " - ) - bgp_config %= (DUT_AS_NUM, - TGEN_AS_NUM, - tgen_ports[0]['ip'], - tgen_ports[0]['ip']) - duthost.shell(bgp_config) - - bgpv6_config = ( - "vtysh " - "-c 'configure terminal' " - "-c 'router bgp %s' " - "-c 'neighbor LCv6 peer-group' " - "-c 'neighbor LCv6 remote-as %s' " - "-c 'neighbor %s peer-group LCv6' " - "-c 'address-family ipv6 unicast' " - "-c 'neighbor %s activate' " - ) - bgpv6_config %= (DUT_AS_NUM, - TGEN_AS_NUM, - tgen_ports[0]['ipv6'], - tgen_ports[0]['ipv6']) - duthost.shell(bgpv6_config) - - # ipv6 next hop route-map - next_hop = ( - "vtysh " - "-c 'configure terminal' " - "-c 'route-map NEXTHOP permit 1' " - "-c 'on-match next' " - "-c 'set ipv6 next-hop prefer-global' " - "-c 'router bgp %s' " - "-c 'address-family ipv6 unicast' " - "-c 'neighbor LCv6 route-map NEXTHOP in' " - ) - next_hop %= (DUT_AS_NUM) - duthost.shell(next_hop) - - -def run_peer_routing_policies_test(snappi_api, - duthost, - tgen_ports): - """ - Run BGP Peer Routing Policies Test - - Args: - snappi_api (pytest fixture): Snappi API - duthost (pytest fixture): duthost fixture - tgen_ports (pytest fixture): Ports mapping info of T0 testbed - """ - logger.info("|--Create BGP TGEN Configuration--|") - tgen_bgp_config = __tgen_bgp_config(snappi_api, - tgen_ports) - - logger.info("|--Updating TGEN Config with BGP Route Attributes--|") - tgen_policies_config = __tgen_policies_config(tgen_bgp_config) - - logger.info("|--BGP Policy Route Map Configuration on DUT--|") - __policies_route_map_config(duthost) - - logger.info("|--Verify Test--|") - __verify_test(duthost, - snappi_api, - tgen_policies_config) - - -def run_community_list_filtering_test(snappi_api, - duthost, - tgen_ports): - """ - Run BGP Community List Filtering Test - - Args: - snappi_api (pytest fixture): Snappi API - duthost (pytest fixture): duthost fixture - tgen_ports (pytest fixture): Ports mapping info of T0 testbed - """ - logger.info("|--Create BGP TGEN Configuration--|") - tgen_bgp_config = __tgen_bgp_config(snappi_api, - tgen_ports) - - logger.info("|--Updating TGEN Config with BGP Community Attribute--|") - tgen_community_config = __tgen_community_config(tgen_bgp_config) - - logger.info("|--BGP Community Route Map Configuration on DUT--|") - __community_route_map_config(duthost) - - logger.info("|--Verify Test--|") - __verify_test(duthost, - snappi_api, - tgen_community_config) - - -def run_prefix_list_filtering_test(snappi_api, - duthost, - tgen_ports): - """ - Run BGP Prefix List Filtering Test - - Args: - snappi_api (pytest fixture): Snappi API - duthost (pytest fixture): duthost fixture - tgen_ports (pytest fixture): Ports mapping info of T0 testbed - """ - logger.info("|--Create BGP TGEN Configuration--|") - tgen_bgp_config = __tgen_bgp_config(snappi_api, - tgen_ports) - - logger.info("|--BGP Prefix List Route Map Configuration on DUT--|") - __prefix_list_route_map_config(duthost) - - logger.info("|--Verify Test--|") - __verify_test(duthost, - snappi_api, - tgen_bgp_config) - - -def run_test_metric_filter(snappi_api, - duthost, - tgen_ports): - """ - Run BGP Metric Filter Test - - Args: - snappi_api (pytest fixture): Snappi API - duthost (pytest fixture): duthost fixture - tgen_ports (pytest fixture): Ports mapping info of T0 testbed - """ - - logger.info("|--Create BGP TGEN Configuration--|") - tgen_bgp_config = __tgen_bgp_config(snappi_api, - tgen_ports) - - logger.info("|--Updating TGEN Config with Metric/MED Attribute--|") - tgen_metric_config = __tgen_metric_config(tgen_bgp_config) - - logger.info("|--BGP Metric Route Map Configuration on DUT--|") - __metric_route_map_config(duthost) - - logger.info("|--Verify Test--|") - __verify_test(duthost, - snappi_api, - tgen_metric_config) - - -def run_group_as_path_modified(snappi_api, - duthost, - tgen_ports): - """ - Run BGP group-as-path Modified Test - - Args: - snappi_api (pytest fixture): Snappi API - duthost (pytest fixture): duthost fixture - tgen_ports (pytest fixture): Ports mapping info of T0 testbed - """ - logger.info("|--Create BGP TGEN Configuration--|") - tgen_bgp_config = __tgen_bgp_config(snappi_api, - tgen_ports) - - logger.info("|--Updating TGEN Config with Group AS-PATH Attribute--|") - tgen_as_path_modified_config = __tgen_as_path_modified_config( - tgen_bgp_config) - - logger.info("|--BGP AS-PATH Route Map Configuration on DUT--|") - __as_path_route_map_config(duthost) - - logger.info("|--Verify Test--|") - __verify_test(duthost, - snappi_api, - tgen_as_path_modified_config) - - -def run_origin_code_modification(snappi_api, - duthost, - tgen_ports): - """ - Run BGP Origin Code Modification Test - - Args: - snappi_api (pytest fixture): Snappi API - duthost (pytest fixture): duthost fixture - tgen_ports (pytest fixture): Ports mapping info of T0 testbed - """ - logger.info("|--Create BGP TGEN Configuration--|") - tgen_bgp_config = __tgen_bgp_config(snappi_api, - tgen_ports) - - logger.info("|--Updating TGEN Config with Origin Attribute--|") - tgen_origin_config = __tgen_origin_config(tgen_bgp_config) - - logger.info("|--BGP Origin Route Map Configuration on DUT--|") - __origin_route_map_config(duthost) - - logger.info("|--Verify Test--|") - __verify_test(duthost, - snappi_api, - tgen_origin_config) - - -# Common TGEN BGP Config -def __tgen_bgp_config(snappi_api, - tgen_ports): - """ - BGP Config on TGEN - Args: - snappi_api (pytest fixture): Snappi API - tgen_ports (pytest fixture): Ports mapping info of T0 testbed - """ - config = snappi_api.config() - - tgen1, tgen2 = ( - config.ports - .port(name='tgen1', location=tgen_ports[0]['location']) - .port(name='tgen2', location=tgen_ports[1]['location']) - ) - - # L1 Config - config.options.port_options.location_preemption = True - ly = config.layer1.layer1()[-1] - ly.name = 'ly' - ly.port_names = [tgen1.name, tgen2.name] - ly.speed = tgen_ports[0]['speed'] - ly.auto_negotiate = False - - # Device Config - d1, d2 = config.devices.device(name='d1').device(name='d2') - d1.container_name = tgen1.name - d2.container_name = tgen2.name - - eth1, eth2 = d1.ethernet, d2.ethernet - eth1.name, eth2.name = "eth1", "eth2" - - ip1, ip2 = eth1.ipv4, eth2.ipv4 - ip1.name, ip2.name = "ip1", "ip2" - - ip1.address = tgen_ports[0]['ip'] - ip1.gateway = tgen_ports[0]['peer_ip'] - ip1.prefix = tgen_ports[0]['prefix'] - - ip2.address = tgen_ports[1]['ip'] - ip2.gateway = tgen_ports[1]['peer_ip'] - ip2.prefix = tgen_ports[1]['prefix'] - - # BGPv4 - bgp = ip1.bgpv4 - bgp.name = "bgp" - bgp.dut_address = tgen_ports[0]['peer_ip'] - bgp.as_number = TGEN_AS_NUM - bgp.as_type = BGP_TYPE - - # v6 config - ip1v6, ip2v6 = eth1.ipv6, eth2.ipv6 - ip1v6.name, ip2v6.name = "ip1v6", "ip2v6" - - ip1v6.address = tgen_ports[0]['ipv6'] - ip1v6.gateway = tgen_ports[0]['peer_ipv6'] - ip1v6.prefix = tgen_ports[0]['ipv6_prefix'] - - ip2v6.address = tgen_ports[1]['ipv6'] - ip2v6.gateway = tgen_ports[1]['peer_ipv6'] - ip2v6.prefix = tgen_ports[1]['ipv6_prefix'] - - # BGPv6 - bgpv6 = ip1v6.bgpv6 - bgpv6.name = "bgpv6" - bgpv6.dut_address = tgen_ports[0]['peer_ipv6'] - bgpv6.as_number = TGEN_AS_NUM - bgpv6.as_type = BGP_TYPE - - # Routes Config - bgp_route1, bgp_route2 = ( - bgp.bgpv4_routes - .bgpv4route(name="bgp_route1") - .bgpv4route(name="bgp_route2") - ) - - # Advertise one route("200.1.0.0") - bgp_route1.addresses.bgpv4routeaddress(address="200.1.0.0", - prefix=16) - - # Advertise another route("20.1.0.0") - bgp_route2.addresses.bgpv4routeaddress(address="20.1.0.0", - prefix=16) - - # Routes Config - bgpv6_route1, bgpv6_route2 = ( - bgpv6.bgpv6_routes - .bgpv6route(name="bgpv6_route1") - .bgpv6route(name="bgpv6_route2") - ) - - # Advertise one route("4000::1") with Attributes - bgpv6_route1.addresses.bgpv6routeaddress(address="4000::1", - prefix=64) - - # Advertise another route("6000::1") - bgpv6_route2.addresses.bgpv6routeaddress(address="6000::1", - prefix=64) - - # Create four flows - permit, deny, permit_ipv6, deny_ipv6 = ( - config.flows - .flow(name='permit') - .flow(name='deny') - .flow(name='permit_ipv6') - .flow(name='deny_ipv6') - ) - - permit.tx_rx.device.tx_names = [ip2.name] - permit.tx_rx.device.rx_names = [bgp_route1.name] - - deny.tx_rx.device.tx_names = [ip2.name] - deny.tx_rx.device.rx_names = [bgp_route2.name] - - permit.rate.percentage = LINE_RATE - permit.duration.fixed_packets.packets = PACKETS - - deny.rate.percentage = LINE_RATE - deny.duration.fixed_packets.packets = PACKETS - - permit_ipv6.tx_rx.device.tx_names = [ip2v6.name] - permit_ipv6.tx_rx.device.rx_names = [bgpv6_route1.name] - - deny_ipv6.tx_rx.device.tx_names = [ip2v6.name] - deny_ipv6.tx_rx.device.rx_names = [bgpv6_route2.name] - - permit_ipv6.rate.percentage = LINE_RATE - permit_ipv6.duration.fixed_packets.packets = PACKETS - - deny_ipv6.rate.percentage = LINE_RATE - deny_ipv6.duration.fixed_packets.packets = PACKETS - - return config - - -def __tgen_policies_config(config): - """ - BGP Attributes Config on TGEN - Args: - config : tgen config - """ - - # update route("200.1.0.0") with attributes - bgp_route_with_policies = ( - config.devices[0].ethernet.ipv4.bgpv4.bgpv4_routes[0]) - - # Community - manual_as_community = ( - bgp_route_with_policies.communities.bgpcommunity()[-1]) - manual_as_community.community_type = manual_as_community.MANUAL_AS_NUMBER - manual_as_community.as_number = int(COMMUNITY.split(":")[0]) - manual_as_community.as_custom = int(COMMUNITY.split(":")[1]) - # Metric - bgp_route_with_policies.advanced.multi_exit_discriminator = MED - # AS PATH - as_path = bgp_route_with_policies.as_path - as_path_segment = as_path.as_path_segments.bgpaspathsegment()[-1] - as_path_segment.segment_type = as_path_segment.AS_SEQ - as_path_segment.as_numbers = GROUP_AS - # Origin - bgp_route_with_policies.advanced.origin = ( - bgp_route_with_policies.advanced.EGP) - - # update route("4000::1") with attributes - bgpv6_route_with_policies = ( - config.devices[0].ethernet.ipv6.bgpv6.bgpv6_routes[0]) - - # Community - manual_as_community = ( - bgpv6_route_with_policies.communities.bgpcommunity()[-1]) - manual_as_community.community_type = manual_as_community.MANUAL_AS_NUMBER - manual_as_community.as_number = int(COMMUNITY.split(":")[0]) - manual_as_community.as_custom = int(COMMUNITY.split(":")[1]) - # Metric - bgpv6_route_with_policies.advanced.multi_exit_discriminator = MED - # AS PATH - as_path = bgpv6_route_with_policies.as_path - as_path_segment = as_path.as_path_segments.bgpaspathsegment()[-1] - as_path_segment.segment_type = as_path_segment.AS_SEQ - as_path_segment.as_numbers = GROUP_AS - # Origin - bgpv6_route_with_policies.advanced.origin = ( - bgpv6_route_with_policies.advanced.EGP) - - return config - - -def __policies_route_map_config(duthost): - """ - BGP Policy Route MAP Config on duthost - Args: - duthost : duthost fixture - """ - # Remove route_map if exists already - duthost.shell( - "vtysh " - "-c 'configure terminal' " - "-c 'no route-map LA' " - "-c 'no route-map LAv6' " - ) - - as_path_access_list = ( - "vtysh " - "-c 'configure terminal' " - "-c 'no bgp as-path access-list PERMIT_100' " - ) - try: - duthost.shell(as_path_access_list) - except Exception: - pass - - community = ( - "vtysh " - "-c 'configure terminal' " - "-c 'no bgp community-list 10' " - ) - try: - duthost.shell(community) - except Exception: - pass - - # Configure route_map - policy_route_map_config = ( - "vtysh " - "-c 'configure terminal' " - "-c 'bgp community-list 10 permit 1:2' " - "-c 'bgp as-path access-list PERMIT_100 permit 100' " - "-c 'route-map LA permit 30' " - "-c 'match community 10' " - "-c 'match as-path PERMIT_100' " - "-c 'match metric 50' " - "-c 'match origin egp' " - "-c 'route-map LAv6 permit 30' " - "-c 'match community 10' " - "-c 'match as-path PERMIT_100' " - "-c 'match metric 50' " - "-c 'match origin egp' " - ) - duthost.shell(policy_route_map_config) - - -def __tgen_community_config(config): - """ - BGP Community Config on TGEN - Args: - config : tgen config - """ - - # update route("200.1.0.0") with community 1:2 - bgp_route_with_community = ( - config.devices[0].ethernet.ipv4.bgpv4.bgpv4_routes[0]) - - manual_as_community = ( - bgp_route_with_community.communities.bgpcommunity()[-1]) - manual_as_community.community_type = manual_as_community.MANUAL_AS_NUMBER - manual_as_community.as_number = int(COMMUNITY.split(":")[0]) - manual_as_community.as_custom = int(COMMUNITY.split(":")[1]) - - # update route("4000::1") with community 1:2 - bgpv6_route_with_community = ( - config.devices[0].ethernet.ipv6.bgpv6.bgpv6_routes[0]) - - manual_as_community = ( - bgpv6_route_with_community.communities.bgpcommunity()[-1]) - manual_as_community.community_type = manual_as_community.MANUAL_AS_NUMBER - manual_as_community.as_number = int(COMMUNITY.split(":")[0]) - manual_as_community.as_custom = int(COMMUNITY.split(":")[1]) - - return config - - -def __community_route_map_config(duthost): - """ - BGP Community Route MAP Config on duthost - Args: - duthost : duthost fixture - """ - # Remove route_map if exists already - remove_route_map = ( - "vtysh " - "-c 'configure terminal' " - "-c 'router bgp %s' " - "-c 'address-family ipv4 unicast' " - "-c 'no neighbor LC route-map LA in' " - "-c 'address-family ipv6 unicast' " - "-c 'no neighbor LCv6 route-map LAv6 in' " - "-c 'neighbor LCv6 route-map NEXTHOP in' " - "-c 'no route-map LA' " - "-c 'no route-map LAv6' " - ) - remove_route_map %= (DUT_AS_NUM) - duthost.shell(remove_route_map) - - community = ( - "vtysh " - "-c 'configure terminal' " - "-c 'no bgp community-list 10' " - ) - try: - duthost.shell(community) - except Exception: - pass - - # Configure route_map - community_config = ( - "vtysh " - "-c 'configure terminal' " - "-c 'bgp community-list 10 permit 1:2' " - "-c 'route-map LA permit 30' " - "-c 'match community 10' " - "-c 'route-map LAv6 permit 30' " - "-c 'match community 10' " - ) - duthost.shell(community_config) - - -def __prefix_list_route_map_config(duthost): - """ - BGP Prefix List Route MAP Config on duthost - Args: - duthost : duthost fixture - """ - - # Remove route_map if exists already - remove_route_map = ( - "vtysh " - "-c 'configure terminal' " - "-c 'router bgp %s' " - "-c 'address-family ipv4 unicast' " - "-c 'no neighbor LC route-map LA in' " - "-c 'address-family ipv6 unicast' " - "-c 'no neighbor LCv6 route-map LAv6 in' " - "-c 'neighbor LCv6 route-map NEXTHOP in' " - "-c 'no route-map LA' " - "-c 'no route-map LAv6' " - ) - remove_route_map %= (DUT_AS_NUM) - duthost.shell(remove_route_map) - - # Configure route_map - prefix_list_config = ( - "vtysh " - "-c 'configure terminal' " - "-c 'no ip prefix-list PERMIT_IP' " - "-c 'no ipv6 prefix-list PERMIT_IPV6' " - "-c 'ip prefix-list PERMIT_IP permit 200.1.0.0/16' " - "-c 'ipv6 prefix-list PERMIT_IPV6 permit 4000::1/64' " - "-c 'route-map LA permit 30' " - "-c 'match ip address prefix-list PERMIT_IP' " - "-c 'route-map LAv6 permit 30' " - "-c 'match ipv6 address prefix-list PERMIT_IPV6' " - ) - duthost.shell(prefix_list_config) - - -def __tgen_metric_config(config): - """ - BGP Metric config on TGEN - Args: - config : tgen config - """ - - # update route("200.1.0.0") with metric/MED 100 - bgp_route_metric_100 = ( - config.devices[0].ethernet.ipv4.bgpv4.bgpv4_routes[0]) - bgp_route_metric_100.advanced.multi_exit_discriminator = MED - - # update route("4000::1") with metric/MED 100 - bgpv6_route_metric_100 = ( - config.devices[0].ethernet.ipv6.bgpv6.bgpv6_routes[0]) - bgpv6_route_metric_100.advanced.multi_exit_discriminator = MED - - return config - - -def __metric_route_map_config(duthost): - """ - BGP Metric Route MAP Config on duthost - Args: - duthost : duthost fixture - """ - # Remove route_map if exists already - remove_route_map = ( - "vtysh " - "-c 'configure terminal' " - "-c 'router bgp %s' " - "-c 'address-family ipv4 unicast' " - "-c 'no neighbor LC route-map LA in' " - "-c 'address-family ipv6 unicast' " - "-c 'no neighbor LCv6 route-map LAv6 in' " - "-c 'neighbor LCv6 route-map NEXTHOP in' " - "-c 'no route-map LA' " - "-c 'no route-map LAv6' " - ) - remove_route_map %= (DUT_AS_NUM) - duthost.shell(remove_route_map) - - # Configure route_map - metric_config = ( - "vtysh " - "-c 'configure terminal' " - "-c 'route-map LA permit 30' " - "-c 'match metric 50' " - "-c 'route-map LAv6 permit 30' " - "-c 'match metric 50' " - ) - duthost.shell(metric_config) - - -def __tgen_as_path_modified_config(config): - """ - BGP group AS config on duthost and TGEN - Args: - config : tgen config - """ - - # update route("200.1.0.0") with additional AS 100 - bgp_route_with_as_100 = ( - config.devices[0].ethernet.ipv4.bgpv4.bgpv4_routes[0]) - - as_path = bgp_route_with_as_100.as_path - as_path_segment = as_path.as_path_segments.bgpaspathsegment()[-1] - as_path_segment.segment_type = as_path_segment.AS_SEQ - as_path_segment.as_numbers = GROUP_AS - - # update route("4000::1") with additional AS 100 - bgpv6_route_with_as_100 = ( - config.devices[0].ethernet.ipv6.bgpv6.bgpv6_routes[0]) - - as_path = bgpv6_route_with_as_100.as_path - as_path_segment = as_path.as_path_segments.bgpaspathsegment()[-1] - as_path_segment.segment_type = as_path_segment.AS_SEQ - as_path_segment.as_numbers = GROUP_AS - - return config - - -def __as_path_route_map_config(duthost): - """ - BGP AS PATH Route MAP Config on duthost - Args: - duthost : duthost fixture - """ - # Remove route_map if exists already - remove_route_map = ( - "vtysh " - "-c 'configure terminal' " - "-c 'router bgp %s' " - "-c 'address-family ipv4 unicast' " - "-c 'no neighbor LC route-map LA in' " - "-c 'address-family ipv6 unicast' " - "-c 'no neighbor LCv6 route-map LAv6 in' " - "-c 'neighbor LCv6 route-map NEXTHOP in' " - "-c 'no route-map LA' " - "-c 'no route-map LAv6' " - ) - remove_route_map %= (DUT_AS_NUM) - duthost.shell(remove_route_map) - - remove_as_path = ( - "vtysh " - "-c 'configure terminal' " - "-c 'no bgp as-path access-list PERMIT_100' " - ) - try: - duthost.shell(remove_as_path) - except Exception: - pass - - # Configure route_map - as_path_route_map = ( - "vtysh " - "-c 'configure terminal' " - "-c 'bgp as-path access-list PERMIT_100 permit 100' " - "-c 'route-map LA permit 30' " - "-c 'match as-path PERMIT_100' " - "-c 'route-map LAv6 permit 30' " - "-c 'match as-path PERMIT_100' " - ) - duthost.shell(as_path_route_map) - - -def __tgen_origin_config(config): - """ - BGP Origin config on TGEN - Args: - config : tgen config - """ - - # update route("200.1.0.0") with ORIGIN EGP - bgp_route_origin_egp = ( - config.devices[0].ethernet.ipv4.bgpv4.bgpv4_routes[0]) - - bgp_route_origin_egp.advanced.origin = bgp_route_origin_egp.advanced.EGP - - # update route("4000::1") with with ORIGIN EGP - bgpv6_route_origin_egp = ( - config.devices[0].ethernet.ipv6.bgpv6.bgpv6_routes[0]) - - bgpv6_route_origin_egp.advanced.origin = ( - bgpv6_route_origin_egp.advanced.EGP) - - return config - - -def __origin_route_map_config(duthost): - """ - BGP Origin Route MAP Config on duthost - Args: - duthost : duthost fixture - """ - - # Remove route_map if exists already - remove_route_map = ( - "vtysh " - "-c 'configure terminal' " - "-c 'router bgp %s' " - "-c 'address-family ipv4 unicast' " - "-c 'no neighbor LC route-map LA in' " - "-c 'address-family ipv6 unicast' " - "-c 'no neighbor LCv6 route-map LAv6 in' " - "-c 'neighbor LCv6 route-map NEXTHOP in' " - "-c 'no route-map LA' " - "-c 'no route-map LAv6' " - ) - remove_route_map %= (DUT_AS_NUM) - duthost.shell(remove_route_map) - - # Configure route_map - origin_route_map = ( - "vtysh " - "-c 'configure terminal' " - "-c 'route-map LA permit 30' " - "-c 'match origin egp' " - "-c 'route-map LAv6 permit 30' " - "-c 'match origin egp' " - ) - duthost.shell(origin_route_map) - - -def __verify_test(duthost, - snappi_api, - config): - """ - Test Verification - - Args: - duthost (pytest fixture): duthost fixture - snappi_api (pytest fixture): Snappi API - config: tgen_config - """ - logger.info("|--Apply TGEN Config--|") - snappi_api.set_config(config) - - # Start traffic - logger.info("|--Start Traffic--|") - ts = snappi_api.transmit_state() - ts.state = ts.START - snappi_api.set_transmit_state(ts) - - # Check there is no loss for 'permit', 'permit_ipv6', 'deny' & deny_ipv6 - logger.info( - "|--Asserting No Loss For All Flows Before Applying Route-Map--|") - pytest_assert(wait_until(60, 2, - lambda: __check_for_no_loss(snappi_api, - ['permit', 'permit_ipv6', - 'deny', 'deny_ipv6'], - PACKETS * 4)), - 'No loss expected') - - logger.info("|--Apply Route-Map--|") - # Apply route-map to permit only expected routes - route_map = ( - "vtysh " - "-c 'configure terminal' " - "-c 'router bgp %s' " - "-c 'address-family ipv4 unicast' " - "-c 'neighbor LC route-map LA in' " - "-c 'address-family ipv6 unicast' " - "-c 'neighbor LCv6 route-map LAv6 in' " - ) - route_map %= (DUT_AS_NUM) - duthost.shell(route_map) - - # Start traffic - logger.info("|--Start Traffic--|") - ts = snappi_api.transmit_state() - ts.state = ts.START - snappi_api.set_transmit_state(ts) - - # Check there is no traffic loss for 'permit' and 'permit_ipv6' flow - logger.info( - "|--Assert No Loss For Flows With Permit--|") - pytest_assert(wait_until(60, 2, - lambda: __check_for_no_loss(snappi_api, - ['permit', 'permit_ipv6'], - PACKETS * 2)), - 'No loss expected') - - # Check 100% traffic loss for 'deny' and 'deny_ipv6' flow - logger.info( - "|--Assert 100 Percent Loss For Flows Without Permit--|") - pytest_assert(wait_until(60, 2, - lambda: __check_for_total_loss( - snappi_api, ['deny', 'deny_ipv6'])), - 'total loss expected') - - # Stop traffic - logger.info("|--Stopping Traffic After Test--|") - ts = snappi_api.transmit_state() - ts.state = ts.STOP - snappi_api.set_transmit_state(ts) - - -def __check_for_no_loss(snappi_api, - flow_names, - expected): - """ - Returns True if there is no traffic loss else False - - Args: - snappi_api (pytest fixture): Snappi API - flow_names: List of flow_names to check for validation - expected: Expected Packets Count - """ - request = snappi_api.metrics_request() - request.flow.flow_names = flow_names - flow_results = snappi_api.get_metrics(request).flow_metrics - flow_rx = sum([f.frames_rx for f in flow_results]) - return flow_rx == expected - - -def __check_for_total_loss(snappi_api, - flow_names): - """ - Returns True if there is 100% traffic loss else False - - Args: - snappi_api (pytest fixture): Snappi API - flow_names: List of flow_names to check for validation - """ - request = snappi_api.metrics_request() - request.flow.flow_names = flow_names - flow_results = snappi_api.get_metrics(request).flow_metrics - flow_rx = sum([f.frames_rx for f in flow_results]) - return flow_rx == 0 - - -def config_cleanup(duthost, - tgen_ports): - - # Remove bgp neighbor config - bgp_config = ( - "vtysh " - "-c 'configure terminal' " - "-c 'no router bgp' " - ) - duthost.shell(bgp_config) - - # Remove any leftover config if not removed - route_map = ( - "vtysh " - "-c 'configure terminal' " - "-c 'no bgp community-list 10' " - ) - try: - duthost.shell(route_map) - except Exception: - pass - - route_map = ( - "vtysh " - "-c 'configure terminal' " - "-c 'no bgp as-path access-list PERMIT_100' " - ) - try: - duthost.shell(route_map) - except Exception: - pass - - route_map = ( - "vtysh " - "-c 'configure terminal' " - "-c 'no ip prefix-list PERMIT_IP' " - ) - try: - duthost.shell(route_map) - except Exception: - pass - - route_map = ( - "vtysh " - "-c 'configure terminal' " - "-c 'no ipv6 prefix-list PERMIT_IPV6' " - ) - try: - duthost.shell(route_map) - except Exception: - pass - - route_map = ( - "vtysh " - "-c 'configure terminal' " - "-c 'no route-map LA permit 30' " - "-c 'no route-map LAv6 permit 30' " - ) - try: - duthost.shell(route_map) - except Exception: - pass - - # Remove interface ip config - intf1_config = ( - "vtysh " - "-c 'configure terminal' " - "-c 'interface %s' " - "-c 'no ip address %s/%s' " - "-c 'no ipv6 address %s/%s' " - ) - intf1_config %= (tgen_ports[0]['peer_port'], - tgen_ports[0]['peer_ip'], - tgen_ports[0]['prefix'], - tgen_ports[0]['peer_ipv6'], - tgen_ports[0]['ipv6_prefix']) - duthost.shell(intf1_config) - - intf2_config = ( - "vtysh " - "-c 'configure terminal' " - "-c 'interface %s' " - "-c 'no ip address %s/%s' " - "-c 'no ipv6 address %s/%s' " - ) - intf2_config %= (tgen_ports[1]['peer_port'], - tgen_ports[1]['peer_ip'], - tgen_ports[1]['prefix'], - tgen_ports[1]['peer_ipv6'], - tgen_ports[1]['ipv6_prefix']) - duthost.shell(intf2_config) - diff --git a/tests/ixia/bgp/test_routing_policies.py b/tests/ixia/bgp/test_routing_policies.py deleted file mode 100755 index 1c937489e00..00000000000 --- a/tests/ixia/bgp/test_routing_policies.py +++ /dev/null @@ -1,316 +0,0 @@ -import pytest -import logging -from tests.common.ixia.ixia_fixtures import snappi_api -from tests.common.ixia.ixia_fixtures import ( - ixia_api_serv_ip, ixia_api_serv_port, tgen_ports) -from files.helper import ( - run_peer_routing_policies_test, run_community_list_filtering_test, - run_prefix_list_filtering_test, run_test_metric_filter, - run_group_as_path_modified, run_origin_code_modification, - config_setup, config_cleanup) -from tests.common.fixtures.conn_graph_facts import ( - conn_graph_facts, fanout_graph_facts) -logger = logging.getLogger(__name__) - - -@pytest.fixture(scope="module") -def setup_and_teardown(duthost, - tgen_ports): - """ - Setup and Teardown - """ - # We are going to use first two ports for all these tests - tgen_ports = tgen_ports[0:2] - logger.info("|--Common Setup Configuration--|") - config_setup(duthost, - tgen_ports) - yield - logger.info("|--Common Cleanup--|") - config_cleanup(duthost, - tgen_ports) - - -# Test 1 -@pytest.mark.topology("tgen") -def test_peer_routing_policies(snappi_api, - duthost, - tgen_ports, - conn_graph_facts, - fanout_graph_facts, - setup_and_teardown): - """ - Topo: - TGEN1 --- DUT --- TGEN2 - - Steps: - 1) Create BGP config on DUT and TGEN respectively - 2) Generate 2 ipv4 routes & 2 ipv6 routes from TGEN1 - -- "200.1.0.0" & "4000::1" with Attributes - a) community-list 1:2 - b) as-path append AS 100 - c) Origin ebgp - d) Metric 50 - -- "20.1.0.0" & "6000::1" - 3) Create route-map in DUT to permit only "200.1.0.0" - & "4000::1" based on BGP Attributes - 4) Create four flows from TGEN2 to TGEN1 - a) 'permit' -- TGEN2 to TGEN1("200.1.0.0") - b) 'permit_ipv6' -- TGEN2 to TGEN1("4000::1") - c) 'deny' -- TGEN2 to TGEN1("20.1.0.0") - d) 'deny_ipv6' -- TGEN2 to TGEN1("6000::1") - - Verification: - 1) Send traffic without applying route-map - Result: Should not observe traffic loss in 'permit' & 'deny' - 'permit_ipv6' & 'deny_ipv6' - 2) Apply route-map - Result: Should observe 100% traffic loss in 'deny' & 'deny_ipv6' - - Args: - snappi_api (pytest fixture): Snappi API - duthost (pytest fixture): duthost fixture - tgen_ports (pytest fixture): Ports mapping info of T0 testbed - conn_graph_facts (pytest fixture): connection graph - fanout_graph_facts (pytest fixture): fanout graph - """ - - tgen_ports = tgen_ports[0:2] - logger.info("|--BGP Peer Policies Test--|") - run_peer_routing_policies_test(snappi_api, - duthost, - tgen_ports) - - -# Test 2 -@pytest.mark.topology("tgen") -def test_community_list_filtering(snappi_api, - duthost, - tgen_ports, - conn_graph_facts, - fanout_graph_facts, - setup_and_teardown): - """ - Topo: - TGEN1 --- DUT --- TGEN2 - - Steps: - 1) Create BGP config on DUT and TGEN respectively - 2) Generate 2 ipv4 routes & 2 ipv6 routes from TGEN1 - -- "200.1.0.0" & "4000::1" with Community Attribute 1:2 - -- "20.1.0.0" & "6000::1" - 3) Create route-map in DUT to permit only "200.1.0.0" - & "4000::1" based on Community Attribute - 4) Create four flows from TGEN2 to TGEN1 - a) 'permit' -- TGEN2 to TGEN1("200.1.0.0") - b) 'permit_ipv6' -- TGEN2 to TGEN1("4000::1") - c) 'deny' -- TGEN2 to TGEN1("20.1.0.0") - d) 'deny_ipv6' -- TGEN2 to TGEN1("6000::1") - - Verification: - 1) Send traffic without applying route-map - Result: Should not observe traffic loss in 'permit' & 'deny' - 'permit_ipv6' & 'deny_ipv6' - 2) Apply route-map - Result: Should observe 100% traffic loss in 'deny' & 'deny_ipv6' - - Args: - snappi_api (pytest fixture): Snappi API - duthost (pytest fixture): duthost fixture - tgen_ports (pytest fixture): Ports mapping info of T0 testbed - conn_graph_facts (pytest fixture): connection graph - fanout_graph_facts (pytest fixture): fanout graph - """ - - tgen_ports = tgen_ports[0:2] - logger.info("|--BGP Community List Filtering Test--|") - run_community_list_filtering_test(snappi_api, - duthost, - tgen_ports) - - -# Test 3 -@pytest.mark.topology("tgen") -def test_prefix_list_filtering(snappi_api, - duthost, - tgen_ports, - conn_graph_facts, - fanout_graph_facts, - setup_and_teardown): - """ - Topo: - TGEN1 --- DUT --- TGEN2 - - Steps: - 1) Create BGP config on DUT and TGEN respectively - 2) Generate 2 ipv4 routes & 2 ipv6 routes from TGEN1 - -- "200.1.0.0" & "4000::1" - -- "20.1.0.0" & "6000::1" - 3) Create Prefix-list route-map in DUT to permit - only "200.1.0.0" & "4000::1" - 4) Create four flows from TGEN2 to TGEN1 - a) 'permit' -- TGEN2 to TGEN1("200.1.0.0") - b) 'permit_ipv6' -- TGEN2 to TGEN1("4000::1") - c) 'deny' -- TGEN2 to TGEN1("20.1.0.0") - d) 'deny_ipv6' -- TGEN2 to TGEN1("6000::1") - - Verification: - 1) Send traffic without applying route-map - Result: Should not observe traffic loss in 'permit' & 'deny' - 'permit_ipv6' & 'deny_ipv6' - 2) Apply route-map - Result: Should observe 100% traffic loss in 'deny' & 'deny_ipv6' - - Args: - snappi_api (pytest fixture): Snappi API - duthost (pytest fixture): duthost fixture - tgen_ports (pytest fixture): Ports mapping info of T0 testbed - conn_graph_facts (pytest fixture): connection graph - fanout_graph_facts (pytest fixture): fanout graph - """ - - tgen_ports = tgen_ports[0:2] - logger.info("|--BGP Prefix List Filtering Test--|") - run_prefix_list_filtering_test(snappi_api, - duthost, - tgen_ports) - - -# Test 4 -@pytest.mark.topology("tgen") -def test_metric_filter(snappi_api, - duthost, - tgen_ports, - conn_graph_facts, - fanout_graph_facts, - setup_and_teardown): - """ - Topo: - TGEN1 --- DUT --- TGEN2 - - Steps: - 1) Create BGP config on DUT and TGEN respectively - 2) Generate 2 ipv4 routes & 2 ipv6 routes from TGEN1 - -- "200.1.0.0" & "4000::1" with Metric 50 - -- "20.1.0.0" & "6000::1" - 3) Create route-map in DUT to permit only "200.1.0.0" - & "4000::1" based on Metric - 4) Create four flows from TGEN2 to TGEN1 - a) 'permit' -- TGEN2 to TGEN1("200.1.0.0") - b) 'permit_ipv6' -- TGEN2 to TGEN1("4000::1") - c) 'deny' -- TGEN2 to TGEN1("20.1.0.0") - d) 'deny_ipv6' -- TGEN2 to TGEN1("6000::1") - - Verification: - 1) Send traffic without applying route-map - Result: Should not observe traffic loss in 'permit' & 'deny' - 'permit_ipv6' & 'deny_ipv6' - 2) Apply route-map - Result: Should observe 100% traffic loss in 'deny' & 'deny_ipv6' - - Args: - snappi_api (pytest fixture): Snappi API - duthost (pytest fixture): duthost fixture - tgen_ports (pytest fixture): Ports mapping info of T0 testbed - conn_graph_facts (pytest fixture): connection graph - fanout_graph_facts (pytest fixture): fanout graph - """ - - tgen_ports = tgen_ports[0:2] - logger.info("|--BGP Metric Filter Test--|") - run_test_metric_filter(snappi_api, - duthost, - tgen_ports) - - -# Test 5 -@pytest.mark.topology("tgen") -def test_group_as_path_modified(snappi_api, - duthost, - tgen_ports, - conn_graph_facts, - fanout_graph_facts, - setup_and_teardown): - """ - Topo: - TGEN1 --- DUT --- TGEN2 - - Steps: - 1) Create BGP config on DUT and TGEN respectively - 2) Generate 2 ipv4 routes & 2 ipv6 routes from TGEN1 - -- "200.1.0.0" & "4000::1" with group AS - -- "20.1.0.0" & "6000::1" - 3) Create route-map in DUT to permit only "200.1.0.0" - & "4000::1" based on group AS - 4) Create four flows from TGEN2 to TGEN1 - a) 'permit' -- TGEN2 to TGEN1("200.1.0.0") - b) 'permit_ipv6' -- TGEN2 to TGEN1("4000::1") - c) 'deny' -- TGEN2 to TGEN1("20.1.0.0") - d) 'deny_ipv6' -- TGEN2 to TGEN1("6000::1") - - Verification: - 1) Send traffic without applying route-map - Result: Should not observe traffic loss in 'permit' & 'deny' - 'permit_ipv6' & 'deny_ipv6' - 2) Apply route-map - Result: Should observe 100% traffic loss in 'deny' & 'deny_ipv6' - - Args: - snappi_api (pytest fixture): Snappi API - duthost (pytest fixture): duthost fixture - tgen_ports (pytest fixture): Ports mapping info of T0 testbed - conn_graph_facts (pytest fixture): connection graph - fanout_graph_facts (pytest fixture): fanout graph - """ - - tgen_ports = tgen_ports[0:2] - logger.info("|--BGP group-as-path modified Test--|") - run_group_as_path_modified(snappi_api, - duthost, - tgen_ports) - - -# Test 6 -@pytest.mark.topology("tgen") -def test_origin_code_modification(snappi_api, - duthost, - tgen_ports, - conn_graph_facts, - fanout_graph_facts, - setup_and_teardown): - """ - Topo: - TGEN1 --- DUT --- TGEN2 - - Steps: - 1) Create BGP config on DUT and TGEN respectively - 2) Generate 2 ipv4 routes & 2 ipv6 routes from TGEN1 - -- "200.1.0.0" & "4000::1" with Origin 'egp' - -- "20.1.0.0" & "6000::1" - 3) Create route-map in DUT to permit only "200.1.0.0" - & "4000::1" based on Origin 'egp' - 4) Create four flows from TGEN2 to TGEN1 - a) 'permit' -- TGEN2 to TGEN1("200.1.0.0") - b) 'permit_ipv6' -- TGEN2 to TGEN1("4000::1") - c) 'deny' -- TGEN2 to TGEN1("20.1.0.0") - d) 'deny_ipv6' -- TGEN2 to TGEN1("6000::1") - - Verification: - 1) Send traffic without applying route-map - Result: Should not observe traffic loss in 'permit' & 'deny' - 'permit_ipv6' & 'deny_ipv6' - 2) Apply route-map - Result: Should observe 100% traffic loss in 'deny' & 'deny_ipv6' - - Args: - snappi_api (pytest fixture): Snappi API - duthost (pytest fixture): duthost fixture - tgen_ports (pytest fixture): Ports mapping info of T0 testbed - conn_graph_facts (pytest fixture): connection graph - fanout_graph_facts (pytest fixture): fanout graph - """ - - tgen_ports = tgen_ports[0:2] - logger.info("|--BGP Group-Origin Code Modifcation Test--|") - run_origin_code_modification(snappi_api, - duthost, - tgen_ports) \ No newline at end of file From 598386012c4612981c742efe2a833e952d829223 Mon Sep 17 00:00:00 2001 From: Anish Date: Sat, 5 Jun 2021 16:03:15 +0000 Subject: [PATCH 09/12] pfc tests migrated to snappi --- tests/common/fixtures/snappi_fixtures.py | 425 ++++++++++++++++++ tests/snappi/conftest.py | 74 ++++ tests/snappi/pfc/__init__.py | 0 tests/snappi/pfc/files/__init__.py | 1 + tests/snappi/pfc/files/helper.py | 454 ++++++++++++++++++++ tests/snappi/pfc/test_global_pause.py | 66 +++ tests/snappi/pfc/test_pfc_pause_lossless.py | 264 ++++++++++++ tests/snappi/pfc/test_pfc_pause_lossy.py | 262 +++++++++++ 8 files changed, 1546 insertions(+) create mode 100644 tests/common/fixtures/snappi_fixtures.py create mode 100644 tests/snappi/conftest.py create mode 100644 tests/snappi/pfc/__init__.py create mode 100644 tests/snappi/pfc/files/__init__.py create mode 100644 tests/snappi/pfc/files/helper.py create mode 100644 tests/snappi/pfc/test_global_pause.py create mode 100644 tests/snappi/pfc/test_pfc_pause_lossless.py create mode 100644 tests/snappi/pfc/test_pfc_pause_lossy.py diff --git a/tests/common/fixtures/snappi_fixtures.py b/tests/common/fixtures/snappi_fixtures.py new file mode 100644 index 00000000000..f0290481a76 --- /dev/null +++ b/tests/common/fixtures/snappi_fixtures.py @@ -0,0 +1,425 @@ +""" +This module contains the snappi fixture +""" +import pytest +import snappi +from ipaddress import ip_address, IPv4Address +from tests.common.fixtures.conn_graph_facts import conn_graph_facts,\ + fanout_graph_facts +from tests.common.ixia.common_helpers import get_vlan_subnet, get_addrs_in_subnet,\ + get_peer_ixia_chassis +from tests.common.ixia.ixia_helpers import IxiaFanoutManager, get_tgen_location +from tests.common.ixia.port import IxiaPortConfig, IxiaPortType +from tests.common.helpers.assertions import pytest_assert + + +@pytest.fixture(scope="module") +def snappi_api_serv_ip(tbinfo): + """ + In an tgen testbed, there is no PTF docker. + Hence, we use ptf_ip field to store snappi API server. + This fixture returns the IP address of the snappi API server. + Args: + tbinfo (pytest fixture): fixture provides information about testbed + Returns: + snappi API server IP + """ + return tbinfo['ptf_ip'] + + +@pytest.fixture(scope="module") +def snappi_api_serv_port(duthosts, rand_one_dut_hostname): + """ + This fixture returns the REST API port of the Snappi API server. + Args: + duthost (pytest fixture): The duthost fixture. + Returns: + snappi API server REST port. + """ + duthost = duthosts[rand_one_dut_hostname] + return (duthost.host.options['variable_manager']. + _hostvars[duthost.hostname]['secret_group_vars'] + ['ixia_api_server']['rest_port']) + + +@pytest.fixture(scope='module') +def snappi_api(snappi_api_serv_ip, + snappi_api_serv_port): + """ + Snappi session fixture for snappi Tgen API + Args: + snappi_api_serv_ip (pytest fixture): snappi_api_serv_ip fixture + snappi_api_serv_port (pytest fixture): snappi_api_serv_port fixture. + """ + host = "https://" + snappi_api_serv_ip + ":" + str(snappi_api_serv_port) + # TODO: Currently extension is defaulted to ixnetwork. + # Going forward, we should be able to specify extension + # from command line while running pytest. + api = snappi.api(host=host, ext="ixnetwork") + + yield api + + if getattr(api, 'assistant', None) is not None: + api.assistant.Session.remove() + + +def __gen_mac(id): + """ + Generate a MAC address + + Args: + id (int): IXIA port ID + + Returns: + MAC address (string) + """ + return '00:11:22:33:44:{:02d}'.format(id) + + +def __valid_ipv4_addr(ip): + """ + Determine if a input string is a valid IPv4 address + + Args: + ip (unicode str): input IP address + + Returns: + True if the input is a valid IPv4 adress or False otherwise + """ + try: + return True if type(ip_address(ip)) is IPv4Address else False + except ValueError: + return False + + +def __l3_intf_config(config, port_config_list, duthost, ixia_ports): + """ + Generate Tgen configuration of layer 3 interfaces + + Args: + config (obj): Tgen API config of the testbed + port_config_list (list): list of IXIA port configuration information + duthost (object): device under test + ixia_ports (list): list of IXIA port information + + Returns: + True if we successfully generate configuration or False + """ + mg_facts = duthost.minigraph_facts(host=duthost.hostname)['ansible_facts'] + if 'minigraph_interfaces' in mg_facts: + l3_intf_facts = mg_facts['minigraph_interfaces'] + else: + return True + + if len(l3_intf_facts) == 0: + return True + + l3_intf = {} + for v in l3_intf_facts: + if __valid_ipv4_addr(v['addr']): + l3_intf[v['attachto']] = v + + dut_mac = str(duthost.facts['router_mac']) + + for k, v in l3_intf.items(): + intf = str(k) + gw_addr = str(v['addr']) + prefix = str(v['prefixlen']) + ip = str(v['peer_addr']) + + port_ids = [id for id, ixia_pot in enumerate(ixia_ports) \ + if ixia_pot['peer_port'] == intf] + if len(port_ids) != 1: + return False + + port_id = port_ids[0] + mac = __gen_mac(port_id) + + device = config.devices.device( + name='Device Port {}'.format(port_id), + container_name=config.ports[port_id].name)[-1] + + ethernet = device.ethernet + ethernet.name = 'Ethernet Port {}'.format(port_id) + ethernet.mac = mac + + ip_stack = ethernet.ipv4 + ip_stack.name = 'Ipv4 Port {}'.format(port_id) + ip_stack.address = ip + ip_stack.prefix = prefix + ip_stack.gateway = gw_addr + + port_config = IxiaPortConfig(id=port_id, + ip=ip, + mac=mac, + gw=gw_addr, + gw_mac=dut_mac, + prefix_len=prefix, + port_type=IxiaPortType.IPInterface, + peer_port=intf) + + port_config_list.append(port_config) + + return True + + +def __vlan_intf_config(config, port_config_list, duthost, ixia_ports): + """ + Generate Tgen configuration of Vlan interfaces + + Args: + config (obj): Tgen API config of the testbed + port_config_list (list): list of IXIA port configuration information + duthost (object): device under test + ixia_ports (list): list of IXIA port information + + Returns: + True if we successfully generate configuration or False + """ + mg_facts = duthost.minigraph_facts(host=duthost.hostname)['ansible_facts'] + if 'minigraph_vlans' in mg_facts: + vlan_facts = mg_facts['minigraph_vlans'] + else: + return True + + if len(vlan_facts) == 0: + return True + + vlan_member = {} + for k, v in vlan_facts.items(): + vlan_member[k] = v['members'] + + vlan_intf_facts = mg_facts['minigraph_vlan_interfaces'] + vlan_intf = {} + for v in vlan_intf_facts: + if __valid_ipv4_addr(v['addr']): + vlan_intf[v['attachto']] = v + + dut_mac = str(duthost.facts['router_mac']) + + """ For each Vlan """ + for vlan in vlan_member: + phy_intfs = vlan_member[vlan] + gw_addr = str(vlan_intf[vlan]['addr']) + prefix = str(vlan_intf[vlan]['prefixlen']) + vlan_subnet = '{}/{}'.format(gw_addr, prefix) + vlan_ip_addrs = get_addrs_in_subnet(vlan_subnet, len(phy_intfs)) + + """ For each physical interface attached to this Vlan """ + for i in range(len(phy_intfs)): + phy_intf = phy_intfs[i] + vlan_ip_addr = vlan_ip_addrs[i] + + port_ids = [id for id, ixia_pot in enumerate(ixia_ports) \ + if ixia_pot['peer_port'] == phy_intf] + if len(port_ids) != 1: + return False + + port_id = port_ids[0] + mac = __gen_mac(port_id) + device = config.devices.device( + name='Device Port {}'.format(port_id), + container_name=config.ports[port_id].name)[-1] + + ethernet = device.ethernet + ethernet.name = 'Ethernet Port {}'.format(port_id) + ethernet.mac = mac + + ip_stack = ethernet.ipv4 + ip_stack.name = 'Ipv4 Port {}'.format(port_id) + ip_stack.address = vlan_ip_addr + ip_stack.prefix = prefix + ip_stack.gateway = gw_addr + + port_config = IxiaPortConfig(id=port_id, + ip=vlan_ip_addr, + mac=mac, + gw=gw_addr, + gw_mac=dut_mac, + prefix_len=prefix, + port_type=IxiaPortType.VlanMember, + peer_port=phy_intf) + + port_config_list.append(port_config) + + return True + + +def __portchannel_intf_config(config, port_config_list, duthost, ixia_ports): + """ + Generate Tgen configuration of portchannel interfaces + + Args: + config (obj): Tgen API config of the testbed + port_config_list (list): list of IXIA port configuration information + duthost (object): device under test + ixia_ports (list): list of IXIA port information + + Returns: + True if we successfully generate configuration or False + """ + mg_facts = duthost.minigraph_facts(host=duthost.hostname)['ansible_facts'] + if 'minigraph_portchannels' in mg_facts: + pc_facts = mg_facts['minigraph_portchannels'] + else: + return True + + if len(pc_facts) == 0: + return True + + pc_member = {} + for k, v in pc_facts.items(): + pc_member[k] = v['members'] + + pc_intf_facts = mg_facts['minigraph_portchannel_interfaces'] + pc_intf = {} + for v in pc_intf_facts: + if __valid_ipv4_addr(v['addr']): + pc_intf[v['attachto']] = v + + dut_mac = str(duthost.facts['router_mac']) + + """ For each port channel """ + for pc in pc_member: + phy_intfs = pc_member[pc] + gw_addr = str(pc_intf[pc]['addr']) + prefix = str(pc_intf[pc]['prefixlen']) + pc_ip_addr = str(pc_intf[pc]['peer_addr']) + + lag = config.lags.lag(name='Lag {}'.format(pc))[-1] + for i in range(len(phy_intfs)): + phy_intf = phy_intfs[i] + + port_ids = [id for id, ixia_pot in enumerate(ixia_ports) \ + if ixia_pot['peer_port'] == phy_intf] + if len(port_ids) != 1: + return False + + port_id = port_ids[0] + mac = __gen_mac(port_id) + + lp = lag.ports.port(port_name=config.ports[port_id].name)[-1] + lp.protocol.lacp.actor_system_id = '00:00:00:00:00:01' + lp.protocol.lacp.actor_system_priority = 1 + lp.protocol.lacp.actor_port_priority = 1 + lp.protocol.lacp.actor_port_number = 1 + lp.protocol.lacp.actor_key = 1 + + lp.ethernet.name = 'Ethernet Port {}'.format(port_id) + lp.ethernet.mac = mac + + port_config = IxiaPortConfig(id=port_id, + ip=pc_ip_addr, + mac=mac, + gw=gw_addr, + gw_mac=dut_mac, + prefix_len=prefix, + port_type=IxiaPortType.PortChannelMember, + peer_port=phy_intf) + + port_config_list.append(port_config) + + device = config.devices.device(name='Device {}'.format(pc), + container_name=lag.name)[-1] + + ip_stack = device.ethernet.ipv4 + ip_stack.address = pc_ip_addr + ip_stack.prefix = prefix + ip_stack.gateway = gw_addr + + return True + + +@pytest.fixture(scope="function") +def tgen_testbed_config(conn_graph_facts, + fanout_graph_facts, + duthosts, + rand_one_dut_hostname, + snappi_api): + """ + Geenrate Tgen API config and port config information for the testbed + + Args: + conn_graph_facts (pytest fixture) + fanout_graph_facts (pytest fixture) + duthosts (pytest fixture): list of DUTs + rand_one_dut_hostname (pytest fixture): DUT hostname + + Returns: + - config (obj): Tgen API config of the testbed + - port_config_list (list): list of port configuration information + """ + duthost = duthosts[rand_one_dut_hostname] + + """ Generate L1 config """ + ixia_fanout = get_peer_ixia_chassis(conn_data=conn_graph_facts, + dut_hostname=duthost.hostname) + + pytest_assert(ixia_fanout is not None, 'Fail to get ixia_fanout') + + ixia_fanout_id = list(fanout_graph_facts.keys()).index(ixia_fanout) + ixia_fanout_list = IxiaFanoutManager(fanout_graph_facts) + ixia_fanout_list.get_fanout_device_details(device_number=ixia_fanout_id) + + ixia_ports = ixia_fanout_list.get_ports(peer_device=duthost.hostname) + + port_speed = None + + """ L1 config """ + config = snappi_api.config() + for i in range(len(ixia_ports)): + config.ports.port(name='Port {}'.format(i), + location=get_tgen_location(ixia_ports[i])) + + if port_speed is None: + port_speed = int(ixia_ports[i]['speed']) + + pytest_assert(port_speed == int(ixia_ports[i]['speed']), + 'Ports have different link speeds') + + speed_gbps = int(port_speed/1000) + + config.options.port_options.location_preemption = True + l1_config = config.layer1.layer1()[-1] + l1_config.name = 'L1 config' + l1_config.port_names = [port.name for port in config.ports] + l1_config.speed = 'speed_{}_gbps'.format(speed_gbps) + l1_config.ieee_media_defaults = False + l1_config.auto_negotiate = False + l1_config.auto_negotiation.link_training = True + l1_config.auto_negotiation.rs_fec = True + + pfc = l1_config.flow_control.ieee_802_1qbb + pfc.pfc_delay = 0 + pfc.pfc_class_0 = 0 + pfc.pfc_class_1 = 1 + pfc.pfc_class_2 = 2 + pfc.pfc_class_3 = 3 + pfc.pfc_class_4 = 4 + pfc.pfc_class_5 = 5 + pfc.pfc_class_6 = 6 + pfc.pfc_class_7 = 7 + + l1_config.flow_control.choice = l1_config.flow_control.IEEE_802_1QBB + + port_config_list = [] + + config_result = __vlan_intf_config(config=config, + port_config_list=port_config_list, + duthost=duthost, + ixia_ports=ixia_ports) + pytest_assert(config_result is True, 'Fail to configure Vlan interfaces') + + config_result = __portchannel_intf_config(config=config, + port_config_list=port_config_list, + duthost=duthost, + ixia_ports=ixia_ports) + pytest_assert(config_result is True, 'Fail to configure portchannel interfaces') + + config_result = __l3_intf_config(config=config, + port_config_list=port_config_list, + duthost=duthost, + ixia_ports=ixia_ports) + pytest_assert(config_result is True, 'Fail to configure L3 interfaces') + + return config, port_config_list diff --git a/tests/snappi/conftest.py b/tests/snappi/conftest.py new file mode 100644 index 00000000000..d0db9397436 --- /dev/null +++ b/tests/snappi/conftest.py @@ -0,0 +1,74 @@ +import pytest +import random +from tests.common.ixia.common_helpers import enable_packet_aging, start_pfcwd +from tests.conftest import generate_priority_lists + +@pytest.fixture(autouse=True, scope="module") +def rand_lossless_prio(request): + """ + Fixture that randomly selects a lossless priority + + Args: + request (object): pytest request object + + Yields: + lossless priority (str): string containing 'hostname|lossless priority' + + """ + lossless_prios = generate_priority_lists(request, "lossless") + if lossless_prios: + yield random.sample(lossless_prios, 1)[0] + else: + yield 'unknown|unknown' + +@pytest.fixture(autouse=True, scope="module") +def rand_lossy_prio(request): + """ + Fixture that randomly selects a lossy priority + + Args: + request (object): pytest request object + + Yields: + lossy priority (str): string containing 'hostname|lossy priority' + + """ + lossy_prios = generate_priority_lists(request, "lossy") + if lossy_prios: + yield random.sample(lossy_prios, 1)[0] + else: + yield 'unknown|unknown' + +@pytest.fixture(autouse=True, scope="module") +def start_pfcwd_after_test(duthosts, rand_one_dut_hostname): + """ + Ensure that PFC watchdog is enabled with default setting after tests + + Args: + duthosts (pytest fixture) : list of DUTs + rand_one_dut_hostname (pytest fixture): DUT hostname + + Yields: + N/A + """ + yield + + duthost = duthosts[rand_one_dut_hostname] + start_pfcwd(duthost) + +@pytest.fixture(autouse=True, scope="module") +def enable_packet_aging_after_test(duthosts, rand_one_dut_hostname): + """ + Ensure that packet aging is enabled after tests + + Args: + duthosts (pytest fixture) : list of DUTs + rand_one_dut_hostname (pytest fixture): DUT hostname + + Yields: + N/A + """ + yield + + duthost = duthosts[rand_one_dut_hostname] + enable_packet_aging(duthost) diff --git a/tests/snappi/pfc/__init__.py b/tests/snappi/pfc/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/snappi/pfc/files/__init__.py b/tests/snappi/pfc/files/__init__.py new file mode 100644 index 00000000000..65d14a7c199 --- /dev/null +++ b/tests/snappi/pfc/files/__init__.py @@ -0,0 +1 @@ +# Local library for PFC tests. diff --git a/tests/snappi/pfc/files/helper.py b/tests/snappi/pfc/files/helper.py new file mode 100644 index 00000000000..be2de66b7ae --- /dev/null +++ b/tests/snappi/pfc/files/helper.py @@ -0,0 +1,454 @@ +import time +import logging +from tests.common.helpers.assertions import pytest_assert +from tests.common.fixtures.conn_graph_facts import conn_graph_facts,\ + fanout_graph_facts +from tests.common.ixia.ixia_helpers import get_dut_port_id +from tests.common.ixia.common_helpers import pfc_class_enable_vector,\ + get_egress_lossless_buffer_size, stop_pfcwd, disable_packet_aging +from tests.common.ixia.port import select_ports, select_tx_port + +logger = logging.getLogger(__name__) + +PAUSE_FLOW_NAME = 'Pause Storm' +TEST_FLOW_NAME = 'Test Flow' +TEST_FLOW_AGGR_RATE_PERCENT = 45 +BG_FLOW_NAME = 'Background Flow' +BG_FLOW_AGGR_RATE_PERCENT = 45 +DATA_PKT_SIZE = 1024 +DATA_FLOW_DURATION_SEC = 2 +DATA_FLOW_DELAY_SEC = 1 +IXIA_POLL_DELAY_SEC = 2 +TOLERANCE_THRESHOLD = 0.05 + + +def run_pfc_test(api, + testbed_config, + port_config_list, + conn_data, + fanout_data, + duthost, + dut_port, + global_pause, + pause_prio_list, + test_prio_list, + bg_prio_list, + prio_dscp_map, + test_traffic_pause): + """ + Run a PFC test + + Args: + api (obj): snappi session + testbed_config (obj): testbed L1/L2/L3 configuration + port_config_list (list): list of port configuration + conn_data (dict): the dictionary returned by conn_graph_fact. + fanout_data (dict): the dictionary returned by fanout_graph_fact. + duthost (Ansible host instance): device under test + dut_port (str): DUT port to test + global_pause (bool): if pause frame is IEEE 802.3X pause + pause_prio_list (list): priorities to pause for pause frames + test_prio_list (list): priorities of test flows + bg_prio_list (list): priorities of background flows + prio_dscp_map (dict): Priority vs. DSCP map (key = priority). + test_traffic_pause (bool): if test flows are expected to be paused + + Returns: + N/A + """ + + pytest_assert(testbed_config is not None, 'Fail to get L2/3 testbed config') + + stop_pfcwd(duthost) + disable_packet_aging(duthost) + + """ Get the ID of the port to test """ + port_id = get_dut_port_id(dut_hostname=duthost.hostname, + dut_port=dut_port, + conn_data=conn_data, + fanout_data=fanout_data) + + pytest_assert(port_id is not None, + 'Fail to get ID for port {}'.format(dut_port)) + + """ Rate percent must be an integer """ + test_flow_rate_percent = int(TEST_FLOW_AGGR_RATE_PERCENT / len(test_prio_list)) + bg_flow_rate_percent = int(BG_FLOW_AGGR_RATE_PERCENT / len(bg_prio_list)) + + """ Generate traffic config """ + __gen_traffic(testbed_config=testbed_config, + port_config_list=port_config_list, + port_id=port_id, + pause_flow_name=PAUSE_FLOW_NAME, + global_pause=global_pause, + pause_prio_list=pause_prio_list, + test_flow_name=TEST_FLOW_NAME, + test_flow_prio_list=test_prio_list, + test_flow_rate_percent=test_flow_rate_percent, + bg_flow_name=BG_FLOW_NAME, + bg_flow_prio_list=bg_prio_list, + bg_flow_rate_percent=bg_flow_rate_percent, + data_flow_dur_sec=DATA_FLOW_DURATION_SEC, + data_flow_delay_sec=DATA_FLOW_DELAY_SEC, + data_pkt_size=DATA_PKT_SIZE, + prio_dscp_map=prio_dscp_map) + + """ Tgen config = testbed config + flow config """ + flows = testbed_config.flows + + """ + import json + config_json = json.dumps(config, indent=2, default=lambda x: x.__dict__) + print(config_json) + """ + + all_flow_names = [flow.name for flow in flows] + data_flow_names = [flow.name for flow in flows if PAUSE_FLOW_NAME not in flow.name] + + """ Run traffic """ + flow_stats = __run_traffic(api=api, + config=testbed_config, + data_flow_names=data_flow_names, + all_flow_names=all_flow_names, + exp_dur_sec=DATA_FLOW_DURATION_SEC+DATA_FLOW_DELAY_SEC) + + speed_str = testbed_config.layer1[0].speed + speed_gbps = int(speed_str.split('_')[1]) + + """ Verify experiment results """ + __verify_results(rows=flow_stats, + duthost=duthost, + pause_flow_name=PAUSE_FLOW_NAME, + test_flow_name=TEST_FLOW_NAME, + bg_flow_name=BG_FLOW_NAME, + data_flow_dur_sec=DATA_FLOW_DURATION_SEC, + test_flow_rate_percent=test_flow_rate_percent, + bg_flow_rate_percent=bg_flow_rate_percent, + data_pkt_size=DATA_PKT_SIZE, + speed_gbps=speed_gbps, + test_flow_pause=test_traffic_pause, + tolerance=TOLERANCE_THRESHOLD) + + +sec_to_nanosec = lambda x: x * 1e9 + + +def __gen_traffic(testbed_config, + port_config_list, + port_id, + pause_flow_name, + global_pause, + pause_prio_list, + test_flow_name, + test_flow_prio_list, + test_flow_rate_percent, + bg_flow_name, + bg_flow_prio_list, + bg_flow_rate_percent, + data_flow_dur_sec, + data_flow_delay_sec, + data_pkt_size, + prio_dscp_map): + """ + Generate configurations of flows, including test flows, background flows and + pause storm. Test flows and background flows are also known as data flows. + + Args: + testbed_config (obj): testbed L1/L2/L3 configuration + port_config_list (list): list of port configuration + port_id (int): ID of DUT port to test + pause_flow_name (str): name of pause storm + global_pause (bool): if pause frame is IEEE 802.3X pause + pause_prio_list (list): priorities to pause for pause frames + test_flow_name (str): name of test flows + test_prio_list (list): priorities of test flows + test_flow_rate_percent (int): rate percentage for each test flow + bg_flow_name (str): name of background flows + bg_prio_list (list): priorities of background flows + bg_flow_rate_percent (int): rate percentage for each background flow + data_flow_dur_sec (int): duration of data flows in second + data_flow_delay_sec (int): start delay of data flows in second + data_pkt_size (int): packet size of data flows in byte + prio_dscp_map (dict): Priority vs. DSCP map (key = priority). + + Returns: + flows configurations (list): the list should have configurations of + len(test_flow_prio_list) test flow, len(bg_flow_prio_list) background + flows and a pause storm. + """ + + rx_port_id = port_id + tx_port_id_list, rx_port_id_list = select_ports(port_config_list=port_config_list, + pattern="many to one", + rx_port_id=rx_port_id) + + pytest_assert(len(tx_port_id_list) > 0, "Cannot find any TX ports") + tx_port_id = select_tx_port(tx_port_id_list=tx_port_id_list, + rx_port_id=rx_port_id) + pytest_assert(tx_port_id is not None, "Cannot find a suitable TX port") + + tx_port_config = next((x for x in port_config_list if x.id == tx_port_id), None) + rx_port_config = next((x for x in port_config_list if x.id == rx_port_id), None) + + tx_mac = tx_port_config.mac + if tx_port_config.gateway == rx_port_config.gateway and \ + tx_port_config.prefix_len == rx_port_config.prefix_len: + """ If soruce and destination port are in the same subnet """ + rx_mac = rx_port_config.mac + else: + rx_mac = tx_port_config.gateway_mac + + tx_port_name = testbed_config.ports[tx_port_id].name + rx_port_name = testbed_config.ports[rx_port_id].name + data_flow_delay_nanosec = sec_to_nanosec(data_flow_delay_sec) + + """ Test flows """ + for prio in test_flow_prio_list: + test_flow = testbed_config.flows.flow( + name='{} Prio {}'.format(test_flow_name, prio))[-1] + test_flow.tx_rx.port.tx_name = tx_port_name + test_flow.tx_rx.port.rx_name = rx_port_name + + eth, ipv4 = test_flow.packet.ethernet().ipv4() + eth.src.value = tx_mac + eth.dst.value = rx_mac + eth.pfc_queue.value = prio + + ipv4.src.value = tx_port_config.ip + ipv4.dst.value = rx_port_config.ip + ipv4.priority.choice = ipv4.priority.DSCP + ipv4.priority.dscp.phb.values = prio_dscp_map[prio] + ipv4.priority.dscp.ecn.value = ( + ipv4.priority.dscp.ecn.CAPABLE_TRANSPORT_1) + + test_flow.size.fixed = data_pkt_size + test_flow.rate.percentage = test_flow_rate_percent + test_flow.duration.fixed_seconds.seconds = data_flow_dur_sec + test_flow.duration.fixed_seconds.delay.nanoseconds = data_flow_delay_nanosec + + test_flow.metrics.enable = True + test_flow.metrics.loss = True + + """ Background flows """ + for prio in bg_flow_prio_list: + bg_flow = testbed_config.flows.flow( + name='{} Prio {}'.format(bg_flow_name, prio))[-1] + bg_flow.tx_rx.port.tx_name = tx_port_name + bg_flow.tx_rx.port.rx_name = rx_port_name + + eth, ipv4 = bg_flow.packet.ethernet().ipv4() + eth.src.value = tx_mac + eth.dst.value = rx_mac + eth.pfc_queue.value = prio + + ipv4.src.value = tx_port_config.ip + ipv4.dst.value = rx_port_config.ip + ipv4.priority.choice = ipv4.priority.DSCP + ipv4.priority.dscp.phb.values = prio_dscp_map[prio] + ipv4.priority.dscp.ecn.value = ( + ipv4.priority.dscp.ecn.CAPABLE_TRANSPORT_1) + + bg_flow.size.fixed = data_pkt_size + bg_flow.rate.percentage = bg_flow_rate_percent + bg_flow.duration.fixed_seconds.seconds = data_flow_dur_sec + bg_flow.duration.fixed_seconds.delay.nanoseconds = data_flow_delay_nanosec + + bg_flow.metrics.enable = True + bg_flow.metrics.loss = True + + """ Pause storm """ + pause_flow = testbed_config.flows.flow(name=pause_flow_name)[-1] + pause_flow.tx_rx.port.tx_name = testbed_config.ports[rx_port_id].name + pause_flow.tx_rx.port.rx_name = testbed_config.ports[tx_port_id].name + + if global_pause: + pause_pkt = pause_flow.packet.ethernetpause()[-1] + pause_pkt.src.value = '00:00:fa:ce:fa:ce' + pause_pkt.dst.value = '01:80:C2:00:00:01' + + else: + pause_time = [] + for x in range(8): + if x in pause_prio_list: + pause_time.append('ffff') + else: + pause_time.append('0000') + + vector = pfc_class_enable_vector(pause_prio_list) + pause_pkt = pause_flow.packet.pfcpause()[-1] + pause_pkt.src.value = '00:00:fa:ce:fa:ce' + pause_pkt.dst.value = '01:80:C2:00:00:01' + pause_pkt.class_enable_vector.value = vector + pause_pkt.pause_class_0.value = pause_time[0] + pause_pkt.pause_class_1.value = pause_time[1] + pause_pkt.pause_class_2.value = pause_time[2] + pause_pkt.pause_class_3.value = pause_time[3] + pause_pkt.pause_class_4.value = pause_time[4] + pause_pkt.pause_class_5.value = pause_time[5] + pause_pkt.pause_class_6.value = pause_time[6] + pause_pkt.pause_class_7.value = pause_time[7] + + """ Pause frames are sent from the RX port """ + + speed_str = testbed_config.layer1[0].speed + speed_gbps = int(speed_str.split('_')[1]) + pause_dur = 65535 * 64 * 8.0 / (speed_gbps * 1e9) + pps = int(2 / pause_dur) + + pause_flow.rate.pps = pps + pause_flow.size.fixed = 64 + pause_flow.duration.choice = pause_flow.duration.CONTINUOUS + pause_flow.duration.continuous.delay.nanoseconds = 0 + + pause_flow.metrics.enable = True + pause_flow.metrics.loss = True + + +def __run_traffic(api, + config, + data_flow_names, + all_flow_names, + exp_dur_sec): + + """ + Run traffic and dump per-flow statistics + + Args: + api (obj): snappi session + config (obj): experiment config (testbed config + flow config) + data_flow_names (list): list of names of data (test and background) flows + all_flow_names (list): list of names of all the flows + exp_dur_sec (int): experiment duration in second + + Returns: + per-flow statistics (list) + """ + api.set_config(config) + logger.info('Starting transmit on all flows ...') + ts = api.transmit_state() + ts.state = ts.START + api.set_transmit_state(ts) + + time.sleep(exp_dur_sec) + + attempts = 0 + max_attempts = 20 + + while attempts < max_attempts: + request = api.metrics_request() + request.flow.flow_names = data_flow_names + rows = api.get_metrics(request).flow_metrics + + """ If all the data flows have stopped """ + transmit_states = [row.transmit for row in rows] + if len(rows) == len(data_flow_names) and\ + list(set(transmit_states)) == ['stopped']: + time.sleep(IXIA_POLL_DELAY_SEC) + break + else: + time.sleep(1) + attempts += 1 + + pytest_assert(attempts < max_attempts, + "Flows do not stop in {} seconds".format(max_attempts)) + + """ Dump per-flow statistics """ + request = api.metrics_request() + request.flow.flow_names = all_flow_names + rows = api.get_metrics(request).flow_metrics + logger.info('Stop transmit on all flows ...') + ts = api.transmit_state() + ts.state = ts.STOP + api.set_transmit_state(ts) + + return rows + + +def __verify_results(rows, + duthost, + pause_flow_name, + test_flow_name, + bg_flow_name, + data_flow_dur_sec, + test_flow_rate_percent, + bg_flow_rate_percent, + data_pkt_size, + speed_gbps, + test_flow_pause, + tolerance): + """ + Verify if we get expected experiment results + + Args: + rows (list): per-flow statistics + duthost (Ansible host instance): device under test + pause_flow_name (str): name of pause storm + test_flow_name (str): name of test flows + bg_flow_name (str): name of background flows + test_flow_rate_percent (int): rate percentage for each test flow + bg_flow_rate_percent (int): rate percentage for each background flow + data_pkt_size (int): packet size of data flows in byte + speed_gbps (int): link speed in Gbps + test_flow_pause (bool): if test flows are expected to be paused + tolerance (float): maximum allowable deviation + + Returns: + N/A + """ + + """ All the pause frames should be dropped """ + pause_flow_row = next(row for row in rows if row.name == pause_flow_name) + tx_frames = pause_flow_row.frames_tx + rx_frames = pause_flow_row.frames_rx + pytest_assert(tx_frames > 0 and rx_frames == 0, + 'All the pause frames should be dropped') + + """ Check background flows """ + for row in rows: + if bg_flow_name not in row.name: + continue + + tx_frames = row.frames_tx + rx_frames = row.frames_rx + + pytest_assert(tx_frames == rx_frames, + '{} should not have any dropped packet'.format(row.name)) + + exp_bg_flow_rx_pkts = bg_flow_rate_percent / 100.0 * speed_gbps \ + * 1e9 * data_flow_dur_sec / 8.0 / data_pkt_size + deviation = (rx_frames - exp_bg_flow_rx_pkts) / float(exp_bg_flow_rx_pkts) + pytest_assert(abs(deviation) < tolerance, + '{} should receive {} packets (actual {})'. + format(row.name, exp_bg_flow_rx_pkts, rx_frames)) + + """ Check test flows """ + for row in rows: + if test_flow_name not in row.name: + continue + + tx_frames = row.frames_tx + rx_frames = row.frames_rx + + if test_flow_pause: + pytest_assert(tx_frames > 0 and rx_frames == 0, + '{} should be paused'.format(row.name)) + else: + pytest_assert(tx_frames == rx_frames, + '{} should not have any dropped packet'.format(row.name)) + + exp_test_flow_rx_pkts = test_flow_rate_percent / 100.0 * speed_gbps \ + * 1e9 * data_flow_dur_sec / 8.0 / data_pkt_size + deviation = (rx_frames - exp_test_flow_rx_pkts) / float(exp_test_flow_rx_pkts) + pytest_assert(abs(deviation) < tolerance, + '{} should receive {} packets (actual {})'. + format(test_flow_name, exp_test_flow_rx_pkts, rx_frames)) + + if test_flow_pause: + """ In-flight TX bytes of test flows should be held by switch buffer """ + tx_frames_total = sum(row.frames_tx for row in rows if test_flow_name in row.name) + tx_bytes_total = tx_frames_total * data_pkt_size + dut_buffer_size = get_egress_lossless_buffer_size(host_ans=duthost) + + pytest_assert(tx_bytes_total < dut_buffer_size, + 'Total TX bytes {} should be smaller than DUT buffer size {}'.\ + format(tx_bytes_total, dut_buffer_size)) diff --git a/tests/snappi/pfc/test_global_pause.py b/tests/snappi/pfc/test_global_pause.py new file mode 100644 index 00000000000..6adffbb7941 --- /dev/null +++ b/tests/snappi/pfc/test_global_pause.py @@ -0,0 +1,66 @@ +import pytest + +from tests.common.helpers.assertions import pytest_require +from tests.common.fixtures.conn_graph_facts import conn_graph_facts,\ + fanout_graph_facts +from tests.common.fixtures.snappi_fixtures import snappi_api_serv_ip, snappi_api_serv_port,\ + snappi_api, tgen_testbed_config +from tests.common.ixia.qos_fixtures import prio_dscp_map, all_prio_list, lossless_prio_list,\ + lossy_prio_list + +from files.helper import run_pfc_test + +pytestmark = [pytest.mark.topology('tgen')] + + +def test_global_pause(snappi_api, + tgen_testbed_config, + conn_graph_facts, + fanout_graph_facts, + duthosts, + rand_one_dut_hostname, + rand_one_dut_portname_oper_up, + lossless_prio_list, + lossy_prio_list, + prio_dscp_map): + """ + Test if IEEE 802.3X pause (a.k.a., global pause) will impact any priority + + Args: + snappi_api (pytest fixture): Snappi session + tgen_testbed_config (pytest fixture): testbed configuration information + conn_graph_facts (pytest fixture): connection graph + fanout_graph_facts (pytest fixture): fanout graph + duthosts (pytest fixture): list of DUTs + rand_one_dut_hostname (str): hostname of DUT + rand_one_dut_portname_oper_up (str): name of port to test, e.g., 's6100-1|Ethernet0' + lossless_prio_list (pytest fixture): list of all the lossless priorities + lossy_prio_list (pytest fixture): list of all the lossy priorities + prio_dscp_map (pytest fixture): priority vs. DSCP map (key = priority). + + Returns: + N/A + """ + + dut_hostname, dut_port = rand_one_dut_portname_oper_up.split('|') + pytest_require(rand_one_dut_hostname == dut_hostname, + "Port is not mapped to the expected DUT") + + testbed_config, port_config_list = tgen_testbed_config + duthost = duthosts[rand_one_dut_hostname] + test_prio_list = lossless_prio_list + bg_prio_list = lossy_prio_list + + run_pfc_test(api=snappi_api, + testbed_config=testbed_config, + port_config_list=port_config_list, + conn_data=conn_graph_facts, + fanout_data=fanout_graph_facts, + duthost=duthost, + dut_port=dut_port, + global_pause=True, + pause_prio_list=None, + test_prio_list=test_prio_list, + bg_prio_list=bg_prio_list, + prio_dscp_map=prio_dscp_map, + test_traffic_pause=False) diff --git a/tests/snappi/pfc/test_pfc_pause_lossless.py b/tests/snappi/pfc/test_pfc_pause_lossless.py new file mode 100644 index 00000000000..a9f2460d9a8 --- /dev/null +++ b/tests/snappi/pfc/test_pfc_pause_lossless.py @@ -0,0 +1,264 @@ +import logging +import pytest + +from files.helper import run_pfc_test +from tests.common.helpers.assertions import pytest_assert, pytest_require +from tests.common.fixtures.conn_graph_facts import conn_graph_facts,\ + fanout_graph_facts +from tests.common.fixtures.snappi_fixtures import snappi_api_serv_ip, snappi_api_serv_port,\ + snappi_api, tgen_testbed_config +from tests.common.ixia.qos_fixtures import prio_dscp_map, all_prio_list, lossless_prio_list,\ + lossy_prio_list +from tests.common.reboot import reboot +from tests.common.utilities import wait_until + +logger = logging.getLogger(__name__) + +pytestmark = [pytest.mark.topology('tgen')] + + +def test_pfc_pause_single_lossless_prio(snappi_api, + tgen_testbed_config, + conn_graph_facts, + fanout_graph_facts, + duthosts, + rand_one_dut_hostname, + rand_one_dut_portname_oper_up, + enum_dut_lossless_prio, + all_prio_list, + prio_dscp_map): + """ + Test if PFC can pause a single lossless priority + + Args: + snappi_api (pytest fixture): Snappi session + tgen_testbed_config (pytest fixture): testbed configuration information + conn_graph_facts (pytest fixture): connection graph + fanout_graph_facts (pytest fixture): fanout graph + duthosts (pytest fixture): list of DUTs + rand_one_dut_hostname (str): hostname of DUT + rand_one_dut_portname_oper_up (str): port to test, e.g., 's6100-1|Ethernet0' + enum_dut_lossless_prio (str): lossless priority to test, e.g., 's6100-1|3' + all_prio_list (pytest fixture): list of all the priorities + prio_dscp_map (pytest fixture): priority vs. DSCP map (key = priority). + + Returns: + N/A + """ + + dut_hostname, dut_port = rand_one_dut_portname_oper_up.split('|') + dut_hostname2, lossless_prio = enum_dut_lossless_prio.split('|') + pytest_require(rand_one_dut_hostname == dut_hostname == dut_hostname2, + "Priority and port are not mapped to the expected DUT") + + testbed_config, port_config_list = tgen_testbed_config + duthost = duthosts[rand_one_dut_hostname] + lossless_prio = int(lossless_prio) + + pause_prio_list = [lossless_prio] + test_prio_list = [lossless_prio] + bg_prio_list = [p for p in all_prio_list] + bg_prio_list.remove(lossless_prio) + + run_pfc_test(api=snappi_api, + testbed_config=testbed_config, + port_config_list=port_config_list, + conn_data=conn_graph_facts, + fanout_data=fanout_graph_facts, + duthost=duthost, + dut_port=dut_port, + global_pause=False, + pause_prio_list=pause_prio_list, + test_prio_list=test_prio_list, + bg_prio_list=bg_prio_list, + prio_dscp_map=prio_dscp_map, + test_traffic_pause=True) + + +def test_pfc_pause_multi_lossless_prio(snappi_api, + tgen_testbed_config, + conn_graph_facts, + fanout_graph_facts, + duthosts, + rand_one_dut_hostname, + rand_one_dut_portname_oper_up, + lossless_prio_list, + lossy_prio_list, + prio_dscp_map): + """ + Test if PFC can pause multiple lossless priorities + + Args: + snappi_api (pytest fixture): Snappi session + tgen_testbed_config (pytest fixture): testbed configuration information + conn_graph_facts (pytest fixture): connection graph + fanout_graph_facts (pytest fixture): fanout graph + duthosts (pytest fixture): list of DUTs + rand_one_dut_hostname (str): hostname of DUT + rand_one_dut_portname_oper_up (str): port to test, e.g., 's6100-1|Ethernet0' + lossless_prio_list (pytest fixture): list of all the lossless priorities + lossy_prio_list (pytest fixture): list of all the lossy priorities + prio_dscp_map (pytest fixture): priority vs. DSCP map (key = priority). + + Returns: + N/A + """ + + dut_hostname, dut_port = rand_one_dut_portname_oper_up.split('|') + pytest_require(rand_one_dut_hostname == dut_hostname, + "Port is not mapped to the expected DUT") + + testbed_config, port_config_list = tgen_testbed_config + duthost = duthosts[rand_one_dut_hostname] + pause_prio_list = lossless_prio_list + test_prio_list = lossless_prio_list + bg_prio_list = lossy_prio_list + + run_pfc_test(api=snappi_api, + testbed_config=testbed_config, + port_config_list=port_config_list, + conn_data=conn_graph_facts, + fanout_data=fanout_graph_facts, + duthost=duthost, + dut_port=dut_port, + global_pause=False, + pause_prio_list=pause_prio_list, + test_prio_list=test_prio_list, + bg_prio_list=bg_prio_list, + prio_dscp_map=prio_dscp_map, + test_traffic_pause=True) + + +@pytest.mark.disable_loganalyzer +@pytest.mark.parametrize('reboot_type', ['warm', 'cold', 'fast']) +def test_pfc_pause_single_lossless_prio_reboot(snappi_api, + tgen_testbed_config, + conn_graph_facts, + fanout_graph_facts, + localhost, + duthosts, + rand_one_dut_hostname, + rand_one_dut_portname_oper_up, + rand_lossless_prio, + all_prio_list, + prio_dscp_map, + reboot_type): + """ + Test if PFC can pause a single lossless priority even after various types of reboot + + Args: + snappi_api (pytest fixture): Snappi session + tgen_testbed_config (pytest fixture): testbed configuration information + conn_graph_facts (pytest fixture): connection graph + fanout_graph_facts (pytest fixture): fanout graph + localhost (pytest fixture): localhost handle + duthosts (pytest fixture): list of DUTs + rand_one_dut_hostname (str): hostname of DUT + rand_one_dut_portname_oper_up (str): port to test, e.g., 's6100-1|Ethernet0' + rand_lossless_prio (str): lossless priority to test, e.g., 's6100-1|3' + all_prio_list (pytest fixture): list of all the priorities + prio_dscp_map (pytest fixture): priority vs. DSCP map (key = priority). + reboot_type (str): reboot type to be issued on the DUT + + Returns: + N/A + """ + dut_hostname, dut_port = rand_one_dut_portname_oper_up.split('|') + dut_hostname2, lossless_prio = rand_lossless_prio.split('|') + pytest_require(rand_one_dut_hostname == dut_hostname == dut_hostname2, + "Priority and port are not mapped to the expected DUT") + + testbed_config, port_config_list = tgen_testbed_config + duthost = duthosts[rand_one_dut_hostname] + lossless_prio = int(lossless_prio) + + pause_prio_list = [lossless_prio] + test_prio_list = [lossless_prio] + bg_prio_list = [p for p in all_prio_list] + bg_prio_list.remove(lossless_prio) + + logger.info("Issuing a {} reboot on the dut {}".format(reboot_type, duthost.hostname)) + reboot(duthost, localhost, reboot_type=reboot_type) + logger.info("Wait until the system is stable") + pytest_assert(wait_until(300, 20, duthost.critical_services_fully_started), + "Not all critical services are fully started") + + run_pfc_test(api=snappi_api, + testbed_config=testbed_config, + port_config_list=port_config_list, + conn_data=conn_graph_facts, + fanout_data=fanout_graph_facts, + duthost=duthost, + dut_port=dut_port, + global_pause=False, + pause_prio_list=pause_prio_list, + test_prio_list=test_prio_list, + bg_prio_list=bg_prio_list, + prio_dscp_map=prio_dscp_map, + test_traffic_pause=True) + + +@pytest.mark.disable_loganalyzer +@pytest.mark.parametrize('reboot_type', ['warm', 'cold', 'fast']) +def test_pfc_pause_multi_lossless_prio_reboot(snappi_api, + tgen_testbed_config, + conn_graph_facts, + fanout_graph_facts, + localhost, + duthosts, + rand_one_dut_hostname, + rand_one_dut_portname_oper_up, + lossless_prio_list, + lossy_prio_list, + prio_dscp_map, + reboot_type): + """ + Test if PFC can pause multiple lossless priorities even after various types of reboot + + Args: + snappi_api (pytest fixture): Snappi session + tgen_testbed_config (pytest fixture): testbed configuration information + conn_graph_facts (pytest fixture): connection graph + fanout_graph_facts (pytest fixture): fanout graph + localhost (pytest fixture): localhost handle + duthosts (pytest fixture): list of DUTs + rand_one_dut_hostname (str): hostname of DUT + rand_one_dut_portname_oper_up (str): port to test, e.g., 's6100-1|Ethernet0' + lossless_prio_list (pytest fixture): list of all the lossless priorities + lossy_prio_list (pytest fixture): list of all the lossy priorities + prio_dscp_map (pytest fixture): priority vs. DSCP map (key = priority). + reboot_type (str): reboot type to be issued on the DUT + + Returns: + N/A + """ + + dut_hostname, dut_port = rand_one_dut_portname_oper_up.split('|') + pytest_require(rand_one_dut_hostname == dut_hostname, + "Port is not mapped to the expected DUT") + + testbed_config, port_config_list = tgen_testbed_config + duthost = duthosts[rand_one_dut_hostname] + pause_prio_list = lossless_prio_list + test_prio_list = lossless_prio_list + bg_prio_list = lossy_prio_list + + logger.info("Issuing a {} reboot on the dut {}".format(reboot_type, duthost.hostname)) + reboot(duthost, localhost, reboot_type=reboot_type) + logger.info("Wait until the system is stable") + pytest_assert(wait_until(300, 20, duthost.critical_services_fully_started), + "Not all critical services are fully started") + + run_pfc_test(api=snappi_api, + testbed_config=testbed_config, + port_config_list=port_config_list, + conn_data=conn_graph_facts, + fanout_data=fanout_graph_facts, + duthost=duthost, + dut_port=dut_port, + global_pause=False, + pause_prio_list=pause_prio_list, + test_prio_list=test_prio_list, + bg_prio_list=bg_prio_list, + prio_dscp_map=prio_dscp_map, + test_traffic_pause=True) diff --git a/tests/snappi/pfc/test_pfc_pause_lossy.py b/tests/snappi/pfc/test_pfc_pause_lossy.py new file mode 100644 index 00000000000..c542eb580a8 --- /dev/null +++ b/tests/snappi/pfc/test_pfc_pause_lossy.py @@ -0,0 +1,262 @@ +import logging +import pytest + +from files.helper import run_pfc_test +from tests.common.helpers.assertions import pytest_assert, pytest_require +from tests.common.fixtures.conn_graph_facts import conn_graph_facts,\ + fanout_graph_facts +from tests.common.fixtures.snappi_fixtures import snappi_api_serv_ip, snappi_api_serv_port,\ + snappi_api, tgen_testbed_config +from tests.common.ixia.qos_fixtures import prio_dscp_map, all_prio_list, lossless_prio_list,\ + lossy_prio_list +from tests.common.reboot import reboot +from tests.common.utilities import wait_until + +logger = logging.getLogger(__name__) + +pytestmark = [pytest.mark.topology('tgen')] + +def test_pfc_pause_single_lossy_prio(snappi_api, + tgen_testbed_config, + conn_graph_facts, + fanout_graph_facts, + duthosts, + rand_one_dut_hostname, + rand_one_dut_portname_oper_up, + enum_dut_lossy_prio, + all_prio_list, + prio_dscp_map): + """ + Test if PFC will impact a single lossy priority + + Args: + snappi_api (pytest fixture): Snappi session + tgen_testbed_config (pytest fixture): testbed configuration information + conn_graph_facts (pytest fixture): connection graph + fanout_graph_facts (pytest fixture): fanout graph + duthosts (pytest fixture): list of DUTs + rand_one_dut_hostname (str): hostname of DUT + rand_one_dut_portname_oper_up (str): port to test, e.g., 's6100-1|Ethernet0' + enum_dut_lossy_prio (str): name of lossy priority to test, e.g., 's6100-1|2' + all_prio_list (pytest fixture): list of all the priorities + prio_dscp_map (pytest fixture): priority vs. DSCP map (key = priority). + + Returns: + N/A + """ + + dut_hostname, dut_port = rand_one_dut_portname_oper_up.split('|') + dut_hostname2, lossy_prio = enum_dut_lossy_prio.split('|') + pytest_require(rand_one_dut_hostname == dut_hostname == dut_hostname2, + "Priority and port are not mapped to the expected DUT") + + testbed_config, port_config_list = tgen_testbed_config + duthost = duthosts[rand_one_dut_hostname] + lossy_prio = int(lossy_prio) + + pause_prio_list = [lossy_prio] + test_prio_list = [lossy_prio] + bg_prio_list = [p for p in all_prio_list] + bg_prio_list.remove(lossy_prio) + + run_pfc_test(api=snappi_api, + testbed_config=testbed_config, + port_config_list=port_config_list, + conn_data=conn_graph_facts, + fanout_data=fanout_graph_facts, + duthost=duthost, + dut_port=dut_port, + global_pause=False, + pause_prio_list=pause_prio_list, + test_prio_list=test_prio_list, + bg_prio_list=bg_prio_list, + prio_dscp_map=prio_dscp_map, + test_traffic_pause=False) + +def test_pfc_pause_multi_lossy_prio(snappi_api, + tgen_testbed_config, + conn_graph_facts, + fanout_graph_facts, + duthosts, + rand_one_dut_hostname, + rand_one_dut_portname_oper_up, + lossless_prio_list, + lossy_prio_list, + prio_dscp_map): + """ + Test if PFC will impact multiple lossy priorities + + Args: + snappi_api (pytest fixture): SNAPPI session + tgen_testbed_config (pytest fixture): testbed configuration information + conn_graph_facts (pytest fixture): connection graph + fanout_graph_facts (pytest fixture): fanout graph + duthosts (pytest fixture): list of DUTs + rand_one_dut_hostname (str): hostname of DUT + rand_one_dut_portname_oper_up (str): port to test, e.g., 's6100-1|Ethernet0' + lossless_prio_list (pytest fixture): list of all the lossless priorities + lossy_prio_list (pytest fixture): list of all the lossy priorities + prio_dscp_map (pytest fixture): priority vs. DSCP map (key = priority). + + Returns: + N/A + """ + + dut_hostname, dut_port = rand_one_dut_portname_oper_up.split('|') + pytest_require(rand_one_dut_hostname == dut_hostname, + "Port is not mapped to the expected DUT") + + testbed_config, port_config_list = tgen_testbed_config + duthost = duthosts[rand_one_dut_hostname] + pause_prio_list = lossy_prio_list + test_prio_list = lossy_prio_list + bg_prio_list = lossless_prio_list + + run_pfc_test(api=snappi_api, + testbed_config=testbed_config, + port_config_list=port_config_list, + conn_data=conn_graph_facts, + fanout_data=fanout_graph_facts, + duthost=duthost, + dut_port=dut_port, + global_pause=False, + pause_prio_list=pause_prio_list, + test_prio_list=test_prio_list, + bg_prio_list=bg_prio_list, + prio_dscp_map=prio_dscp_map, + test_traffic_pause=False) + + +@pytest.mark.disable_loganalyzer +@pytest.mark.parametrize('reboot_type', ['warm', 'cold', 'fast']) +def test_pfc_pause_single_lossy_prio_reboot(snappi_api, + tgen_testbed_config, + conn_graph_facts, + fanout_graph_facts, + localhost, + duthosts, + rand_one_dut_hostname, + rand_one_dut_portname_oper_up, + rand_lossy_prio, + all_prio_list, + prio_dscp_map, + reboot_type): + """ + Test if PFC will impact a single lossy priority after various kinds of reboots + + Args: + snappi_api (pytest fixture): SNAPPI session + tgen_testbed_config (pytest fixture): testbed configuration information + conn_graph_facts (pytest fixture): connection graph + fanout_graph_facts (pytest fixture): fanout graph + localhost (pytest fixture): localhost handle + duthosts (pytest fixture): list of DUTs + rand_one_dut_hostname (str): hostname of DUT + rand_one_dut_portname_oper_up (str): port to test, e.g., 's6100-1|Ethernet0' + rand_lossy_prio (str): lossy priority to test, e.g., 's6100-1|2' + all_prio_list (pytest fixture): list of all the priorities + prio_dscp_map (pytest fixture): priority vs. DSCP map (key = priority). + reboot_type (str): reboot type to be issued on the DUT + + Returns: + N/A + """ + + dut_hostname, dut_port = rand_one_dut_portname_oper_up.split('|') + dut_hostname2, lossy_prio = rand_lossy_prio.split('|') + pytest_require(rand_one_dut_hostname == dut_hostname == dut_hostname2, + "Priority and port are not mapped to the expected DUT") + + testbed_config, port_config_list = tgen_testbed_config + duthost = duthosts[rand_one_dut_hostname] + lossy_prio = int(lossy_prio) + + pause_prio_list = [lossy_prio] + test_prio_list = [lossy_prio] + bg_prio_list = [p for p in all_prio_list] + bg_prio_list.remove(lossy_prio) + + logger.info("Issuing a {} reboot on the dut {}".format(reboot_type, duthost.hostname)) + reboot(duthost, localhost, reboot_type=reboot_type) + logger.info("Wait until the system is stable") + pytest_assert(wait_until(300, 20, duthost.critical_services_fully_started), + "Not all critical services are fully started") + + run_pfc_test(api=snappi_api, + testbed_config=testbed_config, + port_config_list=port_config_list, + conn_data=conn_graph_facts, + fanout_data=fanout_graph_facts, + duthost=duthost, + dut_port=dut_port, + global_pause=False, + pause_prio_list=pause_prio_list, + test_prio_list=test_prio_list, + bg_prio_list=bg_prio_list, + prio_dscp_map=prio_dscp_map, + test_traffic_pause=False) + +@pytest.mark.disable_loganalyzer +@pytest.mark.parametrize('reboot_type', ['warm', 'cold', 'fast']) +def test_pfc_pause_multi_lossy_prio_reboot(snappi_api, + tgen_testbed_config, + conn_graph_facts, + fanout_graph_facts, + localhost, + duthosts, + rand_one_dut_hostname, + rand_one_dut_portname_oper_up, + lossless_prio_list, + lossy_prio_list, + prio_dscp_map, + reboot_type): + """ + Test if PFC will impact multiple lossy priorities after various kinds of reboots + + Args: + snappi_api (pytest fixture): SNAPPI session + tgen_testbed_config (pytest fixture): testbed configuration information + conn_graph_facts (pytest fixture): connection graph + fanout_graph_facts (pytest fixture): fanout graph + localhost (pytest fixture): localhost handle + duthosts (pytest fixture): list of DUTs + rand_one_dut_hostname (str): hostname of DUT + rand_one_dut_portname_oper_up (str): port to test, e.g., 's6100-1|Ethernet0' + lossless_prio_list (pytest fixture): list of all the lossless priorities + lossy_prio_list (pytest fixture): list of all the lossy priorities + prio_dscp_map (pytest fixture): priority vs. DSCP map (key = priority). + reboot_type (str): reboot type to be issued on the DUT + + Returns: + N/A + """ + + dut_hostname, dut_port = rand_one_dut_portname_oper_up.split('|') + pytest_require(rand_one_dut_hostname == dut_hostname, + "Port is not mapped to the expected DUT") + + testbed_config, port_config_list = tgen_testbed_config + duthost = duthosts[rand_one_dut_hostname] + pause_prio_list = lossy_prio_list + test_prio_list = lossy_prio_list + bg_prio_list = lossless_prio_list + + logger.info("Issuing a {} reboot on the dut {}".format(reboot_type, duthost.hostname)) + reboot(duthost, localhost, reboot_type=reboot_type) + logger.info("Wait until the system is stable") + pytest_assert(wait_until(300, 20, duthost.critical_services_fully_started), + "Not all critical services are fully started") + + run_pfc_test(api=snappi_api, + testbed_config=testbed_config, + port_config_list=port_config_list, + conn_data=conn_graph_facts, + fanout_data=fanout_graph_facts, + duthost=duthost, + dut_port=dut_port, + global_pause=False, + pause_prio_list=pause_prio_list, + test_prio_list=test_prio_list, + bg_prio_list=bg_prio_list, + prio_dscp_map=prio_dscp_map, + test_traffic_pause=False) From 91bf065cd7a48d22456c6a720f43a5fa186cc83b Mon Sep 17 00:00:00 2001 From: Anish Date: Tue, 8 Jun 2021 08:55:06 +0000 Subject: [PATCH 10/12] pfc tests migrated to snappi --- tests/common/fixtures/snappi_fixtures.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/common/fixtures/snappi_fixtures.py b/tests/common/fixtures/snappi_fixtures.py index f0290481a76..d2b063d1ea9 100644 --- a/tests/common/fixtures/snappi_fixtures.py +++ b/tests/common/fixtures/snappi_fixtures.py @@ -16,7 +16,7 @@ @pytest.fixture(scope="module") def snappi_api_serv_ip(tbinfo): """ - In an tgen testbed, there is no PTF docker. + In a tgen testbed, there is no PTF docker. Hence, we use ptf_ip field to store snappi API server. This fixture returns the IP address of the snappi API server. Args: @@ -30,11 +30,11 @@ def snappi_api_serv_ip(tbinfo): @pytest.fixture(scope="module") def snappi_api_serv_port(duthosts, rand_one_dut_hostname): """ - This fixture returns the REST API port of the Snappi API server. + This fixture returns the TCP Port of the Snappi API server. Args: duthost (pytest fixture): The duthost fixture. Returns: - snappi API server REST port. + snappi API server port. """ duthost = duthosts[rand_one_dut_hostname] return (duthost.host.options['variable_manager']. @@ -46,7 +46,8 @@ def snappi_api_serv_port(duthosts, rand_one_dut_hostname): def snappi_api(snappi_api_serv_ip, snappi_api_serv_port): """ - Snappi session fixture for snappi Tgen API + Fixture for session handle, + for creating snappi objects and making API calls. Args: snappi_api_serv_ip (pytest fixture): snappi_api_serv_ip fixture snappi_api_serv_port (pytest fixture): snappi_api_serv_port fixture. @@ -344,6 +345,7 @@ def tgen_testbed_config(conn_graph_facts, fanout_graph_facts (pytest fixture) duthosts (pytest fixture): list of DUTs rand_one_dut_hostname (pytest fixture): DUT hostname + snappi_api(pytest fixture): Snappi API fixture Returns: - config (obj): Tgen API config of the testbed @@ -400,8 +402,6 @@ def tgen_testbed_config(conn_graph_facts, pfc.pfc_class_6 = 6 pfc.pfc_class_7 = 7 - l1_config.flow_control.choice = l1_config.flow_control.IEEE_802_1QBB - port_config_list = [] config_result = __vlan_intf_config(config=config, From 903b0551cce6d800ca2710b8ef75ba013a5c4574 Mon Sep 17 00:00:00 2001 From: Anish Date: Tue, 8 Jun 2021 14:08:40 +0000 Subject: [PATCH 11/12] pfc tests migration to snappi --- tests/snappi/pfc/files/helper.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/snappi/pfc/files/helper.py b/tests/snappi/pfc/files/helper.py index be2de66b7ae..90c7366e4f5 100644 --- a/tests/snappi/pfc/files/helper.py +++ b/tests/snappi/pfc/files/helper.py @@ -224,7 +224,7 @@ def __gen_traffic(testbed_config, test_flow.size.fixed = data_pkt_size test_flow.rate.percentage = test_flow_rate_percent test_flow.duration.fixed_seconds.seconds = data_flow_dur_sec - test_flow.duration.fixed_seconds.delay.nanoseconds = data_flow_delay_nanosec + test_flow.duration.fixed_seconds.delay.nanoseconds = int(data_flow_delay_nanosec) test_flow.metrics.enable = True test_flow.metrics.loss = True @@ -251,7 +251,7 @@ def __gen_traffic(testbed_config, bg_flow.size.fixed = data_pkt_size bg_flow.rate.percentage = bg_flow_rate_percent bg_flow.duration.fixed_seconds.seconds = data_flow_dur_sec - bg_flow.duration.fixed_seconds.delay.nanoseconds = data_flow_delay_nanosec + bg_flow.duration.fixed_seconds.delay.nanoseconds = int(data_flow_delay_nanosec) bg_flow.metrics.enable = True bg_flow.metrics.loss = True From cf37111f3d5da94e4fe44448442c3918b7cbc1bb Mon Sep 17 00:00:00 2001 From: Anish Date: Wed, 9 Jun 2021 10:47:18 +0000 Subject: [PATCH 12/12] Pfc tests migration from abstract to snappi --- .../{test_global_pause.py => test_global_pause_with_snappi.py} | 0 ...c_pause_lossless.py => test_pfc_pause_lossless_with_snappi.py} | 0 ...est_pfc_pause_lossy.py => test_pfc_pause_lossy_with_snappi.py} | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename tests/snappi/pfc/{test_global_pause.py => test_global_pause_with_snappi.py} (100%) rename tests/snappi/pfc/{test_pfc_pause_lossless.py => test_pfc_pause_lossless_with_snappi.py} (100%) rename tests/snappi/pfc/{test_pfc_pause_lossy.py => test_pfc_pause_lossy_with_snappi.py} (100%) diff --git a/tests/snappi/pfc/test_global_pause.py b/tests/snappi/pfc/test_global_pause_with_snappi.py similarity index 100% rename from tests/snappi/pfc/test_global_pause.py rename to tests/snappi/pfc/test_global_pause_with_snappi.py diff --git a/tests/snappi/pfc/test_pfc_pause_lossless.py b/tests/snappi/pfc/test_pfc_pause_lossless_with_snappi.py similarity index 100% rename from tests/snappi/pfc/test_pfc_pause_lossless.py rename to tests/snappi/pfc/test_pfc_pause_lossless_with_snappi.py diff --git a/tests/snappi/pfc/test_pfc_pause_lossy.py b/tests/snappi/pfc/test_pfc_pause_lossy_with_snappi.py similarity index 100% rename from tests/snappi/pfc/test_pfc_pause_lossy.py rename to tests/snappi/pfc/test_pfc_pause_lossy_with_snappi.py