Example #1
0
    def _setup_interfaces_dualtor(mg_facts, peer_count):
        try:
            connections = []
            vlan_intf = _find_vlan_intferface(mg_facts)
            loopback_intf = _find_loopback_interface(mg_facts)
            vlan_intf_addr = vlan_intf["addr"]
            vlan_intf_prefixlen = vlan_intf["prefixlen"]
            loopback_intf_addr = loopback_intf["addr"]
            loopback_intf_prefixlen = loopback_intf["prefixlen"]

            mux_configs = mux_cable_server_ip(duthost)
            local_interfaces = random.sample(mux_configs.keys(), peer_count)
            for local_interface in local_interfaces:
                connections.append(
                    {
                        "local_intf": loopback_intf["name"],
                        "local_addr": "%s/%s" % (loopback_intf_addr, loopback_intf_prefixlen),
                        "neighbor_intf": "eth%s" % mg_facts["minigraph_port_indices"][local_interface],
                        "neighbor_addr": "%s/%s" % (mux_configs[local_interface]["server_ipv4"].split("/")[0], vlan_intf_prefixlen)
                    }
                )

            ptfhost.remove_ip_addresses()

            for conn in connections:
                ptfhost.shell("ifconfig %s %s" % (conn["neighbor_intf"],
                                                  conn["neighbor_addr"]))
            ptfhost.shell("ip route add %s via %s" % (loopback_intf_addr, vlan_intf_addr))
            yield connections

        finally:
            ptfhost.shell("ip route delete %s" % loopback_intf_addr)
            for conn in connections:
                ptfhost.shell("ifconfig %s 0.0.0.0" % conn["neighbor_intf"])
Example #2
0
def _setup_arp_responder(rand_selected_dut, ptfhost, tbinfo, ip_type):
    logging.info('Setup ARP responder in the PTF container  {}'\
        .format(ptfhost.hostname))
    duthost = rand_selected_dut
    mg_facts = duthost.get_extended_minigraph_facts(tbinfo)
    minigraph_ptf_indices = mg_facts['minigraph_ptf_indices']
    mux_config = mux_cable_server_ip(duthost)
    if ip_type == 'ipv4':
        arp_responder_conf = {
            "eth%s" % minigraph_ptf_indices[port]:
            [config["server_ipv4"].split("/")[0]]
            for port, config in mux_config.items()
        }
    else:
        arp_responder_conf = {
            "eth%s" % minigraph_ptf_indices[port]:
            [config["server_ipv6"].split("/")[0]]
            for port, config in mux_config.items()
        }
    ptfhost.copy(content=json.dumps(arp_responder_conf, indent=4),
                 dest="/tmp/from_t1.json")

    ptfhost.host.options["variable_manager"].extra_vars.update(
        {"arp_responder_args": ""})
    ptfhost.template(src="templates/arp_responder.conf.j2",
                     dest="/etc/supervisor/conf.d/arp_responder.conf")
    ptfhost.shell('supervisorctl reread && supervisorctl update')
    ptfhost.shell('supervisorctl restart arp_responder')
Example #3
0
def run_arp_responder_ipv6(rand_selected_dut, ptfhost, tbinfo,
                           apply_mock_dual_tor_tables, copy_arp_responder_py):
    """Run arp_responder to enable ptf to respond neighbor solicitation messages"""
    duthost = rand_selected_dut
    mg_facts = duthost.get_extended_minigraph_facts(tbinfo)
    minigraph_ptf_indices = mg_facts['minigraph_ptf_indices']
    mux_config = mux_cable_server_ip(duthost)

    arp_responder_conf = {
        "eth%s" % minigraph_ptf_indices[port]:
        [config["server_ipv6"].split("/")[0]]
        for port, config in mux_config.items()
    }
    ptfhost.copy(content=json.dumps(arp_responder_conf, indent=4),
                 dest="/tmp/from_t1.json")
    ptfhost.host.options["variable_manager"].extra_vars.update(
        {"arp_responder_args": ""})
    ptfhost.template(src="templates/arp_responder.conf.j2",
                     dest="/etc/supervisor/conf.d/arp_responder.conf")
    ptfhost.shell('supervisorctl reread && supervisorctl update')
    ptfhost.shell('supervisorctl restart arp_responder')

    yield

    ptfhost.shell('supervisorctl restart arp_responder')
