Java源码示例:org.onosproject.net.pi.runtime.PiTableAction

示例1
/**
 * Creates a routing flow rule that matches on the given IPv6 prefix and
 * executes the given group ID (created before).
 *
 * @param deviceId  the device where flow rule will be installed
 * @param ip6Prefix the IPv6 prefix
 * @param groupId   the group ID
 * @return a flow rule
 */
private FlowRule createRoutingRule(DeviceId deviceId, Ip6Prefix ip6Prefix,
                                   int groupId) {

    final String tableId = "IngressPipeImpl.routing_v6_table";
    final PiCriterion match = PiCriterion.builder()
            .matchLpm(
                    PiMatchFieldId.of("hdr.ipv6.dst_addr"),
                    ip6Prefix.address().toOctets(),
                    ip6Prefix.prefixLength())
            .build();

    final PiTableAction action = PiActionProfileGroupId.of(groupId);

    return Utils.buildFlowRule(
            deviceId, appId, tableId, match, action);
}
 
示例2
/**
 * Creates a routing flow rule that matches on the given IPv6 prefix and
 * executes the given group ID (created before).
 *
 * @param deviceId  the device where flow rule will be installed
 * @param ip6Prefix the IPv6 prefix
 * @param groupId   the group ID
 * @return a flow rule
 */
private FlowRule createRoutingRule(DeviceId deviceId, Ip6Prefix ip6Prefix,
                                   int groupId) {

    // TODO EXERCISE 3
    // Modify P4Runtime entity names to match content of P4Info file (look
    // for the fully qualified name of tables, match fields, and actions.
    // ---- START SOLUTION ----
    final String tableId = "IngressPipeImpl.l3_table";
    final PiCriterion match = PiCriterion.builder()
            .matchLpm(
                    PiMatchFieldId.of("hdr.ipv6.dst_addr"),
                    ip6Prefix.address().toOctets(),
                    ip6Prefix.prefixLength())
            .build();

    final PiTableAction action = PiActionProfileGroupId.of(groupId);
    // ---- END SOLUTION ----

    return Utils.buildFlowRule(
            deviceId, appId, tableId, match, action);
}
 
示例3
/**
 * Creates a routing flow rule that matches on the given IPv6 prefix and
 * executes the given group ID (created before).
 *
 * @param deviceId  the device where flow rule will be installed
 * @param ip6Prefix the IPv6 prefix
 * @param groupId   the group ID
 * @return a flow rule
 */
private FlowRule createRoutingRule(DeviceId deviceId, Ip6Prefix ip6Prefix,
                                   int groupId) {

    // TODO EXERCISE 3
    // Modify P4Runtime entity names to match content of P4Info file (look
    // for the fully qualified name of tables, match fields, and actions.
    // ---- START SOLUTION ----
    final String tableId = "MODIFY ME";
    final PiCriterion match = PiCriterion.builder()
            .matchLpm(
                    PiMatchFieldId.of("MODIFY ME"),
                    ip6Prefix.address().toOctets(),
                    ip6Prefix.prefixLength())
            .build();

    final PiTableAction action = PiActionProfileGroupId.of(groupId);
    // ---- END SOLUTION ----

    return Utils.buildFlowRule(
            deviceId, appId, tableId, match, action);
}
 
示例4
private PiTableAction decodeTableActionMsg(
        P4RuntimeOuterClass.TableAction tableActionMsg, PiPipeconf pipeconf)
        throws CodecException {
    P4RuntimeOuterClass.TableAction.TypeCase typeCase = tableActionMsg.getTypeCase();
    switch (typeCase) {
        case ACTION:
            P4RuntimeOuterClass.Action actionMsg = tableActionMsg.getAction();
            return CODECS.action().decode(
                    actionMsg, null, pipeconf);
        case ACTION_PROFILE_GROUP_ID:
            return PiActionProfileGroupId.of(
                    tableActionMsg.getActionProfileGroupId());
        case ACTION_PROFILE_MEMBER_ID:
            return PiActionProfileMemberId.of(
                    tableActionMsg.getActionProfileMemberId());
        default:
            throw new CodecException(
                    format("Decoding of table action type %s not implemented",
                           typeCase.name()));
    }
}
 
示例5
/**
 * Tests the encoding of protocol-independent instructions.
 */
