blob: a05b9623d68e6efaa0152096d3ae3c3eeef20339 [file] [log] [blame]
/*
* Copyright 2017-present Open Networking Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.opencord.igmpproxy.impl;
import org.onlab.packet.IGMPMembership;
import org.onlab.packet.Ip4Address;
import org.onlab.packet.VlanId;
import org.onosproject.net.DeviceId;
import org.onosproject.net.PortNumber;
import java.util.ArrayList;
import java.util.Iterator;
/**
* Date struct to keep Igmp member infomations.
*/
public final class GroupMember {
private final VlanId vlan;
private final DeviceId deviceId;
private final PortNumber portNumber;
private final Ip4Address groupIp;
private final boolean v2;
private byte recordType = IGMPMembership.MODE_IS_INCLUDE;
private ArrayList<Ip4Address> sourceList = new ArrayList<>();
private int keepAliveQueryInterval = 0;
private int keepAliveQueryCount = 0;
private int lastQueryInterval = 0;
private int lastQueryCount = 0;
private boolean leave = false;
public GroupMember(Ip4Address groupIp, VlanId vlan, DeviceId deviceId, PortNumber portNum, boolean isV2) {
this.groupIp = groupIp;
this.vlan = vlan;
this.deviceId = deviceId;
this.portNumber = portNum;
v2 = isV2;
}
static String getkey(Ip4Address groupIp, DeviceId deviceId, PortNumber portNum) {
return groupIp.toString() + deviceId.toString() + portNum.toString();
}
public String getkey() {
return GroupMember.getkey(groupIp, deviceId, portNumber);
}
public String getId() {
return getkey();
}
public VlanId getvlan() {
return vlan;
}
public DeviceId getDeviceId() {
return deviceId;
}
public PortNumber getPortNumber() {
return portNumber;
}
public Ip4Address getGroupIp() {
return groupIp;
}
public byte getRecordType() {
return recordType;
}
public boolean getv2() {
return v2;
}
public ArrayList<Ip4Address> getSourceList() {
return sourceList;
}
public void updateList(byte recordType, ArrayList<Ip4Address> newSourceList) {
this.recordType = recordType;
this.sourceList.clear();
this.sourceList.addAll(newSourceList);
/*TODO : support SSM
if (this.recordType == IGMPMembership.MODE_IS_INCLUDE) {
switch (recordType) {
case IGMPMembership.MODE_IS_INCLUDE:
case IGMPMembership.CHANGE_TO_INCLUDE_MODE:
//however , set to include<B> anyway
this.sourceList = sourceList;
this.recordType = IGMPMembership.MODE_IS_INCLUDE;
break;
case IGMPMembership.MODE_IS_EXCLUDE:
case IGMPMembership.CHANGE_TO_EXCLUDE_MODE:
//set to exclude<B>
this.sourceList = sourceList;
this.recordType = IGMPMembership.MODE_IS_EXCLUDE;
break;
case IGMPMembership.ALLOW_NEW_SOURCES:
//set to include <A+B>
join(this.sourceList, sourceList);
break;
case IGMPMembership.BLOCK_OLD_SOURCES:
//set to include <A-B>
exclude(this.sourceList, sourceList);
break;
default:
break;
}
} else if (this.recordType == IGMPMembership.MODE_IS_EXCLUDE) {
switch (recordType) {
case IGMPMembership.MODE_IS_INCLUDE:
case IGMPMembership.CHANGE_TO_INCLUDE_MODE:
//set to include<B>
this.recordType = IGMPMembership.MODE_IS_INCLUDE;
this.sourceList = sourceList;
break;
case IGMPMembership.MODE_IS_EXCLUDE:
case IGMPMembership.CHANGE_TO_EXCLUDE_MODE:
this.sourceList = sourceList;
this.recordType = IGMPMembership.MODE_IS_EXCLUDE;
break;
case IGMPMembership.ALLOW_NEW_SOURCES:
//set to exclude <A-B>
exclude(this.sourceList, sourceList);
break;
case IGMPMembership.BLOCK_OLD_SOURCES:
//set to exclude <A+B>
join(this.sourceList, sourceList);
break;
default:
break;
}
}*/
return;
}
/*join B to A (A+B)*/
private void join(ArrayList<Integer> listA, ArrayList<Integer> listB) {
Iterator<Integer> iterA = null;
Iterator<Integer> iterB = listB.iterator();
boolean exists;
while (iterB.hasNext()) {
iterA = listA.iterator();
exists = false;
int ipToAdd = iterB.next();
while (iterA.hasNext()) {
if (iterA.next().equals(ipToAdd)) {
exists = true;
break;
}
}
if (!exists) {
listA.add(ipToAdd);
}
}
}
/* include A and B (A*B)*/
private void intersection(ArrayList<Integer> listA, ArrayList<Integer> listB) {
Iterator<Integer> iterA = listA.iterator();
Iterator<Integer> iterB;
boolean exists;
while (iterA.hasNext()) {
iterB = listB.iterator();
int ipToInclude = iterA.next();
exists = false;
while (iterB.hasNext()) {
if (iterB.next().equals(ipToInclude)) {
exists = true;
break;
}
}
if (!exists) {
iterA.remove();
}
}
}
/*exclude B from A (A-B)*/
private void exclude(ArrayList<Integer> listA, ArrayList<Integer> listB) {
Iterator<Integer> iterA = null;
Iterator<Integer> iterB = listB.iterator();
while (iterB.hasNext()) {
iterA = listA.iterator();
int ipToDel = iterB.next();
while (iterA.hasNext()) {
if (iterA.next().equals(ipToDel)) {
iterA.remove();
break;
}
}
}
}
public void setLeave(boolean l) {
leave = l;
}
public boolean isLeave() {
return leave;
}
public int getKeepAliveQueryInterval() {
return keepAliveQueryInterval;
}
public int getKeepAliveQueryCount() {
return keepAliveQueryCount;
}
public int getLastQueryInterval() {
return lastQueryInterval;
}
public int getLastQueryCount() {
return lastQueryCount;
}
public void keepAliveQueryCount(boolean add) {
if (add) {
keepAliveQueryCount++;
} else {
keepAliveQueryCount = 0;
}
}
public void lastQueryCount(boolean add) {
if (add) {
lastQueryCount++;
} else {
lastQueryCount = 0;
}
}
public void keepAliveInterval(boolean add) {
if (add) {
keepAliveQueryInterval++;
} else {
keepAliveQueryInterval = 0;
}
}
public void lastQueryInterval(boolean add) {
if (add) {
lastQueryInterval++;
} else {
lastQueryInterval = 0;
}
}
public void resetAllTimers() {
keepAliveQueryInterval = 0;
keepAliveQueryCount = 0;
lastQueryInterval = 0;
lastQueryCount = 0;
}
}