Пример #1
0
def ping_all_neighbors(duthosts, all_cfg_facts, neighbors):
    """
    Pings all neighbors in the neighbor list from all frontend hosts on the DUT..

    Args:
        duthosts: An instance of the duthosts fixture.
        all_cfg_facts: Fixture from voq/conftest.py
        neighbors: A list of neighbor IP addresses.

    """
    for per_host in duthosts.frontend_nodes:
        for asic in per_host.asics:
            cfg_facts = all_cfg_facts[per_host.hostname][asic.asic_index]['ansible_facts']
            inband = get_inband_info(cfg_facts)
            if inband == {}:
                continue

            for neighbor in neighbors:
                logger.info("Ping %s from %s/%s", neighbor, per_host.hostname, asic.asic_index)
                sonic_ping(asic, neighbor, verbose=True)
Пример #2
0
def test_voq_inband_port_create(duthosts):
    """
    Test inband port creation.

    These steps are covered by previous test cases:
        * On each linecard, verify inband ports are present in ASICDB.
        * On each linecard, verify inband router interfaces are present in ASICDB
        * On supervisor card, verify inband router interfaces are present in Chassis App DB

    This test function will cover:
        * On each linecard, verify permanent neighbors for all inband ports.
        * On each linecard, verify kernel routes for all inband ports.
        * Repeat with IPv4, IPv6, dual-stack.


    """
    for per_host in duthosts.frontend_nodes:

        for asic in per_host.asics:
            cfg_facts = asic.config_facts(source="persistent")['ansible_facts']
            dev_sysports = get_device_system_ports(cfg_facts)
            inband_info = get_inband_info(cfg_facts)
            inband_mac = get_sonic_mac(per_host, asic.asic_index,
                                       inband_info['port'])

            inband_ips = []
            if 'ipv6_addr' in inband_info:
                inband_ips.append(inband_info['ipv6_addr'])
            if 'ipv4_addr' in inband_info:
                inband_ips.append(inband_info['ipv4_addr'])

            for neighbor_ip in inband_ips:

                host = per_host
                neighbor_mac = inband_mac
                interface = inband_info['port']

                logger.info(
                    "Check local neighbor on host %s, asic %s for %s/%s via port: %s",
                    host.hostname, str(asic.asic_index), neighbor_ip,
                    neighbor_mac, interface)

                asic_dict = check_local_neighbor_asicdb(
                    asic, neighbor_ip, neighbor_mac)
                encap_idx = asic_dict['encap_index']

                # Check the inband neighbor entry on the supervisor nodes
                sysport_info = find_system_port(dev_sysports,
                                                per_host.facts['slot_num'],
                                                asic.asic_index, interface)
                for sup in duthosts.supervisor_nodes:
                    check_voq_neighbor_on_sup(sup, sysport_info['slot'],
                                              sysport_info['asic'], interface,
                                              neighbor_ip, encap_idx,
                                              inband_mac)

                # Check the neighbor entry on each remote linecard
                for rem_host in duthosts.frontend_nodes:

                    for rem_asic in rem_host.asics:
                        if rem_host == per_host and rem_asic == asic:
                            # skip remote check on local host
                            continue
                        rem_cfg_facts = rem_asic.config_facts(
                            source="persistent")['ansible_facts']
                        remote_inband_info = get_inband_info(rem_cfg_facts)
                        remote_inband_mac = get_sonic_mac(
                            rem_host, rem_asic.asic_index,
                            remote_inband_info['port'])
                        check_voq_remote_neighbor(rem_host, rem_asic,
                                                  neighbor_ip, inband_mac,
                                                  remote_inband_info['port'],
                                                  encap_idx, remote_inband_mac)
