Search in sources :

Example 6 with PiActionParamId

use of org.onosproject.net.pi.model.PiActionParamId in project onos by opennetworkinglab.

the class P4InfoParserTest method testParse.

/**
 * Tests parse method.
 * @throws Exception if equality group objects dose not match as expected
 */
@Test
public void testParse() throws Exception {
    // Generate two PiPipelineModels from the same p4Info file
    PiPipelineModel model = P4InfoParser.parse(p4InfoUrl);
    PiPipelineModel sameAsModel = P4InfoParser.parse(p4InfoUrl);
    // Check equality
    new EqualsTester().addEqualityGroup(model, sameAsModel).testEquals();
    // Generate a P4Info object from the file
    final P4Info p4info;
    try {
        p4info = getP4InfoMessage(p4InfoUrl);
    } catch (IOException e) {
        throw new P4InfoParserException("Unable to parse protobuf " + p4InfoUrl.toString(), e);
    }
    List<Table> tableMsgs = p4info.getTablesList();
    PiTableId table0Id = PiTableId.of(tableMsgs.get(0).getPreamble().getName());
    PiTableId wcmpTableId = PiTableId.of(tableMsgs.get(1).getPreamble().getName());
    PiTableId wcmpTableOneShotId = PiTableId.of(tableMsgs.get(2).getPreamble().getName());
    // parse tables
    PiTableModel table0Model = model.table(table0Id).orElse(null);
    PiTableModel wcmpTableModel = model.table(wcmpTableId).orElse(null);
    PiTableModel wcmpTableOneShotModel = model.table(wcmpTableOneShotId).orElse(null);
    PiTableModel table0Model2 = sameAsModel.table(table0Id).orElse(null);
    PiTableModel wcmpTableModel2 = sameAsModel.table(wcmpTableId).orElse(null);
    new EqualsTester().addEqualityGroup(table0Model, table0Model2).addEqualityGroup(wcmpTableModel, wcmpTableModel2).testEquals();
    // Check existence
    assertThat("model parsed value is null", table0Model, notNullValue());
    assertThat("model parsed value is null", wcmpTableModel, notNullValue());
    assertThat("model parsed value is null", wcmpTableOneShotModel, notNullValue());
    assertThat("Incorrect size for table0 size", table0Model.maxSize(), is(equalTo(DEFAULT_MAX_TABLE_SIZE)));
    assertThat("Incorrect size for wcmp_table size", wcmpTableModel.maxSize(), is(equalTo(DEFAULT_MAX_TABLE_SIZE)));
    assertThat("Incorrect size for wcmp_table_one_shot size", wcmpTableOneShotModel.maxSize(), is(equalTo(DEFAULT_MAX_TABLE_SIZE)));
    // Check one-shot annotation
    assertThat("error parsing one-shot annotation", wcmpTableModel.oneShotOnly(), is(false));
    assertThat("error parsing one-shot annotation", wcmpTableOneShotModel.oneShotOnly(), is(true));
    // Check matchFields
    List<MatchField> matchFieldList = tableMsgs.get(0).getMatchFieldsList();
    List<PiMatchFieldModel> piMatchFieldList = new ArrayList<>();
    for (MatchField matchFieldIter : matchFieldList) {
        MatchField.MatchType matchType = matchFieldIter.getMatchType();
        PiMatchType piMatchType;
        switch(matchType) {
            case EXACT:
                piMatchType = PiMatchType.EXACT;
                break;
            case LPM:
                piMatchType = PiMatchType.LPM;
                break;
            case TERNARY:
                piMatchType = PiMatchType.TERNARY;
                break;
            case RANGE:
                piMatchType = PiMatchType.RANGE;
                break;
            default:
                Assert.fail();
                return;
        }
        piMatchFieldList.add(new P4MatchFieldModel(PiMatchFieldId.of(matchFieldIter.getName()), matchFieldIter.getBitwidth(), piMatchType));
    }
    // Check MatchFields size
    assertThat("Incorrect size for matchFields", table0Model.matchFields().size(), is(equalTo(9)));
    // Check if matchFields are in order
    assertThat("Incorrect order for matchFields", table0Model.matchFields(), IsIterableContainingInOrder.contains(piMatchFieldList.get(0), piMatchFieldList.get(1), piMatchFieldList.get(2), piMatchFieldList.get(3), piMatchFieldList.get(4), piMatchFieldList.get(5), piMatchFieldList.get(6), piMatchFieldList.get(7), piMatchFieldList.get(8)));
    assertThat("Incorrect size for matchFields", wcmpTableModel.matchFields().size(), is(equalTo(1)));
    // check if matchFields are in order
    matchFieldList = tableMsgs.get(1).getMatchFieldsList();
    assertThat("Incorrect order for matchFields", wcmpTableModel.matchFields(), IsIterableContainingInOrder.contains(new P4MatchFieldModel(PiMatchFieldId.of(matchFieldList.get(0).getName()), matchFieldList.get(0).getBitwidth(), PiMatchType.EXACT)));
    // check table0 actionsRefs
    List<ActionRef> actionRefList = tableMsgs.get(0).getActionRefsList();
    assertThat("Incorrect size for actionRefs", actionRefList.size(), is(equalTo(4)));
    // create action instances
    PiActionId actionId = PiActionId.of("set_egress_port");
    PiActionParamId piActionParamId = PiActionParamId.of("port");
    int bitWitdth = 9;
    PiActionParamModel actionParamModel = new P4ActionParamModel(piActionParamId, bitWitdth);
    ImmutableMap<PiActionParamId, PiActionParamModel> params = new ImmutableMap.Builder<PiActionParamId, PiActionParamModel>().put(piActionParamId, actionParamModel).build();
    PiActionModel setEgressPortAction = new P4ActionModel(actionId, params);
    actionId = PiActionId.of("send_to_cpu");
    PiActionModel sendToCpuAction = new P4ActionModel(actionId, new ImmutableMap.Builder<PiActionParamId, PiActionParamModel>().build());
    actionId = PiActionId.of("_drop");
    PiActionModel dropAction = new P4ActionModel(actionId, new ImmutableMap.Builder<PiActionParamId, PiActionParamModel>().build());
    actionId = PiActionId.of("NoAction");
    PiActionModel noAction = new P4ActionModel(actionId, new ImmutableMap.Builder<PiActionParamId, PiActionParamModel>().build());
    actionId = PiActionId.of("table0_control.set_next_hop_id");
    piActionParamId = PiActionParamId.of("next_hop_id");
    bitWitdth = 16;
    actionParamModel = new P4ActionParamModel(piActionParamId, bitWitdth);
    params = new ImmutableMap.Builder<PiActionParamId, PiActionParamModel>().put(piActionParamId, actionParamModel).build();
    PiActionModel setNextHopIdAction = new P4ActionModel(actionId, params);
    // check table0 actions
    assertThat("action dose not match", table0Model.actions(), IsIterableContainingInAnyOrder.containsInAnyOrder(setEgressPortAction, sendToCpuAction, setNextHopIdAction, dropAction));
    // check wcmp_table actions
    assertThat("actions dose not match", wcmpTableModel.actions(), IsIterableContainingInAnyOrder.containsInAnyOrder(setEgressPortAction, noAction));
    PiActionModel table0DefaultAction = table0Model.constDefaultAction().orElse(null);
    new EqualsTester().addEqualityGroup(table0DefaultAction, dropAction).testEquals();
    // Check existence
    assertThat("model parsed value is null", table0DefaultAction, notNullValue());
    // parse action profiles
    PiTableId tableId = PiTableId.of("wcmp_control.wcmp_table");
    ImmutableSet<PiTableId> tableIds = new ImmutableSet.Builder<PiTableId>().add(tableId).build();
    PiActionProfileId actionProfileId = PiActionProfileId.of("wcmp_control.wcmp_selector");
    PiActionProfileModel wcmpSelector3 = new P4ActionProfileModel(actionProfileId, tableIds, true, DEFAULT_MAX_ACTION_PROFILE_SIZE, DEFAULT_MAX_GROUP_SIZE);
    PiActionProfileModel wcmpSelector = model.actionProfiles(actionProfileId).orElse(null);
    PiActionProfileModel wcmpSelector2 = sameAsModel.actionProfiles(actionProfileId).orElse(null);
    new EqualsTester().addEqualityGroup(wcmpSelector, wcmpSelector2, wcmpSelector3).testEquals();
    // Check existence
    assertThat("model parsed value is null", wcmpSelector, notNullValue());
    assertThat("Incorrect value for actions profiles", model.actionProfiles(), containsInAnyOrder(wcmpSelector));
    // ActionProfiles size
    assertThat("Incorrect size for action profiles", model.actionProfiles().size(), is(equalTo(1)));
    // parse counters
    PiCounterModel ingressPortCounterModel = model.counter(PiCounterId.of("port_counters_ingress.ingress_port_counter")).orElse(null);
    PiCounterModel egressPortCounterModel = model.counter(PiCounterId.of("port_counters_egress.egress_port_counter")).orElse(null);
    PiCounterModel table0CounterModel = model.counter(PiCounterId.of("table0_control.table0_counter")).orElse(null);
    PiCounterModel wcmpTableCounterModel = model.counter(PiCounterId.of("wcmp_control.wcmp_table_counter")).orElse(null);
    PiCounterModel ingressPortCounterModel2 = sameAsModel.counter(PiCounterId.of("port_counters_ingress.ingress_port_counter")).orElse(null);
    PiCounterModel egressPortCounterModel2 = sameAsModel.counter(PiCounterId.of("port_counters_egress.egress_port_counter")).orElse(null);
    PiCounterModel table0CounterModel2 = sameAsModel.counter(PiCounterId.of("table0_control.table0_counter")).orElse(null);
    PiCounterModel wcmpTableCounterModel2 = sameAsModel.counter(PiCounterId.of("wcmp_control.wcmp_table_counter")).orElse(null);
    new EqualsTester().addEqualityGroup(ingressPortCounterModel, ingressPortCounterModel2).addEqualityGroup(egressPortCounterModel, egressPortCounterModel2).addEqualityGroup(table0CounterModel, table0CounterModel2).addEqualityGroup(wcmpTableCounterModel, wcmpTableCounterModel2).testEquals();
    assertThat("model parsed value is null", ingressPortCounterModel, notNullValue());
    assertThat("model parsed value is null", egressPortCounterModel, notNullValue());
    assertThat("model parsed value is null", table0CounterModel, notNullValue());
    assertThat("model parsed value is null", wcmpTableCounterModel, notNullValue());
    // Parse meters
    Collection<PiMeterModel> meterModel = model.meters();
    Collection<PiMeterModel> meterModel2 = sameAsModel.meters();
    assertThat("model parsed meter collection should be empty", meterModel.isEmpty(), is(true));
    assertThat("model parsed meter collection should be empty", meterModel2.isEmpty(), is(true));
    // parse packet operations
    PiPacketOperationModel packetInOperationalModel = model.packetOperationModel(PiPacketOperationType.PACKET_IN).orElse(null);
    PiPacketOperationModel packetOutOperationalModel = model.packetOperationModel(PiPacketOperationType.PACKET_OUT).orElse(null);
    PiPacketOperationModel packetInOperationalModel2 = sameAsModel.packetOperationModel(PiPacketOperationType.PACKET_IN).orElse(null);
    PiPacketOperationModel packetOutOperationalModel2 = sameAsModel.packetOperationModel(PiPacketOperationType.PACKET_OUT).orElse(null);
    new EqualsTester().addEqualityGroup(packetInOperationalModel, packetInOperationalModel2).addEqualityGroup(packetOutOperationalModel, packetOutOperationalModel2).testEquals();
    // Check existence
    assertThat("model parsed value is null", packetInOperationalModel, notNullValue());
    assertThat("model parsed value is null", packetOutOperationalModel, notNullValue());
}
Also used : PiTableModel(org.onosproject.net.pi.model.PiTableModel) PiActionId(org.onosproject.net.pi.model.PiActionId) PiActionParamId(org.onosproject.net.pi.model.PiActionParamId) PiCounterModel(org.onosproject.net.pi.model.PiCounterModel) ArrayList(java.util.ArrayList) PiPacketOperationModel(org.onosproject.net.pi.model.PiPacketOperationModel) MatchField(p4.config.v1.P4InfoOuterClass.MatchField) PiTableId(org.onosproject.net.pi.model.PiTableId) ActionRef(p4.config.v1.P4InfoOuterClass.ActionRef) PiPipelineModel(org.onosproject.net.pi.model.PiPipelineModel) Table(p4.config.v1.P4InfoOuterClass.Table) PiMatchType(org.onosproject.net.pi.model.PiMatchType) PiActionModel(org.onosproject.net.pi.model.PiActionModel) EqualsTester(com.google.common.testing.EqualsTester) PiMeterModel(org.onosproject.net.pi.model.PiMeterModel) PiActionParamModel(org.onosproject.net.pi.model.PiActionParamModel) PiActionProfileId(org.onosproject.net.pi.model.PiActionProfileId) IOException(java.io.IOException) ImmutableMap(com.google.common.collect.ImmutableMap) P4Info(p4.config.v1.P4InfoOuterClass.P4Info) PiActionProfileModel(org.onosproject.net.pi.model.PiActionProfileModel) PiMatchFieldModel(org.onosproject.net.pi.model.PiMatchFieldModel) Test(org.junit.Test)