@Test
public void piInstructionEncodingTest() {
    PiActionId actionId = PiActionId.of("set_egress_port");
    PiActionParamId actionParamId = PiActionParamId.of("port");
    PiActionParam actionParam = new PiActionParam(actionParamId, ImmutableByteSequence.copyFrom(10));
    PiTableAction action = PiAction.builder().withId(actionId).withParameter(actionParam).build();
    final PiInstruction actionInstruction = Instructions.piTableAction(action);
    final ObjectNode actionInstructionJson =
            instructionCodec.encode(actionInstruction, context);
    assertThat(actionInstructionJson, matchesInstruction(actionInstruction));

    PiTableAction actionGroupId = PiActionProfileGroupId.of(10);
    final PiInstruction actionGroupIdInstruction = Instructions.piTableAction(actionGroupId);
    final ObjectNode actionGroupIdInstructionJson =
            instructionCodec.encode(actionGroupIdInstruction, context);
    assertThat(actionGroupIdInstructionJson, matchesInstruction(actionGroupIdInstruction));

    PiTableAction actionProfileMemberId = PiActionProfileMemberId.of(10);
    final PiInstruction actionProfileMemberIdInstruction = Instructions.piTableAction(actionProfileMemberId);
    final ObjectNode actionProfileMemberIdInstructionJson =
            instructionCodec.encode(actionProfileMemberIdInstruction, context);
    assertThat(actionProfileMemberIdInstructionJson, matchesInstruction(actionProfileMemberIdInstruction));
}
 
示例6
/**
 * Sets up the "My Station" table for the given device using the
 * myStationMac address found in the config.
 * <p>
 * This method will be called at component activation for each device
 * (switch) known by ONOS, and every time a new device-added event is
 * captured by the InternalDeviceListener defined below.
 *
 * @param deviceId the device ID
 */
private void setUpMyStationTable(DeviceId deviceId) {

    log.info("Adding My Station rules to {}...", deviceId);

    final MacAddress myStationMac = getMyStationMac(deviceId);

    // HINT: in the p4 program, the My Station table matches on the
    // *ethernet destination* and there is only one action called
    // *NoAction*, which is used as an indication of "table hit" in the
    // control block.

    final String tableId = "IngressPipeImpl.my_station_table";

    final PiCriterion match = PiCriterion.builder()
            .matchExact(
                    PiMatchFieldId.of("hdr.ethernet.dst_addr"),
                    myStationMac.toBytes())
            .build();

    // Creates an action which do *NoAction* when hit.
    final PiTableAction action = PiAction.builder()
            .withId(PiActionId.of("NoAction"))
            .build();

    final FlowRule myStationRule = Utils.buildFlowRule(
            deviceId, appId, tableId, match, action);

    flowRuleService.applyFlowRules(myStationRule);
}
 
示例7
public static FlowRule buildFlowRule(DeviceId switchId, ApplicationId appId,
                                     String tableId, PiCriterion piCriterion,
                                     PiTableAction piAction) {
    return DefaultFlowRule.builder()
            .forDevice(switchId)
            .forTable(PiTableId.of(tableId))
            .fromApp(appId)
            .withPriority(DEFAULT_FLOW_RULE_PRIORITY)
            .makePermanent()
            .withSelector(DefaultTrafficSelector.builder()
                                  .matchPi(piCriterion).build())
            .withTreatment(DefaultTrafficTreatment.builder()
                                   .piTableAction(piAction).build())
            .build();
}
 
示例8
/**
 * Sets up the "My Station" table for the given device using the
 * myStationMac address found in the config.
 * <p>
 * This method will be called at component activation for each device
 * (switch) known by ONOS, and every time a new device-added event is
 * captured by the InternalDeviceListener defined below.
 *
 * @param deviceId the device ID
 */
private void setUpMyStationTable(DeviceId deviceId) {

    log.info("Adding My Station rules to {}...", deviceId);

    final MacAddress myStationMac = getMyStationMac(deviceId);

    // HINT: in our solution, the My Station table matches on the *ethernet
    // destination* and there is only one action called *NoAction*, which is
    // used as an indication of "table hit" in the control block.

    // TODO EXERCISE 3
    // Modify P4Runtime entity names to match content of P4Info file (look
    // for the fully qualified name of tables, match fields, and actions.
    // ---- START SOLUTION ----
    final String tableId = "IngressPipeImpl.l2_my_station";

    final PiCriterion match = PiCriterion.builder()
            .matchExact(
                    PiMatchFieldId.of("hdr.ethernet.dst_addr"),
                    myStationMac.toBytes())
            .build();

    // Creates an action which do *NoAction* when hit.
    final PiTableAction action = PiAction.builder()
            .withId(PiActionId.of("NoAction"))
            .build();
    // ---- END SOLUTION ----

    final FlowRule myStationRule = Utils.buildFlowRule(
            deviceId, appId, tableId, match, action);

    flowRuleService.applyFlowRules(myStationRule);
}
 
