Search in sources :

Example 11 with PiMatchFieldId

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

the class PiTableEntryTest method testBuilder.

/**
 * Tests creation of a DefaultFlowRule using a FlowRule constructor.
 */
@Test
public void testBuilder() {
    PiTableId piTableId = PiTableId.of("table10");
    long cookie = 0xfff0323;
    int priority = 100;
    double timeout = 1000;
    PiMatchFieldId piMatchFieldId = PiMatchFieldId.of(IPV4_HEADER_NAME + DOT + DST_ADDR);
    PiFieldMatch piFieldMatch = new PiExactFieldMatch(piMatchFieldId, ImmutableByteSequence.copyFrom(0x0a010101));
    PiAction piAction = PiAction.builder().withId(PiActionId.of(DROP)).build();
    final Map<PiMatchFieldId, PiFieldMatch> fieldMatches = Maps.newHashMap();
    fieldMatches.put(piMatchFieldId, piFieldMatch);
    final PiTableEntry piTableEntry = PiTableEntry.builder().forTable(piTableId).withMatchKey(PiMatchKey.builder().addFieldMatches(fieldMatches.values()).build()).withAction(piAction).withCookie(cookie).withPriority(priority).withTimeout(timeout).build();
    assertThat(piTableEntry.table(), is(piTableId));
    assertThat(piTableEntry.cookie(), is(cookie));
    assertThat("Priority must be set", piTableEntry.priority().isPresent());
    assertThat("Timeout must be set", piTableEntry.timeout().isPresent());
    assertThat(piTableEntry.priority().getAsInt(), is(priority));
    assertThat(piTableEntry.timeout().get(), is(timeout));
    assertThat("Incorrect match param value", CollectionUtils.isEqualCollection(piTableEntry.matchKey().fieldMatches(), fieldMatches.values()));
    assertThat(piTableEntry.action(), is(piAction));
}
Also used : PiTableId(org.onosproject.net.pi.model.PiTableId) PiMatchFieldId(org.onosproject.net.pi.model.PiMatchFieldId) Test(org.junit.Test)

Example 12 with PiMatchFieldId

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

the class P4InfoParser method parse.

/**
 * Parse the given URL pointing to a P4Info file (in text format) to a PI pipeline model.
 *
 * @param p4InfoUrl URL to P4Info in text form
 * @return PI pipeline model
 * @throws P4InfoParserException if the P4Info file cannot be parsed (see message)
 */
