示例#1
0
    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)
示例#2
0
    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)
示例#3
0
    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)
示例#4
0
    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