Julian Lawrence
Committed by Gerrit Code Review

updated mcastforwarding to handle new events

Change-Id: I8b3e9acc147e1f25f19ac25e579f65353cf0c72e
...@@ -32,7 +32,13 @@ import org.onosproject.net.flow.DefaultTrafficSelector; ...@@ -32,7 +32,13 @@ import org.onosproject.net.flow.DefaultTrafficSelector;
32 import org.onosproject.net.flow.DefaultTrafficTreatment; 32 import org.onosproject.net.flow.DefaultTrafficTreatment;
33 import org.onosproject.net.flow.TrafficSelector; 33 import org.onosproject.net.flow.TrafficSelector;
34 import org.onosproject.net.flow.TrafficTreatment; 34 import org.onosproject.net.flow.TrafficTreatment;
35 +import org.onosproject.net.intent.Intent;
36 +import org.onosproject.net.intent.IntentService;
37 +import org.onosproject.net.intent.Key;
38 +import org.onosproject.net.intent.SinglePointToMultiPointIntent;
35 import org.onosproject.net.mcast.McastRoute; 39 import org.onosproject.net.mcast.McastRoute;
40 +import org.onosproject.net.mcast.McastListener;
41 +import org.onosproject.net.mcast.McastEvent;
36 import org.onosproject.net.mcast.MulticastRouteService; 42 import org.onosproject.net.mcast.MulticastRouteService;
37 import org.onosproject.net.packet.DefaultOutboundPacket; 43 import org.onosproject.net.packet.DefaultOutboundPacket;
38 import org.onosproject.net.packet.InboundPacket; 44 import org.onosproject.net.packet.InboundPacket;
...@@ -44,6 +50,10 @@ import org.onosproject.net.packet.PacketService; ...@@ -44,6 +50,10 @@ import org.onosproject.net.packet.PacketService;
44 import org.slf4j.Logger; 50 import org.slf4j.Logger;
45 51
46 import java.util.ArrayList; 52 import java.util.ArrayList;
53 +import java.util.HashMap;
54 +import java.util.HashSet;
55 +import java.util.Map;
56 +import java.util.Set;
47 57
48 import static com.google.common.base.Preconditions.checkNotNull; 58 import static com.google.common.base.Preconditions.checkNotNull;
49 import static org.slf4j.LoggerFactory.getLogger; 59 import static org.slf4j.LoggerFactory.getLogger;
...@@ -66,9 +76,12 @@ public class McastForwarding { ...@@ -66,9 +76,12 @@ public class McastForwarding {
66 protected CoreService coreService; 76 protected CoreService coreService;
67 77
68 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 78 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
69 - protected MulticastRouteService mcastRouteManager; 79 + private IntentService intentService;
70 80
81 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
82 + protected MulticastRouteService mcastRouteManager;
71 83
84 + protected McastIntentManager mcastIntentManager;
72 85
73 private ReactivePacketProcessor processor = new ReactivePacketProcessor(); 86 private ReactivePacketProcessor processor = new ReactivePacketProcessor();
74 private static ApplicationId appId; 87 private static ApplicationId appId;
...@@ -80,6 +93,9 @@ public class McastForwarding { ...@@ -80,6 +93,9 @@ public class McastForwarding {
80 public void activate() { 93 public void activate() {
81 appId = coreService.registerApplication("org.onosproject.mfwd"); 94 appId = coreService.registerApplication("org.onosproject.mfwd");
82 95
96 + mcastIntentManager = new McastIntentManager();
97 + mcastRouteManager.addListener(mcastIntentManager);
98 +
83 packetService.addProcessor(processor, PacketProcessor.director(2)); 99 packetService.addProcessor(processor, PacketProcessor.director(2));
84 100
85 // Build a traffic selector for all multicast traffic 101 // Build a traffic selector for all multicast traffic
...@@ -98,6 +114,8 @@ public class McastForwarding { ...@@ -98,6 +114,8 @@ public class McastForwarding {
98 @Deactivate 114 @Deactivate
99 public void deactivate() { 115 public void deactivate() {
100 packetService.removeProcessor(processor); 116 packetService.removeProcessor(processor);
117 + mcastRouteManager.removeListener(mcastIntentManager);
118 + mcastIntentManager.withdrawAllIntents();
101 processor = null; 119 processor = null;
102 log.info("Stopped"); 120 log.info("Stopped");
103 } 121 }
...@@ -112,10 +130,47 @@ public class McastForwarding { ...@@ -112,10 +130,47 @@ public class McastForwarding {
112 } 130 }
113 131
114 /** 132 /**
133 + * Forward the packet to it's multicast destinations.
134 + *
135 + * @param context The packet context
136 + * @param egressList The list of egress ports which the multicast packet is intended for.
137 + */
138 + private void forwardPacketToDst(PacketContext context, ArrayList<ConnectPoint> egressList) {
139 +
140 + // Send the pack out each of the respective egress ports
141 + for (ConnectPoint egress : egressList) {
142 + TrafficTreatment treatment = DefaultTrafficTreatment.builder()
143 + .setOutput(egress.port()).build();
144 +
145 + OutboundPacket packet = new DefaultOutboundPacket(
146 + egress.deviceId(),
147 + treatment,
148 + context.inPacket().unparsed());
149 +
150 + packetService.emit(packet);
151 + }
152 + }
153 +
154 + public static McastRoute createStaticRoute(String source, String group) {
155 + checkNotNull(source, "Must provide a source");
156 + checkNotNull(group, "Must provide a group");
157 + IpAddress ipSource = IpAddress.valueOf(source);
158 + IpAddress ipGroup = IpAddress.valueOf(group);
159 + return createStaticcreateRoute(ipSource, ipGroup);
160 + }
161 +
162 + public static McastRoute createStaticcreateRoute(IpAddress source, IpAddress group) {
163 + checkNotNull(source, "Must provide a source");
164 + checkNotNull(group, "Must provide a group");
165 + McastRoute.Type type = McastRoute.Type.STATIC;
166 + return new McastRoute(source, group, type);
167 + }
168 +
169 + /**
115 * Packet processor responsible for forwarding packets along their paths. 170 * Packet processor responsible for forwarding packets along their paths.
116 */ 171 */
117 - private class ReactivePacketProcessor implements PacketProcessor {
118 172
173 + private class ReactivePacketProcessor implements PacketProcessor {
119 /** 174 /**
120 * Process incoming packets. 175 * Process incoming packets.
121 * 176 *
...@@ -188,42 +243,75 @@ public class McastForwarding { ...@@ -188,42 +243,75 @@ public class McastForwarding {
188 // Send the pack out each of the egress devices & port 243 // Send the pack out each of the egress devices & port
189 forwardPacketToDst(context, egressList); 244 forwardPacketToDst(context, egressList);
190 } 245 }
246 +
191 } 247 }
192 248
193 - /** 249 + private class McastIntentManager implements McastListener {
194 - * Forward the packet to it's multicast destinations.
195 - *
196 - * @param context The packet context
197 - * @param egressList The list of egress ports which the multicast packet is intended for.
198 - */
199 - private void forwardPacketToDst(PacketContext context, ArrayList<ConnectPoint> egressList) {
200 250
201 - // Send the pack out each of the respective egress ports 251 + private Map<McastRoute, Key> intentHashMap;
202 - for (ConnectPoint egress : egressList) {
203 - TrafficTreatment treatment = DefaultTrafficTreatment.builder()
204 - .setOutput(egress.port()).build();
205 252
206 - OutboundPacket packet = new DefaultOutboundPacket( 253 + public McastIntentManager() {
207 - egress.deviceId(), 254 + intentHashMap = new HashMap<>();
208 - treatment, 255 + }
209 - context.inPacket().unparsed());
210 256
211 - packetService.emit(packet); 257 + @Override
258 + public void event(McastEvent event) {
259 + McastRoute route = event.subject().route();
260 + if (intentHashMap.containsKey(route)) {
261 + withdrawIntent(intentHashMap.get(route));
262 + }
263 + Key routeKey = setIntent(route);
264 + intentHashMap.put(route, routeKey);
212 } 265 }
213 - }
214 266
215 - public static McastRoute createStaticRoute(String source, String group) { 267 + private Key setIntent(McastRoute route) {
216 - checkNotNull(source, "Must provide a source");
217 - checkNotNull(group, "Must provide a group");
218 - IpAddress ipSource = IpAddress.valueOf(source);
219 - IpAddress ipGroup = IpAddress.valueOf(group);
220 - return createStaticcreateRoute(ipSource, ipGroup);
221 - }
222 268
223 - public static McastRoute createStaticcreateRoute(IpAddress source, IpAddress group) { 269 + ConnectPoint ingressPoint = mcastRouteManager.fetchSource(route);
224 - checkNotNull(source, "Must provide a source"); 270 + Set<ConnectPoint> egressPoints = new HashSet<>(mcastRouteManager.fetchSinks(route));
225 - checkNotNull(group, "Must provide a group"); 271 +
226 - McastRoute.Type type = McastRoute.Type.STATIC; 272 + TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
227 - return new McastRoute(source, group, type); 273 + TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment();
274 +
275 + if (ingressPoint == null) {
276 + log.warn("Can't set intent without an ingress or egress connect points");
277 + return null;
278 + }
279 +
280 + selector.matchEthType(Ethernet.TYPE_IPV4)
281 + .matchIPDst(route.group().toIpPrefix())
282 + .matchIPSrc(route.source().toIpPrefix());
283 +
284 + SinglePointToMultiPointIntent.Builder builder = SinglePointToMultiPointIntent.builder()
285 + .appId(appId)
286 + .selector(selector.build())
287 + .treatment(treatment)
288 + .ingressPoint(ingressPoint);
289 +
290 + // allowing intent to be pushed without egress points means we can drop packets.
291 + if (!egressPoints.isEmpty()) {
292 + builder.egressPoints(egressPoints);
293 + }
294 +
295 + SinglePointToMultiPointIntent intent = builder.build();
296 + intentService.submit(intent);
297 +
298 + return intent.key();
299 + }
300 +
301 + public void withdrawAllIntents() {
302 + for (Map.Entry<McastRoute, Key> entry : intentHashMap.entrySet()) {
303 + withdrawIntent(entry.getValue());
304 + }
305 + intentHashMap.clear();
306 + }
307 +
308 + public void withdrawIntent(Key key) {
309 + if (key == null) {
310 + // nothing to withdraw
311 + return;
312 + }
313 + Intent intent = intentService.getIntent(key);
314 + intentService.withdraw(intent);
315 + }
228 } 316 }
229 } 317 }
......