Adds OfdpaPipelineUtility
Change-Id: I96086e408dd9d7265325414dace512b64a048e9a
diff --git a/drivers/default/src/main/java/org/onosproject/driver/pipeline/XpliantPipeline.java b/drivers/default/src/main/java/org/onosproject/driver/pipeline/XpliantPipeline.java
index 3d09258..b5b202d 100644
--- a/drivers/default/src/main/java/org/onosproject/driver/pipeline/XpliantPipeline.java
+++ b/drivers/default/src/main/java/org/onosproject/driver/pipeline/XpliantPipeline.java
@@ -22,6 +22,8 @@
import org.onosproject.driver.pipeline.ofdpa.Ofdpa3Pipeline;
import java.util.Collection;
+import static org.onosproject.driver.pipeline.ofdpa.OfdpaPipelineUtility.ACL_TABLE;
+
public class XpliantPipeline extends Ofdpa3Pipeline {
@Override
diff --git a/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/Ofdpa2GroupHandler.java b/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/Ofdpa2GroupHandler.java
index 52d5382..7db00a8 100644
--- a/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/Ofdpa2GroupHandler.java
+++ b/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/Ofdpa2GroupHandler.java
@@ -90,6 +90,7 @@
import static org.onlab.util.Tools.groupedThreads;
import static org.onosproject.driver.pipeline.ofdpa.Ofdpa2Pipeline.*;
+import static org.onosproject.driver.pipeline.ofdpa.OfdpaPipelineUtility.*;
import static org.onosproject.driver.pipeline.ofdpa.OfdpaGroupHandlerUtility.*;
import static org.onosproject.driver.pipeline.ofdpa.OfdpaGroupHandlerUtility.L2_MULTICAST_TYPE;
import static org.onosproject.driver.pipeline.ofdpa.OfdpaGroupHandlerUtility.l2MulticastGroupKey;
diff --git a/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/Ofdpa2Pipeline.java b/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/Ofdpa2Pipeline.java
index f4ab685..071bf98 100644
--- a/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/Ofdpa2Pipeline.java
+++ b/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/Ofdpa2Pipeline.java
@@ -47,7 +47,6 @@
import org.onosproject.net.behaviour.PipelinerContext;
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.driver.AbstractHandlerBehaviour;
-import org.onosproject.net.driver.Driver;
import org.onosproject.net.flow.DefaultFlowRule;
import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.DefaultTrafficTreatment;
@@ -61,8 +60,6 @@
import org.onosproject.net.flow.criteria.Criterion;
import org.onosproject.net.flow.criteria.EthCriterion;
import org.onosproject.net.flow.criteria.EthTypeCriterion;
-import org.onosproject.net.flow.criteria.ExtensionCriterion;
-import org.onosproject.net.flow.criteria.ExtensionSelector;
import org.onosproject.net.flow.criteria.IPCriterion;
import org.onosproject.net.flow.criteria.Icmpv6CodeCriterion;
import org.onosproject.net.flow.criteria.Icmpv6TypeCriterion;
@@ -77,8 +74,6 @@
import org.onosproject.net.flow.instructions.Instructions.NoActionInstruction;
import org.onosproject.net.flow.instructions.L2ModificationInstruction;
import org.onosproject.net.flow.instructions.L2ModificationInstruction.L2SubType;
-import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction;
-import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModMplsHeaderInstruction;
import org.onosproject.net.flow.instructions.L3ModificationInstruction;
import org.onosproject.net.flow.instructions.L3ModificationInstruction.L3SubType;
@@ -117,7 +112,7 @@
import static org.onosproject.driver.extensions.Ofdpa3CopyField.OXM_ID_PACKET_REG_1;
import static org.onosproject.driver.extensions.Ofdpa3CopyField.OXM_ID_VLAN_VID;
import static org.onosproject.driver.pipeline.ofdpa.OfdpaGroupHandlerUtility.*;
-import static org.onosproject.net.flow.criteria.Criterion.Type.ETH_TYPE;
+import static org.onosproject.driver.pipeline.ofdpa.OfdpaPipelineUtility.*;
import static org.onosproject.net.group.GroupDescription.Type.SELECT;
import static org.slf4j.LoggerFactory.getLogger;
import static org.onosproject.net.flow.criteria.Criterion.Type.MPLS_BOS;
@@ -129,43 +124,7 @@
// Timer for the accumulator
private static final Timer TIMER = new Timer("fwdobj-batching");
private Accumulator<Pair<ForwardingObjective, Collection<FlowRule>>> accumulator;
-
- protected static final int PORT_TABLE = 0;
- protected static final int VLAN_TABLE = 10;
- protected static final int VLAN_1_TABLE = 11;
- protected static final int MPLS_L2_PORT_FLOW_TABLE = 13;
- protected static final int MPLS_L2_PORT_PCP_TRUST_FLOW_TABLE = 16;
- protected static final int TMAC_TABLE = 20;
- protected static final int UNICAST_ROUTING_TABLE = 30;
- protected static final int MULTICAST_ROUTING_TABLE = 40;
- protected static final int MPLS_TABLE_0 = 23;
- protected static final int MPLS_TABLE_1 = 24;
- protected static final int MPLS_L3_TYPE_TABLE = 27;
- protected static final int MPLS_TYPE_TABLE = 29;
- protected static final int BRIDGING_TABLE = 50;
- protected static final int ACL_TABLE = 60;
- protected static final int EGRESS_VLAN_FLOW_TABLE = 210;
- protected static final int EGRESS_DSCP_PCP_REMARK_FLOW_TABLE = 230;
- protected static final int EGRESS_TPID_FLOW_TABLE = 235;
- protected static final int MAC_LEARNING_TABLE = 254;
- protected static final long OFPP_MAX = 0xffffff00L;
-
- protected static final int HIGHEST_PRIORITY = 0xffff;
- protected static final int DEFAULT_PRIORITY = 0x8000;
- protected static final int LOWEST_PRIORITY = 0x0;
-
- protected static final int MPLS_L2_PORT_PRIORITY = 2;
- protected static final int MPLS_TUNNEL_ID_BASE = 0x10000;
- protected static final int MPLS_TUNNEL_ID_MAX = 0x1FFFF;
-
- protected static final int MPLS_UNI_PORT_MAX = 0x0000FFFF;
- protected static final int MPLS_NNI_PORT_BASE = 0x00020000;
- protected static final int MPLS_NNI_PORT_MAX = 0x0002FFFF;
-
- protected static final short ALLOW_VLAN_TRANSLATION = 1;
- protected static final int COPY_FIELD_NBITS = 12;
- protected static final int COPY_FIELD_OFFSET = 0;
-
+ // Internal objects
private final Logger log = getLogger(getClass());
protected ServiceDirectory serviceDirectory;
protected FlowRuleService flowRuleService;
@@ -188,8 +147,6 @@
// flows installations to be retried
private ScheduledExecutorService retryExecutorService
= newScheduledThreadPool(5, groupedThreads("OfdpaPipeliner", "retry-%d", log));
- private static final int MAX_RETRY_ATTEMPTS = 10;
- private static final int RETRY_MS = 1000;
// accumulator executor service
private ScheduledExecutorService accumulatorExecutorService
@@ -206,7 +163,7 @@
flowObjectiveStore = context.store();
deviceService = serviceDirectory.get(DeviceService.class);
// Init the accumulator, if enabled
- if (isAccumulatorEnabled()) {
+ if (isAccumulatorEnabled(this)) {
accumulator = new ForwardingObjectiveAccumulator(context.accumulatorMaxObjectives(),
context.accumulatorMaxBatchMillis(),
context.accumulatorMaxIdleMillis());
@@ -234,15 +191,6 @@
// software switches does require table-miss-entries.
}
- public boolean isAccumulatorEnabled() {
- Driver driver = super.data().driver();
- // we cannot determine the property
- if (driver == null) {
- return false;
- }
- return Boolean.parseBoolean(driver.getProperty(ACCUMULATOR_ENABLED));
- }
-
/**
* Determines whether this pipeline requires MPLS POP instruction.
*
@@ -402,7 +350,7 @@
@Override
public void onSuccess(FlowRuleOperations ops) {
log.trace("Flow rule operations onSuccess {}", ops);
- fwdObjs.forEach(Ofdpa2Pipeline::pass);
+ fwdObjs.forEach(OfdpaPipelineUtility::pass);
}
@Override
@@ -1828,14 +1776,6 @@
return null;
}
- protected static void pass(Objective obj) {
- obj.context().ifPresent(context -> context.onSuccess(obj));
- }
-
- protected static void fail(Objective obj, ObjectiveError error) {
- obj.context().ifPresent(context -> context.onError(obj, error));
- }
-
@Override
public List<String> getNextMappings(NextGroup nextGroup) {
List<String> mappings = new ArrayList<>();
@@ -1870,119 +1810,6 @@
}
/**
- * Returns true iff the given selector matches on BOS==true, indicating that
- * the selector is trying to match on a label that is bottom-of-stack.
- *
- * @param selector the given match
- * @return true iff BoS==true; false if BOS==false, or BOS matching is not
- * expressed in the given selector
- */
- static boolean isMplsBos(TrafficSelector selector) {
- MplsBosCriterion bosCriterion = (MplsBosCriterion) selector.getCriterion(MPLS_BOS);
- return bosCriterion != null && bosCriterion.mplsBos();
- }
-
- /**
- * Returns true iff the given selector matches on BOS==false, indicating
- * that the selector is trying to match on a label that is not the
- * bottom-of-stack label.
- *
- * @param selector the given match
- * @return true iff BoS==false;
- * false if BOS==true, or BOS matching is not expressed in the given selector
- */
- static boolean isNotMplsBos(TrafficSelector selector) {
- MplsBosCriterion bosCriterion = (MplsBosCriterion) selector.getCriterion(MPLS_BOS);
- return bosCriterion != null && !bosCriterion.mplsBos();
- }
-
- /**
- * Returns true iff the forwarding objective includes a treatment to pop the
- * MPLS label.
- *
- * @param fwd the given forwarding objective
- * @return true iff mpls pop treatment exists
- */
- static boolean isMplsPop(ForwardingObjective fwd) {
- if (fwd.treatment() != null) {
- for (Instruction instr : fwd.treatment().allInstructions()) {
- if (instr instanceof L2ModificationInstruction
- && ((L2ModificationInstruction) instr)
- .subtype() == L2SubType.MPLS_POP) {
- return true;
- }
- }
- }
- return false;
- }
-
- private static boolean isIpv6(TrafficSelector selector) {
- EthTypeCriterion ethTypeCriterion = (EthTypeCriterion) selector.getCriterion(ETH_TYPE);
- return ethTypeCriterion != null && ethTypeCriterion.ethType().toShort() == Ethernet.TYPE_IPV6;
- }
-
- static VlanId readVlanFromSelector(TrafficSelector selector) {
- if (selector == null) {
- return null;
- }
- Criterion criterion = selector.getCriterion(Criterion.Type.VLAN_VID);
- return (criterion == null)
- ? null : ((VlanIdCriterion) criterion).vlanId();
- }
-
- static MacAddress readEthDstFromSelector(TrafficSelector selector) {
- if (selector == null) {
- return null;
- }
- Criterion criterion = selector.getCriterion(Criterion.Type.ETH_DST);
- return (criterion == null)
- ? null : ((EthCriterion) criterion).mac();
- }
-
- static IpPrefix readIpDstFromSelector(TrafficSelector selector) {
- if (selector == null) {
- return null;
- }
- Criterion criterion = selector.getCriterion(Criterion.Type.IPV4_DST);
- return (criterion == null) ? null : ((IPCriterion) criterion).ip();
- }
-
- private static VlanId readVlanFromTreatment(TrafficTreatment treatment) {
- if (treatment == null) {
- return null;
- }
- for (Instruction i : treatment.allInstructions()) {
- if (i instanceof ModVlanIdInstruction) {
- return ((ModVlanIdInstruction) i).vlanId();
- }
- }
- return null;
- }
-
- protected static MacAddress readEthDstFromTreatment(TrafficTreatment treatment) {
- if (treatment == null) {
- return null;
- }
- for (Instruction i : treatment.allInstructions()) {
- if (i instanceof ModEtherInstruction) {
- ModEtherInstruction modEtherInstruction = (ModEtherInstruction) i;
- if (modEtherInstruction.subtype() == L2SubType.ETH_DST) {
- return modEtherInstruction.mac();
- }
- }
- }
- return null;
- }
-
- static ExtensionSelector readExtensionFromSelector(TrafficSelector selector) {
- if (selector == null) {
- return null;
- }
- ExtensionCriterion criterion = (ExtensionCriterion) selector.getCriterion(Criterion.Type.EXTENSION);
- return (criterion == null) ? null : criterion.extensionSelector();
- }
-
- /**
* Utility class that retries sending flows a fixed number of times, even if
* some of the attempts are successful. Used only for forwarding objectives.
*/
diff --git a/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/Ofdpa3GroupHandler.java b/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/Ofdpa3GroupHandler.java
index 6d28a11..d427a6c 100644
--- a/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/Ofdpa3GroupHandler.java
+++ b/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/Ofdpa3GroupHandler.java
@@ -29,8 +29,6 @@
import org.onosproject.net.flow.DefaultTrafficTreatment;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
-import org.onosproject.net.flow.criteria.Criterion;
-import org.onosproject.net.flow.criteria.VlanIdCriterion;
import org.onosproject.net.flow.instructions.Instruction;
import org.onosproject.net.flow.instructions.Instructions;
import org.onosproject.net.flow.instructions.L2ModificationInstruction;
@@ -101,7 +99,7 @@
);
if (groupInfo == null) {
log.error("Could not process nextObj={} in dev:{}", nextObjective.id(), deviceId);
- Ofdpa2Pipeline.fail(nextObjective, ObjectiveError.GROUPINSTALLATIONFAILED);
+ OfdpaPipelineUtility.fail(nextObjective, ObjectiveError.GROUPINSTALLATIONFAILED);
return;
}
// We update the chain with the last two groups;
@@ -128,7 +126,7 @@
log.error("Next Objective for pseudo wire should have at "
+ "most {} mpls instruction sets. Next Objective Id:{}",
MAX_DEPTH_UNPROTECTED_PW, nextObjective.id());
- Ofdpa2Pipeline.fail(nextObjective, ObjectiveError.BADPARAMS);
+ OfdpaPipelineUtility.fail(nextObjective, ObjectiveError.BADPARAMS);
return;
}
@@ -487,28 +485,4 @@
return new GroupInfo(l2groupDescription, outerGrpDesc);
}
- /**
- * Helper method to decide whether L2 Interface group or L2 Unfiltered group needs to be created.
- * L2 Unfiltered group will be created if meta has VlanIdCriterion with VlanId.ANY, and
- * treatment has set Vlan ID action.
- *
- * @param treatment treatment passed in by the application as part of the nextObjective
- * @param meta metadata passed in by the application as part of the nextObjective
- * @return true if L2 Unfiltered group needs to be created, false otherwise.
- */
- private boolean isUnfiltered(TrafficTreatment treatment, TrafficSelector meta) {
- if (meta == null || treatment == null) {
- return false;
- }
- VlanIdCriterion vlanIdCriterion = (VlanIdCriterion) meta.getCriterion(Criterion.Type.VLAN_VID);
- if (vlanIdCriterion == null || !vlanIdCriterion.vlanId().equals(VlanId.ANY)) {
- return false;
- }
-
- return treatment.allInstructions().stream()
- .filter(i -> (i.type() == Instruction.Type.L2MODIFICATION
- && ((L2ModificationInstruction) i).subtype() == L2ModificationInstruction.L2SubType.VLAN_ID))
- .count() == 1;
- }
-
}
diff --git a/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/Ofdpa3Pipeline.java b/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/Ofdpa3Pipeline.java
index 7168f6d..dbf1280 100644
--- a/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/Ofdpa3Pipeline.java
+++ b/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/Ofdpa3Pipeline.java
@@ -64,6 +64,7 @@
import java.util.List;
import static org.onlab.packet.MacAddress.NONE;
+import static org.onosproject.driver.pipeline.ofdpa.OfdpaPipelineUtility.*;
import static org.onosproject.driver.extensions.Ofdpa3MplsType.VPWS;
import static org.onosproject.net.flow.criteria.Criterion.Type.INNER_VLAN_VID;
import static org.onosproject.net.flow.criteria.Criterion.Type.IN_PORT;
@@ -446,45 +447,6 @@
}
/**
- * Determines if the filtering objective will be used for double-tagged packets.
- *
- * @param fob Filtering objective
- * @return True if the objective was created for double-tagged packets, false otherwise.
- */
- private boolean isDoubleTagged(FilteringObjective fob) {
- return fob.meta() != null &&
- fob.meta().allInstructions().stream().anyMatch(inst -> inst.type() == L2MODIFICATION
- && ((L2ModificationInstruction) inst).subtype() == L2SubType.VLAN_POP) &&
- fob.conditions().stream().filter(criterion -> criterion.type() == VLAN_VID).count() == 2;
- }
-
- /**
- * Determines if the filtering objective will be used for a pseudowire.
- *
- * @param filteringObjective
- * @return True if objective was created for a pseudowire, false otherwise.
- */
- private boolean isPseudowire(FilteringObjective filteringObjective) {
-
-
- if (filteringObjective.meta() != null) {
-
- TrafficTreatment treatment = filteringObjective.meta();
- for (Instruction instr : treatment.immediate()) {
- if (instr.type().equals(Instruction.Type.L2MODIFICATION)) {
-
- L2ModificationInstruction l2Instr = (L2ModificationInstruction) instr;
- if (l2Instr.subtype().equals(L2SubType.TUNNEL_ID)) {
- return true;
- }
- }
- }
- }
-
- return false;
- }
-
- /**
* Method to process the pw related filtering objectives.
*
* @param portCriterion the in port match
@@ -814,52 +776,6 @@
}
/**
- * Utility function to get the mod tunnel id instruction
- * if present.
- *
- * @param treatment the treatment to analyze
- * @return the mod tunnel id instruction if present,
- * otherwise null
- */
- private ModTunnelIdInstruction getModTunnelIdInstruction(TrafficTreatment treatment) {
- if (treatment == null) {
- return null;
- }
-
- L2ModificationInstruction l2ModificationInstruction;
- for (Instruction instruction : treatment.allInstructions()) {
- if (instruction.type() == L2MODIFICATION) {
- l2ModificationInstruction = (L2ModificationInstruction) instruction;
- if (l2ModificationInstruction.subtype() == L2SubType.TUNNEL_ID) {
- return (ModTunnelIdInstruction) l2ModificationInstruction;
- }
- }
- }
- return null;
- }
-
- /**
- * Utility function to get the output instruction
- * if present.
- *
- * @param treatment the treatment to analyze
- * @return the output instruction if present,
- * otherwise null
- */
- private OutputInstruction getOutputInstruction(TrafficTreatment treatment) {
- if (treatment == null) {
- return null;
- }
-
- for (Instruction instruction : treatment.allInstructions()) {
- if (instruction.type() == Instruction.Type.OUTPUT) {
- return (OutputInstruction) instruction;
- }
- }
- return null;
- }
-
- /**
* Helper method for dividing the tunnel instructions from the mpls
* instructions.
*
@@ -910,4 +826,5 @@
}
}
}
+
}
diff --git a/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/OfdpaGroupHandlerUtility.java b/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/OfdpaGroupHandlerUtility.java
index d4e364f..afab73f 100644
--- a/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/OfdpaGroupHandlerUtility.java
+++ b/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/OfdpaGroupHandlerUtility.java
@@ -51,7 +51,7 @@
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
-import static org.onosproject.driver.pipeline.ofdpa.Ofdpa2Pipeline.isNotMplsBos;
+import static org.onosproject.driver.pipeline.ofdpa.OfdpaPipelineUtility.isNotMplsBos;
import static org.onosproject.driver.pipeline.ofdpa.OfdpaGroupHandlerUtility.OfdpaMplsGroupSubType.OFDPA_GROUP_TYPE_SHIFT;
import static org.onosproject.driver.pipeline.ofdpa.OfdpaGroupHandlerUtility.OfdpaMplsGroupSubType.OFDPA_MPLS_SUBTYPE_SHIFT;
import static org.onosproject.net.flowobjective.NextObjective.Type.HASHED;
@@ -794,4 +794,28 @@
return L3_UNICAST_TYPE | 1 << 27 | (vlanId.toShort() << 15) | (int) (portNum & 0x7FFF);
}
+ /**
+ * Helper method to decide whether L2 Interface group or L2 Unfiltered group needs to be created.
+ * L2 Unfiltered group will be created if meta has VlanIdCriterion with VlanId.ANY, and
+ * treatment has set Vlan ID action.
+ *
+ * @param treatment treatment passed in by the application as part of the nextObjective
+ * @param meta metadata passed in by the application as part of the nextObjective
+ * @return true if L2 Unfiltered group needs to be created, false otherwise.
+ */
+ static boolean isUnfiltered(TrafficTreatment treatment, TrafficSelector meta) {
+ if (meta == null || treatment == null) {
+ return false;
+ }
+ VlanIdCriterion vlanIdCriterion = (VlanIdCriterion) meta.getCriterion(Criterion.Type.VLAN_VID);
+ if (vlanIdCriterion == null || !vlanIdCriterion.vlanId().equals(VlanId.ANY)) {
+ return false;
+ }
+
+ return treatment.allInstructions().stream()
+ .filter(i -> (i.type() == Instruction.Type.L2MODIFICATION
+ && ((L2ModificationInstruction) i).subtype() == L2ModificationInstruction.L2SubType.VLAN_ID))
+ .count() == 1;
+ }
+
}
diff --git a/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/OfdpaPipelineUtility.java b/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/OfdpaPipelineUtility.java
new file mode 100644
index 0000000..683b9f6
--- /dev/null
+++ b/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/OfdpaPipelineUtility.java
@@ -0,0 +1,363 @@
+/*
+ * Copyright 2019-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.driver.pipeline.ofdpa;
+
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.net.driver.Driver;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.criteria.Criterion;
+import org.onosproject.net.flow.criteria.EthCriterion;
+import org.onosproject.net.flow.criteria.EthTypeCriterion;
+import org.onosproject.net.flow.criteria.ExtensionCriterion;
+import org.onosproject.net.flow.criteria.ExtensionSelector;
+import org.onosproject.net.flow.criteria.IPCriterion;
+import org.onosproject.net.flow.criteria.MplsBosCriterion;
+import org.onosproject.net.flow.criteria.VlanIdCriterion;
+import org.onosproject.net.flow.instructions.Instruction;
+import org.onosproject.net.flow.instructions.Instructions;
+import org.onosproject.net.flow.instructions.L2ModificationInstruction;
+import org.onosproject.net.flow.instructions.L2ModificationInstruction.L2SubType;
+import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModTunnelIdInstruction;
+import org.onosproject.net.flowobjective.FilteringObjective;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.net.flowobjective.Objective;
+import org.onosproject.net.flowobjective.ObjectiveError;
+
+import static org.onosproject.net.behaviour.Pipeliner.ACCUMULATOR_ENABLED;
+import static org.onosproject.net.flow.criteria.Criterion.Type.ETH_TYPE;
+import static org.onosproject.net.flow.criteria.Criterion.Type.MPLS_BOS;
+import static org.onosproject.net.flow.criteria.Criterion.Type.VLAN_VID;
+import static org.onosproject.net.flow.instructions.Instruction.Type.L2MODIFICATION;
+import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction;
+import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
+
+public final class OfdpaPipelineUtility {
+
+ private OfdpaPipelineUtility() {
+ // Utility classes should not have a public or default constructor.
+ }
+
+ // Ofdpa specific tables number
+ static final int PORT_TABLE = 0;
+ static final int VLAN_TABLE = 10;
+ static final int VLAN_1_TABLE = 11;
+ static final int MPLS_L2_PORT_FLOW_TABLE = 13;
+ static final int MPLS_L2_PORT_PCP_TRUST_FLOW_TABLE = 16;
+ static final int TMAC_TABLE = 20;
+ static final int UNICAST_ROUTING_TABLE = 30;
+ static final int MULTICAST_ROUTING_TABLE = 40;
+ static final int MPLS_TABLE_0 = 23;
+ static final int MPLS_TABLE_1 = 24;
+ static final int MPLS_L3_TYPE_TABLE = 27;
+ static final int MPLS_TYPE_TABLE = 29;
+ static final int BRIDGING_TABLE = 50;
+ public static final int ACL_TABLE = 60;
+ static final int EGRESS_VLAN_FLOW_TABLE = 210;
+ static final int EGRESS_DSCP_PCP_REMARK_FLOW_TABLE = 230;
+ static final int EGRESS_TPID_FLOW_TABLE = 235;
+ static final int MAC_LEARNING_TABLE = 254;
+
+ // OF max port number
+ static final long OFPP_MAX = 0xffffff00L;
+
+ // Priority values
+ static final int HIGHEST_PRIORITY = 0xffff;
+ static final int DEFAULT_PRIORITY = 0x8000;
+ static final int LOWEST_PRIORITY = 0x0;
+
+ // MPLS L2 table values
+ static final int MPLS_L2_PORT_PRIORITY = 2;
+ static final int MPLS_TUNNEL_ID_BASE = 0x10000;
+ static final int MPLS_TUNNEL_ID_MAX = 0x1FFFF;
+ static final int MPLS_UNI_PORT_MAX = 0x0000FFFF;
+ static final int MPLS_NNI_PORT_BASE = 0x00020000;
+ static final int MPLS_NNI_PORT_MAX = 0x0002FFFF;
+
+ // Egress table values
+ static final short ALLOW_VLAN_TRANSLATION = 1;
+ static final int COPY_FIELD_NBITS = 12;
+ static final int COPY_FIELD_OFFSET = 0;
+
+ // Flow retry values
+ static final int MAX_RETRY_ATTEMPTS = 10;
+ static final int RETRY_MS = 1000;
+
+ //////////////////////////////
+ // Helper and utility methods
+ //////////////////////////////
+
+ /**
+ * Check whether the accumulator is enabled or not.
+ * @param pipeline the pipeline
+ * @return true if the accumulator is enabled. Otherwise not
+ */
+ static boolean isAccumulatorEnabled(Ofdpa2Pipeline pipeline) {
+ Driver driver = pipeline.data().driver();
+ // we cannot determine the property
+ if (driver == null) {
+ return false;
+ }
+ return Boolean.parseBoolean(driver.getProperty(ACCUMULATOR_ENABLED));
+ }
+
+ static void pass(Objective obj) {
+ obj.context().ifPresent(context -> context.onSuccess(obj));
+ }
+
+ static void fail(Objective obj, ObjectiveError error) {
+ obj.context().ifPresent(context -> context.onError(obj, error));
+ }
+
+ /**
+ * Returns true iff the given selector matches on BOS==true, indicating that
+ * the selector is trying to match on a label that is bottom-of-stack.
+ *
+ * @param selector the given match
+ * @return true iff BoS==true; false if BOS==false, or BOS matching is not
+ * expressed in the given selector
+ */
+ static boolean isMplsBos(TrafficSelector selector) {
+ MplsBosCriterion bosCriterion = (MplsBosCriterion) selector.getCriterion(MPLS_BOS);
+ return bosCriterion != null && bosCriterion.mplsBos();
+ }
+
+ /**
+ * Returns true iff the given selector matches on BOS==false, indicating
+ * that the selector is trying to match on a label that is not the
+ * bottom-of-stack label.
+ *
+ * @param selector the given match
+ * @return true iff BoS==false;
+ * false if BOS==true, or BOS matching is not expressed in the given selector
+ */
+ static boolean isNotMplsBos(TrafficSelector selector) {
+ MplsBosCriterion bosCriterion = (MplsBosCriterion) selector.getCriterion(MPLS_BOS);
+ return bosCriterion != null && !bosCriterion.mplsBos();
+ }
+
+ /**
+ * Returns true iff the forwarding objective includes a treatment to pop the
+ * MPLS label.
+ *
+ * @param fwd the given forwarding objective
+ * @return true iff mpls pop treatment exists
+ */
+ static boolean isMplsPop(ForwardingObjective fwd) {
+ if (fwd.treatment() != null) {
+ for (Instruction instr : fwd.treatment().allInstructions()) {
+ if (instr instanceof L2ModificationInstruction
+ && ((L2ModificationInstruction) instr)
+ .subtype() == L2SubType.MPLS_POP) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns true iff the given selector matches on ethtype==ipv6, indicating
+ * that the selector is trying to match on ipv6 traffic.
+ *
+ * @param selector the given match
+ * @return true iff ethtype==ipv6; false otherwise
+ */
+ static boolean isIpv6(TrafficSelector selector) {
+ EthTypeCriterion ethTypeCriterion = (EthTypeCriterion) selector.getCriterion(ETH_TYPE);
+ return ethTypeCriterion != null && ethTypeCriterion.ethType().toShort() == Ethernet.TYPE_IPV6;
+ }
+
+ /**
+ * Reads vlan id from selector.
+ *
+ * @param selector the given match
+ * @return the vlan id if found. null otherwise
+ */
+ static VlanId readVlanFromSelector(TrafficSelector selector) {
+ if (selector == null) {
+ return null;
+ }
+ Criterion criterion = selector.getCriterion(Criterion.Type.VLAN_VID);
+ return (criterion == null)
+ ? null : ((VlanIdCriterion) criterion).vlanId();
+ }
+
+ /**
+ * Reads eth dst from selector.
+ *
+ * @param selector the given match
+ * @return the eth dst if found. null otherwise
+ */
+ static MacAddress readEthDstFromSelector(TrafficSelector selector) {
+ if (selector == null) {
+ return null;
+ }
+ Criterion criterion = selector.getCriterion(Criterion.Type.ETH_DST);
+ return (criterion == null)
+ ? null : ((EthCriterion) criterion).mac();
+ }
+
+ /**
+ * Reads ipv4 dst from selector.
+ *
+ * @param selector the given match
+ * @return the ipv4 dst if found. null otherwise
+ */
+ static IpPrefix readIpDstFromSelector(TrafficSelector selector) {
+ if (selector == null) {
+ return null;
+ }
+ Criterion criterion = selector.getCriterion(Criterion.Type.IPV4_DST);
+ return (criterion == null) ? null : ((IPCriterion) criterion).ip();
+ }
+
+ /**
+ * Reads vlan id from treatment.
+ *
+ * @param treatment the given actions
+ * @return the vlan id if found. null otherwise
+ */
+ static VlanId readVlanFromTreatment(TrafficTreatment treatment) {
+ if (treatment == null) {
+ return null;
+ }
+ for (Instruction i : treatment.allInstructions()) {
+ if (i instanceof ModVlanIdInstruction) {
+ return ((ModVlanIdInstruction) i).vlanId();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Reads eth dst from treatment.
+ *
+ * @param treatment the given actions
+ * @return the eth dst if found. null otherwise
+ */
+ static MacAddress readEthDstFromTreatment(TrafficTreatment treatment) {
+ if (treatment == null) {
+ return null;
+ }
+ for (Instruction i : treatment.allInstructions()) {
+ if (i instanceof ModEtherInstruction) {
+ ModEtherInstruction modEtherInstruction = (ModEtherInstruction) i;
+ if (modEtherInstruction.subtype() == L2SubType.ETH_DST) {
+ return modEtherInstruction.mac();
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Reads extensions from selector.
+ * @param selector the given match
+ * @return the extensions if found. null otherwise
+ */
+ static ExtensionSelector readExtensionFromSelector(TrafficSelector selector) {
+ if (selector == null) {
+ return null;
+ }
+ ExtensionCriterion criterion = (ExtensionCriterion) selector.getCriterion(Criterion.Type.EXTENSION);
+ return (criterion == null) ? null : criterion.extensionSelector();
+ }
+
+ /**
+ * Determines if the filtering objective will be used for a pseudowire.
+ *
+ * @param filteringObjective the filtering objective
+ * @return True if objective was created for a pseudowire, false otherwise.
+ */
+ static boolean isPseudowire(FilteringObjective filteringObjective) {
+ if (filteringObjective.meta() != null) {
+ TrafficTreatment treatment = filteringObjective.meta();
+ for (Instruction instr : treatment.immediate()) {
+ if (instr.type().equals(Instruction.Type.L2MODIFICATION)) {
+
+ L2ModificationInstruction l2Instr = (L2ModificationInstruction) instr;
+ if (l2Instr.subtype().equals(L2SubType.TUNNEL_ID)) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Utility function to get the mod tunnel id instruction
+ * if present.
+ *
+ * @param treatment the treatment to analyze
+ * @return the mod tunnel id instruction if present,
+ * otherwise null
+ */
+ static ModTunnelIdInstruction getModTunnelIdInstruction(TrafficTreatment treatment) {
+ if (treatment == null) {
+ return null;
+ }
+ L2ModificationInstruction l2ModificationInstruction;
+ for (Instruction instruction : treatment.allInstructions()) {
+ if (instruction.type() == L2MODIFICATION) {
+ l2ModificationInstruction = (L2ModificationInstruction) instruction;
+ if (l2ModificationInstruction.subtype() == L2SubType.TUNNEL_ID) {
+ return (ModTunnelIdInstruction) l2ModificationInstruction;
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Utility function to get the output instruction
+ * if present.
+ *
+ * @param treatment the treatment to analyze
+ * @return the output instruction if present,
+ * otherwise null
+ */
+ static Instructions.OutputInstruction getOutputInstruction(TrafficTreatment treatment) {
+ if (treatment == null) {
+ return null;
+ }
+ for (Instruction instruction : treatment.allInstructions()) {
+ if (instruction.type() == Instruction.Type.OUTPUT) {
+ return (Instructions.OutputInstruction) instruction;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Determines if the filtering objective will be used for double-tagged packets.
+ *
+ * @param fob Filtering objective
+ * @return True if the objective was created for double-tagged packets, false otherwise.
+ */
+ static boolean isDoubleTagged(FilteringObjective fob) {
+ return fob.meta() != null &&
+ fob.meta().allInstructions().stream().anyMatch(inst -> inst.type() == L2MODIFICATION
+ && ((L2ModificationInstruction) inst).subtype() == L2SubType.VLAN_POP) &&
+ fob.conditions().stream().filter(criterion -> criterion.type() == VLAN_VID).count() == 2;
+ }
+
+}
diff --git a/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/OvsOfdpaGroupHandler.java b/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/OvsOfdpaGroupHandler.java
index beabae0..d45b0c1 100644
--- a/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/OvsOfdpaGroupHandler.java
+++ b/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/OvsOfdpaGroupHandler.java
@@ -248,7 +248,7 @@
// the transport of a VPWS. The necessary info are contained in the
// meta selector. In particular we are looking for the case of BoS==False;
TrafficSelector metaSelector = nextObjective.meta();
- if (metaSelector != null && Ofdpa2Pipeline.isNotMplsBos(metaSelector)) {
+ if (metaSelector != null && OfdpaPipelineUtility.isNotMplsBos(metaSelector)) {
// storage for all group keys in the chain of groups created
List<Deque<GroupKey>> allGroupKeys = new ArrayList<>();
List<GroupInfo> unsentGroups = new ArrayList<>();
diff --git a/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/OvsOfdpaPipeline.java b/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/OvsOfdpaPipeline.java
index e3b4b06..8c20f50 100644
--- a/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/OvsOfdpaPipeline.java
+++ b/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/OvsOfdpaPipeline.java
@@ -90,8 +90,8 @@
import static org.onlab.packet.MacAddress.NONE;
import static org.onlab.util.Tools.groupedThreads;
import static org.onosproject.driver.pipeline.ofdpa.OfdpaGroupHandlerUtility.*;
+import static org.onosproject.driver.pipeline.ofdpa.OfdpaPipelineUtility.*;
import static org.onosproject.net.flow.criteria.Criterion.Type.VLAN_VID;
-import static org.onosproject.net.flow.instructions.Instruction.Type.L2MODIFICATION;
import static org.slf4j.LoggerFactory.getLogger;
/**
@@ -161,10 +161,11 @@
groupChecker.scheduleAtFixedRate(new PopVlanPuntGroupChecker(), 20, 50, TimeUnit.MILLISECONDS);
super.init(deviceId, context);
}
+
protected void processFilter(FilteringObjective filteringObjective,
boolean install,
ApplicationId applicationId) {
- if (isDoubleTagged(filteringObjective)) {
+ if (OfdpaPipelineUtility.isDoubleTagged(filteringObjective)) {
processDoubleTaggedFilter(filteringObjective, install, applicationId);
} else {
// If it is not a double-tagged filter, we fall back
@@ -174,20 +175,6 @@
}
/**
- * Determines if the filtering objective will be used for double-tagged packets.
- *
- * @param fob Filtering objective
- * @return True if the objective was created for double-tagged packets, false otherwise.
- */
- private boolean isDoubleTagged(FilteringObjective fob) {
- return fob.meta() != null &&
- fob.meta().allInstructions().stream().anyMatch(inst -> inst.type() == L2MODIFICATION
- && ((L2ModificationInstruction) inst).subtype() ==
- L2ModificationInstruction.L2SubType.VLAN_POP) &&
- fob.conditions().stream().filter(criterion -> criterion.type() == VLAN_VID).count() == 2;
- }
-
- /**
* Determines if the forwarding objective will be used for double-tagged packets.
*
* @param fwd Forwarding objective
diff --git a/tools/build/conf/src/main/resources/onos/suppressions.xml b/tools/build/conf/src/main/resources/onos/suppressions.xml
index f87d11f..d1c613b 100644
--- a/tools/build/conf/src/main/resources/onos/suppressions.xml
+++ b/tools/build/conf/src/main/resources/onos/suppressions.xml
@@ -31,7 +31,6 @@
<suppress files="org.onlab.jdvue.*" checks="AbbreviationAsWordInName" />
<suppress files="org.onosproject.driver.pipeline.*" checks="AbbreviationAsWordInName" />
<suppress files="org.onosproject.driver.pipeline.ofdpa.Ofdpa2GroupHandler.java" checks="FileLength" />
- <suppress files="org.onosproject.driver.pipeline.ofdpa.Ofdpa2Pipeline.java" checks="FileLength" />
<suppress files="org.onosproject.segmentrouting.*" checks="AbbreviationAsWordInName" />
<!-- These files carry AT&T copyrights -->