Пример #3
0
def test_voq_neighbor_create(duthosts, nbrhosts, nbrhosts_facts):
    """
    Verify neighbor entries are created on linecards for local and remote VMS.

    For local neighbors:
    * ARP/NDP should be resolved when BGP to adjacent VMs is established.
    * On local linecard, verify ASIC DB entries.
        * MAC address matches MAC of neighbor VM.
        * Router interface OID matches back to the correct interface and port the neighbor was learned on.
    * On local linecard, verify show arp/ndp, ip neigh commands.
        * MAC address matches MAC of neighbor VM.
    * On local linecard. verify neighbor table in appDB.
        * MAC address matches MAC of neighbor VM.
    * On supervisor card, verify SYSTEM_NEIGH table in Chassis AppDB (redis-dump -h <ip> -p 6380 -d 12 on supervisor).
        * Verify encap index and MAC address match between ASICDB the Chassis AppDB
    * Repeat with IPv4, IPv6, dual-stack.

    For remote neighbors:
    * When local neighbors are established as in the Local Neighbor testcase, corresponding entries will be established
      on all other line cards.  On each remote card, verify:
    * Verify ASIC DB entries on remote linecards.
        * Verify impose index=True in ASIC DB.
        * Verify MAC address in ASIC DB is the remote neighbor mac.
        * Verify encap index for ASIC DB entry matches Chassis App DB.
        * Verify router interface OID matches the interface the neighbor was learned on.
    * Verify on linecard CLI, show arp/ndp, ip neigh commands.
        * For inband port, MAC should be inband port mac in kernel table and LC appDb.
        * For inband vlan mode, MAC will be remote ASIC mac in kernel table and LC appdb.
    * Verify neighbor table in linecard appdb.
    * Verify static route is installed in kernel routing table with /32 (or /128 for IPv6) for neighbor entry.
    * Repeat with IPv4, IPv6, dual-stack.

    """

    for per_host in duthosts.frontend_nodes:

        for asic in per_host.asics:
            logger.info("Checking local neighbors on host: %s, asic: %s",
                        per_host.hostname, asic.asic_index)
            cfg_facts = asic.config_facts(source="persistent")['ansible_facts']
            dev_sysports = get_device_system_ports(cfg_facts)
            neighs = cfg_facts['BGP_NEIGHBOR']
            inband_info = get_inband_info(cfg_facts)

            # Check each neighbor in table
            for neighbor in neighs:
                local_ip = neighs[neighbor]['local_addr']
                if local_ip == inband_info[
                        'ipv4_addr'] or local_ip == inband_info['ipv6_addr']:
                    # skip inband neighbors
                    continue

                # Check neighbor on local linecard
                local_port = get_port_by_ip(cfg_facts, local_ip)
                show_intf = asic.show_interface(
                    command="status")['ansible_facts']
                if local_port is None:
                    logger.error(
                        "Did not find port for this neighbor %s, must skip",
                        local_ip)
                    continue
                elif "portchannel" in local_port.lower():
                    # TODO: LAG support
                    logger.info(
                        "Port channel is not supported yet by this test, skip port: %s",
                        local_port)
                    continue
                if show_intf['int_status'][local_port]['oper_state'] == "down":
                    logger.error(
                        "Port is down, must skip interface: %s, IP: %s",
                        local_port, local_ip)
                    continue

                neigh_mac = get_neighbor_mac(neighbor, nbrhosts,
                                             nbrhosts_facts)
                if neigh_mac is None:
                    logger.error(
                        "Could not find neighbor MAC, must skip.  IP: %s, port: %s",
                        local_ip, local_port)

                local_dict = check_local_neighbor(per_host, asic, neighbor,
                                                  neigh_mac, local_port)
                logger.info("Local_dict: %s", local_dict)

                # Check the same neighbor entry on the supervisor nodes
                sysport_info = find_system_port(dev_sysports,
                                                per_host.facts['slot_num'],
                                                asic.asic_index, local_port)
                for sup in duthosts.supervisor_nodes:
                    check_voq_neighbor_on_sup(sup, sysport_info['slot'],
                                              sysport_info['asic'], local_port,
                                              neighbor,
                                              local_dict['encap_index'],
                                              neigh_mac)

                # Check the neighbor entry on each remote linecard
                for rem_host in duthosts.frontend_nodes:

                    for rem_asic in rem_host.asics:
                        if rem_host == per_host and rem_asic == asic:
                            # skip remote check on local host
                            continue
                        rem_cfg_facts = rem_asic.config_facts(
                            source="persistent")['ansible_facts']
                        remote_inband_info = get_inband_info(rem_cfg_facts)
                        remote_inband_mac = get_sonic_mac(
                            rem_host, rem_asic.asic_index,
                            remote_inband_info['port'])
                        check_voq_remote_neighbor(rem_host, rem_asic, neighbor,
                                                  neigh_mac,
                                                  remote_inband_info['port'],
                                                  local_dict['encap_index'],
                                                  remote_inband_mac)
