*/
package org.opendaylight.lispflowmapping.implementation.util;
-import java.net.InetAddress;
+import static org.opendaylight.yangtools.yang.common.UintConversions.fromJava;
+
+import com.google.common.base.Preconditions;
import java.util.ArrayList;
import java.util.Date;
-import java.util.LinkedHashMap;
import java.util.HashMap;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
-
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.SimpleAddress;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.source.dest.key.SourceDestKey;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.source.dest.key.SourceDestKeyBuilder;
+import org.opendaylight.lispflowmapping.config.ConfigIni;
+import org.opendaylight.lispflowmapping.lisp.type.MappingData;
import org.opendaylight.lispflowmapping.lisp.util.LispAddressUtil;
import org.opendaylight.lispflowmapping.lisp.util.MaskUtil;
import org.opendaylight.lispflowmapping.lisp.util.SourceDestKeyHelper;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.SimpleAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.source.dest.key.SourceDestKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.source.dest.key.SourceDestKeyBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.inet.binary.types.rev160303.IpAddressBinary;
import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.XtrId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.locatorrecords.LocatorRecord;
import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.locatorrecords.LocatorRecordBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.base.Preconditions;
-
/**
- * Utility class to implement merging of locator sets
+ * Utility class to implement merging of locator sets.
*
* @author Lorand Jakab
*
*/
public final class MappingMergeUtil {
- protected static final Logger LOG = LoggerFactory.getLogger(MappingMergeUtil.class);
- // A mapping registration is valid for this many milliseconds
- private static final long REGISTRATION_VALIDITY = 200000L;
+ private static final Logger LOG = LoggerFactory.getLogger(MappingMergeUtil.class);
// Utility class, should not be instantiated
private MappingMergeUtil() {
return newLocator;
}
- private static int compareLocators(LocatorRecord a, LocatorRecord b) {
- InetAddress aInet = LispAddressUtil.ipAddressToInet(a.getRloc().getAddress());
- InetAddress bInet = LispAddressUtil.ipAddressToInet(b.getRloc().getAddress());
- return LispAddressUtil.compareInetAddresses(aInet, bInet);
+ private static int compareLocators(LocatorRecord one, LocatorRecord two) {
+ byte[] oneIp = LispAddressUtil.ipAddressToByteArray(one.getRloc().getAddress());
+ byte[] twoIp = LispAddressUtil.ipAddressToByteArray(two.getRloc().getAddress());
+ return LispAddressUtil.compareIpAddressByteArrays(oneIp, twoIp);
}
private static void mergeLocatorRecords(MappingRecordBuilder mrb, MappingRecord newRecord) {
Rloc newRloc = newLocator.getRloc();
if (locatorMap.containsKey(newRloc)) {
// overlapping locator
- if (locatorMap.get(newRloc).equals(newLocator)) {
- continue;
- } else {
+ if (!locatorMap.get(newRloc).equals(newLocator)) {
LocatorRecord mergedLocator = mergeLocators(locatorMap.get(newRloc), newLocator);
newLocatorList.add(mergedLocator);
}
}
// Build new merged and sorted locator set if need be
- if (newLocatorList.size() != 0) {
+ if (!newLocatorList.isEmpty()) {
List<LocatorRecord> mergedLocators = new ArrayList<LocatorRecord>();
- int mlIt = 0, lIt = 0;
- while (mlIt < newLocatorList.size() && lIt < locators.size()) {
- int cmp = compareLocators(locators.get(lIt), newLocatorList.get(mlIt));
+ int mlocIt = 0;
+ int locIt = 0;
+ while (mlocIt < newLocatorList.size() && locIt < locators.size()) {
+ int cmp = compareLocators(locators.get(locIt), newLocatorList.get(mlocIt));
if (cmp < 0) {
- mergedLocators.add(locators.get(lIt));
- lIt++;
+ mergedLocators.add(locators.get(locIt));
+ locIt++;
} else if (cmp > 0) {
- mergedLocators.add(newLocatorList.get(mlIt));
- mlIt++;
+ mergedLocators.add(newLocatorList.get(mlocIt));
+ mlocIt++;
} else {
// when a locator appears in both lists, keep the new (merged) one and skip the old
- mergedLocators.add(newLocatorList.get(mlIt));
- mlIt++;
- lIt++;
+ mergedLocators.add(newLocatorList.get(mlocIt));
+ mlocIt++;
+ locIt++;
}
}
- while (lIt < locators.size()) {
- mergedLocators.add(locators.get(lIt));
- lIt++;
+ while (locIt < locators.size()) {
+ mergedLocators.add(locators.get(locIt));
+ locIt++;
}
- while (mlIt < newLocatorList.size()) {
- mergedLocators.add(newLocatorList.get(mlIt));
- mlIt++;
+ while (mlocIt < newLocatorList.size()) {
+ mergedLocators.add(newLocatorList.get(mlocIt));
+ mlocIt++;
}
mrb.setLocatorRecord(mergedLocators);
}
return mrb.build();
}
- public static MappingRecord mergeXtrIdMappings(List<Object> records, List<XtrId> expiredMappings,
- Set<IpAddress> sourceRlocs) {
+ public static MappingData mergeXtrIdMappings(List<Object> mappingDataList, List<MappingData> expiredMappingDataList,
+ Set<IpAddressBinary> sourceRlocs) {
MappingRecordBuilder mrb = null;
XtrId xtrId = null;
Long timestamp = Long.MAX_VALUE;
- for (int i = 0; i < records.size(); i++) {
- MappingRecord record = (MappingRecord) records.get(i);
+ for (int i = 0; i < mappingDataList.size(); i++) {
+ MappingData mappingData = (MappingData) mappingDataList.get(i);
+ MappingRecord record = mappingData.getRecord();
// Skip expired mappings and add them to a list to be returned to the caller
- if (timestampIsExpired(record.getTimestamp())) {
- expiredMappings.add(record.getXtrId());
+ if (timestampIsExpired(mappingData.getTimestamp())) {
+ expiredMappingDataList.add(mappingData);
continue;
}
if (mrb == null) {
- mrb = new MappingRecordBuilder((MappingRecord) records.get(i));
+ mrb = new MappingRecordBuilder(record);
}
// Save the oldest valid timestamp
- if (record.getTimestamp() < timestamp) {
- timestamp = record.getTimestamp();
- xtrId = record.getXtrId();
+ if (mappingData.getTimestamp().getTime() < timestamp) {
+ timestamp = mappingData.getTimestamp().getTime();
+ xtrId = mappingData.getXtrId();
}
// Merge record fields and locators
return null;
}
mrb.setXtrId(xtrId);
- mrb.setTimestamp(timestamp);
- return mrb.build();
+ return new MappingData(mrb.build(), new Date(timestamp));
}
- public static boolean mappingIsExpired(MappingRecord mapping) {
- Preconditions.checkNotNull(mapping, "mapping should not be null!");
- if (mapping.getTimestamp() != null) {
- return timestampIsExpired(mapping.getTimestamp());
+ /*
+ * The following three methods intentionally throw an exception when their argument is null, because they can't
+ * decide based on that to return true or false, so the calling function should do that and only call these with
+ * non-null arguments
+ */
+ public static boolean mappingIsExpired(MappingData mappingData) {
+ Preconditions.checkNotNull(mappingData, "mapping should not be null!");
+ if (mappingData.getTimestamp() != null) {
+ return timestampIsExpired(mappingData.getTimestamp());
}
return false;
}
return timestampIsExpired(timestamp.getTime());
}
- public static boolean timestampIsExpired(Long timestamp) {
+ private static boolean timestampIsExpired(Long timestamp) {
Preconditions.checkNotNull(timestamp, "timestamp should not be null!");
- if ((System.currentTimeMillis() - timestamp) > REGISTRATION_VALIDITY) {
+ if ((System.currentTimeMillis() - timestamp) > ConfigIni.getInstance().getRegistrationValiditySb()) {
return true;
}
return false;
}
- public static Object computeNbSbIntersection(MappingRecord nbMapping, MappingRecord sbMapping) {
+ public static MappingData computeNbSbIntersection(MappingData nbMappingData,
+ MappingData sbMappingData) {
+ return new MappingData(computeNbSbIntersection(nbMappingData.getRecord(), sbMappingData.getRecord()));
+ }
+
+ private static MappingRecord computeNbSbIntersection(MappingRecord nbMapping, MappingRecord sbMapping) {
// returns a MappingRecord which has the more specific EID, and intersection of locator records.
// If locators intersection is empty, original NB mapping is returned.
// The intersection is only computed for mappings with maskable EIDs.
short sbMask = MaskUtil.getMaskForAddress(sbMapping.getEid().getAddress());
short nbMask = MaskUtil.getMaskForAddress(nbMapping.getEid().getAddress());
- if (nbMapping.getEid().getAddress() instanceof SourceDestKey) {
+ if (nbMapping.getEid().getAddress() instanceof org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
+ .ietf.lisp.address.types.rev151105.lisp.address.address.SourceDestKey) {
nbMask = SourceDestKeyHelper.getDstMask(nbMapping.getEid());
- if ( nbMask < sbMask) {
+ if (nbMask < sbMask) {
// We have to create a new SourceDest EID, where the source is same as the
// one in NB record, and dest EID is the more specific from SB mapping record.
- SourceDestKeyBuilder sdb = new SourceDestKeyBuilder(
- ((SourceDestKey) nbMapping.getEid().getAddress()));
- sdb.setDest(new SimpleAddress ((IpPrefix) sbMapping.getEid().getAddress()));
+ SourceDestKey srcDstKey = ((org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp
+ .address.types.rev151105.lisp.address.address.SourceDestKey) nbMapping.getEid()
+ .getAddress()).getSourceDestKey();
+ SourceDestKeyBuilder sdb = new SourceDestKeyBuilder(srcDstKey);
+ sdb.setDest(new SimpleAddress(getIpPrefix(sbMapping.getEid().getAddress())));
mrb.setEid(LispAddressUtil.asSrcDstEid(sdb.build(), nbMapping.getEid().getVirtualNetworkId()));
}
} else if (nbMask < sbMask) {
// Both EIDs are IP prefixes. SB mapping is a subprefix so we have to update EID intersection
mrb.setEid(sbMapping.getEid());
- mrb.setMaskLength(sbMask);
}
}
// find and update locators intersection if not empty
if (sbLocatorMap.containsKey(nbRloc)) {
// common locator found. use the NB record as the common locator.
- if (sbLocatorMap.get(nbRloc).getPriority() == (short) 255) {
+ if (sbLocatorMap.get(nbRloc).getPriority().toJava() == (short) 255) {
// if SB locator has p == 255 then common locator takes all NB fields except for p
// which must be set to 255
LocatorRecordBuilder lrb = new LocatorRecordBuilder(nbLocator);
- lrb.setPriority((short) 255);
+ lrb.setPriority(fromJava((short) 255));
commonLocators.add(lrb.build());
} else {
commonLocators.add(nbLocator);
return commonLocators;
}
+ private static IpPrefix getIpPrefix(Address address) {
+ IpPrefix ipPrefix = null;
+
+ if (address instanceof org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns
+ .yang.ietf.lisp.address.types.rev151105.lisp.address.address.Ipv4Prefix) {
+ org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp
+ .address.address.Ipv4Prefix lispPrefix = (org.opendaylight.yang.gen.v1.urn.ietf.params
+ .xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.Ipv4Prefix) address;
+
+ Ipv4Prefix inetPrefix = new Ipv4Prefix(lispPrefix.getIpv4Prefix());
+ ipPrefix = new IpPrefix(inetPrefix);
+ } else if (address instanceof org.opendaylight.yang.gen.v1.urn.ietf.params
+ .xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.Ipv6Prefix) {
+ org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp
+ .address.address.Ipv6Prefix lispPrefix = (org.opendaylight.yang.gen.v1.urn.ietf.params
+ .xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.Ipv6Prefix) address;
+
+ Ipv6Prefix inetPrefix = new Ipv6Prefix(lispPrefix.getIpv6Prefix());
+ ipPrefix = new IpPrefix(inetPrefix);
+ } else {
+ LOG.warn("Southbound mapping address is not an IpPrefix");
+ }
+ return ipPrefix;
+ }
}