[ONOS-4718] Initial implementation of LISP control msg serializer
Change-Id: Ia068e1b158f05dd70839cb1020f15dc66b0142a0
diff --git a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispLocatorRecord.java b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispLocatorRecord.java
index 66ef81d..37eeb71 100644
--- a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispLocatorRecord.java
+++ b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispLocatorRecord.java
@@ -20,9 +20,11 @@
import org.onlab.util.ByteOperator;
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 org.onosproject.lisp.msg.types.LispAfiAddress.AfiAddressWriter;
/**
* Default implementation of LispLocatorRecord.
@@ -265,4 +267,59 @@
.build();
}
}
+
+ /**
+ * A LISP message writer for LocatorRecord portion.
+ */
+ public static final class LocatorRecordWriter implements LispMessageWriter<LispLocatorRecord> {
+
+ private static final int LOCAL_LOCATOR_SHIFT_BIT = 2;
+ private static final int PROBED_SHIFT_BIT = 1;
+
+ private static final int ENABLE_BIT = 1;
+ private static final int DISABLE_BIT = 0;
+
+ @Override
+ public void writeTo(ByteBuf byteBuf, LispLocatorRecord message) throws LispWriterException {
+
+ // priority
+ byteBuf.writeByte(message.getPriority());
+
+ // weight
+ byteBuf.writeByte(message.getWeight());
+
+ // multicast priority
+ byteBuf.writeByte(message.getMulticastPriority());
+
+ // multicast weight
+ byteBuf.writeByte(message.getMulticastWeight());
+
+ // unused flags
+ byteBuf.writeByte((short) 0);
+
+ // localLocator flag
+ short localLocator = DISABLE_BIT;
+ if (message.isLocalLocator()) {
+ localLocator = (byte) (ENABLE_BIT << LOCAL_LOCATOR_SHIFT_BIT);
+ }
+
+ // rlocProbed flag
+ short probed = DISABLE_BIT;
+ if (message.isRlocProbed()) {
+ probed = (byte) (ENABLE_BIT << PROBED_SHIFT_BIT);
+ }
+
+ // routed flag
+ short routed = DISABLE_BIT;
+ if (message.isRouted()) {
+ routed = (byte) ENABLE_BIT;
+ }
+
+ byteBuf.writeByte((byte) (localLocator + probed + routed));
+
+ // EID prefix AFI with EID prefix
+ AfiAddressWriter afiAddressWriter = new AfiAddressWriter();
+ afiAddressWriter.writeTo(byteBuf, message.getLocatorAfi());
+ }
+ }
}
diff --git a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispMapNotify.java b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispMapNotify.java
index 05cc7f5..30eba1f 100644
--- a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispMapNotify.java
+++ b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispMapNotify.java
@@ -22,10 +22,13 @@
import org.onlab.util.ImmutableByteSequence;
import org.onosproject.lisp.msg.exceptions.LispParseError;
import org.onosproject.lisp.msg.exceptions.LispReaderException;
+import org.onosproject.lisp.msg.exceptions.LispWriterException;
+import java.util.Arrays;
import java.util.List;
import static com.google.common.base.MoreObjects.toStringHelper;
+import static org.onosproject.lisp.msg.protocols.DefaultLispMapRecord.MapRecordWriter;
/**
* Default LISP map notify message class.
@@ -34,6 +37,7 @@
private final long nonce;
private final short keyId;
+ private final short authDataLength;
private final byte[] authenticationData;
private final byte recordCount;
private final List<LispMapRecord> mapRecords;
@@ -47,10 +51,12 @@
* @param recordCount record count number
* @param mapRecords a collection of map records
*/
- private DefaultLispMapNotify(long nonce, short keyId, byte[] authenticationData,
- byte recordCount, List<LispMapRecord> mapRecords) {
+ private DefaultLispMapNotify(long nonce, short keyId, short authDataLength,
+ byte[] authenticationData, byte recordCount,
+ List<LispMapRecord> mapRecords) {
this.nonce = nonce;
this.keyId = keyId;
+ this.authDataLength = authDataLength;
this.authenticationData = authenticationData;
this.recordCount = recordCount;
this.mapRecords = mapRecords;
@@ -73,26 +79,31 @@
@Override
public long getNonce() {
- return this.nonce;
+ return nonce;
}
@Override
public byte getRecordCount() {
- return this.recordCount;
+ return recordCount;
}
@Override
public short getKeyId() {
- return this.keyId;
+ return keyId;
+ }
+
+ @Override
+ public short getAuthDataLength() {
+ return authDataLength;
}
@Override
public byte[] getAuthenticationData() {
- return ImmutableByteSequence.copyFrom(this.authenticationData).asArray();
+ return ImmutableByteSequence.copyFrom(authenticationData).asArray();
}
@Override
- public List<LispMapRecord> getLispRecords() {
+ public List<LispMapRecord> getMapRecords() {
return ImmutableList.copyOf(mapRecords);
}
@@ -103,6 +114,8 @@
.add("nonce", nonce)
.add("recordCount", recordCount)
.add("keyId", keyId)
+ .add("authentication data length", authDataLength)
+ .add("authentication data", authenticationData)
.add("mapRecords", mapRecords).toString();
}
@@ -118,18 +131,20 @@
return Objects.equal(nonce, that.nonce) &&
Objects.equal(recordCount, that.recordCount) &&
Objects.equal(keyId, that.keyId) &&
+ Objects.equal(authDataLength, that.authDataLength) &&
Objects.equal(authenticationData, that.authenticationData);
}
@Override
public int hashCode() {
- return Objects.hashCode(nonce, recordCount, keyId, authenticationData);
+ return Objects.hashCode(nonce, recordCount, keyId, authDataLength, authenticationData);
}
public static final class DefaultNotifyBuilder implements NotifyBuilder {
private long nonce;
private short keyId;
+ private short authDataLength;
private byte[] authenticationData;
private byte recordCount;
private List<LispMapRecord> mapRecords;
@@ -158,6 +173,12 @@
}
@Override
+ public NotifyBuilder withAuthDataLength(short authDataLength) {
+ this.authDataLength = authDataLength;
+ return this;
+ }
+
+ @Override
public NotifyBuilder withAuthenticationData(byte[] authenticationData) {
this.authenticationData = authenticationData;
return this;
@@ -171,15 +192,15 @@
@Override
public LispMapNotify build() {
- return new DefaultLispMapNotify(nonce, keyId, authenticationData,
- recordCount, mapRecords);
+ return new DefaultLispMapNotify(nonce, keyId, authDataLength,
+ authenticationData, recordCount, mapRecords);
}
}
/**
- * A private LISP message reader for MapNotify message.
+ * A LISP message reader for MapNotify message.
*/
- private static class NotifyReader implements LispMessageReader<LispMapNotify> {
+ public static final class NotifyReader implements LispMessageReader<LispMapNotify> {
private static final int RESERVED_SKIP_LENGTH = 3;
@@ -218,9 +239,64 @@
.withRecordCount(recordCount)
.withNonce(nonce)
.withKeyId(keyId)
+ .withAuthDataLength(authLength)
.withAuthenticationData(authData)
.withMapRecords(mapRecords)
.build();
}
}
+
+ /**
+ * A LISP message reader for MapNotify message.
+ */
+ public static final class NotifyWriter implements LispMessageWriter<LispMapNotify> {
+
+ private static final int NOTIFY_MSG_TYPE = 4;
+ private static final int NOTIFY_SHIFT_BIT = 4;
+
+ private static final int UNUSED_ZERO = 0;
+
+ @Override
+ public void writeTo(ByteBuf byteBuf, LispMapNotify message) throws LispWriterException {
+
+ // specify LISP message type
+ byte msgType = (byte) (NOTIFY_MSG_TYPE << NOTIFY_SHIFT_BIT);
+ byteBuf.writeByte(msgType);
+
+ // reserved field
+ byteBuf.writeShort((short) UNUSED_ZERO);
+
+ // record count
+ byteBuf.writeByte(message.getRecordCount());
+
+ // nonce
+ byteBuf.writeLong(message.getNonce());
+
+ // keyId
+ byteBuf.writeShort(message.getKeyId());
+
+ // authentication data length in octet
+ byteBuf.writeShort(message.getAuthDataLength());
+
+ // authentication data
+ byte[] data = message.getAuthenticationData();
+ byte[] clone;
+ if (data != null) {
+ clone = data.clone();
+ Arrays.fill(clone, (byte) UNUSED_ZERO);
+ }
+
+ byteBuf.writeBytes(data);
+
+ // TODO: need to implement MAC authentication mechanism
+
+ // serialize map records
+ MapRecordWriter writer = new MapRecordWriter();
+ List<LispMapRecord> records = message.getMapRecords();
+
+ for (int i = 0; i < records.size(); i++) {
+ writer.writeTo(byteBuf, records.get(i));
+ }
+ }
+ }
}
diff --git a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispMapRecord.java b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispMapRecord.java
index b6605d6..a924c7f 100644
--- a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispMapRecord.java
+++ b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispMapRecord.java
@@ -22,11 +22,14 @@
import org.onlab.util.ByteOperator;
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 java.util.List;
import static com.google.common.base.MoreObjects.toStringHelper;
+import static org.onosproject.lisp.msg.types.LispAfiAddress.AfiAddressWriter;
+import static org.onosproject.lisp.msg.protocols.DefaultLispLocatorRecord.LocatorRecordWriter;
/**
* Default implementation of LispMapRecord.
@@ -268,4 +271,58 @@
.build();
}
}
+
+ /**
+ * A LISP message writer for MapRecord portion.
+ */
+ public static final class MapRecordWriter implements LispMessageWriter<LispMapRecord> {
+
+ private static final int REPLY_ACTION_SHIFT_BIT = 5;
+ private static final int AUTHORITATIVE_FLAG_SHIFT_BIT = 4;
+
+ private static final int ENABLE_BIT = 1;
+ private static final int DISABLE_BIT = 0;
+
+ @Override
+ public void writeTo(ByteBuf byteBuf, LispMapRecord message) throws LispWriterException {
+
+ // record TTL
+ byteBuf.writeInt(message.getRecordTtl());
+
+ // locator count
+ byteBuf.writeByte((byte) message.getLocatorCount());
+
+ // EID mask length
+ byteBuf.writeByte(message.getMaskLength());
+
+ // reply action
+ byte action = (byte) (message.getAction().getAction() << REPLY_ACTION_SHIFT_BIT);
+
+ // authoritative bit
+ byte authoritative = DISABLE_BIT;
+ if (message.isAuthoritative()) {
+ authoritative = ENABLE_BIT;
+ }
+ authoritative = (byte) (authoritative << AUTHORITATIVE_FLAG_SHIFT_BIT);
+
+ byteBuf.writeByte((byte) (action + authoritative));
+
+ // fill zero into reserved field
+ byteBuf.writeByte((short) 0);
+
+ // map version number
+ byteBuf.writeShort(message.getMapVersionNumber());
+
+ // EID prefix AFI with EID prefix
+ AfiAddressWriter afiAddressWriter = new AfiAddressWriter();
+ afiAddressWriter.writeTo(byteBuf, message.getEidPrefixAfi());
+
+ // serialize locator
+ LocatorRecordWriter recordWriter = new LocatorRecordWriter();
+ List<LispLocatorRecord> locators = message.getLocators();
+ for (int i = 0; i < locators.size(); i++) {
+ recordWriter.writeTo(byteBuf, locators.get(i));
+ }
+ }
+ }
}
diff --git a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispMapRegister.java b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispMapRegister.java
index 7f75181..abaf3c8 100644
--- a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispMapRegister.java
+++ b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispMapRegister.java
@@ -23,11 +23,14 @@
import org.onlab.util.ImmutableByteSequence;
import org.onosproject.lisp.msg.exceptions.LispParseError;
import org.onosproject.lisp.msg.exceptions.LispReaderException;
+import org.onosproject.lisp.msg.exceptions.LispWriterException;
+import java.util.Arrays;
import java.util.List;
import static com.google.common.base.MoreObjects.toStringHelper;
+
/**
* Default LISP map register message class.
*/
@@ -35,6 +38,7 @@
private final long nonce;
private final short keyId;
+ private final short authDataLength;
private final byte[] authenticationData;
private final byte recordCount;
private final List<LispMapRecord> mapRecords;
@@ -52,12 +56,13 @@
* @param proxyMapReply proxy map reply flag
* @param wantMapNotify want map notify flag
*/
- private DefaultLispMapRegister(long nonce, short keyId,
+ private DefaultLispMapRegister(long nonce, short keyId, short authDataLength,
byte[] authenticationData, byte recordCount,
List<LispMapRecord> mapRecords,
boolean proxyMapReply, boolean wantMapNotify) {
this.nonce = nonce;
this.keyId = keyId;
+ this.authDataLength = authDataLength;
this.authenticationData = authenticationData;
this.recordCount = recordCount;
this.mapRecords = mapRecords;
@@ -106,6 +111,11 @@
}
@Override
+ public short getAuthDataLength() {
+ return authDataLength;
+ }
+
+ @Override
public byte[] getAuthenticationData() {
return ImmutableByteSequence.copyFrom(this.authenticationData).asArray();
}
@@ -122,6 +132,8 @@
.add("nonce", nonce)
.add("recordCount", recordCount)
.add("keyId", keyId)
+ .add("authentication data length", authDataLength)
+ .add("authentication data", authenticationData)
.add("mapRecords", mapRecords)
.add("proxyMapReply", proxyMapReply)
.add("wantMapNotify", wantMapNotify).toString();
@@ -140,6 +152,7 @@
return Objects.equal(nonce, that.nonce) &&
Objects.equal(recordCount, that.recordCount) &&
Objects.equal(keyId, that.keyId) &&
+ Objects.equal(authDataLength, that.authDataLength) &&
Objects.equal(authenticationData, that.authenticationData) &&
Objects.equal(proxyMapReply, that.proxyMapReply) &&
Objects.equal(wantMapNotify, that.wantMapNotify);
@@ -147,14 +160,15 @@
@Override
public int hashCode() {
- return Objects.hashCode(nonce, recordCount, keyId, authenticationData,
- proxyMapReply, wantMapNotify);
+ return Objects.hashCode(nonce, recordCount, keyId, authDataLength,
+ authenticationData, proxyMapReply, wantMapNotify);
}
public static final class DefaultRegisterBuilder implements RegisterBuilder {
private long nonce;
private short keyId;
+ private short authDataLength;
private byte[] authenticationData;
private byte recordCount;
private List<LispMapRecord> mapRecords;
@@ -191,6 +205,12 @@
}
@Override
+ public RegisterBuilder withAuthDataLength(short authDataLength) {
+ this.authDataLength = authDataLength;
+ return this;
+ }
+
+ @Override
public RegisterBuilder withKeyId(short keyId) {
this.keyId = keyId;
return this;
@@ -210,15 +230,15 @@
@Override
public LispMapRegister build() {
- return new DefaultLispMapRegister(nonce, keyId, authenticationData,
- recordCount, mapRecords, proxyMapReply, wantMapNotify);
+ return new DefaultLispMapRegister(nonce, keyId, authDataLength,
+ authenticationData, recordCount, mapRecords, proxyMapReply, wantMapNotify);
}
}
/**
- * A private LISP message reader for MapRegister message.
+ * A LISP message reader for MapRegister message.
*/
- private static class RegisterReader implements LispMessageReader<LispMapRegister> {
+ public static final class RegisterReader implements LispMessageReader<LispMapRegister> {
private static final int PROXY_MAP_REPLY_INDEX = 3;
private static final int WANT_MAP_NOTIFY_INDEX = 0;
@@ -274,4 +294,78 @@
.build();
}
}
+
+ /**
+ * LISP map register message writer class.
+ */
+ public static class RegisterWriter implements LispMessageWriter<LispMapRegister> {
+
+ private static final int REGISTER_MSG_TYPE = 3;
+ private static final int REGISTER_SHIFT_BIT = 4;
+
+ private static final int PROXY_MAP_REPLY_SHIFT_BIT = 3;
+
+ private static final int ENABLE_BIT = 1;
+ private static final int DISABLE_BIT = 0;
+
+ private static final int UNUSED_ZERO = 0;
+
+ @Override
+ public void writeTo(ByteBuf byteBuf, LispMapRegister message) throws LispWriterException {
+
+ // specify LISP message type
+ byte msgType = (byte) (REGISTER_MSG_TYPE << REGISTER_SHIFT_BIT);
+
+ // proxy map reply flag
+ byte proxyMapReply = DISABLE_BIT;
+ if (message.isProxyMapReply()) {
+ proxyMapReply = (byte) (ENABLE_BIT << PROXY_MAP_REPLY_SHIFT_BIT);
+ }
+
+ byteBuf.writeByte(msgType + proxyMapReply);
+
+ // fill zero into reserved field
+ byteBuf.writeByte((short) UNUSED_ZERO);
+
+ // want map notify flag
+ byte wantMapNotify = DISABLE_BIT;
+ if (message.isWantMapNotify()) {
+ wantMapNotify = (byte) ENABLE_BIT;
+ }
+
+ byteBuf.writeByte(wantMapNotify);
+
+ // record count
+ byteBuf.writeByte(message.getRecordCount());
+
+ // nonce
+ byteBuf.writeLong(message.getNonce());
+
+ // keyId
+ byteBuf.writeShort(message.getKeyId());
+
+ // authentication data length in octet
+ byteBuf.writeShort(message.getAuthDataLength());
+
+ // authentication data
+ byte[] data = message.getAuthenticationData();
+ byte[] clone;
+ if (data != null) {
+ clone = data.clone();
+ Arrays.fill(clone, (byte) UNUSED_ZERO);
+ }
+
+ byteBuf.writeBytes(data);
+
+ // TODO: need to implement MAC authentication mechanism
+
+ // serialize map records
+ DefaultLispMapRecord.MapRecordWriter writer = new DefaultLispMapRecord.MapRecordWriter();
+ List<LispMapRecord> records = message.getMapRecords();
+
+ for (int i = 0; i < records.size(); i++) {
+ writer.writeTo(byteBuf, records.get(i));
+ }
+ }
+ }
}
diff --git a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispMapReply.java b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispMapReply.java
index a180a2d..220bf7e 100644
--- a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispMapReply.java
+++ b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispMapReply.java
@@ -22,10 +22,12 @@
import org.onlab.util.ByteOperator;
import org.onosproject.lisp.msg.exceptions.LispParseError;
import org.onosproject.lisp.msg.exceptions.LispReaderException;
+import org.onosproject.lisp.msg.exceptions.LispWriterException;
import java.util.List;
import static com.google.common.base.MoreObjects.toStringHelper;
+import static org.onosproject.lisp.msg.protocols.DefaultLispMapRecord.MapRecordWriter;
/**
* Default LISP map reply message class.
@@ -75,27 +77,27 @@
@Override
public boolean isProbe() {
- return this.probe;
+ return probe;
}
@Override
public boolean isEtr() {
- return this.etr;
+ return etr;
}
@Override
public boolean isSecurity() {
- return this.security;
+ return security;
}
@Override
public byte getRecordCount() {
- return this.recordCount;
+ return recordCount;
}
@Override
public long getNonce() {
- return this.nonce;
+ return nonce;
}
@Override
@@ -194,9 +196,9 @@
}
/**
- * A private LISP message reader for MapReply message.
+ * A LISP message reader for MapReply message.
*/
- private static class ReplyReader implements LispMessageReader<LispMapReply> {
+ public static final class ReplyReader implements LispMessageReader<LispMapReply> {
private static final int PROBE_INDEX = 3;
private static final int ETR_INDEX = 2;
@@ -244,4 +246,66 @@
.build();
}
}
+
+ /**
+ * A LISP message writer for MapReply message.
+ */
+ public static final class ReplyWriter implements LispMessageWriter<LispMapReply> {
+
+ private static final int REPLY_MSG_TYPE = 2;
+ private static final int REPLY_SHIFT_BIT = 4;
+
+ private static final int PROBE_FLAG_SHIFT_BIT = 3;
+ private static final int ETR_FLAG_SHIFT_BIT = 2;
+ private static final int SECURITY_FLAG_SHIFT_BIT = 1;
+
+ private static final int ENABLE_BIT = 1;
+ private static final int DISABLE_BIT = 0;
+
+ private static final int UNUSED_ZERO = 0;
+
+ @Override
+ public void writeTo(ByteBuf byteBuf, LispMapReply message) throws LispWriterException {
+
+ // specify LISP message type
+ byte msgType = (byte) (REPLY_MSG_TYPE << REPLY_SHIFT_BIT);
+
+ // probe flag
+ byte probe = DISABLE_BIT;
+ if (message.isProbe()) {
+ probe = (byte) (ENABLE_BIT << PROBE_FLAG_SHIFT_BIT);
+ }
+
+ // etr flag
+ byte etr = DISABLE_BIT;
+ if (message.isEtr()) {
+ etr = (byte) (ENABLE_BIT << ETR_FLAG_SHIFT_BIT);
+ }
+
+ // security flag
+ byte security = DISABLE_BIT;
+ if (message.isSecurity()) {
+ security = (byte) (ENABLE_BIT << SECURITY_FLAG_SHIFT_BIT);
+ }
+
+ byteBuf.writeByte((byte) (msgType + probe + etr + security));
+
+ // reserved field
+ byteBuf.writeShort((short) UNUSED_ZERO);
+
+ // record count
+ byteBuf.writeByte(message.getRecordCount());
+
+ // nonce
+ byteBuf.writeLong(message.getNonce());
+
+ // serialize map records
+ MapRecordWriter writer = new MapRecordWriter();
+ List<LispMapRecord> records = message.getMapRecords();
+
+ for (int i = 0; i < records.size(); i++) {
+ writer.writeTo(byteBuf, records.get(i));
+ }
+ }
+ }
}
diff --git a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispMapRequest.java b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispMapRequest.java
index 9c6ff92..45e85bf 100644
--- a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispMapRequest.java
+++ b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispMapRequest.java
@@ -22,11 +22,14 @@
import org.onlab.util.ByteOperator;
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 java.util.List;
import static com.google.common.base.MoreObjects.toStringHelper;
+import static org.onosproject.lisp.msg.types.LispAfiAddress.AfiAddressWriter;
+import static org.onosproject.lisp.msg.protocols.LispEidRecord.EidRecordWriter;
/**
* Default LISP map request message class.
@@ -94,47 +97,47 @@
@Override
public boolean isAuthoritative() {
- return this.authoritative;
+ return authoritative;
}
@Override
public boolean isMapDataPresent() {
- return this.mapDataPresent;
+ return mapDataPresent;
}
@Override
public boolean isProbe() {
- return this.probe;
+ return probe;
}
@Override
public boolean isSmr() {
- return this.smr;
+ return smr;
}
@Override
public boolean isPitr() {
- return this.pitr;
+ return pitr;
}
@Override
public boolean isSmrInvoked() {
- return this.smrInvoked;
+ return smrInvoked;
}
@Override
public byte getRecordCount() {
- return this.recordCount;
+ return recordCount;
}
@Override
public long getNonce() {
- return this.nonce;
+ return nonce;
}
@Override
public LispAfiAddress getSourceEid() {
- return this.sourceEid;
+ return sourceEid;
}
@Override
@@ -285,9 +288,9 @@
}
/**
- * A private LISP message reader for MapRequest message.
+ * A LISP message reader for MapRequest message.
*/
- private static class RequestReader implements LispMessageReader<LispMapRequest> {
+ public static final class RequestReader implements LispMessageReader<LispMapRequest> {
private static final int AUTHORITATIVE_INDEX = 3;
private static final int MAP_DATA_PRESENT_INDEX = 2;
@@ -365,4 +368,101 @@
.build();
}
}
+
+ /**
+ * A LISP message writer for MapRequest message.
+ */
+ public static final class RequestWriter implements LispMessageWriter<LispMapRequest> {
+
+ private static final int REQUEST_MSG_TYPE = 1;
+ private static final int REQUEST_SHIFT_BIT = 4;
+
+ private static final int AUTHORITATIVE_SHIFT_BIT = 3;
+ private static final int MAP_DATA_PRESENT_SHIFT_BIT = 2;
+ private static final int PROBE_SHIFT_BIT = 1;
+
+ private static final int PITR_SHIFT_BIT = 7;
+ private static final int SMR_INVOKED_SHIFT_BIT = 6;
+
+ private static final int ENABLE_BIT = 1;
+ private static final int DISABLE_BIT = 0;
+
+ private static final int UNUSED_ZERO = 0;
+
+ @Override
+ public void writeTo(ByteBuf byteBuf, LispMapRequest message) throws LispWriterException {
+
+ // specify LISP message type
+ byte msgType = (byte) (REQUEST_MSG_TYPE << REQUEST_SHIFT_BIT);
+
+ // authoritative flag
+ byte authoritative = DISABLE_BIT;
+ if (message.isAuthoritative()) {
+ authoritative = (byte) (ENABLE_BIT << AUTHORITATIVE_SHIFT_BIT);
+ }
+
+ // map data present flag
+ byte mapDataPresent = DISABLE_BIT;
+ if (message.isMapDataPresent()) {
+ mapDataPresent = (byte) (ENABLE_BIT << MAP_DATA_PRESENT_SHIFT_BIT);
+ }
+
+ // probe flag
+ byte probe = DISABLE_BIT;
+ if (message.isProbe()) {
+ probe = (byte) (ENABLE_BIT << PROBE_SHIFT_BIT);
+ }
+
+ // SMR flag
+ byte smr = DISABLE_BIT;
+ if (message.isSmr()) {
+ smr = (byte) ENABLE_BIT;
+ }
+
+ byteBuf.writeByte((byte) (msgType + authoritative + mapDataPresent + probe + smr));
+
+ // PITR flag bit
+ byte pitr = DISABLE_BIT;
+ if (message.isPitr()) {
+ pitr = (byte) (ENABLE_BIT << PITR_SHIFT_BIT);
+ }
+
+ // SMR invoked flag bit
+ byte smrInvoked = DISABLE_BIT;
+ if (message.isSmrInvoked()) {
+ smrInvoked = (byte) (ENABLE_BIT << SMR_INVOKED_SHIFT_BIT);
+ }
+
+ byteBuf.writeByte((byte) (pitr + smrInvoked));
+
+ // TODO: ITR RLOC count
+ byteBuf.writeByte((byte) UNUSED_ZERO);
+
+ // record count
+ byteBuf.writeByte(message.getRecordCount());
+
+ // nonce
+ byteBuf.writeLong(message.getNonce());
+
+ // Source EID AFI with Source EID address
+ AfiAddressWriter afiAddressWriter = new AfiAddressWriter();
+ afiAddressWriter.writeTo(byteBuf, message.getSourceEid());
+
+ // ITR RLOCs
+ List<LispAfiAddress> rlocs = message.getItrRlocs();
+ for (int i = 0; i < rlocs.size(); i++) {
+ afiAddressWriter.writeTo(byteBuf, rlocs.get(i));
+ }
+
+ // EID records
+ EidRecordWriter recordWriter = new EidRecordWriter();
+ List<LispEidRecord> records = message.getEids();
+
+ for (int i = 0; i < records.size(); i++) {
+ recordWriter.writeTo(byteBuf, records.get(i));
+ }
+
+ // TODO: handle Map-Reply record
+ }
+ }
}
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 1e79d19..35fe975 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
@@ -18,8 +18,11 @@
import io.netty.buffer.ByteBuf;
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 org.onosproject.lisp.msg.types.LispAfiAddress.AfiAddressWriter;
+
/**
* LISP EID record section which is part of LISP map request message.
*/
@@ -58,9 +61,9 @@
}
/**
- * A private LISP message reader for EidRecord portion.
+ * A LISP message reader for EidRecord portion.
*/
- public static class EidRecordReader implements LispMessageReader<LispEidRecord> {
+ public static final class EidRecordReader implements LispMessageReader<LispEidRecord> {
private static final int RESERVED_SKIP_LENGTH = 1;
@@ -77,4 +80,26 @@
return new LispEidRecord((byte) maskLength, prefix);
}
}
+
+ /**
+ * A LISP message writer for EidRecord portion.
+ */
+ public static final class EidRecordWriter implements LispMessageWriter<LispEidRecord> {
+
+ private static final int UNUSED_ZERO = 0;
+
+ @Override
+ public void writeTo(ByteBuf byteBuf, LispEidRecord message) throws LispWriterException {
+
+ // fill zero into reserved field
+ byteBuf.writeByte((short) UNUSED_ZERO);
+
+ // mask length
+ byteBuf.writeByte(message.getMaskLength());
+
+ // EID prefix AFI with EID prefix
+ AfiAddressWriter afiAddressWriter = new AfiAddressWriter();
+ afiAddressWriter.writeTo(byteBuf, message.getPrefix());
+ }
+ }
}
diff --git a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/LispMapNotify.java b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/LispMapNotify.java
index fd6e025..052df6a 100644
--- a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/LispMapNotify.java
+++ b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/LispMapNotify.java
@@ -78,6 +78,13 @@
short getKeyId();
/**
+ * Obtains authentication data length.
+ *
+ * @return authentication data length
+ */
+ short getAuthDataLength();
+
+ /**
* Obtains authentication data.
*
* @return authentication data
@@ -89,7 +96,7 @@
*
* @return a collection of records
*/
- List<LispMapRecord> getLispRecords();
+ List<LispMapRecord> getMapRecords();
/**
* A builder of LISP map notify message.
@@ -121,6 +128,14 @@
NotifyBuilder withKeyId(short keyId);
/**
+ * Sets authentication data length.
+ *
+ * @param authDataLength authentication data length
+ * @return NotifyBuilder object
+ */
+ NotifyBuilder withAuthDataLength(short authDataLength);
+
+ /**
* Sets authentication data.
*
* @param authenticationData authentication data
diff --git a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/LispMapRegister.java b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/LispMapRegister.java
index 16f6956..beb79dd 100644
--- a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/LispMapRegister.java
+++ b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/LispMapRegister.java
@@ -92,6 +92,13 @@
short getKeyId();
/**
+ * Obtains authentication data length.
+ *
+ * @return authentication data length
+ */
+ short getAuthDataLength();
+
+ /**
* Obtains authentication data.
*
* @return authentication data
@@ -143,6 +150,14 @@
RegisterBuilder withNonce(long nonce);
/**
+ * Sets authentication data length.
+ *
+ * @param authDataLength authentication data length
+ * @return RegisterBuilder object
+ */
+ RegisterBuilder withAuthDataLength(short authDataLength);
+
+ /**
* Sets key identifier.
*
* @param keyId key identifier
diff --git a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/LispMessageWriter.java b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/LispMessageWriter.java
new file mode 100644
index 0000000..b350ab0
--- /dev/null
+++ b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/LispMessageWriter.java
@@ -0,0 +1,34 @@
+/*
+ * 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;
+
+import io.netty.buffer.ByteBuf;
+import org.onosproject.lisp.msg.exceptions.LispWriterException;
+
+/**
+ * An interface for serializing LISP control message.
+ */
+public interface LispMessageWriter<T> {
+
+ /**
+ * Serializes LISP control message object and writes to byte buffer.
+ *
+ * @param byteBuf byte buffer
+ * @param message LISP address type instance
+ * @throws LispWriterException LISP writer exception
+ */
+ void writeTo(ByteBuf byteBuf, T message) throws LispWriterException;
+}
diff --git a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispAddressWriter.java b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispAddressWriter.java
index 299f57a..2dcea9a 100644
--- a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispAddressWriter.java
+++ b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/LispAddressWriter.java
@@ -24,11 +24,11 @@
public interface LispAddressWriter<T> {
/**
- * Writes from LISP address object and serialize to byte buffer.
+ * Serializes LISP address object and writes to byte buffer.
*
* @param byteBuf byte buffer
* @param address LISP address type instance
- * @throws LispWriterException Lisp writer exception
+ * @throws LispWriterException LISP writer exception
*/
void writeTo(ByteBuf byteBuf, T address) throws LispWriterException;