def runTest(self): target = gc.Target(device_id=0, pipe_id=0xffff) # Get bfrt_info and set it as part of the test bfrt_info = self.interface.bfrt_info_get(p4_program_name) # Set default output port table_output_port = bfrt_info.table_get("SwitchIngress.output_port") action_data = table_output_port.make_data( action_name="SwitchIngress.set_output_port", data_field_list_in=[gc.DataTuple(name="port_id", val=swports[1])]) table_output_port.default_entry_set(target=target, data=action_data) # Set a default entry in the rewrite table so all packets get # their checksum updated. table_translate = bfrt_info.table_get("SwitchIngress.translate") action_data = table_translate.make_data( action_name="SwitchIngress.snupat", data_field_list_in=[ gc.DataTuple(name="src_addr", val=gc.ipv4_to_bytes("4.3.2.1")), gc.DataTuple(name="src_port", val=gc.to_bytes(0x4321, 2)), gc.DataTuple(name="update", val=0x0) ], ) table_translate.default_entry_set(target=target, data=action_data) try: ipkt = testutils.simple_udp_packet(eth_dst='11:11:11:11:11:11', eth_src='00:00:00:00:00:00', ip_src='1.2.3.4', ip_dst='100.99.98.97', ip_id=101, ip_ttl=64, udp_sport=0x1234, udp_dport=0xabcd, with_udp_chksum=True) epkt = testutils.simple_udp_packet(eth_dst='11:11:11:11:11:11', eth_src='00:00:00:00:00:00', ip_src='4.3.2.1', ip_dst='100.99.98.97', ip_id=101, ip_ttl=64, udp_sport=0x4321, udp_dport=0xabcd, with_udp_chksum=False) # We expect the packet to have the same TCP checksum as the packet # we sent in. Calling str forces scapy to calculate the checksum # for the given layer. epkt[scapy.all.IP].chksum = ipkt[scapy.all.IP].__class__( str(ipkt[scapy.all.IP])).chksum epkt[scapy.all.UDP].chksum = ipkt[scapy.all.UDP].__class__( str(ipkt[scapy.all.UDP])).chksum testutils.send_packet(self, swports[0], ipkt) testutils.verify_packet(self, epkt, swports[1]) finally: table_output_port.default_entry_reset(target) table_translate.default_entry_reset(target)
def clear_counters(self): self.logger.info("Clearing set_dst_addr counters...") self.table.operations_execute(self.target, 'SyncCounters') resp = self.table.entry_get( self.target, flags={"from_hw": False}) keys = [] values = [] for v, k in resp: keys.append(k) v = v.to_dict() k = k.to_dict() values.append( self.table.make_data( [gc.DataTuple('$COUNTER_SPEC_BYTES', 0), gc.DataTuple('$COUNTER_SPEC_PKTS', 0)], v['action_name'])) self.table.entry_mod( self.target, keys, values)
def timing_loop(self): from backports.time_perf_counter import perf_counter # initialize self.table.entry_add(self.target, [ self.table.make_key( [gc.KeyTuple('hdr.ethernet.dst_addr', "00:11:22:33:44:55")]) ], [ self.table.make_data( [gc.DataTuple('egress_port', 0)], 'Ingress.non_switchml_forward.set_egress_port') ]) count = 1000000 start = perf_counter() for i in range(count): self.table.entry_mod(self.target, [ self.table.make_key([ gc.KeyTuple('hdr.ethernet.dst_addr', "00:11:22:33:44:55") ]) ], [ self.table.make_data( [gc.DataTuple('egress_port', 0)], 'Ingress.non_switchml_forward.set_egress_port') ]) end = perf_counter() rate = count / (end - start) print("{} mods in {:02f} seconds: {:02f} m/s".format( count, end - start, rate))
def add_send_worker(self, rid, mac, ip, qpn, initial_psn, rkey=None): # first, add entry to fill in headers for RoCE packet self.create_roce_packet.entry_add(self.target, [ self.create_roce_packet.make_key( [gc.KeyTuple('eg_md.switchml_md.worker_id', rid)]) ], [ self.create_roce_packet.make_data( [gc.DataTuple('dest_mac', mac), gc.DataTuple('dest_ip', ip)], 'Egress.rdma_sender.fill_in_roce_fields') ]) # now, add entry to add QPN and PSN to packet self.fill_in_qpn_and_psn.entry_add( self.target, [ self.fill_in_qpn_and_psn.make_key([ gc.KeyTuple('eg_md.switchml_md.worker_id', rid), gc.KeyTuple('eg_md.switchml_md.pool_index', 0x00000, 0x00000) ]) ], [ self.fill_in_qpn_and_psn.make_data( [ gc.DataTuple('qpn', qpn), #gc.DataTuple('Egress.rdma_sender.psn_register.f1', initial_psn)], ], 'Egress.rdma_sender.add_qpn_and_psn') ])
def worker_clear_all(self, mgid): for dev_port, rid in self.rids[mgid].items(): try: # remove group entry self.mgid_table.entry_mod_inc( self.target, [self.mgid_table.make_key([gc.KeyTuple('$MGID', mgid)])], [ self.mgid_table.make_data([ gc.DataTuple('$MULTICAST_NODE_ID', int_arr_val=[rid]), gc.DataTuple('$MULTICAST_NODE_L1_XID_VALID', bool_arr_val=[False]), gc.DataTuple('$MULTICAST_NODE_L1_XID', int_arr_val=[0]) ]) ], bfruntime_pb2.TableModIncFlag.MOD_INC_DELETE) except gc.BfruntimeReadWriteRpcException as e: self.logger.info( "Multicast node ID {} remove from group {} failed; maybe it's already deleted?" .format(rid, mgid)) try: # remove node entry self.node_table.entry_del(self.target, [ self.node_table.make_key( [gc.KeyTuple('$MULTICAST_NODE_ID', rid)]) ]) except gc.BfruntimeReadWriteRpcException as e: self.logger.info( "Multicast node ID {} delete failed; maybe it's already deleted?" .format(rid)) del self.rids[mgid][dev_port]
def add_default_entries(self): # set switch MAC/IP and message size and mask self.switch_mac_and_ip.default_entry_set( self.target, self.switch_mac_and_ip.make_data([gc.DataTuple('switch_mac', self.switch_mac), gc.DataTuple('switch_ip', self.switch_ip)], 'Egress.set_dst_addr.set_switch_mac_and_ip'))
def clear_counters(self): self.logger.info("Clearing rdma_receiver counters...") self.table.operations_execute(self.target, 'SyncCounters') resp = self.table.entry_get(self.target, flags={"from_hw": False}) keys = [] values = [] for v, k in resp: keys.append(k) v = v.to_dict() k = k.to_dict() values.append( self.table.make_data([ gc.DataTuple('$COUNTER_SPEC_BYTES', 0), gc.DataTuple('$COUNTER_SPEC_PKTS', 0) ], v['action_name'])) self.table.entry_mod(self.target, keys, values) self.rdma_packet_counter.entry_del(self.target) self.rdma_message_counter.entry_del(self.target) self.rdma_sequence_violation_counter.entry_del(self.target) self.simulated_drop_counter.entry_del(self.target)
def lpfGetTestHelper(self, num_entries, table, key_fields, action_name): target = client.Target(device_id=0, pipe_id=0xffff) gain_time = [ float(random.randint(1, 200) * 1000) for x in range(num_entries) ] # decay_time = [random.randint(50, 100)*1000 for x in range(num_entries)] decay_time = gain_time out_scale = [random.randint(1, 10) for x in range(num_entries)] logger.info("Inserting %d entries to the lpf table", num_entries) data_list = [] for x in range(num_entries): data_list.append( table.make_data([ client.DataTuple('$LPF_SPEC_TYPE', str_val="RATE"), client.DataTuple('$LPF_SPEC_GAIN_TIME_CONSTANT_NS', float_val=gain_time[x]), client.DataTuple('$LPF_SPEC_DECAY_TIME_CONSTANT_NS', float_val=decay_time[x]), client.DataTuple('$LPF_SPEC_OUT_SCALE_DOWN_FACTOR', out_scale[x]) ], action_name)) table.entry_add(target, key_fields, data_list) for x in range(num_entries): resp = table.entry_get(target, [key_fields[x]], {"from_hw": False}) data_dict = next(resp)[0].to_dict() assert (data_dict["$LPF_SPEC_TYPE"] == "RATE") assert (data_dict["$LPF_SPEC_GAIN_TIME_CONSTANT_NS"] <= gain_time[x]) assert (data_dict["$LPF_SPEC_DECAY_TIME_CONSTANT_NS"] <= decay_time[x]) assert (data_dict["$LPF_SPEC_OUT_SCALE_DOWN_FACTOR"] == out_scale[x])
def CfgPortTableClearTest(self, port1): target = client.Target(device_id=0, pipe_id=0xffff) self.port_table.entry_del(target, key_list=None) self.port_table.entry_add( target, [self.port_table.make_key([client.KeyTuple('$DEV_PORT', port1)])], [ self.port_table.make_data([ client.DataTuple('$SPEED', str_val="BF_SPEED_100G"), client.DataTuple('$FEC', str_val="BF_FEC_TYP_NONE") ]) ]) self.port_table.entry_del(target, key_list=None) try: get_data_list = self.port_table.make_data([client.DataTuple("$SPEED")]) resp = self.port_table.entry_get( target, [self.port_table.make_key([client.KeyTuple('$DEV_PORT', port1)])], {"from_hw": False}, get_data_list) data_dict = next(resp)[0].to_dict() # since we have deleted all the ports, the above API call should have # failed. Assert if not logger.error("Unable to clear port cfg table") assert (0) except: logger.info("Cleared port cfg table successfully")
def modify_grp(self, sel_table, members, member_status): target = gc.Target(device_id=dev_id, pipe_id=0xffff) # Modify group sel_table.entry_mod(target, [ sel_table.make_key( [gc.KeyTuple('$SELECTOR_GROUP_ID', self.group_id)]) ], [ sel_table.make_data([ gc.DataTuple('$ACTION_MEMBER_ID', int_arr_val=members), gc.DataTuple('$ACTION_MEMBER_STATUS', bool_arr_val=member_status) ]) ]) # Verify member_dict = { members[i]: member_status[i] for i in range(len(members)) } get_resp = sel_table.entry_get(target, [ sel_table.make_key( [gc.KeyTuple('$SELECTOR_GROUP_ID', self.group_id)]) ], {"from_hw": False}) data_dict = next(get_resp)[0].to_dict() member_dict_recv = { data_dict["$ACTION_MEMBER_ID"][i]: data_dict["$ACTION_MEMBER_STATUS"][i] for i in range(len(data_dict["$ACTION_MEMBER_ID"])) } assert member_dict == member_dict_recv
def add_default_entries(self): sid = self.normal_base self.table.entry_add( self.target, [self.table.make_key([gc.KeyTuple('$sid', sid)])], [ self.table.make_data([ gc.DataTuple('$direction', str_val="INGRESS"), gc.DataTuple('$ucast_egress_port', self.mirror_port), gc.DataTuple('$ucast_egress_port_valid', bool_val=True), gc.DataTuple('$session_enable', bool_val=True) ], '$normal') ])
def runTest(self): target = gc.Target(device_id=0, pipe_id=0xffff) # Get bfrt_info and set it as part of the test bfrt_info = self.interface.bfrt_info_get(p4_program_name) # Set default output port table_output_port = bfrt_info.table_get("SwitchIngress.output_port") action_data = table_output_port.make_data( action_name="SwitchIngress.set_output_port", data_field_list_in=[gc.DataTuple(name="port_id", val=swports[1])]) table_output_port.default_entry_set(target=target, data=action_data) # Set a default entry in the rewrite table so all packets get # their checksum updated. table_translate = bfrt_info.table_get("SwitchIngress.translate") action_data = table_translate.make_data( action_name="SwitchIngress.sntpat", data_field_list_in=[ gc.DataTuple(name="src_addr", val=gc.ipv4_to_bytes("4.3.2.1")), gc.DataTuple(name="src_port", val=gc.to_bytes(0x4321, 2)), gc.DataTuple(name="update", val=0x1) ], ) table_translate.default_entry_set(target=target, data=action_data) try: ipkt = testutils.simple_tcp_packet(eth_dst='11:11:11:11:11:11', eth_src='00:00:00:00:00:00', ip_src='1.2.3.4', ip_dst='100.99.98.97', ip_id=101, ip_ttl=64, tcp_sport=0x1234, tcp_dport=0xabcd, with_tcp_chksum=True) epkt = testutils.simple_tcp_packet(eth_dst='11:11:11:11:11:11', eth_src='00:00:00:00:00:00', ip_src='4.3.2.1', ip_dst='100.99.98.97', ip_id=101, ip_ttl=64, tcp_sport=0x4321, tcp_dport=0xabcd, with_tcp_chksum=True) testutils.send_packet(self, swports[0], ipkt) testutils.verify_packet(self, epkt, swports[1]) finally: table_output_port.default_entry_reset(target) table_translate.default_entry_reset(target)
def runTest(self): target = gc.Target(device_id=0, pipe_id=0xffff) # Get bfrt_info bfrt_info = self.interface.bfrt_info_get(p4_program_name) # Set default output port table_output_port = bfrt_info.table_get("SwitchIngress.output_port") action_data = table_output_port.make_data( action_name="SwitchIngress.set_output_port", data_field_list_in=[gc.DataTuple(name="port_id", val=swports[1])]) table_output_port.default_entry_set(target=target, data=action_data) # Add bridge_md to ig_intr_md table_bridge_md_ctl = bfrt_info.table_get( "SwitchIngress.bridge_md_ctrl") action_data = table_bridge_md_ctl.make_data( [ gc.DataTuple(name="dst_mac_addr_low", val=0xffeeddcc), gc.DataTuple(name="src_mac_addr_low", val=0x11223344), ], action_name="SwitchIngress.bridge_add_example_hdr") table_bridge_md_ctl.default_entry_set(target=target, data=action_data) try: ipkt = testutils.simple_tcp_packet(eth_dst='11:11:11:11:11:11', eth_src='22:22:22:22:22:22', ip_src='1.2.3.4', ip_dst='100.99.98.97', ip_id=101, ip_ttl=64, tcp_sport=0x1234, tcp_dport=0xabcd, with_tcp_chksum=True) epkt = testutils.simple_tcp_packet(eth_dst='00:00:ff:ee:dd:cc', eth_src='00:00:11:22:33:44', ip_src='1.2.3.4', ip_dst='100.99.98.97', ip_id=101, ip_ttl=64, tcp_sport=0x1234, tcp_dport=0xabcd, with_tcp_chksum=True) testutils.send_packet(self, swports[0], ipkt) testutils.verify_packet(self, epkt, swports[1]) finally: table_output_port.default_entry_reset(target) table_bridge_md_ctl.default_entry_reset(target)
def add_udp_entry(self, worker_rid, worker_mac, worker_ip): self.logger.info("Adding worker {} {} at rid {}".format(worker_mac, worker_ip, worker_rid)) # target all pipes on device 0 target = gc.Target(device_id=0, pipe_id=0xffff) self.table.entry_add( target, [self.table.make_key([gc.KeyTuple('eg_md.switchml_md.worker_id', worker_rid)])], [self.table.make_data([gc.DataTuple('eth_dst_addr', worker_mac), gc.DataTuple('ip_dst_addr', worker_ip)], 'Egress.set_dst_addr.set_dst_addr_for_SwitchML_UDP')])
def runTest(self): target = gc.Target(device_id=0, pipe_id=0xffff) # Get bfrt_info and set it as part of the test bfrt_info = self.interface.bfrt_info_get(p4_program_name) # Set default output port table_output_port = bfrt_info.table_get("SwitchIngress.output_port") action_data = table_output_port.make_data( action_name="SwitchIngress.set_output_port", data_field_list_in=[gc.DataTuple(name="port_id", val=swports[1])]) table_output_port.default_entry_set(target=target, data=action_data) # Set a default entry in the rewrite table so all packets get # their checksum updated. table_translate = bfrt_info.table_get("SwitchIngress.translate") action_data = table_translate.make_data( action_name="SwitchIngress.checksum_upd_ipv4_tcp_udp", data_field_list_in=[gc.DataTuple(name="update", val=0x1)]) table_translate.default_entry_set(target=target, data=action_data) try: ipkt = testutils.simple_tcp_packet(eth_dst='11:11:11:11:11:11', eth_src='00:00:00:00:00:00', ip_src='1.2.3.4', ip_dst='100.99.98.97', ip_id=101, ip_ttl=64, tcp_sport=0x1234, tcp_dport=0xabcd, with_tcp_chksum=True) # Set incorrect checksum ipkt[scapy.all.IP].chksum = 0x4321 # We expect the program to correct the IPv4 checksum. epkt = testutils.simple_tcp_packet(eth_dst='00:00:de:ad:be:ef', eth_src='00:00:00:00:00:00', ip_src='1.2.3.4', ip_dst='100.99.98.97', ip_id=101, ip_ttl=64, tcp_sport=0x1234, tcp_dport=0xabcd, with_tcp_chksum=True) testutils.send_packet(self, swports[0], ipkt) testutils.verify_packet(self, epkt, swports[1]) finally: table_output_port.default_entry_reset(target) table_translate.default_entry_reset(target)
def add_default_entries(self): # set switch MAC/IP and message size and mask self.switch_mac_and_ip.default_entry_set( self.target, self.switch_mac_and_ip.make_data( [ gc.DataTuple('switch_mac', self.switch_mac), gc.DataTuple('switch_ip', self.switch_ip) ], #, # #gc.DataTuple('base_opcode', self.base_opcode), # gc.DataTuple('message_length', self.message_size), # gc.DataTuple('first_last_mask', self.first_last_mask)], 'Egress.rdma_sender.set_switch_mac_and_ip'))
def _forward_table_add(table, target, smac, smac_mask, priority, port, c_bytes, c_pkts): table.entry_add(target, [ table.make_key([ gc.KeyTuple('hdr.ethernet.src_addr', smac, smac_mask), gc.KeyTuple('$MATCH_PRIORITY', priority) ]) ], [ table.make_data([ gc.DataTuple('port', port), gc.DataTuple('$COUNTER_SPEC_BYTES', c_pkts), gc.DataTuple('$COUNTER_SPEC_PKTS', c_bytes) ], 'SwitchIngress.hit') ])
def runTest(self): ig_port = swports[1] eg_port = swports[2] dmac = '22:22:22:22:22:22' target = client.Target(device_id=0, pipe_id=0xffff) # Get bfrt_info and set it as part of the test bfrt_info = self.interface.bfrt_info_get("tna_action_profile") forward_table = bfrt_info.table_get("SwitchIngress.forward") action_profile = bfrt_info.table_get("SwitchIngress.action_profile") ap_key = action_profile.make_key( [client.KeyTuple('$ACTION_MEMBER_ID', 1)]) action_profile.entry_add(target, [ap_key], [ action_profile.make_data([client.DataTuple('port', eg_port)], 'SwitchIngress.set_port') ]) fwd_key = forward_table.make_key([ client.KeyTuple('ig_intr_md.ingress_port', ig_port), client.KeyTuple('vid', 0) ]) forward_table.entry_add(target, [fwd_key], [ forward_table.make_data([client.DataTuple('$ACTION_MEMBER_ID', 1)]) ]) try: pkt = testutils.simple_tcp_packet(eth_dst=dmac) logger.info("Sending packet on port %d", ig_port) testutils.send_packet(self, ig_port, pkt) exp_pkt = pkt logger.info("Expecting packet on port %d", eg_port) testutils.verify_packets(self, exp_pkt, [eg_port]) finally: forward_table.entry_del(target, [fwd_key]) action_profile.entry_del(target, [ap_key]) try: logger.info("Sending packet on port %d", ig_port) testutils.send_packet(self, ig_port, pkt) logger.info("Packet is expected to get dropped.") testutils.verify_no_other_packets(self) finally: pass
def runTest(self): target = gc.Target(device_id=0, pipe_id=0xffff) # Get bfrt_info and set it as part of the test bfrt_info = self.interface.bfrt_info_get(p4_program_name) # Set default output port table_output_port = bfrt_info.table_get("SwitchIngress.output_port") action_data = table_output_port.make_data( action_name="SwitchIngress.set_output_port", data_field_list_in=[gc.DataTuple(name="port_id", val=swports[1])]) table_output_port.default_entry_set(target=target, data=action_data) try: ipkt = testutils.simple_tcp_packet(eth_dst='11:11:11:11:11:11', eth_src='22:33:44:55:66:77', ip_src='1.2.3.4', ip_dst='100.99.98.97', ip_id=101, ip_ttl=64, tcp_sport=0x1234, tcp_dport=0xabcd, with_tcp_chksum=True) epkt = ipkt testutils.send_packet(self, swports[0], ipkt) testutils.verify_packet(self, epkt, swports[1]) finally: table_output_port.default_entry_reset(target)
def runTest(self): target = gc.Target(device_id=0, pipe_id=0xffff) # Get bfrt_info and set it as part of the test bfrt_info = self.interface.bfrt_info_get(p4_program_name) # Set default output port ipv4_match_regular = bfrt_info.table_get("SwitchIngress.ipv4_match_regular") action_data = ipv4_match_regular.make_data( action_name="SwitchIngress.set_output_port", data_field_list_in=[gc.DataTuple(name="port_id", val=swports[0])] ) ipv4_match_regular.default_entry_set( target=target, data=action_data) try: ipkt = testutils.simple_udp_packet(eth_dst='11:11:11:11:11:11', eth_src='22:22:22:22:22:22', ip_src='1.2.3.4', ip_dst='100.99.98.97', ip_id=101, ip_ttl=64, udp_sport=0x1234, udp_dport=0xabcd) testutils.send_packet(self, swports[0], ipkt) testutils.verify_packet(self, ipkt, swports[0]) finally: ipv4_match_regular.default_entry_reset(target)
def clear_counters(self): self.logger.info("Clearing next_step counters...") # this should work, but it doesn't. #self.consume_counter.entry_del(self.target) #self.harvest_counter.entry_del(self.target) self.recirculate_counter.entry_del(self.target) self.broadcast_counter.entry_del(self.target) self.retransmit_counter.entry_del(self.target) self.drop_counter.entry_del(self.target) # so we'll clear them manually for counter in [ #self.consume_counter, #self.harvest_counter, self.recirculate_counter, self.broadcast_counter, self.retransmit_counter, self.drop_counter ]: count = counter.info.size self.logger.info("Clearing {} keys for counter table {}".format( count, counter.info.name_get())) counter.entry_mod(self.target, [ counter.make_key([gc.KeyTuple('$COUNTER_INDEX', i)]) for i in range(count) ], [counter.make_data([gc.DataTuple('$COUNTER_SPEC_PKTS', 0)])] * count)
def enable_loopback_ports(self): # enable loopback on front panel ports self.logger.info("Enabling loopback on {} front panel ports...".format( len(self.loopback_ports))) self.port_table.entry_add(self.target, [ self.port_table.make_key([gc.KeyTuple('$DEV_PORT', dev_port)]) for dev_port in self.loopback_ports ], [ self.port_table.make_data([ gc.DataTuple('$SPEED', str_val='BF_SPEED_100G'), gc.DataTuple('$FEC', str_val='BF_FEC_TYP_NONE'), gc.DataTuple('$LOOPBACK_MODE', str_val="BF_LPBK_MAC_NEAR"), gc.DataTuple('$PORT_ENABLE', bool_val=True) ]) ] * len(self.loopback_ports))
def runTest(self): seed = random.randint(1, 65535) logger.info("Seed used for RegisterTest is %d", seed) random.seed(seed) # Get bfrt_info and set it as part of the test bfrt_info = self.interface.bfrt_info_get("tna_register") register_idx = random.randint(0, 500) register_value_hi = random.randint(0, 1000) register_value_lo = random.randint(0, 1000) logger.info("Register value hi %s", str(register_value_hi)) logger.info("Register value lo %s", str(register_value_lo)) register_value_hi_arr = {} register_value_lo_arr = {} num_pipes = int(testutils.test_param_get('num_pipes')) for i in range(num_pipes): register_value_hi_arr[i] = register_value_hi register_value_lo_arr[i] = register_value_lo target = gc.Target(device_id=0, pipe_id=0xffff) register_table = bfrt_info.table_get("SwitchIngress.test_reg") register_table.entry_add(target, [ register_table.make_key( [gc.KeyTuple('$REGISTER_INDEX', register_idx)]) ], [ register_table.make_data([ gc.DataTuple('SwitchIngress.test_reg.first', register_value_lo), gc.DataTuple('SwitchIngress.test_reg.second', register_value_hi) ]) ]) resp = register_table.entry_get(target, [ register_table.make_key( [gc.KeyTuple('$REGISTER_INDEX', register_idx)]) ], {"from_hw": True}) data, _ = next(resp) data_dict = data.to_dict() VerifyReadRegisters(self, "SwitchIngress.test_reg.first", "SwitchIngress.test_reg.second", register_value_lo_arr, register_value_hi_arr, data_dict)
def modifyEntries(self): # To make sure that the phase0 table modify has taken effect delete # the old entries from the exact match table self.port_md_exm_match_table.entry_del(self.target) for key, value in list(self.igr_to_egr_port_map.items()): igr_port = key egr_port = value # For each igr port add a entry in the port_metadata (phase0) table # Form data to be programmed in the phase0 table for this ingress port phase0data = 0 field1 = 0 field2 = 0 field3 = 0 field4 = 0 old_phase0data = 0 while True: field1 = random.randint(256, 0xffff) # 16 bit field2 = random.randint(1, 0xffffff) # 24 bits field3 = random.randint(1, 0xffff) # 16 bits field4 = random.randint(1, 0xff) # 8 bits phase0data = make_phase0_data(field1, field2, field3, field4) if self.phase0_data_map[igr_port] != phase0data: old_phase0data = self.phase0_data_map[igr_port] self.phase0_data_map[igr_port] = phase0data break self.port_metadata_table.entry_mod( self.target, [self.port_metadata_table.make_key([client.KeyTuple('ig_intr_md.ingress_port', igr_port)])], [self.port_metadata_table.make_data([client.DataTuple('$DEFAULT_FIELD', phase0data)])]) # Add the new entry for the igr port in the exact match table self.port_md_exm_match_table.entry_add( self.target, [self.port_md_exm_match_table.make_key( [client.KeyTuple('ig_md.port_md.field1', field1), client.KeyTuple('ig_md.port_md.field2', field2), client.KeyTuple('ig_md.port_md.field3', field3), client.KeyTuple('ig_md.port_md.field4', field4)])], [self.port_md_exm_match_table.make_data( [client.DataTuple('port', egr_port)], 'SwitchIngress.hit')] )
def add_default_entries(self): # add broadcast entry self.table.entry_add(self.target, [ self.table.make_key( [gc.KeyTuple('hdr.ethernet.dst_addr', "ff:ff:ff:ff:ff:ff")]) ], [ self.table.make_data([gc.DataTuple('flood_mgid', self.mgid)], 'Ingress.non_switchml_forward.flood') ])
def worker_add(self, mgid, rid, port, lane): # get dev port for this worker dev_port = self.ports.get_dev_port(port, lane) if rid in self.rids[mgid]: print("Port {}/{} already added to multicast group {}; skipping.". format(port, lane, mgid)) return # add to rid table for this group self.rids[mgid][dev_port] = rid # erase any existing entry try: self.node_table.entry_del(self.target, [ self.node_table.make_key( [gc.KeyTuple('$MULTICAST_NODE_ID', rid)]) ]) except gc.BfruntimeReadWriteRpcException as e: self.logger.info( "Multicast node ID {} not found in switch already during delete; this is expected." .format(rid)) # add to node table self.node_table.entry_add(self.target, [ self.node_table.make_key([gc.KeyTuple('$MULTICAST_NODE_ID', rid)]) ], [ self.node_table.make_data([ gc.DataTuple('$MULTICAST_RID', rid), gc.DataTuple('$DEV_PORT', int_arr_val=[dev_port]) ]) ]) # now that node is added, extend multicast group self.mgid_table.entry_mod_inc( self.target, [self.mgid_table.make_key([gc.KeyTuple('$MGID', mgid)])], [ self.mgid_table.make_data([ gc.DataTuple('$MULTICAST_NODE_ID', int_arr_val=[rid]), gc.DataTuple('$MULTICAST_NODE_L1_XID_VALID', bool_arr_val=[True]), gc.DataTuple('$MULTICAST_NODE_L1_XID', int_arr_val=[rid]) ]) ], bfruntime_pb2.TableModIncFlag.MOD_INC_ADD)
def insertEntry(self, target, register_idx, register_val): self.register_bool_table.entry_add(target, [ self.register_bool_table.make_key( [gc.KeyTuple('$REGISTER_INDEX', register_idx)]) ], [ self.register_bool_table.make_data([ gc.DataTuple('SwitchIngress.bool_register_table.f1', register_val) ]) ])
def runTest(self): # Get bfrt_info and set it as part of the test target = client.Target(device_id=0, pipe_id=0xffff) # Insert 100 entries num_entries = 100 phase0_igr_ports = {} try: logger.info("Inserting %d entries in the phase0 table", num_entries) for i in range(num_entries): igr_port = 0 phase0data = 0 while True: igr_pipe = random.randint(0, 3) igr_local_port = random.randint(0, 63) igr_port = (igr_pipe << 7) | (igr_local_port) if igr_port not in phase0_igr_ports: field1 = random.randint(1, 0xffff) # 16 bit field2 = random.randint(1, 0xffffff) # 24 bits field3 = random.randint(1, 0xffff) # 16 bits field4 = random.randint(1, 0xff) # 8 bits phase0data = make_phase0_data(field1, field2, field3, field4) phase0_igr_ports[igr_port] = phase0data break self.port_metadata_table.entry_add( target, [self.port_metadata_table.make_key( [client.KeyTuple('ig_intr_md.ingress_port', igr_port)])], [self.port_metadata_table.make_data( [client.DataTuple('$DEFAULT_FIELD', phase0data)])]) # Read back the entries logger.info("Reading back %d entries", num_entries) for key, value in list(phase0_igr_ports.items()): igr_port = key phase0data = value resp = self.port_metadata_table.entry_get( target, [self.port_metadata_table.make_key( [client.KeyTuple('ig_intr_md.ingress_port', igr_port)])], {"from_hw": True}) fields = next(resp)[0].to_dict() logger.info("Verifying %d entry for igr port %d", i, igr_port) recv_data = fields["$DEFAULT_FIELD"] if recv_data != phase0data: logger.info("Exp data : %s : Rcv data : %s", phase0data, recv_data) assert(0) finally: logger.info("Cleaning up entries") self.port_metadata_table.entry_del(target)
def forward_update(ver=0b00, is_mod=False): key_list = [ forward_table.make_key( [gc.KeyTuple('ig_intr_md.ingress_port', client_port)]), forward_table.make_key( [gc.KeyTuple('ig_intr_md.ingress_port', server_port)]) ] data_list = [ forward_table.make_data( [gc.DataTuple('port', server_port), gc.DataTuple('ver', ver)], "SwitchIngress.hit"), forward_table.make_data( [gc.DataTuple('port', client_port), gc.DataTuple('ver', ver)], "SwitchIngress.hit") ] if is_mod: forward_table.entry_mod(target, key_list, data_list) else: forward_table.entry_add(target, key_list, data_list)
def replay_entries(self): seed = random.randint(0, 65535) logger.info("Seed used for Indirect Register Sync Test is %d", seed) random.seed(seed) num_entries = 1024 # Program the same register values in all the 4 pipes logger.info("Inserting %d entries into the register table", num_entries) target = gc.Target(device_id=0, pipe_id=0xffff) self.register_value_hi = [random.randint(1, 10000) for x in range(num_entries)] self.register_value_lo = [random.randint(1, 10000) for x in range(num_entries)] for x in range(num_entries): self.test_reg_table.entry_add( target, [self.test_reg_table.make_key([gc.KeyTuple('$REGISTER_INDEX', x)])], [self.test_reg_table.make_data( [gc.DataTuple('SwitchIngress.test_reg.first', self.register_value_lo[x]), gc.DataTuple('SwitchIngress.test_reg.second', self.register_value_hi[x])])])