Example #4
0
def announce_new_neighbor(ptfadapter, rand_selected_dut, tbinfo):
    """Utility fixture to announce new neighbor from a mux port."""
    def _announce_new_neighbor_gen():
        """Generator to announce the neighbor to a different interface at each iteration."""
        for dut_iface in dut_ifaces:
            update_iface_func = yield dut_iface
            if callable(update_iface_func):
                update_iface_func(dut_iface)
            ptf_iface = dut_to_ptf_intf_map[dut_iface]
            garp_packet = testutils.simple_arp_packet(
                eth_src=NEW_NEIGHBOR_HWADDR,
                hw_snd=NEW_NEIGHBOR_HWADDR,
                ip_snd=NEW_NEIGHBOR_IPV4_ADDR,
                ip_tgt=NEW_NEIGHBOR_IPV4_ADDR,
                arp_op=2)
            logging.info(
                "GARP packet to announce new neighbor %s to mux interface %s:\n%s",
                NEW_NEIGHBOR_IPV4_ADDR, dut_iface,
                dump_scapy_packet_show_output(garp_packet))
            testutils.send(ptfadapter, int(ptf_iface), garp_packet, count=5)
            # let the generator stops here to allow the caller to execute testings
            yield

    dut_to_ptf_intf_map = rand_selected_dut.get_extended_minigraph_facts(
        tbinfo)['minigraph_ptf_indices']
    mux_configs = mux_cable_server_ip(rand_selected_dut)
    dut_ifaces = mux_configs.keys()
    random.shuffle(dut_ifaces)
    return _announce_new_neighbor_gen()
Example #5
0
def get_nexthops(duthost, tbinfo, ipv6=False, count=1):
    mg_facts = duthost.get_extended_minigraph_facts(tbinfo)
    vlan_intf = mg_facts['minigraph_vlan_interfaces'][1 if ipv6 else 0]
    prefix_len = vlan_intf['prefixlen']

    if is_dualtor(tbinfo):
        server_ips = mux_cable_server_ip(duthost)
        vlan_intfs = natsort.natsorted(server_ips.keys())
        nexthop_devs = [
            mg_facts["minigraph_ptf_indices"][_] for _ in vlan_intfs
        ]
        server_ip_key = "server_ipv6" if ipv6 else "server_ipv4"
        nexthop_addrs = [
            server_ips[_][server_ip_key].split("/")[0] for _ in vlan_intfs
        ]
    else:
        vlan_subnet = ipaddress.ip_network(vlan_intf['subnet'])
        vlan_ports = mg_facts['minigraph_vlans'][
            mg_facts['minigraph_vlan_interfaces'][1 if ipv6 else 0]
            ['attachto']]['members']
        vlan_ptf_ports = [
            mg_facts['minigraph_ptf_indices'][port] for port in vlan_ports
        ]
        nexthop_devs = vlan_ptf_ports
        nexthop_addrs = [
            str(vlan_subnet[i + 2]) for i in range(len(nexthop_devs))
        ]
    count = min(count, len(nexthop_devs))
    indices = random.sample(list(range(len(nexthop_devs))), k=count)
    return prefix_len, [nexthop_addrs[_]
                        for _ in indices], [nexthop_devs[_] for _ in indices]
