Committed by
Gerrit Code Review
Support source-specific IGMP joins.
Change-Id: I422f54f908998460ceff994f9b3bfbf3d2f81a56
Showing
1 changed file
with
40 additions
and
15 deletions
... | @@ -320,32 +320,57 @@ public class IgmpSnoop { | ... | @@ -320,32 +320,57 @@ public class IgmpSnoop { |
320 | 320 | ||
321 | IGMPMembership membership = (IGMPMembership) group; | 321 | IGMPMembership membership = (IGMPMembership) group; |
322 | 322 | ||
323 | - // TODO allow pulling source from IGMP packet | 323 | + IpAddress groupAddress = membership.getGaddr(); |
324 | - IpAddress source = ssmTranslateTable.get(group.getGaddr()); | ||
325 | - if (source == null) { | ||
326 | - log.warn("No source found in SSM translate table for {}", group.getGaddr()); | ||
327 | - return; | ||
328 | - } | ||
329 | - | ||
330 | - McastRoute route = new McastRoute(source, | ||
331 | - group.getGaddr(), | ||
332 | - McastRoute.Type.IGMP); | ||
333 | 324 | ||
334 | if (membership.getRecordType() == IGMPMembership.MODE_IS_INCLUDE || | 325 | if (membership.getRecordType() == IGMPMembership.MODE_IS_INCLUDE || |
335 | membership.getRecordType() == IGMPMembership.CHANGE_TO_INCLUDE_MODE) { | 326 | membership.getRecordType() == IGMPMembership.CHANGE_TO_INCLUDE_MODE) { |
336 | 327 | ||
337 | - multicastService.removeSink(route, location); | 328 | + if (membership.getSources().isEmpty()) { |
338 | - // TODO remove route if all sinks are gone | 329 | + McastRoute route = ssmTranslateRoute(groupAddress); |
330 | + if (route != null) { | ||
331 | + removeRoute(route, location); | ||
332 | + } | ||
333 | + } else { | ||
334 | + membership.getSources().stream() | ||
335 | + .map(source -> new McastRoute(source, groupAddress, McastRoute.Type.IGMP)) | ||
336 | + .forEach(route -> addRoute(route, location)); | ||
337 | + } | ||
339 | } else if (membership.getRecordType() == IGMPMembership.MODE_IS_EXCLUDE || | 338 | } else if (membership.getRecordType() == IGMPMembership.MODE_IS_EXCLUDE || |
340 | membership.getRecordType() == IGMPMembership.CHANGE_TO_EXCLUDE_MODE) { | 339 | membership.getRecordType() == IGMPMembership.CHANGE_TO_EXCLUDE_MODE) { |
341 | 340 | ||
342 | - multicastService.add(route); | 341 | + if (membership.getSources().isEmpty()) { |
343 | - multicastService.addSink(route, location); | 342 | + McastRoute route = ssmTranslateRoute(groupAddress); |
343 | + if (route != null) { | ||
344 | + addRoute(route, location); | ||
345 | + } | ||
346 | + } else { | ||
347 | + membership.getSources().stream() | ||
348 | + .map(source -> new McastRoute(source, groupAddress, McastRoute.Type.IGMP)) | ||
349 | + .forEach(route -> removeRoute(route, location)); | ||
350 | + } | ||
344 | } | 351 | } |
345 | - | ||
346 | }); | 352 | }); |
347 | } | 353 | } |
348 | 354 | ||
355 | + private McastRoute ssmTranslateRoute(IpAddress group) { | ||
356 | + IpAddress source = ssmTranslateTable.get(group); | ||
357 | + if (source == null) { | ||
358 | + log.warn("No SSM translate source found for group {}", group); | ||
359 | + return null; | ||
360 | + } | ||
361 | + return new McastRoute(source, group, McastRoute.Type.IGMP); | ||
362 | + } | ||
363 | + | ||
364 | + private void addRoute(McastRoute route, ConnectPoint location) { | ||
365 | + multicastService.add(route); | ||
366 | + multicastService.addSink(route, location); | ||
367 | + } | ||
368 | + | ||
369 | + private void removeRoute(McastRoute route, ConnectPoint location) { | ||
370 | + multicastService.removeSink(route, location); | ||
371 | + // TODO remove route if all sinks are gone | ||
372 | + } | ||
373 | + | ||
349 | private ByteBuffer buildQueryPacket() { | 374 | private ByteBuffer buildQueryPacket() { |
350 | IGMP igmp = new IGMP(); | 375 | IGMP igmp = new IGMP(); |
351 | igmp.setIgmpType(IGMP.TYPE_IGMPV3_MEMBERSHIP_QUERY); | 376 | igmp.setIgmpType(IGMP.TYPE_IGMPV3_MEMBERSHIP_QUERY); | ... | ... |
-
Please register or login to post a comment