From 81b091424eabaeb77c562ffc45b7d1643c93b79d Mon Sep 17 00:00:00 2001 From: Jonathan Hart Date: Wed, 27 Apr 2016 10:09:33 -0700 Subject: [PATCH] Support source-specific IGMP joins. Change-Id: I422f54f908998460ceff994f9b3bfbf3d2f81a56 --- .../java/org/onosproject/igmp/IgmpSnoop.java | 55 ++++++++++++++----- 1 file changed, 40 insertions(+), 15 deletions(-) diff --git a/apps/igmp/src/main/java/org/onosproject/igmp/IgmpSnoop.java b/apps/igmp/src/main/java/org/onosproject/igmp/IgmpSnoop.java index c473f2521f..96a94cb65b 100644 --- a/apps/igmp/src/main/java/org/onosproject/igmp/IgmpSnoop.java +++ b/apps/igmp/src/main/java/org/onosproject/igmp/IgmpSnoop.java @@ -320,32 +320,57 @@ public class IgmpSnoop { IGMPMembership membership = (IGMPMembership) group; - // TODO allow pulling source from IGMP packet - IpAddress source = ssmTranslateTable.get(group.getGaddr()); - if (source == null) { - log.warn("No source found in SSM translate table for {}", group.getGaddr()); - return; - } - - McastRoute route = new McastRoute(source, - group.getGaddr(), - McastRoute.Type.IGMP); + IpAddress groupAddress = membership.getGaddr(); if (membership.getRecordType() == IGMPMembership.MODE_IS_INCLUDE || membership.getRecordType() == IGMPMembership.CHANGE_TO_INCLUDE_MODE) { - multicastService.removeSink(route, location); - // TODO remove route if all sinks are gone + if (membership.getSources().isEmpty()) { + McastRoute route = ssmTranslateRoute(groupAddress); + if (route != null) { + removeRoute(route, location); + } + } else { + membership.getSources().stream() + .map(source -> new McastRoute(source, groupAddress, McastRoute.Type.IGMP)) + .forEach(route -> addRoute(route, location)); + } } else if (membership.getRecordType() == IGMPMembership.MODE_IS_EXCLUDE || membership.getRecordType() == IGMPMembership.CHANGE_TO_EXCLUDE_MODE) { - multicastService.add(route); - multicastService.addSink(route, location); + if (membership.getSources().isEmpty()) { + McastRoute route = ssmTranslateRoute(groupAddress); + if (route != null) { + addRoute(route, location); + } + } else { + membership.getSources().stream() + .map(source -> new McastRoute(source, groupAddress, McastRoute.Type.IGMP)) + .forEach(route -> removeRoute(route, location)); + } } - }); } + private McastRoute ssmTranslateRoute(IpAddress group) { + IpAddress source = ssmTranslateTable.get(group); + if (source == null) { + log.warn("No SSM translate source found for group {}", group); + return null; + } + return new McastRoute(source, group, McastRoute.Type.IGMP); + } + + private void addRoute(McastRoute route, ConnectPoint location) { + multicastService.add(route); + multicastService.addSink(route, location); + } + + private void removeRoute(McastRoute route, ConnectPoint location) { + multicastService.removeSink(route, location); + // TODO remove route if all sinks are gone + } + private ByteBuffer buildQueryPacket() { IGMP igmp = new IGMP(); igmp.setIgmpType(IGMP.TYPE_IGMPV3_MEMBERSHIP_QUERY);