Search in sources :

Example 6 with PiTernaryFieldMatch

use of org.onosproject.net.pi.runtime.PiTernaryFieldMatch in project onos by opennetworkinglab.

the class PiFlowRuleTranslatorImpl method typeCheckFieldMatch.

private static PiFieldMatch typeCheckFieldMatch(PiFieldMatch fieldMatch, PiMatchFieldModel fieldModel) throws PiTranslationException {
    // Check parameter type and size
    if (!fieldModel.matchType().equals(fieldMatch.type())) {
        throw new PiTranslationException(format("Wrong match type for field '%s', expected %s, but found %s", fieldMatch.fieldId(), fieldModel.matchType().name(), fieldMatch.type().name()));
    }
    // Check if the arbitrary bit width is supported
    if (!fieldModel.hasBitWidth() && !fieldModel.matchType().equals(PiMatchType.EXACT) && !fieldModel.matchType().equals(PiMatchType.OPTIONAL)) {
        throw new PiTranslationException(format("Arbitrary bit width for field '%s' and match type %s is not supported", fieldMatch.fieldId(), fieldModel.matchType().name()));
    }
    int modelBitWidth = fieldModel.bitWidth();
    try {
        switch(fieldModel.matchType()) {
            case EXACT:
                PiExactFieldMatch exactField = (PiExactFieldMatch) fieldMatch;
                return new PiExactFieldMatch(fieldMatch.fieldId(), fieldModel.hasBitWidth() ? exactField.value().fit(modelBitWidth) : exactField.value());
            case TERNARY:
                PiTernaryFieldMatch ternField = (PiTernaryFieldMatch) fieldMatch;
                ImmutableByteSequence ternMask = ternField.mask().fit(modelBitWidth);
                ImmutableByteSequence ternValue = ternField.value().fit(modelBitWidth).bitwiseAnd(ternMask);
                return new PiTernaryFieldMatch(fieldMatch.fieldId(), ternValue, ternMask);
            case LPM:
                PiLpmFieldMatch lpmfield = (PiLpmFieldMatch) fieldMatch;
                if (lpmfield.prefixLength() > modelBitWidth) {
                    throw new PiTranslationException(format("Invalid prefix length for LPM field '%s', found %d but field has bit-width %d", fieldMatch.fieldId(), lpmfield.prefixLength(), modelBitWidth));
                }
                ImmutableByteSequence lpmValue = lpmfield.value().fit(modelBitWidth);
                ImmutableByteSequence lpmMask = prefixOnes(lpmValue.size(), lpmfield.prefixLength());
                lpmValue = lpmValue.bitwiseAnd(lpmMask);
                return new PiLpmFieldMatch(fieldMatch.fieldId(), lpmValue, lpmfield.prefixLength());
            case RANGE:
                return new PiRangeFieldMatch(fieldMatch.fieldId(), ((PiRangeFieldMatch) fieldMatch).lowValue().fit(modelBitWidth), ((PiRangeFieldMatch) fieldMatch).highValue().fit(modelBitWidth));
            case OPTIONAL:
                PiOptionalFieldMatch optionalField = (PiOptionalFieldMatch) fieldMatch;
                return new PiOptionalFieldMatch(fieldMatch.fieldId(), fieldModel.hasBitWidth() ? optionalField.value().fit(modelBitWidth) : optionalField.value());
            default:
                // Should never be here.
                throw new IllegalArgumentException("Unrecognized match type " + fieldModel.matchType().name());
        }
    } catch (ByteSequenceTrimException e) {
        throw new PiTranslationException(format("Size mismatch for field %s: %s", fieldMatch.fieldId(), e.getMessage()));
    }
}
Also used : PiRangeFieldMatch(org.onosproject.net.pi.runtime.PiRangeFieldMatch) PiOptionalFieldMatch(org.onosproject.net.pi.runtime.PiOptionalFieldMatch) PiExactFieldMatch(org.onosproject.net.pi.runtime.PiExactFieldMatch) PiTernaryFieldMatch(org.onosproject.net.pi.runtime.PiTernaryFieldMatch) PiTranslationException(org.onosproject.net.pi.service.PiTranslationException) ByteSequenceTrimException(org.onlab.util.ImmutableByteSequence.ByteSequenceTrimException) ImmutableByteSequence(org.onlab.util.ImmutableByteSequence) PiLpmFieldMatch(org.onosproject.net.pi.runtime.PiLpmFieldMatch)

Example 7 with PiTernaryFieldMatch

use of org.onosproject.net.pi.runtime.PiTernaryFieldMatch in project onos by opennetworkinglab.

the class FieldMatchCodec method encode.

