[ONOS-5267] Initial implementation of MapResolver
Change-Id: I1438b0cc71b8fcb88064830d890ffc38ff9abd42
diff --git a/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispChannelHandler.java b/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispChannelHandler.java
index 6c723a6..d1ad800 100644
--- a/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispChannelHandler.java
+++ b/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispChannelHandler.java
@@ -24,7 +24,6 @@
import org.onosproject.lisp.msg.protocols.LispMapNotify;
import org.onosproject.lisp.msg.protocols.LispMapRegister;
import org.onosproject.lisp.msg.protocols.LispMapRequest;
-import org.onosproject.lisp.msg.protocols.LispMapReply;
import org.onosproject.lisp.msg.protocols.LispMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -42,7 +41,16 @@
// first we need to check whether this is an ECM
if (msg instanceof LispEncapsulatedControl) {
- msg = extractMapRequest((LispEncapsulatedControl) msg);
+ LispMessage innerMsg = extractLispMessage((LispEncapsulatedControl) msg);
+ if (innerMsg instanceof LispMapRequest) {
+ LispMapResolver mapResolver = new LispMapResolver();
+ LispMessage lispMessage = mapResolver.processMapRequest((LispEncapsulatedControl) msg);
+
+ // try to remove the received map-request message from buffer
+ ReferenceCountUtil.release(msg);
+
+ ctx.writeAndFlush(lispMessage);
+ }
}
if (msg instanceof LispMapRegister) {
@@ -54,14 +62,6 @@
ctx.writeAndFlush(mapNotify);
}
-
- if (msg instanceof LispMapRequest) {
- LispMapResolver mapResolver = new LispMapResolver();
- LispMapReply mapReply =
- (LispMapReply) mapResolver.processMapRequest((LispMapRequest) msg);
-
- // TODO: serialize mapReply message and write to channel
- }
}
@Override
@@ -96,7 +96,9 @@
* @param ecm Encapsulated Control Message
* @return extracted LISP message
*/
- private LispMessage extractMapRequest(LispEncapsulatedControl ecm) {
- return ecm.getControlMessage();
+ private LispMessage extractLispMessage(LispEncapsulatedControl ecm) {
+ LispMessage message = ecm.getControlMessage();
+ message.configSender(ecm.getSender());
+ return message;
}
}
diff --git a/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispEidRlocMap.java b/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispEidRlocMap.java
index d85ff97..0593366 100644
--- a/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispEidRlocMap.java
+++ b/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispEidRlocMap.java
@@ -15,11 +15,14 @@
*/
package org.onosproject.lisp.ctl;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.onosproject.lisp.msg.protocols.LispEidRecord;
import org.onosproject.lisp.msg.protocols.LispMapRecord;
import org.onosproject.lisp.msg.types.LispAfiAddress;
+import java.util.List;
import java.util.Optional;
import java.util.concurrent.ConcurrentMap;
@@ -69,6 +72,23 @@
}
/**
+ * Obtains a collection of EID-RLOC mapping records with given EID records.
+ *
+ * @param eids endpoint identifier records
+ * @return a collection of EID-RLOC mapping records
+ */
+ public List<LispMapRecord> getMapRecordByEidRecords(List<LispEidRecord> eids) {
+ List<LispMapRecord> mapRecords = Lists.newArrayList();
+ eids.forEach(eidRecord -> {
+ LispMapRecord mapRecord = getMapRecordByEidRecord(eidRecord);
+ if (mapRecord != null) {
+ mapRecords.add(mapRecord);
+ }
+ });
+ return ImmutableList.copyOf(mapRecords);
+ }
+
+ /**
* Obtains an EID-RLOC mapping record with given EID address.
*
* @param address endpoint identifier address
diff --git a/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispMapResolver.java b/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispMapResolver.java
index 9f6ab35..5661681 100644
--- a/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispMapResolver.java
+++ b/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispMapResolver.java
@@ -15,8 +15,19 @@
*/
package org.onosproject.lisp.ctl;
+import org.onosproject.lisp.msg.protocols.LispEncapsulatedControl;
+import org.onosproject.lisp.msg.protocols.LispMapRecord;
import org.onosproject.lisp.msg.protocols.LispMapReply;
+import org.onosproject.lisp.msg.protocols.LispMapRequest;
+import org.onosproject.lisp.msg.protocols.DefaultLispMapReply.DefaultReplyBuilder;
+
import org.onosproject.lisp.msg.protocols.LispMessage;
+import org.onosproject.lisp.msg.types.LispIpAddress;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.net.InetSocketAddress;
+import java.util.List;
/**
* LISP map resolver class.
@@ -24,8 +35,54 @@
*/
public class LispMapResolver {
- public LispMapReply processMapRequest(LispMessage message) {
- // TODO: need to implement map-request message processing logic
- return null;
+ private static final Logger log = LoggerFactory.getLogger(LispMapResolver.class);
+
+ private LispEidRlocMap eidRlocMap;
+
+ LispMapResolver() {
+ eidRlocMap = LispEidRlocMap.getInstance();
+ }
+
+ /**
+ * Handles encapsulated control message and replies with map-reply message.
+ *
+ * @param message encapsulated control message
+ * @return map-reply message
+ */
+ public LispMessage processMapRequest(LispMessage message) {
+
+ LispEncapsulatedControl ecm = (LispEncapsulatedControl) message;
+ LispMapRequest request = (LispMapRequest) ecm.getControlMessage();
+
+ // TODO: for now we always generate map-notify message and send to ITR
+ // no matter proxy bit is set or not
+
+ // build map-reply message
+ LispMapReply.ReplyBuilder replyBuilder = new DefaultReplyBuilder();
+ replyBuilder.withNonce(request.getNonce());
+ replyBuilder.withIsEtr(false);
+ replyBuilder.withIsSecurity(false);
+ replyBuilder.withIsProbe(request.isProbe());
+
+ List<LispMapRecord> mapRecords = eidRlocMap.getMapRecordByEidRecords(request.getEids());
+
+ if (mapRecords.size() == 0) {
+ log.warn("Map information is not found.");
+ } else {
+ replyBuilder.withMapRecords(mapRecords);
+ }
+
+ LispMapReply reply = replyBuilder.build();
+
+ if (request.getItrRlocs() != null && request.getItrRlocs().size() > 0) {
+ LispIpAddress itr = (LispIpAddress) request.getItrRlocs().get(0);
+ InetSocketAddress address = new InetSocketAddress(itr.getAddress().toInetAddress(),
+ ecm.innerUdp().getSourcePort());
+ reply.configSender(address);
+ } else {
+ log.warn("No ITR RLOC is found, cannot respond back to ITR.");
+ }
+
+ return reply;
}
}
diff --git a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/LispEidRecord.java b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/LispEidRecord.java
index e4ea7db..d933783 100644
--- a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/LispEidRecord.java
+++ b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/LispEidRecord.java
@@ -16,11 +16,13 @@
package org.onosproject.lisp.msg.protocols;
import io.netty.buffer.ByteBuf;
+import com.google.common.base.Objects;
import org.onosproject.lisp.msg.exceptions.LispParseError;
import org.onosproject.lisp.msg.exceptions.LispReaderException;
import org.onosproject.lisp.msg.exceptions.LispWriterException;
import org.onosproject.lisp.msg.types.LispAfiAddress;
+import static com.google.common.base.MoreObjects.toStringHelper;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.onosproject.lisp.msg.types.LispAfiAddress.AfiAddressWriter;
@@ -64,6 +66,32 @@
return prefix;
}
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .add("maskLength", maskLength)
+ .add("prefix", prefix).toString();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ LispEidRecord that = (LispEidRecord) o;
+ return Objects.equal(maskLength, that.maskLength) &&
+ Objects.equal(prefix, that.prefix);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(maskLength, prefix);
+ }
+
/**
* A LISP message reader for EidRecord portion.
*/