mirror of
https://github.com/opennetworkinglab/onos.git
synced 2026-05-06 04:36:17 +02:00
[ONOS-5480] The implementation of LISP Encapsulated Control Message (ECM).
Changes 1. ECM message is added. 2. Default ECM message is added with builder, reader, and writer. 3. Implented other messages writeTo() methods. Change-Id: I3ed6f66a7ec7a318f30596d64c35ac15365c8c4c
This commit is contained in:
parent
084caafa4f
commit
ca814bfbee
@ -0,0 +1,271 @@
|
||||
/*
|
||||
* 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 com.google.common.base.Objects;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import org.onlab.packet.Data;
|
||||
import org.onlab.packet.DeserializationException;
|
||||
import org.onlab.packet.IP;
|
||||
import org.onlab.packet.UDP;
|
||||
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 static com.google.common.base.MoreObjects.toStringHelper;
|
||||
import static org.onosproject.lisp.msg.protocols.LispType.LISP_ENCAPSULATED_CONTROL;
|
||||
|
||||
/**
|
||||
* Default LISP Encapsulated Control message class.
|
||||
*/
|
||||
public final class DefaultLispEncapsulatedControl
|
||||
implements LispEncapsulatedControl {
|
||||
|
||||
private final boolean isSecurity;
|
||||
private final IP innerIpHeader;
|
||||
private final UDP innerUdp;
|
||||
private final LispMessage innerMessage;
|
||||
|
||||
static final EcmWriter WRITER;
|
||||
static {
|
||||
WRITER = new EcmWriter();
|
||||
}
|
||||
|
||||
/**
|
||||
* A private constructor that protects object instantiation from external.
|
||||
*
|
||||
* @param isSecurity a security flag
|
||||
* @param innerIpHeader a inner IP Header
|
||||
* @param innerUdp a inner UDP Header
|
||||
* @param innerMessage a inner LISP control message
|
||||
*/
|
||||
private DefaultLispEncapsulatedControl(boolean isSecurity, IP innerIpHeader,
|
||||
UDP innerUdp, LispMessage innerMessage) {
|
||||
this.isSecurity = isSecurity;
|
||||
this.innerIpHeader = innerIpHeader;
|
||||
this.innerUdp = innerUdp;
|
||||
this.innerMessage = innerMessage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LispType getType() {
|
||||
return LISP_ENCAPSULATED_CONTROL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(ByteBuf byteBuf) throws LispWriterException {
|
||||
WRITER.writeTo(byteBuf, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder createBuilder() {
|
||||
return new DefaultEcmBuilder();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSecurity() {
|
||||
return isSecurity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IP innerIpHeader() {
|
||||
return innerIpHeader;
|
||||
}
|
||||
|
||||
public UDP innerUdp() {
|
||||
return innerUdp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LispMessage getControlMessage() {
|
||||
return innerMessage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toStringHelper(this)
|
||||
.add("type", getType())
|
||||
.add("isSecurity", isSecurity)
|
||||
.add("inner IP header", innerIpHeader)
|
||||
.add("inner UDP header", innerUdp)
|
||||
.add("inner lisp Message", innerMessage)
|
||||
.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DefaultLispEncapsulatedControl that = (DefaultLispEncapsulatedControl) o;
|
||||
return Objects.equal(isSecurity, that.isSecurity) &&
|
||||
Objects.equal(innerIpHeader, that.innerIpHeader) &&
|
||||
Objects.equal(innerUdp, that.innerUdp) &&
|
||||
Objects.equal(innerMessage, that.innerMessage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(isSecurity, innerIpHeader, innerUdp, innerMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* LISP ECM Builder implementation.
|
||||
*/
|
||||
public static final class DefaultEcmBuilder implements EcmBuilder {
|
||||
|
||||
private boolean isSecurity;
|
||||
private IP innerIpHeader;
|
||||
private UDP innerUdpHeader;
|
||||
private LispMessage innerMessage;
|
||||
|
||||
@Override
|
||||
public LispType getType() {
|
||||
return LispType.LISP_ENCAPSULATED_CONTROL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EcmBuilder isSecurity(boolean security) {
|
||||
this.isSecurity = security;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EcmBuilder innerIpHeader(IP innerIpHeader) {
|
||||
this.innerIpHeader = innerIpHeader;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EcmBuilder innerUdpHeader(UDP innerUdpHeader) {
|
||||
this.innerUdpHeader = innerUdpHeader;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EcmBuilder innerLispMessage(LispMessage msg) {
|
||||
this.innerMessage = msg;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LispEncapsulatedControl build() {
|
||||
return new DefaultLispEncapsulatedControl(isSecurity, innerIpHeader,
|
||||
innerUdpHeader, innerMessage);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A LISP message reader for ECM.
|
||||
*/
|
||||
public static final class EcmReader
|
||||
implements LispMessageReader<LispEncapsulatedControl> {
|
||||
|
||||
private static final int SECURITY_INDEX = 3;
|
||||
private static final int RESERVED_SKIP_LENGTH = 3;
|
||||
private static final int UDP_HEADER_LENGTH = 8;
|
||||
private static final short HEADER_LENGTH_MASK = 0xf;
|
||||
|
||||
@Override
|
||||
public LispEncapsulatedControl readFrom(ByteBuf byteBuf) throws
|
||||
LispParseError, LispReaderException, DeserializationException {
|
||||
|
||||
if (byteBuf.readerIndex() != 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
boolean securityFlag = ByteOperator.getBit(byteBuf.readByte(),
|
||||
SECURITY_INDEX);
|
||||
// let's skip the reserved field
|
||||
byteBuf.skipBytes(RESERVED_SKIP_LENGTH);
|
||||
|
||||
short totalLength = byteBuf.getShort(byteBuf.readerIndex() + 2);
|
||||
|
||||
byte[] ipHeaderByte = new byte[totalLength];
|
||||
byteBuf.getBytes(byteBuf.readerIndex(), ipHeaderByte, 0, totalLength);
|
||||
|
||||
IP innerIpHeader = IP.deserializer().deserialize(ipHeaderByte, 0,
|
||||
totalLength);
|
||||
|
||||
UDP innerUdp = (UDP) innerIpHeader.getPayload();
|
||||
Data data = (Data) innerUdp.getPayload();
|
||||
ByteBuf msgBuffer = Unpooled.buffer();
|
||||
msgBuffer.writeBytes(data.getData());
|
||||
|
||||
LispMessageReader reader = LispMessageReaderFactory.getReader(msgBuffer);
|
||||
LispMessage innerMessage = (LispMessage) reader.readFrom(msgBuffer);
|
||||
|
||||
return new DefaultLispEncapsulatedControl(securityFlag, innerIpHeader,
|
||||
innerUdp, innerMessage);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* LISP ECM writer class.
|
||||
*/
|
||||
public static class EcmWriter
|
||||
implements LispMessageWriter<LispEncapsulatedControl> {
|
||||
|
||||
private static final short ECM_MSG_CODE =
|
||||
LispType.LISP_ENCAPSULATED_CONTROL.getTypeCode();
|
||||
private static final int TYPE_SHIFT_BIT = 4;
|
||||
|
||||
private static final int SECURITY_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, LispEncapsulatedControl message)
|
||||
throws LispWriterException {
|
||||
|
||||
// specify LISP message type
|
||||
byte msgType = (byte) (ECM_MSG_CODE << TYPE_SHIFT_BIT);
|
||||
|
||||
byte security = DISABLE_BIT;
|
||||
if (message.isSecurity()) {
|
||||
security = (byte) (ENABLE_BIT << SECURITY_SHIFT_BIT);
|
||||
}
|
||||
|
||||
byteBuf.writeByte(msgType + security);
|
||||
|
||||
// fill zero into reserved field
|
||||
byteBuf.writeByte((byte) UNUSED_ZERO);
|
||||
byteBuf.writeByte((byte) UNUSED_ZERO);
|
||||
byteBuf.writeByte((byte) UNUSED_ZERO);
|
||||
|
||||
ByteBuf buffer = Unpooled.buffer();
|
||||
message.getControlMessage().writeTo(buffer);
|
||||
byte[] dataBytes = new byte[buffer.writerIndex()];
|
||||
buffer.getBytes(0, dataBytes, 0, buffer.writerIndex());
|
||||
|
||||
message.innerUdp().setPayload(new Data(dataBytes));
|
||||
message.innerIpHeader().setPayload(message.innerUdp());
|
||||
|
||||
byteBuf.writeBytes(message.innerIpHeader().serialize());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -82,8 +82,8 @@ public class DefaultLispInfo implements LispInfo {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(ByteBuf byteBuf) {
|
||||
// TODO: serialize LispMapRegister message
|
||||
public void writeTo(ByteBuf byteBuf) throws LispWriterException {
|
||||
serialize(byteBuf, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -41,6 +41,11 @@ public final class DefaultLispLocatorRecord implements LispLocatorRecord {
|
||||
private final boolean routed;
|
||||
private final LispAfiAddress locatorAfi;
|
||||
|
||||
static final LocatorRecordWriter WRITER;
|
||||
static {
|
||||
WRITER = new LocatorRecordWriter();
|
||||
}
|
||||
|
||||
/**
|
||||
* A private constructor that protects object instantiation from external.
|
||||
*
|
||||
@ -107,8 +112,8 @@ public final class DefaultLispLocatorRecord implements LispLocatorRecord {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(ByteBuf byteBuf) {
|
||||
|
||||
public void writeTo(ByteBuf byteBuf) throws LispWriterException {
|
||||
WRITER.writeTo(byteBuf, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -41,6 +41,11 @@ public final class DefaultLispMapNotify implements LispMapNotify {
|
||||
private final byte[] authenticationData;
|
||||
private final List<LispMapRecord> mapRecords;
|
||||
|
||||
static final NotifyWriter WRITER;
|
||||
static {
|
||||
WRITER = new NotifyWriter();
|
||||
}
|
||||
|
||||
/**
|
||||
* A private constructor that protects object instantiation from external.
|
||||
*
|
||||
@ -64,8 +69,8 @@ public final class DefaultLispMapNotify implements LispMapNotify {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(ByteBuf byteBuf) {
|
||||
// TODO: serialize LispMapRegister message
|
||||
public void writeTo(ByteBuf byteBuf) throws LispWriterException {
|
||||
WRITER.writeTo(byteBuf, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -45,6 +45,11 @@ public final class DefaultLispMapRecord implements LispMapRecord {
|
||||
private final LispAfiAddress eidPrefixAfi;
|
||||
private final List<LispLocatorRecord> locatorRecords;
|
||||
|
||||
static final MapRecordWriter WRITER;
|
||||
static {
|
||||
WRITER = new MapRecordWriter();
|
||||
}
|
||||
|
||||
/**
|
||||
* A private constructor that protects object instantiation from external.
|
||||
*
|
||||
@ -109,8 +114,8 @@ public final class DefaultLispMapRecord implements LispMapRecord {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(ByteBuf byteBuf) {
|
||||
|
||||
public void writeTo(ByteBuf byteBuf) throws LispWriterException {
|
||||
WRITER.writeTo(byteBuf, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -46,6 +46,11 @@ public final class DefaultLispMapRegister implements LispMapRegister {
|
||||
private final boolean proxyMapReply;
|
||||
private final boolean wantMapNotify;
|
||||
|
||||
static final RegisterWriter WRITER;
|
||||
static {
|
||||
WRITER = new RegisterWriter();
|
||||
}
|
||||
|
||||
/**
|
||||
* A private constructor that protects object instantiation from external.
|
||||
*
|
||||
@ -75,8 +80,8 @@ public final class DefaultLispMapRegister implements LispMapRegister {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(ByteBuf byteBuf) {
|
||||
// TODO: serialize LispMapRegister message
|
||||
public void writeTo(ByteBuf byteBuf) throws LispWriterException {
|
||||
WRITER.writeTo(byteBuf, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -40,6 +40,11 @@ public final class DefaultLispMapReply implements LispMapReply {
|
||||
private final boolean security;
|
||||
private final List<LispMapRecord> mapRecords;
|
||||
|
||||
static final ReplyWriter WRITER;
|
||||
static {
|
||||
WRITER = new ReplyWriter();
|
||||
}
|
||||
|
||||
/**
|
||||
* A private constructor that protects object instantiation from external.
|
||||
*
|
||||
@ -63,8 +68,8 @@ public final class DefaultLispMapReply implements LispMapReply {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(ByteBuf byteBuf) {
|
||||
// TODO: serialize LispMapReply message
|
||||
public void writeTo(ByteBuf byteBuf) throws LispWriterException {
|
||||
WRITER.writeTo(byteBuf, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -49,6 +49,11 @@ public final class DefaultLispMapRequest implements LispMapRequest {
|
||||
private final boolean pitr;
|
||||
private final boolean smrInvoked;
|
||||
|
||||
static final RequestWriter WRITER;
|
||||
static {
|
||||
WRITER = new RequestWriter();
|
||||
}
|
||||
|
||||
/**
|
||||
* A private constructor that protects object instantiation from external.
|
||||
*
|
||||
@ -85,8 +90,8 @@ public final class DefaultLispMapRequest implements LispMapRequest {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(ByteBuf byteBuf) {
|
||||
// TODO: serialize LispMapRequest message
|
||||
public void writeTo(ByteBuf byteBuf) throws LispWriterException {
|
||||
WRITER.writeTo(byteBuf, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -0,0 +1,132 @@
|
||||
/*
|
||||
* 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 org.onlab.packet.IP;
|
||||
import org.onlab.packet.UDP;
|
||||
|
||||
/**
|
||||
* LISP Encapsulated Control Message (ECM) interface.
|
||||
* <p>
|
||||
* LISP ECM format is defined in RFC6830.
|
||||
* https://tools.ietf.org/html/rfc6830#section-6.1.8
|
||||
*
|
||||
* <pre>
|
||||
* {@literal
|
||||
* 0 1 2 3
|
||||
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* / | IPv4 or IPv6 Header |
|
||||
* OH | (uses RLOC addresses) |
|
||||
* \ | |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* / | Source Port = xxxx | Dest Port = 4342 |
|
||||
* UDP +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* \ | UDP Length | UDP Checksum |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* LH |Type=8 |S| Reserved |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* / | IPv4 or IPv6 Header |
|
||||
* IH | (uses RLOC or EID addresses) |
|
||||
* \ | |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* / | Source Port = xxxx | Dest Port = yyyy |
|
||||
* UDP +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* \ | UDP Length | UDP Checksum |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* LCM | LISP Control Message |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* }</pre>
|
||||
*/
|
||||
public interface LispEncapsulatedControl extends LispMessage {
|
||||
|
||||
/**
|
||||
* Obtains security flag.
|
||||
* If this bit is set, the 'Reserved' field will have the authentication data.
|
||||
*
|
||||
* @return security flag
|
||||
*/
|
||||
boolean isSecurity();
|
||||
|
||||
/**
|
||||
* Obtains inner IP header.
|
||||
*
|
||||
* @return inner IP header
|
||||
*/
|
||||
IP innerIpHeader();
|
||||
|
||||
/**
|
||||
* Obtains inner LISP UDP header.
|
||||
*
|
||||
* @return inner LISP UDP header
|
||||
*/
|
||||
UDP innerUdp();
|
||||
|
||||
/**
|
||||
* Obtains inner LISP control message.
|
||||
* The format can be one of other LISP messages.
|
||||
*
|
||||
* @return Inner lisp control messages
|
||||
*/
|
||||
|
||||
LispMessage getControlMessage();
|
||||
|
||||
/**
|
||||
* A builder of LISP map request message.
|
||||
*/
|
||||
interface EcmBuilder extends Builder {
|
||||
|
||||
/**
|
||||
* Sets security flag.
|
||||
*
|
||||
* @param security security flag
|
||||
* @return ECMBuilder object
|
||||
*/
|
||||
EcmBuilder isSecurity(boolean security);
|
||||
|
||||
/**
|
||||
* Sets inner IP header.
|
||||
*
|
||||
* @param innerIpHeader inner IP header in IPv4 or IPv6
|
||||
* @return ECMBuilder object
|
||||
*/
|
||||
EcmBuilder innerIpHeader(IP innerIpHeader);
|
||||
|
||||
/**
|
||||
* Sets inner UDP header.
|
||||
*
|
||||
* @param innerUdpHeader inner UDP packet
|
||||
* @return ECMBuilder object
|
||||
*/
|
||||
EcmBuilder innerUdpHeader(UDP innerUdpHeader);
|
||||
|
||||
/**
|
||||
* Sets inner LISP control message.
|
||||
*
|
||||
* @param msg the inner lisp message
|
||||
* @return ECMBuilder object
|
||||
*/
|
||||
EcmBuilder innerLispMessage(LispMessage msg);
|
||||
|
||||
/**
|
||||
* Builds LISP ECM message.
|
||||
*
|
||||
* @return LISP ECM message
|
||||
*/
|
||||
LispEncapsulatedControl build();
|
||||
}
|
||||
}
|
||||
@ -16,6 +16,7 @@
|
||||
package org.onosproject.lisp.msg.protocols;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import org.onosproject.lisp.msg.exceptions.LispWriterException;
|
||||
import org.onosproject.lisp.msg.types.LispAfiAddress;
|
||||
|
||||
/**
|
||||
@ -84,7 +85,7 @@ public interface LispLocatorRecord {
|
||||
*
|
||||
* @param byteBuf byte buffer
|
||||
*/
|
||||
void writeTo(ByteBuf byteBuf);
|
||||
void writeTo(ByteBuf byteBuf) throws LispWriterException;
|
||||
|
||||
/**
|
||||
* A builder of LISP locator record.
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
package org.onosproject.lisp.msg.protocols;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import org.onosproject.lisp.msg.exceptions.LispWriterException;
|
||||
import org.onosproject.lisp.msg.types.LispAfiAddress;
|
||||
|
||||
import java.util.List;
|
||||
@ -86,7 +87,7 @@ public interface LispMapRecord {
|
||||
*
|
||||
* @param byteBuf byte buffer
|
||||
*/
|
||||
void writeTo(ByteBuf byteBuf);
|
||||
void writeTo(ByteBuf byteBuf) throws LispWriterException;
|
||||
|
||||
/**
|
||||
* A builder of LISP map record.
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
package org.onosproject.lisp.msg.protocols;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import org.onosproject.lisp.msg.exceptions.LispWriterException;
|
||||
|
||||
/**
|
||||
* LISP message interface.
|
||||
@ -33,8 +34,10 @@ public interface LispMessage {
|
||||
* Writes LISP message object into communication channel.
|
||||
*
|
||||
* @param byteBuf byte buffer
|
||||
* @throws LispWriterException if the writing request is failed due to
|
||||
* the lisp object cannot be written to the buffer.
|
||||
*/
|
||||
void writeTo(ByteBuf byteBuf);
|
||||
void writeTo(ByteBuf byteBuf) throws LispWriterException;
|
||||
|
||||
/**
|
||||
* Generates LISP message builder.
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
package org.onosproject.lisp.msg.protocols;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import org.onlab.packet.DeserializationException;
|
||||
import org.onosproject.lisp.msg.exceptions.LispParseError;
|
||||
import org.onosproject.lisp.msg.exceptions.LispReaderException;
|
||||
|
||||
@ -29,7 +30,14 @@ public interface LispMessageReader<T> {
|
||||
*
|
||||
* @param byteBuf byte buffer
|
||||
* @return LISP message instance
|
||||
* @throws LispParseError LISP control message parse error
|
||||
* @throws LispParseError if the requested message cannot be parsed
|
||||
* as a LISP object
|
||||
* @throws LispReaderException if LISP message reader cannot process
|
||||
* the received message
|
||||
* @throws DeserializationException if an inner IP header (IPv4 or IPv6)
|
||||
* cannot be deserialized due to the message not match
|
||||
* with IP header format
|
||||
*/
|
||||
T readFrom(ByteBuf byteBuf) throws LispParseError, LispReaderException;
|
||||
T readFrom(ByteBuf byteBuf) throws LispParseError, LispReaderException,
|
||||
DeserializationException;
|
||||
}
|
||||
|
||||
@ -21,6 +21,7 @@ import static org.onosproject.lisp.msg.protocols.DefaultLispMapReply.ReplyReader
|
||||
import static org.onosproject.lisp.msg.protocols.DefaultLispMapNotify.NotifyReader;
|
||||
import static org.onosproject.lisp.msg.protocols.DefaultLispMapRegister.RegisterReader;
|
||||
import static org.onosproject.lisp.msg.protocols.DefaultLispMapRequest.RequestReader;
|
||||
import static org.onosproject.lisp.msg.protocols.DefaultLispEncapsulatedControl.EcmReader;
|
||||
|
||||
/**
|
||||
* A factory class which helps to instantiate LISP reader class.
|
||||
@ -39,22 +40,31 @@ public final class LispMessageReaderFactory {
|
||||
public static LispMessageReader getReader(ByteBuf buffer) {
|
||||
LispMessageReader reader;
|
||||
|
||||
int type = buffer.getByte(0) >> TYPE_SHIFT_BIT;
|
||||
LispType type = LispType.valueOf(
|
||||
(short) (buffer.getByte(0) >> TYPE_SHIFT_BIT));
|
||||
|
||||
switch (type) {
|
||||
case 1:
|
||||
case LISP_MAP_REQUEST:
|
||||
reader = new RequestReader();
|
||||
break;
|
||||
case 2:
|
||||
case LISP_MAP_REPLY:
|
||||
reader = new ReplyReader();
|
||||
break;
|
||||
case 3:
|
||||
case LISP_MAP_REGISTER:
|
||||
reader = new RegisterReader();
|
||||
break;
|
||||
case 4:
|
||||
case LISP_MAP_NOTIFY:
|
||||
reader = new NotifyReader();
|
||||
break;
|
||||
case LISP_ENCAPSULATED_CONTROL:
|
||||
reader = new EcmReader();
|
||||
break;
|
||||
case UNKNOWN:
|
||||
throw new IllegalArgumentException("Unknown message type: "
|
||||
+ type);
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown LISP message type: " + type);
|
||||
throw new IllegalArgumentException("Undefined message type: "
|
||||
+ type);
|
||||
}
|
||||
return reader;
|
||||
}
|
||||
|
||||
@ -23,12 +23,26 @@ package org.onosproject.lisp.msg.protocols;
|
||||
*/
|
||||
public enum LispType {
|
||||
|
||||
LISP_MAP_REQUEST(1), // LISP Map-Request Message
|
||||
LISP_MAP_REPLY(2), // LISP Map-Reply Message
|
||||
LISP_MAP_REGISTER(3), // LISP Map-Register Message
|
||||
LISP_MAP_NOTIFY(4), // LISP Map-Notify Message
|
||||
LISP_INFO(7), // LISP Info-Request or Info-Reply Message
|
||||
UNKNOWN(-1); // Other Enums for internal use
|
||||
/** LISP Map-Request Message. */
|
||||
LISP_MAP_REQUEST(1),
|
||||
|
||||
/** LISP Map-Reply Message. */
|
||||
LISP_MAP_REPLY(2),
|
||||
|
||||
/** LISP Map-Register Message. */
|
||||
LISP_MAP_REGISTER(3),
|
||||
|
||||
/** LISP Map-Notify Message. */
|
||||
LISP_MAP_NOTIFY(4),
|
||||
|
||||
/** LISP Info-Request or Info-Reply Message. */
|
||||
LISP_INFO(7),
|
||||
|
||||
/** LISP Encapsulated Control Message. */
|
||||
LISP_ENCAPSULATED_CONTROL(8),
|
||||
|
||||
/** Unknown types for internal use. */
|
||||
UNKNOWN(-1);
|
||||
|
||||
private final short type;
|
||||
|
||||
|
||||
@ -0,0 +1,212 @@
|
||||
/*
|
||||
* 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 com.google.common.collect.ImmutableList;
|
||||
import com.google.common.testing.EqualsTester;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.onlab.packet.DeserializationException;
|
||||
import org.onlab.packet.IP;
|
||||
import org.onlab.packet.IPv4;
|
||||
import org.onlab.packet.IpAddress;
|
||||
import org.onlab.packet.UDP;
|
||||
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.LispIpv4Address;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
|
||||
/**
|
||||
* Unit tests for DefaultLispEncapsulatedControl class.
|
||||
*/
|
||||
public final class DefaultLispEncapsulatedControlTest {
|
||||
|
||||
private static final String ECM1_SRC_IP = "192.168.1.1";
|
||||
private static final String ECM1_DST_IP = "192.168.1.2";
|
||||
private static final String ECM2_SRC_IP = "192.168.2.1";
|
||||
private static final String ECM2_DST_IP = "192.168.2.2";
|
||||
private static final String RECORD_EID = "1.1.1.1";
|
||||
|
||||
private LispEncapsulatedControl ecm1;
|
||||
private LispEncapsulatedControl sameAsEcm1;
|
||||
private LispEncapsulatedControl ecm2;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
|
||||
//Creates ecm1
|
||||
LispEncapsulatedControl.EcmBuilder builder1 =
|
||||
new DefaultLispEncapsulatedControl.DefaultEcmBuilder();
|
||||
|
||||
IP innerIp1 = new IPv4().setSourceAddress(ECM1_SRC_IP)
|
||||
.setDestinationAddress(ECM1_DST_IP)
|
||||
.setProtocol(IPv4.PROTOCOL_UDP).setVersion((byte) (4 & 0xf));
|
||||
UDP innerUdp1 = new UDP().setSourcePort(1)
|
||||
.setDestinationPort(2);
|
||||
|
||||
LispMapRegister.RegisterBuilder msgBuilder = new
|
||||
DefaultLispMapRegister.DefaultRegisterBuilder();
|
||||
|
||||
List<LispMapRecord> records1 = ImmutableList.of(getMapRecord(),
|
||||
getMapRecord());
|
||||
|
||||
LispMapRegister innerMsg1 = msgBuilder.withIsProxyMapReply(true)
|
||||
.withIsWantMapNotify(false)
|
||||
.withKeyId((short) 1)
|
||||
.withNonce(1L)
|
||||
.withMapRecords(records1)
|
||||
.build();
|
||||
|
||||
ecm1 = builder1.isSecurity(false)
|
||||
.innerIpHeader(innerIp1)
|
||||
.innerUdpHeader(innerUdp1)
|
||||
.innerLispMessage(innerMsg1)
|
||||
.build();
|
||||
|
||||
//Creates sameAsEcm1
|
||||
LispEncapsulatedControl.EcmBuilder builder2 =
|
||||
new DefaultLispEncapsulatedControl.DefaultEcmBuilder();
|
||||
|
||||
IP innerIp2 = new IPv4().setSourceAddress(ECM1_SRC_IP)
|
||||
.setDestinationAddress(ECM1_DST_IP)
|
||||
.setProtocol(IPv4.PROTOCOL_UDP);
|
||||
UDP innerUdp2 = new UDP().setSourcePort(1)
|
||||
.setDestinationPort(2);
|
||||
|
||||
LispMapRegister.RegisterBuilder msgBuilder2 =
|
||||
new DefaultLispMapRegister.DefaultRegisterBuilder();
|
||||
|
||||
List<LispMapRecord> records2 = ImmutableList.of(getMapRecord(),
|
||||
getMapRecord());
|
||||
|
||||
LispMapRegister innerMsg2 = msgBuilder2.withIsProxyMapReply(true)
|
||||
.withIsWantMapNotify(false)
|
||||
.withKeyId((short) 1)
|
||||
.withNonce(1L)
|
||||
.withMapRecords(records2)
|
||||
.build();
|
||||
|
||||
sameAsEcm1 = builder2.isSecurity(false)
|
||||
.innerIpHeader(innerIp2)
|
||||
.innerUdpHeader(innerUdp2)
|
||||
.innerLispMessage(innerMsg2)
|
||||
.build();
|
||||
|
||||
//Creates ecm2
|
||||
LispEncapsulatedControl.EcmBuilder builder3 =
|
||||
new DefaultLispEncapsulatedControl.DefaultEcmBuilder();
|
||||
|
||||
IP innerIp3 = new IPv4().setSourceAddress(ECM2_SRC_IP)
|
||||
.setDestinationAddress(ECM2_DST_IP)
|
||||
.setProtocol(IPv4.PROTOCOL_UDP);
|
||||
UDP innerUdp3 = new UDP().setSourcePort(10)
|
||||
.setDestinationPort(20);
|
||||
|
||||
LispMapRegister.RegisterBuilder msgBuilder3 =
|
||||
new DefaultLispMapRegister.DefaultRegisterBuilder();
|
||||
|
||||
List<LispMapRecord> records3 = ImmutableList.of(getMapRecord(),
|
||||
getMapRecord());
|
||||
|
||||
LispMapRegister innerMsg3 = msgBuilder3.withIsProxyMapReply(true)
|
||||
.withIsWantMapNotify(false)
|
||||
.withKeyId((short) 2)
|
||||
.withNonce(1L)
|
||||
.withMapRecords(records3)
|
||||
.build();
|
||||
|
||||
ecm2 = builder3.isSecurity(false)
|
||||
.innerIpHeader(innerIp3)
|
||||
.innerUdpHeader(innerUdp3)
|
||||
.innerLispMessage(innerMsg3)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEquality() {
|
||||
new EqualsTester()
|
||||
.addEqualityGroup(ecm1, sameAsEcm1)
|
||||
.addEqualityGroup(ecm2).testEquals();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstruction() {
|
||||
DefaultLispEncapsulatedControl ecm =
|
||||
(DefaultLispEncapsulatedControl) ecm1;
|
||||
|
||||
assertThat("Inner Ip versions are not match",
|
||||
ecm.innerIpHeader().getVersion(), is((byte) 4));
|
||||
assertThat("Inner Ip protocols are not match",
|
||||
((IPv4) ecm.innerIpHeader()).getProtocol(),
|
||||
is(IPv4.PROTOCOL_UDP));
|
||||
assertThat("Inner IP source addresses are not match",
|
||||
((IPv4) ecm.innerIpHeader()).getSourceAddress(),
|
||||
is(IPv4.toIPv4Address(ECM1_SRC_IP)));
|
||||
assertThat("Inner IP destination addresses are not match",
|
||||
((IPv4) ecm.innerIpHeader()).getDestinationAddress(),
|
||||
is(IPv4.toIPv4Address(ECM1_DST_IP)));
|
||||
assertThat("Inner UDP source ports are not match",
|
||||
ecm.innerUdp().getSourcePort(), is(1));
|
||||
assertThat("Inner UDP destination ports are not match",
|
||||
ecm.innerUdp().getDestinationPort(), is(2));
|
||||
assertThat("Inner LISP control messages are not match",
|
||||
ecm.getControlMessage().getType(),
|
||||
is(LispType.LISP_MAP_REGISTER));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSerialization() throws LispReaderException,
|
||||
LispWriterException, LispParseError, DeserializationException {
|
||||
|
||||
ByteBuf byteBuf = Unpooled.buffer();
|
||||
DefaultLispEncapsulatedControl.EcmWriter writer =
|
||||
new DefaultLispEncapsulatedControl.EcmWriter();
|
||||
writer.writeTo(byteBuf, ecm1);
|
||||
|
||||
DefaultLispEncapsulatedControl.EcmReader reader =
|
||||
new DefaultLispEncapsulatedControl.EcmReader();
|
||||
|
||||
LispEncapsulatedControl deserialized = reader.readFrom(byteBuf);
|
||||
|
||||
new EqualsTester()
|
||||
.addEqualityGroup(ecm1, deserialized).testEquals();
|
||||
}
|
||||
|
||||
private LispMapRecord getMapRecord() {
|
||||
LispMapRecord.MapRecordBuilder builder1 =
|
||||
new DefaultLispMapRecord.DefaultMapRecordBuilder();
|
||||
|
||||
LispIpv4Address ipv4Locator1 =
|
||||
new LispIpv4Address(IpAddress.valueOf(RECORD_EID));
|
||||
|
||||
return builder1
|
||||
.withRecordTtl(100)
|
||||
.withAuthoritative(true)
|
||||
.withMapVersionNumber((short) 1)
|
||||
.withMaskLength((byte) 0x01)
|
||||
.withAction(LispMapReplyAction.NativelyForward)
|
||||
.withEidPrefixAfi(ipv4Locator1)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user