Search in sources :

Example 6 with PiMatchFieldId

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

the class PiFlowRuleTranslatorImpl method translateFieldMatches.

/**
 * Builds a collection of PI field matches out of the given selector,
 * optionally using the given interpreter. The field matches returned are
 * guaranteed to be compatible for the given table model.
 */
private static Collection<PiFieldMatch> translateFieldMatches(PiPipelineInterpreter interpreter, TrafficSelector selector, PiTableModel tableModel) throws PiTranslationException {
    Map<PiMatchFieldId, PiFieldMatch> fieldMatches = Maps.newHashMap();
    // If present, find a PiCriterion and get its field matches as a map. Otherwise, use an empty map.
    Map<PiMatchFieldId, PiFieldMatch> piCriterionFields = selector.criteria().stream().filter(c -> c.type().equals(PROTOCOL_INDEPENDENT)).map(c -> (PiCriterion) c).findFirst().map(PiCriterion::fieldMatches).map(c -> {
        Map<PiMatchFieldId, PiFieldMatch> fieldMap = Maps.newHashMap();
        c.forEach(fieldMatch -> fieldMap.put(fieldMatch.fieldId(), fieldMatch));
        return fieldMap;
    }).orElse(Maps.newHashMap());
    Set<Criterion> translatedCriteria = Sets.newHashSet();
    Set<Criterion> ignoredCriteria = Sets.newHashSet();
    Set<PiMatchFieldId> usedPiCriterionFields = Sets.newHashSet();
    Set<PiMatchFieldId> ignoredPiCriterionFields = Sets.newHashSet();
    Map<PiMatchFieldId, Criterion> criterionMap = Maps.newHashMap();
    if (interpreter != null) {
        // NOTE: if two criterion types map to the same match field ID, and
        // those two criterion types are present in the selector, this won't
        // work. This is unlikely to happen since those cases should be
        // mutually exclusive:
        // e.g. ICMPV6_TYPE ->  metadata.my_normalized_icmp_type
        // ICMPV4_TYPE ->  metadata.my_normalized_icmp_type
        // A packet can be either ICMPv6 or ICMPv4 but not both.
        selector.criteria().stream().map(Criterion::type).filter(t -> t != PROTOCOL_INDEPENDENT).forEach(t -> {
            PiMatchFieldId mfid = interpreter.mapCriterionType(t).orElse(null);
            if (mfid != null) {
                if (criterionMap.containsKey(mfid)) {
                    log.warn("Detected criterion mapping " + "conflict for PiMatchFieldId {}", mfid);
                }
                criterionMap.put(mfid, selector.getCriterion(t));
            }
        });
    }
    for (PiMatchFieldModel fieldModel : tableModel.matchFields()) {
        PiMatchFieldId fieldId = fieldModel.id();
        int bitWidth = fieldModel.bitWidth();
        Criterion criterion = criterionMap.get(fieldId);
        if (!piCriterionFields.containsKey(fieldId) && criterion == null) {
            // Can ignore if match is ternary-like, as it means "don't care".
            switch(fieldModel.matchType()) {
                case TERNARY:
                case LPM:
                case RANGE:
                case OPTIONAL:
                    // Skip field.
                    break;
                default:
                    throw new PiTranslationException(format("No value found for required match field '%s'", fieldId));
            }
            // Next field.
            continue;
        }
        PiFieldMatch fieldMatch = null;
        // TODO: we currently do not support fields with arbitrary bit width
        if (criterion != null && fieldModel.hasBitWidth()) {
            // Criterion mapping is possible for this field id.
            try {
                fieldMatch = translateCriterion(criterion, fieldId, fieldModel.matchType(), bitWidth);
                translatedCriteria.add(criterion);
            } catch (PiTranslationException ex) {
                // Ignore exception if the same field was found in PiCriterion.
                if (piCriterionFields.containsKey(fieldId)) {
                    ignoredCriteria.add(criterion);
                } else {
                    throw ex;
                }
            }
        }
        if (piCriterionFields.containsKey(fieldId)) {
            // Field was found in PiCriterion.
            if (fieldMatch != null) {
                // Throw exception only if we are trying to match on different values of the same field...
                if (!fieldMatch.equals(piCriterionFields.get(fieldId))) {
                    throw new PiTranslationException(format("Duplicate match field '%s': instance translated from criterion '%s' is different to " + "what found in PiCriterion.", fieldId, criterion.type()));
                }
                ignoredPiCriterionFields.add(fieldId);
            } else {
                fieldMatch = piCriterionFields.get(fieldId);
                fieldMatch = typeCheckFieldMatch(fieldMatch, fieldModel);
                usedPiCriterionFields.add(fieldId);
            }
        }
        fieldMatches.put(fieldId, fieldMatch);
    }
    // Check if all criteria have been translated.
    StringJoiner skippedCriteriaJoiner = new StringJoiner(", ");
    selector.criteria().stream().filter(c -> !c.type().equals(PROTOCOL_INDEPENDENT)).filter(c -> !translatedCriteria.contains(c) && !ignoredCriteria.contains(c)).forEach(c -> skippedCriteriaJoiner.add(c.type().name()));
    if (skippedCriteriaJoiner.length() > 0) {
        throw new PiTranslationException(format("The following criteria cannot be translated for table '%s': %s", tableModel.id(), skippedCriteriaJoiner.toString()));
    }
    // Check if all fields found in PiCriterion have been used.
    StringJoiner skippedPiFieldsJoiner = new StringJoiner(", ");
    piCriterionFields.keySet().stream().filter(k -> !usedPiCriterionFields.contains(k) && !ignoredPiCriterionFields.contains(k)).forEach(k -> skippedPiFieldsJoiner.add(k.id()));
    if (skippedPiFieldsJoiner.length() > 0) {
        throw new PiTranslationException(format("The following PiCriterion field matches are not supported in table '%s': %s", tableModel.id(), skippedPiFieldsJoiner.toString()));
    }
    return fieldMatches.values();
}
Also used : PiTableId(org.onosproject.net.pi.model.PiTableId) PiOptionalFieldMatch(org.onosproject.net.pi.runtime.PiOptionalFieldMatch) PiUtils.getInterpreterOrNull(org.onosproject.net.pi.impl.PiUtils.getInterpreterOrNull) PiPipeconf(org.onosproject.net.pi.model.PiPipeconf) ImmutableByteSequence(org.onlab.util.ImmutableByteSequence) LoggerFactory(org.slf4j.LoggerFactory) PiActionParam(org.onosproject.net.pi.runtime.PiActionParam) PiActionParamModel(org.onosproject.net.pi.model.PiActionParamModel) PiPipelineModel(org.onosproject.net.pi.model.PiPipelineModel) PiMatchKey(org.onosproject.net.pi.runtime.PiMatchKey) PiUtils.translateTableId(org.onosproject.net.pi.impl.PiUtils.translateTableId) ImmutableByteSequence.prefixOnes(org.onlab.util.ImmutableByteSequence.prefixOnes) TrafficSelector(org.onosproject.net.flow.TrafficSelector) PiInstruction(org.onosproject.net.flow.instructions.PiInstruction) PiTableModel(org.onosproject.net.pi.model.PiTableModel) PiCriterion(org.onosproject.net.flow.criteria.PiCriterion) Map(java.util.Map) PiTranslationException(org.onosproject.net.pi.service.PiTranslationException) PiExactFieldMatch(org.onosproject.net.pi.runtime.PiExactFieldMatch) PiFieldMatch(org.onosproject.net.pi.runtime.PiFieldMatch) Criterion(org.onosproject.net.flow.criteria.Criterion) TrafficTreatment(org.onosproject.net.flow.TrafficTreatment) PiTableAction(org.onosproject.net.pi.runtime.PiTableAction) PiPipelineInterpreter(org.onosproject.net.pi.model.PiPipelineInterpreter) Logger(org.slf4j.Logger) Device(org.onosproject.net.Device) PiActionModel(org.onosproject.net.pi.model.PiActionModel) Instruction(org.onosproject.net.flow.instructions.Instruction) PiMatchFieldModel(org.onosproject.net.pi.model.PiMatchFieldModel) Collection(java.util.Collection) PiRangeFieldMatch(org.onosproject.net.pi.runtime.PiRangeFieldMatch) Set(java.util.Set) PiMatchFieldId(org.onosproject.net.pi.model.PiMatchFieldId) Maps(com.google.common.collect.Maps) Sets(com.google.common.collect.Sets) PiMatchType(org.onosproject.net.pi.model.PiMatchType) String.format(java.lang.String.format) PiTernaryFieldMatch(org.onosproject.net.pi.runtime.PiTernaryFieldMatch) ByteSequenceTrimException(org.onlab.util.ImmutableByteSequence.ByteSequenceTrimException) PROTOCOL_INDEPENDENT(org.onosproject.net.flow.criteria.Criterion.Type.PROTOCOL_INDEPENDENT) PiAction(org.onosproject.net.pi.runtime.PiAction) PiTableEntry(org.onosproject.net.pi.runtime.PiTableEntry) CriterionTranslatorHelper.translateCriterion(org.onosproject.net.pi.impl.CriterionTranslatorHelper.translateCriterion) FlowRule(org.onosproject.net.flow.FlowRule) StringJoiner(java.util.StringJoiner) PiTableType(org.onosproject.net.pi.model.PiTableType) PiLpmFieldMatch(org.onosproject.net.pi.runtime.PiLpmFieldMatch) PiActionSet(org.onosproject.net.pi.runtime.PiActionSet) PiCriterion(org.onosproject.net.flow.criteria.PiCriterion) PiTranslationException(org.onosproject.net.pi.service.PiTranslationException) PiCriterion(org.onosproject.net.flow.criteria.PiCriterion) Criterion(org.onosproject.net.flow.criteria.Criterion) CriterionTranslatorHelper.translateCriterion(org.onosproject.net.pi.impl.CriterionTranslatorHelper.translateCriterion) PiMatchFieldId(org.onosproject.net.pi.model.PiMatchFieldId) PiFieldMatch(org.onosproject.net.pi.runtime.PiFieldMatch) PiMatchFieldModel(org.onosproject.net.pi.model.PiMatchFieldModel) Map(java.util.Map) StringJoiner(java.util.StringJoiner)

