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