use of org.onosproject.net.flowobjective.DefaultNextTreatment in project fabric-tna by stratum.
the class NextObjectiveTranslator method allGroup.
private int allGroup(NextObjective obj, ObjectiveTranslation.Builder resultBuilder) throws FabricPipelinerException {
final Collection<DefaultNextTreatment> defaultNextTreatments = defaultNextTreatments(obj.nextTreatments(), true);
// multicast entries is based solely on the output port.
for (DefaultNextTreatment t : defaultNextTreatments) {
handleEgress(obj, t.treatment(), resultBuilder, true);
}
// FIXME: this implementation supports only the case in which each
// switch interface is associated with only one VLAN, otherwise we would
// need to support replicating multiple times the same packet for the
// same port while setting different VLAN IDs. Hence, collect in a set.
final Set<PortNumber> outPorts = defaultNextTreatments.stream().map(DefaultNextTreatment::treatment).map(FabricUtils::outputPort).filter(Objects::nonNull).collect(Collectors.toSet());
if (outPorts.size() != defaultNextTreatments.size()) {
throw new FabricPipelinerException(format("Found BROADCAST NextObjective with %d treatments but " + "found only %d distinct OUTPUT port numbers, cannot " + "translate to ALL groups", defaultNextTreatments.size(), outPorts.size()), ObjectiveError.UNSUPPORTED);
}
final List<GroupBucket> bucketList = outPorts.stream().map(p -> DefaultTrafficTreatment.builder().setOutput(p).build()).map(DefaultGroupBucket::createAllGroupBucket).collect(Collectors.toList());
final int groupId = obj.id();
// Use DefaultGroupKey instead of PiGroupKey as we don't have any
// action profile to apply to the groups of ALL type.
final GroupKey groupKey = getGroupKey(obj);
resultBuilder.addGroup(new DefaultGroupDescription(deviceId, GroupDescription.Type.ALL, new GroupBuckets(bucketList), groupKey, groupId, obj.appId()));
return groupId;
}
use of org.onosproject.net.flowobjective.DefaultNextTreatment in project fabric-tna by stratum.
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 = P4InfoConstants.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.flowobjective.DefaultNextTreatment in project fabric-tna by stratum.
the class NextObjectiveTranslator method defaultNextTreatments.
private List<DefaultNextTreatment> defaultNextTreatments(Collection<NextTreatment> nextTreatments, boolean strict) throws FabricPipelinerException {
final List<DefaultNextTreatment> defaultNextTreatments = Lists.newArrayList();
final List<NextTreatment> unsupportedNextTreatments = Lists.newArrayList();
for (NextTreatment n : nextTreatments) {
if (n.type() == NextTreatment.Type.TREATMENT) {
defaultNextTreatments.add((DefaultNextTreatment) n);
} else {
unsupportedNextTreatments.add(n);
}
}
if (strict && !unsupportedNextTreatments.isEmpty()) {
throw new FabricPipelinerException(format("Unsupported NextTreatments: %s", unsupportedNextTreatments));
}
return defaultNextTreatments;
}
use of org.onosproject.net.flowobjective.DefaultNextTreatment in project fabric-tna by stratum.
the class NextObjectiveTranslator method simpleNext.
private void simpleNext(NextObjective obj, ObjectiveTranslation.Builder resultBuilder, boolean forceSimple) throws FabricPipelinerException {
if (capabilities.hasHashedTable()) {
// Use hashed table when possible.
hashedNext(obj, resultBuilder);
return;
}
if (obj.nextTreatments().isEmpty()) {
// Do nothing.
return;
} else if (!forceSimple && obj.nextTreatments().size() != 1) {
throw new FabricPipelinerException(format("SIMPLE NextObjective should contain only 1 treatment, found %d", obj.nextTreatments().size()), ObjectiveError.BADPARAMS);
}
final TrafficSelector selector = nextIdSelector(obj.id());
final List<DefaultNextTreatment> treatments = defaultNextTreatments(obj.nextTreatments(), true);
if (forceSimple && treatments.size() > 1) {
log.warn("Forcing SIMPLE behavior for NextObjective with {} treatments [{}]", treatments.size(), obj);
}
// handleEgress(obj, treatment, resultBuilder, false);
throw new FabricPipelinerException("Simple next table not supported", ObjectiveError.UNSUPPORTED);
}
use of org.onosproject.net.flowobjective.DefaultNextTreatment in project fabric-tna by stratum.
the class NextObjectiveTranslator method nextMpls.
private void nextMpls(NextObjective obj, ObjectiveTranslation.Builder resultBuilder) throws FabricPipelinerException {
// Next objective can contain only one mpls push and one mpls label
// instruction. Pipeliner does not support other configurations.
final List<List<ModMplsLabelInstruction>> mplsInstructions = defaultNextTreatments(obj.nextTreatments(), false).stream().map(defaultNextTreatment -> l2Instructions(defaultNextTreatment.treatment(), MPLS_LABEL).stream().map(v -> (ModMplsLabelInstruction) v).collect(Collectors.toList())).filter(l -> !l.isEmpty()).collect(Collectors.toList());
if (mplsInstructions.isEmpty()) {
// No need to apply next mpls table
return;
}
// We expect one mpls label for each treatment and the label has to be the same
final Set<MplsLabel> mplsLabels = mplsInstructions.stream().flatMap(Collection::stream).map(ModMplsLabelInstruction::label).collect(Collectors.toSet());
if (obj.nextTreatments().size() != mplsInstructions.size() || mplsLabels.size() != 1) {
throw new FabricPipelinerException("Inconsistent MPLS_LABEL instructions, cannot process " + "next_mpls rule. It is required that all " + "treatments have the same MPLS_LABEL instructions.");
}
final TrafficSelector selector = nextIdSelector(obj.id());
final TrafficTreatment treatment = DefaultTrafficTreatment.builder().setMpls(mplsLabels.iterator().next()).build();
resultBuilder.addFlowRule(flowRule(obj, P4InfoConstants.FABRIC_INGRESS_PRE_NEXT_NEXT_MPLS, selector, treatment));
}
Aggregations