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))
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)