Пример #4
0
def test_voq_interface_create(duthosts):
    """
    Verify router interfaces are created on all line cards and present in Chassis App Db.

    * Verify router interface creation on local ports in ASIC DB.
    * PORT_ID should match system port table and traced back to config_db.json, mac and MTU should match as well.
    * Verify SYSTEM_INTERFACE table in Chassis AppDb (redis-dump -h <ip> -p 6380 -d 12 on supervisor).
    * Verify creation interfaces with different MTUs in configdb.json.
    * Verify creation of different subnet masks in configdb.json.
    * Repeat with IPv4, IPv6, dual-stack.

    """
    for per_host in duthosts.frontend_nodes:
        logger.info("Check router interfaces on node: %s", per_host.hostname)

        for asic in per_host.asics:
            cfg_facts = asic.config_facts(source="persistent")['ansible_facts']
            dev_intfs = cfg_facts['INTERFACE']
            dev_sysports = get_device_system_ports(cfg_facts)

            slot = per_host.facts['slot_num']
            rif_ports_in_asicdb = []

            # intf_list = get_router_interface_list(dev_intfs)
            asicdb = AsicDbCli(asic)

            asicdb_intf_key_list = asicdb.get_router_if_list()
            # Check each rif in the asicdb, if it is local port, check VOQ DB for correct RIF.
            # If it is on system port, verify slot/asic/port and OID match a RIF in VoQDB
            for rif in asicdb_intf_key_list:
                rif_type = asicdb.hget_key_value(
                    rif, "SAI_ROUTER_INTERFACE_ATTR_TYPE")
                if rif_type != "SAI_ROUTER_INTERFACE_TYPE_PORT":
                    logger.info("Skip this rif: %s, it is not on a port: %s",
                                rif, rif_type)
                    continue
                else:
                    portid = asicdb.hget_key_value(
                        rif, "SAI_ROUTER_INTERFACE_ATTR_PORT_ID")
                    logger.info("Process RIF %s, Find port with ID: %s", rif,
                                portid)

                porttype = asicdb.get_rif_porttype(portid)
                logger.info("RIF: %s is of type: %s", rif, porttype)
                if porttype == 'hostif':
                    # find the hostif entry to get the physical port the router interface is on.
                    hostifkey = asicdb.find_hostif_by_portid(portid)
                    hostif = asicdb.hget_key_value(hostifkey,
                                                   'SAI_HOSTIF_ATTR_NAME')
                    logger.info("RIF: %s is on local port: %s", rif, hostif)
                    rif_ports_in_asicdb.append(hostif)
                    if hostif not in dev_intfs:
                        pytest.fail(
                            "Port: %s has a router interface, but it isn't in configdb."
                            % portid)

                    # check MTU and ethernet address
                    asicdb.get_and_check_key_value(
                        rif,
                        cfg_facts['PORT'][hostif]['mtu'],
                        field="SAI_ROUTER_INTERFACE_ATTR_MTU")
                    intf_mac = get_sonic_mac(per_host, asic.asic_index, hostif)
                    asicdb.get_and_check_key_value(
                        rif,
                        intf_mac,
                        field="SAI_ROUTER_INTERFACE_ATTR_SRC_MAC_ADDRESS")

                    sup_rif = asicdb.hget_key_value("VIDTORID",
                                                    "oid:" + rif.split(":")[3])
                    sysport_info = find_system_port(dev_sysports, slot,
                                                    asic.asic_index, hostif)
                    for sup in duthosts.supervisor_nodes:
                        check_rif_on_sup(sup, sup_rif, sysport_info['slot'],
                                         sysport_info['asic'], hostif)

                elif porttype == 'sysport':
                    try:
                        port_output = asicdb.hget_key_value(
                            "ASIC_STATE:SAI_OBJECT_TYPE_SYSTEM_PORT:" + portid,
                            field="SAI_SYSTEM_PORT_ATTR_CONFIG_INFO")
                    except RedisKeyNotFound:
                        # not a hostif or system port, log error and continue
                        logger.error(
                            "Did not find OID %s in local or system tables" %
                            portid)
                        continue
                    port_data = json.loads(port_output)
                    for cfg_port in dev_sysports:
                        if dev_sysports[cfg_port][
                                'system_port_id'] == port_data['port_id']:
                            logger.info("RIF: %s is on remote port: %s", rif,
                                        cfg_port)
                            break
                    else:
                        raise AssertionError(
                            "Did not find OID %s in local or system tables" %
                            portid)

                    sys_slot, sys_asic, sys_port = cfg_port.split("|")
                    sup_rif = asicdb.hget_key_value("VIDTORID",
                                                    "oid:" + rif.split(":")[3])
                    for sup in duthosts.supervisor_nodes:
                        check_rif_on_sup(sup, sup_rif, sys_slot, sys_asic,
                                         sys_port)

                elif porttype == 'port':
                    # this is the RIF on the inband port.
                    inband = get_inband_info(cfg_facts)
                    logger.info("RIF: %s is on local port: %s", rif,
                                inband['port'])

                    # check MTU and ethernet address
                    asicdb.get_and_check_key_value(
                        rif,
                        cfg_facts['PORT'][inband['port']]['mtu'],
                        field="SAI_ROUTER_INTERFACE_ATTR_MTU")
                    intf_mac = get_sonic_mac(per_host, asic.asic_index,
                                             inband['port'])
                    asicdb.get_and_check_key_value(
                        rif,
                        intf_mac,
                        field="SAI_ROUTER_INTERFACE_ATTR_SRC_MAC_ADDRESS")

                    sup_rif = asicdb.hget_key_value("VIDTORID",
                                                    "oid:" + rif.split(":")[3])
                    sysport_info = find_system_port(dev_sysports, slot,
                                                    asic.asic_index,
                                                    inband['port'])
                    for sup in duthosts.supervisor_nodes:
                        check_rif_on_sup(sup, sup_rif, sysport_info['slot'],
                                         sysport_info['asic'], inband['port'])

            # Verify each RIF in config had a corresponding local port RIF in the asicDB.
            for rif in dev_intfs:
                pytest_assert(
                    rif in rif_ports_in_asicdb,
                    "Interface %s is in configdb.json but not in asicdb" % rif)
            logger.info(
                "Interfaces %s are present in configdb.json and asicdb" %
                str(dev_intfs.keys()))
