Exemple #1
0
def test_self_mac_not_learnt(ptfadapter, rand_selected_dut, pkt_type,
                             toggle_all_simulator_ports_to_rand_selected_tor_m,
                             tbinfo):
    """
    Verify self mac will not be learnt.
    """
    # Clear existing FDB entry from DUT
    rand_selected_dut.command('sonic-clear fdb all')
    # Sleep some time to ensure clear is done
    time.sleep(5)
    if pkt_type == "cleanup":
        return

    mg_facts = rand_selected_dut.get_extended_minigraph_facts(tbinfo)
    port_index = random.choice(list(
        mg_facts['minigraph_ptf_indices'].values()))
    self_mac = rand_selected_dut.facts['router_mac']
    dummy_mac = "00:22:33:44:33:22"
    if pkt_type == "ethernet":
        send_eth(ptfadapter, port_index, self_mac, dummy_mac, 0)
    elif pkt_type == "arp_request":
        send_arp_request(ptfadapter, port_index, self_mac, dummy_mac, 0)
    elif pkt_type == "arp_reply":
        send_arp_reply(ptfadapter, port_index, self_mac, dummy_mac, 0)
    # Sleep some time to ensure FDB is populate
    time.sleep(5)
    # Verify that self mac is not learnt
    fdb_facts = rand_selected_dut.fdb_facts()['ansible_facts']
    pytest_assert(self_mac not in fdb_facts,
                  "Self-mac {} is not supposed to be learnt".format(self_mac))
Exemple #2
0
def setup_fdb(ptfadapter, vlan_table, router_mac, pkt_type, dummy_mac_count):
    """
    :param ptfadapter: PTF adapter object
    :param vlan_table: VLAN table map: VLAN subnet -> list of VLAN members
    :return: FDB table map : VLAN member -> MAC addresses set
    """

    fdb = {}

    assert pkt_type in PKT_TYPES

    for vlan in vlan_table:
        for member in vlan_table[vlan]:
            if 'port_index' not in member or 'tagging_mode' not in member:
                continue
            # member['port_index'] is a list,
            # front panel port only has one member, and portchannel might have 0, 1 and multiple member ports,
            # portchannel might have no member ports or all member ports are down, so skip empty list
            if not member['port_index']:
                continue
            port_index = member['port_index'][0]
            vlan_id = vlan if member['tagging_mode'] == 'tagged' else 0
            mac = ptfadapter.dataplane.get_mac(0, port_index)
            # send a packet to switch to populate layer 2 table with MAC of PTF interface
            send_eth(ptfadapter, port_index, mac, router_mac, vlan_id)

            # put in learned MAC
            fdb[port_index] = {mac}

            # Send packets to switch to populate the layer 2 table with dummy MACs for each port
            # Totally 10 dummy MACs for each port, send 1 packet for each dummy MAC
            dummy_macs = [
                '{}:{:02x}:{:02x}'.format(DUMMY_MAC_PREFIX, port_index, i)
                for i in range(dummy_mac_count)
            ]

            for dummy_mac in dummy_macs:
                if pkt_type == "ethernet":
                    send_eth(ptfadapter, port_index, dummy_mac, router_mac,
                             vlan_id)
                elif pkt_type == "arp_request":
                    send_arp_request(ptfadapter, port_index, dummy_mac,
                                     router_mac, vlan_id)
                elif pkt_type == "arp_reply":
                    send_arp_reply(ptfadapter, port_index, dummy_mac,
                                   router_mac, vlan_id)
                else:
                    pytest.fail("Unknown option '{}'".format(pkt_type))

            # put in set learned dummy MACs
            fdb[port_index].update(dummy_macs)

    time.sleep(FDB_POPULATE_SLEEP_TIMEOUT)
    # Flush dataplane
    ptfadapter.dataplane.flush()

    return fdb
