use of org.onosproject.net.pi.runtime.PiFieldMatch 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.PiFieldMatch in project onos by opennetworkinglab.
the class PiCriteriaTest method testRangeMatchPiMethod.
/**
* Test the RangeMatchPi method.
*/
@Test
public void testRangeMatchPiMethod() {
Criterion matchPiBytes = PiCriterion.builder().matchRange(ipv4MatchFieldId, matchRangeBytes1, matchRangeHighBytes).build();
PiCriterion piCriterionBytes = checkAndConvert(matchPiBytes, Criterion.Type.PROTOCOL_INDEPENDENT, PiCriterion.class);
PiFieldMatch expectedMatchBytes = new PiRangeFieldMatch(ipv4MatchFieldId, copyFrom(matchRangeBytes1), copyFrom(matchRangeHighBytes));
assertThat(piCriterionBytes.fieldMatches().iterator().next(), is(expectedMatchBytes));
Criterion matchPiShort = PiCriterion.builder().matchRange(ipv4MatchFieldId, matchRangeShort1, matchRangeHighShort).build();
PiCriterion piCriterionShort = checkAndConvert(matchPiShort, Criterion.Type.PROTOCOL_INDEPENDENT, PiCriterion.class);
PiFieldMatch expectedMatchShort = new PiRangeFieldMatch(ipv4MatchFieldId, copyFrom(matchRangeShort1), copyFrom(matchRangeHighShort));
assertThat(piCriterionShort.fieldMatches().iterator().next(), is(expectedMatchShort));
Criterion matchPiInt = PiCriterion.builder().matchRange(ipv4MatchFieldId, matchRangeInt1, matchRangeHighInt).build();
PiCriterion piCriterionInt = checkAndConvert(matchPiInt, Criterion.Type.PROTOCOL_INDEPENDENT, PiCriterion.class);
PiFieldMatch expectedMatchInt = new PiRangeFieldMatch(ipv4MatchFieldId, copyFrom(matchRangeInt1), copyFrom(matchRangeHighInt));
assertThat(piCriterionInt.fieldMatches().iterator().next(), is(expectedMatchInt));
Criterion matchPiLong = PiCriterion.builder().matchRange(ipv4MatchFieldId, matchRangeLong1, matchRangeHighLong).build();
PiCriterion piCriterionLong = checkAndConvert(matchPiLong, Criterion.Type.PROTOCOL_INDEPENDENT, PiCriterion.class);
PiFieldMatch expectedMatchLong = new PiRangeFieldMatch(ipv4MatchFieldId, copyFrom(matchRangeLong1), copyFrom(matchRangeHighLong));
assertThat(piCriterionLong.fieldMatches().iterator().next(), is(expectedMatchLong));
}
use of org.onosproject.net.pi.runtime.PiFieldMatch in project onos by opennetworkinglab.
the class CriterionCodecTest method matchPiTypeDecodingTest.
/**
* Tests protocol-independent type criterion decoding.
*/
@Test
public void matchPiTypeDecodingTest() throws IOException {
Criterion criterion = getCriterion("PiCriterion.json");
Assert.assertThat(criterion.type(), is(Criterion.Type.PROTOCOL_INDEPENDENT));
Collection<PiFieldMatch> piFieldMatches = ((PiCriterion) criterion).fieldMatches();
for (PiFieldMatch piFieldMatch : piFieldMatches) {
switch(piFieldMatch.type()) {
case EXACT:
Assert.assertThat(piFieldMatch.fieldId().id(), is("ingress_port"));
Assert.assertThat(((PiExactFieldMatch) piFieldMatch).value(), is(copyFrom((byte) 0x10)));
break;
case LPM:
Assert.assertThat(piFieldMatch.fieldId().id(), is("src_addr"));
Assert.assertThat(((PiLpmFieldMatch) piFieldMatch).value(), is(copyFrom(0xa010101)));
Assert.assertThat(((PiLpmFieldMatch) piFieldMatch).prefixLength(), is(24));
break;
case TERNARY:
Assert.assertThat(piFieldMatch.fieldId().id(), is("dst_addr"));
Assert.assertThat(((PiTernaryFieldMatch) piFieldMatch).value(), is(copyFrom(0xa010101)));
Assert.assertThat(((PiTernaryFieldMatch) piFieldMatch).mask(), is(copyFrom(0xfffffff)));
break;
case RANGE:
Assert.assertThat(piFieldMatch.fieldId().id(), is("egress_port"));
Assert.assertThat(((PiRangeFieldMatch) piFieldMatch).highValue(), is(copyFrom((byte) 0x20)));
Assert.assertThat(((PiRangeFieldMatch) piFieldMatch).lowValue(), is(copyFrom((byte) 0x10)));
break;
case OPTIONAL:
Assert.assertThat(piFieldMatch.fieldId().id(), is("eth_dst"));
Assert.assertThat(((PiOptionalFieldMatch) piFieldMatch).value(), is(copyFrom(new byte[] { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 })));
break;
default:
Assert.fail();
}
}
}
use of org.onosproject.net.pi.runtime.PiFieldMatch 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.PiFieldMatch in project onos by opennetworkinglab.
the class PiFlowRuleTranslatorImpl method translate.
/**
* Returns a PI table entry equivalent to the given flow rule, for the given
* pipeconf and device.
*
* @param rule flow rule
* @param pipeconf pipeconf
* @param device device
* @return PI table entry
* @throws PiTranslationException if the flow rule cannot be translated
*/
static PiTableEntry translate(FlowRule rule, PiPipeconf pipeconf, Device device) throws PiTranslationException {
PiPipelineModel pipelineModel = pipeconf.pipelineModel();
// Retrieve interpreter, if any.
final PiPipelineInterpreter interpreter = getInterpreterOrNull(device, pipeconf);
// Get table model.
final PiTableId piTableId = translateTableId(rule.table(), interpreter);
final PiTableModel tableModel = getTableModel(piTableId, pipelineModel);
// Translate selector.
final PiMatchKey piMatchKey;
final boolean needPriority;
if (rule.selector().criteria().isEmpty()) {
piMatchKey = PiMatchKey.EMPTY;
needPriority = false;
} else {
final Collection<PiFieldMatch> fieldMatches = translateFieldMatches(interpreter, rule.selector(), tableModel);
piMatchKey = PiMatchKey.builder().addFieldMatches(fieldMatches).build();
// FIXME: P4Runtime limit
// Need to ignore priority if no TCAM lookup match field
needPriority = tableModel.matchFields().stream().anyMatch(match -> match.matchType() == PiMatchType.TERNARY || match.matchType() == PiMatchType.RANGE || match.matchType() == PiMatchType.OPTIONAL);
}
// Translate treatment.
final PiTableAction piTableAction = translateTreatment(rule.treatment(), interpreter, piTableId, pipelineModel);
// Build PI entry.
final PiTableEntry.Builder tableEntryBuilder = PiTableEntry.builder();
tableEntryBuilder.forTable(piTableId).withMatchKey(piMatchKey);
if (piTableAction != null) {
tableEntryBuilder.withAction(piTableAction);
}
if (needPriority) {
// FIXME: move priority check to P4Runtime driver.
final int newPriority;
if (rule.priority() > MAX_PI_PRIORITY) {
log.warn("Flow rule priority too big, setting translated priority to max value {}: {}", MAX_PI_PRIORITY, rule);
newPriority = MAX_PI_PRIORITY;
} else {
newPriority = MIN_PI_PRIORITY + rule.priority();
}
tableEntryBuilder.withPriority(newPriority);
}
if (!rule.isPermanent()) {
if (tableModel.supportsAging()) {
tableEntryBuilder.withTimeout(rule.timeout());
} else {
log.debug("Flow rule is temporary, but table '{}' doesn't support " + "aging, translating to permanent.", tableModel.id());
}
}
return tableEntryBuilder.build();
}
Aggregations