示例9
public static FlowRule buildFlowRule(DeviceId switchId, ApplicationId appId,
                                     String tableId, PiCriterion piCriterion,
                                     PiTableAction piAction) {
    return DefaultFlowRule.builder()
            .forDevice(switchId)
            .forTable(PiTableId.of(tableId))
            .fromApp(appId)
            .withPriority(DEFAULT_FLOW_RULE_PRIORITY)
            .makePermanent()
            .withSelector(DefaultTrafficSelector.builder()
                                  .matchPi(piCriterion).build())
            .withTreatment(DefaultTrafficTreatment.builder()
                                   .piTableAction(piAction).build())
            .build();
}
 
示例10
/**
 * Populate the My SID table from the network configuration for the
 * specified device.
 *
 * @param deviceId the device Id
 */
private void setUpMySidTable(DeviceId deviceId) {

    Ip6Address mySid = getMySid(deviceId);

    log.info("Adding mySid rule on {} (sid {})...", deviceId, mySid);

    // TODO EXERCISE 4
    // Fill in the table ID for the SRv6 my segment identifier table
    // ---- START SOLUTION ----
    String tableId = "IngressPipeImpl.srv6_my_sid";
    // ---- END SOLUTION ----

    // TODO EXERCISE 4
    // Modify the field and action id to match your P4Info
    // ---- START SOLUTION ----
    PiCriterion match = PiCriterion.builder()
            .matchLpm(
                    PiMatchFieldId.of("hdr.ipv6.dst_addr"),
                    mySid.toOctets(), 128)
            .build();

    PiTableAction action = PiAction.builder()
            .withId(PiActionId.of("IngressPipeImpl.srv6_end"))
            .build();
    // ---- END SOLUTION ----

    FlowRule myStationRule = Utils.buildFlowRule(
            deviceId, appId, tableId, match, action);

    flowRuleService.applyFlowRules(myStationRule);
}
 
示例11
/**
 * Sets up the "My Station" table for the given device using the
 * myStationMac address found in the config.
 * <p>
 * This method will be called at component activation for each device
 * (switch) known by ONOS, and every time a new device-added event is
 * captured by the InternalDeviceListener defined below.
 *
 * @param deviceId the device ID
 */
private void setUpMyStationTable(DeviceId deviceId) {

    log.info("Adding My Station rules to {}...", deviceId);

    final MacAddress myStationMac = getMyStationMac(deviceId);

    // HINT: in our solution, the My Station table matches on the *ethernet
    // destination* and there is only one action called *NoAction*, which is
    // used as an indication of "table hit" in the control block.

    // TODO EXERCISE 3
    // Modify P4Runtime entity names to match content of P4Info file (look
    // for the fully qualified name of tables, match fields, and actions.
    // ---- START SOLUTION ----
    final String tableId = "MODIFY ME";

    final PiCriterion match = PiCriterion.builder()
            .matchExact(
                    PiMatchFieldId.of("MODIFY ME"),
                    myStationMac.toBytes())
            .build();

    // Creates an action which do *NoAction* when hit.
    final PiTableAction action = PiAction.builder()
            .withId(PiActionId.of("MODIFY ME"))
            .build();
    // ---- END SOLUTION ----

    final FlowRule myStationRule = Utils.buildFlowRule(
            deviceId, appId, tableId, match, action);

    flowRuleService.applyFlowRules(myStationRule);
}
 
示例12
public static FlowRule buildFlowRule(DeviceId switchId, ApplicationId appId,
                                     String tableId, PiCriterion piCriterion,
                                     PiTableAction piAction) {
    return DefaultFlowRule.builder()
            .forDevice(switchId)
            .forTable(PiTableId.of(tableId))
            .fromApp(appId)
            .withPriority(DEFAULT_FLOW_RULE_PRIORITY)
            .makePermanent()
            .withSelector(DefaultTrafficSelector.builder()
                                  .matchPi(piCriterion).build())
            .withTreatment(DefaultTrafficTreatment.builder()
                                   .piTableAction(piAction).build())
            .build();
}
 
