[ONOS-5710] Process Map-Request msg when proxy bit is set to false
Change-Id: I0ceef00c67ab266b01dec121fe6a4fe1f3dca3e5
diff --git a/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/impl/LispChannelHandler.java b/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/impl/LispChannelHandler.java
index a36031e..b5e0105 100644
--- a/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/impl/LispChannelHandler.java
+++ b/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/impl/LispChannelHandler.java
@@ -30,6 +30,8 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.util.List;
+
/**
* Channel handler deals with the xTR connection and dispatches xTR messages
* to the appropriate locations.
@@ -42,18 +44,22 @@
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
try {
- // first we need to check whether this is an ECM
+
+ // process map-request message that is encapsulated in ECM
if (msg instanceof LispEncapsulatedControl) {
LispMessage innerMsg = extractLispMessage((LispEncapsulatedControl) msg);
if (innerMsg instanceof LispMapRequest) {
LispMapResolver mapResolver = LispMapResolver.getInstance();
- LispMessage lispMessage =
+ List<LispMessage> lispMessages =
mapResolver.processMapRequest((LispEncapsulatedControl) msg);
- ctx.writeAndFlush(lispMessage);
+ if (lispMessages != null) {
+ lispMessages.forEach(ctx::writeAndFlush);
+ }
}
}
+ // process map-register message
if (msg instanceof LispMapRegister) {
LispMapServer mapServer = LispMapServer.getInstance();
LispMapNotify mapNotify =
@@ -64,11 +70,14 @@
}
}
+ // process info-request message
if (msg instanceof LispInfoRequest) {
LispMapServer mapServer = LispMapServer.getInstance();
LispInfoReply infoReply = mapServer.processInfoRequest((LispInfoRequest) msg);
- ctx.writeAndFlush(infoReply);
+ if (infoReply != null) {
+ ctx.writeAndFlush(infoReply);
+ }
}
} finally {
// try to remove the received message form the buffer
diff --git a/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/impl/LispMapResolver.java b/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/impl/LispMapResolver.java
index 5784a07..fc22f80 100644
--- a/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/impl/LispMapResolver.java
+++ b/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/impl/LispMapResolver.java
@@ -15,14 +15,19 @@
*/
package org.onosproject.lisp.ctl.impl;
+import com.google.common.collect.Lists;
+import org.onosproject.lisp.msg.protocols.DefaultLispEncapsulatedControl.DefaultEcmBuilder;
import org.onosproject.lisp.msg.protocols.DefaultLispMapReply.DefaultReplyBuilder;
import org.onosproject.lisp.msg.protocols.LispEncapsulatedControl;
+import org.onosproject.lisp.msg.protocols.LispEncapsulatedControl.EcmBuilder;
+import org.onosproject.lisp.msg.protocols.LispLocatorRecord;
import org.onosproject.lisp.msg.protocols.LispMapRecord;
-import org.onosproject.lisp.msg.protocols.LispMapReply;
import org.onosproject.lisp.msg.protocols.LispMapReply.ReplyBuilder;
-import org.onosproject.lisp.msg.protocols.LispMessage;
-import org.onosproject.lisp.msg.types.LispIpAddress;
import org.onosproject.lisp.msg.protocols.LispMapRequest;
+import org.onosproject.lisp.msg.protocols.LispMapReply;
+import org.onosproject.lisp.msg.protocols.LispMessage;
+import org.onosproject.lisp.msg.types.LispAfiAddress;
+import org.onosproject.lisp.msg.types.LispIpAddress;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -38,13 +43,20 @@
private static final Logger log = LoggerFactory.getLogger(LispMapResolver.class);
+ private static final int ECM_DST_PORT = 4342;
+ private static final String NO_ITR_RLOCS_MSG =
+ "No ITR RLOC is found, cannot respond to ITR.";
+ private static final String NO_ETR_RLOCS_MSG =
+ "No ETR RLOC is found, cannot relay to ETR.";
+ private static final String NO_MAP_INFO_MSG = "Map information is not found.";
+
private LispMappingDatabase mapDb = LispMappingDatabase.getInstance();
// non-instantiable (except for our Singleton)
private LispMapResolver() {
}
- public static LispMapResolver getInstance() {
+ static LispMapResolver getInstance() {
return SingletonHelper.INSTANCE;
}
@@ -54,38 +66,145 @@
* @param message encapsulated control message
* @return map-reply message
*/
- public LispMessage processMapRequest(LispMessage message) {
+ List<LispMessage> processMapRequest(LispMessage message) {
LispEncapsulatedControl ecm = (LispEncapsulatedControl) message;
LispMapRequest request = (LispMapRequest) ecm.getControlMessage();
- // build map-reply message
+ List<LispMapRecord> mapReplyRecords =
+ mapDb.getMapRecordByEidRecords(request.getEids(), true);
+
+ List<LispMapRecord> mapRequestRecords =
+ mapDb.getMapRecordByEidRecords(request.getEids(), false);
+
+ if (mapReplyRecords.size() + mapRequestRecords.size() == 0) {
+
+ // TODO: need to generate map-reply with configured native-forward action
+ log.warn(NO_MAP_INFO_MSG);
+
+ } else {
+
+ if (mapReplyRecords.size() > 0) {
+
+ List<LispMessage> mapReplies = Lists.newArrayList();
+
+ // build map-reply message based on map-request from ITR
+ ReplyBuilder replyBuilder = initMapReplyBuilder(request);
+ replyBuilder.withMapRecords(mapReplyRecords);
+
+ List<InetSocketAddress> addresses =
+ getItrAddresses(request.getItrRlocs(),
+ ecm.innerUdp().getSourcePort());
+
+ addresses.forEach(address -> {
+ if (address != null) {
+ LispMapReply reply = replyBuilder.build();
+ reply.configSender(address);
+ mapReplies.add(reply);
+ } else {
+ log.warn(NO_ITR_RLOCS_MSG);
+ }
+ });
+
+ return mapReplies;
+ }
+
+ if (mapRequestRecords.size() > 0) {
+
+ List<LispMessage> ecms = Lists.newArrayList();
+
+ // re-encapsulate encapsulated control message from ITR
+ List<InetSocketAddress> addresses =
+ getEtrAddresses(mapRequestRecords, ECM_DST_PORT);
+
+ addresses.forEach(address -> {
+ if (address != null) {
+ LispEncapsulatedControl reencapEcm = cloneEcm(ecm);
+ reencapEcm.configSender(address);
+ ecms.add(reencapEcm);
+ } else {
+ log.warn(NO_ETR_RLOCS_MSG);
+ }
+ });
+
+ return ecms;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Initializes MapReply builder without specifying map records.
+ *
+ * @param request received map request from ITR
+ * @return initialized MapReply builder
+ */
+ private ReplyBuilder initMapReplyBuilder(LispMapRequest request) {
ReplyBuilder replyBuilder = new DefaultReplyBuilder();
replyBuilder.withNonce(request.getNonce());
replyBuilder.withIsEtr(false);
replyBuilder.withIsSecurity(false);
replyBuilder.withIsProbe(request.isProbe());
- List<LispMapRecord> mapRecords = mapDb.getMapRecordByEidRecords(request.getEids());
+ return replyBuilder;
+ }
- if (mapRecords.size() == 0) {
- log.warn("Map information is not found.");
- } else {
- replyBuilder.withMapRecords(mapRecords);
+ /**
+ * Clones ECM from original ECM.
+ *
+ * @param ecm original ECM
+ * @return cloned ECM
+ */
+ private LispEncapsulatedControl cloneEcm(LispEncapsulatedControl ecm) {
+ EcmBuilder ecmBuilder = new DefaultEcmBuilder();
+ ecmBuilder.innerLispMessage(ecm.getControlMessage());
+ ecmBuilder.isSecurity(ecm.isSecurity());
+ ecmBuilder.innerIpHeader(ecm.innerIpHeader());
+ ecmBuilder.innerUdpHeader(ecm.innerUdp());
+
+ return ecmBuilder.build();
+ }
+
+ /**
+ * Obtains a collection of valid ITR addresses with a port number specified.
+ * These addresses will be used to acknowledge map-reply to ITR.
+ *
+ * @param itrRlocs a collection of ITR RLOCs
+ * @param port port number
+ * @return a collection of valid ITR addresses with a port number specified
+ */
+ private List<InetSocketAddress> getItrAddresses(List<LispAfiAddress> itrRlocs,
+ int port) {
+ List<InetSocketAddress> addresses = Lists.newArrayList();
+ for (LispAfiAddress itrRloc : itrRlocs) {
+ addresses.add(new InetSocketAddress(((LispIpAddress)
+ itrRloc).getAddress().toInetAddress(), port));
}
+ return addresses;
+ }
- LispMapReply reply = replyBuilder.build();
+ /**
+ * Obtains a collection of valid ETR addresses with a port number specified.
+ * These addresses will be used to relay map-request to ETR.
+ *
+ * @param mapRecords a collection of map records
+ * @param port port number
+ * @return a collection of valid ETR addresses with a port number specified
+ */
+ private List<InetSocketAddress> getEtrAddresses(List<LispMapRecord> mapRecords,
+ int port) {
+ List<InetSocketAddress> addresses = Lists.newArrayList();
+ for (LispMapRecord mapRecord : mapRecords) {
- 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.");
+ // we only select the first locator record in all cases...
+ LispLocatorRecord locatorRecord = mapRecord.getLocators().get(0);
+ if (locatorRecord != null) {
+ addresses.add(new InetSocketAddress(((LispIpAddress)
+ locatorRecord.getLocatorAfi()).getAddress()
+ .toInetAddress(), port));
+ }
}
-
- return reply;
+ return addresses;
}
/**
diff --git a/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/impl/LispMapServer.java b/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/impl/LispMapServer.java
index 58792a2..faac48d 100644
--- a/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/impl/LispMapServer.java
+++ b/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/impl/LispMapServer.java
@@ -44,6 +44,7 @@
import java.net.UnknownHostException;
import java.util.Arrays;
+import static org.onlab.packet.IpAddress.valueOf;
import static org.onosproject.lisp.msg.authentication.LispAuthenticationKeyEnum.valueOf;
/**
@@ -52,10 +53,16 @@
*/
public final class LispMapServer {
+ private static final Logger log = LoggerFactory.getLogger(LispMapServer.class);
+
private static final int MAP_NOTIFY_PORT = 4342;
private static final int INFO_REPLY_PORT = 4342;
- private static final Logger log = LoggerFactory.getLogger(LispMapServer.class);
+ private static final String INVALID_AUTHENTICATION_DATA_MSG =
+ "Unmatched authentication data of {}.";
+ private static final String FAILED_TO_FORMULATE_NAT_MSG =
+ "Fails during formulate NAT address.";
+
private LispMappingDatabase mapDb = LispMappingDatabase.getInstance();
private LispAuthenticationConfig authConfig = LispAuthenticationConfig.getInstance();
@@ -64,7 +71,7 @@
private LispMapServer() {
}
- public static LispMapServer getInstance() {
+ static LispMapServer getInstance() {
return SingletonHelper.INSTANCE;
}
@@ -74,21 +81,21 @@
* @param message map-register message
* @return map-notify message
*/
- public LispMapNotify processMapRegister(LispMessage message) {
+ LispMapNotify processMapRegister(LispMessage message) {
LispMapRegister register = (LispMapRegister) message;
if (!checkMapRegisterAuthData(register)) {
- log.warn("Unmatched authentication data of Map-Register");
+ log.warn(INVALID_AUTHENTICATION_DATA_MSG, "Map-Register");
return null;
}
register.getMapRecords().forEach(mapRecord -> {
LispEidRecord eidRecord =
- new LispEidRecord(mapRecord.getMaskLength(),
- mapRecord.getEidPrefixAfi());
+ new LispEidRecord(mapRecord.getMaskLength(),
+ mapRecord.getEidPrefixAfi());
- mapDb.putMapRecord(eidRecord, mapRecord);
+ mapDb.putMapRecord(eidRecord, mapRecord, register.isProxyMapReply());
});
// we only acknowledge back to ETR when want-map-notify bit is set to true
@@ -119,23 +126,23 @@
* @param message info-request message
* @return info-reply message
*/
- public LispInfoReply processInfoRequest(LispMessage message) {
+ LispInfoReply processInfoRequest(LispMessage message) {
LispInfoRequest request = (LispInfoRequest) message;
if (!checkInfoRequestAuthData(request)) {
- log.warn("Unmatched authentication data of Info-Request");
+ log.warn(INVALID_AUTHENTICATION_DATA_MSG, "Info-Request");
return null;
}
NatAddressBuilder natBuilder = new NatAddressBuilder();
try {
LispAfiAddress msAddress =
- new LispIpv4Address(IpAddress.valueOf(InetAddress.getLocalHost()));
+ new LispIpv4Address(valueOf(InetAddress.getLocalHost()));
natBuilder.withMsRlocAddress(msAddress);
natBuilder.withMsUdpPortNumber((short) INFO_REPLY_PORT);
// try to extract global ETR RLOC address from info-request
- IpAddress globalRlocIp = IpAddress.valueOf(request.getSender().getAddress());
+ IpAddress globalRlocIp = valueOf(request.getSender().getAddress());
LispAfiAddress globalRlocAddress;
if (globalRlocIp.isIp4()) {
globalRlocAddress = new LispIpv4Address(globalRlocIp);
@@ -149,7 +156,7 @@
// TODO: need to specify RTR addresses
} catch (UnknownHostException e) {
- log.warn("Fails during formulate NAT address", e);
+ log.warn(FAILED_TO_FORMULATE_NAT_MSG, e);
}
InfoReplyBuilder replyBuilder = new DefaultInfoReplyBuilder();
diff --git a/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/impl/LispMappingDatabase.java b/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/impl/LispMappingDatabase.java
index f4f421b..4545542 100644
--- a/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/impl/LispMappingDatabase.java
+++ b/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/impl/LispMappingDatabase.java
@@ -20,8 +20,10 @@
import org.onlab.packet.IpPrefix;
import org.onosproject.lisp.ctl.impl.map.ExpireMap;
import org.onosproject.lisp.ctl.impl.map.ExpireHashMap;
+import org.onosproject.lisp.msg.protocols.DefaultLispProxyMapRecord.DefaultMapWithProxyBuilder;
import org.onosproject.lisp.msg.protocols.LispEidRecord;
import org.onosproject.lisp.msg.protocols.LispMapRecord;
+import org.onosproject.lisp.msg.protocols.LispProxyMapRecord;
import org.onosproject.lisp.msg.types.LispAfiAddress;
import java.util.List;
@@ -34,7 +36,7 @@
private static final long MINUTE_TO_MS_UNIT = 60 * 1000;
- private ExpireMap<LispEidRecord, LispMapRecord> map = new ExpireHashMap<>();
+ private ExpireMap<LispEidRecord, LispProxyMapRecord> map = new ExpireHashMap<>();
/**
* Prevents object instantiation from external.
@@ -54,11 +56,17 @@
/**
* Inserts a new EID-RLOC mapping record.
*
- * @param eid endpoint identifier
- * @param rloc route locator record
+ * @param eid endpoint identifier
+ * @param rloc route locator record
+ * @param proxyMapReply proxy map reply flag
*/
- public void putMapRecord(LispEidRecord eid, LispMapRecord rloc) {
- map.put(eid, rloc, rloc.getRecordTtl() * MINUTE_TO_MS_UNIT);
+ public void putMapRecord(LispEidRecord eid, LispMapRecord rloc,
+ boolean proxyMapReply) {
+ LispProxyMapRecord mapWithProxy = new DefaultMapWithProxyBuilder()
+ .withMapRecord(rloc)
+ .withIsProxyMapReply(proxyMapReply)
+ .build();
+ map.put(eid, mapWithProxy, rloc.getRecordTtl() * MINUTE_TO_MS_UNIT);
}
/**
@@ -81,16 +89,19 @@
}
/**
- * Obtains an EID-RLOC mapping record with given EID record.
+ * Obtains an EID-RLOC mapping record in accordance with the proxy map reply
+ * flag bit and EID record.
*
- * @param eid endpoint identifier record
+ * @param eid endpoint identifier record
+ * @param proxyMapReply proxy map reply flag
* @return an EID-RLOC mapping record
*/
- public LispMapRecord getMapRecordByEidRecord(LispEidRecord eid) {
+ public LispMapRecord getMapRecordByEidRecord(LispEidRecord eid, boolean proxyMapReply) {
for (LispEidRecord key : map.keySet()) {
- if (isInRange(key, eid)) {
- return map.get(key);
+ if (isInRange(key, eid) && map.get(key) != null
+ && map.get(key).isProxyMapReply() == proxyMapReply) {
+ return map.get(key).getMapRecord();
}
}
@@ -98,15 +109,18 @@
}
/**
- * Obtains a collection of EID-RLOC mapping records with given EID records.
+ * Obtains a collection of EID-RLOC mapping record in accordance with the
+ * proxy map reply flag bit and EID record.
*
- * @param eids endpoint identifier records
+ * @param eids endpoint identifier records
+ * @param proxyMapReply proxy map reply flag
* @return a collection of EID-RLOC mapping records
*/
- public List<LispMapRecord> getMapRecordByEidRecords(List<LispEidRecord> eids) {
+ public List<LispMapRecord> getMapRecordByEidRecords(List<LispEidRecord> eids,
+ boolean proxyMapReply) {
List<LispMapRecord> mapRecords = Lists.newArrayList();
eids.forEach(eidRecord -> {
- LispMapRecord mapRecord = getMapRecordByEidRecord(eidRecord);
+ LispMapRecord mapRecord = getMapRecordByEidRecord(eidRecord, proxyMapReply);
if (mapRecord != null) {
mapRecords.add(mapRecord);
}
@@ -123,7 +137,8 @@
public LispMapRecord getMapRecordByEidAddress(LispAfiAddress address) {
Optional<LispEidRecord> eidRecord =
map.keySet().stream().filter(k -> k.getPrefix().equals(address)).findFirst();
- return eidRecord.map(lispEidRecord -> map.get(lispEidRecord)).orElse(null);
+ return eidRecord.map(lispEidRecord ->
+ map.get(lispEidRecord).getMapRecord()).orElse(null);
}
/**
diff --git a/protocols/lisp/ctl/src/test/java/org/onosproject/lisp/ctl/impl/LispMappingDatabaseTest.java b/protocols/lisp/ctl/src/test/java/org/onosproject/lisp/ctl/impl/LispMappingDatabaseTest.java
index 2c2142a..6f6c603 100644
--- a/protocols/lisp/ctl/src/test/java/org/onosproject/lisp/ctl/impl/LispMappingDatabaseTest.java
+++ b/protocols/lisp/ctl/src/test/java/org/onosproject/lisp/ctl/impl/LispMappingDatabaseTest.java
@@ -106,9 +106,9 @@
builder3.withRecordTtl(60);
LispMapRecord mapRecord3 = builder3.build();
- mapDb.putMapRecord(eidRecord1, mapRecord1);
- mapDb.putMapRecord(eidRecord2, mapRecord2);
- mapDb.putMapRecord(eidRecord3, mapRecord3);
+ mapDb.putMapRecord(eidRecord1, mapRecord1, true);
+ mapDb.putMapRecord(eidRecord2, mapRecord2, true);
+ mapDb.putMapRecord(eidRecord3, mapRecord3, true);
}
@Test
@@ -116,7 +116,7 @@
byte cidr32 = (byte) 32;
LispIpv4Address eid = new LispIpv4Address(IpAddress.valueOf("10.1.1.1"));
LispEidRecord record = new LispEidRecord(cidr32, eid);
- LispMapRecord mapRecord = mapDb.getMapRecordByEidRecord(record);
+ LispMapRecord mapRecord = mapDb.getMapRecordByEidRecord(record, true);
assertThat("Failed to fetch the RLOCs with /32 EID record",
mapRecord.getLocatorCount(), is(3));
@@ -127,12 +127,12 @@
byte cidr32 = (byte) 32;
LispIpv4Address eid = new LispIpv4Address(IpAddress.valueOf("10.1.2.1"));
LispEidRecord record32 = new LispEidRecord(cidr32, eid);
- LispMapRecord mapRecord32 = mapDb.getMapRecordByEidRecord(record32);
+ LispMapRecord mapRecord32 = mapDb.getMapRecordByEidRecord(record32, true);
byte cidr24 = (byte) 24;
LispIpv4Address eid24 = new LispIpv4Address(IpAddress.valueOf("10.1.2.0"));
LispEidRecord record24 = new LispEidRecord(cidr24, eid24);
- LispMapRecord mapRecord24 = mapDb.getMapRecordByEidRecord(record24);
+ LispMapRecord mapRecord24 = mapDb.getMapRecordByEidRecord(record24, true);
assertThat("Failed to fetch the RLOCs with /32 EID record",
mapRecord32.getLocatorCount(), is(2));
@@ -145,17 +145,17 @@
byte cidr32 = (byte) 32;
LispIpv4Address eid = new LispIpv4Address(IpAddress.valueOf("10.2.1.1"));
LispEidRecord record32 = new LispEidRecord(cidr32, eid);
- LispMapRecord mapRecord32 = mapDb.getMapRecordByEidRecord(record32);
+ LispMapRecord mapRecord32 = mapDb.getMapRecordByEidRecord(record32, true);
byte cidr24 = (byte) 24;
LispIpv4Address eid24 = new LispIpv4Address(IpAddress.valueOf("10.2.1.0"));
LispEidRecord record24 = new LispEidRecord(cidr24, eid24);
- LispMapRecord mapRecord24 = mapDb.getMapRecordByEidRecord(record24);
+ LispMapRecord mapRecord24 = mapDb.getMapRecordByEidRecord(record24, true);
byte cidr16 = (byte) 16;
LispIpv4Address eid16 = new LispIpv4Address(IpAddress.valueOf("10.2.0.0"));
LispEidRecord record16 = new LispEidRecord(cidr16, eid16);
- LispMapRecord mapRecord16 = mapDb.getMapRecordByEidRecord(record16);
+ LispMapRecord mapRecord16 = mapDb.getMapRecordByEidRecord(record16, true);
assertThat("Failed to fetch the RLOCs with /32 EID record",
mapRecord32.getLocatorCount(), is(1));
diff --git a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispProxyMapRecord.java b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispProxyMapRecord.java
new file mode 100644
index 0000000..ac67130
--- /dev/null
+++ b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispProxyMapRecord.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.lisp.msg.protocols;
+
+/**
+ * A default implementation class of LispMapWithProxy interface.
+ */
+public final class DefaultLispProxyMapRecord implements LispProxyMapRecord {
+
+ private final LispMapRecord mapRecord;
+ private final boolean proxyMapReply;
+
+ private DefaultLispProxyMapRecord(LispMapRecord mapRecord, boolean proxyMapReply) {
+ this.mapRecord = mapRecord;
+ this.proxyMapReply = proxyMapReply;
+ }
+
+ @Override
+ public LispMapRecord getMapRecord() {
+ return mapRecord;
+ }
+
+ @Override
+ public boolean isProxyMapReply() {
+ return proxyMapReply;
+ }
+
+ /**
+ * A default builder class that builds MapWithProxy object.
+ */
+ public static final class DefaultMapWithProxyBuilder implements MapWithProxyBuilder {
+
+ private LispMapRecord mapRecord;
+ private boolean proxyMapReply;
+
+ @Override
+ public MapWithProxyBuilder withMapRecord(LispMapRecord mapRecord) {
+ this.mapRecord = mapRecord;
+ return this;
+ }
+
+ @Override
+ public MapWithProxyBuilder withIsProxyMapReply(boolean proxyMapReply) {
+ this.proxyMapReply = proxyMapReply;
+ return this;
+ }
+
+ @Override
+ public LispProxyMapRecord build() {
+ return new DefaultLispProxyMapRecord(mapRecord, proxyMapReply);
+ }
+ }
+}
diff --git a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/LispProxyMapRecord.java b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/LispProxyMapRecord.java
new file mode 100644
index 0000000..913f7c6
--- /dev/null
+++ b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/LispProxyMapRecord.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.lisp.msg.protocols;
+
+/**
+ * An interface that wraps LispMapRecord with proxy-bit flag.
+ */
+public interface LispProxyMapRecord {
+
+ /**
+ * Obtains LISP map record.
+ *
+ * @return LISP map record
+ */
+ LispMapRecord getMapRecord();
+
+ /**
+ * Obtains proxy-map-reply flag.
+ *
+ * @return proxy-map-reply flag
+ */
+ boolean isProxyMapReply();
+
+ /**
+ * A builder of LISP map with proxy flag internal data structure.
+ */
+ interface MapWithProxyBuilder {
+
+ /**
+ * Sets LISP map record.
+ *
+ * @param mapRecord map record
+ * @return MapWithProxyBuilder object
+ */
+ MapWithProxyBuilder withMapRecord(LispMapRecord mapRecord);
+
+ /**
+ * Sets isProxyMapReply flag.
+ *
+ * @param isProxyMapReply isProxyMapReply flag
+ * @return MapWithProxyBuilder object
+ */
+ MapWithProxyBuilder withIsProxyMapReply(boolean isProxyMapReply);
+
+ /**
+ * Builds LISP map with proxy data object.
+ *
+ * @return LISP map with proxy data object
+ */
+ LispProxyMapRecord build();
+ }
+}