Bug 8112: IT: send SMR-invoked Map-Request on SMR
[lispflowmapping.git] / integrationtest / src / test / java / org / opendaylight / lispflowmapping / integrationtest / MultiSiteScenario.java
index a78d72a665d37949106526b0809bb678e081f300..6b6ddbd0badfa8a8fddc27b6433e50a4c4c78ec9 100644 (file)
@@ -30,10 +30,12 @@ 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.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.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.SiteId;
@@ -169,6 +171,55 @@ class MultiSiteScenario {
         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();
@@ -443,6 +494,10 @@ class MultiSiteScenario {
     private List<MapRequest> translateBuffersToMapRequest(byte[][] buffers) {
         final List<MapRequest> mapRequests = new ArrayList<>();
         for (byte[] buffer : buffers) {
+            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);
@@ -472,15 +527,21 @@ class MultiSiteScenario {
             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());
@@ -490,7 +551,17 @@ 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;
@@ -498,10 +569,8 @@ class MultiSiteScenario {
 
     protected static boolean areBuffersEmpty(byte[][] buffers) {
         for (byte[] buffer : buffers) {
-            for (byte b : buffer) {
-                if (b != 0) {
-                    return false;
-                }
+            if (!isBufferEmpty(buffer)) {
+                return false;
             }
         }
         return true;