VOL-2770 IGMPv2 should stay v2, not get converted to v3 for TT use-cases
"outgoingIgmpWithV3" config property added to igmpproxy config parameters.
When it is set to true, outgoing IGMP messages are converted to IGMPv3;
IGMPv2 otherwise.
Change-Id: I9f2f5c15d1073c91f7bd11677e3dd09896321e9e
diff --git a/app/src/main/java/org/opencord/igmpproxy/impl/IgmpManager.java b/app/src/main/java/org/opencord/igmpproxy/impl/IgmpManager.java
index 11e28e5..b985b14 100644
--- a/app/src/main/java/org/opencord/igmpproxy/impl/IgmpManager.java
+++ b/app/src/main/java/org/opencord/igmpproxy/impl/IgmpManager.java
@@ -132,6 +132,7 @@
private static ConnectPoint sourceDeviceAndPort = null;
private static boolean enableIgmpProvisioning = false;
private static boolean igmpOnPodBasis = false;
+ private static boolean outgoingIgmpWithV3 = true;
private static final Integer MAX_PRIORITY = 10000;
private static final String INSTALLED = "installed";
@@ -210,6 +211,10 @@
return unSolicitedTimeout;
}
+ public static boolean outgoingIgmpWithV3() {
+ return outgoingIgmpWithV3;
+ }
+
protected BaseInformationService<SubscriberAndDeviceInformation> subsService;
private List<Byte> validMembershipModes = Arrays.asList(MODE_IS_INCLUDE, MODE_IS_EXCLUDE, CHANGE_TO_INCLUDE_MODE,
@@ -561,7 +566,7 @@
break;
default:
- log.warn("wrong IGMP v3 type:" + igmp.getIgmpType());
+ log.warn("Unknown IGMP message type:" + igmp.getIgmpType());
igmpStatisticsManager.getIgmpStats().increaseInvalidIgmpMsgReceived();
igmpStatisticsManager.getIgmpStats().increaseUnknownIgmpTypePacketsRxCounter();
break;
@@ -870,6 +875,10 @@
pimSSmInterworking = newCfg.pimSsmInterworking();
enableIgmpProvisioning = newCfg.enableIgmpProvisioning();
igmpOnPodBasis = newCfg.igmpOnPodBasis();
+ if (newCfg.outgoingIgmpWithV3() != null &&
+ outgoingIgmpWithV3 != newCfg.outgoingIgmpWithV3()) {
+ outgoingIgmpWithV3 = newCfg.outgoingIgmpWithV3();
+ }
if (connectPointMode != newCfg.connectPointMode() ||
connectPoint != newCfg.connectPoint()) {
diff --git a/app/src/main/java/org/opencord/igmpproxy/impl/IgmpSender.java b/app/src/main/java/org/opencord/igmpproxy/impl/IgmpSender.java
index a4cbaa5..ec958f4 100644
--- a/app/src/main/java/org/opencord/igmpproxy/impl/IgmpSender.java
+++ b/app/src/main/java/org/opencord/igmpproxy/impl/IgmpSender.java
@@ -43,6 +43,7 @@
*/
public final class IgmpSender {
static final String V3_REPORT_ADDRESS = "224.0.0.22";
+ static final String V2_LEAVE_DST = "224.0.0.2";
static final String MAC_ADDRESS = "DE:AD:BE:EF:BA:11";
static final short DEFAULT_MVLAN = 4000;
static final byte DEFAULT_COS = 7;
@@ -103,6 +104,15 @@
return buildIgmpPacket(IGMP.TYPE_IGMPV3_MEMBERSHIP_REPORT, groupIp, igmpMembership, sourceIp, false);
}
+ public Ethernet buildIgmpV2Join(Ip4Address groupIp, Ip4Address sourceIp) {
+ IGMPMembership igmpMembership = new IGMPMembership(groupIp);
+ return buildIgmpPacket(IGMP.TYPE_IGMPV2_MEMBERSHIP_REPORT, groupIp, igmpMembership, sourceIp, true);
+ }
+
+ public Ethernet buildIgmpV2ResponseQuery(Ip4Address groupIp, Ip4Address sourceIp) {
+ return buildIgmpV2Join(groupIp, sourceIp);
+ }
+
public Ethernet buildIgmpV3ResponseQuery(Ip4Address groupIp, Ip4Address sourceIp) {
IGMPMembership igmpMembership = new IGMPMembership(groupIp);
igmpMembership.setRecordType(IGMPMembership.MODE_IS_EXCLUDE);
@@ -117,6 +127,11 @@
return buildIgmpPacket(IGMP.TYPE_IGMPV3_MEMBERSHIP_REPORT, groupIp, igmpMembership, sourceIp, false);
}
+ public Ethernet buildIgmpV2Leave(Ip4Address groupIp, Ip4Address sourceIp) {
+ IGMPMembership igmpMembership = new IGMPMembership(groupIp);
+ return buildIgmpPacket(IGMP.TYPE_IGMPV2_LEAVE_GROUP, groupIp, igmpMembership, sourceIp, true);
+ }
+
public Ethernet buildIgmpV2Query(Ip4Address groupIp, Ip4Address sourceIp) {
return buildIgmpPacket(IGMP.TYPE_IGMPV3_MEMBERSHIP_QUERY, groupIp, null, sourceIp, true);
}
@@ -157,11 +172,8 @@
return null;
}
igmpPacket.addGroup(igmpMembership);
- if (type == IGMP.TYPE_IGMPV3_MEMBERSHIP_REPORT) {
- ip4Packet.setDestinationAddress(Ip4Address.valueOf(V3_REPORT_ADDRESS).toInt());
- } else {
- ip4Packet.setDestinationAddress(groupIp.toInt());
- }
+ ip4Packet.setDestinationAddress(Ip4Address.valueOf(V3_REPORT_ADDRESS).toInt());
+
if (withRAUplink) {
ip4Packet.setOptions(RA_BYTES);
}
@@ -169,7 +181,15 @@
case IGMP.TYPE_IGMPV2_MEMBERSHIP_REPORT:
case IGMP.TYPE_IGMPV2_LEAVE_GROUP:
- return null;
+ if (igmpMembership == null) {
+ return null;
+ }
+ igmpPacket.addGroup(igmpMembership);
+ int dst = (type == IGMP.TYPE_IGMPV2_MEMBERSHIP_REPORT ?
+ groupIp.toInt() :
+ Ip4Address.valueOf(V2_LEAVE_DST).toInt());
+ ip4Packet.setDestinationAddress(dst);
+ break;
default:
igmpStatisticsService.getIgmpStats().increaseUnknownIgmpTypePacketsRxCounter();
return null;
diff --git a/app/src/main/java/org/opencord/igmpproxy/impl/IgmpproxyConfig.java b/app/src/main/java/org/opencord/igmpproxy/impl/IgmpproxyConfig.java
index e8297c1..95beea8 100644
--- a/app/src/main/java/org/opencord/igmpproxy/impl/IgmpproxyConfig.java
+++ b/app/src/main/java/org/opencord/igmpproxy/impl/IgmpproxyConfig.java
@@ -39,6 +39,7 @@
private static final Boolean DEFAULT_PIMSSM_INTERWORKING = false;
private static final Boolean DEFAULT_IGMP_PROVISIONING_SUPPORT = Boolean.FALSE;
private static final Boolean DEFAULT_IGMP_ON_POD_BASIS = Boolean.FALSE;
+ private static final Boolean DEFAULT_OUTGOING_IGMP_WITH_V3 = Boolean.TRUE;
protected static final String CONNECT_POINT_MODE = "globalConnectPointMode";
protected static final String CONNECT_POINT = "globalConnectPoint";
@@ -57,6 +58,7 @@
private static final String SOURCE_DEV_PORT = "sourceDeviceAndPort";
private static final String ENABLE_IGMP_PROVISIONING = "enableIgmpProvisioning";
private static final String IGMP_ON_POD_BASIS = "igmpOnPodBasis";
+ private static final String OUTGOING_IGMP_WITH_V3 = "outgoingIgmpWithV3";
/**
* Gets the value of a string property, protecting for an empty
@@ -214,4 +216,11 @@
return Boolean.parseBoolean(getStringProperty(IGMP_ON_POD_BASIS,
DEFAULT_IGMP_ON_POD_BASIS.toString()));
}
+
+ public Boolean outgoingIgmpWithV3() {
+ if (object == null || object.path(OUTGOING_IGMP_WITH_V3) == null) {
+ return null;
+ }
+ return Boolean.parseBoolean(getStringProperty(OUTGOING_IGMP_WITH_V3, DEFAULT_OUTGOING_IGMP_WITH_V3.toString()));
+ }
}
diff --git a/app/src/main/java/org/opencord/igmpproxy/impl/SingleStateMachine.java b/app/src/main/java/org/opencord/igmpproxy/impl/SingleStateMachine.java
index c4d73a8..ca68bf6 100644
--- a/app/src/main/java/org/opencord/igmpproxy/impl/SingleStateMachine.java
+++ b/app/src/main/java/org/opencord/igmpproxy/impl/SingleStateMachine.java
@@ -139,7 +139,9 @@
public void leave(boolean messageOutAllowed) {
if (messageOutAllowed) {
- Ethernet eth = IgmpSender.getInstance().buildIgmpV3Leave(groupIp, srcIp);
+ Ethernet eth = IgmpManager.outgoingIgmpWithV3() ?
+ IgmpSender.getInstance().buildIgmpV3Leave(groupIp, srcIp) :
+ IgmpSender.getInstance().buildIgmpV2Leave(groupIp, srcIp);
IgmpSender.getInstance().sendIgmpPacketUplink(eth, devId, upLinkPort);
}
}
@@ -155,7 +157,9 @@
class NonMember extends State {
public void join(boolean messageOutAllowed) {
if (messageOutAllowed) {
- Ethernet eth = IgmpSender.getInstance().buildIgmpV3Join(groupIp, srcIp);
+ Ethernet eth = IgmpManager.outgoingIgmpWithV3() ?
+ IgmpSender.getInstance().buildIgmpV3Join(groupIp, srcIp) :
+ IgmpSender.getInstance().buildIgmpV2Join(groupIp, srcIp);
IgmpSender.getInstance().sendIgmpPacketUplink(eth, devId, upLinkPort);
timeOut = getTimeOut(IgmpManager.getUnsolicitedTimeout());
timerId = IgmpTimer.start(SingleStateMachine.this, timeOut);
@@ -173,7 +177,9 @@
public void timeOut() {
if (sendQuery) {
- Ethernet eth = IgmpSender.getInstance().buildIgmpV3ResponseQuery(groupIp, srcIp);
+ Ethernet eth = IgmpManager.outgoingIgmpWithV3() ?
+ IgmpSender.getInstance().buildIgmpV3ResponseQuery(groupIp, srcIp) :
+ IgmpSender.getInstance().buildIgmpV2ResponseQuery(groupIp, srcIp);
IgmpSender.getInstance().sendIgmpPacketUplink(eth, devId, upLinkPort);
timeOut = DEFAULT_MAX_RESP;
}