def process_counter_read(switch_id, entry): # Get the counter (register) object from the database. counter_id = entry.counter_id counter = SwitchConf.getRegisterById(switch_id, counter_id) if counter is False: code = grpc.StatusCode.NOT_FOUND message = "Counter with id {} not found".format(counter_id) return (p4runtime_pb2.ReadResponse(), code, message) ServerConfig.print_debug( "Processing read request for counter {} from switch id {}".format( counter.reg_name, counter.switch_id)) data = p4_regs_api.reg_read(counter.switch_id, counter.reg_name, entry.index.index) if data is False: code = grpc.StatusCode.NOT_FOUND message = "Failed reading data from counter '{}'".format( counter.reg_name) return (p4runtime_pb2.ReadResponse(), code, message) # Create and fill the counter read response. response = p4runtime_pb2.ReadResponse() resp_entity = response.entities.add() resp_entity.counter_entry.counter_id = counter_id + 10 resp_entity.counter_entry.index.index = entry.index.index code = grpc.StatusCode.OK message = None return (response, code, message)
def process_register_read(switch_id, entry): # Get the register object from the database. register_id = entry.register_id register = SwitchConf.getRegisterById(switch_id, register_id) if register is False: code = grpc.StatusCode.NOT_FOUND message = "Register with id {} not found".format(register_id) return (p4runtime_pb2.ReadResponse(), code, message) # TODO: finish this when testing is possible. ServerConfig.print_debug( "Processing read request for register {} from switch id {}".format( register.reg_name, register.switch_id)) data = p4_regs_api.reg_read(register.switch_id, register.reg_name, entry.index.index) if data is False: code = grpc.StatusCode.NOT_FOUND message = "Failed reading data from register '{}'".format( register.reg_name) return (p4runtime_pb2.ReadResponse(), code, message) # Create and fill the register read response. response = p4runtime_pb2.ReadResponse() resp_entity = response.entities.add() resp_entity.register_entry.register_id = register_id resp_entity.register_entry.index.index = entry.index.index resp_entity.register_entry.data.enum_value = bytes(data) code = grpc.StatusCode.OK message = None return (response, code, message)
def process_table_read(peer_key, username, switch, entry): # Get the switch table object from the database. table_id = entry.table_id try: table = SwitchConf.table_dict[switch.switch_id, table_id] except KeyError: code = grpc.StatusCode.NOT_FOUND message = "Table with id {} not found".format(table_id) return (p4runtime_pb2.ReadResponse(), code, message) # Check the table type. match = entry.match[0] if not match.HasField("exact"): code = grpc.StatusCode.UNIMPLEMENTED message = "The requested table type is not supported" return (p4runtime_pb2.ReadResponse(), code, message) # Necessary match manipulations. match = entry.match[0] match_key = entry.match[0].exact.value match_key = re.sub('match_key', '[match_key]', match_key) match_key = match_key.split() match_key = ast.literal_eval(json.dumps(match_key)) # Read the data from the requested table entry. ServerConfig.print_debug( "Processing read request from {}({}) for table {}, switch {}". format(peer_key, username, table.table_name, switch.switch_name)) (found, data) = p4_tables_api.table_cam_read_entry(switch, table, match_key) ServerConfig.print_debug("Entry found: {}, data: {}\n".format( found, data)) # Create and fill the table read response. # Note that the action parameter id is hardcoded. response = p4runtime_pb2.ReadResponse() resp_entity = response.entities.add() resp_entity.table_entry.table_id = table.table_id resp_match = resp_entity.table_entry.match.add() resp_match.field_id = match.field_id resp_match.exact.value = match.exact.value bin_data = bin(int(data, 16))[2:] if len(bin_data) % 4: padding = 4 - (len(bin_data) % 4) bin_data = "0" * padding + bin_data resp_entity.table_entry.action.action.action_id = int(bin_data[0:4], 2) resp_action = resp_entity.table_entry.action.action.params.add() resp_action.param_id = 2 resp_action.value = bin_data[4:] ServerConfig.print_debug(response) code = grpc.StatusCode.OK message = None return (response, code, message)
def process_read_request(request, context): peer_key = context.peer() username = ConnectionArray.getUsername(peer_key) ServerConfig.print_debug("Received read request from {}({}):".format( peer_key, username)) ServerConfig.print_debug(request) # Verify if the user is authenticated. if ConnectionArray.isAuthenticated(context.peer()) is False: user_name = ConnectionArray.getUsername(context.peer()) context.set_code(grpc.StatusCode.UNAUTHENTICATED) context.set_details( "User '{}' is not authenticated".format(user_name)) yield p4runtime_pb2.ReadResponse() return # Verify from which type of device to read. switch_id = request.device_id if switch_id == 0: context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details("PvS read methods are not implemented") yield p4runtime_pb2.ReadResponse() return # Search for the requested switch. try: switch = SwitchConf.switch_dict[switch_id] except KeyError: context.set_code(grpc.StatusCode.NOT_FOUND) context.set_details( "Switch with id {} not found".format(switch_id)) yield p4runtime_pb2.ReadResponse() return # Check every entity inside the request array. # If a requested entity is not found, an empty response is sent and the connection is closed. for entity in request.entities: if entity.HasField("table_entry"): # Verify if the user has permission to read table entries from the requested switch. if ConnectionArray.verifyPermission( context, switch, PermEnum.DEVICE_READ | PermEnum.FLOWRULE_READ) is False: user_name = ConnectionArray.getUsername(context.peer()) context.set_code(grpc.StatusCode.PERMISSION_DENIED) context.set_details( "User '{}' does not have permission to read table entries from switch '{}'" .format(user_name, switch.switch_name)) yield p4runtime_pb2.ReadResponse() return (response, code, message) = RPC_mgmt.process_table_read( peer_key, username, switch, entity.table_entry) yield response if code is not grpc.StatusCode.OK: context.set_code(code) context.set_details(message) return elif entity.HasField("register_entry"): # Verify if the user has permission to read registers from the requested switch. if ConnectionArray.verifyPermission( context, switch, PermEnum.DEVICE_READ | PermEnum.RESOURCE_READ) is False: user_name = ConnectionArray.getUsername(context.peer()) context.set_code(grpc.StatusCode.PERMISSION_DENIED) context.set_details( "User '{}' does not have permission to read registers from switch '{}'" .format(user_name, switch.switch_name)) yield p4runtime_pb2.ReadResponse() return (response, code, message) = RPC_mgmt.process_register_read( switch_id, entity.register_entry) yield response if code is not grpc.StatusCode.OK: context.set_code(code) context.set_details(message) return elif entity.HasField("counter_entry"): # Verify if the user has permission to read counters from the requested switch. if ConnectionArray.verifyPermission( context, switch, PermEnum.DEVICE_READ | PermEnum.RESOURCE_READ) is False: user_name = ConnectionArray.getUsername(context.peer()) context.set_code(grpc.StatusCode.PERMISSION_DENIED) context.set_details( "User '{}' does not have permission to read counters from switch '{}'" .format(user_name, switch.switch_name)) yield p4runtime_pb2.ReadResponse() return (response, code, message) = RPC_mgmt.process_counter_read( switch_id, entity.counter_entry) yield response if code is not grpc.StatusCode.OK: context.set_code(code) context.set_details(message) return else: context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details("Unsupported entity") yield p4runtime_pb2.ReadResponse() return return