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=5faea8bf8f1813c5e09f757dfe96d58c9f8b91d6;hb=b91f4a75479b262d57d4a2c162deb15fd14751cb;hp=a8f5ba0ad80106f09c42f56119775b0463c8c101;hpb=73c7f9369eab54ea7d568030255f16b9d21cf503;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 a8f5ba0ad..5faea8bf8 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 @@ -15,34 +15,36 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Enumeration; import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Objects; import java.util.Set; - import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.exception.ExceptionUtils; import org.opendaylight.controller.md.sal.binding.api.NotificationService; -import org.opendaylight.lispflowmapping.implementation.authentication.LispAuthenticationUtil; import org.opendaylight.lispflowmapping.implementation.config.ConfigIni; import org.opendaylight.lispflowmapping.interfaces.dao.SubKeys; import org.opendaylight.lispflowmapping.interfaces.dao.SubscriberRLOC; import org.opendaylight.lispflowmapping.interfaces.lisp.IMapNotifyHandler; import org.opendaylight.lispflowmapping.interfaces.lisp.IMapServerAsync; import org.opendaylight.lispflowmapping.interfaces.mappingservice.IMappingService; +import org.opendaylight.lispflowmapping.lisp.authentication.LispAuthenticationUtil; import org.opendaylight.lispflowmapping.lisp.type.LispMessage; import org.opendaylight.lispflowmapping.lisp.util.LispAddressStringifier; import org.opendaylight.lispflowmapping.lisp.util.LispAddressUtil; import org.opendaylight.lispflowmapping.lisp.util.MapNotifyBuilderHelper; import org.opendaylight.lispflowmapping.lisp.util.MapRequestUtil; import org.opendaylight.lispflowmapping.lisp.util.SourceDestKeyHelper; -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.PortNumber; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.SourceDestKey; +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.MapRegister; +import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.SiteId; import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eid.container.Eid; import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eid.list.EidItem; import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eid.list.EidItemBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapnotifymessage.MapNotifyBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.authkey.container.MappingAuthkey; import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.container.MappingRecord; import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.container.MappingRecordBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.list.MappingRecordItem; @@ -54,27 +56,23 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev15090 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.MappingChanged; import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.MappingOrigin; import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.OdlMappingserviceListener; -import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.SiteId; -import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.mapping.authkey.container.MappingAuthkey; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - import com.google.common.base.Preconditions; public class MapServer implements IMapServerAsync, OdlMappingserviceListener { protected static final Logger LOG = LoggerFactory.getLogger(MapServer.class); + private static final byte[] ALL_ZEROES_XTR_ID = new byte[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ,0}; private IMappingService mapService; - private boolean authenticate; private boolean subscriptionService; private IMapNotifyHandler notifyHandler; private NotificationService notificationService; - public MapServer(IMappingService mapService, boolean authenticate, boolean subscriptionService, + public MapServer(IMappingService mapService, boolean subscriptionService, IMapNotifyHandler notifyHandler, NotificationService notificationService) { Preconditions.checkNotNull(mapService); this.mapService = mapService; - this.authenticate = authenticate; this.subscriptionService = subscriptionService; this.notifyHandler = notifyHandler; this.notificationService = notificationService; @@ -88,42 +86,32 @@ public class MapServer implements IMapServerAsync, OdlMappingserviceListener { this.subscriptionService = subscriptionService; } - @Override - public boolean shouldAuthenticate() { - return authenticate; - } - - @Override - public void setShouldAuthenticate(boolean shouldAuthenticate) { - authenticate = shouldAuthenticate; - } - @SuppressWarnings("unchecked") public void handleMapRegister(MapRegister mapRegister) { - boolean authFailed = false; - String password = null; + boolean mappingUpdated = false; + boolean merge = ConfigIni.getInstance().mappingMergeIsSet() && mapRegister.isMergeEnabled(); Set subscribers = null; MappingRecord oldMapping; + if (merge) { + if (!mapRegister.isXtrSiteIdPresent() || mapRegister.getXtrId() == null) { + LOG.error("Merge bit is set in Map-Register, but xTR-ID is not present. Will not merge."); + merge = false; + } else if (Arrays.equals(mapRegister.getXtrId().getValue(), ALL_ZEROES_XTR_ID)) { + LOG.warn("Merge bit is set in Map-Register, but xTR-ID is all zeroes."); + } + } + for (MappingRecordItem record : mapRegister.getMappingRecordItem()) { MappingRecord mapping = record.getMappingRecord(); - if (authenticate) { - MappingAuthkey authkey = mapService.getAuthenticationKey(mapping.getEid()); - if (authkey != null) { - password = authkey.getKeyString(); - } - if (!LispAuthenticationUtil.validate(mapRegister, password)) { - LOG.warn("Authentication failed"); - authFailed = true; - break; - } - } + oldMapping = (MappingRecord) mapService.getMapping(MappingOrigin.Southbound, mapping.getEid()); - mapService.addMapping(MappingOrigin.Southbound, mapping.getEid(), getSiteId(mapRegister), mapping); + mapService.addMapping(MappingOrigin.Southbound, mapping.getEid(), getSiteId(mapRegister), mapping, merge); if (subscriptionService) { - MappingRecord newMapping = ConfigIni.getInstance().mappingMergeIsSet() - ? (MappingRecord) mapService.getMapping(MappingOrigin.Southbound, mapping.getEid()) : mapping; + MappingRecord newMapping = merge ? + (MappingRecord) mapService.getMapping(MappingOrigin.Southbound, mapping.getEid()) : mapping; + if (mappingChanged(oldMapping, newMapping)) { if (LOG.isDebugEnabled()) { LOG.debug("Mapping update occured for {} SMRs will be sent for its subscribers.", @@ -131,43 +119,52 @@ public class MapServer implements IMapServerAsync, OdlMappingserviceListener { } subscribers = getSubscribers(mapping.getEid()); sendSmrs(mapping, subscribers); + mappingUpdated = true; } } } - if (!authFailed && BooleanUtils.isTrue(mapRegister.isWantMapNotify())) { + if (BooleanUtils.isTrue(mapRegister.isWantMapNotify())) { LOG.trace("MapRegister wants MapNotify"); MapNotifyBuilder builder = new MapNotifyBuilder(); List rlocs = null; - if (ConfigIni.getInstance().mappingMergeIsSet()) { - Set notifyRlocs = new HashSet(); + if (merge) { + Set notifyRlocs = new HashSet(); List mergedMappings = new ArrayList(); for (MappingRecordItem record : mapRegister.getMappingRecordItem()) { MappingRecord mapping = record.getMappingRecord(); MappingRecord currentRecord = (MappingRecord) mapService.getMapping(MappingOrigin.Southbound, mapping.getEid()); mergedMappings.add(new MappingRecordItemBuilder().setMappingRecord(currentRecord).build()); - Set sourceRlocs = (Set) mapService.getData(MappingOrigin.Southbound, - mapping.getEid(), SubKeys.SRC_RLOCS); + Set sourceRlocs = (Set) mapService.getData( + MappingOrigin.Southbound, mapping.getEid(), SubKeys.SRC_RLOCS); if (sourceRlocs != null) { notifyRlocs.addAll(sourceRlocs); } } MapNotifyBuilderHelper.setFromMapRegisterAndMappingRecordItems(builder, mapRegister, mergedMappings); - rlocs = getTransportAddresses(notifyRlocs); + // send map-notify to merge group only when mapping record is changed + if (mappingUpdated) { + rlocs = getTransportAddresses(notifyRlocs); + } } else { MapNotifyBuilderHelper.setFromMapRegister(builder, mapRegister); } - if (authenticate) { - builder.setAuthenticationData(LispAuthenticationUtil.createAuthenticationData(builder.build(), - password)); + List mappings = builder.getMappingRecordItem(); + if (mappings != null && mappings.get(0) != null && mappings.get(0).getMappingRecord() != null && + mappings.get(0).getMappingRecord().getEid() != null) { + MappingAuthkey authkey = mapService.getAuthenticationKey(mappings.get(0).getMappingRecord().getEid()); + if (authkey != null) { + builder.setAuthenticationData(LispAuthenticationUtil.createAuthenticationData(builder.build(), + authkey.getKeyString())); + } } notifyHandler.handleMapNotify(builder.build(), rlocs); } } - private static List getTransportAddresses(Set addresses) { + private static List getTransportAddresses(Set addresses) { List rlocs = new ArrayList(); - for (IpAddress address : addresses) { + for (IpAddressBinary address : addresses) { TransportAddressBuilder tab = new TransportAddressBuilder(); tab.setIpAddress(address); tab.setPort(new PortNumber(LispMessage.PORT_NUM)); @@ -209,12 +206,6 @@ public class MapServer implements IMapServerAsync, OdlMappingserviceListener { } else if (!Objects.equals(oldMapping.getRecordTtl(), newMapping.getRecordTtl())) { LOG.trace("mappingChanged(): TTL"); return true; - } else if (!Arrays.equals(oldMapping.getXtrId(), newMapping.getXtrId())) { - LOG.trace("mappingChanged(): xTR-ID"); - return true; - } else if (!Arrays.equals(oldMapping.getSiteId(), newMapping.getSiteId())) { - LOG.trace("mappingChanged(): site-ID"); - return true; } else if (!Objects.equals(oldMapping.getMapVersion(), newMapping.getMapVersion())) { LOG.trace("mappingChanged(): mapping version"); return true; @@ -228,7 +219,7 @@ public class MapServer implements IMapServerAsync, OdlMappingserviceListener { // For SrcDst LCAF also send SMRs to Dst prefix if (eid.getAddress() instanceof SourceDestKey) { - Eid dstAddr = SourceDestKeyHelper.getDst(eid); + Eid dstAddr = SourceDestKeyHelper.getDstBinary(eid); Set dstSubs = getSubscribers(dstAddr); MappingRecord newRecord = new MappingRecordBuilder(record).setEid(dstAddr).build(); handleSmr(newRecord.getEid(), dstSubs, notifyHandler); @@ -241,10 +232,14 @@ public class MapServer implements IMapServerAsync, OdlMappingserviceListener { } MapRequestBuilder mrb = MapRequestUtil.prepareSMR(eid, LispAddressUtil.toRloc(getLocalAddress())); LOG.trace("Built SMR packet: " + mrb.build().toString()); - for (SubscriberRLOC subscriber : subscribers) { + // Using Iterator ensures that we don't get a ConcurrentModificationException when removing a SubscriberRLOC + // from a Set. + Iterator iterator = subscribers.iterator(); + while (iterator.hasNext()) { + SubscriberRLOC subscriber = iterator.next(); if (subscriber.timedOut()) { LOG.trace("Lazy removing expired subscriber entry " + subscriber.toString()); - subscribers.remove(subscriber); + iterator.remove(); } else { try { // The address stored in the SMR's EID record is used as Source EID in the SMR-invoked Map-Request.