Julian Lawrence
Committed by Gerrit Code Review

Updated mfwd delete behavior and fixed some small bugs

Change-Id: Id354a88507e94b83fd0007c084cdbf35093bbd1a
...@@ -37,9 +37,32 @@ public class McastDeleteCommand extends AbstractShellCommand { ...@@ -37,9 +37,32 @@ public class McastDeleteCommand extends AbstractShellCommand {
37 required = true, multiValued = false) 37 required = true, multiValued = false)
38 String gAddr = null; 38 String gAddr = null;
39 39
40 + @Argument(index = 2, name = "egressList",
41 + description = "Egress id/port",
42 + required = false, multiValued = true)
43 + String[] egressList = null;
44 +
45 +
40 @Override 46 @Override
41 protected void execute() { 47 protected void execute() {
48 +
49 + boolean deleted = false;
42 McastRouteTable mrib = McastRouteTable.getInstance(); 50 McastRouteTable mrib = McastRouteTable.getInstance();
51 +
52 + if (egressList == null) {
43 mrib.removeRoute(sAddr, gAddr); 53 mrib.removeRoute(sAddr, gAddr);
54 + deleted = true;
55 + } else {
56 + // check list for validity before we begin to delete.
57 + for (String egress : egressList) {
58 + deleted = mrib.removeEgress(sAddr, gAddr, egress);
59 + }
60 + }
61 +
62 + if (deleted) {
63 + print("Successful delete");
64 + } else {
65 + print("Failed to delete");
66 + }
44 } 67 }
45 } 68 }
......
...@@ -79,8 +79,7 @@ public class McastIntentManager { ...@@ -79,8 +79,7 @@ public class McastIntentManager {
79 TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); 79 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
80 TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment(); 80 TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment();
81 81
82 - if (mroute.getIngressPoint() == null || 82 + if (mroute.getIngressPoint() == null) {
83 - mroute.getEgressPoints().isEmpty()) {
84 return null; 83 return null;
85 } 84 }
86 85
...@@ -96,16 +95,22 @@ public class McastIntentManager { ...@@ -96,16 +95,22 @@ public class McastIntentManager {
96 .matchIPDst(mroute.getGaddr()) 95 .matchIPDst(mroute.getGaddr())
97 .matchIPSrc(mroute.getSaddr()); 96 .matchIPSrc(mroute.getSaddr());
98 97
99 - SinglePointToMultiPointIntent intent = 98 +
100 - SinglePointToMultiPointIntent.builder() 99 + SinglePointToMultiPointIntent.Builder builder = SinglePointToMultiPointIntent.builder()
101 .appId(McastForwarding.getAppId()) 100 .appId(McastForwarding.getAppId())
102 .selector(selector.build()) 101 .selector(selector.build())
103 .treatment(treatment) 102 .treatment(treatment)
104 - .ingressPoint(mroute.getIngressPoint().getConnectPoint()) 103 + .ingressPoint(mroute.getIngressPoint().getConnectPoint());
105 - .egressPoints(mroute.getEgressConnectPoints()). 104 +
106 - build(); 105 + // allowing intent to be pushed without egress points means we can drop packets.
106 + if (!mroute.getEgressPoints().isEmpty()) {
107 + builder.egressPoints(mroute.getEgressConnectPoints());
108 + }
107 109
110 + SinglePointToMultiPointIntent intent = builder.build();
108 intentService.submit(intent); 111 intentService.submit(intent);
112 + mroute.setDirty(false);
113 +
109 return intent; 114 return intent;
110 } 115 }
111 116
...@@ -114,9 +119,10 @@ public class McastIntentManager { ...@@ -114,9 +119,10 @@ public class McastIntentManager {
114 * 119 *
115 * @param mroute the mcast route whose intent we want to remove 120 * @param mroute the mcast route whose intent we want to remove
116 */ 121 */
117 - public void withdrawIntent(McastRouteBase mroute) { 122 + public void withdrawIntent(McastRoute mroute) {
118 Intent intent = intentService.getIntent(mroute.getIntentKey()); 123 Intent intent = intentService.getIntent(mroute.getIntentKey());
119 intentService.withdraw(intent); 124 intentService.withdraw(intent);
125 + mroute.setDirty(false);
120 } 126 }
121 127
122 /** 128 /**
......
...@@ -57,6 +57,21 @@ interface McastRoute { ...@@ -57,6 +57,21 @@ interface McastRoute {
57 public boolean isIp6(); 57 public boolean isIp6();
58 58
59 /** 59 /**
60 + * Get the dirty state.
61 + *
62 + * @return whether this route is dirty or not.
63 + */
64 + public boolean getDirty();
65 +
66 + /**
67 + * Set the dirty state to indicate that something changed.
68 + * This may require an update to the flow tables (intents).
69 + *
70 + * @param dirty set the dirty bit
71 + */
72 + public void setDirty(boolean dirty);
73 +
74 + /**
60 * Add the ingress ConnectPoint. 75 * Add the ingress ConnectPoint.
61 * 76 *
62 * @param cpstr string representing a ConnectPoint 77 * @param cpstr string representing a ConnectPoint
......
...@@ -17,7 +17,6 @@ package org.onosproject.mfwd.impl; ...@@ -17,7 +17,6 @@ package org.onosproject.mfwd.impl;
17 17
18 import static com.google.common.base.Preconditions.checkNotNull; 18 import static com.google.common.base.Preconditions.checkNotNull;
19 19
20 -import org.apache.commons.collections.set.ListOrderedSet;
21 import org.onlab.packet.IpPrefix; 20 import org.onlab.packet.IpPrefix;
22 import org.onosproject.net.ConnectPoint; 21 import org.onosproject.net.ConnectPoint;
23 import org.onosproject.net.intent.SinglePointToMultiPointIntent; 22 import org.onosproject.net.intent.SinglePointToMultiPointIntent;
...@@ -267,6 +266,33 @@ public class McastRouteBase implements McastRoute { ...@@ -267,6 +266,33 @@ public class McastRouteBase implements McastRoute {
267 } 266 }
268 267
269 /** 268 /**
269 + * Remove an egress from McastConnectPoint.
270 + *
271 + * @param connectPoint the egress connect point
272 + * @return boolean result of removal
273 + */
274 + public boolean removeEgressPoint(String connectPoint) {
275 + checkNotNull(connectPoint);
276 + return this.removeEgressPoint(ConnectPoint.deviceConnectPoint(connectPoint));
277 + }
278 +
279 + /**
280 + * Remove an egress from McastConnectPoint.
281 + *
282 + * @param cp the egress connect point
283 + * @return boolean result of removal
284 + */
285 + public boolean removeEgressPoint(ConnectPoint cp) {
286 + boolean removed = false;
287 + McastConnectPoint mcp = this.findEgressConnectPoint(checkNotNull(cp));
288 + if (mcp != null) {
289 + removed = egressPoints.remove(mcp);
290 + setDirty(true);
291 + }
292 + return removed;
293 + }
294 +
295 + /**
270 * Add an egress McastConnectPoint. 296 * Add an egress McastConnectPoint.
271 * 297 *
272 * @param cpstr deviceId/port of the connect point 298 * @param cpstr deviceId/port of the connect point
...@@ -292,7 +318,7 @@ public class McastRouteBase implements McastRoute { ...@@ -292,7 +318,7 @@ public class McastRouteBase implements McastRoute {
292 * @return Set of egress ConnectPoints 318 * @return Set of egress ConnectPoints
293 */ 319 */
294 public Set<ConnectPoint> getEgressConnectPoints() { 320 public Set<ConnectPoint> getEgressConnectPoints() {
295 - Set<ConnectPoint> cps = new ListOrderedSet(); 321 + Set<ConnectPoint> cps = new HashSet<ConnectPoint>();
296 322
297 for (McastConnectPoint mcp : egressPoints) { 323 for (McastConnectPoint mcp : egressPoints) {
298 cps.add(mcp.getConnectPoint()); 324 cps.add(mcp.getConnectPoint());
...@@ -417,7 +443,7 @@ public class McastRouteBase implements McastRoute { ...@@ -417,7 +443,7 @@ public class McastRouteBase implements McastRoute {
417 out += "intent: "; 443 out += "intent: ";
418 out += (intentKey == null) ? "not installed" : this.intentKey.toString(); 444 out += (intentKey == null) ? "not installed" : this.intentKey.toString();
419 out += "\n\tingress: "; 445 out += "\n\tingress: ";
420 - out += (ingressPoint == null) ? "NULL" : ingressPoint.toString(); 446 + out += (ingressPoint == null) ? "NULL" : ingressPoint.getConnectPoint().toString();
421 out += "\n\tegress: {\n"; 447 out += "\n\tegress: {\n";
422 if (egressPoints != null && !egressPoints.isEmpty()) { 448 if (egressPoints != null && !egressPoints.isEmpty()) {
423 for (McastConnectPoint eg : egressPoints) { 449 for (McastConnectPoint eg : egressPoints) {
......
...@@ -17,6 +17,7 @@ package org.onosproject.mfwd.impl; ...@@ -17,6 +17,7 @@ package org.onosproject.mfwd.impl;
17 17
18 import org.apache.felix.scr.annotations.Service; 18 import org.apache.felix.scr.annotations.Service;
19 import org.onlab.packet.IpPrefix; 19 import org.onlab.packet.IpPrefix;
20 +
20 import java.util.Map; 21 import java.util.Map;
21 import java.util.concurrent.ConcurrentHashMap; 22 import java.util.concurrent.ConcurrentHashMap;
22 import static com.google.common.base.Preconditions.checkNotNull; 23 import static com.google.common.base.Preconditions.checkNotNull;
...@@ -191,6 +192,30 @@ public final class McastRouteTable { ...@@ -191,6 +192,30 @@ public final class McastRouteTable {
191 } 192 }
192 193
193 /** 194 /**
195 + * Delete a specific egress from the MRIB.
196 + *
197 + * @param saddr source address * or x.x.x.x or x.x.x.x/y
198 + * @param gaddr group address x.x.x.x or x.x.x.x/y
199 + * @param egress group address x.x.x.x or x.x.x.x/y
200 + * @return boolean if egress was deleted
201 + */
202 + public boolean removeEgress(String saddr, String gaddr, String egress) {
203 +
204 + IpPrefix gpfx = IpPrefix.valueOf(gaddr);
205 + IpPrefix spfx = IpPrefix.valueOf(0, 0);
206 + if (saddr != null && !saddr.equals("*")) {
207 + spfx = IpPrefix.valueOf(saddr);
208 + }
209 +
210 + McastRouteSource src = (McastRouteSource) findBestMatch(spfx, gpfx);
211 + boolean removed = src.removeEgressPoint(egress);
212 + if (removed) {
213 + src.setIntent();
214 + }
215 + return removed;
216 + }
217 +
218 + /**
194 * Delete a multicast route from the MRIB. 219 * Delete a multicast route from the MRIB.
195 * 220 *
196 * @param saddr source address * or x.x.x.x or x.x.x.x/y 221 * @param saddr source address * or x.x.x.x or x.x.x.x/y
......