Пример #5
0
def test_voq_inband_port_create(duthosts, enum_frontend_dut_hostname,
                                enum_asic_index, all_cfg_facts):
    """
    Test inband port creation.

    These steps are covered by previous test cases:
        * On each linecard, verify inband ports are present in ASICDB.
        * On each linecard, verify inband router interfaces are present in ASICDB
        * On supervisor card, verify inband router interfaces are present in Chassis App DB

    This test function will cover:
        * On each linecard, verify permanent neighbors for all inband ports.
        * On each linecard, verify kernel routes for all inband ports.
        * Repeat with IPv4, IPv6, dual-stack.


    """
    per_host = duthosts[enum_frontend_dut_hostname]
    asic = per_host.asics[
        enum_asic_index if enum_asic_index is not None else 0]
    cfg_facts = all_cfg_facts[per_host.hostname][
        asic.asic_index]['ansible_facts']

    inband_info = get_inband_info(cfg_facts)
    if inband_info == {}:
        logger.info("No inband configuration on this ASIC: %s/%s, skipping",
                    per_host.hostname, asic.asic_index)
        return
    inband_mac = get_sonic_mac(per_host, asic.asic_index, inband_info['port'])

    inband_ips = []
    if 'ipv6_addr' in inband_info:
        inband_ips.append(inband_info['ipv6_addr'])
    if 'ipv4_addr' in inband_info:
        inband_ips.append(inband_info['ipv4_addr'])

    for neighbor_ip in inband_ips:

        host = per_host
        neighbor_mac = inband_mac
        interface = inband_info['port']

        logger.info(
            "Check local neighbor on host %s, asic %s for %s/%s via port: %s",
            host.hostname, str(asic.asic_index), neighbor_ip, neighbor_mac,
            interface)

        asic_dict = check_local_neighbor_asicdb(asic, neighbor_ip,
                                                neighbor_mac)
        encap_idx = asic_dict['encap_index']

        sysport_info = {
            'slot': cfg_facts['DEVICE_METADATA']['localhost']['hostname'],
            'asic': cfg_facts['DEVICE_METADATA']['localhost']['asic_name']
        }

        for sup in duthosts.supervisor_nodes:
            check_voq_neighbor_on_sup(sup, sysport_info['slot'],
                                      sysport_info['asic'], interface,
                                      neighbor_ip, encap_idx, inband_mac)

        # Check the neighbor entry on each remote linecard
        for rem_host in duthosts.frontend_nodes:

            for rem_asic in rem_host.asics:
                if rem_host == per_host and rem_asic == asic:
                    # skip remote check on local host
                    continue
                rem_cfg_facts = all_cfg_facts[rem_host.hostname][
                    rem_asic.asic_index]['ansible_facts']
                remote_inband_info = get_inband_info(rem_cfg_facts)
                if remote_inband_info == {}:
                    logger.info(
                        "No inband configuration on this asic: %s/%s, will be skipped.",
                        rem_host.hostname, rem_asic.asic_index)
                    continue
                remote_inband_mac = get_sonic_mac(rem_host,
                                                  rem_asic.asic_index,
                                                  remote_inband_info['port'])
                check_voq_remote_neighbor(rem_host, rem_asic, neighbor_ip,
                                          inband_mac,
                                          remote_inband_info['port'],
                                          encap_idx, remote_inband_mac)
