Support for PI table entry with default action
Equivalent to a flow rule with empty selector
Change-Id: I5dcbc234e59e3d8647476ffa54d80f5861bad077
diff --git a/core/api/src/test/java/org/onosproject/net/pi/runtime/PiMatchKeyTest.java b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiMatchKeyTest.java
index a6d62af..765deca 100644
--- a/core/api/src/test/java/org/onosproject/net/pi/runtime/PiMatchKeyTest.java
+++ b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiMatchKeyTest.java
@@ -75,6 +75,7 @@
new EqualsTester()
.addEqualityGroup(piMatchKey1, sameAsPiMatchKey1)
+ .addEqualityGroup(PiMatchKey.EMPTY, PiMatchKey.EMPTY)
.addEqualityGroup(piMatchKey2)
.testEquals();
}
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 3230f41..c637144 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
@@ -97,27 +97,35 @@
final PiTableId piTableId = translateTableId(rule.table(), interpreter);
final PiTableModel tableModel = getTableModel(piTableId, pipelineModel);
// Translate selector.
- final Collection<PiFieldMatch> fieldMatches = translateFieldMatches(interpreter, rule.selector(), tableModel);
+ 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 = fieldMatches.stream()
+ .anyMatch(match -> match.type() == PiMatchType.TERNARY ||
+ match.type() == PiMatchType.RANGE);
+ }
// Translate treatment.
final PiTableAction piTableAction = translateTreatment(rule.treatment(), interpreter, piTableId, pipelineModel);
// Build PI entry.
final PiTableEntry.Builder tableEntryBuilder = PiTableEntry.builder();
- // FIXME: P4Runtime limit
- // Need to ignore priority if no TCAM lookup match field
- boolean dontIgnorePriority = fieldMatches.stream()
- .anyMatch(match -> match.type() == PiMatchType.TERNARY ||
- match.type() == PiMatchType.RANGE);
-
tableEntryBuilder
.forTable(piTableId)
- .withMatchKey(PiMatchKey.builder()
- .addFieldMatches(fieldMatches)
- .build())
+ .withMatchKey(piMatchKey)
.withAction(piTableAction);
- if (dontIgnorePriority) {
+ if (needPriority) {
tableEntryBuilder.withPriority(rule.priority());
}
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 500f8cf..1d0caee 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
@@ -50,6 +50,7 @@
import org.onosproject.net.pi.runtime.PiActionGroupMemberId;
import org.onosproject.net.pi.runtime.PiActionParam;
import org.onosproject.net.pi.runtime.PiGroupKey;
+import org.onosproject.net.pi.runtime.PiMatchKey;
import org.onosproject.net.pi.runtime.PiTableAction;
import org.onosproject.net.pi.runtime.PiTableEntry;
import org.onosproject.net.pi.runtime.PiTernaryFieldMatch;
@@ -134,6 +135,9 @@
.matchEthType(ethType)
.build();
+ TrafficSelector emptySelector = DefaultTrafficSelector
+ .builder().build();
+
TrafficTreatment outPort2 = DefaultTrafficTreatment
.builder()
.setOutput(PortNumber.portNumber(outPort))
@@ -159,8 +163,19 @@
.withPriority(priority)
.build();
+ FlowRule defActionRule = DefaultFlowRule.builder()
+ .forDevice(DEVICE_ID)
+ .forTable(tableId)
+ .fromApp(appId)
+ .withSelector(emptySelector)
+ .withTreatment(outPort2)
+ .makeTemporary(timeout)
+ .withPriority(priority)
+ .build();
+
PiTableEntry entry1 = PiFlowRuleTranslatorImpl.translate(rule1, pipeconf, null);
- PiTableEntry entry2 = 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()
@@ -204,6 +219,9 @@
// 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());
}
diff --git a/protocols/p4runtime/ctl/src/main/java/org/onosproject/p4runtime/ctl/TableEntryEncoder.java b/protocols/p4runtime/ctl/src/main/java/org/onosproject/p4runtime/ctl/TableEntryEncoder.java
index b61ae69..c95e2f3 100644
--- a/protocols/p4runtime/ctl/src/main/java/org/onosproject/p4runtime/ctl/TableEntryEncoder.java
+++ b/protocols/p4runtime/ctl/src/main/java/org/onosproject/p4runtime/ctl/TableEntryEncoder.java
@@ -201,8 +201,12 @@
tableEntryMsgBuilder.setTableId(tableInfo.getPreamble().getId());
// Field matches.
- for (PiFieldMatch piFieldMatch : matchKey.fieldMatches()) {
- tableEntryMsgBuilder.addMatch(encodePiFieldMatch(piFieldMatch, tableInfo, browser));
+ if (matchKey.equals(PiMatchKey.EMPTY)) {
+ tableEntryMsgBuilder.setIsDefaultAction(true);
+ } else {
+ for (PiFieldMatch piFieldMatch : matchKey.fieldMatches()) {
+ tableEntryMsgBuilder.addMatch(encodePiFieldMatch(piFieldMatch, tableInfo, browser));
+ }
}
return tableEntryMsgBuilder.build();
@@ -234,8 +238,12 @@
tableEntryMsgBuilder.setAction(encodePiTableAction(piTableEntry.action(), browser));
// Field matches.
- for (PiFieldMatch piFieldMatch : piTableEntry.matchKey().fieldMatches()) {
- tableEntryMsgBuilder.addMatch(encodePiFieldMatch(piFieldMatch, tableInfo, browser));
+ if (piTableEntry.matchKey().equals(PiMatchKey.EMPTY)) {
+ tableEntryMsgBuilder.setIsDefaultAction(true);
+ } else {
+ for (PiFieldMatch piFieldMatch : piTableEntry.matchKey().fieldMatches()) {
+ tableEntryMsgBuilder.addMatch(encodePiFieldMatch(piFieldMatch, tableInfo, browser));
+ }
}
return tableEntryMsgBuilder.build();
@@ -360,7 +368,11 @@
throws P4InfoBrowser.NotFoundException, EncodeException {
P4InfoBrowser browser = PipeconfHelper.getP4InfoBrowser(pipeconf);
P4InfoOuterClass.Table tableInfo = browser.tables().getById(tableEntryMsg.getTableId());
- return decodeFieldMatchMsgs(tableEntryMsg.getMatchList(), tableInfo, browser);
+ if (tableEntryMsg.getMatchCount() == 0) {
+ return PiMatchKey.EMPTY;
+ } else {
+ return decodeFieldMatchMsgs(tableEntryMsg.getMatchList(), tableInfo, browser);
+ }
}
private static PiMatchKey decodeFieldMatchMsgs(Collection<FieldMatch> fieldMatchs, P4InfoOuterClass.Table tableInfo,