@Override
public P4RuntimeOuterClass.FieldMatch encode(PiFieldMatch piFieldMatch, P4InfoOuterClass.Preamble tablePreamble, PiPipeconf pipeconf, P4InfoBrowser browser) throws CodecException, P4InfoBrowser.NotFoundException {
    P4RuntimeOuterClass.FieldMatch.Builder messageBuilder = P4RuntimeOuterClass.FieldMatch.newBuilder();
    // FIXME: check how field names for stacked headers are constructed in P4Runtime.
    String fieldName = piFieldMatch.fieldId().id();
    P4InfoOuterClass.MatchField matchFieldInfo = browser.matchFields(tablePreamble.getId()).getByName(fieldName);
    String entityName = format("field match '%s' of table '%s'", matchFieldInfo.getName(), tablePreamble.getName());
    int fieldId = matchFieldInfo.getId();
    int fieldBitwidth = matchFieldInfo.getBitwidth();
    boolean isSdnString = browser.isTypeString(matchFieldInfo.getTypeName());
    messageBuilder.setFieldId(fieldId);
    switch(piFieldMatch.type()) {
        case EXACT:
            PiExactFieldMatch fieldMatch = (PiExactFieldMatch) piFieldMatch;
            ByteString exactValue;
            if (isSdnString) {
                exactValue = ByteString.copyFrom(fieldMatch.value().asReadOnlyBuffer());
            } else {
                exactValue = ByteString.copyFrom(fieldMatch.value().canonical().asReadOnlyBuffer());
                assertSize(VALUE_OF_PREFIX + entityName, exactValue, fieldBitwidth);
            }
            return messageBuilder.setExact(P4RuntimeOuterClass.FieldMatch.Exact.newBuilder().setValue(exactValue).build()).build();
        case TERNARY:
            PiTernaryFieldMatch ternaryMatch = (PiTernaryFieldMatch) piFieldMatch;
            ByteString ternaryValue = ByteString.copyFrom(ternaryMatch.value().canonical().asReadOnlyBuffer());
            ByteString ternaryMask = ByteString.copyFrom(ternaryMatch.mask().canonical().asReadOnlyBuffer());
            if (isSdnString) {
                sdnStringUnsupported(entityName, piFieldMatch.type());
            }
            assertSize(VALUE_OF_PREFIX + entityName, ternaryValue, fieldBitwidth);
            assertSize(MASK_OF_PREFIX + entityName, ternaryMask, fieldBitwidth);
            return messageBuilder.setTernary(P4RuntimeOuterClass.FieldMatch.Ternary.newBuilder().setValue(ternaryValue).setMask(ternaryMask).build()).build();
        case LPM:
            PiLpmFieldMatch lpmMatch = (PiLpmFieldMatch) piFieldMatch;
            ByteString lpmValue = ByteString.copyFrom(lpmMatch.value().canonical().asReadOnlyBuffer());
            int lpmPrefixLen = lpmMatch.prefixLength();
            if (isSdnString) {
                sdnStringUnsupported(entityName, piFieldMatch.type());
            }
            assertSize(VALUE_OF_PREFIX + entityName, lpmValue, fieldBitwidth);
            assertPrefixLen(entityName, lpmPrefixLen, fieldBitwidth);
            return messageBuilder.setLpm(P4RuntimeOuterClass.FieldMatch.LPM.newBuilder().setValue(lpmValue).setPrefixLen(lpmPrefixLen).build()).build();
        case RANGE:
            PiRangeFieldMatch rangeMatch = (PiRangeFieldMatch) piFieldMatch;
            ByteString rangeHighValue = ByteString.copyFrom(rangeMatch.highValue().canonical().asReadOnlyBuffer());
            ByteString rangeLowValue = ByteString.copyFrom(rangeMatch.lowValue().canonical().asReadOnlyBuffer());
            if (isSdnString) {
                sdnStringUnsupported(entityName, piFieldMatch.type());
            }
            assertSize(HIGH_RANGE_VALUE_OF_PREFIX + entityName, rangeHighValue, fieldBitwidth);
            assertSize(LOW_RANGE_VALUE_OF_PREFIX + entityName, rangeLowValue, fieldBitwidth);
            return messageBuilder.setRange(P4RuntimeOuterClass.FieldMatch.Range.newBuilder().setHigh(rangeHighValue).setLow(rangeLowValue).build()).build();
        case OPTIONAL:
            PiOptionalFieldMatch optionalMatch = (PiOptionalFieldMatch) piFieldMatch;
            ByteString optionalValue;
            if (isSdnString) {
                optionalValue = ByteString.copyFrom(optionalMatch.value().asReadOnlyBuffer());
            } else {
                optionalValue = ByteString.copyFrom(optionalMatch.value().canonical().asReadOnlyBuffer());
                assertSize(VALUE_OF_PREFIX + entityName, optionalValue, fieldBitwidth);
            }
            return messageBuilder.setOptional(P4RuntimeOuterClass.FieldMatch.Optional.newBuilder().setValue(optionalValue).build()).build();
        default:
            throw new CodecException(format("Building of match type %s not implemented", piFieldMatch.type()));
    }
}
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) ByteString(com.google.protobuf.ByteString) 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) PiExactFieldMatch(org.onosproject.net.pi.runtime.PiExactFieldMatch)

Example 8 with PiTernaryFieldMatch

