ONOS-7066 ONOS-7067 PI abstractions refactoring and P4Info model parser
Includes changes previously reviewed in #15607, #15877, and #15955.
Change-Id: Ie2ff62e415f2099832ebfe05961a879b7b188fc3
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 4e0fd16..20a2d0f 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
@@ -80,10 +80,10 @@
import org.onosproject.net.pi.impl.CriterionTranslators.UdpPortCriterionTranslator;
import org.onosproject.net.pi.impl.CriterionTranslators.VlanIdCriterionTranslator;
import org.onosproject.net.pi.impl.CriterionTranslators.VlanPcpCriterionTranslator;
+import org.onosproject.net.pi.model.PiMatchFieldId;
import org.onosproject.net.pi.model.PiMatchType;
import org.onosproject.net.pi.runtime.PiExactFieldMatch;
import org.onosproject.net.pi.runtime.PiFieldMatch;
-import org.onosproject.net.pi.runtime.PiHeaderFieldId;
import org.onosproject.net.pi.runtime.PiLpmFieldMatch;
import org.onosproject.net.pi.runtime.PiTernaryFieldMatch;
@@ -140,14 +140,14 @@
/**
* Translates a given criterion instance to a PiFieldMatch with the given id, match type, and bit-width.
*
- * @param fieldId PI header field identifier
+ * @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, PiHeaderFieldId fieldId, PiMatchType matchType,
+ static PiFieldMatch translateCriterion(Criterion criterion, PiMatchFieldId fieldId, PiMatchType matchType,
int bitWidth)
throws PiTranslationException {
diff --git a/core/net/src/main/java/org/onosproject/net/pi/impl/PiFlowRuleTranslator.java b/core/net/src/main/java/org/onosproject/net/pi/impl/PiFlowRuleTranslator.java
index 0a4ffbb..6f61c3b 100644
--- a/core/net/src/main/java/org/onosproject/net/pi/impl/PiFlowRuleTranslator.java
+++ b/core/net/src/main/java/org/onosproject/net/pi/impl/PiFlowRuleTranslator.java
@@ -29,22 +29,22 @@
import org.onosproject.net.flow.instructions.PiInstruction;
import org.onosproject.net.pi.model.PiActionModel;
import org.onosproject.net.pi.model.PiActionParamModel;
+import org.onosproject.net.pi.model.PiMatchFieldId;
+import org.onosproject.net.pi.model.PiMatchFieldModel;
import org.onosproject.net.pi.model.PiPipeconf;
import org.onosproject.net.pi.model.PiPipelineInterpreter;
import org.onosproject.net.pi.model.PiPipelineModel;
-import org.onosproject.net.pi.model.PiTableMatchFieldModel;
+import org.onosproject.net.pi.model.PiTableId;
import org.onosproject.net.pi.model.PiTableModel;
import org.onosproject.net.pi.runtime.PiAction;
import org.onosproject.net.pi.runtime.PiActionParam;
import org.onosproject.net.pi.runtime.PiExactFieldMatch;
import org.onosproject.net.pi.runtime.PiFieldMatch;
-import org.onosproject.net.pi.runtime.PiHeaderFieldId;
import org.onosproject.net.pi.runtime.PiLpmFieldMatch;
import org.onosproject.net.pi.runtime.PiMatchKey;
import org.onosproject.net.pi.runtime.PiRangeFieldMatch;
import org.onosproject.net.pi.runtime.PiTableAction;
import org.onosproject.net.pi.runtime.PiTableEntry;
-import org.onosproject.net.pi.runtime.PiTableId;
import org.onosproject.net.pi.runtime.PiTernaryFieldMatch;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -128,7 +128,7 @@
tableEntryBuilder.withTimeout((double) rule.timeout());
} else {
log.warn("Flow rule is temporary, but table '{}' doesn't support " +
- "aging, translating to permanent.", tableModel.name());
+ "aging, translating to permanent.", tableModel.id());
}
}
@@ -159,7 +159,7 @@
private static PiTableModel getTableModel(PiTableId piTableId, PiPipelineModel pipelineModel)
throws PiTranslationException {
- return pipelineModel.table(piTableId.toString())
+ return pipelineModel.table(piTableId)
.orElseThrow(() -> new PiTranslationException(format(
"Not such a table in pipeline model: %s", piTableId)));
}
@@ -221,24 +221,24 @@
private static PiTableAction checkPiAction(PiAction piAction, PiTableModel table)
throws PiTranslationException {
// Table supports this action?
- PiActionModel actionModel = table.action(piAction.id().name()).orElseThrow(
+ PiActionModel actionModel = table.action(piAction.id()).orElseThrow(
() -> new PiTranslationException(format("Not such action '%s' for table '%s'",
- piAction.id(), table.name())));
+ piAction.id(), table.id())));
// Is the number of runtime parameters correct?
if (actionModel.params().size() != piAction.parameters().size()) {
throw new PiTranslationException(format(
"Wrong number of runtime parameters for action '%s', expected %d but found %d",
- actionModel.name(), actionModel.params().size(), piAction.parameters().size()));
+ actionModel.id(), actionModel.params().size(), piAction.parameters().size()));
}
// Forge a new action instance with well-sized parameters.
// The same comment as in typeCheckFieldMatch() about duplicating field match instances applies here.
PiAction.Builder newActionBuilder = PiAction.builder().withId(piAction.id());
for (PiActionParam param : piAction.parameters()) {
- PiActionParamModel paramModel = actionModel.param(param.id().name())
+ PiActionParamModel paramModel = actionModel.param(param.id())
.orElseThrow(() -> new PiTranslationException(format(
- "Not such parameter '%s' for action '%s'", param.id(), actionModel.name())));
+ "Not such parameter '%s' for action '%s'", param.id(), actionModel)));
try {
newActionBuilder.withParameter(new PiActionParam(param.id(),
fit(param.value(), paramModel.bitWidth())));
@@ -260,16 +260,16 @@
TrafficSelector selector, PiTableModel tableModel)
throws PiTranslationException {
- Map<PiHeaderFieldId, PiFieldMatch> fieldMatches = Maps.newHashMap();
+ Map<PiMatchFieldId, PiFieldMatch> fieldMatches = Maps.newHashMap();
// If present, find a PiCriterion and get its field matches as a map. Otherwise, use an empty map.
- Map<PiHeaderFieldId, PiFieldMatch> piCriterionFields = selector.criteria().stream()
+ Map<PiMatchFieldId, PiFieldMatch> piCriterionFields = selector.criteria().stream()
.filter(c -> c.type().equals(PROTOCOL_INDEPENDENT))
.map(c -> (PiCriterion) c)
.findFirst()
.map(PiCriterion::fieldMatches)
.map(c -> {
- Map<PiHeaderFieldId, PiFieldMatch> fieldMap = Maps.newHashMap();
+ Map<PiMatchFieldId, PiFieldMatch> fieldMap = Maps.newHashMap();
c.forEach(fieldMatch -> fieldMap.put(fieldMatch.fieldId(), fieldMatch));
return fieldMap;
})
@@ -277,31 +277,20 @@
Set<Criterion> translatedCriteria = Sets.newHashSet();
Set<Criterion> ignoredCriteria = Sets.newHashSet();
- Set<PiHeaderFieldId> usedPiCriterionFields = Sets.newHashSet();
- Set<PiHeaderFieldId> ignoredPiCriterionFields = Sets.newHashSet();
+ Set<PiMatchFieldId> usedPiCriterionFields = Sets.newHashSet();
+ Set<PiMatchFieldId> ignoredPiCriterionFields = Sets.newHashSet();
- for (PiTableMatchFieldModel fieldModel : tableModel.matchFields()) {
+ for (PiMatchFieldModel fieldModel : tableModel.matchFields()) {
- PiHeaderFieldId fieldId = PiHeaderFieldId.of(fieldModel.field().header().name(),
- fieldModel.field().type().name(),
- fieldModel.field().header().index());
+ PiMatchFieldId fieldId = fieldModel.id();
- // FIXME: workaround until ONOS-7066 is resolved
- if (fieldId.id().startsWith("scalars")) {
- String newFieldId = fieldId.id()
- .replace("scalars.", "")
- .replace("_t.", ".");
- String[] piecies = newFieldId.split("\\.");
- fieldId = PiHeaderFieldId.of(piecies[0], piecies[1]);
- }
-
- int bitWidth = fieldModel.field().type().bitWidth();
+ int bitWidth = fieldModel.bitWidth();
int fieldByteWidth = (int) Math.ceil((double) bitWidth / 8);
Optional<Criterion.Type> criterionType =
interpreter == null
? Optional.empty()
- : interpreter.mapPiHeaderFieldId(fieldId);
+ : interpreter.mapPiMatchFieldId(fieldId);
Criterion criterion = criterionType.map(selector::getCriterion).orElse(null);
@@ -378,7 +367,7 @@
if (skippedCriteriaJoiner.length() > 0) {
throw new PiTranslationException(format(
"The following criteria cannot be translated for table '%s': %s",
- tableModel.name(), skippedCriteriaJoiner.toString()));
+ tableModel.id(), skippedCriteriaJoiner.toString()));
}
// Check if all fields found in PiCriterion have been used.
@@ -389,13 +378,13 @@
if (skippedPiFieldsJoiner.length() > 0) {
throw new PiTranslationException(format(
"The following PiCriterion field matches are not supported in table '%s': %s",
- tableModel.name(), skippedPiFieldsJoiner.toString()));
+ tableModel.id(), skippedPiFieldsJoiner.toString()));
}
return fieldMatches.values();
}
- private static PiFieldMatch typeCheckFieldMatch(PiFieldMatch fieldMatch, PiTableMatchFieldModel fieldModel)
+ private static PiFieldMatch typeCheckFieldMatch(PiFieldMatch fieldMatch, PiMatchFieldModel fieldModel)
throws PiTranslationException {
// Check parameter type and size
@@ -405,7 +394,7 @@
fieldMatch.fieldId(), fieldModel.matchType().name(), fieldMatch.type().name()));
}
- int modelBitWidth = fieldModel.field().type().bitWidth();
+ int modelBitWidth = fieldModel.bitWidth();
/*
Here we try to be robust against wrong size fields with the goal of having PiCriterion independent of the
diff --git a/core/net/src/main/java/org/onosproject/net/pi/impl/PiGroupTranslator.java b/core/net/src/main/java/org/onosproject/net/pi/impl/PiGroupTranslator.java
index 7b798c0..a682409 100644
--- a/core/net/src/main/java/org/onosproject/net/pi/impl/PiGroupTranslator.java
+++ b/core/net/src/main/java/org/onosproject/net/pi/impl/PiGroupTranslator.java
@@ -19,6 +19,7 @@
import org.onosproject.net.Device;
import org.onosproject.net.group.Group;
import org.onosproject.net.group.GroupBucket;
+import org.onosproject.net.pi.model.PiActionGroupType;
import org.onosproject.net.pi.model.PiPipeconf;
import org.onosproject.net.pi.model.PiPipelineInterpreter;
import org.onosproject.net.pi.runtime.PiAction;
@@ -64,7 +65,7 @@
switch (group.type()) {
case SELECT:
- piActionGroupBuilder.withType(PiActionGroup.Type.SELECT);
+ piActionGroupBuilder.withType(PiActionGroupType.SELECT);
break;
default:
throw new PiTranslationException(format("Group type %s not supported", group.type()));
diff --git a/core/net/src/main/java/org/onosproject/net/pi/impl/PiUtils.java b/core/net/src/main/java/org/onosproject/net/pi/impl/PiUtils.java
index aab8b40..f3270f4 100644
--- a/core/net/src/main/java/org/onosproject/net/pi/impl/PiUtils.java
+++ b/core/net/src/main/java/org/onosproject/net/pi/impl/PiUtils.java
@@ -21,7 +21,7 @@
import org.onosproject.net.flow.TableId;
import org.onosproject.net.pi.model.PiPipeconf;
import org.onosproject.net.pi.model.PiPipelineInterpreter;
-import org.onosproject.net.pi.runtime.PiTableId;
+import org.onosproject.net.pi.model.PiTableId;
import org.onosproject.net.pi.runtime.PiTranslationService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/core/net/src/test/java/org/onosproject/net/pi/impl/PiCriterionTranslatorsTest.java b/core/net/src/test/java/org/onosproject/net/pi/impl/PiCriterionTranslatorsTest.java
index 156be3a..1938c05 100644
--- a/core/net/src/test/java/org/onosproject/net/pi/impl/PiCriterionTranslatorsTest.java
+++ b/core/net/src/test/java/org/onosproject/net/pi/impl/PiCriterionTranslatorsTest.java
@@ -57,8 +57,8 @@
import org.onosproject.net.flow.criteria.UdpPortCriterion;
import org.onosproject.net.flow.criteria.VlanIdCriterion;
import org.onosproject.net.flow.criteria.VlanPcpCriterion;
+import org.onosproject.net.pi.model.PiMatchFieldId;
import org.onosproject.net.pi.runtime.PiExactFieldMatch;
-import org.onosproject.net.pi.runtime.PiHeaderFieldId;
import org.onosproject.net.pi.runtime.PiLpmFieldMatch;
import org.onosproject.net.pi.runtime.PiTernaryFieldMatch;
@@ -67,7 +67,9 @@
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.onosproject.net.pi.impl.CriterionTranslatorHelper.translateCriterion;
-import static org.onosproject.net.pi.model.PiMatchType.*;
+import static org.onosproject.net.pi.model.PiMatchType.EXACT;
+import static org.onosproject.net.pi.model.PiMatchType.LPM;
+import static org.onosproject.net.pi.model.PiMatchType.TERNARY;
/**
* Tests for CriterionTranslators.
@@ -75,7 +77,7 @@
public class PiCriterionTranslatorsTest {
private Random random = new Random();
- private final PiHeaderFieldId fieldId = PiHeaderFieldId.of("foo", "bar");
+ private final PiMatchFieldId fieldId = PiMatchFieldId.of("foo.bar");
@Test
public void testEthCriterion() throws Exception {
@@ -480,4 +482,4 @@
assertThat(exactMatch.value().asReadOnlyBuffer().get(), is(criterion.ipEcn()));
}
-}
\ No newline at end of file
+}
diff --git a/core/net/src/test/java/org/onosproject/net/pi/impl/PiTranslatorServiceTest.java b/core/net/src/test/java/org/onosproject/net/pi/impl/PiTranslatorServiceTest.java
index e7e3e23..d13def7 100644
--- a/core/net/src/test/java/org/onosproject/net/pi/impl/PiTranslatorServiceTest.java
+++ b/core/net/src/test/java/org/onosproject/net/pi/impl/PiTranslatorServiceTest.java
@@ -43,6 +43,7 @@
import org.onosproject.net.group.GroupBucket;
import org.onosproject.net.group.GroupBuckets;
import org.onosproject.net.group.GroupDescription;
+import org.onosproject.net.pi.model.PiActionGroupType;
import org.onosproject.net.pi.model.PiPipeconf;
import org.onosproject.net.pi.runtime.PiAction;
import org.onosproject.net.pi.runtime.PiActionGroup;
@@ -169,13 +170,13 @@
.addEqualityGroup(entry1, entry2)
.testEquals();
- int numMatchParams = pipeconf.pipelineModel().table(TBL_TABLE0_ID.id()).get().matchFields().size();
+ int numMatchParams = pipeconf.pipelineModel().table(TBL_TABLE0_ID).get().matchFields().size();
// parse values stored in entry1
PiTernaryFieldMatch inPortParam = (PiTernaryFieldMatch) entry1.matchKey().fieldMatch(HDR_IN_PORT_ID).get();
PiTernaryFieldMatch ethDstParam = (PiTernaryFieldMatch) entry1.matchKey().fieldMatch(HDR_ETH_DST_ID).get();
PiTernaryFieldMatch ethSrcParam = (PiTernaryFieldMatch) entry1.matchKey().fieldMatch(HDR_ETH_SRC_ID).get();
PiTernaryFieldMatch ethTypeParam = (PiTernaryFieldMatch) entry1.matchKey().fieldMatch(HDR_ETH_TYPE_ID).get();
- Optional<Double> expectedTimeout = pipeconf.pipelineModel().table(TBL_TABLE0_ID.id()).get().supportsAging()
+ Optional<Double> expectedTimeout = pipeconf.pipelineModel().table(TBL_TABLE0_ID).get().supportsAging()
? Optional.of((double) rule1.timeout()) : Optional.empty();
// check that the number of parameters in the entry is the same as the number of table keys
@@ -245,7 +246,7 @@
assertThat("Group ID must be equal",
piGroup1.id().id(), is(equalTo(GROUP_ID.id())));
assertThat("Group type must be SELECT",
- piGroup1.type(), is(equalTo(PiActionGroup.Type.SELECT)));
+ piGroup1.type(), is(equalTo(PiActionGroupType.SELECT)));
assertThat("Action profile ID must be equal",
piGroup1.actionProfileId(), is(equalTo(ACT_PRF_WCMP_SELECTOR_ID)));