Jian Li
Committed by Thomas Vachuska

[ONOS-4718] Deserialize addresses from LISP control message class

With this commit, we try to deserilize all LispAfiAddress from
all LISP control message classes.

Change-Id: Iaf911bff90c45a70859285e426dc1649c3e6db32
Showing 17 changed files with 435 additions and 64 deletions
......@@ -19,6 +19,7 @@ import com.google.common.base.Objects;
import io.netty.buffer.ByteBuf;
import org.onlab.util.ByteOperator;
import org.onosproject.lisp.msg.exceptions.LispParseError;
import org.onosproject.lisp.msg.exceptions.LispReaderException;
import org.onosproject.lisp.msg.types.LispAfiAddress;
import static com.google.common.base.MoreObjects.toStringHelper;
......@@ -222,7 +223,7 @@ public final class DefaultLispLocatorRecord implements LispLocatorRecord {
private static final int ROUTED_INDEX = 0;
@Override
public LispLocatorRecord readFrom(ByteBuf byteBuf) throws LispParseError {
public LispLocatorRecord readFrom(ByteBuf byteBuf) throws LispParseError, LispReaderException {
// priority -> 8 bits
byte priority = (byte) byteBuf.readUnsignedByte();
......@@ -250,7 +251,7 @@ public final class DefaultLispLocatorRecord implements LispLocatorRecord {
// routed flag -> 1 bit
boolean routed = ByteOperator.getBit(flags, ROUTED_INDEX);
// TODO: de-serialize ITR-RLOC AFI and address
LispAfiAddress address = new LispAfiAddress.AfiAddressReader().readFrom(byteBuf);
return new DefaultLocatorRecordBuilder()
.withPriority(priority)
......@@ -260,6 +261,7 @@ public final class DefaultLispLocatorRecord implements LispLocatorRecord {
.withLocalLocator(localLocator)
.withRlocProbed(rlocProbed)
.withRouted(routed)
.withLocatorAfi(address)
.build();
}
}
......
......@@ -21,6 +21,7 @@ import com.google.common.collect.Lists;
import io.netty.buffer.ByteBuf;
import org.onlab.util.ImmutableByteSequence;
import org.onosproject.lisp.msg.exceptions.LispParseError;
import org.onosproject.lisp.msg.exceptions.LispReaderException;
import java.util.List;
......@@ -183,7 +184,7 @@ public final class DefaultLispMapNotify implements LispMapNotify {
private static final int RESERVED_SKIP_LENGTH = 3;
@Override
public LispMapNotify readFrom(ByteBuf byteBuf) throws LispParseError {
public LispMapNotify readFrom(ByteBuf byteBuf) throws LispParseError, LispReaderException {
if (byteBuf.readerIndex() != 0) {
return null;
......
......@@ -21,6 +21,7 @@ import com.google.common.collect.Lists;
import io.netty.buffer.ByteBuf;
import org.onlab.util.ByteOperator;
import org.onosproject.lisp.msg.exceptions.LispParseError;
import org.onosproject.lisp.msg.exceptions.LispReaderException;
import org.onosproject.lisp.msg.types.LispAfiAddress;
import java.util.List;
......@@ -225,7 +226,7 @@ public final class DefaultLispMapRecord implements LispMapRecord {
private static final int RESERVED_SKIP_LENGTH = 1;
@Override
public LispMapRecord readFrom(ByteBuf byteBuf) throws LispParseError {
public LispMapRecord readFrom(ByteBuf byteBuf) throws LispParseError, LispReaderException {
// Record TTL -> 32 bits
int recordTtl = byteBuf.readInt();
......@@ -249,7 +250,7 @@ public final class DefaultLispMapRecord implements LispMapRecord {
// Map version number -> 12 bits, we treat Rsvd field is all zero
short mapVersionNumber = (short) byteBuf.readUnsignedShort();
// TODO: need to de-serialize EID AFI address
LispAfiAddress eidPrefixAfi = new LispAfiAddress.AfiAddressReader().readFrom(byteBuf);
List<LispLocatorRecord> locators = Lists.newArrayList();
for (int i = 0; i < locatorCount; i++) {
......@@ -263,6 +264,7 @@ public final class DefaultLispMapRecord implements LispMapRecord {
.withAuthoritative(authoritative)
.withMapVersionNumber(mapVersionNumber)
.withLocators(locators)
.withEidPrefixAfi(eidPrefixAfi)
.build();
}
}
......
......@@ -22,6 +22,7 @@ import io.netty.buffer.ByteBuf;
import org.onlab.util.ByteOperator;
import org.onlab.util.ImmutableByteSequence;
import org.onosproject.lisp.msg.exceptions.LispParseError;
import org.onosproject.lisp.msg.exceptions.LispReaderException;
import java.util.List;
......@@ -110,7 +111,7 @@ public final class DefaultLispMapRegister implements LispMapRegister {
}
@Override
public List<LispMapRecord> getLispRecords() {
public List<LispMapRecord> getMapRecords() {
return ImmutableList.copyOf(mapRecords);
}
......@@ -224,7 +225,7 @@ public final class DefaultLispMapRegister implements LispMapRegister {
private static final int RESERVED_SKIP_LENGTH = 1;
@Override
public LispMapRegister readFrom(ByteBuf byteBuf) throws LispParseError {
public LispMapRegister readFrom(ByteBuf byteBuf) throws LispParseError, LispReaderException {
if (byteBuf.readerIndex() != 0) {
return null;
......
......@@ -16,9 +16,14 @@
package org.onosproject.lisp.msg.protocols;
import com.google.common.base.Objects;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import io.netty.buffer.ByteBuf;
import org.onlab.util.ByteOperator;
import org.onosproject.lisp.msg.exceptions.LispParseError;
import org.onosproject.lisp.msg.exceptions.LispReaderException;
import java.util.List;
import static com.google.common.base.MoreObjects.toStringHelper;
......@@ -32,6 +37,7 @@ public final class DefaultLispMapReply implements LispMapReply {
private final boolean probe;
private final boolean etr;
private final boolean security;
private final List<LispMapRecord> mapRecords;
/**
* A private constructor that protects object instantiation from external.
......@@ -43,12 +49,13 @@ public final class DefaultLispMapReply implements LispMapReply {
* @param security security flag
*/
private DefaultLispMapReply(long nonce, byte recordCount, boolean probe,
boolean etr, boolean security) {
boolean etr, boolean security, List<LispMapRecord> mapRecords) {
this.nonce = nonce;
this.recordCount = recordCount;
this.probe = probe;
this.etr = etr;
this.security = security;
this.mapRecords = mapRecords;
}
@Override
......@@ -92,6 +99,11 @@ public final class DefaultLispMapReply implements LispMapReply {
}
@Override
public List<LispMapRecord> getMapRecords() {
return ImmutableList.copyOf(mapRecords);
}
@Override
public String toString() {
return toStringHelper(this)
.add("type", getType())
......@@ -99,7 +111,8 @@ public final class DefaultLispMapReply implements LispMapReply {
.add("recordCount", recordCount)
.add("probe", probe)
.add("etr", etr)
.add("security", security).toString();
.add("security", security)
.add("map records", mapRecords).toString();
}
@Override
......@@ -115,12 +128,13 @@ public final class DefaultLispMapReply implements LispMapReply {
Objects.equal(recordCount, that.recordCount) &&
Objects.equal(probe, that.probe) &&
Objects.equal(etr, that.etr) &&
Objects.equal(security, that.security);
Objects.equal(security, that.security) &&
Objects.equal(mapRecords, that.mapRecords);
}
@Override
public int hashCode() {
return Objects.hashCode(nonce, recordCount, probe, etr, security);
return Objects.hashCode(nonce, recordCount, probe, etr, security, mapRecords);
}
public static final class DefaultReplyBuilder implements ReplyBuilder {
......@@ -130,6 +144,7 @@ public final class DefaultLispMapReply implements LispMapReply {
private boolean probe;
private boolean etr;
private boolean security;
private List<LispMapRecord> mapRecords;
@Override
public LispType getType() {
......@@ -167,8 +182,14 @@ public final class DefaultLispMapReply implements LispMapReply {
}
@Override
public ReplyBuilder withMapRecords(List<LispMapRecord> mapRecords) {
this.mapRecords = ImmutableList.copyOf(mapRecords);
return this;
}
@Override
public LispMapReply build() {
return new DefaultLispMapReply(nonce, recordCount, probe, etr, security);
return new DefaultLispMapReply(nonce, recordCount, probe, etr, security, mapRecords);
}
}
......@@ -183,7 +204,7 @@ public final class DefaultLispMapReply implements LispMapReply {
private static final int RESERVED_SKIP_LENGTH = 2;
@Override
public LispMapReply readFrom(ByteBuf byteBuf) throws LispParseError {
public LispMapReply readFrom(ByteBuf byteBuf) throws LispParseError, LispReaderException {
if (byteBuf.readerIndex() != 0) {
return null;
......@@ -209,7 +230,10 @@ public final class DefaultLispMapReply implements LispMapReply {
// nonce -> 64 bits
long nonce = byteBuf.readLong();
// TODO: need to de-serialize EID-RLOC records
List<LispMapRecord> mapRecords = Lists.newArrayList();
for (int i = 0; i < recordCount; i++) {
mapRecords.add(new DefaultLispMapRecord.MapRecordReader().readFrom(byteBuf));
}
return new DefaultReplyBuilder()
.withIsProbe(probe)
......
......@@ -21,6 +21,7 @@ import com.google.common.collect.Lists;
import io.netty.buffer.ByteBuf;
import org.onlab.util.ByteOperator;
import org.onosproject.lisp.msg.exceptions.LispParseError;
import org.onosproject.lisp.msg.exceptions.LispReaderException;
import org.onosproject.lisp.msg.types.LispAfiAddress;
import java.util.List;
......@@ -296,7 +297,7 @@ public final class DefaultLispMapRequest implements LispMapRequest {
private static final int SMR_INVOKED_INDEX = 6;
@Override
public LispMapRequest readFrom(ByteBuf byteBuf) throws LispParseError {
public LispMapRequest readFrom(ByteBuf byteBuf) throws LispParseError, LispReaderException {
if (byteBuf.readerIndex() != 0) {
return null;
......@@ -335,11 +336,19 @@ public final class DefaultLispMapRequest implements LispMapRequest {
// nonce -> 64 bits
long nonce = byteBuf.readLong();
// TODO: de-serialize source EID AFI and address
LispAfiAddress sourceEid = new LispAfiAddress.AfiAddressReader().readFrom(byteBuf);
// TODO: de-serialize ITR-RLOC AFI and address
// deserialize a collection of RLOC addresses
List<LispAfiAddress> itrRlocs = Lists.newArrayList();
for (int i = 0; i < irc; i++) {
itrRlocs.add(new LispAfiAddress.AfiAddressReader().readFrom(byteBuf));
}
// TODO: de-serialize EID-RECORD
// deserialize a collection of EID records
List<LispEidRecord> eidRecords = Lists.newArrayList();
for (int i = 0; i < recordCount; i++) {
eidRecords.add(new LispEidRecord.EidRecordReader().readFrom(byteBuf));
}
return new DefaultRequestBuilder()
.withIsAuthoritative(authoritative)
......@@ -350,6 +359,9 @@ public final class DefaultLispMapRequest implements LispMapRequest {
.withIsSmrInvoked(smrInvoked)
.withNonce(nonce)
.withRecordCount((byte) recordCount)
.withSourceEid(sourceEid)
.withEidRecords(eidRecords)
.withItrRlocs(itrRlocs)
.build();
}
}
......
......@@ -17,6 +17,7 @@ package org.onosproject.lisp.msg.protocols;
import io.netty.buffer.ByteBuf;
import org.onosproject.lisp.msg.exceptions.LispParseError;
import org.onosproject.lisp.msg.exceptions.LispReaderException;
import org.onosproject.lisp.msg.types.LispAfiAddress;
/**
......@@ -59,20 +60,19 @@ public final class LispEidRecord {
/**
* A private LISP message reader for EidRecord portion.
*/
private static class EidRecordReader implements LispMessageReader<LispEidRecord> {
public static class EidRecordReader implements LispMessageReader<LispEidRecord> {
private static final int RESERVED_SKIP_LENGTH = 1;
@Override
public LispEidRecord readFrom(ByteBuf byteBuf) throws LispParseError {
public LispEidRecord readFrom(ByteBuf byteBuf) throws LispParseError, LispReaderException {
// let's skip the reserved field
byteBuf.skipBytes(RESERVED_SKIP_LENGTH);
short maskLength = (short) byteBuf.readUnsignedShort();
// TODO: need to de-serialize AFI address
LispAfiAddress prefix = null;
LispAfiAddress prefix = new LispAfiAddress.AfiAddressReader().readFrom(byteBuf);
return new LispEidRecord((byte) maskLength, prefix);
}
......
......@@ -103,7 +103,7 @@ public interface LispMapRegister extends LispMessage {
*
* @return a collection of records
*/
List<LispMapRecord> getLispRecords();
List<LispMapRecord> getMapRecords();
/**
* A builder of LISP map register message.
......
......@@ -15,6 +15,8 @@
*/
package org.onosproject.lisp.msg.protocols;
import java.util.List;
/**
* LISP map reply message interface.
* <p>
......@@ -86,6 +88,13 @@ public interface LispMapReply extends LispMessage {
long getNonce();
/**
* Obtains map records.
*
* @return map records
*/
List<LispMapRecord> getMapRecords();
/**
* A builder of LISP map reply message.
*/
interface ReplyBuilder extends Builder {
......@@ -131,6 +140,14 @@ public interface LispMapReply extends LispMessage {
ReplyBuilder withNonce(long nonce);
/**
* Sets a collection of map records.
*
* @param mapRecords a collection of map records
* @return ReplyBuilder object
*/
ReplyBuilder withMapRecords(List<LispMapRecord> mapRecords);
/**
* Builds LISP map reply message.
*
* @return LISP map reply message
......
......@@ -17,6 +17,7 @@ package org.onosproject.lisp.msg.protocols;
import io.netty.buffer.ByteBuf;
import org.onosproject.lisp.msg.exceptions.LispParseError;
import org.onosproject.lisp.msg.exceptions.LispReaderException;
/**
* An interface for de-serializing LISP control message.
......@@ -30,5 +31,5 @@ public interface LispMessageReader<T> {
* @return LISP message instance
* @throws LispParseError LISP control message parse error
*/
T readFrom(ByteBuf byteBuf) throws LispParseError;
T readFrom(ByteBuf byteBuf) throws LispParseError, LispReaderException;
}
......
......@@ -15,8 +15,14 @@
*/
package org.onosproject.lisp.msg.types;
import io.netty.buffer.ByteBuf;
import org.onosproject.lisp.msg.exceptions.LispParseError;
import org.onosproject.lisp.msg.exceptions.LispReaderException;
import java.util.Objects;
import static org.onosproject.lisp.msg.types.AddressFamilyIdentifierEnum.*;
/**
* LISP Locator address typed by Address Family Identifier (AFI).
*/
......@@ -67,4 +73,45 @@ public abstract class LispAfiAddress {
}
return true;
}
public static class AfiAddressReader implements LispAddressReader<LispAfiAddress> {
@Override
public LispAfiAddress readFrom(ByteBuf byteBuf)
throws LispParseError, LispReaderException {
int index = byteBuf.readerIndex();
// AFI code -> 16 bits
short afiCode = (short) byteBuf.getUnsignedShort(index);
// handle IPv4 and IPv6 address
if (afiCode == IP.getIanaCode() ||
afiCode == IP6.getIanaCode()) {
return new LispIpAddress.IpAddressReader().readFrom(byteBuf);
}
// handle distinguished name address
if (afiCode == DISTINGUISHED_NAME.getIanaCode()) {
return new LispDistinguishedNameAddress.DistinguishedNameAddressReader().readFrom(byteBuf);
}
// handle MAC address
if (afiCode == MAC.getIanaCode()) {
return new LispMacAddress.MacAddressReader().readFrom(byteBuf);
}
// handle LCAF address
if (afiCode == LCAF.getIanaCode()) {
return new LispLcafAddress.LcafAddressReader().readFrom(byteBuf);
}
// handle autonomous system address
if (afiCode == AS.getIanaCode()) {
return new LispAsAddress.AsAddressReader().readFrom(byteBuf);
}
return null;
}
}
}
......
......@@ -60,6 +60,8 @@ public final class LispAppDataLcafAddress extends LispLcafAddress {
private LispAfiAddress address;
/**
* Initializes application data type LCAF address.
*
* @param protocol protocol number
* @param ipTos IP type of service
* @param localPortLow low-ranged local port number
......@@ -82,6 +84,35 @@ public final class LispAppDataLcafAddress extends LispLcafAddress {
}
/**
* Initializes application data type LCAF address.
*
* @param reserved1 reserved1
* @param reserved2 reserved2
* @param flag flag
* @param length length
* @param protocol protocol number
* @param ipTos IP type of service
* @param localPortLow low-ranged local port number
* @param localPortHigh high-ranged local port number
* @param remotePortLow low-ranged remote port number
* @param remotePortHigh high-ranged remote port number
* @param address address
*/
private LispAppDataLcafAddress(byte reserved1, byte reserved2, byte flag, short length,
byte protocol, int ipTos, short localPortLow,
short localPortHigh, short remotePortLow,
short remotePortHigh, LispAfiAddress address) {
super(LispCanonicalAddressFormatEnum.APPLICATION_DATA, reserved1, reserved2, flag, length);
this.protocol = protocol;
this.ipTos = ipTos;
this.localPortLow = localPortLow;
this.localPortHigh = localPortHigh;
this.remotePortLow = remotePortLow;
this.remotePortHigh = remotePortHigh;
this.address = address;
}
/**
* Obtains protocol number.
*
* @return protocol number
......@@ -182,7 +213,8 @@ public final class LispAppDataLcafAddress extends LispLcafAddress {
.toString();
}
public static final class AppDataAddressBuilder {
public static final class AppDataAddressBuilder
extends LcafAddressBuilder<AppDataAddressBuilder> {
private byte protocol;
private int ipTos;
private short localPortLow;
......@@ -197,7 +229,7 @@ public final class LispAppDataLcafAddress extends LispLcafAddress {
* @param protocol protocol number
* @return AppDataAddressBuilder object
*/
AppDataAddressBuilder withProtocol(byte protocol) {
public AppDataAddressBuilder withProtocol(byte protocol) {
this.protocol = protocol;
return this;
}
......@@ -208,7 +240,7 @@ public final class LispAppDataLcafAddress extends LispLcafAddress {
* @param ipTos IP type of service
* @return AppDataAddressBuilder object
*/
AppDataAddressBuilder withIpTos(int ipTos) {
public AppDataAddressBuilder withIpTos(int ipTos) {
this.ipTos = ipTos;
return this;
}
......@@ -219,7 +251,7 @@ public final class LispAppDataLcafAddress extends LispLcafAddress {
* @param localPortLow low-ranged local port number
* @return AppDataAddressBuilder object
*/
AppDataAddressBuilder withLocalPortLow(short localPortLow) {
public AppDataAddressBuilder withLocalPortLow(short localPortLow) {
this.localPortLow = localPortLow;
return this;
}
......@@ -230,7 +262,7 @@ public final class LispAppDataLcafAddress extends LispLcafAddress {
* @param localPortHigh high-ranged local port number
* @return AppDataAddressBuilder object
*/
AppDataAddressBuilder withLocalPortHigh(short localPortHigh) {
public AppDataAddressBuilder withLocalPortHigh(short localPortHigh) {
this.localPortHigh = localPortHigh;
return this;
}
......@@ -241,7 +273,7 @@ public final class LispAppDataLcafAddress extends LispLcafAddress {
* @param remotePortLow low-ranged remote port number
* @return AppDataAddressBuilder object
*/
AppDataAddressBuilder withRemotePortLow(short remotePortLow) {
public AppDataAddressBuilder withRemotePortLow(short remotePortLow) {
this.remotePortLow = remotePortLow;
return this;
}
......@@ -252,7 +284,7 @@ public final class LispAppDataLcafAddress extends LispLcafAddress {
* @param remotePortHigh high-ranged remote port number
* @return AppDataAddressBuilder object
*/
AppDataAddressBuilder withRemotePortHigh(short remotePortHigh) {
public AppDataAddressBuilder withRemotePortHigh(short remotePortHigh) {
this.remotePortHigh = remotePortHigh;
return this;
}
......@@ -263,7 +295,7 @@ public final class LispAppDataLcafAddress extends LispLcafAddress {
* @param address AFI address
* @return AppDataAddressBuilder object
*/
AppDataAddressBuilder withAddress(LispAfiAddress address) {
public AppDataAddressBuilder withAddress(LispAfiAddress address) {
this.address = address;
return this;
}
......@@ -273,9 +305,10 @@ public final class LispAppDataLcafAddress extends LispLcafAddress {
*
* @return LispAddDataLcafAddress instance
*/
LispAppDataLcafAddress build() {
return new LispAppDataLcafAddress(protocol, ipTos, localPortLow,
localPortHigh, remotePortLow, remotePortHigh, address);
public LispAppDataLcafAddress build() {
return new LispAppDataLcafAddress(reserved1, reserved2, flag, length,
protocol, ipTos, localPortLow, localPortHigh, remotePortLow,
remotePortHigh, address);
}
}
......@@ -288,6 +321,8 @@ public final class LispAppDataLcafAddress extends LispLcafAddress {
@Override
public LispAppDataLcafAddress readFrom(ByteBuf byteBuf) throws LispParseError, LispReaderException {
LispLcafAddress lcafAddress = LispLcafAddress.deserializeCommon(byteBuf);
byte[] ipTosByte = new byte[3];
byteBuf.readBytes(ipTosByte);
......@@ -298,9 +333,13 @@ public final class LispAppDataLcafAddress extends LispLcafAddress {
short remotePortLow = (short) byteBuf.readUnsignedShort();
short remotePortHigh = (short) byteBuf.readUnsignedShort();
LispAfiAddress address = new LispIpAddress.IpAddressReader().readFrom(byteBuf);
LispAfiAddress address = new LispAfiAddress.AfiAddressReader().readFrom(byteBuf);
return new AppDataAddressBuilder()
.withReserved1(lcafAddress.getReserved1())
.withReserved2(lcafAddress.getReserved2())
.withFlag(lcafAddress.getFlag())
.withLength(lcafAddress.getLength())
.withProtocol(protocol)
.withIpTos(ipTos)
.withLocalPortLow(localPortLow)
......
......@@ -15,9 +15,14 @@
*/
package org.onosproject.lisp.msg.types;
import io.netty.buffer.ByteBuf;
import org.onosproject.lisp.msg.exceptions.LispParseError;
import org.onosproject.lisp.msg.exceptions.LispReaderException;
import java.util.Objects;
import static com.google.common.base.MoreObjects.toStringHelper;
import static org.onosproject.lisp.msg.types.LispCanonicalAddressFormatEnum.*;
/**
* LISP Canonical Address Formatted address class.
......@@ -35,11 +40,11 @@ import static com.google.common.base.MoreObjects.toStringHelper;
*/
public class LispLcafAddress extends LispAfiAddress {
protected final LispCanonicalAddressFormatEnum lcafType;
protected final byte reserved1;
protected final byte reserved2;
protected final byte flag;
protected final byte length;
private final LispCanonicalAddressFormatEnum lcafType;
private final byte reserved1;
private final byte reserved2;
private final byte flag;
private final short length;
/**
* Initializes LCAF address.
......@@ -51,7 +56,7 @@ public class LispLcafAddress extends LispAfiAddress {
* @param length length field
*/
protected LispLcafAddress(LispCanonicalAddressFormatEnum lcafType,
byte reserved1, byte reserved2, byte flag, byte length) {
byte reserved1, byte reserved2, byte flag, short length) {
super(AddressFamilyIdentifierEnum.LCAF);
this.lcafType = lcafType;
this.reserved1 = reserved1;
......@@ -69,7 +74,7 @@ public class LispLcafAddress extends LispAfiAddress {
* @param length length field
*/
protected LispLcafAddress(LispCanonicalAddressFormatEnum lcafType,
byte reserved2, byte flag, byte length) {
byte reserved2, byte flag, short length) {
super(AddressFamilyIdentifierEnum.LCAF);
this.lcafType = lcafType;
this.reserved2 = reserved2;
......@@ -86,7 +91,7 @@ public class LispLcafAddress extends LispAfiAddress {
* @param length length field
*/
protected LispLcafAddress(LispCanonicalAddressFormatEnum lcafType,
byte reserved2, byte length) {
byte reserved2, short length) {
super(AddressFamilyIdentifierEnum.LCAF);
this.lcafType = lcafType;
this.reserved2 = reserved2;
......@@ -114,6 +119,21 @@ public class LispLcafAddress extends LispAfiAddress {
* Initializes LCAF address.
*
* @param lcafType LCAF type
* @param length length field
*/
protected LispLcafAddress(LispCanonicalAddressFormatEnum lcafType, short length) {
super(AddressFamilyIdentifierEnum.LCAF);
this.lcafType = lcafType;
this.reserved1 = 0;
this.reserved2 = 0;
this.flag = 0;
this.length = length;
}
/**
* Initializes LCAF address.
*
* @param lcafType LCAF type
*/
protected LispLcafAddress(LispCanonicalAddressFormatEnum lcafType) {
super(AddressFamilyIdentifierEnum.LCAF);
......@@ -165,10 +185,37 @@ public class LispLcafAddress extends LispAfiAddress {
*
* @return LCAF length value
*/
public byte getLength() {
public short getLength() {
return length;
}
/**
* Deserializes common fields from byte buffer.
*
* @param byteBuf byte buffer
* @return LispLcafAddress with filled common data fields
*/
public static LispLcafAddress deserializeCommon(ByteBuf byteBuf) {
// reserved1 -> 8 bits
byte reserved1 = (byte) byteBuf.readUnsignedByte();
// flags -> 8 bits
byte flag = (byte) byteBuf.readUnsignedByte();
// LCAF type -> 8 bits
byte lcafType = (byte) byteBuf.readUnsignedByte();
// reserved2 -> 8bits
byte reserved2 = (byte) byteBuf.readUnsignedByte();
// length -> 16 bits
short length = (short) byteBuf.readUnsignedShort();
return new LispLcafAddress(LispCanonicalAddressFormatEnum.valueOf(lcafType),
reserved1, reserved2, flag, length);
}
@Override
public int hashCode() {
return Objects.hash(lcafType, reserved1, reserved2, flag, length);
......@@ -201,4 +248,110 @@ public class LispLcafAddress extends LispAfiAddress {
.add("length", length)
.toString();
}
protected static class LcafAddressBuilder<T> {
protected byte reserved1;
protected byte flag;
protected byte lcafType;
protected byte reserved2;
protected short length;
/**
* Sets reserved1 value.
*
* @param reserved1 reserved1 value
* @return LcafAddressBuilder object
*/
public T withReserved1(byte reserved1) {
this.reserved1 = reserved1;
return (T) this;
}
/**
* Sets flag.
*
* @param flag flag boolean
* @return LcafAddressBuilder object
*/
public T withFlag(byte flag) {
this.flag = flag;
return (T) this;
}
/**
* Sets LCAF type.
*
* @param lcafType LCAF type
* @return LcafAddressBuilder object
*/
public T withLcafType(byte lcafType) {
this.lcafType = lcafType;
return (T) this;
}
/**
* Sets reserved2 value.
*
* @param reserved2 reserved2 value
* @return LcafAddressBuilder object
*/
public T withReserved2(byte reserved2) {
this.reserved2 = reserved2;
return (T) this;
}
/**
* Sets length value.
*
* @param length length value
* @return LcafAddressBuilder object
*/
public T withLength(short length) {
this.length = length;
return (T) this;
}
/**
* Builds LispLcafAddress object.
*
* @return LispLcafAddress instance
*/
public LispLcafAddress build() {
return new LispLcafAddress(LispCanonicalAddressFormatEnum.valueOf(lcafType),
reserved1, reserved2, flag, length);
}
}
public static class LcafAddressReader implements LispAddressReader<LispLcafAddress> {
private static final int LCAF_TYPE_FIELD_INDEX = 4;
@Override
public LispLcafAddress readFrom(ByteBuf byteBuf) throws LispParseError, LispReaderException {
int index = byteBuf.readerIndex();
// LCAF type -> 8 bits
byte lcafType = (byte) byteBuf.getUnsignedByte(index + LCAF_TYPE_FIELD_INDEX);
if (lcafType == APPLICATION_DATA.getLispCode()) {
return new LispAppDataLcafAddress.AppDataLcafAddressReader().readFrom(byteBuf);
}
if (lcafType == LIST.getLispCode()) {
return new LispListLcafAddress.ListLcafAddressReader().readFrom(byteBuf);
}
if (lcafType == SEGMENT.getLispCode()) {
return new LispSegmentLcafAddress.SegmentLcafAddressReader().readFrom(byteBuf);
}
if (lcafType == SOURCE_DEST.getLispCode()) {
return new LispSourceDestLcafAddress.SourceDestLcafAddressReader().readFrom(byteBuf);
}
return null;
}
}
}
......
......@@ -56,7 +56,7 @@ import static com.google.common.base.MoreObjects.toStringHelper;
*/
public final class LispListLcafAddress extends LispLcafAddress {
private static final byte LENGTH = 24;
private static final short LENGTH = 24;
List<LispAfiAddress> addresses;
/**
......@@ -70,6 +70,20 @@ public final class LispListLcafAddress extends LispLcafAddress {
}
/**
* Initializes list type LCAF address.
*
* @param reserved1 reserved1 field
* @param flag flag
* @param reserved2 reserved2 field
* @param addresses a set of IPv4 and IPv6 addresses
*/
public LispListLcafAddress(byte reserved1, byte reserved2, byte flag,
List<LispAfiAddress> addresses) {
super(LispCanonicalAddressFormatEnum.LIST, reserved1, flag, reserved2, LENGTH);
this.addresses = addresses;
}
/**
* Obtains a set of AFI addresses including IPv4 and IPv6.
*
* @return a set of AFI addresses
......@@ -111,11 +125,13 @@ public final class LispListLcafAddress extends LispLcafAddress {
@Override
public LispListLcafAddress readFrom(ByteBuf byteBuf) throws LispParseError, LispReaderException {
LispLcafAddress lcafAddress = LispLcafAddress.deserializeCommon(byteBuf);
LispAfiAddress ipv4 = new LispIpAddress.IpAddressReader().readFrom(byteBuf);
LispAfiAddress ipv6 = new LispIpAddress.IpAddressReader().readFrom(byteBuf);
LispAfiAddress ipv4 = new LispAfiAddress.AfiAddressReader().readFrom(byteBuf);
LispAfiAddress ipv6 = new LispAfiAddress.AfiAddressReader().readFrom(byteBuf);
return new LispListLcafAddress(ImmutableList.of(ipv4, ipv6));
return new LispListLcafAddress(lcafAddress.getReserved1(), lcafAddress.getReserved2(),
lcafAddress.getFlag(), ImmutableList.of(ipv4, ipv6));
}
}
}
......
......@@ -63,6 +63,23 @@ public final class LispSegmentLcafAddress extends LispLcafAddress {
}
/**
* Initializes segment type LCAF address.
*
* @param reserved1 reserved1
* @param idMaskLength ID mask length
* @param flag flag
* @param length length
* @param instanceId instance id
* @param address address
*/
private LispSegmentLcafAddress(byte reserved1, byte idMaskLength, byte flag, short length,
int instanceId, LispAfiAddress address) {
super(LispCanonicalAddressFormatEnum.SEGMENT, reserved1, idMaskLength, flag, length);
this.address = address;
this.instanceId = instanceId;
}
/**
* Obtains address.
*
* @return address
......@@ -86,12 +103,12 @@ public final class LispSegmentLcafAddress extends LispLcafAddress {
* @return id mask length
*/
public byte getIdMaskLength() {
return reserved2;
return getReserved2();
}
@Override
public int hashCode() {
return Objects.hash(address, instanceId, reserved2);
return Objects.hash(address, instanceId, getReserved2());
}
@Override
......@@ -104,7 +121,7 @@ public final class LispSegmentLcafAddress extends LispLcafAddress {
final LispSegmentLcafAddress other = (LispSegmentLcafAddress) obj;
return Objects.equals(this.address, other.address) &&
Objects.equals(this.instanceId, other.instanceId) &&
Objects.equals(this.reserved2, other.reserved2);
Objects.equals(this.getReserved2(), other.getReserved2());
}
return false;
}
......@@ -114,11 +131,12 @@ public final class LispSegmentLcafAddress extends LispLcafAddress {
return toStringHelper(this)
.add("address", address)
.add("instanceId", instanceId)
.add("idMaskLength", reserved2)
.add("idMaskLength", getReserved2())
.toString();
}
public static final class SegmentAddressBuilder {
public static final class SegmentAddressBuilder
extends LcafAddressBuilder<SegmentAddressBuilder> {
private byte idMaskLength;
private LispAfiAddress address;
private int instanceId;
......@@ -162,7 +180,8 @@ public final class LispSegmentLcafAddress extends LispLcafAddress {
* @return LispSegmentLcafAddress instance
*/
public LispSegmentLcafAddress build() {
return new LispSegmentLcafAddress(idMaskLength, instanceId, address);
return new LispSegmentLcafAddress(reserved1, idMaskLength, flag,
length, instanceId, address);
}
}
......@@ -176,12 +195,17 @@ public final class LispSegmentLcafAddress extends LispLcafAddress {
public LispSegmentLcafAddress readFrom(ByteBuf byteBuf)
throws LispParseError, LispReaderException {
// TODO: need to de-serialize IdMaskLength
byte idMaskLength = 0x01;
LispLcafAddress lcafAddress = LispLcafAddress.deserializeCommon(byteBuf);
byte idMaskLength = lcafAddress.getReserved2();
int instanceId = (int) byteBuf.readUnsignedInt();
LispAfiAddress address = new LispIpAddress.IpAddressReader().readFrom(byteBuf);
LispAfiAddress address = new LispAfiAddress.AfiAddressReader().readFrom(byteBuf);
return new SegmentAddressBuilder()
.withReserved1(lcafAddress.getReserved1())
.withFlag(lcafAddress.getFlag())
.withLength(lcafAddress.getLength())
.withIdMaskLength(idMaskLength)
.withInstanceId(instanceId)
.withAddress(address)
......
......@@ -76,6 +76,31 @@ public final class LispSourceDestLcafAddress extends LispLcafAddress {
}
/**
* Initializes source/dest key type LCAF address.
*
* @param reserved1 reserved1
* @param reserved2 reserved2
* @param flag flag
* @param length length
* @param reserved reserved
* @param srcMaskLength source mask length
* @param dstMaskLength destination mask length
* @param srcPrefix source address prefix
* @param dstPrefix destination address prefix
*/
private LispSourceDestLcafAddress(byte reserved1, byte reserved2, byte flag, short length,
short reserved, byte srcMaskLength,
byte dstMaskLength, LispAfiAddress srcPrefix,
LispAfiAddress dstPrefix) {
super(LispCanonicalAddressFormatEnum.SOURCE_DEST, reserved1, reserved2, flag, length);
this.reserved = reserved;
this.srcMaskLength = srcMaskLength;
this.dstMaskLength = dstMaskLength;
this.srcPrefix = srcPrefix;
this.dstPrefix = dstPrefix;
}
/**
* Obtains source address prefix.
*
* @return source address prefix
......@@ -153,7 +178,8 @@ public final class LispSourceDestLcafAddress extends LispLcafAddress {
.toString();
}
public static final class SourceDestAddressBuilder {
public static final class SourceDestAddressBuilder
extends LcafAddressBuilder<SourceDestAddressBuilder> {
private LispAfiAddress srcPrefix;
private LispAfiAddress dstPrefix;
private byte srcMaskLength;
......@@ -221,8 +247,8 @@ public final class LispSourceDestLcafAddress extends LispLcafAddress {
* @return LispSourceDestLcafAddress instance
*/
public LispSourceDestLcafAddress build() {
return new LispSourceDestLcafAddress(reserved, srcMaskLength,
dstMaskLength, srcPrefix, dstPrefix);
return new LispSourceDestLcafAddress(reserved1, reserved2, flag, length,
reserved, srcMaskLength, dstMaskLength, srcPrefix, dstPrefix);
}
}
......@@ -235,14 +261,20 @@ public final class LispSourceDestLcafAddress extends LispLcafAddress {
@Override
public LispSourceDestLcafAddress readFrom(ByteBuf byteBuf) throws LispParseError, LispReaderException {
LispLcafAddress lcafAddress = LispLcafAddress.deserializeCommon(byteBuf);
short reserved = byteBuf.readShort();
byte srcMaskLength = (byte) byteBuf.readUnsignedByte();
byte dstMaskLength = (byte) byteBuf.readUnsignedByte();
LispAfiAddress srcPrefix = new LispIpAddress.IpAddressReader().readFrom(byteBuf);
LispAfiAddress dstPrefix = new LispIpAddress.IpAddressReader().readFrom(byteBuf);
LispAfiAddress srcPrefix = new LispAfiAddress.AfiAddressReader().readFrom(byteBuf);
LispAfiAddress dstPrefix = new LispAfiAddress.AfiAddressReader().readFrom(byteBuf);
return new SourceDestAddressBuilder()
.withReserved1(lcafAddress.getReserved1())
.withReserved2(lcafAddress.getReserved2())
.withFlag(lcafAddress.getFlag())
.withLength(lcafAddress.getLength())
.withReserved(reserved)
.withSrcMaskLength(srcMaskLength)
.withDstMaskLength(dstMaskLength)
......
......@@ -57,6 +57,6 @@ public class LispLcafAddressTest {
assertThat(lcafAddress.getReserved1(), is((byte) 0x01));
assertThat(lcafAddress.getReserved2(), is((byte) 0x01));
assertThat(lcafAddress.getFlag(), is((byte) 0x01));
assertThat(lcafAddress.getLength(), is((byte) 0x01));
assertThat(lcafAddress.getLength(), is((short) 1));
}
}
......