Support arbitrary bit width action parameter and match field
This commit goes into the direction of supporting user-defined types in P4Runtime.
The modification is focusing on supporting fields and params with arbitrary bit width, that is the
case of using a String with the p4runtime_translation annotation on the user-defined type.
Change-Id: I7db7a6d97211378ff78ab4f1b3734a0bec4558e6
diff --git a/protocols/p4runtime/utils/src/main/java/org/onosproject/p4runtime/ctl/codec/ActionCodec.java b/protocols/p4runtime/utils/src/main/java/org/onosproject/p4runtime/ctl/codec/ActionCodec.java
index 3ae46c9..69b31a8 100644
--- a/protocols/p4runtime/utils/src/main/java/org/onosproject/p4runtime/ctl/codec/ActionCodec.java
+++ b/protocols/p4runtime/utils/src/main/java/org/onosproject/p4runtime/ctl/codec/ActionCodec.java
@@ -48,8 +48,11 @@
final P4InfoOuterClass.Action.Param paramInfo = browser.actionParams(actionId)
.getByName(p.id().toString());
final ByteString paramValue = ByteString.copyFrom(p.value().asReadOnlyBuffer());
- assertSize(format("param '%s' of action '%s'", p.id(), piAction.id()),
- paramValue, paramInfo.getBitwidth());
+ if (!browser.isTypeString(paramInfo.getTypeName())) {
+ // Check size only if the param type is not a sdn_string
+ assertSize(format("param '%s' of action '%s'", p.id(), piAction.id()),
+ paramValue, paramInfo.getBitwidth());
+ }
actionMsgBuilder.addParams(P4RuntimeOuterClass.Action.Param.newBuilder()
.setParamId(paramInfo.getId())
.setValue(paramValue)
diff --git a/protocols/p4runtime/utils/src/main/java/org/onosproject/p4runtime/ctl/codec/FieldMatchCodec.java b/protocols/p4runtime/utils/src/main/java/org/onosproject/p4runtime/ctl/codec/FieldMatchCodec.java
index f289d5d..5e2ec43 100644
--- a/protocols/p4runtime/utils/src/main/java/org/onosproject/p4runtime/ctl/codec/FieldMatchCodec.java
+++ b/protocols/p4runtime/utils/src/main/java/org/onosproject/p4runtime/ctl/codec/FieldMatchCodec.java
@@ -71,7 +71,10 @@
case EXACT:
PiExactFieldMatch fieldMatch = (PiExactFieldMatch) piFieldMatch;
ByteString exactValue = ByteString.copyFrom(fieldMatch.value().asReadOnlyBuffer());
- assertSize(VALUE_OF_PREFIX + entityName, exactValue, fieldBitwidth);
+ // We support string only for EXACT match (via p4runtime_translation)
+ if (!browser.isTypeString(matchFieldInfo.getTypeName())) {
+ assertSize(VALUE_OF_PREFIX + entityName, exactValue, fieldBitwidth);
+ }
return messageBuilder.setExact(
P4RuntimeOuterClass.FieldMatch.Exact
.newBuilder()
diff --git a/protocols/p4runtime/utils/src/main/java/org/onosproject/p4runtime/ctl/utils/P4InfoBrowser.java b/protocols/p4runtime/utils/src/main/java/org/onosproject/p4runtime/ctl/utils/P4InfoBrowser.java
index 8504202..85405ca 100644
--- a/protocols/p4runtime/utils/src/main/java/org/onosproject/p4runtime/ctl/utils/P4InfoBrowser.java
+++ b/protocols/p4runtime/utils/src/main/java/org/onosproject/p4runtime/ctl/utils/P4InfoBrowser.java
@@ -31,6 +31,7 @@
import p4.config.v1.P4InfoOuterClass.Preamble;
import p4.config.v1.P4InfoOuterClass.Table;
import p4.config.v1.P4InfoOuterClass.Digest;
+import p4.config.v1.P4Types;
import java.util.Map;
@@ -57,6 +58,7 @@
private final Map<Integer, EntityBrowser<ControllerPacketMetadata.Metadata>> ctrlPktMetadatasMetadata =
Maps.newHashMap();
private final EntityBrowser<Digest> digests = new EntityBrowser<>("digest");
+ private final Map<String, Boolean> isTypeString = Maps.newHashMap();
/**
* Creates a new browser for the given P4Info.
@@ -121,6 +123,12 @@
p4info.getDigestsList().forEach(
entity -> digests.addWithPreamble(entity.getPreamble(), entity));
+ p4info.getTypeInfo().getNewTypesMap().forEach(
+ (s, p4NewTypeSpec) ->
+ isTypeString.put(s,
+ p4NewTypeSpec.hasTranslatedType()
+ && p4NewTypeSpec.getTranslatedType().hasSdnString()
+ ));
}
/**
@@ -245,6 +253,17 @@
}
/**
+ * Checks if the given type name is a sdn_string.
+ *
+ * @param typeName Type name to check
+ * @return True if the given type name is a sdn_string, false otherwise
+ */
+ public boolean isTypeString(P4Types.P4NamedType typeName) {
+ return isTypeString.containsKey(typeName.getName())
+ && isTypeString.get(typeName.getName());
+ }
+
+ /**
* Browser of P4Info entities.
*
* @param <T> protobuf message type