use of org.onosproject.net.pi.model.PiTableId in project onos by opennetworkinglab.
the class PiFlowRuleTranslatorImpl method translate.
/**
* Returns a PI table entry equivalent to the given flow rule, for the given
* pipeconf and device.
*
* @param rule flow rule
* @param pipeconf pipeconf
* @param device device
* @return PI table entry
* @throws PiTranslationException if the flow rule cannot be translated
*/
static PiTableEntry translate(FlowRule rule, PiPipeconf pipeconf, Device device) throws PiTranslationException {
PiPipelineModel pipelineModel = pipeconf.pipelineModel();
// Retrieve interpreter, if any.
final PiPipelineInterpreter interpreter = getInterpreterOrNull(device, pipeconf);
// Get table model.
final PiTableId piTableId = translateTableId(rule.table(), interpreter);
final PiTableModel tableModel = getTableModel(piTableId, pipelineModel);
// Translate selector.
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 = tableModel.matchFields().stream().anyMatch(match -> match.matchType() == PiMatchType.TERNARY || match.matchType() == PiMatchType.RANGE || match.matchType() == PiMatchType.OPTIONAL);
}
// Translate treatment.
final PiTableAction piTableAction = translateTreatment(rule.treatment(), interpreter, piTableId, pipelineModel);
// Build PI entry.
final PiTableEntry.Builder tableEntryBuilder = PiTableEntry.builder();
tableEntryBuilder.forTable(piTableId).withMatchKey(piMatchKey);
if (piTableAction != null) {
tableEntryBuilder.withAction(piTableAction);
}
if (needPriority) {
// FIXME: move priority check to P4Runtime driver.
final int newPriority;
if (rule.priority() > MAX_PI_PRIORITY) {
log.warn("Flow rule priority too big, setting translated priority to max value {}: {}", MAX_PI_PRIORITY, rule);
newPriority = MAX_PI_PRIORITY;
} else {
newPriority = MIN_PI_PRIORITY + rule.priority();
}
tableEntryBuilder.withPriority(newPriority);
}
if (!rule.isPermanent()) {
if (tableModel.supportsAging()) {
tableEntryBuilder.withTimeout(rule.timeout());
} else {
log.debug("Flow rule is temporary, but table '{}' doesn't support " + "aging, translating to permanent.", tableModel.id());
}
}
return tableEntryBuilder.build();
}
use of org.onosproject.net.pi.model.PiTableId in project onos by opennetworkinglab.
the class P4RuntimeTableStatisticsDiscovery method getTableStatistics.
@Override
public List<TableStatisticsEntry> getTableStatistics() {
if (!setupBehaviour("getTableStatistics()")) {
return Collections.emptyList();
}
FlowRuleService flowService = handler().get(FlowRuleService.class);
PiPipelineInterpreter interpreter = getInterpreter(handler());
PiPipelineModel model = pipeconf.pipelineModel();
List<TableStatisticsEntry> tableStatsList;
List<FlowEntry> rules = newArrayList(flowService.getFlowEntries(deviceId));
Map<PiTableId, Integer> piTableFlowCount = piFlowRuleCounting(model, interpreter, rules);
Map<PiTableId, Long> piTableMatchCount = piMatchedCounting(model, interpreter, rules);
tableStatsList = generatePiFlowTableStatistics(piTableFlowCount, piTableMatchCount, model, deviceId);
return tableStatsList;
}
use of org.onosproject.net.pi.model.PiTableId in project onos by opennetworkinglab.
the class NextObjectiveTranslator method selectGroup.
private int selectGroup(NextObjective obj, ObjectiveTranslation.Builder resultBuilder) throws FabricPipelinerException {
final PiTableId hashedTableId = FabricConstants.FABRIC_INGRESS_NEXT_HASHED;
final List<DefaultNextTreatment> defaultNextTreatments = defaultNextTreatments(obj.nextTreatments(), true);
final List<TrafficTreatment> piTreatments = Lists.newArrayList();
for (DefaultNextTreatment t : defaultNextTreatments) {
// Map treatment to PI...
piTreatments.add(mapTreatmentToPiIfNeeded(t.treatment(), hashedTableId));
// ...and handle egress if necessary.
handleEgress(obj, t.treatment(), resultBuilder, false);
}
final List<GroupBucket> bucketList = piTreatments.stream().map(DefaultGroupBucket::createSelectGroupBucket).collect(Collectors.toList());
final int groupId = obj.id();
final PiGroupKey groupKey = (PiGroupKey) getGroupKey(obj);
resultBuilder.addGroup(new DefaultGroupDescription(deviceId, GroupDescription.Type.SELECT, new GroupBuckets(bucketList), groupKey, groupId, obj.appId()));
return groupId;
}
use of org.onosproject.net.pi.model.PiTableId in project onos by opennetworkinglab.
the class NextObjectiveTranslator method indirectGroup.
private int indirectGroup(NextObjective obj, ObjectiveTranslation.Builder resultBuilder) throws FabricPipelinerException {
if (isGroupModifyOp(obj)) {
throw new FabricPipelinerException("Simple next objective does not support" + "*_TO_EXISTING operations");
}
final PiTableId hashedTableId = FabricConstants.FABRIC_INGRESS_NEXT_HASHED;
final List<DefaultNextTreatment> defaultNextTreatments = defaultNextTreatments(obj.nextTreatments(), true);
if (defaultNextTreatments.size() != 1) {
throw new FabricPipelinerException("Simple next objective must have a single" + " treatment");
}
final TrafficTreatment piTreatment;
final DefaultNextTreatment defaultNextTreatment = defaultNextTreatments.get(0);
piTreatment = mapTreatmentToPiIfNeeded(defaultNextTreatment.treatment(), hashedTableId);
handleEgress(obj, defaultNextTreatment.treatment(), resultBuilder, false);
final GroupBucket groupBucket = DefaultGroupBucket.createIndirectGroupBucket(piTreatment);
final int groupId = obj.id();
final PiGroupKey groupKey = (PiGroupKey) getGroupKey(obj);
resultBuilder.addGroup(new DefaultGroupDescription(deviceId, GroupDescription.Type.INDIRECT, new GroupBuckets(Collections.singletonList(groupBucket)), groupKey, groupId, obj.appId()));
return groupId;
}
use of org.onosproject.net.pi.model.PiTableId 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));
}
Aggregations