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 authenticate(peer_key): global _connections _connections[peer_key].state = Connection.CLIENT_AUTHENTICATED ServerConfig.print_debug("Authenticated {} (user id {})".format( _connections[peer_key].user.user_name, _connections[peer_key].user.user_id)) return
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 main(): global dev_id host = ServerConfig.HOST server_port = ServerConfig.SERVER_PORT with open(ServerConfig.SERVER_CERTIFICATE, "rb") as file: trusted_certs = file.read() credentials = grpc.ssl_channel_credentials(root_certificates=trusted_certs) channel = grpc.secure_channel("{}:{}".format(host, server_port), credentials) client = P4RuntimeClient() streamC = client.StreamChannel() while True: try: packet = next(streamC) # we will only process packet-ins from l2 (check device id) if packet.HasField("packet") and packet.packet.metadata[ 0].metadata_id == dev_id: print "Received Packet inf from switch {}".format( packet.packet.metadata[0].metadata_id) if packet.HasField("other"): if packet.other.value == "\n\014Auth success": ServerConfig.print_debug( "Received authentication response from server:") ServerConfig.print_debug(packet) except IndexError: continue
def remove(peer_key): global _connections if peer_key in _connections: ServerConfig.print_debug( "Removed {} (user id {}) from ConnectionArray".format( _connections[peer_key].user.user_name, _connections[peer_key].user.user_id)) del _connections[peer_key] return
def add(peer_key, user_name): global _connections if peer_key not in _connections: user = Auth.getUserByName(user_name) _connections[peer_key] = Connection(user) ServerConfig.print_debug( "Added {} (user id {}) to ConnectionArray".format( _connections[peer_key].user.user_name, _connections[peer_key].user.user_id)) return
def hexify_key(table, key_list): ServerConfig.print_debug( "Calling hexify_key for switch id {}, table id {}, key list {}". format(table.switch_id, table.table_id, key_list)) fields = PXTable.extract_fields(table) field_vals = key_list ServerConfig.print_debug( "Table match fields: {}, supplied values: {}".format( fields, field_vals)) return PXTable._hexify(field_vals, fields)
def reg_write(switch_id, reg_name, index, value): if switch_id not in p4_externs_dict: ServerConfig.print_debug( "Failed reading register: switch id {} not found in p4_externs_dict" .format(switch_id)) return False address = get_address(switch_id, reg_name, index) return libsume.regwrite(address, value) if address != False else False
def table_cam_add_entry(switch, table, action, keys, action_data): ServerConfig.print_debug("Processing table_cam_add_entry: switch {}(id {}), table {}(id {}), keys {}, action {}(id {}), action_data {}".format(switch.switch_name, switch.switch_id, table.table_name, table.table_id, keys, action.action_name, action.action_id, action_data)) # TODO: change this return value. if not check_valid_cam_table_name(table): return ("NA", "NA") key = PXTable.hexify_key(table, keys) value = PXTable.hexify_value(table, action, action_data) ServerConfig.print_debug("table_cam_add_entry: table id {}, key {:X}, value {:X}".format(table.table_id, key, value)) rc = libcam_dict[switch.switch_id].cam_add_entry(table.table_id, "{:X}".format(key), "{:X}".format(value)) print libcam_dict[switch.switch_id].cam_error_decode(rc)
def table_cam_get_size(switch_id, table_name): ServerConfig.print_debug("Processing table_cam_get_size for switch id {} and table name {}".format(switch_id, table_name)) switch_table = SwitchConf.getSwitchTableByName(switch_id, table_name) if switch_table is False: return "NA", "NA" if not check_valid_cam_table_name(switch_table.switch_id, switch_table.table_id): return 0 return libcam_dict[switch_table.switch_id].cam_get_size(switch_table.table_id)
def table_lpm_verify_dataset(switch_id, table_name, filename): ServerConfig.print_debug("Processing table_lpm_verify_dataset for switch id {} and table name {}".format(switch_id, table_name)) switch_table = SwitchConf.getSwitchTableByName(switch_id, table_name) if switch_table is False: return "NA", "NA" if not check_valid_lpm_table_name(switch_table.switch_id, switch_table.table_id): return return liblpm_dict[switch_table.switch_id].lpm_verify_dataset(switch_table.table_id, filename)
def hexify_value(table, action, action_data): ServerConfig.print_debug( "Calling hexify_value for switch id {}, table id {}, action {}, data {}" .format(table.switch_id, table.table_id, action.action_name, action_data)) fields = PXTable.extract_action_fields(action) field_vals = [action.action_id] + action_data ServerConfig.print_debug( "Table action fields: {}, supplied values: {}".format( fields, field_vals)) return PXTable._hexify(field_vals, fields)
def table_lpm_set_active_lookup_bank(switch_id, table_name, bank): ServerConfig.print_debug("Processing table_lpm_set_active_lookup_bank for switch id {} and table name {}".format(switch_id, table_name)) switch_table = SwitchConf.getSwitchTableByName(switch_id, table_name) if switch_table is False: return "NA", "NA" if not check_valid_lpm_table_name(switch_table.switch_id, switch_table.table_id): return rc = liblpm_dict[switch_table.switch_id].lpm_set_active_lookup_bank(switch_table.table_id, bank) ServerConfig.print_debug(liblpm_dict[switch_table.switch_id].lpm_error_decode(rc))
def table_tcam_erase_entry(switch_id, table_name, addr): ServerConfig.print_debug("Processing table_tcam_erase_entry for switch id {} and table name {}".format(switch_id, table_name)) switch_table = SwitchConf.getSwitchTableByName(switch_id, table_name) if switch_table is False: return "NA", "NA" if not check_valid_tcam_table_name(switch_table.switch_id, switch_table.table_id): return rc = libtcam_dict[switch_table.switch_id].tcam_erase_entry(switch_table.table_id, addr) ServerConfig.print_debug(libtcam_dict[switch_table.switch_id].tcam_error_decode(rc))
def table_tcam_verify_entry(switch_id, table_name, addr, keys, masks, action_name, action_data): ServerConfig.print_debug("Processing table_tcam_verify_entry for switch id {} and table name {}".format(switch_id, table_name)) switch_table = SwitchConf.getSwitchTableByName(switch_id, table_name) if switch_table is False: return "NA", "NA" if not check_valid_tcam_table_name(switch_table.switch_id, switch_table.table_id): return mask = PXTable.hexify_mask(switch_table.switch_id, switch_table.table_id, masks) key = PXTable.hexify_key(switch_table.switch_id, switch_table.table_id, keys) value = PXTable.hexify_value(switch_table.switch_id, switch_table.table_id, action_name, action_data) return libtcam_dict[switch_table.switch_id].tcam_verify_entry(switch_table.table_id, addr, "{:X}".format(key), "{:X}".format(mask), "{:X}".format(value))
def WriteTableEntry(self, update_type, table, match_key, action_data): global dev_id request = p4runtime_pb2.WriteRequest() request.device_id = dev_id request.election_id.low = 1 update = request.updates.add() update.type = update_type update.entity.table_entry.table_id = table update.entity.table_entry.is_default_action = 1 update.entity.table_entry.action.action.action_id = 1 matches = update.entity.table_entry.match.add() matches.field_id = 1 matches.exact.value = bytes(match_key) act = update.entity.table_entry.action.action.params.add() act.param_id = 2 act.value = bytes(action_data) ServerConfig.print_debug("Sending table write request to server:") ServerConfig.print_debug(request) try: self.stub.Write(request) except grpc.RpcError as error: ServerConfig.print_debug("An error ocurred during a 'write' execution!") ServerConfig.print_debug("{}: {}".format(error.code().name, error.details())) return
def table_cam_delete_entry(switch_id, table_name, keys): ServerConfig.print_debug("Processing table_cam_delete_entry: switch_id {}, table {}, keys {}".format(switch_id, table_name, keys)) switch_table = SwitchConf.getSwitchTableByName(switch_id, table_name) if switch_table is False: return "NA", "NA" if not check_valid_cam_table_name(switch_table.switch_id, switch_table.table_id): return key = PXTable.hexify_key(switch_table.switch_id, switch_table.table_id, keys) ServerConfig.print_debug("table_cam_delete_entry: switch_table.table_id {}, key {:X}".format (switch_table.table_id, key)) rc = libcam_dict[switch_table.switch_id].cam_delete_entry(switch_table.table_id, "{:X}".format(key)) print libcam_dict[switch_table.switch_id].cam_error_decode(rc)
def process_write_request(self, request, context): peer_key = context.peer() username = ConnectionArray.getUsername(peer_key) ServerConfig.print_debug( "Received write request from peer {}({}):".format( peer_key, username)) ServerLog.print_log("Received write request (%s): %.9f" % (username, time.time())) response = request # Verify if the user is authenticated. if ConnectionArray.isAuthenticated(peer_key) is False: context.set_code(grpc.StatusCode.UNAUTHENTICATED) context.set_details( "User {} is not authenticated".format(username)) return response # Get the switch object from memory. switch = SwitchConf.getSwitchById(request.device_id) if switch == False: context.set_code(grpc.StatusCode.NOT_FOUND) context.set_details( "Switch with id {} not found".format(switch_id)) return response # Verify permissions for request_update in request.updates: if request_update.entity.HasField("table_entry"): # Verify if the user has permission to write table entries into the requested switch. if ConnectionArray.verifyPermission( context, switch, PermEnum.DEVICE_WRITE | PermEnum.FLOWRULE_WRITE) is False: context.set_code(grpc.StatusCode.PERMISSION_DENIED) context.set_details( "User {} does not have permission to write table entries into switch {}" .format(username, switch.switch_name)) return response if switch.switch_type == SwitchTypeEnum.TYPE_BMV2: response = RPC_mgmt.process_write_request_bmv2(request) elif switch.switch_type == SwitchTypeEnum.TYPE_PVS: response = RPC_mgmt.process_write_request_pvs(request) ServerLog.print_log("Write Request success (%s): %.9f" % (username, time.time())) return response
def table_cam_read_entry(switch, table, keys): ServerConfig.print_debug("Processing table_cam_read_entry: switch {}(id {}), table {}(id {}), keys {}".format(switch.switch_name, switch.switch_id, table.table_name, table.table_id, keys)) # TODO: change this return value. if not check_valid_cam_table_name(table): return ("NA", "NA") key = PXTable.hexify_key(table, keys) hex_key_buf = create_string_buffer("{:X}".format(key)) value = create_string_buffer(1024) # TODO: Fix this ... Must be large enough to hold entire value found = create_string_buffer(10) # Should only need to hold "True" or "False" ServerConfig.print_debug("table_cam_read_entry: table id {}, key {}, key_hex_buf {}".format(table.table_id, key, hex_key_buf)) rc = libcam_dict[switch.switch_id].cam_read_entry(table.table_id, hex_key_buf, value, found) print libcam_dict[switch.switch_id].cam_error_decode(rc) return (found.value, value.value)
def reg_read(switch_id, reg_name, index): if switch_id not in p4_externs_dict: ServerConfig.print_debug( "Failed reading register: switch id {} not found in p4_externs_dict" .format(switch_id)) return False # print "REGISTERS FROM SWITCH ID {}: {}\n".format(switch_id, p4_externs_dict[switch_id].keys()) # print "KEYS FROM '{}' REGISTER: {}\n".format(reg_name, p4_externs_dict[switch_id][reg_name].keys()) # print "CONTROL WIDTH FOR REGISTER '{}': {}\n".format(reg_name, p4_externs_dict[switch_id][reg_name]["control_width"]) address = get_address(switch_id, reg_name, index) # print "READ ADDRESS: {}\n".format(address) return libsume.regread(address) if address != False else False
def main(): config = ServerConfig() if config.mode == "server": with open(config.users, "r") as f: data = [item.strip().split("\t") for item in f.readlines()] print(data) FTPServer(config).run() pass elif config.mode == "tests": do_tests(config)
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 get_address(switch_id, reg_name, index): # cond = reg_name not in p4_externs_dict[switch_id].keys() or "control_width" not in p4_externs_dict[switch_id][reg_name].keys() or p4_externs_dict[switch_id][reg_name]["control_width"] < 0 if reg_name not in p4_externs_dict[switch_id].keys(): ServerConfig.print_debug( "Failed getting register read address: register {} not found". format(reg_name)) return False if "control_width" not in p4_externs_dict[switch_id][reg_name].keys(): ServerConfig.print_debug( "Failed getting register read address: register {} does not have 'control_width' field" .format(reg_name)) return False if p4_externs_dict[switch_id][reg_name]["control_width"] < 0: ServerConfig.print_debug( "Failed getting register read address: register {} has negative 'control_width' field" .format(reg_name)) return False # This is handled differently from the original API. if "base_addr" not in p4_externs_dict[switch_id][reg_name].keys(): ServerConfig.print_debug( "Failed getting register read address: register {} does not have 'base_addr' field" .format(reg_name)) return False addressable_depth = 2**p4_externs_dict[switch_id][reg_name][ "control_width"] if index >= addressable_depth or index < 0: ServerConfig.print_debug( "Failed getting register read address: index {}[{}] out of bounds". format(reg_name, index)) return False return p4_externs_dict[switch_id][reg_name]["base_addr"] + index
def process_setPipe(request, context): ServerConfig.print_debug( "Method process_setPipe called from client...") switch_id = request.device_id switch = SwitchConf.getSwitchById(switch_id) if switch is False: ServerConfig.print_debug( "Switch with id {} not found".format(switch_id)) return code_pb2.NOT_FOUND global p4_cookie response = request p4_cookie = response.config.cookie response.device_id = request.device_id response.role_id = request.role_id p4info = None p4_device_config = None config = p4runtime_pb2.ForwardingPipelineConfig() if p4info: config.p4info.CopyFrom(p4info) if p4_device_config: config.p4_device_config = p4_device_config.SerializeToString() response.action = p4runtime_pb2.SetForwardingPipelineConfigRequest.VERIFY_AND_COMMIT return p4runtime_pb2.SetForwardingPipelineConfigResponse()
def WriteRegisterEntry(self, register_id, index, value): global dev_id request = p4runtime_pb2.WriteRequest() request.device_id = dev_id request.election_id.low = 1 update = request.updates.add() update.type = p4runtime_pb2.Update.MODIFY update.entity.register_entry.register_id = register_id update.entity.register_entry.index.index = index update.entity.register_entry.data.enum_value = bytes(value) ServerConfig.print_debug("Sending register write request to server:") ServerConfig.print_debug(request) try: self.stub.Write(request) except grpc.RpcError as error: ServerConfig.print_debug("An error ocurred during a 'write' execution!") ServerConfig.print_debug("{}: {}\n".format(error.code().name, error.details())) return
def recv_packet(self, pktlen, packet_data, timestamp): switch_id = ord(packet_data[0]) input_port = ord(packet_data[1]) payload = packet_data[2:] switch = SwitchConf.getSwitchById(switch_id) if switch is not False: ServerConfig.print_debug("Packet {} ----------".format(self.packet_count)) ServerConfig.print_debug("Packet-in arrived at {} from Switch {} (Switch ID = {})".format(timestamp, switch.switch_name, str(switch.switch_id))) ServerConfig.print_debug("Preparing to send to the control plane, switch id {}, input port {}".format(switch_id, input_port)) # print "Raw Data: {}".format(hexlify(payload)) # we need to do it quickly # else: # print "Error retrieving Switch ID {}".format(switch_id) self.output [0] = switch_id self.output [1] = struct.pack("Q", input_port) self.output [2] = payload self.packet_count += 1
def recv_packet(self, pktlen, packet_data, timestamp): packet_ok = True switch_id = ord(packet_data[0]) input_port = ord(packet_data[1]) payload = packet_data[2:] #payload = packet_data[0:] #switch_id = ord(packet_data[-3]) #input_port = ord(packet_data[-1]) switch = SwitchConf.getSwitchById(switch_id) if switch is not False: ServerConfig.print_debug("Packet {} ----------".format( self.packet_count)) ServerConfig.print_debug( "Packet-in arrived at {} from Switch {} (Switch ID = {})". format(timestamp, switch.switch_name, str(switch.switch_id))) ServerConfig.print_debug( "Preparing to send to the control plane, switch id {}, input port {}" .format(switch_id, input_port)) else: print "ID %d - No found" % switch_id packet_ok = False if input_port != 1: print "Invalid Input Port: %d" % input_port packet_ok = False self.output[0] = switch_id self.output[1] = struct.pack("h", input_port) self.output[2] = payload if packet_ok: self.packet_count += 1 else: self.output[0] = -1
def ReadTableEntry(self, table, match_key): global dev_id request = p4runtime_pb2.ReadRequest() request.device_id = dev_id entity = request.entities.add() entity.table_entry.table_id = table matches = entity.table_entry.match.add() matches.field_id = 1 matches.exact.value = bytes(match_key) ServerConfig.print_debug("Sending table read request to server:") ServerConfig.print_debug(request) try: for response in self.stub.Read(request): ServerConfig.print_debug("Table read response received from server:") ServerConfig.print_debug(response) except grpc.RpcError as error: ServerConfig.print_debug("An error occured during a 'read' execution!") ServerConfig.print_debug("{}: {}\n".format(error.code().name, error.details())) return
def main(): host = ServerConfig.HOST server_port = ServerConfig.SERVER_PORT with open(ServerConfig.SERVER_CERTIFICATE, "rb") as file: trusted_certs = file.read() credentials = grpc.ssl_channel_credentials(root_certificates=trusted_certs) channel = grpc.secure_channel("{}:{}".format(host, server_port), credentials) client = P4RuntimeClient() streamC = client.StreamChannel() tables_initialized = False while True: try: packet = next(streamC) if packet.HasField("packet") and packet.packet.metadata[0].metadata_id == dev_id: ServerConfig.print_debug("Received packet:") ServerConfig.print_debug("Payload: {}".format(hexlify(packet.packet.payload))) ServerConfig.print_debug("Switch id: {}".format(packet.packet.metadata[0].metadata_id)) ServerConfig.print_debug("Input port: {}\n".format(hexlify(packet.packet.metadata[0].value))) if packet.HasField("other"): if packet.other.value == "\n\014Auth success": ServerConfig.print_debug("Received authentication response from server:") ServerConfig.print_debug(packet) # Prepare an arbitration request. client.streamChannelRequest = p4runtime_pb2.StreamMessageRequest() client.streamChannelRequest.arbitration.device_id = 1 client.streamChannelRequest.arbitration.role.id = 1 client.sendRequest = True if packet.HasField("arbitration"): ServerConfig.print_debug("Received arbitration response from server:") ServerConfig.print_debug(packet) if tables_initialized is False: for mac in forward_table_dict: client.WriteTableEntry(p4runtime_pb2.Update.INSERT, FORWARD, mac, forward_table_dict[mac]) # client.ReadTableEntry(FORWARD, mac) tables_initialized = True while True: client.ReadRegisterEntry(2, 0) client.WriteRegisterEntry(2, 0, 10) client.ReadRegisterEntry(2, 0) sleep(2) except IndexError: continue
def ReadCounterEntry(self, counter_id, index): global dev_id request = p4runtime_pb2.ReadRequest() request.device_id = dev_id entity = request.entities.add() entity.counter_entry.counter_id = counter_id entity.counter_entry.index.index = index ServerConfig.print_debug("Sending counter read request to server:") ServerConfig.print_debug(request) try: for response in self.stub.Read(request): ServerConfig.print_debug("Read counter response received from server:") ServerConfig.print_debug(response) except grpc.RpcError as error: ServerConfig.print_debug("An error occured during a 'read' execution!") ServerConfig.print_debug("{}: {}\n".format(error.code().name, error.details())) return
from __future__ import print_function from threading import Thread from json_socket import JSONSocket, NoMessageAvailable, ConnectionLost from data_model import AbstractTweet, GenericTweet, dbConnect, genericSize from socket import error as SocketError from config import ServerConfig import time import json import operator import sys import signal import errno import getopt CONFIG = ServerConfig.fromArgs(sys.argv[1:]) print('loaded config:') print(CONFIG) def verbosePrint(*args, **kwargs): if CONFIG.verbose: print(*args, **kwargs) def split_coordinates(coordinates): longitudeDelta = coordinates[2] - coordinates[0] latitudeDelta = coordinates[3] - coordinates[1] if longitudeDelta >= latitudeDelta: mid = coordinates[0] + longitudeDelta / 2.0 return (coordinates[0:2] + [ mid, coordinates[3] ], [ mid ] + coordinates[1:])