Calculate IGMP checksum and use more reasonble max response time.
Also made IGMP properties configurable at runtime.
Change-Id: I98b40a43a0c17b7bf21f1bd622032c64d7434214
diff --git a/src/main/java/org/onosproject/igmp/IgmpSnoop.java b/src/main/java/org/onosproject/igmp/IgmpSnoop.java
index 03f561b..19bd221 100644
--- a/src/main/java/org/onosproject/igmp/IgmpSnoop.java
+++ b/src/main/java/org/onosproject/igmp/IgmpSnoop.java
@@ -18,6 +18,7 @@
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Modified;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
@@ -31,6 +32,8 @@
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
import org.onlab.util.SafeRecurringTask;
+import org.onlab.util.Tools;
+import org.onosproject.cfg.ComponentConfigService;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.net.ConnectPoint;
@@ -63,12 +66,15 @@
import org.onosproject.net.packet.PacketService;
import org.onosproject.olt.AccessDeviceConfig;
import org.onosproject.olt.AccessDeviceData;
+import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
import java.nio.ByteBuffer;
import java.util.Collection;
+import java.util.Dictionary;
import java.util.List;
import java.util.Map;
+import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
@@ -90,7 +96,7 @@
private static final String DEST_IP = "224.0.0.1";
private static final int DEFAULT_QUERY_PERIOD_SECS = 60;
- private static final byte DEFAULT_IGMP_RESP_CODE = 0;
+ private static final byte DEFAULT_IGMP_RESP_CODE = 100;
private static final String DEFAULT_MCAST_ADDR = "224.0.0.0/4";
@Property(name = "multicastAddress",
@@ -118,6 +124,9 @@
protected NetworkConfigRegistry networkConfig;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected ComponentConfigService componentConfigService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected MulticastRouteService multicastService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
@@ -169,9 +178,13 @@
@Activate
- public void activate() {
+ public void activate(ComponentContext context) {
+ modified(context);
+
appId = coreService.registerApplication("org.onosproject.igmp");
+ componentConfigService.registerProperties(getClass());
+
packetService.addProcessor(processor, PacketProcessor.director(1));
networkConfig.registerConfigFactory(configFactory);
@@ -208,13 +221,7 @@
deviceService.addListener(deviceListener);
- queryPacket = buildQueryPacket();
-
- queryTask = queryService.scheduleWithFixedDelay(
- SafeRecurringTask.wrap(this::querySubscribers),
- 0,
- queryPeriod,
- TimeUnit.SECONDS);
+ restartQueryTask();
log.info("Started");
}
@@ -229,9 +236,49 @@
networkConfig.unregisterConfigFactory(ssmTranslateConfigFactory);
queryTask.cancel(true);
queryService.shutdownNow();
+ componentConfigService.unregisterProperties(getClass(), false);
log.info("Stopped");
}
+ @Modified
+ protected void modified(ComponentContext context) {
+ Dictionary<?, ?> properties = context != null ? context.getProperties() : new Properties();
+
+ String strQueryPeriod = Tools.get(properties, "queryPeriod");
+ String strResponseCode = Tools.get(properties, "maxRespCode");
+ try {
+ byte newMaxRespCode = Byte.parseByte(strResponseCode);
+ if (maxRespCode != newMaxRespCode) {
+ maxRespCode = newMaxRespCode;
+ queryPacket = buildQueryPacket();
+ }
+
+ int newQueryPeriod = Integer.parseInt(strQueryPeriod);
+ if (newQueryPeriod != queryPeriod) {
+ queryPeriod = newQueryPeriod;
+ restartQueryTask();
+ }
+
+ } catch (NumberFormatException e) {
+ log.warn("Error parsing config input", e);
+ }
+
+ log.info("queryPeriod set to {}", queryPeriod);
+ log.info("maxRespCode set to {}", maxRespCode);
+ }
+
+ private void restartQueryTask() {
+ if (queryTask != null) {
+ queryTask.cancel(true);
+ }
+ queryPacket = buildQueryPacket();
+ queryTask = queryService.scheduleWithFixedDelay(
+ SafeRecurringTask.wrap(this::querySubscribers),
+ 0,
+ queryPeriod,
+ TimeUnit.SECONDS);
+ }
+
private void processFilterObjective(DeviceId devId, Port port, boolean remove) {
//TODO migrate to packet requests when packet service uses filtering objectives