Example #6
0
def get_nexthops(duthost, tbinfo, ipv6=False, count=1):
    mg_facts = duthost.get_extended_minigraph_facts(tbinfo)
    vlan_intf = mg_facts['minigraph_vlan_interfaces'][1 if ipv6 else 0]
    prefix_len = vlan_intf['prefixlen']

    is_backend_topology = mg_facts.get(constants.IS_BACKEND_TOPOLOGY_KEY, False)
    if is_dualtor(tbinfo):
        server_ips = mux_cable_server_ip(duthost)
        vlan_intfs = natsort.natsorted(server_ips.keys())
        nexthop_devs = [mg_facts["minigraph_ptf_indices"][_] for _ in vlan_intfs]
        server_ip_key = "server_ipv6" if ipv6 else "server_ipv4"
        nexthop_addrs = [server_ips[_][server_ip_key].split("/")[0] for _ in vlan_intfs]
        nexthop_interfaces = nexthop_devs
    else:
        vlan_subnet = ipaddress.ip_network(vlan_intf['subnet'])
        vlan = mg_facts['minigraph_vlans'][mg_facts['minigraph_vlan_interfaces'][1 if ipv6 else 0]['attachto']]
        vlan_ports = vlan['members']
        vlan_id = vlan['vlanid']
        vlan_ptf_ports = [mg_facts['minigraph_ptf_indices'][port] for port in vlan_ports]
        nexthop_devs = vlan_ptf_ports
        # backend topology use ethx.x(e.g. eth30.1000) during servers and T0 in ptf
        # in other topology use ethx(e.g. eth30)
        if is_backend_topology:
            nexthop_interfaces = [str(dev) + constants.VLAN_SUB_INTERFACE_SEPARATOR + str(vlan_id) for dev in nexthop_devs]
        else:
            nexthop_interfaces = nexthop_devs
        nexthop_addrs = [str(vlan_subnet[i + 2]) for i in range(len(nexthop_devs))]
    count = min(count, len(nexthop_devs))
    indices = random.sample(list(range(len(nexthop_devs))), k=count)
    return prefix_len, [nexthop_addrs[_] for _ in indices], [nexthop_devs[_] for _ in indices], [nexthop_interfaces[_] for _ in indices]
Example #7
0
def pfc_test_setup(duthosts, rand_one_dut_hostname, tbinfo, ptfhost):
    """
    Generate configurations for the tests

    Args:
        duthosts(AnsibleHost) : multi dut instance
        rand_one_dut_hostname(string) : one of the dut instances from the multi dut

    Yields:
        setup(dict): DUT interfaces, PTF interfaces, PTF IP addresses, and PTF MAC addresses
    """
    """ Get all the active physical interfaces enslaved to the Vlan """
    """ These interfaces are actually server-faced interfaces at T0 """
    duthost = duthosts[rand_one_dut_hostname]
    vlan_members, vlan_id = get_active_vlan_members(duthost)
    """ Get Vlan subnet """
    vlan_subnet = get_vlan_subnet(duthost)
    """ Generate IP addresses for servers in the Vlan """
    vlan_ip_addrs = list()
    if 'dualtor' in tbinfo['topo']['name']:
        servers = mux_cable_server_ip(duthost)
        for intf, value in natsorted(servers.items()):
            vlan_ip_addrs.append(value['server_ipv4'].split('/')[0])
    else:
        vlan_ip_addrs = get_addrs_in_subnet(vlan_subnet, len(vlan_members))
    """ Find correspoinding interfaces on PTF """
    phy_intfs = get_phy_intfs(duthost)
    phy_intfs.sort(key=natural_keys)
    vlan_members.sort(key=natural_keys)
    vlan_members_index = [phy_intfs.index(intf) for intf in vlan_members]
    ptf_intfs = ['eth' + str(i) for i in vlan_members_index]

    duthost.command('sonic-clear fdb all')
    """ Disable DUT's PFC wd """
    duthost.shell('sudo pfcwd stop')

    testbed_type = tbinfo['topo']['name']

    yield {
        'vlan_members': vlan_members,
        'vlan_id': vlan_id,
        'ptf_intfs': ptf_intfs,
        'vlan_ip_addrs': vlan_ip_addrs,
        'testbed_type': testbed_type
    }

    duthost.command('sonic-clear fdb all')
    """ Enable DUT's PFC wd """
    duthost.shell('sudo pfcwd start_default')