public static PiPipelineModel parse(URL p4InfoUrl) throws P4InfoParserException {
    final P4Info p4info;
    try {
        p4info = getP4InfoMessage(p4InfoUrl);
    } catch (IOException e) {
        throw new P4InfoParserException("Unable to parse protobuf " + p4InfoUrl.toString(), e);
    }
    // Generate fingerprint of the pipeline by hashing p4info file
    final int fingerprint;
    try {
        HashingInputStream hin = new HashingInputStream(Hashing.crc32(), p4InfoUrl.openStream());
        // noinspection StatementWithEmptyBody
        while (hin.read() != -1) {
        // Do nothing. Reading all input stream to update hash.
        }
        fingerprint = hin.hash().asInt();
    } catch (IOException e) {
        throw new P4InfoParserException("Unable to generate fingerprint " + p4InfoUrl.toString(), e);
    }
    // Start by parsing and mapping instances to to their integer P4Info IDs.
    // Convenient to build the table model at the end.
    final String architecture = parseArchitecture(p4info);
    // Counters.
    final Map<Integer, PiCounterModel> counterMap = Maps.newHashMap();
    counterMap.putAll(parseCounters(p4info));
    counterMap.putAll(parseDirectCounters(p4info));
    // Meters.
    final Map<Integer, PiMeterModel> meterMap = Maps.newHashMap();
    meterMap.putAll(parseMeters(p4info));
    meterMap.putAll(parseDirectMeters(p4info));
    // Registers.
    final Map<Integer, PiRegisterModel> registerMap = Maps.newHashMap();
    registerMap.putAll(parseRegisters(p4info));
    // Action profiles.
    final Map<Integer, PiActionProfileModel> actProfileMap = parseActionProfiles(p4info);
    // Actions.
    final Map<Integer, PiActionModel> actionMap = parseActions(p4info);
    // Controller packet metadatas.
    final Map<PiPacketOperationType, PiPacketOperationModel> pktOpMap = parseCtrlPktMetadatas(p4info);
    // Finally, parse tables.
    final ImmutableMap.Builder<PiTableId, PiTableModel> tableImmMapBuilder = ImmutableMap.builder();
    for (Table tableMsg : p4info.getTablesList()) {
        final PiTableId tableId = PiTableId.of(tableMsg.getPreamble().getName());
        // Parse match fields.
        final ImmutableMap.Builder<PiMatchFieldId, PiMatchFieldModel> tableFieldMapBuilder = ImmutableMap.builder();
        for (MatchField fieldMsg : tableMsg.getMatchFieldsList()) {
            final PiMatchFieldId fieldId = PiMatchFieldId.of(fieldMsg.getName());
            tableFieldMapBuilder.put(fieldId, new P4MatchFieldModel(fieldId, isFieldString(p4info, fieldMsg.getTypeName().getName()) ? P4MatchFieldModel.BIT_WIDTH_UNDEFINED : fieldMsg.getBitwidth(), mapMatchFieldType(fieldMsg.getMatchType())));
        }
        // Retrieve action models by inter IDs.
        final ImmutableMap.Builder<PiActionId, PiActionModel> tableActionMapBuilder = ImmutableMap.builder();
        tableMsg.getActionRefsList().stream().map(ActionRef::getId).map(actionMap::get).forEach(actionModel -> tableActionMapBuilder.put(actionModel.id(), actionModel));
        // Retrieve direct meters by integer IDs.
        final ImmutableMap.Builder<PiMeterId, PiMeterModel> tableMeterMapBuilder = ImmutableMap.builder();
        tableMsg.getDirectResourceIdsList().stream().map(meterMap::get).filter(Objects::nonNull).forEach(meterModel -> tableMeterMapBuilder.put(meterModel.id(), meterModel));
        // Retrieve direct counters by integer IDs.
        final ImmutableMap.Builder<PiCounterId, PiCounterModel> tableCounterMapBuilder = ImmutableMap.builder();
        tableMsg.getDirectResourceIdsList().stream().map(counterMap::get).filter(Objects::nonNull).forEach(counterModel -> tableCounterMapBuilder.put(counterModel.id(), counterModel));
        // Check if table supports one-shot only
        boolean oneShotOnly = isAnnotationPresent(ONE_SHOT_ONLY_ANNOTATION, tableMsg.getPreamble());
        tableImmMapBuilder.put(tableId, new P4TableModel(PiTableId.of(tableMsg.getPreamble().getName()), tableMsg.getImplementationId() == 0 ? PiTableType.DIRECT : PiTableType.INDIRECT, actProfileMap.get(tableMsg.getImplementationId()), tableMsg.getSize(), tableCounterMapBuilder.build(), tableMeterMapBuilder.build(), !tableMsg.getIdleTimeoutBehavior().equals(Table.IdleTimeoutBehavior.NO_TIMEOUT), tableFieldMapBuilder.build(), tableActionMapBuilder.build(), actionMap.get(tableMsg.getConstDefaultActionId()), tableMsg.getIsConstTable(), oneShotOnly));
    }
    // Get a map with proper PI IDs for some of those maps we created at the beginning.
    ImmutableMap<PiCounterId, PiCounterModel> counterImmMap = ImmutableMap.copyOf(counterMap.values().stream().collect(Collectors.toMap(PiCounterModel::id, c -> c)));
    ImmutableMap<PiMeterId, PiMeterModel> meterImmMap = ImmutableMap.copyOf(meterMap.values().stream().collect(Collectors.toMap(PiMeterModel::id, m -> m)));
    ImmutableMap<PiRegisterId, PiRegisterModel> registerImmMap = ImmutableMap.copyOf(registerMap.values().stream().collect(Collectors.toMap(PiRegisterModel::id, r -> r)));
    ImmutableMap<PiActionProfileId, PiActionProfileModel> actProfileImmMap = ImmutableMap.copyOf(actProfileMap.values().stream().collect(Collectors.toMap(PiActionProfileModel::id, a -> a)));
    return new P4PipelineModel(tableImmMapBuilder.build(), counterImmMap, meterImmMap, registerImmMap, actProfileImmMap, ImmutableMap.copyOf(pktOpMap), architecture, fingerprint);
}
Also used : PiCounterModel(org.onosproject.net.pi.model.PiCounterModel) PiTableModel(org.onosproject.net.pi.model.PiTableModel) PiActionId(org.onosproject.net.pi.model.PiActionId) PiMeterId(org.onosproject.net.pi.model.PiMeterId) PiPacketOperationType(org.onosproject.net.pi.model.PiPacketOperationType) PiPacketOperationModel(org.onosproject.net.pi.model.PiPacketOperationModel) MatchField(p4.config.v1.P4InfoOuterClass.MatchField) PiTableId(org.onosproject.net.pi.model.PiTableId) PiMatchFieldId(org.onosproject.net.pi.model.PiMatchFieldId) ActionRef(p4.config.v1.P4InfoOuterClass.ActionRef) PiRegisterModel(org.onosproject.net.pi.model.PiRegisterModel) Table(p4.config.v1.P4InfoOuterClass.Table) PiActionModel(org.onosproject.net.pi.model.PiActionModel) PiMeterModel(org.onosproject.net.pi.model.PiMeterModel) PiActionProfileId(org.onosproject.net.pi.model.PiActionProfileId) IOException(java.io.IOException) ImmutableMap(com.google.common.collect.ImmutableMap) HashingInputStream(com.google.common.hash.HashingInputStream) P4Info(p4.config.v1.P4InfoOuterClass.P4Info) PiActionProfileModel(org.onosproject.net.pi.model.PiActionProfileModel) PiRegisterId(org.onosproject.net.pi.model.PiRegisterId) PiMatchFieldModel(org.onosproject.net.pi.model.PiMatchFieldModel) PiCounterId(org.onosproject.net.pi.model.PiCounterId)

