import static org.opendaylight.lispflowmapping.integrationtest.MultiSiteScenarioUtil.SITE_A;
import static org.opendaylight.lispflowmapping.integrationtest.MultiSiteScenarioUtil.SITE_D5;
+import com.google.common.net.InetAddresses;
import java.nio.ByteBuffer;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
-import org.apache.commons.lang3.ArrayUtils;
import org.opendaylight.lispflowmapping.integrationtest.MultiSiteScenarioUtil.Site;
import org.opendaylight.lispflowmapping.interfaces.lisp.IFlowMapping;
import org.opendaylight.lispflowmapping.interfaces.mappingservice.IMappingService;
import org.opendaylight.lispflowmapping.lisp.serializer.MapRequestSerializer;
+import org.opendaylight.lispflowmapping.lisp.type.MappingData;
import org.opendaylight.lispflowmapping.lisp.util.LispAddressStringifier;
import org.opendaylight.lispflowmapping.lisp.util.LispAddressUtil;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
+import org.opendaylight.lispflowmapping.lisp.util.MaskUtil;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.InstanceIdType;
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.Ipv4;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.inet.binary.types.rev160303.Ipv4AddressBinary;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.binary.address.types.rev160504.augmented.lisp.address.address.Ipv4Binary;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.binary.address.types.rev160504.augmented.lisp.address.address.Ipv6Binary;
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.XtrId;
+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.locatorrecords.LocatorRecord;
import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.locatorrecords.LocatorRecordBuilder;
+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.authkey.container.MappingAuthkeyBuilder;
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.maprequestnotification.MapRequestBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.rloc.container.Rloc;
import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.MappingOrigin;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.mapping.authkey.container.MappingAuthkey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.mapping.authkey.container.MappingAuthkeyBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-
/**
* Contains methods for:
* - checking sites visibility (availability) - simulation of ping command
private final Boolean DEFAULT_LOCAL_LOCATOR = true;
private final Boolean DEFAULT_RLOC_PROBED = false;
private final Boolean DEFAULT_ROUTED = true;
+ private final byte[] DEFAULT_SITE_ID = new byte[]{0, 0, 0, 0, 0, 0, 0, 0};
private final MappingAuthkey NULL_AUTH_KEY = new MappingAuthkeyBuilder().setKeyType(0).build();
private final IMappingService mapService;
this.lms = lms;
}
- private Ipv4Address verifyIpv4Address(final LocatorRecord locatorRecord) {
+ private Ipv4AddressBinary verifyIpv4Address(final LocatorRecord locatorRecord) {
assertNotNull(locatorRecord);
final Rloc rloc = locatorRecord.getRloc();
assertNotNull(rloc);
final Address address = rloc.getAddress();
- assertTrue(address instanceof Ipv4);
- return ((Ipv4) address).getIpv4();
+ assertTrue(address instanceof Ipv4Binary);
+ return ((Ipv4Binary) address).getIpv4Binary();
}
private List<LocatorRecord> verifyLocatorRecordExists(final MappingRecord mappingRecord) {
return mappingRecord;
}
- private void emitMapRegisterMessage(final Site dstSite) {
+ private void emitMapRegisterMessage(final Site dstSite, final boolean merge) {
final MapRegisterBuilder mapRegisterBuilder = new MapRegisterBuilder();
+ mapRegisterBuilder.setXtrSiteIdPresent(true);
+ mapRegisterBuilder.setXtrId(dstSite.getXtrId());
+ mapRegisterBuilder.setSiteId(new SiteId(DEFAULT_SITE_ID));
+ mapRegisterBuilder.setMergeEnabled(merge);
final MappingRecordItemBuilder mappingRecordItemBuilder = new MappingRecordItemBuilder();
mappingRecordItemBuilder.setMappingRecordItemId(MAP_RECORD_A);
}
void setCommonAuthentication() {
- Eid eid = LispAddressUtil.toEid(new Ipv4Prefix("0.0.0.0/0"), SITE_A.getVNI());
+ Eid eid = LispAddressUtil.asIpv4PrefixBinaryEid("0.0.0.0/0", SITE_A.getVNI());
mapService.addAuthenticationKey(eid, NULL_AUTH_KEY);
- eid = LispAddressUtil.toEid(new Ipv4Prefix("0.0.0.0/0"), SITE_D5.getVNI());
+ eid = LispAddressUtil.asIpv4PrefixBinaryEid("0.0.0.0/0", SITE_D5.getVNI());
mapService.addAuthenticationKey(eid, NULL_AUTH_KEY);
sleepForSeconds(1);
}
private Eid toEid(final String destSiteEidPrefix, final InstanceIdType vniValue, final int mask) {
- return LispAddressUtil.toEid(new Ipv4Prefix(destSiteEidPrefix + "/" + mask), vniValue);
+ return LispAddressUtil.asIpv4PrefixBinaryEid(destSiteEidPrefix + "/" + mask, vniValue);
}
mapRequestBuilder.setSourceEid(new SourceEidBuilder().setEid(srcEid).build());
mapRequestBuilder.setEidItem(eidItem);
mapRequestBuilder.setItrRloc(prepareDummyItrRloc());
+ mapRequestBuilder.setSmrInvoked(false);
return lms.handleMapRequest(mapRequestBuilder.build());
}
+ /**
+ * This method expects a SMR Map-Request as input, which it will turn into a SMR-invoked Map-Request and use the
+ * LISP mapping service to send it
+ *
+ * @param mapRequest the SMR Map-Request
+ */
+ private void emitSMRInvokedMapRequestMessage(MapRequest mapRequest) {
+ if (mapRequest.getEidItem().isEmpty()) {
+ fail("Empty SMR received!");
+ }
+
+ Eid srcEid = addMaximumPrefixIfNecessary(mapRequest.getSourceEid().getEid());
+ final EidItemBuilder eidItemBuilder = new EidItemBuilder();
+ eidItemBuilder.setEid(srcEid);
+ eidItemBuilder.setEidItemId(LispAddressStringifier.getString(srcEid));
+ final List<EidItem> eidItem = Collections.singletonList(eidItemBuilder.build());
+
+ final MapRequestBuilder mapRequestBuilder = new MapRequestBuilder(mapRequest);
+ mapRequestBuilder.setSmr(false);
+ mapRequestBuilder.setSmrInvoked(true);
+ mapRequestBuilder.setItrRloc(prepareDummyItrRloc());
+ mapRequestBuilder.setEidItem(eidItem);
+ for (EidItem ei : mapRequest.getEidItem()) {
+ mapRequestBuilder.setSourceEid(new SourceEidBuilder().setEid(ei.getEid()).build());
+ LOG.debug("Sending SMR-invoked Map-Reqeust for EID {}, Source EID {}",
+ LispAddressStringifier.getString(srcEid),
+ LispAddressStringifier.getString(ei.getEid()));
+ lms.handleMapRequest(mapRequestBuilder.build());
+ }
+ }
+
+ /*
+ * Since the Source EID field from a Map-Request packet does not have a prefix length field, IPv4 and IPv6 addresses
+ * are serialized into Ipv4Binary and Ipv6Binary objects. However, when we want to use the addresses in a
+ * SMR-invoked Map-Request, we need to use an Ipv4PrefixBinary or Ipv6PrefixBinary object respectively, since that's
+ * what the EID item field would be deserialized into.
+ */
+ private static Eid addMaximumPrefixIfNecessary(Eid eid) {
+ Address address = eid.getAddress();
+ if (address instanceof Ipv4Binary) {
+ return LispAddressUtil.asIpv4PrefixBinaryEid(
+ eid, ((Ipv4Binary) address).getIpv4Binary().getValue(), MaskUtil.IPV4_MAX_MASK);
+ } else if (address instanceof Ipv6Binary) {
+ return LispAddressUtil.asIpv6PrefixBinaryEid(
+ eid, ((Ipv6Binary) address).getIpv6Binary().getValue(), MaskUtil.IPV6_MAX_MASK);
+ }
+ return eid;
+ }
+
private List<ItrRloc> prepareDummyItrRloc() {
List<ItrRloc> itrRlocs = new ArrayList<>();
final ItrRlocBuilder itrRlocBuilder = new ItrRlocBuilder();
}
void storeNorthMappingNegative(final Site dstSite, final MappingRecord.Action action) {
- final Ipv4Prefix ipv4Prefix = new Ipv4Prefix(dstSite.getEidPrefix() + "/" + DEFAULT_NETWORK_MASK);
- final Eid eidAsIpv4Prefix = LispAddressUtil.toEid(ipv4Prefix, dstSite.getVNI());
+ final Eid eidAsIpv4Prefix = LispAddressUtil.asIpv4PrefixBinaryEid(
+ dstSite.getEidPrefix() + "/" + DEFAULT_NETWORK_MASK, dstSite.getVNI());
final MappingRecordBuilder mrbNegative = prepareMappingRecord(EidType.EID_WITH_PREFIX, null, dstSite);
mrbNegative.setEid(eidAsIpv4Prefix);
mrbNegative.setAction(action);
- mapService.addMapping(MappingOrigin.Northbound, eidAsIpv4Prefix, dstSite.getSiteId(), mrbNegative.build());
+ mapService.addMapping(MappingOrigin.Northbound, eidAsIpv4Prefix, new SiteId(DEFAULT_SITE_ID),
+ new MappingData(mrbNegative.build()));
}
void deleteNorthMappingNegative(final Site dstSite) {
- final Ipv4Prefix ipv4Prefix = new Ipv4Prefix(dstSite.getEidPrefix() + "/" + DEFAULT_NETWORK_MASK);
- final Eid eidAsIpv4Prefix = LispAddressUtil.toEid(ipv4Prefix, dstSite.getVNI());
+ final Eid eidAsIpv4Prefix = LispAddressUtil.asIpv4PrefixBinaryEid(
+ dstSite.getEidPrefix() + "/" + DEFAULT_NETWORK_MASK, dstSite.getVNI());
mapService.removeMapping(MappingOrigin.Northbound, eidAsIpv4Prefix);
}
void storeNorthMappingSrcDst(final Site srcSite, final Site ... dstSite) {
final MappingRecordBuilder mrb = prepareMappingRecord(EidType.EID_SRC_DST, srcSite,
dstSite);
- mapService.addMapping(MappingOrigin.Northbound, mrb.getEid(), dstSite[0].getSiteId(), mrb.build());
+ mapService.addMapping(MappingOrigin.Northbound, mrb.getEid(), new SiteId(DEFAULT_SITE_ID),
+ new MappingData(mrb.build()));
}
void storeNorthMappingIpPrefix(final Site... dstSite) {
final MappingRecordBuilder mrb = prepareMappingRecord(EidType.EID_WITH_PREFIX, null, dstSite);
- mapService.addMapping(MappingOrigin.Northbound, mrb.getEid(), dstSite[0].getSiteId(), mrb.build());
+ mapService.addMapping(MappingOrigin.Northbound, mrb.getEid(), new SiteId(DEFAULT_SITE_ID),
+ new MappingData(mrb.build()));
}
- private void storeDestinationSiteMappingViaSouthbound(final Site dstSite) {
- emitMapRegisterMessage(dstSite);
+ private void storeDestinationSiteMappingViaSouthbound(final Site dstSite, final boolean merge) {
+ emitMapRegisterMessage(dstSite, merge);
}
private MappingRecordBuilder prepareMappingRecordGeneral(final EidType eidType,
final Site srcSite, final Site dstSite) {
final MappingRecordBuilder mrb = provideCommonMapRecordBuilder();
- mrb.setXtrId(new XtrId(ArrayUtils.addAll(dstSite.getSiteId().getValue(), dstSite.getSiteId().getValue())));
+ mrb.setXtrId(dstSite.getXtrId());
Eid eid = null;
if (EidType.EID_SRC_DST.equals(eidType)) {
if (!dstSites[0].isForDeletion) {
for (Site dstSite : dstSites) {
if (dstSite.getRloc() != null) {
- locatorRecords.add(provideLocatorRecord(LispAddressUtil.toRloc(new Ipv4Address(dstSite.getRloc())),
+ locatorRecords.add(provideLocatorRecord(LispAddressUtil.asIpv4Rloc(dstSite.getRloc()),
dstSite.getRloc(), dstSite.getWeight(), dstSite.getPriority()));
}
}
}
void deleteSouthboundMappings(final Site dstSite) {
- emitMapRegisterMessage(dstSite);
+ emitMapRegisterMessage(dstSite, false);
}
- void storeSouthboundMappings(final Site ... sites) {
+ void storeSouthboundMappings(final boolean merge, final Site ... sites) {
for (Site site : sites) {
- storeDestinationSiteMappingViaSouthbound(site);
+ storeDestinationSiteMappingViaSouthbound(site, merge);
}
}
boolean expectedTargetFound = false;
for (LocatorRecord locatorRecord : locatorRecords) {
if (expectedTargetSite.getRloc().equals(rlocToString(locatorRecord))) {
- final Ipv4Address ipv4AddressSrcDst = verifyIpv4Address(locatorRecord);
- final boolean isRlocSrcDstEqual = ipv4AddressSrcDst.getValue().equals(expectedTargetSite.getRloc());
+ final byte[] ipv4AddressSrcDst = verifyIpv4Address(locatorRecord).getValue();
+ final byte[] rloc = InetAddresses.forString((expectedTargetSite.getRloc())).getAddress();
+ final boolean isRlocSrcDstEqual = Arrays.equals(ipv4AddressSrcDst, rloc);
if (isPossibleAssertPingResultImmediately(expectedPingWorks, isRlocSrcDstEqual, "Unexpected RLOC." +
- "Expected value " + dstSite.getRloc() + ". Real value " + ipv4AddressSrcDst.getValue() +
+ "Expected value " + rloc + ". Real value " + ipv4AddressSrcDst +
".")) {
return true;
}
boolean expectedPingWorks, final Site ... additionalSitesFromMapping) {
final MapReply mapReplyFromSrcToDst = emitMapRequestMessage(srcSite.getHost(srcHostIndex), dstSite.getHost
(dstHostIndex), dstSite.getVNI());
- if (checkActionAndRloc(dstSite, expectedPingWorks, mapReplyFromSrcToDst,
- additionalSitesFromMapping)) {
+ if (checkActionAndRloc(dstSite, expectedPingWorks, mapReplyFromSrcToDst, additionalSitesFromMapping)) {
return;
}
private List<MapRequest> translateBuffersToMapRequest(byte[][] buffers) {
final List<MapRequest> mapRequests = new ArrayList<>();
for (byte[] buffer : buffers) {
- final MapRequest mapRequest = MapRequestSerializer.getInstance().deserialize(ByteBuffer.wrap(buffer));
+ if (isBufferEmpty(buffer)) {
+ LOG.error("Empty buffer while translating Map-Request");
+ continue;
+ }
+ final MapRequest mapRequest = MapRequestSerializer.getInstance().deserialize(ByteBuffer.wrap(buffer), null);
assertNotNull(mapRequest);
mapRequests.add(mapRequest);
}
private Set<Eid> prepareExpectedEid(final String ... hosts) {
final Set<Eid> eids = new HashSet<>();
for (String host : hosts) {
- eids.add(LispAddressUtil.asIpv4PrefixEid(host + "/" + IP_MASK, new InstanceIdType(MultiSiteScenarioUtil
- .VNI2)));
+ eids.add(LispAddressUtil.asIpv4PrefixBinaryEid(host + "/" + IP_MASK,
+ new InstanceIdType(MultiSiteScenarioUtil.VNI2)));
}
return eids;
}
}
void checkSMR(final SocketReader socketReader, final String site, final String ... hosts) {
- List<MapRequest> mapRequests = translateBuffersToMapRequest(socketReader.getBuffers(hosts.length));
+ LOG.debug("\n" + mapService.prettyPrintMappings());
+ byte[][] buffers = socketReader.getBuffers(hosts.length);
+ if (areBuffersEmpty(buffers)) {
+ fail("No SMR received!");
+ }
+ List<MapRequest> mapRequests = translateBuffersToMapRequest(buffers);
+ if (hosts.length != mapRequests.size()) {
+ LOG.error("Expected {} SMRs, received {}", hosts.length, mapRequests.size());
+ fail("Unexpected number of SMRs received");
+ }
final Set<Eid> eids = prepareExpectedEid(hosts);
final SourceEid expectedSourceEid = prepareSourceEid(site);
for(MapRequest mapRequest : mapRequests) {
+ LOG.trace("Map-Request: {}", mapRequest);
assertTrue(mapRequest.isSmr());
final SourceEid receivedSourceEid = mapRequest.getSourceEid();
assertEquals(expectedSourceEid, receivedSourceEid);
final List<EidItem> currentEidItems = mapRequest.getEidItem();
assertNotNull(currentEidItems);
assertTrue(SMRContainsExpectedEid(eids, currentEidItems));
+ emitSMRInvokedMapRequestMessage(mapRequest);
}
//all expected eids should be after looping via mapRequests matched.
assertTrue("Expected eids wasn't/weren't found " + eids, eids.isEmpty());
for (EidItem eidItem : currentEidItems) {
//if eid from map request is matched then it is removed from set of expected eids
if (!eids.remove(eidItem.getEid())) {
- fail("SMR contained " + eidItem.getEid() + " which wasn't expected.");
+ fail("SMR contained EID `" + LispAddressStringifier.getString(eidItem.getEid())
+ + "' which wasn't expected.");
}
}
return true;
}
+ private static boolean isBufferEmpty(byte[] buffer) {
+ for (byte b : buffer) {
+ if (b != 0) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ protected static boolean areBuffersEmpty(byte[][] buffers) {
+ for (byte[] buffer : buffers) {
+ if (!isBufferEmpty(buffer)) {
+ return false;
+ }
+ }
+ return true;
+ }
}