Example #8
0
def setup_interfaces(ptfhost, upper_tor_host, lower_tor_host, tbinfo):
    """Setup the interfaces used by the new BGP sessions on PTF."""

    def _find_test_lo_interface(mg_facts):
        for loopback in mg_facts["minigraph_lo_interfaces"]:
            if loopback["name"] == TEST_DEVICE_INTERFACE:
                return loopback

    def _find_ipv4_vlan(mg_facts):
        for vlan_intf in mg_facts["minigraph_vlan_interfaces"]:
            if is_ipv4_address(vlan_intf["addr"]):
                return vlan_intf

    # find the DUT interface ip used in the bgp session
    upper_tor_mg_facts = upper_tor_host.get_extended_minigraph_facts(tbinfo)
    lower_tor_mg_facts = lower_tor_host.get_extended_minigraph_facts(tbinfo)
    upper_tor_intf = _find_test_lo_interface(upper_tor_mg_facts)
    lower_tor_intf = _find_test_lo_interface(lower_tor_mg_facts)
    assert upper_tor_intf
    assert lower_tor_intf
    upper_tor_intf_addr = "%s/%s" % (upper_tor_intf["addr"], upper_tor_intf["prefixlen"])
    lower_tor_intf_addr = "%s/%s" % (lower_tor_intf["addr"], lower_tor_intf["prefixlen"])

    # find the server ip used in the bgp session
    mux_configs = mux_cable_server_ip(upper_tor_host)
    test_iface = random.choice(mux_configs.keys())
    test_server = mux_configs[test_iface]
    test_server_ip = test_server["server_ipv4"]
    upper_tor_server_ptf_intf_idx = upper_tor_mg_facts["minigraph_port_indices"][test_iface]
    lower_tor_server_ptf_intf_idx = lower_tor_mg_facts["minigraph_port_indices"][test_iface]
    upper_tor_server_ptf_intf = "eth%s" % upper_tor_server_ptf_intf_idx
    lower_tor_server_ptf_intf = "eth%s" % lower_tor_server_ptf_intf_idx
    assert upper_tor_server_ptf_intf == lower_tor_server_ptf_intf

    # find the vlan interface ip, used as next-hop for routes added on ptf
    upper_tor_vlan = _find_ipv4_vlan(upper_tor_mg_facts)
    lower_tor_vlan = _find_ipv4_vlan(lower_tor_mg_facts)
    assert upper_tor_vlan
    assert lower_tor_vlan
    assert upper_tor_vlan["addr"] == lower_tor_vlan["addr"]
    vlan_intf_addr = upper_tor_vlan["addr"]
    vlan_intf_prefixlen = upper_tor_vlan["prefixlen"]

    # construct the server ip with the vlan prefix length
    upper_tor_server_ip = "%s/%s" % (test_server_ip.split("/")[0], vlan_intf_prefixlen)
    lower_tor_server_ip = "%s/%s" % (test_server_ip.split("/")[0], vlan_intf_prefixlen)

    # find ToRs' ASNs
    upper_tor_asn = upper_tor_mg_facts["minigraph_bgp_asn"]
    lower_tor_asn = lower_tor_mg_facts["minigraph_bgp_asn"]
    assert upper_tor_asn == lower_tor_asn

    upper_tor_slb_asn = upper_tor_host.shell("sonic-cfggen -m -d -y /etc/sonic/constants.yml -v \"constants.deployment_id_asn_map[DEVICE_METADATA['localhost']['deployment_id']]\"")["stdout"]
    lower_tor_slb_asn = lower_tor_host.shell("sonic-cfggen -m -d -y /etc/sonic/constants.yml -v \"constants.deployment_id_asn_map[DEVICE_METADATA['localhost']['deployment_id']]\"")["stdout"]

    connections = {
        "upper_tor": {
            "localhost": upper_tor_host,
            "local_intf": TEST_DEVICE_INTERFACE,
            "local_addr": upper_tor_intf_addr,
            "local_asn": upper_tor_asn,
            "test_intf": test_iface,
            "neighbor_intf": upper_tor_server_ptf_intf,
            "neighbor_addr": upper_tor_server_ip,
            "neighbor_asn": upper_tor_slb_asn,
            "exabgp_port": EXABGP_PORT_UPPER_TOR,
        },
        "lower_tor": {
            "localhost": lower_tor_host,
            "local_intf": TEST_DEVICE_INTERFACE,
            "local_addr": lower_tor_intf_addr,
            "local_asn": lower_tor_asn,
            "test_intf": test_iface,
            "neighbor_intf": lower_tor_server_ptf_intf,
            "neighbor_addr": lower_tor_server_ip,
            "neighbor_asn": lower_tor_slb_asn,
            "exabgp_port": EXABGP_PORT_LOWER_TOR,
        }
    }

    try:
        ptfhost.shell("ifconfig %s %s" % (upper_tor_server_ptf_intf, upper_tor_server_ip))
        for conn in connections.values():
            ptfhost.shell("ip route add %s via %s" % (conn["local_addr"], vlan_intf_addr))
        yield connections
    finally:
        for conn in connections.values():
            ptfhost.shell("ifconfig %s 0.0.0.0" % conn["neighbor_intf"], module_ignore_errors=True)
            ptfhost.shell("ip route del %s" % conn["local_addr"], module_ignore_errors=True)