Example 7 with PiMatchFieldId

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

the class PiMatchFieldIdTest method testConstructionWithIndex.

/**
 * Checks the construction of a PiMatchFieldId object with index.
 */
@Test
public void testConstructionWithIndex() {
    final String name = IPV4_HEADER_NAME + DOT + DST_ADDR + "[1]";
    final PiMatchFieldId piMatchFieldId = PiMatchFieldId.of(name);
    assertThat(piMatchFieldId, is(notNullValue()));
    assertThat(piMatchFieldId.id(), is(name));
}
Also used : PiMatchFieldId(org.onosproject.net.pi.model.PiMatchFieldId) Test(org.junit.Test)

Example 8 with PiMatchFieldId

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

the class PiMatchFieldIdTest method testConstruction.

/**
 * Checks the construction of a PiMatchFieldId object.
 */
@Test
public void testConstruction() {
    final String name = IPV4_HEADER_NAME + DOT + DST_ADDR;
    final PiMatchFieldId piMatchFieldId = PiMatchFieldId.of(name);
    assertThat(piMatchFieldId, is(notNullValue()));
    assertThat(piMatchFieldId.id(), is(name));
}
Also used : PiMatchFieldId(org.onosproject.net.pi.model.PiMatchFieldId) Test(org.junit.Test)

