diff --git a/core/net/src/main/java/org/onosproject/net/pi/impl/PiGroupTranslatorImpl.java b/core/net/src/main/java/org/onosproject/net/pi/impl/PiGroupTranslatorImpl.java index e06f54ea35..4bf4330f39 100644 --- a/core/net/src/main/java/org/onosproject/net/pi/impl/PiGroupTranslatorImpl.java +++ b/core/net/src/main/java/org/onosproject/net/pi/impl/PiGroupTranslatorImpl.java @@ -173,7 +173,10 @@ final class PiGroupTranslatorImpl { .withAction((PiAction) tableAction) .build(); - piActionGroupBuilder.addMember(member, bucket.weight()); + // NOTE Indirect groups have weight set to -1 which is not supported + // by P4RT - setting to 1 to avoid problems with the p4rt server. + final int weight = group.type() == GroupDescription.Type.INDIRECT ? 1 : bucket.weight(); + piActionGroupBuilder.addMember(member, weight); } return piActionGroupBuilder.build(); diff --git a/drivers/p4runtime/src/main/java/org/onosproject/drivers/p4runtime/P4RuntimeGroupProgrammable.java b/drivers/p4runtime/src/main/java/org/onosproject/drivers/p4runtime/P4RuntimeGroupProgrammable.java index f38b504760..80da11ddda 100644 --- a/drivers/p4runtime/src/main/java/org/onosproject/drivers/p4runtime/P4RuntimeGroupProgrammable.java +++ b/drivers/p4runtime/src/main/java/org/onosproject/drivers/p4runtime/P4RuntimeGroupProgrammable.java @@ -51,6 +51,7 @@ public class P4RuntimeGroupProgrammable final List preGroups = Lists.newArrayList(); groupOps.operations().forEach(op -> { switch (op.groupType()) { + case INDIRECT: case SELECT: actionGroups.add(op); break; @@ -59,7 +60,6 @@ public class P4RuntimeGroupProgrammable preGroups.add(op); break; case FAILOVER: - case INDIRECT: default: log.warn("{} group type not supported [{}]", op.groupType(), op); } diff --git a/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/NextObjectiveTranslator.java b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/NextObjectiveTranslator.java index 47b7ef6d14..037e5dd587 100644 --- a/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/NextObjectiveTranslator.java +++ b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/NextObjectiveTranslator.java @@ -53,6 +53,7 @@ import org.onosproject.pipelines.fabric.FabricConstants; import org.onosproject.pipelines.fabric.impl.behaviour.FabricUtils; import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.Set; @@ -268,8 +269,18 @@ class NextObjectiveTranslator return; } - // Updated result builder with hashed group. - final int groupId = selectGroup(obj, resultBuilder); + // Updated result builder with hashed group or indirect group + // use indirect group allow us to optimize the resource in those + // devices that preallocate memory based on the maxGroupSize + final int groupId; + if (obj.type() == NextObjective.Type.HASHED) { + groupId = selectGroup(obj, resultBuilder); + } else if (obj.type() == NextObjective.Type.SIMPLE) { + groupId = indirectGroup(obj, resultBuilder); + } else { + throw new FabricPipelinerException("Cannot translate BROADCAST next objective" + + "into hashedNext actions"); + } if (isGroupModifyOp(obj) || obj.op() == Objective.Operation.VERIFY) { // No changes to flow rules. @@ -505,6 +516,44 @@ class NextObjectiveTranslator return groupId; } + 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 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; + } + private List defaultNextTreatments( Collection nextTreatments, boolean strict) throws FabricPipelinerException {