Example #9
0
def unknownMacSetup(duthosts, rand_one_dut_hostname, tbinfo):
    """
    Fixture to populate all the parameters needed for the test

    Args:
        duthosts(AnsibleHost) : multi dut instance
        rand_one_dut_hostname(string) : one of the dut instances from the multi dut
        tbinfo(TestbedInfo) : testbed info

    Yields:
        setup(dict): dict of vlan, ptf, portchannel intf mappings

    """
    duthost = duthosts[rand_one_dut_hostname]
    mg_facts = duthost.get_extended_minigraph_facts(tbinfo)
    server_ips = []
    if 'dualtor' in tbinfo['topo']['name']:
        servers = mux_cable_server_ip(duthost)
        for ips in servers.values():
            server_ips.append(ips['server_ipv4'].split('/')[0])

    # populate vlan info
    vlan = dict()
    vlan['addr'] = mg_facts['minigraph_vlan_interfaces'][0]['addr']
    vlan['pfx'] = mg_facts['minigraph_vlan_interfaces'][0]['prefixlen']
    vlan['ips'] = duthost.get_ip_in_range(
        num=1,
        prefix="{}/{}".format(vlan['addr'], vlan['pfx']),
        exclude_ips=[vlan['addr']] +
        server_ips)['ansible_facts']['generated_ips']
    vlan['hostip'] = vlan['ips'][0].split('/')[0]
    vlan['ports'] = mg_facts["minigraph_vlans"].values()[0]["members"]
    # populate dst intf and ptf id
    ptf_portmap = mg_facts['minigraph_ptf_indices']
    dst_port = random.choice(vlan['ports'])
    ptf_dst_port = ptf_portmap[dst_port]
    ptf_vlan_ports = [ptf_portmap[ifname] for ifname in vlan['ports']]
    # populate portchannel intf, peer address and ptf ids
    pc = dict()
    pc_intfs = list()
    ptf_pc_ports = dict()
    for key in mg_facts['minigraph_portchannels']:
        value = mg_facts['minigraph_portchannels'][key]
        for item in value['members']:
            pc_intfs.append(item)
            ptf_pc_ports[item] = (ptf_portmap[item], item, None)
            pc.setdefault(key, []).append(item)

        for element in mg_facts['minigraph_portchannel_interfaces']:
            if key in element['attachto']:
                for member in pc[key]:
                    tmp_list = list(ptf_pc_ports[member])
                    tmp_list[2] = element['peer_addr']
                    ptf_pc_ports[member] = tuple(tmp_list)
                break

    setup = {
        'vlan': vlan,
        'dst_port': dst_port,
        'ptf_dst_port': ptf_dst_port,
        'ptf_vlan_ports': ptf_vlan_ports,
        'pc_intfs': pc_intfs,
        'ptf_pc_ports': ptf_pc_ports
    }
    yield setup