Example 13 with PiMatchFieldId

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

the class FieldMatchCodec method decode.

@Override
public PiFieldMatch decode(P4RuntimeOuterClass.FieldMatch message, P4InfoOuterClass.Preamble tablePreamble, PiPipeconf pipeconf, P4InfoBrowser browser) throws CodecException, P4InfoBrowser.NotFoundException {
    final P4InfoOuterClass.MatchField matchField = browser.matchFields(tablePreamble.getId()).getById(message.getFieldId());
    final int fieldBitwidth = matchField.getBitwidth();
    final PiMatchFieldId headerFieldId = PiMatchFieldId.of(matchField.getName());
    final boolean isSdnString = browser.isTypeString(matchField.getTypeName());
    final P4RuntimeOuterClass.FieldMatch.FieldMatchTypeCase typeCase = message.getFieldMatchTypeCase();
    try {
        switch(typeCase) {
            case EXACT:
                P4RuntimeOuterClass.FieldMatch.Exact exactFieldMatch = message.getExact();
                final ImmutableByteSequence exactValue;
                if (isSdnString) {
                    exactValue = copyFrom(new String(exactFieldMatch.getValue().toByteArray()));
                } else {
                    exactValue = copyAndFit(exactFieldMatch.getValue().asReadOnlyByteBuffer(), fieldBitwidth);
                }
                return new PiExactFieldMatch(headerFieldId, exactValue);
            case TERNARY:
                P4RuntimeOuterClass.FieldMatch.Ternary ternaryFieldMatch = message.getTernary();
                ImmutableByteSequence ternaryValue = copyAndFit(ternaryFieldMatch.getValue().asReadOnlyByteBuffer(), fieldBitwidth);
                ImmutableByteSequence ternaryMask = copyAndFit(ternaryFieldMatch.getMask().asReadOnlyByteBuffer(), fieldBitwidth);
                return new PiTernaryFieldMatch(headerFieldId, ternaryValue, ternaryMask);
            case LPM:
                P4RuntimeOuterClass.FieldMatch.LPM lpmFieldMatch = message.getLpm();
                ImmutableByteSequence lpmValue = copyAndFit(lpmFieldMatch.getValue().asReadOnlyByteBuffer(), fieldBitwidth);
                int lpmPrefixLen = lpmFieldMatch.getPrefixLen();
                return new PiLpmFieldMatch(headerFieldId, lpmValue, lpmPrefixLen);
            case RANGE:
                P4RuntimeOuterClass.FieldMatch.Range rangeFieldMatch = message.getRange();
                ImmutableByteSequence rangeHighValue = copyAndFit(rangeFieldMatch.getHigh().asReadOnlyByteBuffer(), fieldBitwidth);
                ImmutableByteSequence rangeLowValue = copyAndFit(rangeFieldMatch.getLow().asReadOnlyByteBuffer(), fieldBitwidth);
                return new PiRangeFieldMatch(headerFieldId, rangeLowValue, rangeHighValue);
            case OPTIONAL:
                P4RuntimeOuterClass.FieldMatch.Optional optionalFieldMatch = message.getOptional();
                final ImmutableByteSequence optionalValue;
                if (isSdnString) {
                    optionalValue = copyFrom(new String(optionalFieldMatch.getValue().toByteArray()));
                } else {
                    optionalValue = copyAndFit(optionalFieldMatch.getValue().asReadOnlyByteBuffer(), fieldBitwidth);
                }
                return new PiOptionalFieldMatch(headerFieldId, optionalValue);
            default:
                throw new CodecException(format("Decoding of field match type '%s' not implemented", typeCase.name()));
        }
    } catch (ImmutableByteSequence.ByteSequenceTrimException e) {
        throw new CodecException(e.getMessage());
    }
}
Also used : PiOptionalFieldMatch(org.onosproject.net.pi.runtime.PiOptionalFieldMatch) PiRangeFieldMatch(org.onosproject.net.pi.runtime.PiRangeFieldMatch) PiTernaryFieldMatch(org.onosproject.net.pi.runtime.PiTernaryFieldMatch) PiExactFieldMatch(org.onosproject.net.pi.runtime.PiExactFieldMatch) PiLpmFieldMatch(org.onosproject.net.pi.runtime.PiLpmFieldMatch) PiFieldMatch(org.onosproject.net.pi.runtime.PiFieldMatch) PiRangeFieldMatch(org.onosproject.net.pi.runtime.PiRangeFieldMatch) ByteString(com.google.protobuf.ByteString) PiTernaryFieldMatch(org.onosproject.net.pi.runtime.PiTernaryFieldMatch) PiLpmFieldMatch(org.onosproject.net.pi.runtime.PiLpmFieldMatch) P4InfoOuterClass(p4.config.v1.P4InfoOuterClass) PiOptionalFieldMatch(org.onosproject.net.pi.runtime.PiOptionalFieldMatch) PiMatchFieldId(org.onosproject.net.pi.model.PiMatchFieldId) PiExactFieldMatch(org.onosproject.net.pi.runtime.PiExactFieldMatch) ImmutableByteSequence(org.onlab.util.ImmutableByteSequence)

