X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=mappingservice%2Fimplementation%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Flispflowmapping%2Fimplementation%2Flisp%2FMapServer.java;h=b12d2107c80e40ccce57f27bd00c0c513339884e;hb=d1d595dc2d9e96167383836cf3ab41e38460a424;hp=e7a8628c58d65decd90fb43556131b281b935e57;hpb=a065677c2f1fcb0e1d0610531ad7b83e0b1e2690;p=lispflowmapping.git diff --git a/mappingservice/implementation/src/main/java/org/opendaylight/lispflowmapping/implementation/lisp/MapServer.java b/mappingservice/implementation/src/main/java/org/opendaylight/lispflowmapping/implementation/lisp/MapServer.java index e7a8628c5..b12d2107c 100644 --- a/mappingservice/implementation/src/main/java/org/opendaylight/lispflowmapping/implementation/lisp/MapServer.java +++ b/mappingservice/implementation/src/main/java/org/opendaylight/lispflowmapping/implementation/lisp/MapServer.java @@ -18,14 +18,18 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Random; +import java.util.Map.Entry; import org.apache.commons.lang3.BooleanUtils; +import org.apache.commons.lang3.exception.ExceptionUtils; import org.opendaylight.lispflowmapping.implementation.authentication.LispAuthenticationUtil; import org.opendaylight.lispflowmapping.implementation.config.ConfigIni; import org.opendaylight.lispflowmapping.implementation.dao.MappingServiceKeyUtil; import org.opendaylight.lispflowmapping.implementation.util.DAOMappingUtil; import org.opendaylight.lispflowmapping.implementation.util.LispAFIConvertor; import org.opendaylight.lispflowmapping.implementation.util.MapNotifyBuilderHelper; +import org.opendaylight.lispflowmapping.inmemorydb.HashMapDb; +import org.opendaylight.lispflowmapping.implementation.util.MaskUtil; import org.opendaylight.lispflowmapping.interfaces.dao.ILispDAO; import org.opendaylight.lispflowmapping.interfaces.dao.IMappingServiceKey; import org.opendaylight.lispflowmapping.interfaces.dao.MappingEntry; @@ -33,20 +37,22 @@ import org.opendaylight.lispflowmapping.interfaces.dao.MappingServiceRLOCGroup; import org.opendaylight.lispflowmapping.interfaces.dao.MappingServiceSubscriberRLOC; import org.opendaylight.lispflowmapping.interfaces.lisp.IMapNotifyHandler; import org.opendaylight.lispflowmapping.interfaces.lisp.IMapServerAsync; -import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.MapRegister; -import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.MapRequest; -import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.eidrecords.EidRecordBuilder; -import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.eidtolocatorrecords.EidToLocatorRecord; -import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.eidtolocatorrecords.EidToLocatorRecordBuilder; -import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.lispaddress.LispAddressContainer; -import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.lispaddress.lispaddresscontainer.address.LcafKeyValue; -import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.lispsimpleaddress.primitiveaddress.DistinguishedName; -import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.locatorrecords.LocatorRecord; -import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.mapnotifymessage.MapNotifyBuilder; -import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.maprequest.ItrRloc; -import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.maprequest.ItrRlocBuilder; -import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.maprequest.SourceEidBuilder; -import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.maprequestnotification.MapRequestBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.LispAFIAddress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.MapRegister; +import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.eidrecords.EidRecordBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.eidtolocatorrecords.EidToLocatorRecord; +import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.eidtolocatorrecords.EidToLocatorRecordBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lispaddress.LispAddressContainer; +import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lispaddress.lispaddresscontainer.Address; +import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lispaddress.lispaddresscontainer.address.LcafKeyValue; +import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lispaddress.lispaddresscontainer.address.LcafSourceDest; +import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lispsimpleaddress.primitiveaddress.DistinguishedName; +import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.locatorrecords.LocatorRecord; +import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.mapnotifymessage.MapNotifyBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.maprequest.ItrRloc; +import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.maprequest.ItrRlocBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.maprequest.SourceEidBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.maprequestnotification.MapRequestBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -98,7 +104,7 @@ public class MapServer extends AbstractLispComponent implements IMapServerAsync return null; } - private static MapRequest buildSMR(EidToLocatorRecord eidRecord) { + private static MapRequestBuilder buildSMR(LispAddressContainer srcEid) { MapRequestBuilder builder = new MapRequestBuilder(); builder.setAuthoritative(false); builder.setMapDataPresent(false); @@ -107,19 +113,18 @@ public class MapServer extends AbstractLispComponent implements IMapServerAsync builder.setSmr(true); builder.setSmrInvoked(false); - builder.setEidRecord(new ArrayList()); - LispAddressContainer container = eidRecord.getLispAddressContainer(); - builder.getEidRecord().add(new EidRecordBuilder().setMask((short) eidRecord.getMaskLength()).setLispAddressContainer(container).build()); - + builder.setEidRecord(new ArrayList()); + // The address stored in the SMR's EID record is used as Source EID in the SMR-invoked Map-Request. To + // ensure consistent behavior it is set to the value used to originally request a given mapping + builder.getEidRecord().add(new EidRecordBuilder() + .setMask((short)MaskUtil.getMaxMask(LispAFIConvertor.toAFI(srcEid))) + .setLispAddressContainer(srcEid).build()); builder.setItrRloc(new ArrayList()); builder.getItrRloc().add(new ItrRlocBuilder().setLispAddressContainer(LispAFIConvertor.toContainer(getLocalAddress())).build()); - builder.setMapReply(null); builder.setNonce(new Random().nextLong()); - // XXX For now we set source EID to queried EID... - builder.setSourceEid(new SourceEidBuilder().setLispAddressContainer(container).build()); - return builder.build(); + return builder; } public void handleMapRegister(MapRegister mapRegister, boolean smr, IMapNotifyHandler callback) { @@ -139,9 +144,7 @@ public class MapServer extends AbstractLispComponent implements IMapServerAsync } boolean mappingChanged = saveRlocs(eidRecord, smr); if (smr && mappingChanged) { - HashSet subscribers = getSubscribers(eidRecord.getLispAddressContainer(), - eidRecord.getMaskLength()); - handleSmr(eidRecord, subscribers, callback); + sendSmrs(eidRecord, callback); } } if (!failed) { @@ -159,12 +162,10 @@ public class MapServer extends AbstractLispComponent implements IMapServerAsync } public boolean saveRlocs(EidToLocatorRecord eidRecord, boolean checkForChanges) { - List oldLocators = null, newLocators = null; - IMappingServiceKey key = MappingServiceKeyUtil.generateMappingServiceKey(eidRecord.getLispAddressContainer(), eidRecord.getMaskLength()); Map rlocGroups = new HashMap(); if (eidRecord.getLocatorRecord() != null) { for (LocatorRecord locatorRecord : eidRecord.getLocatorRecord()) { - String subkey = getLocatorKey(locatorRecord); + String subkey = getAddressKey(locatorRecord.getLispAddressContainer().getAddress()); if (!rlocGroups.containsKey(subkey)) { rlocGroups.put(subkey, new MappingServiceRLOCGroup(eidRecord.getRecordTtl(), eidRecord.getAction(), eidRecord.isAuthoritative())); } @@ -175,30 +176,57 @@ public class MapServer extends AbstractLispComponent implements IMapServerAsync for (String subkey : rlocGroups.keySet()) { entries.add(new MappingEntry<>(subkey, rlocGroups.get(subkey))); } - if (checkForChanges) { - oldLocators = DAOMappingUtil.getLocatorsByEidToLocatorRecord(eidRecord, dao, shouldIterateMask()); - } - dao.put(key, entries.toArray(new MappingEntry[entries.size()])); - if (checkForChanges) { - newLocators = DAOMappingUtil.getLocatorsByEidToLocatorRecord(eidRecord, dao, shouldIterateMask()); - if (!newLocators.equals(oldLocators)) { - return true; + + if (eidRecord.getLispAddressContainer().getAddress() instanceof LcafSourceDest) { + Entry> oldMapping= null, newMapping = null; + LispAFIAddress srcAddr = getSrcForLcafSrcDst(eidRecord.getLispAddressContainer()); + LispAFIAddress dstAddr = getDstForLcafSrcDst(eidRecord.getLispAddressContainer()); + short srcMask = getSrcMaskForLcafSrcDst(eidRecord.getLispAddressContainer()); + short dstMask = getDstMaskForLcafSrcDst(eidRecord.getLispAddressContainer()); + + if (checkForChanges) { + oldMapping = DAOMappingUtil.getMappingExact(srcAddr, dstAddr, srcMask, dstMask, dao); + } + IMappingServiceKey dstKey = MappingServiceKeyUtil.generateMappingServiceKey(dstAddr, dstMask); + ILispDAO srcDstDao = (ILispDAO) dao.getSpecific(dstKey, LCAF_SRCDST_SUBKEY); + if (srcDstDao == null) { + srcDstDao = new HashMapDb(); + dao.put(dstKey, new MappingEntry<>(LCAF_SRCDST_SUBKEY, srcDstDao)); + } + IMappingServiceKey srcKey = MappingServiceKeyUtil.generateMappingServiceKey(srcAddr, srcMask); + srcDstDao.put(srcKey, entries.toArray(new MappingEntry[entries.size()])); + if (checkForChanges) { + newMapping = DAOMappingUtil.getMappingExact(srcAddr, dstAddr, srcMask, dstMask, dao); + return (newMapping.getValue() == null) ? oldMapping.getValue() != null : + !newMapping.getValue().equals(oldMapping.getValue()); + } + } else { + List oldLocators = null, newLocators = null; + if (checkForChanges) { + oldLocators = DAOMappingUtil.getLocatorsByEidToLocatorRecord(eidRecord, dao, shouldIterateMask()); + } + IMappingServiceKey key = MappingServiceKeyUtil.generateMappingServiceKey(eidRecord.getLispAddressContainer(), + eidRecord.getMaskLength()); + dao.put(key, entries.toArray(new MappingEntry[entries.size()])); + if (checkForChanges) { + newLocators = DAOMappingUtil.getLocatorsByEidToLocatorRecord(eidRecord, dao, shouldIterateMask()); + return (newLocators == null) ? oldLocators != null : !newLocators.equals(oldLocators); } } return false; } - private String getLocatorKey(LocatorRecord locatorRecord) { - if (locatorRecord.getLispAddressContainer().getAddress() instanceof LcafKeyValue) { - LcafKeyValue keyVal = (LcafKeyValue) locatorRecord.getLispAddressContainer().getAddress(); - if (keyVal.getKey().getPrimitiveAddress() instanceof DistinguishedName) { - return ((DistinguishedName) keyVal.getKey().getPrimitiveAddress()).getDistinguishedName(); + private String getAddressKey(Address address) { + if (address instanceof LcafKeyValue) { + LcafKeyValue keyVal = (LcafKeyValue) address; + if (keyVal.getLcafKeyValueAddressAddr().getKey().getPrimitiveAddress() instanceof DistinguishedName) { + return ((DistinguishedName) keyVal.getLcafKeyValueAddressAddr().getKey().getPrimitiveAddress()).getDistinguishedNameAddress().getDistinguishedName(); } } if (shouldOverwrite()) { return ADDRESS_SUBKEY; } else { - return String.valueOf(locatorRecord.getLispAddressContainer().getAddress().hashCode()); + return String.valueOf(address.hashCode()); } } @@ -207,25 +235,84 @@ public class MapServer extends AbstractLispComponent implements IMapServerAsync } public void removeAuthenticationKey(LispAddressContainer address, int maskLen) { - IMappingServiceKey key = MappingServiceKeyUtil.generateMappingServiceKey(address, maskLen); - dao.removeSpecific(key, PASSWORD_SUBKEY); + if (address.getAddress() instanceof LcafSourceDest) { + ILispDAO srcDstDao = getSrcDstInnerDao(address, maskLen); + if (srcDstDao != null) { + IMappingServiceKey srcKey = MappingServiceKeyUtil.generateMappingServiceKey(getSrcForLcafSrcDst(address), + getSrcMaskForLcafSrcDst(address)); + srcDstDao.removeSpecific(srcKey, PASSWORD_SUBKEY); + } + } else { + IMappingServiceKey key = MappingServiceKeyUtil.generateMappingServiceKey(address, maskLen); + dao.removeSpecific(key, PASSWORD_SUBKEY); + } } public void addAuthenticationKey(LispAddressContainer address, int maskLen, String key) { IMappingServiceKey mappingServiceKey = MappingServiceKeyUtil.generateMappingServiceKey(address, maskLen); - dao.put(mappingServiceKey, new MappingEntry(PASSWORD_SUBKEY, key)); + if (address.getAddress() instanceof LcafSourceDest) { + IMappingServiceKey srcKey = MappingServiceKeyUtil.generateMappingServiceKey(getSrcForLcafSrcDst(address), + getSrcMaskForLcafSrcDst(address)); + ILispDAO srcDstDao = getOrInstantiateSrcDstInnerDao(address, maskLen); + srcDstDao.put(srcKey, new MappingEntry(PASSWORD_SUBKEY, key)); + } else { + dao.put(mappingServiceKey, new MappingEntry(PASSWORD_SUBKEY, key)); + } } public void removeMapping(LispAddressContainer address, int maskLen, boolean smr, IMapNotifyHandler callback) { - IMappingServiceKey mappingServiceKey = MappingServiceKeyUtil.generateMappingServiceKey(address, maskLen); + Entry> mapping; + ILispDAO db; + if (address.getAddress() instanceof LcafSourceDest) { + db = getSrcDstInnerDao(address, maskLen); + LispAFIAddress srcAddr = getSrcForLcafSrcDst(address); + short srcMask = getSrcMaskForLcafSrcDst(address); + mapping = DAOMappingUtil.getMappingForEid(srcAddr, srcMask, db); + } else { + db = dao; + mapping = DAOMappingUtil.getMappingForEid(LispAFIConvertor.toAFI(address), maskLen, db); + } if (smr) { HashSet subscribers = getSubscribers(address, maskLen); // mapping is removed before first SMR is sent to avoid inconsistent replies - dao.remove(mappingServiceKey); + removeMappingRlocs(mapping, db); handleSmr(new EidToLocatorRecordBuilder().setLispAddressContainer(address). setMaskLength((short) maskLen).build(), subscribers, callback); + db.removeSpecific(mapping.getKey(), SUBSCRIBERS_SUBKEY); } else { - dao.remove(mappingServiceKey); + removeMappingRlocs(mapping, db); + db.removeSpecific(mapping.getKey(), SUBSCRIBERS_SUBKEY); + } + } + + private void removeMappingRlocs(Entry> mapping, ILispDAO db) { + if (mapping == null || mapping.getValue() == null) { + return; + } + for (MappingServiceRLOCGroup group : mapping.getValue()) { + for (LocatorRecord record : group.getRecords()) { + db.removeSpecific(mapping.getKey(), getAddressKey(record.getLispAddressContainer().getAddress())); + } + } + } + + private void sendSmrs(EidToLocatorRecord record, IMapNotifyHandler callback) { + LispAddressContainer eid = record.getLispAddressContainer(); + HashSet subscribers; + + subscribers = getSubscribers(eid, record.getMaskLength()); + handleSmr(record, subscribers, callback); + + // For SrcDst LCAF also send SMRs to Dst prefix + if (eid.getAddress() instanceof LcafSourceDest) { + LispAddressContainer dstAddr = LispAFIConvertor.toContainer(getDstForLcafSrcDst(eid)); + short dstMask = getDstMaskForLcafSrcDst(eid); + subscribers = getSubscribers(dstAddr, dstMask); + EidToLocatorRecord newRecord = new EidToLocatorRecordBuilder().setAction(record.getAction()). + setAuthoritative(record.isAuthoritative()).setLocatorRecord(record.getLocatorRecord()). + setMapVersion(record.getMapVersion()).setRecordTtl(record.getRecordTtl()). + setLispAddressContainer(dstAddr).setMaskLength(dstMask).build(); + handleSmr(newRecord, subscribers, callback); } } @@ -234,17 +321,19 @@ public class MapServer extends AbstractLispComponent implements IMapServerAsync if (subscribers == null) { return; } - MapRequest mapRequest = buildSMR(record); - LOG.trace("Built SMR packet: " + mapRequest.toString()); - for (MappingServiceSubscriberRLOC rloc : subscribers) { - if (rloc.timedOut()) { - LOG.trace("Lazy removing expired subscriber entry " + rloc.toString()); - subscribers.remove(rloc); + MapRequestBuilder mrb = buildSMR(subscribers.iterator().next().getSrcEid()); + LOG.trace("Built SMR packet: " + mrb.build().toString()); + for (MappingServiceSubscriberRLOC subscriber : subscribers) { + if (subscriber.timedOut()) { + LOG.trace("Lazy removing expired subscriber entry " + subscriber.toString()); + subscribers.remove(subscriber); } else { try { - callback.handleSMR(mapRequest, rloc.getSrcRloc()); + // The Source EID in a SMR is used as EID record in the SMR-invoked Map-Request. + mrb.setSourceEid(new SourceEidBuilder().setLispAddressContainer(record.getLispAddressContainer()).build()); + callback.handleSMR(mrb.build(), subscriber.getSrcRloc()); } catch (Exception e) { - LOG.error("Errors encountered while handling SMR:" + e.getStackTrace()); + LOG.error("Errors encountered while handling SMR:" + ExceptionUtils.getStackTrace(e)); } } }