Пример #6
0
def check_voq_interfaces(duthosts, per_host, asic, cfg_facts):
    """
    Checks router interfaces on a dut.

    Args:
        duthosts: The duthosts fixture
        per_host: Instance of MultiAsicSonic host to check.
        asic: Instance of SonicAsic to check,
        cfg_facts: Config facts for the frontend duthost/asic under test

    """
    logger.info("Check router interfaces on node: %s, asic: %d",
                per_host.hostname, asic.asic_index)

    dev_intfs = cfg_facts.get('INTERFACE', {})
    voq_intfs = cfg_facts.get('VOQ_INBAND_INTERFACE', [])
    dev_sysports = get_device_system_ports(cfg_facts)

    rif_ports_in_asicdb = []

    # intf_list = get_router_interface_list(dev_intfs)
    asicdb = AsicDbCli(asic)
    asicdb_rif_table = asicdb.dump(asicdb.ASIC_ROUTERINTF_TABLE)
    sys_port_table = asicdb.dump(asicdb.ASIC_SYSPORT_TABLE)

    # asicdb_intf_key_list = asicdb.get_router_if_list()
    # Check each rif in the asicdb, if it is local port, check VOQ DB for correct RIF.
    # If it is on system port, verify slot/asic/port and OID match a RIF in VoQDB
    for rif in asicdb_rif_table.keys():
        rif_type = asicdb_rif_table[rif]['value'][
            "SAI_ROUTER_INTERFACE_ATTR_TYPE"]
        if rif_type != "SAI_ROUTER_INTERFACE_TYPE_PORT":
            logger.info("Skip this rif: %s, it is not on a port: %s", rif,
                        rif_type)
            continue
        else:
            portid = asicdb_rif_table[rif]['value'][
                "SAI_ROUTER_INTERFACE_ATTR_PORT_ID"]
            logger.info("Process RIF %s, Find port with ID: %s", rif, portid)

        porttype = asicdb.get_rif_porttype(portid)
        logger.info("RIF: %s is of type: %s", rif, porttype)
        if porttype == 'hostif':
            # find the hostif entry to get the physical port the router interface is on.
            hostifkey = asicdb.find_hostif_by_portid(portid)
            hostif = asicdb.hget_key_value(hostifkey, 'SAI_HOSTIF_ATTR_NAME')
            logger.info("RIF: %s is on local port: %s", rif, hostif)
            rif_ports_in_asicdb.append(hostif)
            if hostif not in dev_intfs and hostif not in voq_intfs:
                pytest.fail(
                    "Port: %s has a router interface, but it isn't in configdb."
                    % portid)

            # check MTU and ethernet address
            pytest_assert(
                asicdb_rif_table[rif]['value']["SAI_ROUTER_INTERFACE_ATTR_MTU"]
                == cfg_facts['PORT'][hostif]['mtu'],
                "MTU for rif %s is not %s" %
                (rif, cfg_facts['PORT'][hostif]['mtu']))
            intf_mac = get_sonic_mac(per_host, asic.asic_index, hostif)
            pytest_assert(
                asicdb_rif_table[rif]['value']
                ["SAI_ROUTER_INTERFACE_ATTR_SRC_MAC_ADDRESS"].lower() ==
                intf_mac.lower(), "MAC for rif %s is not %s" % (rif, intf_mac))

            sysport_info = {
                'slot': cfg_facts['DEVICE_METADATA']['localhost']['hostname'],
                'asic': cfg_facts['DEVICE_METADATA']['localhost']['asic_name']
            }

            if per_host.is_multi_asic and len(duthosts.supervisor_nodes) == 0:
                check_rif_on_sup(per_host, sysport_info['slot'],
                                 sysport_info['asic'], hostif)
            else:
                for sup in duthosts.supervisor_nodes:
                    check_rif_on_sup(sup, sysport_info['slot'],
                                     sysport_info['asic'], hostif)

        elif porttype == 'sysport':
            try:
                port_output = sys_port_table[
                    "ASIC_STATE:SAI_OBJECT_TYPE_SYSTEM_PORT:" +
                    portid]['value']['SAI_SYSTEM_PORT_ATTR_CONFIG_INFO']
            except KeyError:
                # not a hostif or system port, log error and continue
                logger.error("Did not find OID %s in local or system tables" %
                             portid)
                continue
            port_data = json.loads(port_output)
            for cfg_port in dev_sysports:
                if dev_sysports[cfg_port]['system_port_id'] == port_data[
                        'port_id']:
                    logger.info("RIF: %s is on remote port: %s", rif, cfg_port)
                    break
            else:
                raise AssertionError(
                    "Did not find OID %s in local or system tables" % portid)

            sys_slot, sys_asic, sys_port = cfg_port.split("|")
            if per_host.is_multi_asic and len(duthosts.supervisor_nodes) == 0:
                check_rif_on_sup(per_host, sys_slot, sys_asic, sys_port)
            else:
                for sup in duthosts.supervisor_nodes:
                    check_rif_on_sup(sup, sys_slot, sys_asic, sys_port)

        elif porttype == 'port':
            # this is the RIF on the inband port.
            inband = get_inband_info(cfg_facts)
            logger.info("RIF: %s is on local port: %s", rif, inband['port'])

            # check MTU and ethernet address
            pytest_assert(
                asicdb_rif_table[rif]['value']["SAI_ROUTER_INTERFACE_ATTR_MTU"]
                == cfg_facts['PORT'][inband['port']]['mtu'],
                "MTU for rif %s is not %s" %
                (rif, cfg_facts['PORT'][inband['port']]['mtu']))
            intf_mac = get_sonic_mac(per_host, asic.asic_index, inband['port'])
            pytest_assert(
                asicdb_rif_table[rif]['value']
                ["SAI_ROUTER_INTERFACE_ATTR_SRC_MAC_ADDRESS"].lower() ==
                intf_mac.lower(), "MAC for rif %s is not %s" % (rif, intf_mac))

            sysport_info = {
                'slot': cfg_facts['DEVICE_METADATA']['localhost']['hostname'],
                'asic': cfg_facts['DEVICE_METADATA']['localhost']['asic_name']
            }

            if per_host.is_multi_asic and len(duthosts.supervisor_nodes) == 0:
                check_rif_on_sup(per_host, sysport_info['slot'],
                                 sysport_info['asic'], inband['port'])
            else:
                for sup in duthosts.supervisor_nodes:
                    check_rif_on_sup(sup, sysport_info['slot'],
                                     sysport_info['asic'], inband['port'])

        # TODO: Could be on a LAG
        elif porttype == 'lag':
            lagid = asicdb.hget_key_value(
                "%s:%s" % (AsicDbCli.ASIC_LAG_TABLE, portid),
                'SAI_LAG_ATTR_SYSTEM_PORT_AGGREGATE_ID')
            logger.info("RIF: %s is on system LAG: %s", rif, lagid)

            if per_host.is_multi_asic and len(duthosts.supervisor_nodes) == 0:
                voqdb = VoqDbCli(per_host)
            else:
                voqdb = VoqDbCli(duthosts.supervisor_nodes[0])

            systemlagtable = voqdb.dump("SYSTEM_LAG_ID_TABLE")
            for lag, sysid in systemlagtable['SYSTEM_LAG_ID_TABLE'][
                    'value'].iteritems():
                if sysid == lagid:
                    logger.info("System LAG ID %s is portchannel: %s", lagid,
                                lag)
                    break

            myslot = cfg_facts['DEVICE_METADATA']['localhost']['hostname']
            myasic = cfg_facts['DEVICE_METADATA']['localhost']['asic_name']
            if lag.startswith("%s|%s" % (myslot, myasic)):
                logger.info(
                    "Lag: %s is a local portchannel with a router interface.",
                    lag)
                (s, a, lagname) = lag.split("|")
                pytest_assert(
                    lagname in cfg_facts['PORTCHANNEL_INTERFACE'],
                    "RIF Interface %s is in configdb.json but not in asicdb" %
                    rif)

                if per_host.is_multi_asic and len(
                        duthosts.supervisor_nodes) == 0:
                    check_rif_on_sup(per_host, myslot, myasic, lagname)
                else:
                    for sup in duthosts.supervisor_nodes:
                        check_rif_on_sup(sup, myslot, myasic, lagname)

            else:
                logger.info(
                    "Lag: %s is a remote portchannel with a router interface.",
                    lag)

    # Verify each RIF in config had a corresponding local port RIF in the asicDB.
    for rif in dev_intfs:
        if rif not in rif_ports_in_asicdb:
            raise AssertionError(
                "Interface %s is in configdb.json but not in asicdb" % rif)

    logger.info("Interfaces %s are present in configdb.json and asicdb" %
                str(dev_intfs.keys()))
