use of org.onosproject.net.pi.runtime.PiOptionalFieldMatch in project onos by opennetworkinglab.
the class PiCriteriaTest method testOptionalMatchPiMethod.
/**
* Test the OptionalMatchPi method.
*/
@Test
public void testOptionalMatchPiMethod() {
Criterion matchPiBytes = PiCriterion.builder().matchOptional(ethMatchFieldId, matchExactBytes1).build();
PiCriterion piCriterionBytes = checkAndConvert(matchPiBytes, Criterion.Type.PROTOCOL_INDEPENDENT, PiCriterion.class);
PiFieldMatch expectedMatchBytes = new PiOptionalFieldMatch(ethMatchFieldId, copyFrom(matchExactBytes1));
assertThat(piCriterionBytes.fieldMatches().iterator().next(), is(expectedMatchBytes));
Criterion matchPiShort = PiCriterion.builder().matchOptional(ethMatchFieldId, matchExactShort1).build();
PiCriterion piCriterionShort = checkAndConvert(matchPiShort, Criterion.Type.PROTOCOL_INDEPENDENT, PiCriterion.class);
PiFieldMatch expectedMatchShort = new PiOptionalFieldMatch(ethMatchFieldId, copyFrom(matchExactShort1));
assertThat(piCriterionShort.fieldMatches().iterator().next(), is(expectedMatchShort));
Criterion matchPiInt = PiCriterion.builder().matchOptional(ethMatchFieldId, matchExactInt1).build();
PiCriterion piCriterionInt = checkAndConvert(matchPiInt, Criterion.Type.PROTOCOL_INDEPENDENT, PiCriterion.class);
PiFieldMatch expectedMatchInt = new PiOptionalFieldMatch(ethMatchFieldId, copyFrom(matchExactInt1));
assertThat(piCriterionInt.fieldMatches().iterator().next(), is(expectedMatchInt));
Criterion matchPiLong = PiCriterion.builder().matchOptional(ethMatchFieldId, matchExactLong1).build();
PiCriterion piCriterionLong = checkAndConvert(matchPiLong, Criterion.Type.PROTOCOL_INDEPENDENT, PiCriterion.class);
PiFieldMatch expectedMatchLong = new PiOptionalFieldMatch(ethMatchFieldId, copyFrom(matchExactLong1));
assertThat(piCriterionLong.fieldMatches().iterator().next(), is(expectedMatchLong));
}
use of org.onosproject.net.pi.runtime.PiOptionalFieldMatch in project onos by opennetworkinglab.
the class CriterionJsonMatcher method matchCriterion.
/**
* Matches a protocol-independent Type criterion object.
*
* @param criterion criterion to match
* @return true if the JSON matches the criterion, false otherwise.
*/
private boolean matchCriterion(PiCriterion criterion) {
Collection<PiFieldMatch> piFieldMatches = criterion.fieldMatches();
JsonNode jsonMathes = jsonCriterion.get("matches");
if (!jsonMathes.isArray()) {
return false;
}
for (JsonNode matchNode : jsonMathes) {
for (PiFieldMatch fieldMatch : piFieldMatches) {
if (!Objects.equals(matchNode.get("field").textValue(), fieldMatch.fieldId().id())) {
description.appendText("match field was " + fieldMatch.fieldId().id());
return false;
}
if (!Objects.equals(matchNode.get("match").textValue(), fieldMatch.type().name().toLowerCase())) {
description.appendText("match type was " + fieldMatch.type().name().toLowerCase());
return false;
}
switch(fieldMatch.type()) {
case EXACT:
if (!Objects.equals(copyFrom(HexString.fromHexString(matchNode.get("value").textValue(), null)), ((PiExactFieldMatch) fieldMatch).value())) {
description.appendText("match value was " + ((PiExactFieldMatch) fieldMatch).value());
return false;
}
break;
case LPM:
if (!Objects.equals(copyFrom(HexString.fromHexString(matchNode.get("value").textValue(), null)), ((PiLpmFieldMatch) fieldMatch).value())) {
description.appendText("match value was " + ((PiLpmFieldMatch) fieldMatch).value());
return false;
}
if (!Objects.equals(matchNode.get("prefixLength").intValue(), ((PiLpmFieldMatch) fieldMatch).prefixLength())) {
description.appendText("match prefix was " + ((PiLpmFieldMatch) fieldMatch).prefixLength());
return false;
}
break;
case TERNARY:
if (!Objects.equals(copyFrom(HexString.fromHexString(matchNode.get("value").textValue(), null)), ((PiTernaryFieldMatch) fieldMatch).value())) {
description.appendText("match value was " + ((PiTernaryFieldMatch) fieldMatch).value());
return false;
}
if (!Objects.equals(copyFrom(HexString.fromHexString(matchNode.get("mask").textValue(), null)), ((PiTernaryFieldMatch) fieldMatch).mask())) {
description.appendText("match mask was " + ((PiTernaryFieldMatch) fieldMatch).mask());
return false;
}
break;
case RANGE:
if (!Objects.equals(copyFrom(HexString.fromHexString(matchNode.get("highValue").textValue(), null)), ((PiRangeFieldMatch) fieldMatch).highValue())) {
description.appendText("match high value was " + ((PiRangeFieldMatch) fieldMatch).highValue());
return false;
}
if (!Objects.equals(copyFrom(HexString.fromHexString(matchNode.get("lowValue").textValue(), null)), ((PiRangeFieldMatch) fieldMatch).lowValue())) {
description.appendText("match low value was " + ((PiRangeFieldMatch) fieldMatch).lowValue());
return false;
}
break;
case OPTIONAL:
if (!Objects.equals(copyFrom(HexString.fromHexString(matchNode.get("value").textValue(), null)), ((PiOptionalFieldMatch) fieldMatch).value())) {
description.appendText("match value was " + ((PiOptionalFieldMatch) fieldMatch).value());
return false;
}
break;
default:
description.appendText("match type was " + fieldMatch.type().name().toLowerCase());
return false;
}
}
}
return true;
}
use of org.onosproject.net.pi.runtime.PiOptionalFieldMatch in project onos by opennetworkinglab.
the class CriterionTranslatorHelper method translateCriterion.
/**
* Translates a given criterion instance to a PiFieldMatch with the given id, match type, and bit-width.
*
* @param fieldId PI match field identifier
* @param criterion criterion
* @param matchType match type
* @param bitWidth size of the field match in bits
* @return a PI field match
* @throws PiTranslationException if the criterion cannot be translated (see exception message)
*/
static PiFieldMatch translateCriterion(Criterion criterion, PiMatchFieldId fieldId, PiMatchType matchType, int bitWidth) throws PiTranslationException {
if (!TRANSLATORS.containsKey(criterion.getClass())) {
throw new PiTranslationException(format("Translation of criterion class %s is not implemented.", criterion.getClass().getSimpleName()));
}
try {
final CriterionTranslator translator = TRANSLATORS.get(criterion.getClass()).newInstance();
translator.init(criterion, bitWidth);
switch(matchType) {
case EXACT:
return new PiExactFieldMatch(fieldId, translator.exactMatch());
case OPTIONAL:
return new PiOptionalFieldMatch(fieldId, translator.exactMatch());
case TERNARY:
final Pair<ImmutableByteSequence, ImmutableByteSequence> tp = translator.ternaryMatch();
return new PiTernaryFieldMatch(fieldId, tp.getLeft(), tp.getRight());
case LPM:
final Pair<ImmutableByteSequence, Integer> lp = translator.lpmMatch();
return new PiLpmFieldMatch(fieldId, lp.getLeft(), lp.getRight());
default:
throw new PiTranslationException(format("Translation of criterion %s (%s class) to match type %s is not implemented.", criterion.type().name(), criterion.getClass().getSimpleName(), matchType.name()));
}
} catch (ByteSequenceTrimException e) {
throw new PiTranslationException(format("Size mismatch for criterion %s: %s", criterion.type(), e.getMessage()));
} catch (CriterionTranslatorException e) {
throw new PiTranslationException(format("Unable to translate criterion %s: %s", criterion.type(), e.getMessage()));
} catch (InstantiationException | IllegalAccessException e) {
// Was not able to instantiate the criterion translator.
throw new IllegalStateException(e);
}
}
use of org.onosproject.net.pi.runtime.PiOptionalFieldMatch 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()));
}
}
use of org.onosproject.net.pi.runtime.PiOptionalFieldMatch 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 = ByteString.copyFrom(fieldMatch.value().asReadOnlyBuffer());
if (!isSdnString) {
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().asReadOnlyBuffer());
ByteString ternaryMask = ByteString.copyFrom(ternaryMatch.mask().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().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().asReadOnlyBuffer());
ByteString rangeLowValue = ByteString.copyFrom(rangeMatch.lowValue().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 = ByteString.copyFrom(optionalMatch.value().asReadOnlyBuffer());
if (!isSdnString) {
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()));
}
}
Aggregations