Example 7 with PiActionParamId

use of org.onosproject.net.pi.model.PiActionParamId in project onos by opennetworkinglab.

the class DecodeInstructionCodecHelper method decodePi.

/**
 * Decodes a protocol-independent instruction.
 *
 * @return instruction object decoded from the JSON
 * @throws IllegalArgumentException if the JSON is invalid
 */
private Instruction decodePi() {
    String subType = nullIsIllegal(json.get(InstructionCodec.SUBTYPE), InstructionCodec.SUBTYPE + InstructionCodec.ERROR_MESSAGE).asText();
    if (subType.equals(PiTableAction.Type.ACTION.name())) {
        PiActionId piActionId = PiActionId.of(nullIsIllegal(json.get(InstructionCodec.PI_ACTION_ID), InstructionCodec.PI_ACTION_ID + InstructionCodec.MISSING_MEMBER_MESSAGE).asText());
        JsonNode params = json.get(InstructionCodec.PI_ACTION_PARAMS);
        PiAction.Builder builder = PiAction.builder();
        PiActionParam piActionParam;
        PiActionParamId piActionParamId;
        if (params != null) {
            for (Map.Entry<String, String> param : ((Map<String, String>) (context.mapper().convertValue(params, Map.class))).entrySet()) {
                piActionParamId = PiActionParamId.of(param.getKey());
                piActionParam = new PiActionParam(piActionParamId, ImmutableByteSequence.copyFrom(HexString.fromHexString(param.getValue(), null)));
                builder.withParameter(piActionParam);
            }
        }
        return Instructions.piTableAction(builder.withId(piActionId).build());
    } else if (subType.equals(PiTableAction.Type.ACTION_PROFILE_GROUP_ID.name())) {
        PiActionProfileGroupId piActionGroupId = PiActionProfileGroupId.of(nullIsIllegal(json.get(InstructionCodec.PI_ACTION_PROFILE_GROUP_ID), InstructionCodec.PI_ACTION_PROFILE_GROUP_ID + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt());
        return Instructions.piTableAction(piActionGroupId);
    } else if (subType.equals(PiTableAction.Type.ACTION_PROFILE_MEMBER_ID.name())) {
        PiActionProfileMemberId piActionProfileMemberId = PiActionProfileMemberId.of(nullIsIllegal(json.get(InstructionCodec.PI_ACTION_PROFILE_MEMBER_ID), InstructionCodec.PI_ACTION_PROFILE_MEMBER_ID + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt());
        return Instructions.piTableAction(piActionProfileMemberId);
    }
    // TODO: implement JSON decoder for ACTION_SET
    throw new IllegalArgumentException("Protocol-independent Instruction subtype " + subType + " is not supported");
}
Also used : PiActionProfileMemberId(org.onosproject.net.pi.runtime.PiActionProfileMemberId) PiActionId(org.onosproject.net.pi.model.PiActionId) PiActionParamId(org.onosproject.net.pi.model.PiActionParamId) PiActionProfileGroupId(org.onosproject.net.pi.runtime.PiActionProfileGroupId) JsonNode(com.fasterxml.jackson.databind.JsonNode) HexString(org.onlab.util.HexString) PiActionParam(org.onosproject.net.pi.runtime.PiActionParam) Map(java.util.Map) PiAction(org.onosproject.net.pi.runtime.PiAction)

Example 8 with PiActionParamId

use of org.onosproject.net.pi.model.PiActionParamId in project onos by opennetworkinglab.

the class InstructionCodecTest method piInstructionEncodingTest.

/**
 * 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));
}
Also used : PiActionId(org.onosproject.net.pi.model.PiActionId) PiActionParamId(org.onosproject.net.pi.model.PiActionParamId) PiTableAction(org.onosproject.net.pi.runtime.PiTableAction) PiInstruction(org.onosproject.net.flow.instructions.PiInstruction) ObjectNode(com.fasterxml.jackson.databind.node.ObjectNode) PiActionParam(org.onosproject.net.pi.runtime.PiActionParam) Test(org.junit.Test)

Example 9 with PiActionParamId

use of org.onosproject.net.pi.model.PiActionParamId in project onos by opennetworkinglab.

the class MyTunnelApp method insertTunnelForwardRule.

/**
 * Generates and insert a flow rule to perform the tunnel FORWARD/EGRESS
 * function for the given switch, output port address and tunnel ID.
 *
 * @param switchId switch ID
 * @param outPort  output port where to forward tunneled packets
 * @param tunId    tunnel ID
 * @param isEgress if true, perform tunnel egress action, otherwise forward
 *                 packet as is to port
 */
private void insertTunnelForwardRule(DeviceId switchId, PortNumber outPort, int tunId, boolean isEgress) {
    PiTableId tunnelForwardTableId = PiTableId.of("c_ingress.t_tunnel_fwd");
    // Exact match on tun_id
    PiMatchFieldId tunIdMatchFieldId = PiMatchFieldId.of("hdr.my_tunnel.tun_id");
    PiCriterion match = PiCriterion.builder().matchExact(tunIdMatchFieldId, tunId).build();
    // Action depend on isEgress parameter.
    // if true, perform tunnel egress action on the given outPort, otherwise
    // simply forward packet as is (set_out_port action).
    PiActionParamId portParamId = PiActionParamId.of("port");
    PiActionParam portParam = new PiActionParam(portParamId, (short) outPort.toLong());
    final PiAction action;
    if (isEgress) {
        // Tunnel egress action.
        // Remove MyTunnel header and forward to outPort.
        PiActionId egressActionId = PiActionId.of("c_ingress.my_tunnel_egress");
        action = PiAction.builder().withId(egressActionId).withParameter(portParam).build();
    } else {
        // Tunnel transit action.
        // Forward the packet as is to outPort.
        /*
             * TODO EXERCISE: create action object for the transit case.
             * Look at the t_tunnel_fwd table in the P4 program. Which of the 3
             * actions can be used to simply set the output port? Get the full
             * action name from the P4Info file, and use that when creating the
             * PiActionId object. When creating the PiAction object, remember to
             * add all action parameters as defined in the P4 program.
             *
             * Hint: the code will be similar to the case when isEgress is true.
             */
        // Replace null with your solution.
        action = null;
    }
    log.info("Inserting {} rule on switch {}: table={}, match={}, action={}", isEgress ? "EGRESS" : "TRANSIT", switchId, tunnelForwardTableId, match, action);
    insertPiFlowRule(switchId, tunnelForwardTableId, match, action);
}
Also used : PiActionParamId(org.onosproject.net.pi.model.PiActionParamId) PiActionId(org.onosproject.net.pi.model.PiActionId) PiCriterion(org.onosproject.net.flow.criteria.PiCriterion) PiTableId(org.onosproject.net.pi.model.PiTableId) PiMatchFieldId(org.onosproject.net.pi.model.PiMatchFieldId) PiActionParam(org.onosproject.net.pi.runtime.PiActionParam) PiAction(org.onosproject.net.pi.runtime.PiAction)

Aggregations

PiActionParamId (org.onosproject.net.pi.model.PiActionParamId)9 Test (org.junit.Test)5 PiActionId (org.onosproject.net.pi.model.PiActionId)5 PiActionParam (org.onosproject.net.pi.runtime.PiActionParam)4 ImmutableMap (com.google.common.collect.ImmutableMap)3 PiActionModel (org.onosproject.net.pi.model.PiActionModel)3 PiActionParamModel (org.onosproject.net.pi.model.PiActionParamModel)3 PiTableId (org.onosproject.net.pi.model.PiTableId)3 PiAction (org.onosproject.net.pi.runtime.PiAction)3 IOException (java.io.IOException)2 ArrayList (java.util.ArrayList)2 PiCriterion (org.onosproject.net.flow.criteria.PiCriterion)2 PiMatchFieldModel (org.onosproject.net.pi.model.PiMatchFieldModel)2 PiMatchType (org.onosproject.net.pi.model.PiMatchType)2 PiPipelineModel (org.onosproject.net.pi.model.PiPipelineModel)2 PiTableModel (org.onosproject.net.pi.model.PiTableModel)2 ActionRef (p4.config.v1.P4InfoOuterClass.ActionRef)2 MatchField (p4.config.v1.P4InfoOuterClass.MatchField)2 P4Info (p4.config.v1.P4InfoOuterClass.P4Info)2 Table (p4.config.v1.P4InfoOuterClass.Table)2