Example 14 with PiMatchFieldId

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

the class MyTunnelApp method insertTunnelIngressRule.

/**
 * Generates and insert a flow rule to perform the tunnel INGRESS function
 * for the given switch, destination IP address and tunnel ID.
 *
 * @param switchId  switch ID
 * @param dstIpAddr IP address to forward inside the tunnel
 * @param tunId     tunnel ID
 */
private void insertTunnelIngressRule(DeviceId switchId, IpAddress dstIpAddr, int tunId) {
    PiTableId tunnelIngressTableId = PiTableId.of("c_ingress.t_tunnel_ingress");
    // Longest prefix match on IPv4 dest address.
    PiMatchFieldId ipDestMatchFieldId = PiMatchFieldId.of("hdr.ipv4.dst_addr");
    PiCriterion match = PiCriterion.builder().matchLpm(ipDestMatchFieldId, dstIpAddr.toOctets(), 32).build();
    PiActionParam tunIdParam = new PiActionParam(PiActionParamId.of("tun_id"), tunId);
    PiActionId ingressActionId = PiActionId.of("c_ingress.my_tunnel_ingress");
    PiAction action = PiAction.builder().withId(ingressActionId).withParameter(tunIdParam).build();
    log.info("Inserting INGRESS rule on switch {}: table={}, match={}, action={}", switchId, tunnelIngressTableId, match, action);
    insertPiFlowRule(switchId, tunnelIngressTableId, match, action);
}
Also used : 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)

Example 15 with PiMatchFieldId

use of org.onosproject.net.pi.model.PiMatchFieldId 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

PiMatchFieldId (org.onosproject.net.pi.model.PiMatchFieldId)15 Test (org.junit.Test)10 ImmutableByteSequence (org.onlab.util.ImmutableByteSequence)7 PiTableId (org.onosproject.net.pi.model.PiTableId)5 PiCriterion (org.onosproject.net.flow.criteria.PiCriterion)4 PiActionId (org.onosproject.net.pi.model.PiActionId)3 PiAction (org.onosproject.net.pi.runtime.PiAction)3 PiActionParam (org.onosproject.net.pi.runtime.PiActionParam)3 Criterion (org.onosproject.net.flow.criteria.Criterion)2 PiActionModel (org.onosproject.net.pi.model.PiActionModel)2 PiMatchFieldModel (org.onosproject.net.pi.model.PiMatchFieldModel)2 PiTableModel (org.onosproject.net.pi.model.PiTableModel)2 PiExactFieldMatch (org.onosproject.net.pi.runtime.PiExactFieldMatch)2 PiFieldMatch (org.onosproject.net.pi.runtime.PiFieldMatch)2 PiLpmFieldMatch (org.onosproject.net.pi.runtime.PiLpmFieldMatch)2 PiOptionalFieldMatch (org.onosproject.net.pi.runtime.PiOptionalFieldMatch)2 PiRangeFieldMatch (org.onosproject.net.pi.runtime.PiRangeFieldMatch)2 PiTernaryFieldMatch (org.onosproject.net.pi.runtime.PiTernaryFieldMatch)2 ObjectNode (com.fasterxml.jackson.databind.node.ObjectNode)1 ImmutableMap (com.google.common.collect.ImmutableMap)1