def setUp(self, grpc_addr, proto_txt_path): #BaseTest.setUp(self) self.device_id = 0 # Setting up PTF dataplane # self.dataplane = ptf.dataplane_instance # self.dataplane.flush() self._swports = [] # for device, port, ifname in config["interfaces"]: # self._swports.append(port) # grpc_addr = testutils.test_param_get("grpcaddr") if grpc_addr is None: grpc_addr = 'localhost:50051' self.channel = grpc.insecure_channel(grpc_addr) self.stub = p4runtime_pb2_grpc.P4RuntimeStub(self.channel) # proto_txt_path = testutils.test_param_get("p4info") print "Importing p4info proto from", proto_txt_path self.p4info = p4info_pb2.P4Info() with open(proto_txt_path, "rb") as fin: google.protobuf.text_format.Merge(fin.read(), self.p4info) self.import_p4info_names() self.import_p4info_ids() # used to store write requests sent to the P4Runtime server, useful for # autocleanup of tests (see definition of autocleanup decorator below) self._reqs = [] self.set_up_stream()
def __init__(self, name, address='127.0.0.1:50051', device_id=0): self.name = name self.address = address self.device_id = device_id self.p4info = None self.channel = grpc.insecure_channel(self.address) self.client_stub = p4runtime_pb2_grpc.P4RuntimeStub(self.channel)
def __init__(self, p4info_helper, sw_info, p4_ingress, p4_egress, proto_dump_file=None): self.p4info_helper = p4info_helper self.sw_info = sw_info self.p4_ingress = p4_ingress self.p4_egress = p4_egress self.name = sw_info['name'] self.device_id = sw_info['id'] channel = grpc.insecure_channel(sw_info['grpc']) if proto_dump_file is not None: logger.info('Adding interceptor with file - [%s]', proto_dump_file) interceptor = GrpcRequestLogger(proto_dump_file) channel = grpc.intercept_channel(channel, interceptor) logger.info('Creating client stub to channel - [%s] at address - [%s]', channel, self.sw_info['grpc']) self.client_stub = p4runtime_pb2_grpc.P4RuntimeStub(channel) self.requests_stream = IterableQueue() self.stream_msg_resp = self.client_stub.StreamChannel( iter(self.requests_stream)) self.proto_dump_file = proto_dump_file self.digest_thread = Thread(target=self.receive_digests)
def setUp(self): BaseTest.setUp(self) self._swports = [] for device, port, ifname in config["interfaces"]: self._swports.append(port) grpc_addr = testutils.test_param_get("grpcaddr") if grpc_addr is None: grpc_addr = 'localhost:50051' self.device_id = int(testutils.test_param_get("device_id")) if self.device_id is None: self.fail("Device ID is not set") self.cpu_port = int(testutils.test_param_get("cpu_port")) if self.cpu_port is None: self.fail("CPU port is not set") self.device = testutils.test_param_get("device") if self.device is None: self.fail("Device is not set") pltfm = testutils.test_param_get("pltfm") if pltfm is not None and pltfm == 'hw' and getattr( self, "_skip_on_hw", False): raise SkipTest("Skipping test in HW") proto_txt_path = testutils.test_param_get("p4info") # print "Importing p4info proto from", proto_txt_path self.p4info = p4info_pb2.P4Info() with open(proto_txt_path, "rb") as fin: google.protobuf.text_format.Merge(fin.read(), self.p4info) self.import_p4info_names() # used to store write requests sent to the P4Runtime server, useful for # autocleanup of tests (see definition of autocleanup decorator below) self.reqs = [] self.election_id = 1 if testutils.test_param_get("generate_tv") == 'True': self.generate_tv = True else: self.generate_tv = False if self.generate_tv: self.tv_list = [] self.tv_name = self.__class__.__name__ else: # Setting up PTF dataplane self.dataplane = ptf.dataplane_instance self.dataplane.flush() self.channel = grpc.insecure_channel(grpc_addr) self.stub = p4runtime_pb2_grpc.P4RuntimeStub(self.channel) self.set_up_stream()
def __init__(self, device_id, grpc_addr, election_id): self.device_id = device_id self.election_id = election_id logging.debug("Connecting to device {} at {}".format(device_id, grpc_addr)) try: self.channel = grpc.insecure_channel(grpc_addr) except Exception: logging.critical("Failed to connect to P4Runtime server") sys.exit(1) self.stub = p4runtime_pb2_grpc.P4RuntimeStub(self.channel) self.stream_recv_handlers = [] self.set_up_stream()
def __init__(self, name, address='127.0.0.1:50051', device_id=0, type='bmv2', crypto_address = None, debug=False): self.name = name self.address = address self.device_id = device_id self.p4info = None self.channel = grpc.insecure_channel(self.address) self.client_stub = p4runtime_pb2_grpc.P4RuntimeStub(self.channel) self.type = type self.crypto_client = None if self.type == 'tofino': self.crypto_client = TofinoCryptoClient(crypto_address) self.debug = debug self.request_lock = threading.Lock()
def __init__(self, device_id, grpc_addr, election_id): self.device_id = device_id self.election_id = election_id self.grpc_addr = grpc_addr logger.debug("Connecting to device {} at {}".format(device_id, grpc_addr)) try: self.channel = grpc.insecure_channel(grpc_addr) except Exception: logger.critical("Failed to connect to P4Runtime server") sys.exit(1) self.stub = p4runtime_pb2_grpc.P4RuntimeStub(self.channel) return
def __init__(self): self.host = ServerConfig.HOST self.server_port = ServerConfig.SERVER_PORT self.device_id = 0 with open(ServerConfig.SERVER_CERTIFICATE, "rb") as file: trusted_certs = file.read() self.credentials = grpc.ssl_channel_credentials( root_certificates=trusted_certs) self.channel = grpc.secure_channel( "{}:{}".format(self.host, self.server_port), self.credentials) self.stub = p4runtime_pb2_grpc.P4RuntimeStub(self.channel)
def __init__(self, name=None, address='127.0.0.1:50051', device_id=0, proto_dump_file=None): self.name = name self.address = address self.device_id = device_id self.p4info = None self.channel = grpc.insecure_channel(self.address) if proto_dump_file is not None: interceptor = GrpcRequestLogger(proto_dump_file) self.channel = grpc.intercept_channel(self.channel, interceptor) self.client_stub = p4runtime_pb2_grpc.P4RuntimeStub(self.channel) self.requests_stream = IterableQueue() self.stream_msg_resp = self.client_stub.StreamChannel(iter(self.requests_stream)) self.proto_dump_file = proto_dump_file connections.append(self)
def __init__(self): # Configure the host and the port to which the client should connect to. self.host = ServerConfig.HOST self.server_port = ServerConfig.SERVER_PORT with open(ServerConfig.SERVER_CERTIFICATE, "rb") as file: trusted_certs = file.read() # Instantiate a communication channel and bind the client to the server. self.credentials = grpc.ssl_channel_credentials(root_certificates=trusted_certs) self.channel = grpc.secure_channel("{}:{}".format(self.host, self.server_port), self.credentials) self.stub = p4runtime_pb2_grpc.P4RuntimeStub(self.channel) self.streamChannelRequest = p4runtime_pb2.StreamMessageRequest() self.sendRequest = True
def __init__(self, sw_info, p4_ingress, p4_egress, proto_dump_file=None): super(P4RuntimeSwitch, self).__init__(sw_info) p4info_txt = sw_info['runtime_p4info'] logger.info('Loading p4info_helper with file - [%s]', p4info_txt) self.p4info_helper = helper.P4InfoHelper(p4info_txt) self.p4_ingress = p4_ingress self.p4_egress = p4_egress grpc_channel = grpc.insecure_channel(self.grpc_addr) if proto_dump_file is not None: logger.info('Adding interceptor with file - [%s] to device [%s]', proto_dump_file, self.grpc_addr) interceptor = GrpcRequestLogger(proto_dump_file) grpc_channel = grpc.intercept_channel(grpc_channel, interceptor) logger.info('Creating client stub to channel - [%s] at address - [%s]', grpc_channel, self.grpc_addr) self.client_stub = p4runtime_pb2_grpc.P4RuntimeStub(grpc_channel) self.requests_stream = IterableQueue() self.stream_msg_resp = self.client_stub.StreamChannel( iter(self.requests_stream)) self.proto_dump_file = proto_dump_file self.digest_thread = Thread(target=self.receive_digests)
def update_config(config_path, p4info_path, grpc_addr, device_id): ''' Performs a SetForwardingPipelineConfig on the device with provided P4Info and binary device config ''' channel = grpc.insecure_channel(grpc_addr) stub = p4runtime_pb2_grpc.P4RuntimeStub(channel) print("Sending P4 config") request = p4runtime_pb2.SetForwardingPipelineConfigRequest() request.device_id = device_id config = request.config with open(p4info_path, 'r') as p4info_f: google.protobuf.text_format.Merge(p4info_f.read(), config.p4info) with open(config_path, 'rb') as config_f: config.p4_device_config = config_f.read() request.action = p4runtime_pb2.SetForwardingPipelineConfigRequest.VERIFY_AND_COMMIT try: response = stub.SetForwardingPipelineConfig(request) except Exception as e: print("Error during SetForwardingPipelineConfig") print(str(e)) return False return True
def __init__(self, device_id, grpc_addr, election_id, role_name=None, ssl_options=None): self.device_id = device_id self.election_id = election_id self.role_name = role_name if ssl_options is None: self.ssl_options = SSLOptions(True) else: self.ssl_options = ssl_options logging.debug("Connecting to device {} at {}".format(device_id, grpc_addr)) if self.ssl_options.insecure: try: logging.debug("Using insecure channel") self.channel = grpc.insecure_channel(grpc_addr) except Exception: logging.critical("Failed to connect to P4Runtime server") sys.exit(1) else: # root certificates are retrieved from a default location chosen by gRPC runtime unless # the user provides custom certificates. root_certificates = None if self.ssl_options.cacert is not None: root_certificates = read_pem_file(self.ssl_options.cacert) certificate_chain = None if self.ssl_options.cert is not None: certificate_chain = read_pem_file(self.ssl_options.cert) private_key = None if self.ssl_options.key is not None: private_key = read_pem_file(self.ssl_options.key) creds = grpc.ssl_channel_credentials(root_certificates, private_key, certificate_chain) try: self.channel = grpc.secure_channel(grpc_addr, creds) except Exception: logging.critical("Failed to connect to P4Runtime server") sys.exit(1) self.stub = p4runtime_pb2_grpc.P4RuntimeStub(self.channel) self.set_up_stream()
def __init__(self, name=None, address='127.0.0.1:50051', device_id=0, proto_dump_file=None): self.name = name self.address = address self.device_id = device_id self.p4info = None self.channel = grpc.insecure_channel(self.address) if proto_dump_file is not None: interceptor = GrpcRequestLogger(proto_dump_file) self.channel = grpc.intercept_channel(self.channel, interceptor) self.client_stub = p4runtime_pb2_grpc.P4RuntimeStub(self.channel) self.proto_dump_file = proto_dump_file self.stream_out_q = IterableQueue() self.stream_in_q = IterableQueue() self.stream = self.client_stub.StreamChannel(self.stream_req_iterator()) self.stream_recv_thread = threading.Thread( target=self.stream_recv, args=(self.stream,)) self.active = True connections.append(self)
def __init__(self, name=None, address="127.0.0.1:50051", device_id=0, p4info_file_path=None, proto_dump_file=None, p4configjson=None, toFlowID=0xffff0000, queueDepth=1000, queueRate=1000, thriftPort=9090, controlPlaneDelay=0): self.name = name self.toFlowID = toFlowID self.address = address self.device_id = device_id self.swNum = device_id + 1 self.p4info = None self.bmv2_json_file_path = NotImplemented # set this at programming time self.p4info_file_path = p4info_file_path self.p4info_helper = p4runtime_lib_helper.P4InfoHelper( p4info_file_path) self.channel = grpc.insecure_channel(self.address) if proto_dump_file is not None: interceptor = GrpcRequestLogger(proto_dump_file) self.channel = grpc.intercept_channel(self.channel, interceptor) self.client_stub = p4runtime_pb2_grpc.P4RuntimeStub(self.channel) self.proto_dump_file = proto_dump_file self.p4configjson = p4configjson ## below is from me: self.stop = False self.defaultRules = [] self.activePorts = {} self.activePorts[1] = 0 self.inactivePorts = [] self.activeServices = {} self.master = False self.stream_out_q = Queue() self.qlogfile = open('logs/' + str(self.device_id) + '.log', "w+") self.qlogfileFirst = False self.numdigest = 0 self.vnfList = [] self.services = [] self.flowRates = {} self.queueDepth = queueDepth self.thriftPort = thriftPort self.queueRate = queueRate self.overloadDetected = False self.migThreads = [] self.controlPlaneDelay = controlPlaneDelay self.overloading = 0 def stream_req_iterator(): while True: p = self.stream_out_q.get() if p is None: break yield p def stream_recv(self): i = 0 #pr = cProfile.Profile() for msg in self.stream: tStart = time() if msg.HasField('packet'): if msg.packet.payload.encode( 'hex')[0:4] == '3341' or msg.packet.payload.encode( 'hex')[0:4] == '3143': #print msg.packet.payload.encode('hex') + ' recevied from ' + str(self.name) if (msg.packet.payload.encode('hex')[20] == str( self.swNum) and (msg.packet.payload.encode('hex')[0:4] == '3341')): # this packet is a sync thing received from a migration source: #print msg.packet.payload.encode('hex') migThread = threading.Thread(target=self.doCPSYnc, args=(msg, )) migThread.start() else: migThread = threading.Thread( target=self.processMigPkt, args=(msg, )) migThread.start() #print "processing migpacket took %f seconds"% float(time() - tStart) else: pkt = controlPacket.controlPacket(msg, self.name, ts=float(tStart)) # # break if no valid ethtype can be derived if hasattr(pkt.eth, 'type') and pkt.eth != None: discList = [0xffff, 0xffee, 0xeffe] ignoreList = [0x86dd, 0x0806] if pkt.eth.type in discList: thread = threading.Thread( target=self.processDiscPacket, args=(pkt, )) thread.start() continue elif hex(pkt.eth.type ) not in ignoreList and pkt.ip != None: thread = threading.Thread( target=self.processpacketIn, args=(pkt, )) thread.start() elif msg.HasField('arbitration'): print('arbitration packet recieved!') if not msg.arbitration.status.message == "Is master": print('Error setting controller as master for device') else: self.master = True elif msg.HasField('digest'): # Digest message received. Send digestACK back: self.digestMessageACK(msg.digest.digest_id, msg.digest.list_id) self.numdigest += 1 digFields = self.p4info_helper.get_digest_fields_by_id( msg.digest.digest_id) # convert message to json format: dictMsg = google.protobuf.json_format.MessageToDict(msg) # read information to a dictionary: infoDict = {} printVals = [] printHdrs = [] enq_qdepth = None deq_qdepth = None deq_timedelta = None threshold = None timestamp = None flowID = None numPackets = None enq_timestamp = None for x in range(0, len(digFields)): for y in digFields[x]: infoDict[y] = {} infoDict[y]['value'] = int( bytes( base64.decodestring( dictMsg['digest']['data'][0]['struct'] ['members'][x]['bitstring'])).encode( 'hex'), 16) infoDict[y]['bitlength'] = digFields[x][y] if self.qlogfileFirst == False: printHdrs.append(str(y)) printVals.append(infoDict[y]['value']) if False == True: print '%s, (%i bit): %i' % ( y, infoDict[y]['bitlength'], infoDict[y]['value']) # save values if str(y) == str('enq_qdepth'): enq_qdepth = infoDict[y]['value'] if str(y) == str('deq_qdepth'): deq_qdepth = infoDict[y]['value'] if str(y) == str('deq_timedelta'): deq_timedelta = float( infoDict[y]['value']) / float( 1000000) # convert to ms if str(y) == str('threshold'): threshold = infoDict[y]['value'] if str(y) == str('timestamp'): timestamp = infoDict[y]['value'] if str(y) == str('flowID'): flowID = infoDict[y]['value'] if str(y) == str('numPackets'): numPackets = infoDict[y]['value'] if str(y) == str('enq_timestamp'): enq_timestamp = infoDict[y]['value'] if enq_qdepth != None and deq_qdepth != None and deq_timedelta != None and enq_timestamp != None: # print 'SWITCH OVERLOADING!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!' # print "enq_qdepth %s" % enq_qdepth # print "deq_qdepth %s" % deq_qdepth # print "deq_timedelta %s" % deq_timedelta # figure out what to do # create a thread that runs the checks for migration and initializes the migration. # runMigration = False # if self.overloadDetected == False: # runMigration = True # # try: # # if (time() - float(self.overloadDetected)) > float(10): # # runMigration = True # # except: # # pass t = threading.Thread(target=pktMon.addpktDigestReading, args=(self.name, enq_qdepth, deq_qdepth, deq_timedelta, enq_timestamp)) t.start() #print 'enqdepth: %i, deqdepth:%i' % (enq_qdepth, deq_qdepth) if (enq_qdepth < deq_qdepth) and (deq_qdepth > 20): #print "enqQdepth: %f deqQdepth: %f" %(float(enq_qdepth), float(deq_qdepth)) # NO SCALING IF CONTINUE BELOW HERE! #continue if self.overloadDetected == False: # and self.overloading > 5: self.overloadDetected = tStart migrateThread = threading.Thread( target=flowHandler.migrationHandler, args=(self, enq_timestamp)) migrateThread.start() print('Switch %s overloading!!!!' % self.name) # Start the procedure to redirect the load to an other switch (if possible). # if no solution exists, a new hardware switch should be added. # This can be a problem.... elif threshold != None and timestamp != None and flowID != None and numPackets != None: # this is a packet for rates.... t = threading.Thread(target=flowMonitor.addReading, args=(flowID, timestamp, numPackets, self)) t.start() #flowMonitor.addReading(flowID, timestamp, numPackets, self) #print "%i/%i at timestamp %i for flowID %s from switch %s" % (numPackets, threshold, timestamp, flowID, self.name) else: print ' begin hellup' if enq_qdepth == None: print 'enq_qdepth is none' if deq_qdepth == None: print 'deq_qdepth is none' if deq_timedelta == None: print 'deq_timedelta is none' print ' eind hellup' # # writ things to file # if self.qlogfileFirst == False: # self.qlogfile.write(str(printHdrs) + '\n') # self.qlogfileFirst = True # self.qlogfile.write(str(printVals) + '\n') else: print('unknown packet received') # has completed successfully tElapsed = time() - tStart #print("Elapsed time for packetin/out: %.20f ms" %(tElapsed * 1000)) self.stream = self.client_stub.StreamChannel(stream_req_iterator()) self.stream_recv_thread = threading.Thread(target=stream_recv, args=(self, )) self.stream_recv_thread.start() # send masterarbitrationupdate: req = p4runtime_pb2.StreamMessageRequest() arbitration = req.arbitration arbitration.device_id = self.device_id arbitration.election_id.high = 0 arbitration.election_id.low = 1 self.stream_out_q.put(req) switchFinder.addSwitch(self)
def update_config(p4info_path, bmv2_json_path, grpc_addr, device_id): """ Performs a SetForwardingPipelineConfig on the device """ channel = grpc.insecure_channel(grpc_addr) stub = p4runtime_pb2_grpc.P4RuntimeStub(channel) debug("Sending P4 config") # Send master arbitration via stream channel # This should go in library, to be re-used also by base_test.py. stream_out_q = Queue.Queue() stream_in_q = Queue.Queue() def stream_req_iterator(): while True: p = stream_out_q.get() if p is None: break yield p def stream_recv(stream): for p in stream: stream_in_q.put(p) def get_stream_packet(type_, timeout=1): start = time.time() try: while True: remaining = timeout - (time.time() - start) if remaining < 0: break msg = stream_in_q.get(timeout=remaining) if not msg.HasField(type_): continue return msg except: # timeout expired pass return None stream = stub.StreamChannel(stream_req_iterator()) stream_recv_thread = threading.Thread(target=stream_recv, args=(stream, )) stream_recv_thread.start() req = p4runtime_pb2.StreamMessageRequest() arbitration = req.arbitration arbitration.device_id = device_id election_id = arbitration.election_id election_id.high = 0 election_id.low = 1 stream_out_q.put(req) rep = get_stream_packet("arbitration", timeout=5) if rep is None: error("Failed to establish handshake") return False try: # Set pipeline config. request = p4runtime_pb2.SetForwardingPipelineConfigRequest() request.device_id = device_id election_id = request.election_id election_id.high = 0 election_id.low = 1 config = request.config with open(p4info_path, 'r') as p4info_f: google.protobuf.text_format.Merge(p4info_f.read(), config.p4info) config.p4_device_config = build_bmv2_config(bmv2_json_path) request.action = p4runtime_pb2.SetForwardingPipelineConfigRequest.VERIFY_AND_COMMIT try: stub.SetForwardingPipelineConfig(request) except Exception as e: error("Error during SetForwardingPipelineConfig") error(str(e)) return False return True finally: stream_out_q.put(None) stream_recv_thread.join()
def update_config(p4info_path, bmv2_json_path, tofino_bin_path, tofino_cxt_json_path, grpc_addr, device_id, generate_tv=False): """ Performs a SetForwardingPipelineConfig on the device """ # Build pipeline config request request = p4runtime_pb2.SetForwardingPipelineConfigRequest() request.device_id = device_id election_id = request.election_id election_id.high = 0 election_id.low = 1 config = request.config with open(p4info_path, 'r') as p4info_f: google.protobuf.text_format.Merge(p4info_f.read(), config.p4info) if bmv2_json_path is not None: device_config = build_bmv2_config(bmv2_json_path) else: device_config = build_tofino_config("name", tofino_bin_path, tofino_cxt_json_path) config.p4_device_config = device_config request.action = p4runtime_pb2.SetForwardingPipelineConfigRequest.VERIFY_AND_COMMIT if generate_tv: # Create new target proto object for testvectors if bmv2_json_path is not None: tv_target = targetutils.get_new_target(grpc_addr, target_id="bmv2") else: tv_target = targetutils.get_new_target(grpc_addr, target_id="tofino") # Write the target proto object to testvectors/target.pb.txt targetutils.write_to_file(tv_target, os.getcwd()) # Create new testvector for set pipeline config and write to testvectors/PipelineConfig.pb.txt tv = tvutils.get_new_testvector() tv_name = "PipelineConfig" tc = tvutils.get_new_testcase(tv, tv_name) tvutils.add_pipeline_config_operation(tc, request) tvutils.write_to_file(tv, os.getcwd(), tv_name) return True channel = grpc.insecure_channel(grpc_addr) stub = p4runtime_pb2_grpc.P4RuntimeStub(channel) info("Sending P4 config") # Send master arbitration via stream channel # This should go in library, to be re-used also by base_test.py. stream_out_q = Queue.Queue() stream_in_q = Queue.Queue() def stream_req_iterator(): while True: p = stream_out_q.get() if p is None: break yield p def stream_recv(stream): for p in stream: stream_in_q.put(p) def get_stream_packet(type_, timeout=1): start = time.time() try: while True: remaining = timeout - (time.time() - start) if remaining < 0: break msg = stream_in_q.get(timeout=remaining) if not msg.HasField(type_): continue return msg except: # timeout expired pass return None stream = stub.StreamChannel(stream_req_iterator()) stream_recv_thread = threading.Thread(target=stream_recv, args=(stream, )) stream_recv_thread.start() req = p4runtime_pb2.StreamMessageRequest() arbitration = req.arbitration arbitration.device_id = device_id election_id = arbitration.election_id election_id.high = 0 election_id.low = 1 stream_out_q.put(req) rep = get_stream_packet("arbitration", timeout=5) if rep is None: error("Failed to establish handshake") return False try: try: stub.SetForwardingPipelineConfig(request) except Exception as e: error("Error during SetForwardingPipelineConfig") error(str(e)) return False return True finally: stream_out_q.put(None) stream_recv_thread.join()