[CORD-640] PW clean up.
Changes:
- Re-enable the pop mpls action for PW;
- OFDPA 3.0 has some changes in the pipeline
which don't allow the VLAN pop in the PW termination;
Change-Id: I42b5a3fe4b703d9c9af083768fb6b2decd6f54d7
diff --git a/drivers/default/src/main/java/org/onosproject/driver/pipeline/Ofdpa2Pipeline.java b/drivers/default/src/main/java/org/onosproject/driver/pipeline/Ofdpa2Pipeline.java
index dc9d3ed..5c2b8f6 100644
--- a/drivers/default/src/main/java/org/onosproject/driver/pipeline/Ofdpa2Pipeline.java
+++ b/drivers/default/src/main/java/org/onosproject/driver/pipeline/Ofdpa2Pipeline.java
@@ -15,8 +15,24 @@
*/
package org.onosproject.driver.pipeline;
+import static java.util.concurrent.Executors.newScheduledThreadPool;
+import static org.onlab.util.Tools.groupedThreads;
+import static org.onosproject.net.flow.criteria.Criterion.Type.MPLS_BOS;
+import static org.slf4j.LoggerFactory.getLogger;
+
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Deque;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
import org.onlab.osgi.ServiceDirectory;
import org.onlab.packet.Ethernet;
import org.onlab.packet.IpPrefix;
@@ -76,23 +92,7 @@
import org.onosproject.store.serializers.KryoNamespaces;
import org.slf4j.Logger;
-import java.util.ArrayDeque;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Deque;
-import java.util.List;
-import java.util.Objects;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-
-import static java.util.concurrent.Executors.newScheduledThreadPool;
-import static org.onlab.util.Tools.groupedThreads;
-import static org.onosproject.net.flow.criteria.Criterion.Type.MPLS_BOS;
import static org.onosproject.net.flowobjective.NextObjective.Type.HASHED;
-import static org.slf4j.LoggerFactory.getLogger;
/**
* Driver for Broadcom's OF-DPA v2.0 TTP.
@@ -867,7 +867,6 @@
TrafficSelector selector = fwd.selector();
EthTypeCriterion ethType =
(EthTypeCriterion) selector.getCriterion(Criterion.Type.ETH_TYPE);
- boolean defaultRule = false;
boolean popMpls = false;
boolean emptyGroup = false;
int forTableId;
@@ -876,49 +875,16 @@
TrafficSelector.Builder complementarySelector = DefaultTrafficSelector.builder();
if (ethType.ethType().toShort() == Ethernet.TYPE_IPV4) {
+ if (buildIpv4Selector(filteredSelector, complementarySelector, fwd, allowDefaultRoute) < 0) {
+ return Collections.emptyList();
+ }
+ // We need to set properly the next table
IpPrefix ipv4Dst = ((IPCriterion) selector.getCriterion(Criterion.Type.IPV4_DST)).ip();
if (ipv4Dst.isMulticast()) {
- if (ipv4Dst.prefixLength() != 32) {
- log.warn("Multicast specific forwarding objective can only be /32");
- fail(fwd, ObjectiveError.BADPARAMS);
- return ImmutableSet.of();
- }
- VlanId assignedVlan = readVlanFromSelector(fwd.meta());
- if (assignedVlan == null) {
- log.warn("VLAN ID required by multicast specific fwd obj is missing. Abort.");
- fail(fwd, ObjectiveError.BADPARAMS);
- return ImmutableSet.of();
- }
- OfdpaMatchVlanVid ofdpaMatchVlanVid = new OfdpaMatchVlanVid(assignedVlan);
- filteredSelector.extension(ofdpaMatchVlanVid, deviceId);
- filteredSelector.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(ipv4Dst);
forTableId = MULTICAST_ROUTING_TABLE;
- log.debug("processing IPv4 multicast specific forwarding objective {} -> next:{}"
- + " in dev:{}", fwd.id(), fwd.nextId(), deviceId);
} else {
- if (ipv4Dst.prefixLength() == 0) {
- if (allowDefaultRoute) {
- // The entire IPV4_DST field is wildcarded intentionally
- filteredSelector.matchEthType(Ethernet.TYPE_IPV4);
- } else {
- /*
- * NOTE: The switch does not support matching 0.0.0.0/0
- * Split it into 0.0.0.0/1 and 128.0.0.0/1
- */
- filteredSelector.matchEthType(Ethernet.TYPE_IPV4)
- .matchIPDst(IpPrefix.valueOf("0.0.0.0/1"));
- complementarySelector.matchEthType(Ethernet.TYPE_IPV4)
- .matchIPDst(IpPrefix.valueOf("128.0.0.0/1"));
- defaultRule = true;
- }
- } else {
- filteredSelector.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(ipv4Dst);
- }
forTableId = UNICAST_ROUTING_TABLE;
- log.debug("processing IPv4 unicast specific forwarding objective {} -> next:{}"
- + " in dev:{}", fwd.id(), fwd.nextId(), deviceId);
}
-
if (fwd.treatment() != null) {
for (Instruction instr : fwd.treatment().allInstructions()) {
if (instr instanceof L3ModificationInstruction &&
@@ -949,8 +915,11 @@
if (instr instanceof L2ModificationInstruction &&
((L2ModificationInstruction) instr).subtype() == L2SubType.MPLS_POP) {
popMpls = true;
- // OF-DPA does not pop in MPLS table. Instead it requires
+ // OF-DPA does not pop in MPLS table in some cases. For the L3 VPN, it requires
// setting the MPLS_TYPE so pop can happen down the pipeline
+ if (mplsNextTable == MPLS_TYPE_TABLE && bos != null && !bos.mplsBos()) {
+ tb.immediate().popMpls();
+ }
}
if (instr instanceof L3ModificationInstruction &&
((L3ModificationInstruction) instr).subtype() == L3SubType.DEC_TTL) {
@@ -970,10 +939,9 @@
log.warn("SR CONTINUE case cannot be handled as MPLS ECMP "
+ "is not implemented in OF-DPA yet. Aborting this flow {} -> next:{}"
+ "in this device {}", fwd.id(), fwd.nextId(), deviceId);
- // XXX We could convert to forwarding to a single-port, via a
- // MPLS interface, or a MPLS SWAP (with-same) but that would
- // have to be handled in the next-objective. Also the pop-mpls
- // logic used here won't work in non-BoS case.
+ // XXX We could convert to forwarding to a single-port, via a MPLS interface,
+ // or a MPLS SWAP (with-same) but that would have to be handled in the next-objective.
+ // Also the pop-mpls logic used here won't work in non-BoS case.
fail(fwd, ObjectiveError.FLOWINSTALLATIONFAILED);
return Collections.emptySet();
}
@@ -1037,20 +1005,10 @@
}
Collection<FlowRule> flowRuleCollection = new ArrayList<>();
flowRuleCollection.add(ruleBuilder.build());
- if (defaultRule) {
- FlowRule.Builder rule = DefaultFlowRule.builder()
- .fromApp(fwd.appId())
- .withPriority(fwd.priority())
- .forDevice(deviceId)
- .withSelector(complementarySelector.build())
- .withTreatment(tb.build())
- .forTable(forTableId);
- if (fwd.permanent()) {
- rule.makePermanent();
- } else {
- rule.makeTemporary(fwd.timeout());
- }
- flowRuleCollection.add(rule.build());
+ if (!allowDefaultRoute) {
+ flowRuleCollection.add(
+ defaultRoute(fwd, complementarySelector, forTableId, tb)
+ );
log.debug("Default rule 0.0.0.0/0 is being installed two rules");
}
// XXX retrying flows may be necessary due to bug CORD-554
@@ -1061,6 +1019,71 @@
return flowRuleCollection;
}
+ protected int buildIpv4Selector(TrafficSelector.Builder builderToUpdate,
+ TrafficSelector.Builder extBuilder,
+ ForwardingObjective fwd,
+ boolean allowDefaultRoute) {
+ TrafficSelector selector = fwd.selector();
+
+ IpPrefix ipv4Dst = ((IPCriterion) selector.getCriterion(Criterion.Type.IPV4_DST)).ip();
+ if (ipv4Dst.isMulticast()) {
+ if (ipv4Dst.prefixLength() != 32) {
+ log.warn("Multicast specific forwarding objective can only be /32");
+ fail(fwd, ObjectiveError.BADPARAMS);
+ return -1;
+ }
+ VlanId assignedVlan = readVlanFromSelector(fwd.meta());
+ if (assignedVlan == null) {
+ log.warn("VLAN ID required by multicast specific fwd obj is missing. Abort.");
+ fail(fwd, ObjectiveError.BADPARAMS);
+ return -1;
+ }
+ OfdpaMatchVlanVid ofdpaMatchVlanVid = new OfdpaMatchVlanVid(assignedVlan);
+ builderToUpdate.extension(ofdpaMatchVlanVid, deviceId);
+ builderToUpdate.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(ipv4Dst);
+ log.debug("processing IPv4 multicast specific forwarding objective {} -> next:{}"
+ + " in dev:{}", fwd.id(), fwd.nextId(), deviceId);
+ } else {
+ if (ipv4Dst.prefixLength() == 0) {
+ if (allowDefaultRoute) {
+ // The entire IPV4_DST field is wildcarded intentionally
+ builderToUpdate.matchEthType(Ethernet.TYPE_IPV4);
+ } else {
+ // NOTE: The switch does not support matching 0.0.0.0/0
+ // Split it into 0.0.0.0/1 and 128.0.0.0/1
+ builderToUpdate.matchEthType(Ethernet.TYPE_IPV4)
+ .matchIPDst(IpPrefix.valueOf("0.0.0.0/1"));
+ extBuilder.matchEthType(Ethernet.TYPE_IPV4)
+ .matchIPDst(IpPrefix.valueOf("128.0.0.0/1"));
+ }
+ } else {
+ builderToUpdate.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(ipv4Dst);
+ }
+ log.debug("processing IPv4 unicast specific forwarding objective {} -> next:{}"
+ + " in dev:{}", fwd.id(), fwd.nextId(), deviceId);
+ }
+ return 0;
+ }
+
+ protected FlowRule defaultRoute(ForwardingObjective fwd,
+ TrafficSelector.Builder complementarySelector,
+ int forTableId,
+ TrafficTreatment.Builder tb) {
+ FlowRule.Builder rule = DefaultFlowRule.builder()
+ .fromApp(fwd.appId())
+ .withPriority(fwd.priority())
+ .forDevice(deviceId)
+ .withSelector(complementarySelector.build())
+ .withTreatment(tb.build())
+ .forTable(forTableId);
+ if (fwd.permanent()) {
+ rule.makePermanent();
+ } else {
+ rule.makeTemporary(fwd.timeout());
+ }
+ return rule.build();
+ }
+
/**
* Handles forwarding rules to the L2 bridging table. Flow actions are not
* allowed in the bridging table - instead we use L2 Interface group or
diff --git a/drivers/default/src/main/java/org/onosproject/driver/pipeline/Ofdpa3Pipeline.java b/drivers/default/src/main/java/org/onosproject/driver/pipeline/Ofdpa3Pipeline.java
index 2536dc1..01bd28f 100644
--- a/drivers/default/src/main/java/org/onosproject/driver/pipeline/Ofdpa3Pipeline.java
+++ b/drivers/default/src/main/java/org/onosproject/driver/pipeline/Ofdpa3Pipeline.java
@@ -366,7 +366,10 @@
// according to the OFDPA 2.0 specification.
flowTreatment = DefaultTrafficTreatment.builder(mplsTreatment.build());
flowTreatment.extension(new Ofdpa3PopCw(), deviceId);
- flowTreatment.popVlan();
+ // Even though the specification and the xml/json files
+ // specify is allowed, the switch rejects the flow. In the
+ // version 2.0 the pop vlan was necessary and not accepted.
+ //flowTreatment.popVlan();
flowTreatment.extension(new Ofdpa3PopL2Header(), deviceId);
flowTreatment.setTunnelId(tunnelId);
flowTreatment.extension(new Ofdpa3SetMplsL2Port(mplsLogicalPort), deviceId);