Example #10
0
def test_tunnel_memory_leak(
    toggle_all_simulator_ports_to_upper_tor,
    upper_tor_host, lower_tor_host, ptfhost, 
    ptfadapter, conn_graph_facts, tbinfo, vmhost
):
    """
    Test if there is memory leak for service tunnel_packet_handler.
    Send ip packets from standby TOR T1 to Server, standby TOR will
    forward the packets to active TOR with tunnel, active TOR will
    decapsulate the IPinIP packets, but there is no neighbor for destination
    as we remove neighbor before test, tunnel_packet_handler will be
    triggered and neighbor will be added. Server will receive the packets.
    Check if memory usage is increased after tunnel_packet_handler's
    operation. Since tunnel_packet_handler is only triggered by the
    first packet, loop the process for all severs to trigger it as much
    as possible.
    """
    @contextlib.contextmanager
    def prepare_services(ptfhost):
        """
        Temporarily start arp and icmp service. Make sure to stop garp service,
        otherwise, it will add neighbor entry back automatically.
        It has to stop garp_service for triggering tunnel_packet_handler.
        It has to start arp and icmp service for receiving packets at server side. 
        """
        ptfhost.shell("supervisorctl stop garp_service")
        ptfhost.shell("supervisorctl start arp_responder")
        ptfhost.shell("supervisorctl start icmp_responder")
        yield
        ptfhost.shell("supervisorctl stop arp_responder")
        ptfhost.shell("supervisorctl stop icmp_responder")
	
    @contextlib.contextmanager
    def remove_neighbor(duthost, server_ip):
        """
        Remove ip neighbor before test for triggering tunnel_packet_handler,
        restore it after test
        """
        flush_neighbor_ct = flush_neighbor(duthost, server_ip, True)

        with flush_neighbor_ct:
            command = "ip neighbor show %s" % server_ip
            output = [_.strip() for _ in duthost.shell(command)["stdout_lines"]]
            pytest_assert(not output, "server ip {} isn't flushed in neighbor table.".format(server_ip))
            yield

    pytest_assert(is_tunnel_packet_handler_running(upper_tor_host), 
                "tunnel_packet_handler is not running in SWSS conainter.")

    ptf_t1_intf = random.choice(get_t1_ptf_ports(lower_tor_host, tbinfo))

    all_servers_ips = mux_cable_server_ip(upper_tor_host)

    with prepare_services(ptfhost):
        # Get the original memeory percent before test
        check_memory_leak(upper_tor_host)
        for iface, server_ips in all_servers_ips.items():
            server_ipv4 = server_ips["server_ipv4"].split("/")[0]
            logging.info("Select DUT interface {} and server IP {} to test.".format(iface, server_ipv4))

            pkt, exp_pkt = build_packet_to_server(lower_tor_host, ptfadapter, server_ipv4)

            rm_neighbor = remove_neighbor(upper_tor_host, server_ipv4)

            server_traffic_monitor = ServerTrafficMonitor(
                upper_tor_host, ptfhost, vmhost, tbinfo, iface,
                conn_graph_facts, exp_pkt, existing=True, is_mocked=True
            )
            with rm_neighbor, server_traffic_monitor:
                testutils.send(ptfadapter, int(ptf_t1_intf.strip("eth")), pkt, count=PACKET_COUNT)
                logging.info("Sent {} packets from ptf t1 interface {} on standby TOR {}"
                            .format(PACKET_COUNT, ptf_t1_intf, lower_tor_host.hostname))
                # Check memory usage for every operation, used for debugging if test failed
                check_memory_leak(upper_tor_host)
                pytest_assert(validate_neighbor_entry_exist(upper_tor_host, server_ipv4),
                            "The server ip {} doesn't exist in neighbor table on dut {}. \
                            tunnel_packet_handler isn't triggered.".format(server_ipv4, upper_tor_host.hostname))

            pytest_assert(len(server_traffic_monitor.matched_packets) > PACKET_COUNT /2, 
                        "Received {} expected packets for server {}, drop more than 50%."
                        .format(len(server_traffic_monitor.matched_packets), server_ipv4))
        # sleep 10s to wait memory usage stable, check if there is memory leak
        time.sleep(10)
        check_result = check_memory_leak(upper_tor_host)
        pytest_assert(check_result == False, "Test failed because there is memory leak on {}"
                    .format(upper_tor_host.hostname))
