Do not insert or delete default action entries in P4Runtime
Spec says:
the default entry for a table is always set. It can be set at
compile-time by the P4 programmer - or defaults to NoAction (which is a
no-op) otherwise - and assuming it is not declared as const, can be
modified by the P4Runtime client. Because the default entry is always
set, we do not allow INSERT and DELETE updates on the default entry and
the P4Runtime server must return an INVALID_ARGUMENT error code if the
client attempts one.
With this patch we convert insert or delete operations into modify ones
(unless specified by a driver property, to support non-compliant devices).
For delete, we use the interpreter to suggest a default action that is
the same as the one when the pipeline was originally deployed.
Also, we introduce the capability of synchronizing the device mirror
with the device state.
Change-Id: I3758fc11780eb0f1cf4ed5a295bd98b54b182e29
diff --git a/core/api/src/main/java/org/onosproject/net/pi/model/PiPipelineInterpreter.java b/core/api/src/main/java/org/onosproject/net/pi/model/PiPipelineInterpreter.java
index 4414931..9206f5c 100644
--- a/core/api/src/main/java/org/onosproject/net/pi/model/PiPipelineInterpreter.java
+++ b/core/api/src/main/java/org/onosproject/net/pi/model/PiPipelineInterpreter.java
@@ -126,6 +126,18 @@
}
/**
+ * If the given table allows for mutable default actions, this method
+ * returns an action instance to be used when ONOS tries to remove a
+ * different default action previously set.
+ *
+ * @param tableId table ID
+ * @return optional default action
+ */
+ default Optional<PiAction> getOriginalDefaultAction(PiTableId tableId) {
+ return Optional.empty();
+ }
+
+ /**
* Signals that an error was encountered while executing the interpreter.
*/
@Beta
diff --git a/core/api/src/main/java/org/onosproject/net/pi/model/PiTableModel.java b/core/api/src/main/java/org/onosproject/net/pi/model/PiTableModel.java
index ba66c10..f7ba1bd 100644
--- a/core/api/src/main/java/org/onosproject/net/pi/model/PiTableModel.java
+++ b/core/api/src/main/java/org/onosproject/net/pi/model/PiTableModel.java
@@ -42,8 +42,9 @@
PiTableType tableType();
/**
- * Returns the model of the action profile that implements this table. Meaningful if this table is of type {@link
- * PiTableType#INDIRECT}, otherwise returns null.
+ * Returns the model of the action profile that implements this table.
+ * Meaningful if this table is of type {@link PiTableType#INDIRECT},
+ * otherwise returns null.
*
* @return action profile ID
*/
@@ -92,16 +93,19 @@
Collection<PiActionModel> actions();
/**
- * Returns the model of the default action associated with this table, if any.
+ * Returns the model of the constant default action associated with this
+ * table, if any.
*
* @return optional default action model
*/
- Optional<PiActionModel> defaultAction();
+ Optional<PiActionModel> constDefaultAction();
/**
- * Returns true if the default action has mutable parameters that can be changed at runtime, false otherwise.
+ * Returns true if the default action has mutable parameters that can be
+ * changed at runtime, false otherwise.
*
- * @return true if the default action has mutable parameters, false otherwise
+ * @return true if the default action has mutable parameters, false
+ * otherwise
*/
boolean hasDefaultMutableParams();
@@ -114,8 +118,8 @@
boolean isConstantTable();
/**
- * Returns the action model associated with the given ID, if present. If not present, it means that this table does
- * not support such an action.
+ * Returns the action model associated with the given ID, if present. If not
+ * present, it means that this table does not support such an action.
*
* @param actionId action ID
* @return optional action model
@@ -123,8 +127,9 @@
Optional<PiActionModel> action(PiActionId actionId);
/**
- * Returns the match field model associated with the given ID, if present. If not present, it means that this table
- * does not support such a match field.
+ * Returns the match field model associated with the given ID, if present.
+ * If not present, it means that this table does not support such a match
+ * field.
*
* @param matchFieldId match field ID
* @return optional match field model
diff --git a/core/api/src/main/java/org/onosproject/net/pi/runtime/PiTableEntry.java b/core/api/src/main/java/org/onosproject/net/pi/runtime/PiTableEntry.java
index 7b8797a..04b2528 100644
--- a/core/api/src/main/java/org/onosproject/net/pi/runtime/PiTableEntry.java
+++ b/core/api/src/main/java/org/onosproject/net/pi/runtime/PiTableEntry.java
@@ -38,15 +38,18 @@
private final PiTableId tableId;
private final PiMatchKey matchKey;
private final PiTableAction tableAction;
+ private final boolean isDefaultAction;
private final long cookie;
private final int priority;
private final double timeout;
private PiTableEntry(PiTableId tableId, PiMatchKey matchKey,
- PiTableAction tableAction, long cookie, int priority, double timeout) {
+ PiTableAction tableAction, boolean isDefaultAction,
+ long cookie, int priority, double timeout) {
this.tableId = tableId;
this.matchKey = matchKey;
this.tableAction = tableAction;
+ this.isDefaultAction = isDefaultAction;
this.cookie = cookie;
this.priority = priority;
this.timeout = timeout;
@@ -63,6 +66,9 @@
/**
* Returns the match key of this table entry.
+ * <p>
+ * If {@link #isDefaultAction()} is {@code true} this method returns the
+ * empty match key ({@link PiMatchKey#EMPTY}).
*
* @return match key
*/
@@ -80,6 +86,16 @@
}
/**
+ * Returns true if this table entry contains the default action for this
+ * table, a.k.a. table-miss entry, false otherwise.
+ *
+ * @return boolean
+ */
+ public boolean isDefaultAction() {
+ return isDefaultAction;
+ }
+
+ /**
* Returns the cookie of this table entry.
*
* @return cookie
@@ -89,8 +105,8 @@
}
/**
- * Returns the priority of this table entry, if present. If the priority value is not present, then this table entry
- * has no explicit priority.
+ * Returns the priority of this table entry, if present. If the priority
+ * value is not present, then this table entry has no explicit priority.
*
* @return optional priority
*/
@@ -99,8 +115,9 @@
}
/**
- * Returns the timeout in seconds of this table entry, if present. If the timeout value is not present, then this
- * table entry is meant to be permanent.
+ * Returns the timeout in seconds of this table entry, if present. If the
+ * timeout value is not present, then this table entry is meant to be
+ * permanent.
*
* @return optional timeout value in seconds
*/
@@ -121,25 +138,42 @@
Double.compare(that.timeout, timeout) == 0 &&
Objects.equal(tableId, that.tableId) &&
Objects.equal(matchKey, that.matchKey) &&
+ Objects.equal(isDefaultAction, that.isDefaultAction) &&
Objects.equal(tableAction, that.tableAction);
}
@Override
public int hashCode() {
- return Objects.hashCode(tableId, matchKey, tableAction, priority, timeout);
+ return Objects.hashCode(tableId, matchKey, isDefaultAction, tableAction,
+ priority, timeout);
}
@Override
public String toString() {
return MoreObjects.toStringHelper(this)
.add("tableId", tableId)
- .add("matchKey", matchKey)
- .add("tableAction", tableAction)
+ .add("matchKey", isDefaultAction ? "DEFAULT-ACTION" : matchKey)
+ .add("tableAction", tableActionToString(tableAction))
.add("priority", priority == NO_PRIORITY ? "N/A" : String.valueOf(priority))
.add("timeout", timeout == NO_TIMEOUT ? "PERMANENT" : String.valueOf(timeout))
.toString();
}
+ private String tableActionToString(PiTableAction tableAction) {
+ if (tableAction == null) {
+ return "null";
+ }
+ switch (tableAction.type()) {
+ case ACTION_GROUP_ID:
+ return "GROUP:" + ((PiActionGroupId) tableAction).id();
+ case GROUP_MEMBER_ID:
+ return "GROUP_MEMBER:" + ((PiActionGroupMemberId) tableAction).id();
+ case ACTION:
+ default:
+ return tableAction.toString();
+ }
+ }
+
/**
* Returns a table entry builder.
*
@@ -244,7 +278,9 @@
public PiTableEntry build() {
checkNotNull(tableId);
checkNotNull(matchKey);
- return new PiTableEntry(tableId, matchKey, tableAction, cookie, priority, timeout);
+ final boolean isDefaultAction = matchKey.equals(PiMatchKey.EMPTY);
+ return new PiTableEntry(tableId, matchKey, tableAction,
+ isDefaultAction, cookie, priority, timeout);
}
}
}