Add architecture method to PiPipelineModel Interface.
The field `pkg_info:arch` is now parsed, when parsing a P4Info file.
Change-Id: Ia1b24b929fe4ed8ac2a2becfa0ce7678642e9037
(cherry picked from commit ce9942049825c51c0a0818ad4b89395321aa82b3)
diff --git a/core/api/src/main/java/org/onosproject/net/pi/model/PiPipelineModel.java b/core/api/src/main/java/org/onosproject/net/pi/model/PiPipelineModel.java
index bddbae8..2efa40f 100644
--- a/core/api/src/main/java/org/onosproject/net/pi/model/PiPipelineModel.java
+++ b/core/api/src/main/java/org/onosproject/net/pi/model/PiPipelineModel.java
@@ -28,6 +28,13 @@
public interface PiPipelineModel {
/**
+ * Returns the data plane target architecture supported by this pipeline model.
+ *
+ * @return optional architecture string.
+ */
+ Optional<String> architecture();
+
+ /**
* Returns the table model associated with the given ID, if present.
*
* @param tableId table ID
diff --git a/pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/MockPiPipelineModel.java b/pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/MockPiPipelineModel.java
index db438b5..2560346 100644
--- a/pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/MockPiPipelineModel.java
+++ b/pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/upf/MockPiPipelineModel.java
@@ -49,6 +49,11 @@
}
@Override
+ public Optional<String> architecture() {
+ return Optional.empty();
+ }
+
+ @Override
public Optional<PiTableModel> table(PiTableId tableId) {
return Optional.ofNullable(tableMap.getOrDefault(tableId, null));
}
diff --git a/protocols/p4runtime/model/src/main/java/org/onosproject/p4runtime/model/P4InfoParser.java b/protocols/p4runtime/model/src/main/java/org/onosproject/p4runtime/model/P4InfoParser.java
index cbe1d6e..f47a0b7 100644
--- a/protocols/p4runtime/model/src/main/java/org/onosproject/p4runtime/model/P4InfoParser.java
+++ b/protocols/p4runtime/model/src/main/java/org/onosproject/p4runtime/model/P4InfoParser.java
@@ -160,6 +160,8 @@
// Start by parsing and mapping instances to to their integer P4Info IDs.
// Convenient to build the table model at the end.
+ final String architecture = parseArchitecture(p4info);
+
// Counters.
final Map<Integer, PiCounterModel> counterMap = Maps.newHashMap();
counterMap.putAll(parseCounters(p4info));
@@ -269,9 +271,16 @@
registerImmMap,
actProfileImmMap,
ImmutableMap.copyOf(pktOpMap),
+ architecture,
fingerprint);
}
+ private static String parseArchitecture(P4Info p4info) {
+ if (p4info.hasPkgInfo()) {
+ return p4info.getPkgInfo().getArch();
+ }
+ return null;
+ }
private static Map<Integer, PiCounterModel> parseCounters(P4Info p4info)
throws P4InfoParserException {
diff --git a/protocols/p4runtime/model/src/main/java/org/onosproject/p4runtime/model/P4PipelineModel.java b/protocols/p4runtime/model/src/main/java/org/onosproject/p4runtime/model/P4PipelineModel.java
index 28e5372..46889a6 100644
--- a/protocols/p4runtime/model/src/main/java/org/onosproject/p4runtime/model/P4PipelineModel.java
+++ b/protocols/p4runtime/model/src/main/java/org/onosproject/p4runtime/model/P4PipelineModel.java
@@ -48,6 +48,7 @@
private final ImmutableMap<PiRegisterId, PiRegisterModel> registers;
private final ImmutableMap<PiActionProfileId, PiActionProfileModel> actionProfiles;
private final ImmutableMap<PiPacketOperationType, PiPacketOperationModel> packetOperations;
+ private final String architecture;
private final int fingerprint;
P4PipelineModel(
@@ -57,6 +58,7 @@
ImmutableMap<PiRegisterId, PiRegisterModel> registers,
ImmutableMap<PiActionProfileId, PiActionProfileModel> actionProfiles,
ImmutableMap<PiPacketOperationType, PiPacketOperationModel> packetOperations,
+ String architecture,
int fingerprint) {
this.tables = tables;
this.counters = counters;
@@ -65,6 +67,12 @@
this.actionProfiles = actionProfiles;
this.packetOperations = packetOperations;
this.fingerprint = fingerprint;
+ this.architecture = architecture;
+ }
+
+ @Override
+ public Optional<String> architecture() {
+ return Optional.ofNullable(this.architecture);
}
@Override
@@ -160,6 +168,7 @@
.add("actionProfiles", actionProfiles.values())
.add("packetOperations", packetOperations.values())
.add("fingerprint", fingerprint)
+ .add("architecture", architecture)
.toString();
}
}
diff --git a/protocols/p4runtime/model/src/test/java/org/onosproject/p4runtime/model/P4InfoParserTest.java b/protocols/p4runtime/model/src/test/java/org/onosproject/p4runtime/model/P4InfoParserTest.java
index 3785c96..27bffc8 100644
--- a/protocols/p4runtime/model/src/test/java/org/onosproject/p4runtime/model/P4InfoParserTest.java
+++ b/protocols/p4runtime/model/src/test/java/org/onosproject/p4runtime/model/P4InfoParserTest.java
@@ -59,6 +59,7 @@
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.core.IsNull.notNullValue;
+import static org.hamcrest.core.IsNull.nullValue;
/**
* Test for P4Info Parser.
@@ -75,16 +76,46 @@
private static final int DEFAULT_MAX_GROUP_SIZE = 16;
/**
+ * Tests the parsing of the architecture field.
+ * @throws Exception if the equality group objects does not match expected
+ */
+ @Test
+ public void testParseArchitecture() throws Exception {
+ // Generate two PiPipelineModels from the same p4Info file
+ PiPipelineModel model = P4InfoParser.parse(p4InfoUrl);
+ PiPipelineModel sameAsModel = P4InfoParser.parse(p4InfoUrl);
+
+ PiPipelineModel model3 = P4InfoParser.parse(p4InfoUrl2);
+
+ String architecture1 = model.architecture().orElse(null);
+ String architecture2 = sameAsModel.architecture().orElse(null);
+
+ assertThat("null value is returned if `arch` not present in P4Info",
+ architecture1,
+ is(nullValue()));
+ assertThat("null value is returned if `arch` not present in P4Info",
+ architecture2,
+ is(nullValue()));
+
+ String architecture3 = model3.architecture().orElse(null);
+ assertThat("test that `arch` field is correctly parsed",
+ architecture3,
+ is("v1model"));
+ }
+
+ /**
* Tests parse method.
* @throws Exception if equality group objects dose not match as expected
*/
@Test
public void testParse() throws Exception {
- // Generate two PiPipelineModels from p4Info file
+ // Generate two PiPipelineModels from the same p4Info file
PiPipelineModel model = P4InfoParser.parse(p4InfoUrl);
- PiPipelineModel model2 = P4InfoParser.parse(p4InfoUrl);
+ PiPipelineModel sameAsModel = P4InfoParser.parse(p4InfoUrl);
+
// Check equality
- new EqualsTester().addEqualityGroup(model, model2).testEquals();
+ new EqualsTester().addEqualityGroup(model, sameAsModel).testEquals();
+
// Generate a P4Info object from the file
final P4Info p4info;
try {
@@ -100,8 +131,9 @@
PiTableModel table0Model = model.table(table0Id).orElse(null);
PiTableModel wcmpTableModel = model.table(wcmpTableId).orElse(null);
PiTableModel wcmpTableOneShotModel = model.table(wcmpTableOneShotId).orElse(null);
- PiTableModel table0Model2 = model2.table(table0Id).orElse(null);
- PiTableModel wcmpTableModel2 = model2.table(wcmpTableId).orElse(null);
+ PiTableModel table0Model2 = sameAsModel.table(table0Id).orElse(null);
+ PiTableModel wcmpTableModel2 = sameAsModel.table(wcmpTableId).orElse(null);
+
new EqualsTester().addEqualityGroup(table0Model, table0Model2)
.addEqualityGroup(wcmpTableModel, wcmpTableModel2).testEquals();
// Check existence
@@ -142,18 +174,15 @@
piMatchFieldList.get(6), piMatchFieldList.get(7),
piMatchFieldList.get(8)));
assertThat("Incorrect size for matchFields", wcmpTableModel.matchFields().size(), is(equalTo(1)));
-
// check if matchFields are in order
matchFieldList = tableMsgs.get(1).getMatchFieldsList();
assertThat("Incorrect order for matchFields",
wcmpTableModel.matchFields(), IsIterableContainingInOrder.contains(
new P4MatchFieldModel(PiMatchFieldId.of(matchFieldList.get(0).getName()),
matchFieldList.get(0).getBitwidth(), PiMatchType.EXACT)));
-
//check table0 actionsRefs
List<ActionRef> actionRefList = tableMsgs.get(0).getActionRefsList();
assertThat("Incorrect size for actionRefs", actionRefList.size(), is(equalTo(4)));
-
//create action instances
PiActionId actionId = PiActionId.of("set_egress_port");
PiActionParamId piActionParamId = PiActionParamId.of("port");
@@ -168,15 +197,12 @@
actionId = PiActionId.of("send_to_cpu");
PiActionModel sendToCpuAction =
new P4ActionModel(actionId, new ImmutableMap.Builder<PiActionParamId, PiActionParamModel>().build());
-
actionId = PiActionId.of("_drop");
PiActionModel dropAction =
new P4ActionModel(actionId, new ImmutableMap.Builder<PiActionParamId, PiActionParamModel>().build());
-
actionId = PiActionId.of("NoAction");
PiActionModel noAction =
new P4ActionModel(actionId, new ImmutableMap.Builder<PiActionParamId, PiActionParamModel>().build());
-
actionId = PiActionId.of("table0_control.set_next_hop_id");
piActionParamId = PiActionParamId.of("next_hop_id");
bitWitdth = 16;
@@ -190,7 +216,6 @@
assertThat("action dose not match",
table0Model.actions(), IsIterableContainingInAnyOrder.containsInAnyOrder(
setEgressPortAction, sendToCpuAction, setNextHopIdAction, dropAction));
-
//check wcmp_table actions
assertThat("actions dose not match",
wcmpTableModel.actions(), IsIterableContainingInAnyOrder.containsInAnyOrder(
@@ -211,7 +236,7 @@
true, DEFAULT_MAX_ACTION_PROFILE_SIZE,
DEFAULT_MAX_GROUP_SIZE);
PiActionProfileModel wcmpSelector = model.actionProfiles(actionProfileId).orElse(null);
- PiActionProfileModel wcmpSelector2 = model2.actionProfiles(actionProfileId).orElse(null);
+ PiActionProfileModel wcmpSelector2 = sameAsModel.actionProfiles(actionProfileId).orElse(null);
new EqualsTester().addEqualityGroup(wcmpSelector, wcmpSelector2, wcmpSelector3).testEquals();
@@ -232,13 +257,13 @@
model.counter(PiCounterId.of("wcmp_control.wcmp_table_counter")).orElse(null);
PiCounterModel ingressPortCounterModel2 =
- model2.counter(PiCounterId.of("port_counters_ingress.ingress_port_counter")).orElse(null);
+ sameAsModel.counter(PiCounterId.of("port_counters_ingress.ingress_port_counter")).orElse(null);
PiCounterModel egressPortCounterModel2 =
- model2.counter(PiCounterId.of("port_counters_egress.egress_port_counter")).orElse(null);
+ sameAsModel.counter(PiCounterId.of("port_counters_egress.egress_port_counter")).orElse(null);
PiCounterModel table0CounterModel2 =
- model2.counter(PiCounterId.of("table0_control.table0_counter")).orElse(null);
+ sameAsModel.counter(PiCounterId.of("table0_control.table0_counter")).orElse(null);
PiCounterModel wcmpTableCounterModel2 =
- model2.counter(PiCounterId.of("wcmp_control.wcmp_table_counter")).orElse(null);
+ sameAsModel.counter(PiCounterId.of("wcmp_control.wcmp_table_counter")).orElse(null);
new EqualsTester()
.addEqualityGroup(ingressPortCounterModel, ingressPortCounterModel2)
@@ -254,7 +279,7 @@
//Parse meters
Collection<PiMeterModel> meterModel = model.meters();
- Collection<PiMeterModel> meterModel2 = model2.meters();
+ Collection<PiMeterModel> meterModel2 = sameAsModel.meters();
assertThat("model parsed meter collection should be empty", meterModel.isEmpty(), is(true));
assertThat("model parsed meter collection should be empty", meterModel2.isEmpty(), is(true));
@@ -266,9 +291,9 @@
model.packetOperationModel(PiPacketOperationType.PACKET_OUT).orElse(null);
PiPacketOperationModel packetInOperationalModel2 =
- model2.packetOperationModel(PiPacketOperationType.PACKET_IN).orElse(null);
+ sameAsModel.packetOperationModel(PiPacketOperationType.PACKET_IN).orElse(null);
PiPacketOperationModel packetOutOperationalModel2 =
- model2.packetOperationModel(PiPacketOperationType.PACKET_OUT).orElse(null);
+ sameAsModel.packetOperationModel(PiPacketOperationType.PACKET_OUT).orElse(null);
new EqualsTester()
.addEqualityGroup(packetInOperationalModel, packetInOperationalModel2)
diff --git a/protocols/p4runtime/model/src/test/java/org/onosproject/p4runtime/model/P4PipelineModelTest.java b/protocols/p4runtime/model/src/test/java/org/onosproject/p4runtime/model/P4PipelineModelTest.java
index 3da1ffb..57c3a87 100644
--- a/protocols/p4runtime/model/src/test/java/org/onosproject/p4runtime/model/P4PipelineModelTest.java
+++ b/protocols/p4runtime/model/src/test/java/org/onosproject/p4runtime/model/P4PipelineModelTest.java
@@ -364,21 +364,25 @@
private static final int FINGER_PRINT_1 = 0;
private static final int FINGER_PRINT_2 = 1;
+ private static final String ARCHITECTURE_ID_1 = "tna";
+ private static final String ARCHITECTURE_ID_2 = "v1model";
+
+
private static final PiPipelineModel P4_PIPELINE_MODEL_1 =
new P4PipelineModel(TABLES_1, COUNTERS_1, METERS_1, REGISTERS_1, ACTION_PROFILES_1, PACKET_OPERATIONS_1,
- FINGER_PRINT_1);
+ ARCHITECTURE_ID_1, FINGER_PRINT_1);
private static final PiPipelineModel SAME_AS_P4_PIPELINE_MODEL_1 =
new P4PipelineModel(TABLES_1, COUNTERS_1, METERS_1, REGISTERS_1, ACTION_PROFILES_1, PACKET_OPERATIONS_1,
- FINGER_PRINT_1);
+ ARCHITECTURE_ID_1, FINGER_PRINT_1);
private static final PiPipelineModel P4_PIPELINE_MODEL_2 =
new P4PipelineModel(TABLES_2, COUNTERS_2, METERS_2, REGISTERS_1, ACTION_PROFILES_2, PACKET_OPERATIONS_2,
- FINGER_PRINT_2);
+ ARCHITECTURE_ID_2, FINGER_PRINT_2);
private static final PiPipelineModel P4_PIPELINE_MODEL_3 =
new P4PipelineModel(TABLES_2, COUNTERS_2, METERS_2, REGISTERS_1, ACTION_PROFILES_2, PACKET_OPERATIONS_3,
- FINGER_PRINT_2);
+ ARCHITECTURE_ID_2, FINGER_PRINT_2);
private static final PiPipelineModel P4_PIPELINE_MODEL_4 =
new P4PipelineModel(TABLES_3, COUNTERS_2, METERS_2, REGISTERS_1, ACTION_PROFILES_2, PACKET_OPERATIONS_3,
- FINGER_PRINT_2);
+ ARCHITECTURE_ID_2, FINGER_PRINT_2);
/**
* Checks that the P4PipelineModel class is immutable.