Added McastConnectPoint to track membership source
for egress ConnectPoints by STATIC config, PIM and
IGMP.
Change-Id: Ia913ee697e0cae32dd74db508e5ea2cba0d47c45
diff --git a/apps/mfwd/src/main/java/org/onosproject/mfwd/cli/McastJoinCommand.java b/apps/mfwd/src/main/java/org/onosproject/mfwd/cli/McastJoinCommand.java
index 5172691..3ce2925 100644
--- a/apps/mfwd/src/main/java/org/onosproject/mfwd/cli/McastJoinCommand.java
+++ b/apps/mfwd/src/main/java/org/onosproject/mfwd/cli/McastJoinCommand.java
@@ -20,6 +20,7 @@
import org.onlab.packet.IpPrefix;
import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.mfwd.impl.McastConnectPoint;
import org.onosproject.mfwd.impl.McastRouteBase;
import org.onosproject.mfwd.impl.McastRouteTable;
@@ -76,21 +77,13 @@
if (ingressPort != null) {
String inCP = ingressPort;
log.debug("Ingress port provided: " + inCP);
- String [] cp = inCP.split("/");
- mr.addIngressPoint(cp[0], Long.parseLong(cp[1]));
- } else {
- return;
- }
-
- if (ports == null) {
- return;
+ mr.addIngressPoint(inCP);
}
for (int i = 0; i < ports.length; i++) {
String egCP = ports[i];
log.debug("Egress port provided: " + egCP);
- String [] cp = egCP.split("/");
- mr.addEgressPoint(cp[0], Long.parseLong(cp[1]));
+ mr.addEgressPoint(egCP, McastConnectPoint.JoinSource.STATIC);
}
print("Added the mcast route");
}
diff --git a/apps/mfwd/src/main/java/org/onosproject/mfwd/cli/McastShowCommand.java b/apps/mfwd/src/main/java/org/onosproject/mfwd/cli/McastShowCommand.java
index 750fac9..215ee84 100644
--- a/apps/mfwd/src/main/java/org/onosproject/mfwd/cli/McastShowCommand.java
+++ b/apps/mfwd/src/main/java/org/onosproject/mfwd/cli/McastShowCommand.java
@@ -72,7 +72,7 @@
inPort = mg.getIngressPoint().toString();
log.info("Multicast Ingress: " + inPort);
}
- Set<ConnectPoint> eps = mg.getEgressPoints();
+ Set<ConnectPoint> eps = mg.getEgressConnectPoints();
if (eps != null && !eps.isEmpty()) {
outPorts = eps.toString();
}
diff --git a/apps/mfwd/src/main/java/org/onosproject/mfwd/impl/McastConnectPoint.java b/apps/mfwd/src/main/java/org/onosproject/mfwd/impl/McastConnectPoint.java
new file mode 100644
index 0000000..e2a6ff0
--- /dev/null
+++ b/apps/mfwd/src/main/java/org/onosproject/mfwd/impl/McastConnectPoint.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * 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.mfwd.impl;
+
+import org.onosproject.net.ConnectPoint;
+import java.util.EnumSet;
+import java.util.Set;
+
+/**
+ * Mulitcast ConnectPoint adds a variable to track the usage
+ * of these multicast endpoints.
+ */
+public class McastConnectPoint {
+
+ private ConnectPoint connectPoint;
+
+ public enum JoinSource {
+ STATIC, IGMP, PIM;
+ }
+
+ public EnumSet<JoinSource> interest = EnumSet.noneOf(JoinSource.class);
+
+ public McastConnectPoint(ConnectPoint cp) {
+ this.connectPoint = cp;
+ }
+
+ public McastConnectPoint(ConnectPoint cp, JoinSource src) {
+ this.connectPoint = cp;
+ interest.add(src);
+ }
+
+ public McastConnectPoint(String connectPoint, JoinSource src) {
+ ConnectPoint cp = ConnectPoint.deviceConnectPoint(connectPoint);
+ this.connectPoint = cp;
+ this.interest.add(src);
+ }
+
+ /**
+ * Get the connect point.
+ *
+ * @return connectPoint
+ */
+ public ConnectPoint getConnectPoint() {
+ return connectPoint;
+ }
+
+ /**
+ * Get the sources of interest for this egressPoint.
+ *
+ * @return interest flags
+ */
+ public Set<JoinSource> getInterest() {
+ return interest;
+ }
+}
diff --git a/apps/mfwd/src/main/java/org/onosproject/mfwd/impl/McastForwarding.java b/apps/mfwd/src/main/java/org/onosproject/mfwd/impl/McastForwarding.java
index bcba060..f5bd1e0 100644
--- a/apps/mfwd/src/main/java/org/onosproject/mfwd/impl/McastForwarding.java
+++ b/apps/mfwd/src/main/java/org/onosproject/mfwd/impl/McastForwarding.java
@@ -222,7 +222,7 @@
private void forwardPacketToDst(PacketContext context, McastRoute entry) {
// Send the pack out each of the respective egress ports
- for (ConnectPoint egress : entry.getEgressPoints()) {
+ for (ConnectPoint egress : entry.getEgressConnectPoints()) {
TrafficTreatment treatment = DefaultTrafficTreatment.builder()
.setOutput(egress.port()).build();
diff --git a/apps/mfwd/src/main/java/org/onosproject/mfwd/impl/McastIntentManager.java b/apps/mfwd/src/main/java/org/onosproject/mfwd/impl/McastIntentManager.java
index c3709e6..90f65c9 100644
--- a/apps/mfwd/src/main/java/org/onosproject/mfwd/impl/McastIntentManager.java
+++ b/apps/mfwd/src/main/java/org/onosproject/mfwd/impl/McastIntentManager.java
@@ -101,8 +101,8 @@
.appId(McastForwarding.getAppId())
.selector(selector.build())
.treatment(treatment)
- .ingressPoint(mroute.getIngressPoint())
- .egressPoints(mroute.getEgressPoints()).
+ .ingressPoint(mroute.getIngressPoint().getConnectPoint())
+ .egressPoints(mroute.getEgressConnectPoints()).
build();
intentService.submit(intent);
diff --git a/apps/mfwd/src/main/java/org/onosproject/mfwd/impl/McastRoute.java b/apps/mfwd/src/main/java/org/onosproject/mfwd/impl/McastRoute.java
index d56488e..e78c257 100644
--- a/apps/mfwd/src/main/java/org/onosproject/mfwd/impl/McastRoute.java
+++ b/apps/mfwd/src/main/java/org/onosproject/mfwd/impl/McastRoute.java
@@ -57,48 +57,91 @@
public boolean isIp6();
/**
- * Add the ingress ConnectPoint with a ConnectPoint.
+ * Add the ingress ConnectPoint.
*
- * @param ingress ingress point
+ * @param cpstr string representing a ConnectPoint
+ * @return whether ingress has been added, only add if ingressPoint is null
*/
- public void addIngressPoint(ConnectPoint ingress);
+ public boolean addIngressPoint(String cpstr);
/**
- * Add the ingress Connect Point using. ..
+ * Add the ingress ConnectPoint.
*
- * @param deviceId device ID
- * @param portNum port number
+ * @param cp the ConnectPoint of incoming traffic.
+ * @return whether ingress has been added, only add if ingressPoint is null
*/
- public void addIngressPoint(String deviceId, long portNum);
+ public boolean addIngressPoint(ConnectPoint cp);
/**
* Get the ingress connect point.
*
* @return the ingress connect point
*/
- public ConnectPoint getIngressPoint();
+ public McastConnectPoint getIngressPoint();
/**
* Add an egress connect point.
*
- * @param member the egress ConnectPoint to be added
+ * @param cp the egress McastConnectPoint to be added
+ * @return return the McastConnectPoint
*/
- public void addEgressPoint(ConnectPoint member);
+ public McastConnectPoint addEgressPoint(ConnectPoint cp);
/**
* Add an egress connect point.
*
- * @param deviceId the device ID of the connect point
- * @param portNum the port number of the connect point
+ * @param connectPoint deviceId/portNum
+ * @return return the McastConnectPoint
*/
- public void addEgressPoint(String deviceId, long portNum);
+ public McastConnectPoint addEgressPoint(String connectPoint);
+
+ /**
+ * Add an egress connect point.
+ *
+ * @param cp the egress McastConnectPoint to be added
+ * @param interest the protocol that has shown interest in this route
+ * @return return the McastConnectPoint
+ */
+ public McastConnectPoint addEgressPoint(ConnectPoint cp, McastConnectPoint.JoinSource interest);
+
+ /**
+ * Add an egress connect point.
+ *
+ * @param connectPoint deviceId/portNum
+ * @param interest the protocol that has shown interest in this route
+ * @return return the McastConnectPoint
+ */
+ public McastConnectPoint addEgressPoint(String connectPoint, McastConnectPoint.JoinSource interest);
/**
* Get the egress connect points.
*
* @return a set of egress connect points
*/
- public Set<ConnectPoint> getEgressPoints();
+ public Set<McastConnectPoint> getEgressPoints();
+
+ /**
+ * Get the egress connect points.
+ *
+ * @return a set of egress connect points
+ */
+ public Set<ConnectPoint> getEgressConnectPoints();
+
+ /**
+ * Find the egress connect point if it exists.
+ *
+ * @return the connect point when found, null otherwise.
+ */
+ public McastConnectPoint findEgressConnectPoint(ConnectPoint cp);
+
+ /**
+ * remove Interest from a McastConnectPoint.
+ *
+ * @param mcp connect point.
+ * @param interest the protocol interested in this multicast stream
+ * @return whether or not interest was removed
+ */
+ public boolean removeInterest(McastConnectPoint mcp, McastConnectPoint.JoinSource interest);
/**
* Increment the punt count.
diff --git a/apps/mfwd/src/main/java/org/onosproject/mfwd/impl/McastRouteBase.java b/apps/mfwd/src/main/java/org/onosproject/mfwd/impl/McastRouteBase.java
index 36582ad..730acfa 100644
--- a/apps/mfwd/src/main/java/org/onosproject/mfwd/impl/McastRouteBase.java
+++ b/apps/mfwd/src/main/java/org/onosproject/mfwd/impl/McastRouteBase.java
@@ -17,10 +17,9 @@
import static com.google.common.base.Preconditions.checkNotNull;
+import org.apache.commons.collections.set.ListOrderedSet;
import org.onlab.packet.IpPrefix;
import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.PortNumber;
import org.onosproject.net.intent.SinglePointToMultiPointIntent;
import org.onosproject.net.intent.Key;
@@ -34,11 +33,13 @@
protected final IpPrefix gaddr;
protected final IpPrefix saddr;
- protected ConnectPoint ingressPoint;
- protected Set<ConnectPoint> egressPoints;
+ protected McastConnectPoint ingressPoint;
+ protected Set<McastConnectPoint> egressPoints;
protected boolean isGroup = false;
+ protected boolean dirty = false;
+
/**
* How may times has this packet been punted.
*/
@@ -160,58 +161,120 @@
}
/**
+ * Get the dirty state.
+ *
+ * @return whether this route is dirty or not.
+ */
+ public boolean getDirty() {
+ return this.dirty;
+ }
+
+ /**
+ * Set the dirty state to indicate that something changed.
+ * This may require an update to the flow tables (intents).
+ *
+ * @param dirty set the dirty bit
+ */
+ public void setDirty(boolean dirty) {
+ this.dirty = dirty;
+ }
+
+ /**
* Add an ingress point to this route.
*
* @param ingress incoming connect point
+ * @return whether ingress has been added, only add if ingressPoint is null
*/
- @Override
- public void addIngressPoint(ConnectPoint ingress) {
- ingressPoint = checkNotNull(ingress);
+ public boolean addIngressPoint(ConnectPoint ingress) {
+
+ // Do NOT add the ingressPoint if it is not null.
+ if (this.ingressPoint != null) {
+ // TODO: Log an warning.
+ return false;
+ }
+ this.ingressPoint = new McastConnectPoint(checkNotNull(ingress));
+ setDirty(true);
+ return true;
}
/**
* Add or modify the ingress connect point.
*
- * @param deviceId the switch device Id
- * @param portNum the ingress port number
+ * @param connectPoint string switch device Id
+ * @return whether ingress has been added, only add if ingressPoint is null
*/
- @Override
- public void addIngressPoint(String deviceId, long portNum) {
- ingressPoint = new ConnectPoint(
- DeviceId.deviceId(deviceId),
- PortNumber.portNumber(portNum));
+ public boolean addIngressPoint(String connectPoint) {
+
+ if (this.ingressPoint != null) {
+ // TODO: log a warning.
+ return false;
+ }
+ ConnectPoint cp = ConnectPoint.deviceConnectPoint(checkNotNull(connectPoint));
+ return this.addIngressPoint(cp);
}
/**
- * Get the ingress ConnectPoint.
+ * Get the ingress McastConnectPoint.
*
- * @return the ingress ConnectPoint
+ * @return the ingress McastConnectPoint
*/
- @Override
- public ConnectPoint getIngressPoint() {
+ public McastConnectPoint getIngressPoint() {
return this.ingressPoint;
}
/**
- * Add an egress ConnectPoint.
+ * Add an egress McastConnectPoint.
*
- * @param member member egress connect point
+ * @param cp egress connect point
+ * @return return the McastConnectPoint
*/
- @Override
- public void addEgressPoint(ConnectPoint member) {
- egressPoints.add(checkNotNull(member));
+ public McastConnectPoint addEgressPoint(ConnectPoint cp) {
+ McastConnectPoint mcp = this.findEgressConnectPoint(cp);
+ if (mcp == null) {
+ mcp = new McastConnectPoint(checkNotNull(cp));
+ egressPoints.add(mcp);
+ setDirty(true);
+ }
+ return mcp;
}
/**
- * Add an egress ConnectPoint.
+ * Add an egress connect point from a string.
*
- * @param deviceId deviceId of the connect point
- * @param portNum portNum of the connect point
+ * @param connectPoint string representing a connect point
+ * @return the MulticastConnectPoint
*/
- @Override
- public void addEgressPoint(String deviceId, long portNum) {
- ConnectPoint cp = new ConnectPoint(DeviceId.deviceId(deviceId), PortNumber.portNumber(portNum));
- this.egressPoints.add(cp);
+ public McastConnectPoint addEgressPoint(String connectPoint) {
+ checkNotNull(connectPoint);
+ return this.addEgressPoint(ConnectPoint.deviceConnectPoint(connectPoint));
+ }
+
+ /**
+ * Add an egress McastConnectPoint.
+ *
+ * @param cp the egress connect point
+ * @param interest the source of interest for mcast traffic
+ */
+ public McastConnectPoint addEgressPoint(ConnectPoint cp, McastConnectPoint.JoinSource interest) {
+ checkNotNull(cp);
+ checkNotNull(interest);
+ McastConnectPoint mcp = this.addEgressPoint(cp);
+ if (mcp != null) {
+ mcp.interest.add(interest);
+ setDirty(true);
+ }
+ return mcp;
+ }
+
+ /**
+ * Add an egress McastConnectPoint.
+ *
+ * @param cpstr deviceId/port of the connect point
+ */
+ public McastConnectPoint addEgressPoint(String cpstr, McastConnectPoint.JoinSource interest) {
+ checkNotNull(cpstr);
+ checkNotNull(interest);
+ return this.addEgressPoint(ConnectPoint.deviceConnectPoint(cpstr), interest);
}
/**
@@ -219,12 +282,57 @@
*
* @return Set of egress connect points
*/
- @Override
- public Set<ConnectPoint> getEgressPoints() {
+ public Set<McastConnectPoint> getEgressPoints() {
return egressPoints;
}
/**
+ * Get egress McastConnectPoints points as ConnectPoints for intent system.
+ *
+ * @return Set of egress ConnectPoints
+ */
+ public Set<ConnectPoint> getEgressConnectPoints() {
+ Set<ConnectPoint> cps = new ListOrderedSet();
+
+ for (McastConnectPoint mcp : egressPoints) {
+ cps.add(mcp.getConnectPoint());
+ }
+ return cps;
+ }
+
+ /**
+ * Find the Multicast Connect Point that contains the ConnectPoint.
+ *
+ * @param cp the regular ConnectPoint to match
+ * @return the McastConnectPoint that contains cp or null if not found.
+ */
+ public McastConnectPoint findEgressConnectPoint(ConnectPoint cp) {
+ for (McastConnectPoint mcp : this.egressPoints) {
+ if (mcp.getConnectPoint().equals(cp)) {
+ return mcp;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Remove specified interest from the given ConnectPoint.
+ *
+ * @param mcp connect point.
+ * @param interest the protocol interested in this multicast stream
+ * @return true if removed, false otherwise
+ */
+ public boolean removeInterest(McastConnectPoint mcp, McastConnectPoint.JoinSource interest) {
+ checkNotNull(mcp);
+ if (mcp.interest.contains(interest)) {
+ mcp.interest.remove(interest);
+ setDirty(true);
+ return true;
+ }
+ return false;
+ }
+
+ /**
* Get the number of times the packet has been punted.
*
* @return the punt count
@@ -264,7 +372,7 @@
/**
* Set the Intent key.
*
- * @param intent intent
+ * @param intent the multicast intent
*/
@Override
public void setIntent(SinglePointToMultiPointIntent intent) {
@@ -312,8 +420,8 @@
out += (ingressPoint == null) ? "NULL" : ingressPoint.toString();
out += "\n\tegress: {\n";
if (egressPoints != null && !egressPoints.isEmpty()) {
- for (ConnectPoint eg : egressPoints) {
- out += "\t\t" + eg.toString() + "\n";
+ for (McastConnectPoint eg : egressPoints) {
+ out += "\t\t" + eg.getConnectPoint().toString() + "\n";
}
}
out += ("\t}\n");
diff --git a/apps/mfwd/src/main/java/org/onosproject/mfwd/impl/McastRouteTable.java b/apps/mfwd/src/main/java/org/onosproject/mfwd/impl/McastRouteTable.java
index ff7a026..5a07bec 100644
--- a/apps/mfwd/src/main/java/org/onosproject/mfwd/impl/McastRouteTable.java
+++ b/apps/mfwd/src/main/java/org/onosproject/mfwd/impl/McastRouteTable.java
@@ -157,7 +157,7 @@
if (gpfx.isIp4()) {
this.mrib4.put(gpfx, group);
} else if (gpfx.isIp6() && ipv6Enabled) {
- this.mrib6.put(gpfx, group);
+ this.mrib6.put(gpfx, group);
}
}
@@ -259,7 +259,7 @@
if (group.isIp4()) {
g = mrib4.get(group);
} else if (group.isIp6() && ipv6Enabled) {
- g = mrib6.get(group);
+ g = mrib6.get(group);
}
return g;
}