use of org.onosproject.net.pi.runtime.PiTernaryFieldMatch 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.PiTernaryFieldMatch 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.PiTernaryFieldMatch in project onos by opennetworkinglab.
the class PiCriterionTranslatorsTest method testSctpPortCriterion.
@Test
public void testSctpPortCriterion() 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;
SctpPortCriterion criterion = (SctpPortCriterion) Criteria.matchSctpDst(value1);
PiExactFieldMatch exactMatch = (PiExactFieldMatch) translateCriterion(criterion, fieldId, EXACT, bitWidth);
SctpPortCriterion maskedCriterion = (SctpPortCriterion) Criteria.matchSctpDstMasked(value2, mask);
PiTernaryFieldMatch ternaryMatch = (PiTernaryFieldMatch) translateCriterion(maskedCriterion, fieldId, TERNARY, bitWidth);
assertThat(exactMatch.value().asReadOnlyBuffer().getShort(), is((short) criterion.sctpPort().toInt()));
assertThat(ternaryMatch.value().asReadOnlyBuffer().getShort(), is((short) maskedCriterion.sctpPort().toInt()));
assertThat(ternaryMatch.mask().asReadOnlyBuffer().getShort(), is((short) maskedCriterion.mask().toInt()));
}
use of org.onosproject.net.pi.runtime.PiTernaryFieldMatch in project onos by opennetworkinglab.
the class PiFlowRuleTranslatorImplTest method testTranslateFlowRules.
@Test
public void testTranslateFlowRules() throws Exception {
ApplicationId appId = new DefaultApplicationId(1, "test");
MacAddress ethDstMac = MacAddress.valueOf(random.nextLong());
MacAddress ethSrcMac = MacAddress.valueOf(random.nextLong());
short ethType = (short) (0x0000FFFF & random.nextInt());
short outPort = (short) random.nextInt(65);
short inPort = (short) random.nextInt(65);
int timeout = random.nextInt(100);
int priority = random.nextInt(100);
TrafficSelector matchInPort1 = DefaultTrafficSelector.builder().matchInPort(PortNumber.portNumber(inPort)).matchEthDst(ethDstMac).matchEthSrc(ethSrcMac).matchEthType(ethType).build();
TrafficSelector emptySelector = DefaultTrafficSelector.builder().build();
TrafficTreatment outPort2 = DefaultTrafficTreatment.builder().setOutput(PortNumber.portNumber(outPort)).build();
FlowRule rule1 = DefaultFlowRule.builder().forDevice(DEVICE_ID).forTable(INGRESS_TABLE0_CONTROL_TABLE0).fromApp(appId).withSelector(matchInPort1).withTreatment(outPort2).makeTemporary(timeout).withPriority(priority).build();
FlowRule rule2 = DefaultFlowRule.builder().forDevice(DEVICE_ID).forTable(INGRESS_TABLE0_CONTROL_TABLE0).fromApp(appId).withSelector(matchInPort1).withTreatment(outPort2).makeTemporary(timeout).withPriority(priority).build();
FlowRule defActionRule = DefaultFlowRule.builder().forDevice(DEVICE_ID).forTable(INGRESS_TABLE0_CONTROL_TABLE0).fromApp(appId).withSelector(emptySelector).withTreatment(outPort2).makeTemporary(timeout).withPriority(priority).build();
PiTableEntry entry1 = PiFlowRuleTranslatorImpl.translate(rule1, pipeconf, null);
PiTableEntry entry2 = PiFlowRuleTranslatorImpl.translate(rule2, pipeconf, null);
PiTableEntry defActionEntry = PiFlowRuleTranslatorImpl.translate(defActionRule, pipeconf, null);
// check equality, i.e. same rules must produce same entries
new EqualsTester().addEqualityGroup(rule1, rule2).addEqualityGroup(entry1, entry2).testEquals();
// parse values stored in entry1
PiTernaryFieldMatch inPortParam = (PiTernaryFieldMatch) entry1.matchKey().fieldMatch(HDR_STANDARD_METADATA_INGRESS_PORT).get();
PiTernaryFieldMatch ethDstParam = (PiTernaryFieldMatch) entry1.matchKey().fieldMatch(HDR_HDR_ETHERNET_DST_ADDR).get();
PiTernaryFieldMatch ethSrcParam = (PiTernaryFieldMatch) entry1.matchKey().fieldMatch(HDR_HDR_ETHERNET_SRC_ADDR).get();
PiTernaryFieldMatch ethTypeParam = (PiTernaryFieldMatch) entry1.matchKey().fieldMatch(HDR_HDR_ETHERNET_ETHER_TYPE).get();
Optional<Double> expectedTimeout = pipeconf.pipelineModel().table(INGRESS_TABLE0_CONTROL_TABLE0).get().supportsAging() ? Optional.of((double) rule1.timeout()) : Optional.empty();
// check that values stored in entry are the same used for the flow rule
assertThat("Incorrect inPort match param value", inPortParam.value().asReadOnlyBuffer().getShort(), is(equalTo(inPort)));
assertThat("Incorrect inPort match param mask", inPortParam.mask().asReadOnlyBuffer().getShort(), is(equalTo(IN_PORT_MASK)));
assertThat("Incorrect ethDestMac match param value", ethDstParam.value().asArray(), is(equalTo(ethDstMac.toBytes())));
assertThat("Incorrect ethDestMac match param mask", ethDstParam.mask().asArray(), is(equalTo(MacAddress.BROADCAST.toBytes())));
assertThat("Incorrect ethSrcMac match param value", ethSrcParam.value().asArray(), is(equalTo(ethSrcMac.toBytes())));
assertThat("Incorrect ethSrcMac match param mask", ethSrcParam.mask().asArray(), is(equalTo(MacAddress.BROADCAST.toBytes())));
assertThat("Incorrect ethType match param value", ethTypeParam.value().asReadOnlyBuffer().getShort(), is(equalTo(ethType)));
assertThat("Incorrect ethType match param mask", ethTypeParam.mask().asReadOnlyBuffer().getShort(), is(equalTo(ETH_TYPE_MASK)));
// FIXME: re-enable when P4Runtime priority handling will be moved out of transltion service
// see PiFlowRuleTranslatorImpl
// assertThat("Incorrect priority value",
// entry1.priority().get(), is(equalTo(MAX_PI_PRIORITY - rule1.priority())));
assertThat("Incorrect timeout value", entry1.timeout(), is(equalTo(expectedTimeout)));
assertThat("Match key should be empty", defActionEntry.matchKey(), is(equalTo(PiMatchKey.EMPTY)));
assertThat("Priority should not be set", !defActionEntry.priority().isPresent());
}
use of org.onosproject.net.pi.runtime.PiTernaryFieldMatch in project onos by opennetworkinglab.
the class PiCriteriaTest method testTernaryMatchPiMethod.
/**
* Test the TernaryMatchPi method.
*/
@Test
public void testTernaryMatchPiMethod() {
Criterion matchPiBytes = PiCriterion.builder().matchTernary(ipv4MatchFieldId, matchTernaryBytes1, matchTernaryMaskBytes).build();
PiCriterion piCriterionBytes = checkAndConvert(matchPiBytes, Criterion.Type.PROTOCOL_INDEPENDENT, PiCriterion.class);
PiFieldMatch expectedMatchBytes = new PiTernaryFieldMatch(ipv4MatchFieldId, copyFrom(matchTernaryBytes1), copyFrom(matchTernaryMaskBytes));
assertThat(piCriterionBytes.fieldMatches().iterator().next(), is(expectedMatchBytes));
Criterion matchPiShort = PiCriterion.builder().matchTernary(ipv4MatchFieldId, matchTernaryShort1, matchTernaryMaskShort).build();
PiCriterion piCriterionShort = checkAndConvert(matchPiShort, Criterion.Type.PROTOCOL_INDEPENDENT, PiCriterion.class);
PiFieldMatch expectedMatchShort = new PiTernaryFieldMatch(ipv4MatchFieldId, copyFrom(matchTernaryShort1), copyFrom(matchTernaryMaskShort));
assertThat(piCriterionShort.fieldMatches().iterator().next(), is(expectedMatchShort));
Criterion matchPiInt = PiCriterion.builder().matchTernary(ipv4MatchFieldId, matchTernaryInt1, matchTernaryMaskInt).build();
PiCriterion piCriterionInt = checkAndConvert(matchPiInt, Criterion.Type.PROTOCOL_INDEPENDENT, PiCriterion.class);
PiFieldMatch expectedMatchInt = new PiTernaryFieldMatch(ipv4MatchFieldId, copyFrom(matchTernaryInt1), copyFrom(matchTernaryMaskInt));
assertThat(piCriterionInt.fieldMatches().iterator().next(), is(expectedMatchInt));
Criterion matchPiLong = PiCriterion.builder().matchTernary(ipv4MatchFieldId, matchTernaryLong1, matchTernaryMaskLong).build();
PiCriterion piCriterionLong = checkAndConvert(matchPiLong, Criterion.Type.PROTOCOL_INDEPENDENT, PiCriterion.class);
PiFieldMatch expectedMatchLong = new PiTernaryFieldMatch(ipv4MatchFieldId, copyFrom(matchTernaryLong1), copyFrom(matchTernaryMaskLong));
assertThat(piCriterionLong.fieldMatches().iterator().next(), is(expectedMatchLong));
}
Aggregations