示例13
/**
 * Populate the My SID table from the network configuration for the
 * specified device.
 *
 * @param deviceId the device Id
 */
private void setUpMySidTable(DeviceId deviceId) {

    Ip6Address mySid = getMySid(deviceId);

    log.info("Adding mySid rule on {} (sid {})...", deviceId, mySid);

    // TODO EXERCISE 4
    // Fill in the table ID for the SRv6 my segment identifier table
    // ---- START SOLUTION ----
    String tableId = "MODIFY ME";
    // ---- END SOLUTION ----

    // TODO EXERCISE 4
    // Modify the field and action id to match your P4Info
    // ---- START SOLUTION ----
    PiCriterion match = PiCriterion.builder()
            .matchLpm(
                    PiMatchFieldId.of("MODIFY ME"),
                    mySid.toOctets(), 128)
            .build();

    PiTableAction action = PiAction.builder()
            .withId(PiActionId.of("MODIFY ME"))
            .build();
    // ---- END SOLUTION ----

    FlowRule myStationRule = Utils.buildFlowRule(
            deviceId, appId, tableId, match, action);

    flowRuleService.applyFlowRules(myStationRule);
}
 
示例14
private P4RuntimeOuterClass.TableAction encodePiTableAction(
        PiTableAction piTableAction, PiPipeconf pipeconf)
        throws CodecException {
    checkNotNull(piTableAction, "Cannot encode null PiTableAction");
    final P4RuntimeOuterClass.TableAction.Builder tableActionMsgBuilder =
            P4RuntimeOuterClass.TableAction.newBuilder();
    switch (piTableAction.type()) {
        case ACTION:
            P4RuntimeOuterClass.Action theAction = CODECS.action()
                    .encode((PiAction) piTableAction, null, pipeconf);
            tableActionMsgBuilder.setAction(theAction);
            break;
        case ACTION_PROFILE_GROUP_ID:
            tableActionMsgBuilder.setActionProfileGroupId(
                    ((PiActionProfileGroupId) piTableAction).id());
            break;
        case ACTION_PROFILE_MEMBER_ID:
            tableActionMsgBuilder.setActionProfileMemberId(
                    ((PiActionProfileMemberId) piTableAction).id());
            break;
        default:
            throw new CodecException(
                    format("Building of table action type %s not implemented",
                           piTableAction.type()));
    }
    return tableActionMsgBuilder.build();
}
 
示例15
/**
 * Builds a PI action out of the given treatment, optionally using the given
 * interpreter.
 */
private static PiTableAction buildAction(TrafficTreatment treatment, PiPipelineInterpreter interpreter,
                                         PiTableId tableId)
        throws PiTranslationException {

    PiTableAction piTableAction = null;

    // If treatment has only one instruction of type PiInstruction, use that.
    for (Instruction inst : treatment.allInstructions()) {
        if (inst.type() == Instruction.Type.PROTOCOL_INDEPENDENT) {
            if (treatment.allInstructions().size() == 1) {
                piTableAction = ((PiInstruction) inst).action();
            } else {
                throw new PiTranslationException(format(
                        "Unable to translate treatment, found multiple instructions " +
                                "of which one is protocol-independent: %s", treatment));
            }
        }
    }

    if (piTableAction == null && interpreter != null) {
        // No PiInstruction, use interpreter to build action.
        try {
            piTableAction = interpreter.mapTreatment(treatment, tableId);
        } catch (PiPipelineInterpreter.PiInterpreterException e) {
            throw new PiTranslationException(
                    "Interpreter was unable to translate treatment. " + e.getMessage());
        }
    }

    return piTableAction;
}
 
示例16
private static PiTableAction typeCheckAction(PiTableAction piTableAction, PiTableModel table)
        throws PiTranslationException {
    if (piTableAction == null) {
        // skip check if null
        return null;
    }
    switch (piTableAction.type()) {
        case ACTION:
            return checkPiAction((PiAction) piTableAction, table);
        case ACTION_PROFILE_GROUP_ID:
        case ACTION_PROFILE_MEMBER_ID:
            if (!table.tableType().equals(PiTableType.INDIRECT)) {
                throw new PiTranslationException(format(
                        "action is indirect of type '%s', but table '%s' is of type '%s'",
                        piTableAction.type(), table.id(), table.tableType()));
            }
            if (piTableAction.type().equals(PiTableAction.Type.ACTION_PROFILE_GROUP_ID)
                    && (table.actionProfile() == null || !table.actionProfile().hasSelector())) {
                throw new PiTranslationException(format(
                        "action is of type '%s', but table '%s' does not" +
                                "implement an action profile with dynamic selection",
                        piTableAction.type(), table.id()));
            }
            return piTableAction;
        default:
            throw new PiTranslationException(format(
                    "Unknown table action type %s", piTableAction.type()));

    }
}
 
