def setUpGrpcClient(self): try: logger.warn("Binding client[%s] to device[%s]@%s with MASTER role", self.client_id, self.device_id, self.grpc_addr) self.interface = gc.ClientInterface(self.grpc_addr, client_id=self.client_id, device_id=self.device_id, is_master=self.is_master, notifications=self.notification) except Exception as e: logger.error("Error in %s. Is grpc server running at %s ?" % (sys._getframe().f_code.co_name, self.grpc_addr))
def __init__(self, program, retries, addr='localhost:50052', client_id=0, device_id=0): ## Due to a bug in client.py, the num_tries parameter is currently ## fixed at 5. re_retries = int((retries - 1) / 5) + 1 for i in range(0, re_retries): ## The "is_master" argument has been removed in SED 9.4.0 args = dict(client_id=client_id, num_tries=retries, device_id=device_id) if "is_master" in inspect.getargspec( gc.ClientInterface.__init__).args: args["is_master"] = True try: self.intf = gc.ClientInterface(addr, **args) except: if i < re_retries - 1: continue else: raise Exception("connection attempts exceeded") else: break self.intf.bind_pipeline_config(program) self.target = gc.Target(device_id=device_id, pipe_id=0xffff) self.info = self.intf.bfrt_info_get()
def main(): print("Starting...") grpc_addr = 'localhost:50052' client_id = 1 is_master = False p4_name = "netassay_tunnel_j8" interface = gc.ClientInterface(grpc_addr, client_id=client_id, device_id=0, is_master=is_master) interface.bind_pipeline_config(p4_name) target = gc.Target(device_id=0, pipe_id=0xffff) bfrt_info = interface.bfrt_info_get(p4_name) def signal_handler(sig, frame): print('You pressed Ctrl+C! Tearing down gRPC connection...') interface._tear_down_stream() sys.exit(0) signal.signal(signal.SIGINT, signal_handler) while 1: # pull regsiters 1 client_reg_pair_1 = bfrt_info.table_get( "SwitchEgress.client_reg_pair_1") entries_list = client_reg_pair_1.entry_get(target) ip_count_pair_list_1 = get_index_and_value_tunnel( entries_list, "SwitchEgress.client_reg_pair_1.cip", "SwitchEgress.client_reg_pair_1.counter") # pull regsiters 2 client_reg_pair_2 = bfrt_info.table_get( "SwitchEgress.client_reg_pair_2") entries_list = client_reg_pair_2.entry_get(target) ip_count_pair_list_2 = get_index_and_value_tunnel( entries_list, "SwitchEgress.client_reg_pair_2.cip", "SwitchEgress.client_reg_pair_2.counter") # combine ip_count_pair_list_all = ip_count_pair_list_1 + ip_count_pair_list_2 # print print("Suspected clients using DNS tunneling...(w/ counter value):") for i in ip_count_pair_list_all: ip_addr = socket.inet_ntoa(struct.pack("!I", int(i[0]))) print("- {}: {}".format(str(ip_addr), str(i[1]))) print("\n\n") # sleep time.sleep(INTERVAL_SECONDS) # Tear down. interface._tear_down_stream() exit() interface._tear_down_stream()
import sys import os sys.path.append( os.path.expandvars('$SDE/install/lib/python2.7/site-packages/tofino/')) from bfrt_grpc import client GRPC_CLIENT = client.ClientInterface(grpc_addr="localhost:50052", client_id=0, device_id=0, is_master=True) bfrt_info = GRPC_CLIENT.bfrt_info_get(p4_name=None) GRPC_CLIENT.bind_pipeline_config(p4_name=bfrt_info.p4_name) def table_add(table_name, match_key_names_list, match_key_values_list, action_name, action_data_names_list, action_data_values_list): # simply a wrapper t = bfrt_info.table_dict[table_name] def table_add_gen_kd(table_name, match_key_names_list, match_key_values_list, action_name, action_data_names_list, action_data_values_list): # prepare to add a single match-action table rule t = bfrt_info.table_dict[table_name] # prepare KeyTuple KeyTuple_list = [] for keyName, keyValue in zip(match_key_names_list, match_key_values_list): KeyTuple_list.append(client.KeyTuple(name=keyName, value=keyValue))
def fill_table_with_junk(target, table, table_size): table_clear(target, table) for i in range(table_size): table_add(target, table, [("hdr.qmon.qmon_key", i)], "qmon_forward", [("port", 152)]) # 104 try: grpc_addr = "localhost:50052" # ToDo: IP address of switch 1 client_id = 0 device_id = 0 pipe_id = 0xFFFF is_master = True client = gc.ClientInterface(grpc_addr, client_id, device_id, is_master) target = gc.Target(device_id, pipe_id) client.bind_pipeline_config("qmon") ipv4_exact = client.bfrt_info_get().table_get( "pipe.SwitchIngress.ipv4_exact") resubmit_ctrl = client.bfrt_info_get().table_get( "pipe.SwitchIngress.resubmit_ctrl") reg_match = client.bfrt_info_get().table_get( "pipe.SwitchIngress.reg_match") qlen = client.bfrt_info_get().table_get("pipe.SwitchIngress.qlen") reg_match_egress = client.bfrt_info_get().table_get( "pipe.SwitchEgress.reg_match") qlen_egress = client.bfrt_info_get().table_get("pipe.SwitchEgress.qlen") table3 = client.bfrt_info_get().table_get("$PORT") table_clear(target, ipv4_exact) table_clear(target, resubmit_ctrl)
ks = [] x = table.entry_get(target) for i in x: ks.append(i[1]) if None in ks: ks.remove(None) table.entry_del(target, ks) grpc_addr = 'localhost:50052' client_id = 1 is_master = False p4_name = "pinot64" interface = gc.ClientInterface(grpc_addr, client_id=client_id, device_id=0, is_master=is_master) interface.bind_pipeline_config(p4_name) target = gc.Target(device_id=0, pipe_id=0xffff) bfrt_info = interface.bfrt_info_get(p4_name) forward_table = bfrt_info.table_get("SwitchIngress.forward") svr_table_6 = bfrt_info.table_get("SwitchIngress.get_svr_addr6") svr_table_6.info.key_field_annotation_add("hdr.ipv4.dst_addr", "ipv4") svr_table_4 = bfrt_info.table_get("SwitchIngress.get_svr_addr4")
#if not len(logger.handlers): # logger.addHandler(logging.StreamHandler()) logger.info("SwitchML controller starting up...") logger.info("""\n ****************************** *** Hit Control-\ to exit! *** ****************************** """) # connect to GRPC server logger.info( "Connecting to GRPC server {}:{} and binding to program {}...".format( args.grpc_server, args.grpc_port, args.program)) c = gc.ClientInterface("{}:{}".format(args.grpc_server, args.grpc_port), 0, 0, is_master=False) c.bind_pipeline_config(args.program) # get all tables for program bfrt_info = c.bfrt_info_get(args.program) # # configure job # # # Print overall list of tables # logger.info(pformat(bfrt_info.table_dict)) # mac, ip, and udp port number that switch will respond to for SwitchML # port number is associated with a mask for use with legacy SwitchML code
log_file = '{}/{}'.format(args.log_dir, args.log_file) logging.basicConfig(level=logging.DEBUG, filename=log_file) else: logging.basicConfig(stream=sys.stdout, level=logging.DEBUG) # # Connect to the BF Runtime Server # logger.info('Creating client interface with client stub') logger.debug( 'grpc-addr - [%s], client_id - [%s], device_id - [%s], ' 'is_master - [%s]', args.grpc_addr, args.client_id, args.device_id, args.is_master) interface = bfrt_client.ClientInterface(grpc_addr=args.grpc_addr, client_id=args.client_id, device_id=args.device_id, is_master=args.is_master) # # Get the information about the running program # bfrt_info = interface.bfrt_info_get(args.program_name) # Attempt to receive the ID for the args.table_name argument if args.table_name: logger.info('Retrieve table name - [%s]', args.table_name) try: table = bfrt_info.table_get(args.table_name) logger.info('Table ID - [%s]', table.info.id_get()) except Exception as e: logger.error("Exit with error - [%s]", e)
def setup( self, program, switch_mac, switch_ip, bfrt_ip, bfrt_port, ports_file, ): # Device 0 self.dev = 0 # Target all pipes self.target = gc.Target(self.dev, pipe_id=0xFFFF) # Connect to BFRT server try: interface = gc.ClientInterface('{}:{}'.format(bfrt_ip, bfrt_port), client_id=0, device_id=self.dev) except RuntimeError as re: msg = re.args[0] % re.args[1] self.critical_error(msg) else: self.log.info('Connected to BFRT server {}:{}'.format( bfrt_ip, bfrt_port)) try: interface.bind_pipeline_config(program) except gc.BfruntimeForwardingRpcException: self.critical_error('P4 program {} not found!'.format(program)) try: # Get all tables for program self.bfrt_info = interface.bfrt_info_get(program) # Ports table self.ports = Ports(self.target, gc, self.bfrt_info) # Enable loopback on front panel ports loopback_ports = ( [64] + # Pipe 0 CPU ethernet port # Pipe 0: all 16 front-panel ports #list(range( 0, 0+64,4)) + # Pipe 1: all 16 front-panel ports list(range(128, 128 + 64, 4)) + # Pipe 2: all 16 front-panel ports list(range(256, 256 + 64, 4)) + # Pipe 3: all 16 front-panel ports list(range(384, 384 + 64, 4))) print('Setting {} front panel ports in loopback mode'.format( len(loopback_ports))) self.ports.set_loopback_mode(loopback_ports) # Enable loopback on PktGen ports pktgen_ports = [192, 448] if not self.ports.get_loopback_mode_pktgen(pktgen_ports): # Not all PktGen ports are in loopback mode print('\nYou must \'remove\' the ports in the BF ucli:\n') for p in pktgen_ports: print(' bf-sde> dvm rmv_port 0 {}'.format(p)) input('\nPress Enter to continue...') if not self.ports.set_loopback_mode_pktgen(pktgen_ports): self.critical_error( 'Failed setting front panel ports in loopback mode') print('\nAdd the ports again:\n') for p in pktgen_ports: print(' bf-sde> dvm add_port 0 {} 100 0'.format(p)) input('\nPress Enter to continue...') if not self.ports.get_loopback_mode_pktgen(pktgen_ports): self.critical_error( 'Front panel ports are not in loopback mode') # Packet Replication Engine table self.pre = PRE(self.target, gc, self.bfrt_info, self.cpu_port) # Setup tables # Forwarder self.forwarder = Forwarder(self.target, gc, self.bfrt_info, self.all_ports_mgid) # ARP and ICMP responder self.arp_and_icmp = ARPandICMPResponder(self.target, gc, self.bfrt_info) # Drop simulator self.drop_simulator = DropSimulator(self.target, gc, self.bfrt_info) # RDMA receiver self.rdma_receiver = RDMAReceiver(self.target, gc, self.bfrt_info) # UDP receiver self.udp_receiver = UDPReceiver(self.target, gc, self.bfrt_info) # Bitmap checker self.bitmap_checker = BitmapChecker(self.target, gc, self.bfrt_info) # Workers counter self.workers_counter = WorkersCounter(self.target, gc, self.bfrt_info) # Exponents self.exponents = Exponents(self.target, gc, self.bfrt_info) # Processors self.processors = [] for i in range(32): p = Processor(self.target, gc, self.bfrt_info, i) self.processors.append(p) # Next step selector self.next_step_selector = NextStepSelector(self.target, gc, self.bfrt_info) # RDMA sender self.rdma_sender = RDMASender(self.target, gc, self.bfrt_info) # UDP sender self.udp_sender = UDPSender(self.target, gc, self.bfrt_info) # Add multicast group for flood self.pre.add_multicast_group(self.all_ports_mgid) # Enable ports success, ports = self.load_ports_file(ports_file) if not success: self.critical_error(ports) # Set switch addresses self.set_switch_mac_and_ip(switch_mac, switch_ip) # CLI setup self.cli = Cli() self.cli.setup(self, prompt='SwitchML', name='SwitchML controller') # Set up gRPC server self.grpc_server = GRPCServer(ip='[::]', port=50099) # Run event loop for gRPC server in a separate thread # limit concurrency to 1 to avoid synchronization problems in the BFRT interface self.grpc_executor = futures.ThreadPoolExecutor(max_workers=1) self.event_loop = asyncio.get_event_loop() except KeyboardInterrupt: self.critical_error('Stopping controller.') except Exception as e: self.log.exception(e) self.critical_error('Unexpected error. Stopping controller.')
return parser.parse_args() if __name__ == '__main__': """ Inserts entries into P4 tables based on the entries within table config file """ args = get_args() logger = logging.getLogger('bfrt_connect') logging.basicConfig(level=logging.DEBUG) # # Connect to the BF Runtime Server # interface = bfrt_client.ClientInterface(grpc_addr=args.grpc_addr, client_id=0, device_id=0, is_master=True) logger.info('Connected to BF Runtime Server') target = bfrt_client.Target(device_id=args.device_id, pipe_id=0xffff) # # Get the information about the running program # bfrt_info = interface.bfrt_info_get() p4_name = bfrt_info.p4_name_get() logger.info('The target runs program ', p4_name) interface.bind_pipeline_config(p4_name) table_name = "{}.{}".format(args.ingress, args.table) logger.info('Table name - [%s]', table_name) table = bfrt_info.table_get(table_name)