Пример #7
0
def test_voq_interface_create(duthosts, enum_frontend_dut_hostname,
                              enum_asic_index, all_cfg_facts):
    """
    Verify router interfaces are created on all line cards and present in Chassis App Db.

    * Verify router interface creation on local ports in ASIC DB.
    * PORT_ID should match system port table and traced back to config_db.json, mac and MTU should match as well.
    * Verify SYSTEM_INTERFACE table in Chassis AppDb (redis-dump -h <ip> -p 6380 -d 12 on supervisor).
    * Verify creation interfaces with different MTUs in configdb.json.
    * Verify creation of different subnet masks in configdb.json.
    * Repeat with IPv4, IPv6, dual-stack.

    """
    per_host = duthosts[enum_frontend_dut_hostname]
    asic = per_host.asics[
        enum_asic_index if enum_asic_index is not None else 0]
    cfg_facts = all_cfg_facts[per_host.hostname][
        asic.asic_index]['ansible_facts']
    logger.info("Check router interfaces on node: %s, asic: %d",
                per_host.hostname, asic.asic_index)

    dev_intfs = cfg_facts['INTERFACE']
    voq_intfs = cfg_facts['VOQ_INBAND_INTERFACE']
    dev_sysports = get_device_system_ports(cfg_facts)

    slot = per_host.facts['slot_num']

    rif_ports_in_asicdb = []

    # intf_list = get_router_interface_list(dev_intfs)
    asicdb = AsicDbCli(asic)
    asicdb_rif_table = asicdb.dump(asicdb.ASIC_ROUTERINTF_TABLE)
    sys_port_table = asicdb.dump(asicdb.ASIC_SYSPORT_TABLE)

    # asicdb_intf_key_list = asicdb.get_router_if_list()
    # Check each rif in the asicdb, if it is local port, check VOQ DB for correct RIF.
    # If it is on system port, verify slot/asic/port and OID match a RIF in VoQDB
    for rif in asicdb_rif_table.keys():
        rif_type = asicdb_rif_table[rif]['value'][
            "SAI_ROUTER_INTERFACE_ATTR_TYPE"]
        if rif_type != "SAI_ROUTER_INTERFACE_TYPE_PORT":
            logger.info("Skip this rif: %s, it is not on a port: %s", rif,
                        rif_type)
            continue
        else:
            portid = asicdb_rif_table[rif]['value'][
                "SAI_ROUTER_INTERFACE_ATTR_PORT_ID"]
            logger.info("Process RIF %s, Find port with ID: %s", rif, portid)

        porttype = asicdb.get_rif_porttype(portid)
        logger.info("RIF: %s is of type: %s", rif, porttype)
        if porttype == 'hostif':
            # find the hostif entry to get the physical port the router interface is on.
            hostifkey = asicdb.find_hostif_by_portid(portid)
            hostif = asicdb.hget_key_value(hostifkey, 'SAI_HOSTIF_ATTR_NAME')
            logger.info("RIF: %s is on local port: %s", rif, hostif)
            rif_ports_in_asicdb.append(hostif)
            if hostif not in dev_intfs and hostif not in voq_intfs:
                pytest.fail(
                    "Port: %s has a router interface, but it isn't in configdb."
                    % portid)

            # check MTU and ethernet address
            pytest_assert(
                asicdb_rif_table[rif]['value']["SAI_ROUTER_INTERFACE_ATTR_MTU"]
                == cfg_facts['PORT'][hostif]['mtu'],
                "MTU for rif %s is not %s" %
                (rif, cfg_facts['PORT'][hostif]['mtu']))
            intf_mac = get_sonic_mac(per_host, asic.asic_index, hostif)
            pytest_assert(
                asicdb_rif_table[rif]['value']
                ["SAI_ROUTER_INTERFACE_ATTR_SRC_MAC_ADDRESS"].lower() ==
                intf_mac.lower(), "MAC for rif %s is not %s" % (rif, intf_mac))

            sysport_info = find_system_port(dev_sysports, slot,
                                            asic.asic_index, hostif)
            for sup in duthosts.supervisor_nodes:
                check_rif_on_sup(sup, sysport_info['slot'],
                                 sysport_info['asic'], hostif)

        elif porttype == 'sysport':
            try:
                port_output = sys_port_table[
                    "ASIC_STATE:SAI_OBJECT_TYPE_SYSTEM_PORT:" +
                    portid]['value']['SAI_SYSTEM_PORT_ATTR_CONFIG_INFO']
            except KeyError:
                # not a hostif or system port, log error and continue
                logger.error("Did not find OID %s in local or system tables" %
                             portid)
                continue
            port_data = json.loads(port_output)
            for cfg_port in dev_sysports:
                if dev_sysports[cfg_port]['system_port_id'] == port_data[
                        'port_id']:
                    logger.info("RIF: %s is on remote port: %s", rif, cfg_port)
                    break
            else:
                raise AssertionError(
                    "Did not find OID %s in local or system tables" % portid)

            sys_slot, sys_asic, sys_port = cfg_port.split("|")
            for sup in duthosts.supervisor_nodes:
                check_rif_on_sup(sup, sys_slot, sys_asic, sys_port)

        elif porttype == 'port':
            # this is the RIF on the inband port.
            inband = get_inband_info(cfg_facts)
            logger.info("RIF: %s is on local port: %s", rif, inband['port'])

            # check MTU and ethernet address
            pytest_assert(
                asicdb_rif_table[rif]['value']["SAI_ROUTER_INTERFACE_ATTR_MTU"]
                == cfg_facts['PORT'][inband['port']]['mtu'],
                "MTU for rif %s is not %s" %
                (rif, cfg_facts['PORT'][inband['port']]['mtu']))
            intf_mac = get_sonic_mac(per_host, asic.asic_index, inband['port'])
            pytest_assert(
                asicdb_rif_table[rif]['value']
                ["SAI_ROUTER_INTERFACE_ATTR_SRC_MAC_ADDRESS"].lower() ==
                intf_mac.lower(), "MAC for rif %s is not %s" % (rif, intf_mac))

            sysport_info = find_system_port(dev_sysports, slot,
                                            asic.asic_index, inband['port'])

            for sup in duthosts.supervisor_nodes:
                check_rif_on_sup(sup, sysport_info['slot'],
                                 sysport_info['asic'], inband['port'])

        # TODO: Could be on a LAG

    # Verify each RIF in config had a corresponding local port RIF in the asicDB.
    for rif in dev_intfs:
        pytest_assert(
            rif in rif_ports_in_asicdb,
            "Interface %s is in configdb.json but not in asicdb" % rif)

    logger.info("Interfaces %s are present in configdb.json and asicdb" %
                str(dev_intfs.keys()))