Added support for clone session on fabric.p4
Now on ACL table in fabric.p4 you can clone a packet to the CPU using the clone session.
Change-Id: Ic21f948cffe553e32e7b2fe1f7af49b6a387fffb
diff --git a/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/pipeliner/ForwardingObjectiveTranslator.java b/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/pipeliner/ForwardingObjectiveTranslator.java
index 5647d26..066af7d 100644
--- a/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/pipeliner/ForwardingObjectiveTranslator.java
+++ b/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/pipeliner/ForwardingObjectiveTranslator.java
@@ -18,11 +18,14 @@
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.MacAddress;
+import org.onosproject.core.ApplicationId;
import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.DefaultTrafficTreatment;
import org.onosproject.net.flow.FlowRule;
@@ -34,7 +37,14 @@
import org.onosproject.net.flow.criteria.MplsCriterion;
import org.onosproject.net.flow.criteria.VlanIdCriterion;
import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.net.flowobjective.Objective;
import org.onosproject.net.flowobjective.ObjectiveError;
+import org.onosproject.net.group.DefaultGroupDescription;
+import org.onosproject.net.group.GroupBucket;
+import org.onosproject.net.group.GroupBuckets;
+import org.onosproject.net.group.DefaultGroupKey;
+import org.onosproject.net.group.GroupDescription;
+import org.onosproject.net.group.GroupKey;
import org.onosproject.net.pi.model.PiActionId;
import org.onosproject.net.pi.model.PiTableId;
import org.onosproject.net.pi.runtime.PiAction;
@@ -49,6 +59,9 @@
import static java.lang.String.format;
import static org.onosproject.pipelines.fabric.FabricUtils.criterionNotNull;
+import static org.onosproject.pipelines.fabric.FabricUtils.outputPort;
+import static org.onosproject.net.group.DefaultGroupBucket.createCloneGroupBucket;
+
/**
* ObjectiveTranslator implementation ForwardingObjective.
@@ -56,6 +69,8 @@
class ForwardingObjectiveTranslator
extends AbstractObjectiveTranslator<ForwardingObjective> {
+ //FIXME: Max number supported by PI
+ static final int CLONE_TO_CPU_ID = 511;
private static final List<String> DEFAULT_ROUTE_PREFIXES = Lists.newArrayList(
"0.0.0.0/1", "128.0.0.0/1");
@@ -245,11 +260,64 @@
private void aclRule(ForwardingObjective obj,
ObjectiveTranslation.Builder resultBuilder)
throws FabricPipelinerException {
+ if (obj.nextId() == null && obj.treatment() != null) {
+ final TrafficTreatment treatment = obj.treatment();
+ final PortNumber outPort = outputPort(treatment);
+ if (outPort != null
+ && outPort.equals(PortNumber.CONTROLLER)
+ && treatment.allInstructions().size() == 1) {
+ final PiAction aclAction;
+ if (treatment.clearedDeferred()) {
+ aclAction = PiAction.builder()
+ .withId(FabricConstants.FABRIC_INGRESS_ACL_PUNT_TO_CPU)
+ .build();
+ } else {
+ // Action is SET_CLONE_SESSION_ID
+ if (obj.op() == Objective.Operation.ADD) {
+ // Action is ADD, create clone group
+ final DefaultGroupDescription cloneGroup =
+ createCloneGroup(obj.appId(),
+ CLONE_TO_CPU_ID,
+ outPort);
+ resultBuilder.addGroup(cloneGroup);
+ }
+ aclAction = PiAction.builder()
+ .withId(FabricConstants.FABRIC_INGRESS_ACL_SET_CLONE_SESSION_ID)
+ .withParameter(new PiActionParam(
+ FabricConstants.CLONE_ID, CLONE_TO_CPU_ID))
+ .build();
+ }
+ final TrafficTreatment piTreatment = DefaultTrafficTreatment.builder()
+ .piTableAction(aclAction)
+ .build();
+ resultBuilder.addFlowRule(flowRule(
+ obj, FabricConstants.FABRIC_INGRESS_ACL_ACL, obj.selector(), piTreatment));
+ return;
+ }
+ }
resultBuilder.addFlowRule(flowRule(
obj, FabricConstants.FABRIC_INGRESS_ACL_ACL, obj.selector()));
}
+ private DefaultGroupDescription createCloneGroup(
+ ApplicationId appId,
+ int cloneSessionId,
+ PortNumber outPort) {
+ final GroupKey groupKey = new DefaultGroupKey(
+ FabricPipeliner.KRYO.serialize(cloneSessionId));
+
+ final List<GroupBucket> bucketList = ImmutableList.of(
+ createCloneGroupBucket(DefaultTrafficTreatment.builder()
+ .setOutput(outPort)
+ .build()));
+ final DefaultGroupDescription cloneGroup = new DefaultGroupDescription(
+ deviceId, GroupDescription.Type.CLONE,
+ new GroupBuckets(bucketList),
+ groupKey, cloneSessionId, appId);
+ return cloneGroup;
+ }
+
private FlowRule flowRule(
ForwardingObjective obj, PiTableId tableId, TrafficSelector selector)
throws FabricPipelinerException {