use of org.onosproject.net.pi.model.PiActionParamModel in project onos by opennetworkinglab.
the class PiFlowRuleTranslatorImpl method checkPiAction.
private static PiTableAction checkPiAction(PiAction piAction, PiTableModel table) throws PiTranslationException {
// Table supports this action?
PiActionModel actionModel = table.action(piAction.id()).orElseThrow(() -> new PiTranslationException(format("Not such action '%s' for table '%s'", 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.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()).orElseThrow(() -> new PiTranslationException(format("Not such parameter '%s' for action '%s'", param.id(), actionModel)));
try {
newActionBuilder.withParameter(new PiActionParam(param.id(), paramModel.hasBitWidth() ? param.value().fit(paramModel.bitWidth()) : param.value()));
} catch (ByteSequenceTrimException e) {
throw new PiTranslationException(format("Size mismatch for parameter '%s' of action '%s': %s", param.id(), piAction.id(), e.getMessage()));
}
}
return newActionBuilder.build();
}
use of org.onosproject.net.pi.model.PiActionParamModel in project onos by opennetworkinglab.
the class P4InfoParserTest method testParseP4RuntimeTranslationAndOptional.
/**
* Tests parse method with P4Runtime translation fields and optional fields.
* @throws Exception if equality group objects dose not match as expected
*/
@Test
public void testParseP4RuntimeTranslationAndOptional() throws Exception {
PiPipelineModel model = P4InfoParser.parse(p4InfoUrl2);
// Generate a P4Info object from the file
final P4Info p4info;
try {
p4info = getP4InfoMessage(p4InfoUrl2);
} catch (IOException e) {
throw new P4InfoParserException("Unable to parse protobuf " + p4InfoUrl.toString(), e);
}
List<Table> tableMsgs = p4info.getTablesList();
PiTableId table0Id = PiTableId.of(tableMsgs.get(0).getPreamble().getName());
// parse tables
PiTableModel table0Model = model.table(table0Id).orElse(null);
// Check matchFields
List<MatchField> matchFieldList = tableMsgs.get(0).getMatchFieldsList();
List<PiMatchFieldModel> piMatchFieldList = new ArrayList<>();
for (MatchField matchFieldIter : matchFieldList) {
MatchField.MatchType matchType = matchFieldIter.getMatchType();
PiMatchType piMatchType;
switch(matchType) {
case EXACT:
piMatchType = PiMatchType.EXACT;
break;
case LPM:
piMatchType = PiMatchType.LPM;
break;
case TERNARY:
piMatchType = PiMatchType.TERNARY;
break;
case RANGE:
piMatchType = PiMatchType.RANGE;
break;
case OPTIONAL:
piMatchType = PiMatchType.OPTIONAL;
break;
default:
Assert.fail();
return;
}
if (matchFieldIter.getTypeName().getName().equals("mac_addr_t")) {
piMatchFieldList.add(new P4MatchFieldModel(PiMatchFieldId.of(matchFieldIter.getName()), P4MatchFieldModel.BIT_WIDTH_UNDEFINED, piMatchType));
} else {
piMatchFieldList.add(new P4MatchFieldModel(PiMatchFieldId.of(matchFieldIter.getName()), matchFieldIter.getBitwidth(), piMatchType));
}
}
assertThat("Incorrect order for matchFields", table0Model.matchFields(), IsIterableContainingInOrder.contains(piMatchFieldList.get(0), piMatchFieldList.get(1), piMatchFieldList.get(2), piMatchFieldList.get(3)));
// check table0 actionsRefs
List<ActionRef> actionRefList = tableMsgs.get(0).getActionRefsList();
assertThat("Incorrect size for actionRefs", actionRefList.size(), is(equalTo(4)));
// create action instances
// Set egress with string as parameter
PiActionId actionId = PiActionId.of("set_egress_port");
PiActionParamId piActionParamId = PiActionParamId.of("port");
PiActionParamModel actionParamModel = new P4ActionParamModel(piActionParamId, P4ActionParamModel.BIT_WIDTH_UNDEFINED);
ImmutableMap<PiActionParamId, PiActionParamModel> params = new ImmutableMap.Builder<PiActionParamId, PiActionParamModel>().put(piActionParamId, actionParamModel).build();
PiActionModel setEgressPortAction = new P4ActionModel(actionId, params);
// Set egress with 32 bit as parameter
actionId = PiActionId.of("set_egress_port2");
piActionParamId = PiActionParamId.of("port");
int bitWitdth = 32;
actionParamModel = new P4ActionParamModel(piActionParamId, bitWitdth);
params = new ImmutableMap.Builder<PiActionParamId, PiActionParamModel>().put(piActionParamId, actionParamModel).build();
PiActionModel setEgressPortAction2 = new P4ActionModel(actionId, params);
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());
// check table0 actions
assertThat("action dose not match", table0Model.actions(), IsIterableContainingInAnyOrder.containsInAnyOrder(setEgressPortAction, setEgressPortAction2, sendToCpuAction, dropAction));
}
use of org.onosproject.net.pi.model.PiActionParamModel in project onos by opennetworkinglab.
the class P4InfoParser method parseActions.
private static Map<Integer, PiActionModel> parseActions(P4Info p4info) {
final Map<Integer, PiActionModel> actionMap = Maps.newHashMap();
for (Action actionMsg : p4info.getActionsList()) {
final ImmutableMap.Builder<PiActionParamId, PiActionParamModel> paramMapBuilder = ImmutableMap.builder();
actionMsg.getParamsList().forEach(paramMsg -> {
final PiActionParamId paramId = PiActionParamId.of(paramMsg.getName());
paramMapBuilder.put(paramId, new P4ActionParamModel(PiActionParamId.of(paramMsg.getName()), isFieldString(p4info, paramMsg.getTypeName().getName()) ? P4ActionParamModel.BIT_WIDTH_UNDEFINED : paramMsg.getBitwidth()));
});
actionMap.put(actionMsg.getPreamble().getId(), new P4ActionModel(PiActionId.of(actionMsg.getPreamble().getName()), paramMapBuilder.build()));
}
return actionMap;
}
use of org.onosproject.net.pi.model.PiActionParamModel in project onos by opennetworkinglab.
the class P4InfoParserTest method testParse.
/**
* Tests parse method.
* @throws Exception if equality group objects dose not match as expected
*/
@Test
public void testParse() throws Exception {
// Generate two PiPipelineModels from the same p4Info file
PiPipelineModel model = P4InfoParser.parse(p4InfoUrl);
PiPipelineModel sameAsModel = P4InfoParser.parse(p4InfoUrl);
// Check equality
new EqualsTester().addEqualityGroup(model, sameAsModel).testEquals();
// Generate a P4Info object from the file
final P4Info p4info;
try {
p4info = getP4InfoMessage(p4InfoUrl);
} catch (IOException e) {
throw new P4InfoParserException("Unable to parse protobuf " + p4InfoUrl.toString(), e);
}
List<Table> tableMsgs = p4info.getTablesList();
PiTableId table0Id = PiTableId.of(tableMsgs.get(0).getPreamble().getName());
PiTableId wcmpTableId = PiTableId.of(tableMsgs.get(1).getPreamble().getName());
PiTableId wcmpTableOneShotId = PiTableId.of(tableMsgs.get(2).getPreamble().getName());
// parse tables
PiTableModel table0Model = model.table(table0Id).orElse(null);
PiTableModel wcmpTableModel = model.table(wcmpTableId).orElse(null);
PiTableModel wcmpTableOneShotModel = model.table(wcmpTableOneShotId).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
assertThat("model parsed value is null", table0Model, notNullValue());
assertThat("model parsed value is null", wcmpTableModel, notNullValue());
assertThat("model parsed value is null", wcmpTableOneShotModel, notNullValue());
assertThat("Incorrect size for table0 size", table0Model.maxSize(), is(equalTo(DEFAULT_MAX_TABLE_SIZE)));
assertThat("Incorrect size for wcmp_table size", wcmpTableModel.maxSize(), is(equalTo(DEFAULT_MAX_TABLE_SIZE)));
assertThat("Incorrect size for wcmp_table_one_shot size", wcmpTableOneShotModel.maxSize(), is(equalTo(DEFAULT_MAX_TABLE_SIZE)));
// Check one-shot annotation
assertThat("error parsing one-shot annotation", wcmpTableModel.oneShotOnly(), is(false));
assertThat("error parsing one-shot annotation", wcmpTableOneShotModel.oneShotOnly(), is(true));
// Check matchFields
List<MatchField> matchFieldList = tableMsgs.get(0).getMatchFieldsList();
List<PiMatchFieldModel> piMatchFieldList = new ArrayList<>();
for (MatchField matchFieldIter : matchFieldList) {
MatchField.MatchType matchType = matchFieldIter.getMatchType();
PiMatchType piMatchType;
switch(matchType) {
case EXACT:
piMatchType = PiMatchType.EXACT;
break;
case LPM:
piMatchType = PiMatchType.LPM;
break;
case TERNARY:
piMatchType = PiMatchType.TERNARY;
break;
case RANGE:
piMatchType = PiMatchType.RANGE;
break;
default:
Assert.fail();
return;
}
piMatchFieldList.add(new P4MatchFieldModel(PiMatchFieldId.of(matchFieldIter.getName()), matchFieldIter.getBitwidth(), piMatchType));
}
// Check MatchFields size
assertThat("Incorrect size for matchFields", table0Model.matchFields().size(), is(equalTo(9)));
// Check if matchFields are in order
assertThat("Incorrect order for matchFields", table0Model.matchFields(), IsIterableContainingInOrder.contains(piMatchFieldList.get(0), piMatchFieldList.get(1), piMatchFieldList.get(2), piMatchFieldList.get(3), piMatchFieldList.get(4), piMatchFieldList.get(5), 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");
int bitWitdth = 9;
PiActionParamModel actionParamModel = new P4ActionParamModel(piActionParamId, bitWitdth);
ImmutableMap<PiActionParamId, PiActionParamModel> params = new ImmutableMap.Builder<PiActionParamId, PiActionParamModel>().put(piActionParamId, actionParamModel).build();
PiActionModel setEgressPortAction = new P4ActionModel(actionId, params);
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;
actionParamModel = new P4ActionParamModel(piActionParamId, bitWitdth);
params = new ImmutableMap.Builder<PiActionParamId, PiActionParamModel>().put(piActionParamId, actionParamModel).build();
PiActionModel setNextHopIdAction = new P4ActionModel(actionId, params);
// check table0 actions
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(setEgressPortAction, noAction));
PiActionModel table0DefaultAction = table0Model.constDefaultAction().orElse(null);
new EqualsTester().addEqualityGroup(table0DefaultAction, dropAction).testEquals();
// Check existence
assertThat("model parsed value is null", table0DefaultAction, notNullValue());
// parse action profiles
PiTableId tableId = PiTableId.of("wcmp_control.wcmp_table");
ImmutableSet<PiTableId> tableIds = new ImmutableSet.Builder<PiTableId>().add(tableId).build();
PiActionProfileId actionProfileId = PiActionProfileId.of("wcmp_control.wcmp_selector");
PiActionProfileModel wcmpSelector3 = new P4ActionProfileModel(actionProfileId, tableIds, true, DEFAULT_MAX_ACTION_PROFILE_SIZE, DEFAULT_MAX_GROUP_SIZE);
PiActionProfileModel wcmpSelector = model.actionProfiles(actionProfileId).orElse(null);
PiActionProfileModel wcmpSelector2 = sameAsModel.actionProfiles(actionProfileId).orElse(null);
new EqualsTester().addEqualityGroup(wcmpSelector, wcmpSelector2, wcmpSelector3).testEquals();
// Check existence
assertThat("model parsed value is null", wcmpSelector, notNullValue());
assertThat("Incorrect value for actions profiles", model.actionProfiles(), containsInAnyOrder(wcmpSelector));
// ActionProfiles size
assertThat("Incorrect size for action profiles", model.actionProfiles().size(), is(equalTo(1)));
// parse counters
PiCounterModel ingressPortCounterModel = model.counter(PiCounterId.of("port_counters_ingress.ingress_port_counter")).orElse(null);
PiCounterModel egressPortCounterModel = model.counter(PiCounterId.of("port_counters_egress.egress_port_counter")).orElse(null);
PiCounterModel table0CounterModel = model.counter(PiCounterId.of("table0_control.table0_counter")).orElse(null);
PiCounterModel wcmpTableCounterModel = model.counter(PiCounterId.of("wcmp_control.wcmp_table_counter")).orElse(null);
PiCounterModel ingressPortCounterModel2 = sameAsModel.counter(PiCounterId.of("port_counters_ingress.ingress_port_counter")).orElse(null);
PiCounterModel egressPortCounterModel2 = sameAsModel.counter(PiCounterId.of("port_counters_egress.egress_port_counter")).orElse(null);
PiCounterModel table0CounterModel2 = sameAsModel.counter(PiCounterId.of("table0_control.table0_counter")).orElse(null);
PiCounterModel wcmpTableCounterModel2 = sameAsModel.counter(PiCounterId.of("wcmp_control.wcmp_table_counter")).orElse(null);
new EqualsTester().addEqualityGroup(ingressPortCounterModel, ingressPortCounterModel2).addEqualityGroup(egressPortCounterModel, egressPortCounterModel2).addEqualityGroup(table0CounterModel, table0CounterModel2).addEqualityGroup(wcmpTableCounterModel, wcmpTableCounterModel2).testEquals();
assertThat("model parsed value is null", ingressPortCounterModel, notNullValue());
assertThat("model parsed value is null", egressPortCounterModel, notNullValue());
assertThat("model parsed value is null", table0CounterModel, notNullValue());
assertThat("model parsed value is null", wcmpTableCounterModel, notNullValue());
// Parse meters
Collection<PiMeterModel> meterModel = model.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));
// parse packet operations
PiPacketOperationModel packetInOperationalModel = model.packetOperationModel(PiPacketOperationType.PACKET_IN).orElse(null);
PiPacketOperationModel packetOutOperationalModel = model.packetOperationModel(PiPacketOperationType.PACKET_OUT).orElse(null);
PiPacketOperationModel packetInOperationalModel2 = sameAsModel.packetOperationModel(PiPacketOperationType.PACKET_IN).orElse(null);
PiPacketOperationModel packetOutOperationalModel2 = sameAsModel.packetOperationModel(PiPacketOperationType.PACKET_OUT).orElse(null);
new EqualsTester().addEqualityGroup(packetInOperationalModel, packetInOperationalModel2).addEqualityGroup(packetOutOperationalModel, packetOutOperationalModel2).testEquals();
// Check existence
assertThat("model parsed value is null", packetInOperationalModel, notNullValue());
assertThat("model parsed value is null", packetOutOperationalModel, notNullValue());
}
Aggregations