Example 9 with PiMatchFieldId

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

the class PiTernaryFieldMatchTest method testConstruction.

/**
 * Checks the construction of a PiTernaryFieldMatch object.
 */
@Test
public void testConstruction() {
    final ImmutableByteSequence value = copyFrom(0x0a01010a);
    final ImmutableByteSequence mask = copyFrom(0x00ffffff);
    final PiMatchFieldId piMatchField = PiMatchFieldId.of(IPV4_HEADER_NAME + DOT + DST_ADDR);
    PiTernaryFieldMatch piTernaryFieldMatch = new PiTernaryFieldMatch(piMatchField, value, mask);
    assertThat(piTernaryFieldMatch, is(notNullValue()));
    assertThat(piTernaryFieldMatch.value(), is(value));
    assertThat(piTernaryFieldMatch.mask(), is(mask));
    assertThat(piTernaryFieldMatch.type(), is(PiMatchType.TERNARY));
}
Also used : PiMatchFieldId(org.onosproject.net.pi.model.PiMatchFieldId) ImmutableByteSequence(org.onlab.util.ImmutableByteSequence) Test(org.junit.Test)

Example 10 with PiMatchFieldId

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

the class PiOptionalFieldMatchTest method testConstruction.

/**
 * Checks the construction of a PiOptionalFieldMatch object.
 */
@Test
public void testConstruction() {
    final ImmutableByteSequence value = copyFrom(0x0806);
    final PiMatchFieldId piMatchField = PiMatchFieldId.of(ETH_HEADER_NAME + DOT + ETH_TYPE);
    PiOptionalFieldMatch piOptionalFieldMatch = new PiOptionalFieldMatch(piMatchField, value);
    assertThat(piOptionalFieldMatch, is(notNullValue()));
    assertThat(piOptionalFieldMatch.value(), is(value));
    assertThat(piOptionalFieldMatch.type(), is(PiMatchType.OPTIONAL));
}
Also used : PiMatchFieldId(org.onosproject.net.pi.model.PiMatchFieldId) ImmutableByteSequence(org.onlab.util.ImmutableByteSequence) PiConstantsTest(org.onosproject.net.pi.runtime.PiConstantsTest) Test(org.junit.Test)

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