Add Optional match fields support to PI subsystem
Change-Id: Ic458f59cab98340e40c04a0ad060d3c725ac5dbb
diff --git a/core/net/src/main/java/org/onosproject/net/pi/impl/CriterionTranslatorHelper.java b/core/net/src/main/java/org/onosproject/net/pi/impl/CriterionTranslatorHelper.java
index 4b64b0c..a6b213b 100644
--- a/core/net/src/main/java/org/onosproject/net/pi/impl/CriterionTranslatorHelper.java
+++ b/core/net/src/main/java/org/onosproject/net/pi/impl/CriterionTranslatorHelper.java
@@ -85,6 +85,7 @@
import org.onosproject.net.pi.runtime.PiExactFieldMatch;
import org.onosproject.net.pi.runtime.PiFieldMatch;
import org.onosproject.net.pi.runtime.PiLpmFieldMatch;
+import org.onosproject.net.pi.runtime.PiOptionalFieldMatch;
import org.onosproject.net.pi.runtime.PiTernaryFieldMatch;
import org.onosproject.net.pi.service.PiTranslationException;
@@ -163,6 +164,8 @@
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());
diff --git a/core/net/src/main/java/org/onosproject/net/pi/impl/PiFlowRuleTranslatorImpl.java b/core/net/src/main/java/org/onosproject/net/pi/impl/PiFlowRuleTranslatorImpl.java
index 8350549..f399508 100644
--- a/core/net/src/main/java/org/onosproject/net/pi/impl/PiFlowRuleTranslatorImpl.java
+++ b/core/net/src/main/java/org/onosproject/net/pi/impl/PiFlowRuleTranslatorImpl.java
@@ -44,6 +44,7 @@
import org.onosproject.net.pi.runtime.PiFieldMatch;
import org.onosproject.net.pi.runtime.PiLpmFieldMatch;
import org.onosproject.net.pi.runtime.PiMatchKey;
+import org.onosproject.net.pi.runtime.PiOptionalFieldMatch;
import org.onosproject.net.pi.runtime.PiRangeFieldMatch;
import org.onosproject.net.pi.runtime.PiTableAction;
import org.onosproject.net.pi.runtime.PiTableEntry;
@@ -114,7 +115,8 @@
// 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.RANGE ||
+ match.matchType() == PiMatchType.OPTIONAL);
}
// Translate treatment.
final PiTableAction piTableAction = translateTreatment(rule.treatment(), interpreter, piTableId, pipelineModel);
@@ -362,6 +364,7 @@
case TERNARY:
case LPM:
case RANGE:
+ case OPTIONAL:
// Skip field.
break;
default:
@@ -447,6 +450,15 @@
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();
/*
@@ -461,7 +473,6 @@
try {
switch (fieldModel.matchType()) {
case EXACT:
- // TODO: arbitrary bit width is supported only for the EXACT match case.
PiExactFieldMatch exactField = (PiExactFieldMatch) fieldMatch;
return new PiExactFieldMatch(fieldMatch.fieldId(),
fieldModel.hasBitWidth() ?
@@ -492,6 +503,12 @@
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(