Committed by
Gerrit Code Review
updated mcastforwarding to handle new events
Change-Id: I8b3e9acc147e1f25f19ac25e579f65353cf0c72e
Showing
1 changed file
with
117 additions
and
29 deletions
... | @@ -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)); | ||
212 | } | 262 | } |
263 | + Key routeKey = setIntent(route); | ||
264 | + intentHashMap.put(route, routeKey); | ||
213 | } | 265 | } |
214 | 266 | ||
215 | - public static McastRoute createStaticRoute(String source, String group) { | 267 | + private Key setIntent(McastRoute route) { |
216 | - checkNotNull(source, "Must provide a source"); | 268 | + |
217 | - checkNotNull(group, "Must provide a group"); | 269 | + ConnectPoint ingressPoint = mcastRouteManager.fetchSource(route); |
218 | - IpAddress ipSource = IpAddress.valueOf(source); | 270 | + Set<ConnectPoint> egressPoints = new HashSet<>(mcastRouteManager.fetchSinks(route)); |
219 | - IpAddress ipGroup = IpAddress.valueOf(group); | 271 | + |
220 | - return createStaticcreateRoute(ipSource, ipGroup); | 272 | + TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); |
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; | ||
221 | } | 278 | } |
222 | 279 | ||
223 | - public static McastRoute createStaticcreateRoute(IpAddress source, IpAddress group) { | 280 | + selector.matchEthType(Ethernet.TYPE_IPV4) |
224 | - checkNotNull(source, "Must provide a source"); | 281 | + .matchIPDst(route.group().toIpPrefix()) |
225 | - checkNotNull(group, "Must provide a group"); | 282 | + .matchIPSrc(route.source().toIpPrefix()); |
226 | - McastRoute.Type type = McastRoute.Type.STATIC; | 283 | + |
227 | - return new McastRoute(source, group, type); | 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 | } | ... | ... |
-
Please register or login to post a comment