Example #11
0
def get_neighbors(duthost, tbinfo, ipv6=False, count=1):
    topo_type = tbinfo['topo']['name']
    mg_facts = duthost.get_extended_minigraph_facts(tbinfo)

    if 't0' in topo_type:
        vlan_intf = mg_facts['minigraph_vlan_interfaces'][1 if ipv6 else 0]
        prefix_len = vlan_intf['prefixlen']
        vlan_addr = vlan_intf["addr"]

        is_backend_topology = mg_facts.get(constants.IS_BACKEND_TOPOLOGY_KEY,
                                           False)
        if is_dualtor(tbinfo):
            server_ips = mux_cable_server_ip(duthost)
            vlan_intfs = natsort.natsorted(server_ips.keys())
            neighbor_devs = [
                mg_facts["minigraph_ptf_indices"][_] for _ in vlan_intfs
            ]
            server_ip_key = "server_ipv6" if ipv6 else "server_ipv4"
            neighbor_addrs = [
                server_ips[_][server_ip_key].split("/")[0] for _ in vlan_intfs
            ]
            neighbor_interfaces = neighbor_devs
        else:
            vlan_subnet = ipaddress.ip_network(vlan_intf['subnet'])
            vlan = mg_facts['minigraph_vlans'][mg_facts[
                'minigraph_vlan_interfaces'][1 if ipv6 else 0]['attachto']]
            vlan_ports = vlan['members']
            vlan_id = vlan['vlanid']
            vlan_ptf_ports = [
                mg_facts['minigraph_ptf_indices'][port] for port in vlan_ports
            ]
            neighbor_devs = vlan_ptf_ports
            # backend topology use ethx.x(e.g. eth30.1000) during servers and T0 in ptf
            # in other topology use ethx(e.g. eth30)
            if is_backend_topology:
                neighbor_interfaces = [
                    str(dev) + constants.VLAN_SUB_INTERFACE_SEPARATOR +
                    str(vlan_id) for dev in neighbor_devs
                ]
            else:
                neighbor_interfaces = neighbor_devs
            neighbor_addrs = [
                str(vlan_subnet[i + 2]) for i in range(len(neighbor_devs))
            ]
        count = min(count, len(neighbor_devs))
        indices = random.sample(list(range(len(neighbor_devs))), k=count)
        return [vlan_addr for _ in indices], prefix_len, [
            neighbor_addrs[_] for _ in indices
        ], [neighbor_devs[_]
            for _ in indices], [neighbor_interfaces[_] for _ in indices]
    elif 't1' in topo_type:
        t1_ipv4_pattern = '101.0.0.{}'
        t1_ipv6_pattern = '2000:2000::{:x}'
        t0_intfs = get_t0_intfs(mg_facts)
        ptf_ports = [
            mg_facts['minigraph_ptf_indices'][port] for port in t0_intfs
        ]
        count = min(count, len(t0_intfs))
        indices = random.sample(list(range(len(t0_intfs))), k=count)
        if ipv6:
            return [t1_ipv6_pattern.format(idx * 2) for idx in indices], 127, [
                t1_ipv6_pattern.format(idx * 2 + 1) for idx in indices
            ], [t0_intfs[_] for _ in indices], [ptf_ports[_] for _ in indices]
        else:
            return [t1_ipv4_pattern.format(idx * 2) for idx in indices], 31, [
                t1_ipv4_pattern.format(idx * 2 + 1) for idx in indices
            ], [t0_intfs[_] for _ in indices], [ptf_ports[_] for _ in indices]
