X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=integrationtest%2Fsrc%2Ftest%2Fjava%2Forg%2Fopendaylight%2Flispflowmapping%2Fintegrationtest%2FMultiSiteScenario.java;h=6b6ddbd0badfa8a8fddc27b6433e50a4c4c78ec9;hb=refs%2Fchanges%2F86%2F54186%2F8;hp=42097f6937e0b6510dbe951e899c018cb60cd912;hpb=0c166c2c28b82adb36762cfa970b0d6a46ab6f82;p=lispflowmapping.git diff --git a/integrationtest/src/test/java/org/opendaylight/lispflowmapping/integrationtest/MultiSiteScenario.java b/integrationtest/src/test/java/org/opendaylight/lispflowmapping/integrationtest/MultiSiteScenario.java index 42097f693..6b6ddbd0b 100644 --- a/integrationtest/src/test/java/org/opendaylight/lispflowmapping/integrationtest/MultiSiteScenario.java +++ b/integrationtest/src/test/java/org/opendaylight/lispflowmapping/integrationtest/MultiSiteScenario.java @@ -15,32 +15,37 @@ import static org.opendaylight.lispflowmapping.integrationtest.MappingServiceInt 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; @@ -53,12 +58,9 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.ma 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 @@ -78,6 +80,7 @@ class MultiSiteScenario { 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; @@ -94,13 +97,13 @@ class MultiSiteScenario { 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 verifyLocatorRecordExists(final MappingRecord mappingRecord) { @@ -121,8 +124,12 @@ class MultiSiteScenario { 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); @@ -134,16 +141,16 @@ class MultiSiteScenario { } 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); } @@ -160,9 +167,59 @@ class MultiSiteScenario { 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 = 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 prepareDummyItrRloc() { List itrRlocs = new ArrayList<>(); final ItrRlocBuilder itrRlocBuilder = new ItrRlocBuilder(); @@ -173,19 +230,20 @@ class MultiSiteScenario { } 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); } @@ -193,22 +251,24 @@ class MultiSiteScenario { 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)) { @@ -231,7 +291,7 @@ class MultiSiteScenario { 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())); } } @@ -287,13 +347,13 @@ class MultiSiteScenario { } 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); } } @@ -336,10 +396,11 @@ class MultiSiteScenario { 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; } @@ -390,8 +451,7 @@ class MultiSiteScenario { 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; } @@ -434,7 +494,11 @@ class MultiSiteScenario { private List translateBuffersToMapRequest(byte[][] buffers) { final List 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); } @@ -444,8 +508,8 @@ class MultiSiteScenario { private Set prepareExpectedEid(final String ... hosts) { final Set 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; } @@ -457,16 +521,27 @@ class MultiSiteScenario { } void checkSMR(final SocketReader socketReader, final String site, final String ... hosts) { - List 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 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 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 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()); @@ -476,10 +551,28 @@ class MultiSiteScenario { 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; + } }