import org.opendaylight.lispflowmapping.lisp.serializer.MapRequestSerializer;
import org.opendaylight.lispflowmapping.lisp.type.LispMessage;
import org.opendaylight.lispflowmapping.lisp.type.MappingData;
+import org.opendaylight.lispflowmapping.lisp.util.ByteUtil;
import org.opendaylight.lispflowmapping.lisp.util.LispAddressStringifier;
import org.opendaylight.lispflowmapping.lisp.util.LispAddressUtil;
import org.opendaylight.lispflowmapping.type.sbplugin.IConfigLispSouthboundPlugin;
import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MapReply;
import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MapRequest;
import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MappingKeepAlive;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MessageType;
import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.OdlLispProtoListener;
import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.RequestMapping;
import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.SiteId;
areWeReady();
mapService.setLookupPolicy(IMappingService.LookupPolicy.NB_FIRST);
mapService.setMappingMerge(false);
+ ConfigIni.getInstance().setSmrRetryCount(1);
locatorEid = LispAddressUtil.asIpv4Rloc("4.3.2.1");
socket = initSocket(socket, LispMessage.PORT_NUM);
}
@Test
- public void testNegativePrefix() throws UnknownHostException {
+ public void testNegativePrefix_gapIntersection() throws UnknownHostException {
insertMappings();
testGapIntersection();
+
+ insertMappings();
testMultipleMappings();
}
private void testRepeatedSmr() throws SocketTimeoutException, UnknownHostException {
cleanUP();
long timeout = ConfigIni.getInstance().getSmrTimeout();
+ ConfigIni.getInstance().setSmrRetryCount(5);
final InstanceIdType iid = new InstanceIdType(1L);
final Eid eid1 = LispAddressUtil.asIpv4Eid("1.1.1.1", 1L);
.setEid(eid1).setTimestamp(System.currentTimeMillis()).setRecordTtl(1440).build();
mapService.addMapping(MappingOrigin.Northbound, eid1, null, new MappingData(mapping1));
- sleepForMilliseconds((timeout * expectedSmrs1) - 1500);
+ sleepForMilliseconds((timeout * expectedSmrs1) - (timeout / 2));
final List<MapRequest> requests1 = processSmrPackets(reader1, subscriberSrcRloc1, expectedSmrs1);
final MapReply mapReply1 = lms.handleMapRequest(
new MapRequestBuilder(requests1.get(0))
public void mapRequestMapRegisterAndMapRequestTestTimeout() throws SocketTimeoutException {
cleanUP();
+ ConfigIni.getInstance().setSmrRetryCount(0);
Eid eid = LispAddressUtil.asIpv4PrefixBinaryEid("1.2.3.4/32");
mapService.addAuthenticationKey(eid, NULL_AUTH_KEY);
sleepForSeconds(1);
}
private MapReply receiveMapReply() throws SocketTimeoutException {
- return MapReplySerializer.getInstance().deserialize(ByteBuffer.wrap(receivePacket().getData()));
+ return receiveMapReply(socket, 1000);
}
private MapRequest receiveMapRequest(DatagramSocket datagramSocket) throws SocketTimeoutException {
}
}
+ private MapReply receiveMapReply(DatagramSocket receivedSocket, int timeout) throws SocketTimeoutException {
+ DatagramPacket packet;
+ try {
+ while (true) {
+ packet = receivePacket(receivedSocket, timeout);
+ final ByteBuffer buff = ByteBuffer.wrap(packet.getData());
+ final int type = ByteUtil.getUnsignedByte(buff, LispMessage.Pos.TYPE) >> 4;
+ final Object lispType = MessageType.forValue(type);
+
+ if (lispType == MessageType.MapReply) {
+ return MapReplySerializer.getInstance().deserialize(buff);
+ }
+ }
+ } catch (SocketTimeoutException ste) {
+ throw ste;
+ }
+ }
+
private void sleepForSeconds(int seconds) {
try {
Thread.sleep(seconds*1000);
* List of xTR-IDs that need to be removed
*/
void removeXtrIdMappings(Eid key, List<XtrId> xtrIds);
+
+ /**
+ * Returns the parent prefix for given key.
+ *
+ * @param key
+ * The key which parent is to be returned.
+ * @return The parent perfix of a specific key.
+ */
+ Eid getParentPrefix(Eid key);
}
*/
void removeData(MappingOrigin origin, Eid key, String subKey);
+ /**
+ * Returns the parent prefix for given key.
+ *
+ * @param key
+ * The key which parent is to be returned.
+ * @return The parent perfix of a specific key.
+ */
+ Eid getParentPrefix(Eid key);
+
/**
* Sets iterateMask. If set to true, longest prefix matching for IP keys is used.
*
*/
void removeData(MappingOrigin origin, Eid key, String subKey);
+ /**
+ * Returns the parent prefix for given key.
+ *
+ * @param key
+ * The key which parent is to be returned.
+ * @return The parent perfix of a specific key.
+ */
+ Eid getParentPrefix(Eid key);
+
/**
* Configures Mapping Service mapping merge option. If set to false, mappings with the same key are overwritten,
* otherwise, mappings with the same key but from different xTR-IDs are all stored.
mappingSystem.removeData(origin, key, subKey);
}
+ @Override
+ public Eid getParentPrefix(Eid key) {
+ return mappingSystem.getParentPrefix(key);
+ }
+
@Override
public String printMappings() {
return mappingSystem.printMappings();
tableMap.get(origin).removeData(key, subKey);
}
+ @Override
+ public Eid getParentPrefix(Eid key) {
+ return smc.getParentPrefix(key);
+ }
+
/**
* Restore all mappings and keys from mdsal datastore.
for (EidItem eidRecord : request.getEidItem()) {
MappingData mappingData = mapService.getMapping(srcEid, eidRecord.getEid());
MappingRecord mapping;
- if (mappingData != null) {
+ if (mappingData == null) {
+ mapping = getNegativeMapping(eidRecord.getEid());
+ mapService.addMapping(MappingOrigin.Southbound, mapping.getEid(), null, new MappingData(mapping));
+ } else {
mapping = mappingData.getRecord();
- if (itrRlocs != null && itrRlocs.size() != 0) {
- if (subscriptionService) {
- final Rloc resolvedRloc = resolveRloc(itrRlocs, sourceRloc);
- updateSubscribers(resolvedRloc, eidRecord.getEid(), mapping.getEid(),
- srcEid, mapping.getRecordTtl());
- }
- mapping = updateLocators(mapping, itrRlocs);
+ }
+
+ if (itrRlocs != null && itrRlocs.size() != 0) {
+ if (subscriptionService) {
+ final Rloc resolvedRloc = resolveRloc(itrRlocs, sourceRloc);
+ updateSubscribers(resolvedRloc, eidRecord.getEid(), mapping.getEid(),
+ srcEid, mapping.getRecordTtl());
}
- mapping = fixIfNotSDRequest(mapping, eidRecord.getEid());
- } else {
- mapping = getNegativeMapping(eidRecord.getEid());
+ mapping = updateLocators(mapping, itrRlocs);
}
+ mapping = fixIfNotSDRequest(mapping, eidRecord.getEid());
replyBuilder.getMappingRecordItem().add(new MappingRecordItemBuilder().setMappingRecord(mapping).build());
}
requestHandler.handleMapReply(replyBuilder.build());
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;
import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.list.MappingRecordItemBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.maprequestnotification.MapRequestBuilder;
for (MappingRecordItem record : mapRegister.getMappingRecordItem()) {
MappingRecord mapping = record.getMappingRecord();
+ Eid eid = mapping.getEid();
MappingData mappingData = new MappingData(mapping, System.currentTimeMillis());
mappingData.setMergeEnabled(merge);
mappingData.setXtrId(mapRegister.getXtrId());
- oldMapping = getMappingRecord(mapService.getMapping(MappingOrigin.Southbound, mapping.getEid()));
- mapService.addMapping(MappingOrigin.Southbound, mapping.getEid(), getSiteId(mapRegister), mappingData);
+ oldMapping = getMappingRecord(mapService.getMapping(MappingOrigin.Southbound, eid));
+ mapService.addMapping(MappingOrigin.Southbound, eid, getSiteId(mapRegister), mappingData);
if (subscriptionService) {
MappingRecord newMapping = merge
- ? getMappingRecord(mapService.getMapping(MappingOrigin.Southbound, mapping.getEid())) : mapping;
+ ? getMappingRecord(mapService.getMapping(MappingOrigin.Southbound, eid)) : mapping;
if (mappingChanged(oldMapping, newMapping)) {
if (LOG.isDebugEnabled()) {
LOG.debug("Mapping update occured for {} SMRs will be sent for its subscribers.",
LispAddressStringifier.getString(mapping.getEid()));
}
- subscribers = getSubscribers(mapping.getEid());
- sendSmrs(mapping, subscribers);
+ subscribers = getSubscribers(eid);
+ if (oldMapping != null && !oldMapping.getEid().equals(eid)) {
+ subscribers = addParentSubscribers(eid, subscribers);
+ }
+ sendSmrs(eid, subscribers);
mappingUpdated = true;
}
}
@Override
public void onMappingChanged(MappingChanged notification) {
if (subscriptionService) {
+ Eid eid = notification.getMappingRecord().getEid();
if (mapService.isMaster()) {
- sendSmrs(notification.getMappingRecord(), getSubscribers(notification.getMappingRecord().getEid()));
+ sendSmrs(eid, getSubscribers(eid));
}
if (notification.getChangeType().equals(MappingChange.Removed)) {
- removeSubscribers(notification.getMappingRecord().getEid());
+ removeSubscribers(eid);
}
}
}
return false;
}
- private void sendSmrs(MappingRecord record, Set<SubscriberRLOC> subscribers) {
- Eid eid = record.getEid();
+ private void sendSmrs(Eid eid, Set<SubscriberRLOC> subscribers) {
handleSmr(eid, subscribers);
// For SrcDst LCAF also send SMRs to Dst prefix
if (eid.getAddress() instanceof SourceDestKey) {
Eid dstAddr = SourceDestKeyHelper.getDstBinary(eid);
Set<SubscriberRLOC> dstSubs = getSubscribers(dstAddr);
- MappingRecord newRecord = new MappingRecordBuilder(record).setEid(dstAddr).build();
- handleSmr(newRecord.getEid(), dstSubs);
+ handleSmr(dstAddr, dstSubs);
}
}
return (Set<SubscriberRLOC>) mapService.getData(MappingOrigin.Southbound, address, SubKeys.SUBSCRIBERS);
}
+ private Set<SubscriberRLOC> addParentSubscribers(Eid eid, Set<SubscriberRLOC> subscribers) {
+ Eid parentPrefix = mapService.getParentPrefix(eid);
+ if (parentPrefix == null) {
+ return subscribers;
+ }
+
+ Set<SubscriberRLOC> parentSubscribers = getSubscribers(parentPrefix);
+ if (parentSubscribers != null) {
+ if (subscribers != null) {
+ subscribers.addAll(parentSubscribers);
+ } else {
+ subscribers = parentSubscribers;
+ }
+ }
+ return subscribers;
+ }
+
private void removeSubscribers(Eid address) {
mapService.removeData(MappingOrigin.Southbound, address, SubKeys.SUBSCRIBERS);
}
mrb.setEidItem(new ArrayList<EidItem>());
mrb.getEidItem().add(new EidItemBuilder().setEid(subscriber.getSrcEid()).build());
notifyHandler.handleSMR(mrb.build(), subscriber.getSrcRloc());
- LOG.trace("{}. attempt to send SMR for MapRequest " + subscriber.getSrcEid(), executionCount);
+ LOG.trace("{}. attempt to send SMR for MapRequest " + mrb.getSourceEid().getEid()
+ + " to subscriber " + subscriber.getSrcRloc(), executionCount);
} else {
LOG.trace("Cancelling execution of a SMR Map-Request after {} failed attempts.",
executionCount - 1);
private static final String IPV4_SOURCE_STRING_4 = "127.0.0.4";
private static final String IPV4_SOURCE_STRING_5 = "127.0.0.5";
private static final String IPV4_SOURCE_STRING_6 = "127.0.0.6";
- private static final String IPV4_PREFIX = "/24";
+ private static final String IPV4_PREFIX_1 = "/24";
+ private static final String IPV4_PREFIX_2 = "/16";
private static final int MASK = 24;
private static final int VNI = 10;
- private static final Eid IPV4_EID_1 = LispAddressUtil.asIpv4PrefixEid(IPV4_STRING_1 + IPV4_PREFIX);
- private static final Eid IPV4_EID_2 = LispAddressUtil.asIpv4PrefixEid(IPV4_STRING_2 + IPV4_PREFIX);
+ private static final Eid IPV4_EID_1 = LispAddressUtil.asIpv4Eid(IPV4_STRING_1);
+ private static final Eid IPV4_EID_2 = LispAddressUtil.asIpv4Eid(IPV4_STRING_2);
+ private static final Eid IPV4_PREFIX_EID_1 = LispAddressUtil.asIpv4PrefixBinaryEid(IPV4_STRING_1 + IPV4_PREFIX_1);
+ private static final Eid IPV4_PREFIX_EID_2 = LispAddressUtil.asIpv4PrefixBinaryEid(IPV4_STRING_1 + IPV4_PREFIX_2);
private static final Eid IPV4_SOURCE_EID_1 = LispAddressUtil.asIpv4Eid(IPV4_SOURCE_STRING_1);
private static final Eid IPV4_SOURCE_EID_2 = LispAddressUtil.asIpv4Eid(IPV4_SOURCE_STRING_2);
private static final Eid IPV4_SOURCE_EID_3 = LispAddressUtil.asIpv4Eid(IPV4_SOURCE_STRING_3);
Mockito.verify(notifyHandler).handleMapNotify(mapNotifyBuilder.setAuthenticationData(null).build(), null);
}
+ @Test
+ public void handleMapRegisterTest_findNegativeSubscribers() throws NoSuchFieldException, IllegalAccessException {
+ setConfigIniMappingMergeField(true);
+
+ mapRegister.getMappingRecordItem().clear();
+ mapRegister.getMappingRecordItem().add(getDefaultMappingRecordItemBuilder(IPV4_PREFIX_EID_1).build());
+
+ final MappingRecordBuilder mappingRecordBuilder_1 = getDefaultMappingRecordBuilder()
+ // apply the change
+ .setEid(IPV4_PREFIX_EID_2);
+ final MappingRecordBuilder mappingRecordBuilder_2 = getDefaultMappingRecordBuilder();
+ final Eid maskedEid1 = LispAddressUtil.asIpv4Eid("1.2.0.0");
+
+ final SubscriberRLOC subscriber1 = Mockito.mock(SubscriberRLOC.class);
+ Mockito.when(subscriber1.timedOut()).thenReturn(true);
+ Mockito.when(subscriber1.toString()).thenReturn("sub1");
+
+ final Set<SubscriberRLOC> set1 = Sets.newHashSet(subscriber1);
+
+ Mockito.when(mapService.getAuthenticationKey(IPV4_PREFIX_EID_1)).thenReturn(MAPPING_AUTHKEY);
+ Mockito.when(mapService.getData(MappingOrigin.Southbound, IPV4_PREFIX_EID_1, SubKeys.SRC_RLOCS))
+ .thenReturn(DEFAULT_IP_ADDRESS_SET);
+
+ Mockito.when(mapService.getParentPrefix(IPV4_PREFIX_EID_1)).thenReturn(maskedEid1);
+ Mockito.when(mapService.getData(MappingOrigin.Southbound, IPV4_PREFIX_EID_1, SubKeys.SUBSCRIBERS))
+ .thenReturn(null);
+ Mockito.when(mapService.getData(MappingOrigin.Southbound, maskedEid1, SubKeys.SUBSCRIBERS)).thenReturn(set1);
+
+ Mockito.when(mapService.getMapping(MappingOrigin.Southbound, IPV4_PREFIX_EID_1))
+ .thenReturn(getDefaultMappingData(mappingRecordBuilder_1.build()))
+ .thenReturn(getDefaultMappingData(mappingRecordBuilder_2.build()))
+ .thenReturn(null);
+
+ mapServer.handleMapRegister(mapRegister);
+ Mockito.verify(subscriber1).timedOut();
+ }
+
@Test
public void handleMapRegisterTest_verifyTransportAddresses() throws NoSuchFieldException, IllegalAccessException {
setConfigIniMappingMergeField(true);
}
private static MappingRecordItemBuilder getDefaultMappingRecordItemBuilder() {
+ return getDefaultMappingRecordItemBuilder(IPV4_EID_1);
+ }
+
+ private static MappingRecordItemBuilder getDefaultMappingRecordItemBuilder(Eid eid) {
return new MappingRecordItemBuilder()
.setMappingRecordItemId("mapping-record-item-id")
.setKey(new MappingRecordItemKey("mapping-record-item-key"))
- .setMappingRecord(getDefaultMappingRecordBuilder().build());
+ .setMappingRecord(getDefaultMappingRecordBuilder(eid).build());
}
private static MappingRecordBuilder getDefaultMappingRecordBuilder() {
+ return getDefaultMappingRecordBuilder(IPV4_EID_1);
+ }
+
+ private static MappingRecordBuilder getDefaultMappingRecordBuilder(Eid eid) {
return new MappingRecordBuilder()
.setAction(MappingRecord.Action.NoAction)
.setAuthoritative(false)
.setLocatorRecord(new ArrayList<>())
.setMapVersion((short) 0)
.setRecordTtl(60)
- .setEid(IPV4_EID_1);
+ .setEid(eid);
}
private static MapNotifyBuilder getDefaultMapNotifyBuilder(MapRegister mapRegister) {
return table.getWidestNegativePrefix(MaskUtil.normalize(eid));
}
+ @Override
+ public Eid getParentPrefix(Eid eid) {
+ Eid key = MaskUtil.normalize(eid);
+ ILispDAO table = getVniTable(key);
+ if (table == null) {
+ return null;
+ }
+ return table.getParentPrefix(key);
+ }
+
@Override
public void removeMapping(Eid eid) {
Eid key = MaskUtil.normalize(eid);