org.onosproject.net.pi.runtime.PiTableAction Java Examples

The following examples show how to use org.onosproject.net.pi.runtime.PiTableAction. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: Ipv6RoutingComponent.java    From ngsdn-tutorial with Apache License 2.0 6 votes vote down vote up
/**
 * 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);
}
 
Example #2
Source File: InstructionCodecTest.java    From onos with Apache License 2.0 6 votes vote down vote up
/**
 * 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));
}
 
Example #3
Source File: Ipv6RoutingComponent.java    From onos-p4-tutorial with Apache License 2.0 6 votes vote down vote up
/**
 * 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);
}
 
Example #4
Source File: Ipv6RoutingComponent.java    From onos-p4-tutorial with Apache License 2.0 6 votes vote down vote up
/**
 * 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);
}
 
Example #5
Source File: TableEntryCodec.java    From onos with Apache License 2.0 6 votes vote down vote up
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()));
    }
}
 
Example #6
Source File: InstructionCodecTest.java    From onos with Apache License 2.0 5 votes vote down vote up
/**
 * 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));
}
 
Example #7
Source File: Ipv6RoutingComponent.java    From ngsdn-tutorial with Apache License 2.0 5 votes vote down vote up
/**
 * 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);
}
 
Example #8
Source File: PiGroupTranslatorImplTest.java    From onos with Apache License 2.0 5 votes vote down vote up
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);
}
 
Example #9
Source File: PiFlowRuleTranslatorImpl.java    From onos with Apache License 2.0 5 votes vote down vote up
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();
}
 
Example #10
Source File: PiFlowRuleTranslatorImpl.java    From onos with Apache License 2.0 5 votes vote down vote up
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()));

    }
}
 
Example #11
Source File: PiFlowRuleTranslatorImpl.java    From onos with Apache License 2.0 5 votes vote down vote up
/**
 * 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;
}
 
Example #12
Source File: TableEntryCodec.java    From onos with Apache License 2.0 5 votes vote down vote up
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();
}
 
Example #13
Source File: Srv6Component.java    From onos-p4-tutorial with Apache License 2.0 5 votes vote down vote up
/**
 * 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);
}
 
Example #14
Source File: Utils.java    From onos-p4-tutorial with Apache License 2.0 5 votes vote down vote up
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();
}
 
Example #15
Source File: Ipv6RoutingComponent.java    From onos-p4-tutorial with Apache License 2.0 5 votes vote down vote up
/**
 * 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);
}
 
Example #16
Source File: Srv6Component.java    From onos-p4-tutorial with Apache License 2.0 5 votes vote down vote up
/**
 * 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);
}
 
Example #17
Source File: Utils.java    From onos-p4-tutorial with Apache License 2.0 5 votes vote down vote up
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();
}
 
Example #18
Source File: Ipv6RoutingComponent.java    From onos-p4-tutorial with Apache License 2.0 5 votes vote down vote up
/**
 * 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);
}
 
Example #19
Source File: Utils.java    From ngsdn-tutorial with Apache License 2.0 5 votes vote down vote up
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();
}
 
Example #20
Source File: PiFlowRuleTranslatorImpl.java    From onos with Apache License 2.0 4 votes vote down vote up
/**
 * 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();
}
 
Example #21
Source File: PiFlowRuleTranslatorImpl.java    From onos with Apache License 2.0 3 votes vote down vote up
/**
 * 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);
}
 
Example #22
Source File: PiInstruction.java    From onos with Apache License 2.0 2 votes vote down vote up
/**
 * Creates a new instruction with the given protocol-independent table action.
 *
 * @param tableAction a protocol-independent action
 */
PiInstruction(PiTableAction tableAction) {
    this.tableAction = tableAction;
}
 
Example #23
Source File: PiInstruction.java    From onos with Apache License 2.0 2 votes vote down vote up
/**
 * Returns the protocol-independent table action defined by this instruction.
 *
 * @return an action
 */
public PiTableAction action() {
    return tableAction;
}