示例17
private static PiTableAction checkPiAction(PiAction piAction, PiTableModel table)
        throws PiTranslationException {
    // Table supports this action?
    PiActionModel actionModel = table.action(piAction.id()).orElseThrow(
            () -> new PiTranslationException(format("Not such action '%s' for table '%s'",
                                                    piAction.id(), table.id())));

    // Is the number of runtime parameters correct?
    if (actionModel.params().size() != piAction.parameters().size()) {
        throw new PiTranslationException(format(
                "Wrong number of runtime parameters for action '%s', expected %d but found %d",
                actionModel.id(), actionModel.params().size(), piAction.parameters().size()));
    }

    // Forge a new action instance with well-sized parameters.
    // The same comment as in typeCheckFieldMatch() about duplicating field match instances applies here.
    PiAction.Builder newActionBuilder = PiAction.builder().withId(piAction.id());
    for (PiActionParam param : piAction.parameters()) {
        PiActionParamModel paramModel = actionModel.param(param.id())
                .orElseThrow(() -> new PiTranslationException(format(
                        "Not such parameter '%s' for action '%s'", param.id(), actionModel)));
        try {
            newActionBuilder.withParameter(new PiActionParam(param.id(),
                                                             param.value().fit(paramModel.bitWidth())));
        } catch (ByteSequenceTrimException e) {
            throw new PiTranslationException(format(
                    "Size mismatch for parameter '%s' of action '%s': %s",
                    param.id(), piAction.id(), e.getMessage()));
        }
    }

    return newActionBuilder.build();
}
 
示例18
private static GroupBucket selectOutputBucket(int portNum) {
    ImmutableByteSequence paramVal = copyFrom(portNum);
    PiActionParam param = new PiActionParam(PORT, paramVal);
    PiTableAction action = PiAction.builder()
            .withId(INGRESS_WCMP_CONTROL_SET_EGRESS_PORT)
            .withParameter(param).build();
    TrafficTreatment treatment = DefaultTrafficTreatment.builder()
            .add(Instructions.piTableAction(action))
            .build();
    return DefaultGroupBucket.createSelectGroupBucket(treatment);
}
 
示例19
/**
 * Tests the decoding of protocol-independent instructions.
 */
@Test
public void piInstructionDecodingTest() throws IOException {

    Instruction actionInstruction = getInstruction("PiActionInstruction.json");
    Assert.assertThat(actionInstruction.type(), is(Instruction.Type.PROTOCOL_INDEPENDENT));
    PiTableAction action = ((PiInstruction) actionInstruction).action();
    Assert.assertThat(action.type(), is(PiTableAction.Type.ACTION));
    Assert.assertThat(((PiAction) action).id().id(), is("set_egress_port"));
    Assert.assertThat(((PiAction) action).parameters().size(), is(1));
    Collection<PiActionParam> actionParams = ((PiAction) action).parameters();
    PiActionParam actionParam = actionParams.iterator().next();
    Assert.assertThat(actionParam.id().id(), is("port"));
    Assert.assertThat(actionParam.value(), is(copyFrom((byte) 0x1)));

    Instruction actionGroupIdInstruction = getInstruction("PiActionProfileGroupIdInstruction.json");
    Assert.assertThat(actionInstruction.type(), is(Instruction.Type.PROTOCOL_INDEPENDENT));
    PiTableAction actionGroupId = ((PiInstruction) actionGroupIdInstruction).action();
    Assert.assertThat(actionGroupId.type(), is(PiTableAction.Type.ACTION_PROFILE_GROUP_ID));
    Assert.assertThat(((PiActionProfileGroupId) actionGroupId).id(), is(100));

    Instruction actionMemberIdInstruction = getInstruction("PiActionProfileMemberIdInstruction.json");
    Assert.assertThat(actionInstruction.type(), is(Instruction.Type.PROTOCOL_INDEPENDENT));
    PiTableAction actionMemberId = ((PiInstruction) actionMemberIdInstruction).action();
    Assert.assertThat(actionMemberId.type(), is(PiTableAction.Type.ACTION_PROFILE_MEMBER_ID));
    Assert.assertThat(((PiActionProfileMemberId) actionMemberId).id(), is(100));
}
 
