CORD-348 multicast support in SegmentRouting and vRouter
In this submission:
* Setup/teardown multicast route according to SinkAdded/SinkRemoved event
- ingressVlan and egressVlan is configurable through network config
* Change behavior of OFDPA VLAN assignment
- Always use the VLAN in metadata if present
* Bugfix of writing immutable object
NOT in this submission (coming soon):
* Error handling (e.g. link/device failure recovery)
Change-Id: I9be11af04eb2d6456b865c7e59e96cc02370f846
diff --git a/drivers/default/src/main/java/org/onosproject/driver/pipeline/CpqdOfdpa2Pipeline.java b/drivers/default/src/main/java/org/onosproject/driver/pipeline/CpqdOfdpa2Pipeline.java
index 6bcebd7..0b945a3 100644
--- a/drivers/default/src/main/java/org/onosproject/driver/pipeline/CpqdOfdpa2Pipeline.java
+++ b/drivers/default/src/main/java/org/onosproject/driver/pipeline/CpqdOfdpa2Pipeline.java
@@ -22,8 +22,6 @@
import java.util.Collections;
import java.util.Deque;
import java.util.List;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
@@ -279,17 +277,6 @@
}
for (PortNumber pnum : portnums) {
- // update storage
- groupHandler.port2Vlan.put(pnum, storeVlan);
- Set<PortNumber> vlanPorts = groupHandler.vlan2Port.get(storeVlan);
- if (vlanPorts == null) {
- vlanPorts = Collections.newSetFromMap(
- new ConcurrentHashMap<PortNumber, Boolean>());
- vlanPorts.add(pnum);
- groupHandler.vlan2Port.put(storeVlan, vlanPorts);
- } else {
- vlanPorts.add(pnum);
- }
// create rest of flowrule
selector.matchInPort(pnum);
FlowRule rule = DefaultFlowRule.builder()
diff --git a/drivers/default/src/main/java/org/onosproject/driver/pipeline/Ofdpa2GroupHandler.java b/drivers/default/src/main/java/org/onosproject/driver/pipeline/Ofdpa2GroupHandler.java
index 9c3c9eb..a9c2bb1 100644
--- a/drivers/default/src/main/java/org/onosproject/driver/pipeline/Ofdpa2GroupHandler.java
+++ b/drivers/default/src/main/java/org/onosproject/driver/pipeline/Ofdpa2GroupHandler.java
@@ -65,7 +65,6 @@
import java.util.Collections;
import java.util.Deque;
import java.util.List;
-import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
@@ -123,10 +122,6 @@
// index number for group creation
private AtomicCounter nextIndex;
- // local stores for port-vlan mapping
- protected Map<PortNumber, VlanId> port2Vlan = new ConcurrentHashMap<>();
- protected Map<VlanId, Set<PortNumber>> vlan2Port = new ConcurrentHashMap<>();
-
// local store for pending bucketAdds - by design there can only be one
// pending bucket for a group
protected ConcurrentHashMap<Integer, NextObjective> pendingBuckets = new ConcurrentHashMap<>();
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 be35026..97751ec 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
@@ -313,31 +313,22 @@
}
VlanId assignedVlan = null;
- // For VLAN cross-connect packets, use the configured VLAN
if (vidCriterion != null) {
- if (vidCriterion.vlanId() != VlanId.NONE) {
+ // Use the VLAN in metadata whenever a metadata is provided
+ if (filt.meta() != null) {
+ assignedVlan = readVlanFromTreatment(filt.meta());
+ // Use the VLAN in criterion if metadata is not present and the traffic is tagged
+ } else if (!vidCriterion.vlanId().equals(VlanId.NONE)) {
assignedVlan = vidCriterion.vlanId();
+ }
- // For untagged packets, assign a VLAN ID
- } else {
- if (filt.meta() == null) {
- log.error("Missing metadata in filtering objective required " +
- "for vlan assignment in dev {}", deviceId);
- fail(filt, ObjectiveError.BADPARAMS);
- return;
- }
- for (Instruction i : filt.meta().allInstructions()) {
- if (i instanceof ModVlanIdInstruction) {
- assignedVlan = ((ModVlanIdInstruction) i).vlanId();
- }
- }
- if (assignedVlan == null) {
- log.error("Driver requires an assigned vlan-id to tag incoming "
- + "untagged packets. Not processing vlan filters on "
- + "device {}", deviceId);
- fail(filt, ObjectiveError.BADPARAMS);
- return;
- }
+ if (assignedVlan == null) {
+ log.error("Driver fails to extract VLAN information. "
+ + "Not proccessing VLAN filters on device {}.", deviceId);
+ log.debug("VLAN ID in criterion={}, metadata={}",
+ readVlanFromTreatment(filt.meta()), vidCriterion.vlanId());
+ fail(filt, ObjectiveError.BADPARAMS);
+ return;
}
}
@@ -457,22 +448,14 @@
TrafficSelector.Builder preSelector = null;
TrafficTreatment.Builder preTreatment = null;
-
treatment.transition(TMAC_TABLE);
- VlanId storeVlan = null;
if (vidCriterion.vlanId() == VlanId.NONE) {
// untagged packets are assigned vlans
OfdpaMatchVlanVid ofdpaMatchVlanVid = new OfdpaMatchVlanVid(VlanId.NONE);
selector.extension(ofdpaMatchVlanVid, deviceId);
OfdpaSetVlanVid ofdpaSetVlanVid = new OfdpaSetVlanVid(assignedVlan);
treatment.extension(ofdpaSetVlanVid, deviceId);
- // ofdpa requires an additional vlan match rule for the assigned vlan
- // and it does not require the push when setting the assigned vlan.
- // It also requires the extra rule to be sent to the switch before we
- // send the untagged match rule.
- // None of this in compliance with OF standard.
- storeVlan = assignedVlan;
preSelector = DefaultTrafficSelector.builder();
OfdpaMatchVlanVid preOfdpaMatchVlanVid = new OfdpaMatchVlanVid(assignedVlan);
@@ -482,7 +465,11 @@
} else {
OfdpaMatchVlanVid ofdpaMatchVlanVid = new OfdpaMatchVlanVid(vidCriterion.vlanId());
selector.extension(ofdpaMatchVlanVid, deviceId);
- storeVlan = vidCriterion.vlanId();
+
+ if (!assignedVlan.equals(vidCriterion.vlanId())) {
+ OfdpaSetVlanVid ofdpaSetVlanVid = new OfdpaSetVlanVid(assignedVlan);
+ treatment.extension(ofdpaSetVlanVid, deviceId);
+ }
}
// ofdpa cannot match on ALL portnumber, so we need to use separate
@@ -499,17 +486,6 @@
}
for (PortNumber pnum : portnums) {
- // update storage
- groupHandler.port2Vlan.put(pnum, storeVlan);
- Set<PortNumber> vlanPorts = groupHandler.vlan2Port.get(storeVlan);
- if (vlanPorts == null) {
- vlanPorts = Collections.newSetFromMap(
- new ConcurrentHashMap<PortNumber, Boolean>());
- vlanPorts.add(pnum);
- groupHandler.vlan2Port.put(storeVlan, vlanPorts);
- } else {
- vlanPorts.add(pnum);
- }
// create rest of flowrule
selector.matchInPort(pnum);
FlowRule rule = DefaultFlowRule.builder()
@@ -1112,4 +1088,13 @@
Criterion criterion = selector.getCriterion(Criterion.Type.IPV4_DST);
return (criterion == null) ? null : ((IPCriterion) criterion).ip();
}
+
+ private static VlanId readVlanFromTreatment(TrafficTreatment treatment) {
+ for (Instruction i : treatment.allInstructions()) {
+ if (i instanceof ModVlanIdInstruction) {
+ return ((ModVlanIdInstruction) i).vlanId();
+ }
+ }
+ return null;
+ }
}