Example #12
0
def unknownMacSetup(duthosts, rand_one_dut_hostname, tbinfo):
    """
    Fixture to populate all the parameters needed for the test

    Args:
        duthosts(AnsibleHost) : multi dut instance
        rand_one_dut_hostname(string) : one of the dut instances from the multi dut
        tbinfo(TestbedInfo) : testbed info

    Yields:
        setup(dict): dict of vlan, ptf, portchannel intf mappings

    """
    duthost = duthosts[rand_one_dut_hostname]
    # The behavior on Mellanox for unknown MAC is flooding rather than DROP,
    # so we need to skip this test on Mellanox platform
    asic_type = duthost.facts["asic_type"]
    pytest_require(asic_type != "mellanox", "Skip on Mellanox platform")

    mg_facts = duthost.get_extended_minigraph_facts(tbinfo)
    is_backend_topology = mg_facts.get(constants.IS_BACKEND_TOPOLOGY_KEY, False)
    server_ips = []
    if 'dualtor' in tbinfo['topo']['name']:
        servers = mux_cable_server_ip(duthost)
        for ips in servers.values():
            server_ips.append(ips['server_ipv4'].split('/')[0])

    # populate vlan info
    vlan = dict()
    vlan['addr'] = mg_facts['minigraph_vlan_interfaces'][0]['addr']
    vlan['pfx'] = mg_facts['minigraph_vlan_interfaces'][0]['prefixlen']
    vlan['ips'] = duthost.get_ip_in_range(num=1, prefix="{}/{}".format(vlan['addr'], vlan['pfx']),
                                          exclude_ips=[vlan['addr']] + server_ips)['ansible_facts']['generated_ips']
    vlan['hostip'] = vlan['ips'][0].split('/')[0]
    vlan['ports'] = mg_facts["minigraph_vlans"].values()[0]["members"]
    # populate dst intf and ptf id
    ptf_portmap = mg_facts['minigraph_ptf_indices']
    dst_port = random.choice(vlan['ports'])
    if is_backend_topology:
        ptf_dst_port = str(ptf_portmap[dst_port]) + constants.VLAN_SUB_INTERFACE_SEPARATOR + \
                       mg_facts["minigraph_vlans"].values()[0]["vlanid"]
    else:
        ptf_dst_port = ptf_portmap[dst_port]
    ptf_vlan_ports = [ptf_portmap[ifname] for ifname in vlan['ports']]
    # populate portchannel intf, peer address and ptf ids
    pc = dict()
    intfs = list()
    ptf_ports = dict()
    sub_intfs = set()
    if is_backend_topology:
        for vlan_sub_interface in mg_facts['minigraph_vlan_sub_interfaces']:
            sub_intf_name = vlan_sub_interface['attachto']
            if sub_intf_name in intfs:
                continue
            vlan_id = vlan_sub_interface['vlan']
            intf_name = get_intf_by_sub_intf(sub_intf_name, vlan_id)
            sub_intfs.add(sub_intf_name)
            ptf_ports[sub_intf_name] = (ptf_portmap[intf_name], sub_intf_name,
                                           vlan_sub_interface['peer_addr'],
                                           vlan_id)
            intfs = list(sub_intfs)
    else:
        for key in mg_facts['minigraph_portchannels']:
            value = mg_facts['minigraph_portchannels'][key]
            for item in value['members']:
                intfs.append(item)
                ptf_ports[item] = (ptf_portmap[item], item, None, None)
                pc.setdefault(key, []).append(item)

            for element in mg_facts['minigraph_portchannel_interfaces']:
                if key in element['attachto']:
                    for member in pc[key]:
                        tmp_list = list(ptf_ports[member])
                        tmp_list[2] = element['peer_addr']
                        ptf_ports[member] = tuple(tmp_list)
                    break

    setup = {'vlan': vlan,
             'dst_port': dst_port,
             'ptf_dst_port': ptf_dst_port,
             'ptf_vlan_ports': ptf_vlan_ports,
             'intfs': intfs,
             'ptf_ports': ptf_ports
             }
    yield setup