示例20
/**
 * Returns a PI table entry equivalent to the given flow rule, for the given
 * pipeconf and device.
 *
 * @param rule     flow rule
 * @param pipeconf pipeconf
 * @param device   device
 * @return PI table entry
 * @throws PiTranslationException if the flow rule cannot be translated
 */
static PiTableEntry translate(FlowRule rule, PiPipeconf pipeconf, Device device)
        throws PiTranslationException {

    PiPipelineModel pipelineModel = pipeconf.pipelineModel();

    // Retrieve interpreter, if any.
    final PiPipelineInterpreter interpreter = getInterpreterOrNull(device, pipeconf);
    // Get table model.
    final PiTableId piTableId = translateTableId(rule.table(), interpreter);
    final PiTableModel tableModel = getTableModel(piTableId, pipelineModel);
    // Translate selector.
    final PiMatchKey piMatchKey;
    final boolean needPriority;
    if (rule.selector().criteria().isEmpty()) {
        piMatchKey = PiMatchKey.EMPTY;
        needPriority = false;
    } else {
        final Collection<PiFieldMatch> fieldMatches = translateFieldMatches(
                interpreter, rule.selector(), tableModel);
        piMatchKey = PiMatchKey.builder()
                .addFieldMatches(fieldMatches)
                .build();
        // FIXME: P4Runtime limit
        // Need to ignore priority if no TCAM lookup match field
        needPriority = tableModel.matchFields().stream()
                .anyMatch(match -> match.matchType() == PiMatchType.TERNARY ||
                        match.matchType() == PiMatchType.RANGE);
    }
    // Translate treatment.
    final PiTableAction piTableAction = translateTreatment(rule.treatment(), interpreter, piTableId, pipelineModel);

    // Build PI entry.
    final PiTableEntry.Builder tableEntryBuilder = PiTableEntry.builder();

    tableEntryBuilder
            .forTable(piTableId)
            .withMatchKey(piMatchKey);

    if (piTableAction != null) {
        tableEntryBuilder.withAction(piTableAction);
    }

    if (needPriority) {
        // FIXME: move priority check to P4Runtime driver.
        final int newPriority;
        if (rule.priority() > MAX_PI_PRIORITY) {
            log.warn("Flow rule priority too big, setting translated priority to max value {}: {}",
                     MAX_PI_PRIORITY, rule);
            newPriority = MAX_PI_PRIORITY;
        } else {
            newPriority = MIN_PI_PRIORITY + rule.priority();
        }
        tableEntryBuilder.withPriority(newPriority);
    }

    if (!rule.isPermanent()) {
        if (tableModel.supportsAging()) {
            tableEntryBuilder.withTimeout((double) rule.timeout());
        } else {
            log.debug("Flow rule is temporary, but table '{}' doesn't support " +
                              "aging, translating to permanent.", tableModel.id());
        }

    }

    return tableEntryBuilder.build();
}
 
示例21
/**
 * Returns a PI action equivalent to the given treatment, optionally using
 * the given interpreter. This method also checks that the produced PI table
 * action is suitable for the given table ID and pipeline model. If
 * suitable, the returned action instance will have parameters well-sized,
 * according to the table model.
 *
 * @param treatment     traffic treatment
 * @param interpreter   interpreter
 * @param tableId       PI table ID
 * @param pipelineModel pipeline model
 * @return PI table action
 * @throws PiTranslationException if the treatment cannot be translated or
 *                                if the PI action is not suitable for the
 *                                given pipeline model
 */
static PiTableAction translateTreatment(TrafficTreatment treatment, PiPipelineInterpreter interpreter,
                                        PiTableId tableId, PiPipelineModel pipelineModel)
        throws PiTranslationException {
    PiTableModel tableModel = getTableModel(tableId, pipelineModel);
    return typeCheckAction(buildAction(treatment, interpreter, tableId), tableModel);
}
 
示例22
/**
 * Creates a new instruction with the given protocol-independent table action.
 *
 * @param tableAction a protocol-independent action
 */
PiInstruction(PiTableAction tableAction) {
    this.tableAction = tableAction;
}
 
示例23
/**
 * Returns the protocol-independent table action defined by this instruction.
 *
 * @return an action
 */
public PiTableAction action() {
    return tableAction;
}