Committed by
Gerrit Code Review
Calculate IGMP checksum and use more reasonble max response time.
Also made IGMP properties configurable at runtime. Change-Id: I98b40a43a0c17b7bf21f1bd622032c64d7434214
Showing
4 changed files
with
95 additions
and
14 deletions
... | @@ -138,7 +138,9 @@ public class CordMcast { | ... | @@ -138,7 +138,9 @@ public class CordMcast { |
138 | private String fabricOnosUrl; | 138 | private String fabricOnosUrl; |
139 | 139 | ||
140 | @Activate | 140 | @Activate |
141 | - public void activate() { | 141 | + public void activate(ComponentContext context) { |
142 | + modified(context); | ||
143 | + | ||
142 | appId = coreService.registerApplication("org.onosproject.cordmcast"); | 144 | appId = coreService.registerApplication("org.onosproject.cordmcast"); |
143 | componentConfigService.registerProperties(getClass()); | 145 | componentConfigService.registerProperties(getClass()); |
144 | mcastService.addListener(listener); | 146 | mcastService.addListener(listener); | ... | ... |
... | @@ -18,6 +18,7 @@ package org.onosproject.igmp; | ... | @@ -18,6 +18,7 @@ package org.onosproject.igmp; |
18 | import org.apache.felix.scr.annotations.Activate; | 18 | import org.apache.felix.scr.annotations.Activate; |
19 | import org.apache.felix.scr.annotations.Component; | 19 | import org.apache.felix.scr.annotations.Component; |
20 | import org.apache.felix.scr.annotations.Deactivate; | 20 | import org.apache.felix.scr.annotations.Deactivate; |
21 | +import org.apache.felix.scr.annotations.Modified; | ||
21 | import org.apache.felix.scr.annotations.Property; | 22 | import org.apache.felix.scr.annotations.Property; |
22 | import org.apache.felix.scr.annotations.Reference; | 23 | import org.apache.felix.scr.annotations.Reference; |
23 | import org.apache.felix.scr.annotations.ReferenceCardinality; | 24 | import org.apache.felix.scr.annotations.ReferenceCardinality; |
... | @@ -31,6 +32,8 @@ import org.onlab.packet.Ip4Address; | ... | @@ -31,6 +32,8 @@ import org.onlab.packet.Ip4Address; |
31 | import org.onlab.packet.IpAddress; | 32 | import org.onlab.packet.IpAddress; |
32 | import org.onlab.packet.IpPrefix; | 33 | import org.onlab.packet.IpPrefix; |
33 | import org.onlab.util.SafeRecurringTask; | 34 | import org.onlab.util.SafeRecurringTask; |
35 | +import org.onlab.util.Tools; | ||
36 | +import org.onosproject.cfg.ComponentConfigService; | ||
34 | import org.onosproject.core.ApplicationId; | 37 | import org.onosproject.core.ApplicationId; |
35 | import org.onosproject.core.CoreService; | 38 | import org.onosproject.core.CoreService; |
36 | import org.onosproject.net.ConnectPoint; | 39 | import org.onosproject.net.ConnectPoint; |
... | @@ -63,12 +66,15 @@ import org.onosproject.net.packet.PacketProcessor; | ... | @@ -63,12 +66,15 @@ import org.onosproject.net.packet.PacketProcessor; |
63 | import org.onosproject.net.packet.PacketService; | 66 | import org.onosproject.net.packet.PacketService; |
64 | import org.onosproject.olt.AccessDeviceConfig; | 67 | import org.onosproject.olt.AccessDeviceConfig; |
65 | import org.onosproject.olt.AccessDeviceData; | 68 | import org.onosproject.olt.AccessDeviceData; |
69 | +import org.osgi.service.component.ComponentContext; | ||
66 | import org.slf4j.Logger; | 70 | import org.slf4j.Logger; |
67 | 71 | ||
68 | import java.nio.ByteBuffer; | 72 | import java.nio.ByteBuffer; |
69 | import java.util.Collection; | 73 | import java.util.Collection; |
74 | +import java.util.Dictionary; | ||
70 | import java.util.List; | 75 | import java.util.List; |
71 | import java.util.Map; | 76 | import java.util.Map; |
77 | +import java.util.Properties; | ||
72 | import java.util.concurrent.ConcurrentHashMap; | 78 | import java.util.concurrent.ConcurrentHashMap; |
73 | import java.util.concurrent.Executors; | 79 | import java.util.concurrent.Executors; |
74 | import java.util.concurrent.ScheduledExecutorService; | 80 | import java.util.concurrent.ScheduledExecutorService; |
... | @@ -90,7 +96,7 @@ public class IgmpSnoop { | ... | @@ -90,7 +96,7 @@ public class IgmpSnoop { |
90 | private static final String DEST_IP = "224.0.0.1"; | 96 | private static final String DEST_IP = "224.0.0.1"; |
91 | 97 | ||
92 | private static final int DEFAULT_QUERY_PERIOD_SECS = 60; | 98 | private static final int DEFAULT_QUERY_PERIOD_SECS = 60; |
93 | - private static final byte DEFAULT_IGMP_RESP_CODE = 0; | 99 | + private static final byte DEFAULT_IGMP_RESP_CODE = 100; |
94 | private static final String DEFAULT_MCAST_ADDR = "224.0.0.0/4"; | 100 | private static final String DEFAULT_MCAST_ADDR = "224.0.0.0/4"; |
95 | 101 | ||
96 | @Property(name = "multicastAddress", | 102 | @Property(name = "multicastAddress", |
... | @@ -118,6 +124,9 @@ public class IgmpSnoop { | ... | @@ -118,6 +124,9 @@ public class IgmpSnoop { |
118 | protected NetworkConfigRegistry networkConfig; | 124 | protected NetworkConfigRegistry networkConfig; |
119 | 125 | ||
120 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 126 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
127 | + protected ComponentConfigService componentConfigService; | ||
128 | + | ||
129 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
121 | protected MulticastRouteService multicastService; | 130 | protected MulticastRouteService multicastService; |
122 | 131 | ||
123 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 132 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
... | @@ -169,9 +178,13 @@ public class IgmpSnoop { | ... | @@ -169,9 +178,13 @@ public class IgmpSnoop { |
169 | 178 | ||
170 | 179 | ||
171 | @Activate | 180 | @Activate |
172 | - public void activate() { | 181 | + public void activate(ComponentContext context) { |
182 | + modified(context); | ||
183 | + | ||
173 | appId = coreService.registerApplication("org.onosproject.igmp"); | 184 | appId = coreService.registerApplication("org.onosproject.igmp"); |
174 | 185 | ||
186 | + componentConfigService.registerProperties(getClass()); | ||
187 | + | ||
175 | packetService.addProcessor(processor, PacketProcessor.director(1)); | 188 | packetService.addProcessor(processor, PacketProcessor.director(1)); |
176 | 189 | ||
177 | networkConfig.registerConfigFactory(configFactory); | 190 | networkConfig.registerConfigFactory(configFactory); |
... | @@ -208,13 +221,7 @@ public class IgmpSnoop { | ... | @@ -208,13 +221,7 @@ public class IgmpSnoop { |
208 | 221 | ||
209 | deviceService.addListener(deviceListener); | 222 | deviceService.addListener(deviceListener); |
210 | 223 | ||
211 | - queryPacket = buildQueryPacket(); | 224 | + restartQueryTask(); |
212 | - | ||
213 | - queryTask = queryService.scheduleWithFixedDelay( | ||
214 | - SafeRecurringTask.wrap(this::querySubscribers), | ||
215 | - 0, | ||
216 | - queryPeriod, | ||
217 | - TimeUnit.SECONDS); | ||
218 | 225 | ||
219 | log.info("Started"); | 226 | log.info("Started"); |
220 | } | 227 | } |
... | @@ -229,9 +236,49 @@ public class IgmpSnoop { | ... | @@ -229,9 +236,49 @@ public class IgmpSnoop { |
229 | networkConfig.unregisterConfigFactory(ssmTranslateConfigFactory); | 236 | networkConfig.unregisterConfigFactory(ssmTranslateConfigFactory); |
230 | queryTask.cancel(true); | 237 | queryTask.cancel(true); |
231 | queryService.shutdownNow(); | 238 | queryService.shutdownNow(); |
239 | + componentConfigService.unregisterProperties(getClass(), false); | ||
232 | log.info("Stopped"); | 240 | log.info("Stopped"); |
233 | } | 241 | } |
234 | 242 | ||
243 | + @Modified | ||
244 | + protected void modified(ComponentContext context) { | ||
245 | + Dictionary<?, ?> properties = context != null ? context.getProperties() : new Properties(); | ||
246 | + | ||
247 | + String strQueryPeriod = Tools.get(properties, "queryPeriod"); | ||
248 | + String strResponseCode = Tools.get(properties, "maxRespCode"); | ||
249 | + try { | ||
250 | + byte newMaxRespCode = Byte.parseByte(strResponseCode); | ||
251 | + if (maxRespCode != newMaxRespCode) { | ||
252 | + maxRespCode = newMaxRespCode; | ||
253 | + queryPacket = buildQueryPacket(); | ||
254 | + } | ||
255 | + | ||
256 | + int newQueryPeriod = Integer.parseInt(strQueryPeriod); | ||
257 | + if (newQueryPeriod != queryPeriod) { | ||
258 | + queryPeriod = newQueryPeriod; | ||
259 | + restartQueryTask(); | ||
260 | + } | ||
261 | + | ||
262 | + } catch (NumberFormatException e) { | ||
263 | + log.warn("Error parsing config input", e); | ||
264 | + } | ||
265 | + | ||
266 | + log.info("queryPeriod set to {}", queryPeriod); | ||
267 | + log.info("maxRespCode set to {}", maxRespCode); | ||
268 | + } | ||
269 | + | ||
270 | + private void restartQueryTask() { | ||
271 | + if (queryTask != null) { | ||
272 | + queryTask.cancel(true); | ||
273 | + } | ||
274 | + queryPacket = buildQueryPacket(); | ||
275 | + queryTask = queryService.scheduleWithFixedDelay( | ||
276 | + SafeRecurringTask.wrap(this::querySubscribers), | ||
277 | + 0, | ||
278 | + queryPeriod, | ||
279 | + TimeUnit.SECONDS); | ||
280 | + } | ||
281 | + | ||
235 | private void processFilterObjective(DeviceId devId, Port port, boolean remove) { | 282 | private void processFilterObjective(DeviceId devId, Port port, boolean remove) { |
236 | 283 | ||
237 | //TODO migrate to packet requests when packet service uses filtering objectives | 284 | //TODO migrate to packet requests when packet service uses filtering objectives | ... | ... |
... | @@ -44,6 +44,11 @@ public final class ConfigProperty { | ... | @@ -44,6 +44,11 @@ public final class ConfigProperty { |
44 | STRING, | 44 | STRING, |
45 | 45 | ||
46 | /** | 46 | /** |
47 | + * Indicates the value is a byte. | ||
48 | + */ | ||
49 | + BYTE, | ||
50 | + | ||
51 | + /** | ||
47 | * Indicates the value is an integer. | 52 | * Indicates the value is an integer. |
48 | */ | 53 | */ |
49 | INTEGER, | 54 | INTEGER, |
... | @@ -194,6 +199,16 @@ public final class ConfigProperty { | ... | @@ -194,6 +199,16 @@ public final class ConfigProperty { |
194 | } | 199 | } |
195 | 200 | ||
196 | /** | 201 | /** |
202 | + * Returns the property value as a byte. | ||
203 | + * | ||
204 | + * @return byte value | ||
205 | + */ | ||
206 | + public byte asByte() { | ||
207 | + checkState(type == Type.BYTE, "Value is not a byte"); | ||
208 | + return Byte.parseByte(value); | ||
209 | + } | ||
210 | + | ||
211 | + /** | ||
197 | * Returns the property value as an integer. | 212 | * Returns the property value as an integer. |
198 | * | 213 | * |
199 | * @return integer value | 214 | * @return integer value | ... | ... |
... | @@ -15,6 +15,8 @@ | ... | @@ -15,6 +15,8 @@ |
15 | */ | 15 | */ |
16 | package org.onlab.packet; | 16 | package org.onlab.packet; |
17 | 17 | ||
18 | +import org.slf4j.Logger; | ||
19 | + | ||
18 | import java.nio.ByteBuffer; | 20 | import java.nio.ByteBuffer; |
19 | import java.util.ArrayList; | 21 | import java.util.ArrayList; |
20 | import java.util.Arrays; | 22 | import java.util.Arrays; |
... | @@ -22,8 +24,6 @@ import java.util.HashMap; | ... | @@ -22,8 +24,6 @@ import java.util.HashMap; |
22 | import java.util.List; | 24 | import java.util.List; |
23 | import java.util.Map; | 25 | import java.util.Map; |
24 | 26 | ||
25 | -import org.slf4j.Logger; | ||
26 | - | ||
27 | import static com.google.common.base.MoreObjects.toStringHelper; | 27 | import static com.google.common.base.MoreObjects.toStringHelper; |
28 | import static com.google.common.base.Preconditions.checkNotNull; | 28 | import static com.google.common.base.Preconditions.checkNotNull; |
29 | import static org.onlab.packet.PacketUtils.checkInput; | 29 | import static org.onlab.packet.PacketUtils.checkInput; |
... | @@ -33,7 +33,7 @@ import static org.slf4j.LoggerFactory.getLogger; | ... | @@ -33,7 +33,7 @@ import static org.slf4j.LoggerFactory.getLogger; |
33 | * Implements IGMP control packet format. | 33 | * Implements IGMP control packet format. |
34 | */ | 34 | */ |
35 | public class IGMP extends BasePacket { | 35 | public class IGMP extends BasePacket { |
36 | - private final Logger log = getLogger(getClass()); | 36 | + private static final Logger log = getLogger(IGMP.class); |
37 | 37 | ||
38 | public static final byte TYPE_IGMPV3_MEMBERSHIP_QUERY = 0x11; | 38 | public static final byte TYPE_IGMPV3_MEMBERSHIP_QUERY = 0x11; |
39 | public static final byte TYPE_IGMPV1_MEMBERSHIP_REPORT = 0x12; | 39 | public static final byte TYPE_IGMPV1_MEMBERSHIP_REPORT = 0x12; |
... | @@ -169,6 +169,8 @@ public class IGMP extends BasePacket { | ... | @@ -169,6 +169,8 @@ public class IGMP extends BasePacket { |
169 | // Must calculate checksum | 169 | // Must calculate checksum |
170 | bb.putShort((short) 0); | 170 | bb.putShort((short) 0); |
171 | 171 | ||
172 | + | ||
173 | + | ||
172 | switch (this.igmpType) { | 174 | switch (this.igmpType) { |
173 | 175 | ||
174 | case IGMP.TYPE_IGMPV3_MEMBERSHIP_REPORT: | 176 | case IGMP.TYPE_IGMPV3_MEMBERSHIP_REPORT: |
... | @@ -191,6 +193,21 @@ public class IGMP extends BasePacket { | ... | @@ -191,6 +193,21 @@ public class IGMP extends BasePacket { |
191 | } | 193 | } |
192 | 194 | ||
193 | int size = bb.position(); | 195 | int size = bb.position(); |
196 | + | ||
197 | + // compute checksum if needed | ||
198 | + if (this.checksum == 0) { | ||
199 | + bb.rewind(); | ||
200 | + int accumulation = 0; | ||
201 | + for (int i = 0; i < size * 2; ++i) { | ||
202 | + accumulation += 0xffff & bb.getShort(); | ||
203 | + } | ||
204 | + accumulation = (accumulation >> 16 & 0xffff) | ||
205 | + + (accumulation & 0xffff); | ||
206 | + this.checksum = (short) (~accumulation & 0xffff); | ||
207 | + bb.putShort(2, this.checksum); | ||
208 | + } | ||
209 | + | ||
210 | + | ||
194 | bb.position(0); | 211 | bb.position(0); |
195 | byte[] rdata = new byte[size]; | 212 | byte[] rdata = new byte[size]; |
196 | bb.get(rdata, 0, size); | 213 | bb.get(rdata, 0, size); |
... | @@ -238,7 +255,7 @@ public class IGMP extends BasePacket { | ... | @@ -238,7 +255,7 @@ public class IGMP extends BasePacket { |
238 | igmp.igmpType = bb.get(); | 255 | igmp.igmpType = bb.get(); |
239 | igmp.resField = bb.get(); | 256 | igmp.resField = bb.get(); |
240 | igmp.checksum = bb.getShort(); | 257 | igmp.checksum = bb.getShort(); |
241 | - int len = MINIMUM_HEADER_LEN; | 258 | + |
242 | String msg; | 259 | String msg; |
243 | 260 | ||
244 | switch (igmp.igmpType) { | 261 | switch (igmp.igmpType) { | ... | ... |
-
Please register or login to post a comment