Jonathan Hart
Committed by Gerrit Code Review

Fixes to the IGMP app to process group membership reports

Change-Id: I7a478011caadb8250f6a25b5fb5a820485e593b6
1 -/*
2 - * Copyright 2015 Open Networking Laboratory
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - */
16 -package org.onosproject.igmp;
17 -
18 -import org.onlab.packet.IGMP;
19 -import org.onosproject.net.ConnectPoint;
20 -
21 -/**
22 - * Process an IGMP Membership Report.
23 - */
24 -public final class IGMPProcessMembership {
25 -
26 - // Hide the default constructor.
27 - private IGMPProcessMembership() {
28 - }
29 -
30 - /**
31 - * Process the IGMP Membership report.
32 - *
33 - * @param igmp the deserialized IGMP message.
34 - * @param receivedFrom the ConnectPoint this message came from.
35 - */
36 - public static void processMembership(IGMP igmp, ConnectPoint receivedFrom) {
37 - }
38 -
39 -}
1 -/*
2 - * Copyright 2015 Open Networking Laboratory
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - */
16 -package org.onosproject.igmp;
17 -
18 -import org.onlab.packet.IGMP;
19 -import org.onosproject.net.ConnectPoint;
20 -
21 -/**
22 - * Process IGMP Query messages.
23 - */
24 -public final class IGMPProcessQuery {
25 -
26 - // Hide the default constructor.
27 - private IGMPProcessQuery() {
28 - }
29 -
30 - /**
31 - * Process the IGMP Membership Query message.
32 - *
33 - * @param igmp The deserialzed IGMP message
34 - * @param receivedFrom the ConnectPoint this message came from.
35 - */
36 - public static void processQuery(IGMP igmp, ConnectPoint receivedFrom) {
37 - }
38 -
39 -}
...@@ -24,6 +24,7 @@ import org.apache.felix.scr.annotations.ReferenceCardinality; ...@@ -24,6 +24,7 @@ import org.apache.felix.scr.annotations.ReferenceCardinality;
24 import org.onlab.packet.EthType; 24 import org.onlab.packet.EthType;
25 import org.onlab.packet.Ethernet; 25 import org.onlab.packet.Ethernet;
26 import org.onlab.packet.IGMP; 26 import org.onlab.packet.IGMP;
27 +import org.onlab.packet.IGMPMembership;
27 import org.onlab.packet.IPv4; 28 import org.onlab.packet.IPv4;
28 import org.onlab.packet.Ip4Address; 29 import org.onlab.packet.Ip4Address;
29 import org.onlab.packet.IpAddress; 30 import org.onlab.packet.IpAddress;
...@@ -76,7 +77,7 @@ public class IgmpSnoop { ...@@ -76,7 +77,7 @@ public class IgmpSnoop {
76 private static final String DEFAULT_MCAST_ADDR = "224.0.0.0/4"; 77 private static final String DEFAULT_MCAST_ADDR = "224.0.0.0/4";
77 78
78 @Property(name = "multicastAddress", 79 @Property(name = "multicastAddress",
79 - label = "Define the multicast base raneg to listen to") 80 + label = "Define the multicast base range to listen to")
80 private String multicastAddress = DEFAULT_MCAST_ADDR; 81 private String multicastAddress = DEFAULT_MCAST_ADDR;
81 82
82 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 83 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
...@@ -194,6 +195,7 @@ public class IgmpSnoop { ...@@ -194,6 +195,7 @@ public class IgmpSnoop {
194 } 195 }
195 196
196 private void processQuery(IGMP pkt, ConnectPoint location) { 197 private void processQuery(IGMP pkt, ConnectPoint location) {
198 + // TODO is this the right thing to do for a query?
197 pkt.getGroups().forEach(group -> group.getSources().forEach(src -> { 199 pkt.getGroups().forEach(group -> group.getSources().forEach(src -> {
198 200
199 McastRoute route = new McastRoute(src, 201 McastRoute route = new McastRoute(src,
...@@ -205,6 +207,36 @@ public class IgmpSnoop { ...@@ -205,6 +207,36 @@ public class IgmpSnoop {
205 })); 207 }));
206 } 208 }
207 209
210 + private void processMembership(IGMP pkt, ConnectPoint location) {
211 + pkt.getGroups().forEach(group -> {
212 +
213 + if (!(group instanceof IGMPMembership)) {
214 + log.warn("Wrong group type in IGMP membership");
215 + return;
216 + }
217 +
218 + IGMPMembership membership = (IGMPMembership) group;
219 +
220 + McastRoute route = new McastRoute(IpAddress.valueOf("0.0.0.0"),
221 + group.getGaddr(),
222 + McastRoute.Type.IGMP);
223 +
224 + if (membership.getRecordType() == IGMPMembership.MODE_IS_INCLUDE ||
225 + membership.getRecordType() == IGMPMembership.CHANGE_TO_INCLUDE_MODE) {
226 +
227 +
228 + multicastService.add(route);
229 + multicastService.addSink(route, location);
230 +
231 + } else if (membership.getRecordType() == IGMPMembership.MODE_IS_EXCLUDE ||
232 + membership.getRecordType() == IGMPMembership.CHANGE_TO_EXCLUDE_MODE) {
233 + multicastService.removeSink(route, location);
234 + // TODO remove route if all sinks are gone
235 + }
236 +
237 + });
238 + }
239 +
208 /** 240 /**
209 * Packet processor responsible for handling IGMP packets. 241 * Packet processor responsible for handling IGMP packets.
210 */ 242 */
...@@ -259,7 +291,7 @@ public class IgmpSnoop { ...@@ -259,7 +291,7 @@ public class IgmpSnoop {
259 switch (igmp.getIgmpType()) { 291 switch (igmp.getIgmpType()) {
260 292
261 case IGMP.TYPE_IGMPV3_MEMBERSHIP_REPORT: 293 case IGMP.TYPE_IGMPV3_MEMBERSHIP_REPORT:
262 - IGMPProcessMembership.processMembership(igmp, pkt.receivedFrom()); 294 + processMembership(igmp, pkt.receivedFrom());
263 break; 295 break;
264 296
265 case IGMP.TYPE_IGMPV3_MEMBERSHIP_QUERY: 297 case IGMP.TYPE_IGMPV3_MEMBERSHIP_QUERY:
...@@ -269,12 +301,11 @@ public class IgmpSnoop { ...@@ -269,12 +301,11 @@ public class IgmpSnoop {
269 case IGMP.TYPE_IGMPV1_MEMBERSHIP_REPORT: 301 case IGMP.TYPE_IGMPV1_MEMBERSHIP_REPORT:
270 case IGMP.TYPE_IGMPV2_MEMBERSHIP_REPORT: 302 case IGMP.TYPE_IGMPV2_MEMBERSHIP_REPORT:
271 case IGMP.TYPE_IGMPV2_LEAVE_GROUP: 303 case IGMP.TYPE_IGMPV2_LEAVE_GROUP:
272 - log.debug("IGMP version 1 & 2 message types are not currently supported. Message type: " + 304 + log.debug("IGMP version 1 & 2 message types are not currently supported. Message type: {}",
273 igmp.getIgmpType()); 305 igmp.getIgmpType());
274 break; 306 break;
275 -
276 default: 307 default:
277 - log.debug("Unkown IGMP message type: " + igmp.getIgmpType()); 308 + log.debug("Unknown IGMP message type: {}", igmp.getIgmpType());
278 break; 309 break;
279 } 310 }
280 } 311 }
...@@ -312,7 +343,6 @@ public class IgmpSnoop { ...@@ -312,7 +343,6 @@ public class IgmpSnoop {
312 log.warn("Unknown device event {}", event.type()); 343 log.warn("Unknown device event {}", event.type());
313 break; 344 break;
314 } 345 }
315 -
316 } 346 }
317 347
318 @Override 348 @Override
......
...@@ -54,13 +54,11 @@ public class DistributedMcastStore extends AbstractStore<McastEvent, McastStoreD ...@@ -54,13 +54,11 @@ public class DistributedMcastStore extends AbstractStore<McastEvent, McastStoreD
54 mcastRib = storageService.<McastRoute, MulticastData>consistentMapBuilder() 54 mcastRib = storageService.<McastRoute, MulticastData>consistentMapBuilder()
55 .withName(MCASTRIB) 55 .withName(MCASTRIB)
56 .withSerializer(Serializer.using(KryoNamespace.newBuilder() 56 .withSerializer(Serializer.using(KryoNamespace.newBuilder()
57 - .register(KryoNamespaces.BASIC) 57 + .register(KryoNamespaces.API)
58 - .register(KryoNamespaces.MISC)
59 .register( 58 .register(
60 MulticastData.class, 59 MulticastData.class,
61 McastRoute.class, 60 McastRoute.class,
62 - McastRoute.Type.class, 61 + McastRoute.Type.class
63 - ConnectPoint.class
64 ).build())) 62 ).build()))
65 //.withRelaxedReadConsistency() 63 //.withRelaxedReadConsistency()
66 .build(); 64 .build();
......
...@@ -16,9 +16,9 @@ ...@@ -16,9 +16,9 @@
16 package org.onosproject.incubator.store.mcast.impl; 16 package org.onosproject.incubator.store.mcast.impl;
17 17
18 import com.google.common.collect.ImmutableSet; 18 import com.google.common.collect.ImmutableSet;
19 -import com.google.common.collect.Sets;
20 import org.onosproject.net.ConnectPoint; 19 import org.onosproject.net.ConnectPoint;
21 20
21 +import java.util.HashSet;
22 import java.util.Set; 22 import java.util.Set;
23 import java.util.concurrent.atomic.AtomicBoolean; 23 import java.util.concurrent.atomic.AtomicBoolean;
24 import java.util.concurrent.atomic.AtomicReference; 24 import java.util.concurrent.atomic.AtomicReference;
...@@ -37,13 +37,16 @@ public final class MulticastData { ...@@ -37,13 +37,16 @@ public final class MulticastData {
37 private final AtomicBoolean isEmpty = new AtomicBoolean(); 37 private final AtomicBoolean isEmpty = new AtomicBoolean();
38 38
39 private MulticastData() { 39 private MulticastData() {
40 - this.sinks = Sets.newConcurrentHashSet(); 40 + // FIXME we have major problems trying to serialize these sets
41 + //this.sinks = Sets.newConcurrentHashSet();
42 + this.sinks = new HashSet<>();
41 isEmpty.set(true); 43 isEmpty.set(true);
42 } 44 }
43 45
44 public MulticastData(ConnectPoint source) { 46 public MulticastData(ConnectPoint source) {
45 this.source.set(checkNotNull(source, "Multicast source cannot be null.")); 47 this.source.set(checkNotNull(source, "Multicast source cannot be null."));
46 - this.sinks = Sets.newConcurrentHashSet(); 48 + //this.sinks = Sets.newConcurrentHashSet();
49 + this.sinks = new HashSet<>();
47 isEmpty.set(false); 50 isEmpty.set(false);
48 } 51 }
49 52
......
...@@ -20,6 +20,7 @@ import static org.onlab.packet.PacketUtils.checkBufferLength; ...@@ -20,6 +20,7 @@ import static org.onlab.packet.PacketUtils.checkBufferLength;
20 20
21 public class IGMPMembership extends IGMPGroup { 21 public class IGMPMembership extends IGMPGroup {
22 22
23 + // TODO should be an enum
23 public static final byte MODE_IS_INCLUDE = 0x1; 24 public static final byte MODE_IS_INCLUDE = 0x1;
24 public static final byte MODE_IS_EXCLUDE = 0x2; 25 public static final byte MODE_IS_EXCLUDE = 0x2;
25 public static final byte CHANGE_TO_INCLUDE_MODE = 0x3; 26 public static final byte CHANGE_TO_INCLUDE_MODE = 0x3;
...@@ -50,6 +51,15 @@ public class IGMPMembership extends IGMPGroup { ...@@ -50,6 +51,15 @@ public class IGMPMembership extends IGMPGroup {
50 } 51 }
51 52
52 /** 53 /**
54 + * Gets the IGMP record type.
55 + *
56 + * @return record type
57 + */
58 + public byte getRecordType() {
59 + return recordType;
60 + }
61 +
62 + /**
53 * Serialize this Membership Report. 63 * Serialize this Membership Report.
54 * 64 *
55 * @param bb the ByteBuffer to write into, positioned at the next spot to be written to. 65 * @param bb the ByteBuffer to write into, positioned at the next spot to be written to.
......