CORD-1622 CORD-1624 Add IPv6 mutlicast in McastHandler and OFDPA2.0 Drivers
Change-Id: Ibbb402b62999b39f8aea2cd236b959fc61fb94ac
diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/McastHandler.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/McastHandler.java
index 9f91712..bbbbc3c 100644
--- a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/McastHandler.java
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/McastHandler.java
@@ -253,7 +253,7 @@
}
// Process the ingress device
- addFilterToDevice(source.deviceId(), source.port(), assignedVlan(source));
+ addFilterToDevice(source.deviceId(), source.port(), assignedVlan(source), mcastIp);
// When source and sink are on the same device
if (source.deviceId().equals(sink.deviceId())) {
@@ -277,7 +277,7 @@
links.forEach(link -> {
addPortToDevice(link.src().deviceId(), link.src().port(), mcastIp,
assignedVlan(link.src().deviceId().equals(source.deviceId()) ? source : null));
- addFilterToDevice(link.dst().deviceId(), link.dst().port(), assignedVlan(null));
+ addFilterToDevice(link.dst().deviceId(), link.dst().port(), assignedVlan(null), mcastIp);
});
// Process the egress device
@@ -344,7 +344,7 @@
links.forEach(link -> {
addPortToDevice(link.src().deviceId(), link.src().port(), mcastIp,
assignedVlan(link.src().deviceId().equals(source.deviceId()) ? source : null));
- addFilterToDevice(link.dst().deviceId(), link.dst().port(), assignedVlan(null));
+ addFilterToDevice(link.dst().deviceId(), link.dst().port(), assignedVlan(null), mcastIp);
});
// Setup new transit mcast role
mcastRoleStore.put(new McastStoreKey(mcastIp,
@@ -365,7 +365,7 @@
* @param port ingress port number
* @param assignedVlan assigned VLAN ID
*/
- private void addFilterToDevice(DeviceId deviceId, PortNumber port, VlanId assignedVlan) {
+ private void addFilterToDevice(DeviceId deviceId, PortNumber port, VlanId assignedVlan, IpAddress mcastIp) {
// Do nothing if the port is configured as suppressed
ConnectPoint connectPoint = new ConnectPoint(deviceId, port);
SegmentRoutingAppConfig appConfig = srManager.cfgService
@@ -376,7 +376,7 @@
}
FilteringObjective.Builder filtObjBuilder =
- filterObjBuilder(deviceId, port, assignedVlan);
+ filterObjBuilder(deviceId, port, assignedVlan, mcastIp);
ObjectiveContext context = new DefaultObjectiveContext(
(objective) -> log.debug("Successfully add filter on {}/{}, vlan {}",
deviceId, port.toLong(), assignedVlan),
@@ -596,9 +596,17 @@
private ForwardingObjective.Builder fwdObjBuilder(IpAddress mcastIp,
VlanId assignedVlan, int nextId) {
TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
- IpPrefix mcastPrefix = IpPrefix.valueOf(mcastIp, IpPrefix.MAX_INET_MASK_LENGTH);
- sbuilder.matchEthType(Ethernet.TYPE_IPV4);
- sbuilder.matchIPDst(mcastPrefix);
+ IpPrefix mcastPrefix = mcastIp.toIpPrefix();
+
+ if (mcastIp.isIp4()) {
+ sbuilder.matchEthType(Ethernet.TYPE_IPV4);
+ sbuilder.matchIPDst(mcastPrefix);
+ } else {
+ sbuilder.matchEthType(Ethernet.TYPE_IPV6);
+ sbuilder.matchIPv6Dst(mcastPrefix);
+ }
+
+
TrafficSelector.Builder metabuilder = DefaultTrafficSelector.builder();
metabuilder.matchVlanId(assignedVlan);
@@ -621,14 +629,22 @@
* @return filtering objective builder
*/
private FilteringObjective.Builder filterObjBuilder(DeviceId deviceId, PortNumber ingressPort,
- VlanId assignedVlan) {
+ VlanId assignedVlan, IpAddress mcastIp) {
FilteringObjective.Builder filtBuilder = DefaultFilteringObjective.builder();
- filtBuilder.withKey(Criteria.matchInPort(ingressPort))
- .addCondition(Criteria.matchEthDstMasked(MacAddress.IPV4_MULTICAST,
- MacAddress.IPV4_MULTICAST_MASK))
- .addCondition(Criteria.matchVlanId(egressVlan()))
- .withPriority(SegmentRoutingService.DEFAULT_PRIORITY);
+ if (mcastIp.isIp4()) {
+ filtBuilder.withKey(Criteria.matchInPort(ingressPort))
+ .addCondition(Criteria.matchEthDstMasked(MacAddress.IPV4_MULTICAST,
+ MacAddress.IPV4_MULTICAST_MASK))
+ .addCondition(Criteria.matchVlanId(egressVlan()))
+ .withPriority(SegmentRoutingService.DEFAULT_PRIORITY);
+ } else {
+ filtBuilder.withKey(Criteria.matchInPort(ingressPort))
+ .addCondition(Criteria.matchEthDstMasked(MacAddress.IPV6_MULTICAST,
+ MacAddress.IPV6_MULTICAST_MASK))
+ .addCondition(Criteria.matchVlanId(egressVlan()))
+ .withPriority(SegmentRoutingService.DEFAULT_PRIORITY);
+ }
TrafficTreatment tt = DefaultTrafficTreatment.builder()
.pushVlan().setVlanId(assignedVlan).build();
filtBuilder.withMeta(tt);
diff --git a/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/CpqdOfdpa2Pipeline.java b/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/CpqdOfdpa2Pipeline.java
index 95dcfa1..9f2e84c 100644
--- a/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/CpqdOfdpa2Pipeline.java
+++ b/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/CpqdOfdpa2Pipeline.java
@@ -18,6 +18,7 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import org.onlab.packet.Ethernet;
+import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.VlanId;
import org.onosproject.core.ApplicationId;
@@ -491,10 +492,30 @@
+ " in dev:{}", fwd.id(), fwd.nextId(), deviceId);
}
} else if (ethType.ethType().toShort() == Ethernet.TYPE_IPV6) {
- if (buildIpv6Selector(filteredSelector, fwd) < 0) {
- return Collections.emptyList();
+ IpPrefix ipv6Dst = ((IPCriterion) selector.getCriterion(Criterion.Type.IPV6_DST)).ip();
+ if (ipv6Dst.isMulticast()) {
+ if (ipv6Dst.prefixLength() != IpAddress.INET6_BIT_LENGTH) {
+ log.debug("Multicast specific IPv6 forwarding objective can only be /128");
+ fail(fwd, ObjectiveError.BADPARAMS);
+ return ImmutableSet.of();
+ }
+ VlanId assignedVlan = readVlanFromSelector(fwd.meta());
+ if (assignedVlan == null) {
+ log.debug("VLAN ID required by multicast specific fwd obj is missing. Abort.");
+ fail(fwd, ObjectiveError.BADPARAMS);
+ return ImmutableSet.of();
+ }
+ filteredSelector.matchVlanId(assignedVlan);
+ filteredSelector.matchEthType(Ethernet.TYPE_IPV6).matchIPv6Dst(ipv6Dst);
+ forTableId = MULTICAST_ROUTING_TABLE;
+ log.debug("processing IPv6 multicast specific forwarding objective {} -> next:{}"
+ + " in dev:{}", fwd.id(), fwd.nextId(), deviceId);
+ } else {
+ if (buildIpv6Selector(filteredSelector, fwd) < 0) {
+ return Collections.emptyList();
+ }
+ forTableId = UNICAST_ROUTING_TABLE;
}
- forTableId = UNICAST_ROUTING_TABLE;
} else {
filteredSelector
.matchEthType(Ethernet.MPLS_UNICAST)
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 cc85cbf..c0c6639 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
@@ -19,6 +19,7 @@
import com.google.common.collect.Sets;
import org.onlab.osgi.ServiceDirectory;
import org.onlab.packet.Ethernet;
+import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.VlanId;
import org.onlab.util.KryoNamespace;
@@ -857,6 +858,7 @@
protected List<FlowRule> processMcastEthDstFilter(EthCriterion ethCriterion,
ApplicationId applicationId) {
+ ImmutableList.Builder<FlowRule> builder = ImmutableList.builder();
TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
selector.matchEthType(Ethernet.TYPE_IPV4);
@@ -870,7 +872,22 @@
.fromApp(applicationId)
.makePermanent()
.forTable(TMAC_TABLE).build();
- return ImmutableList.<FlowRule>builder().add(rule).build();
+ builder.add(rule);
+
+ selector = DefaultTrafficSelector.builder();
+ treatment = DefaultTrafficTreatment.builder();
+ selector.matchEthType(Ethernet.TYPE_IPV6);
+ selector.matchEthDstMasked(ethCriterion.mac(), ethCriterion.mask());
+ treatment.transition(MULTICAST_ROUTING_TABLE);
+ rule = DefaultFlowRule.builder()
+ .forDevice(deviceId)
+ .withSelector(selector.build())
+ .withTreatment(treatment.build())
+ .withPriority(DEFAULT_PRIORITY)
+ .fromApp(applicationId)
+ .makePermanent()
+ .forTable(TMAC_TABLE).build();
+ return builder.add(rule).build();
}
private Collection<FlowRule> processForward(ForwardingObjective fwd) {
@@ -1281,16 +1298,34 @@
IpPrefix ipv6Dst = ((IPCriterion) selector.getCriterion(Criterion.Type.IPV6_DST)).ip();
if (ipv6Dst.isMulticast()) {
- log.warn("IPv6 Multicast is currently not supported");
- fail(fwd, ObjectiveError.BADPARAMS);
- return -1;
- }
- if (ipv6Dst.prefixLength() != 0) {
- builderToUpdate.matchIPv6Dst(ipv6Dst);
- }
+ if (ipv6Dst.prefixLength() != IpAddress.INET6_BIT_LENGTH) {
+ log.warn("Multicast specific forwarding objective can only be /128");
+ 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;
+ }
+ if (requireVlanExtensions()) {
+ OfdpaMatchVlanVid ofdpaMatchVlanVid = new OfdpaMatchVlanVid(assignedVlan);
+ builderToUpdate.extension(ofdpaMatchVlanVid, deviceId);
+ } else {
+ builderToUpdate.matchVlanId(assignedVlan);
+ }
+ builderToUpdate.matchEthType(Ethernet.TYPE_IPV6).matchIPv6Dst(ipv6Dst);
+ log.debug("processing IPv6 multicast specific forwarding objective {} -> next:{}"
+ + " in dev:{}", fwd.id(), fwd.nextId(), deviceId);
+ } else {
+ if (ipv6Dst.prefixLength() != 0) {
+ builderToUpdate.matchIPv6Dst(ipv6Dst);
+ }
builderToUpdate.matchEthType(Ethernet.TYPE_IPV6);
log.debug("processing IPv6 unicast specific forwarding objective {} -> next:{}"
+ " in dev:{}", fwd.id(), fwd.nextId(), deviceId);
+ }
return 0;
}
diff --git a/utils/misc/src/main/java/org/onlab/packet/MacAddress.java b/utils/misc/src/main/java/org/onlab/packet/MacAddress.java
index e41fb05..b048794 100644
--- a/utils/misc/src/main/java/org/onlab/packet/MacAddress.java
+++ b/utils/misc/src/main/java/org/onlab/packet/MacAddress.java
@@ -56,6 +56,14 @@
*/
public static final MacAddress IPV4_MULTICAST_MASK = valueOf("ff:ff:ff:80:00:00");
/**
+ * IPv6 multicast MAC address.
+ */
+ public static final MacAddress IPV6_MULTICAST = valueOf("33:33:00:00:00:00");
+ /**
+ * IPv6 multicast MAC mask.
+ */
+ public static final MacAddress IPV6_MULTICAST_MASK = valueOf("FF:FF:00:00:00:00");
+ /**
* A set of LLDP MAC addresses.
*/
public static final Set<MacAddress> LLDP = ImmutableSet.of(