use of org.onosproject.net.pi.runtime.PiTernaryFieldMatch 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 9 with PiTernaryFieldMatch

use of org.onosproject.net.pi.runtime.PiTernaryFieldMatch in project onos by opennetworkinglab.

the class PiCriterionTranslatorsTest method testTcpPortCriterion.

@Test
public void testTcpPortCriterion() throws Exception {
    TpPort value1 = TpPort.tpPort(random.nextInt(1 << 16));
    TpPort value2 = TpPort.tpPort(random.nextInt(1 << 16));
    TpPort mask = TpPort.tpPort(random.nextInt(1 << 16));
    int bitWidth = 16;
    TcpPortCriterion criterion = (TcpPortCriterion) Criteria.matchTcpDst(value1);
    PiExactFieldMatch exactMatch = (PiExactFieldMatch) translateCriterion(criterion, fieldId, EXACT, bitWidth);
    TcpPortCriterion maskedCriterion = (TcpPortCriterion) Criteria.matchTcpDstMasked(value2, mask);
    PiTernaryFieldMatch ternaryMatch = (PiTernaryFieldMatch) translateCriterion(maskedCriterion, fieldId, TERNARY, bitWidth);
    assertThat(exactMatch.value().asReadOnlyBuffer().getShort(), is((short) criterion.tcpPort().toInt()));
    assertThat(ternaryMatch.value().asReadOnlyBuffer().getShort(), is((short) maskedCriterion.tcpPort().toInt()));
    assertThat(ternaryMatch.mask().asReadOnlyBuffer().getShort(), is((short) maskedCriterion.mask().toInt()));
}
Also used : TcpPortCriterion(org.onosproject.net.flow.criteria.TcpPortCriterion) TpPort(org.onlab.packet.TpPort) PiExactFieldMatch(org.onosproject.net.pi.runtime.PiExactFieldMatch) PiTernaryFieldMatch(org.onosproject.net.pi.runtime.PiTernaryFieldMatch) Test(org.junit.Test)

Example 10 with PiTernaryFieldMatch

use of org.onosproject.net.pi.runtime.PiTernaryFieldMatch in project onos by opennetworkinglab.

the class PiCriterionTranslatorsTest method testLpmToTernaryTranslation.

@Test
public void testLpmToTernaryTranslation() throws Exception {
    IpPrefix ipPrefix = IpPrefix.valueOf("10.0.0.1/23");
    int bitWidth = ipPrefix.address().toOctets().length * Byte.SIZE;
    IPCriterion criterion = (IPCriterion) Criteria.matchIPDst(ipPrefix);
    PiTernaryFieldMatch ternaryMatch = (PiTernaryFieldMatch) translateCriterion(criterion, fieldId, TERNARY, bitWidth);
    ImmutableByteSequence expectedMask = ImmutableByteSequence.prefixOnes(Integer.BYTES, 23);
    ImmutableByteSequence expectedValue = ImmutableByteSequence.copyFrom(ipPrefix.address().toOctets());
    assertThat(ternaryMatch.mask(), is(expectedMask));
    assertThat(ternaryMatch.value(), is(expectedValue));
}
Also used : IpPrefix(org.onlab.packet.IpPrefix) IPCriterion(org.onosproject.net.flow.criteria.IPCriterion) PiTernaryFieldMatch(org.onosproject.net.pi.runtime.PiTernaryFieldMatch) ImmutableByteSequence(org.onlab.util.ImmutableByteSequence) Test(org.junit.Test)

Aggregations

PiTernaryFieldMatch (org.onosproject.net.pi.runtime.PiTernaryFieldMatch)13 PiExactFieldMatch (org.onosproject.net.pi.runtime.PiExactFieldMatch)10 Test (org.junit.Test)7 PiLpmFieldMatch (org.onosproject.net.pi.runtime.PiLpmFieldMatch)6 PiOptionalFieldMatch (org.onosproject.net.pi.runtime.PiOptionalFieldMatch)5 ImmutableByteSequence (org.onlab.util.ImmutableByteSequence)4 PiRangeFieldMatch (org.onosproject.net.pi.runtime.PiRangeFieldMatch)4 TpPort (org.onlab.packet.TpPort)3 PiFieldMatch (org.onosproject.net.pi.runtime.PiFieldMatch)3 ByteString (com.google.protobuf.ByteString)2 MacAddress (org.onlab.packet.MacAddress)2 ByteSequenceTrimException (org.onlab.util.ImmutableByteSequence.ByteSequenceTrimException)2 P4InfoOuterClass (p4.config.v1.P4InfoOuterClass)2 JsonNode (com.fasterxml.jackson.databind.JsonNode)1 EqualsTester (com.google.common.testing.EqualsTester)1 Ip4Prefix (org.onlab.packet.Ip4Prefix)1 IpPrefix (org.onlab.packet.IpPrefix)1 ApplicationId (org.onosproject.core.ApplicationId)1 DefaultApplicationId (org.onosproject.core.DefaultApplicationId)1 UpfApplication (org.onosproject.net.behaviour.upf.UpfApplication)1