def test_fdb_mac_move(ptfadapter, duthosts, rand_one_dut_hostname, ptfhost,
                      get_function_conpleteness_level):
    # Perform FDB clean up before each test
    fdb_cleanup(duthosts, rand_one_dut_hostname)

    normalized_level = get_function_conpleteness_level
    if normalized_level is None:
        normalized_level = "basic"
    loop_times = LOOP_TIMES_LEVEL_MAP[normalized_level]

    duthost = duthosts[rand_one_dut_hostname]
    conf_facts = duthost.config_facts(host=duthost.hostname,
                                      source="persistent")['ansible_facts']

    # reinitialize data plane due to above changes on PTF interfaces
    ptfadapter.reinit()

    router_mac = duthost.facts['router_mac']

    port_index_to_name = {
        v: k
        for k, v in conf_facts['port_index_map'].items()
    }

    # Only take interfaces that are in ptf topology
    ptf_ports_available_in_topo = ptfhost.host.options[
        'variable_manager'].extra_vars.get("ifaces_map")
    available_ports_idx = []
    for idx, name in ptf_ports_available_in_topo.items():
        if idx in port_index_to_name and conf_facts['PORT'][
                port_index_to_name[idx]].get('admin_status', 'down') == 'up':
            available_ports_idx.append(idx)

    vlan_table = {}
    interface_table = defaultdict(set)
    config_portchannels = conf_facts.get('PORTCHANNEL', {})

    # if DUT has more than one VLANs, use the first vlan
    name = conf_facts['VLAN'].keys()[0]
    vlan = conf_facts['VLAN'][name]
    vlan_id = int(vlan['vlanid'])
    vlan_table[vlan_id] = []

    for ifname in conf_facts['VLAN_MEMBER'][name].keys():
        if 'tagging_mode' not in conf_facts['VLAN_MEMBER'][name][ifname]:
            continue
        tagging_mode = conf_facts['VLAN_MEMBER'][name][ifname]['tagging_mode']
        port_index = []
        if ifname in config_portchannels:
            for member in config_portchannels[ifname]['members']:
                if conf_facts['port_index_map'][member] in available_ports_idx:
                    port_index.append(conf_facts['port_index_map'][member])
            if port_index:
                interface_table[ifname].add(vlan_id)
        elif conf_facts['port_index_map'][ifname] in available_ports_idx:
            port_index.append(conf_facts['port_index_map'][ifname])
            interface_table[ifname].add(vlan_id)
        if port_index:
            vlan_table[vlan_id].append({
                'port_index': port_index,
                'tagging_mode': tagging_mode
            })

    vlan = vlan_table.keys()[0]
    vlan_member_count = len(vlan_table[vlan])
    total_fdb_entries = min(
        TOTAL_FDB_ENTRIES,
        (get_crm_resources(duthost, "fdb_entry", "available") -
         get_crm_resources(duthost, "fdb_entry", "used")))
    dummay_mac_count = int(math.floor(total_fdb_entries / vlan_member_count))

    fdb = get_fdb_dict(ptfadapter, vlan_table, dummay_mac_count)
    port_list = fdb.keys()
    dummy_mac_list = fdb.values()

    for loop_time in range(0, loop_times):
        port_index_start = (0 + loop_time) % len(port_list)

        for (port, dummy_mac_set) in zip(range(len(port_list)),
                                         dummy_mac_list):
            port_index = (port_index_start + port) % len(port_list)
            for dummy_mac in dummy_mac_set:
                send_arp_request(ptfadapter, port_index, dummy_mac, router_mac,
                                 vlan_id)

        time.sleep(FDB_POPULATE_SLEEP_TIMEOUT)
        pytest_assert(
            wait_until(
                20, 1, 0, lambda: get_fdb_dynamic_mac_count(duthost) >
                vlan_member_count), "FDB Table Add failed")
        # Flush dataplane
        ptfadapter.dataplane.flush()
        fdb_cleanup(duthosts, rand_one_dut_hostname)
        # Wait for 10 seconds before starting next loop
        time.sleep(10)