Vidyashree Rama
Committed by Gerrit Code Review

[Emu] [ONOS-2598] Implementation of BGP Capabilities parsing, decoding and encoding

Change-Id: I5893c490f97ad23a0180b847e8b8af9b00560806
......@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.bgpio.protocol;
import java.util.LinkedList;
......@@ -91,8 +90,7 @@ public interface BGPOpenMsg extends BGPMessage {
/**
* Sets hold time in Open Message and return its builder.
*
* @param holdtime
* hold timer value in open message
* @param holdtime hold timer value in open message
* @return builder by setting hold time
*/
Builder setHoldTime(short holdtime);
......@@ -107,8 +105,7 @@ public interface BGPOpenMsg extends BGPMessage {
/**
* Sets AS number in Open Message and return its builder.
*
* @param asNumber
* as number in open message
* @param asNumber as number in open message
* @return builder by setting asNumber
*/
Builder setAsNumber(short asNumber);
......@@ -123,8 +120,7 @@ public interface BGPOpenMsg extends BGPMessage {
/**
* Sets BGP Identifier in Open Message and return its builder.
*
* @param bgpId
* BGP Identifier in open message
* @param bgpId BGP Identifier in open message
* @return builder by setting BGP Identifier
*/
Builder setBgpId(int bgpId);
......@@ -139,12 +135,29 @@ public interface BGPOpenMsg extends BGPMessage {
/**
* Sets capabilities in Open Message and return its builder.
*
* @param capabilityTlv
* capabilities in open message
* @param capabilityTlv capabilities in open message
* @return builder by setting capabilities
*/
Builder setCapabilityTlv(LinkedList<BGPValueType> capabilityTlv);
/**
* Sets isLargeAsCapabilityTlvSet and return its builder.
*
* @param isLargeAsCapabilitySet
* boolean value to know whether large AS capability is set or not
* @return builder by setting capabilities
*/
Builder setLargeAsCapabilityTlv(boolean isLargeAsCapabilitySet);
/**
* Sets isLsCapabilityTlvSet and return its builder.
*
* @param isLsCapabilitySet
* boolean value to know whether LS capability is set or not
* @return builder by setting capabilities
*/
Builder setLsCapabilityTlv(boolean isLsCapabilitySet);
@Override
Builder setHeader(BGPHeader bgpMsgHeader);
}
......
......@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.bgpio.protocol.ver4;
import java.util.LinkedList;
......@@ -29,6 +28,8 @@ import org.onosproject.bgpio.protocol.BGPVersion;
import org.onosproject.bgpio.types.BGPErrorType;
import org.onosproject.bgpio.types.BGPHeader;
import org.onosproject.bgpio.types.BGPValueType;
import org.onosproject.bgpio.types.FourOctetAsNumCapabilityTlv;
import org.onosproject.bgpio.types.MultiProtocolExtnCapabilityTlv;
import org.onosproject.bgpio.util.Validation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -67,8 +68,13 @@ public class BGPOpenMsgVer4 implements BGPOpenMsg {
public static final int MSG_HEADER_LENGTH = 19;
public static final int MARKER_LENGTH = 16;
public static final int DEFAULT_HOLD_TIME = 120;
public static final short AS_TRANS = 23456;
public static final int OPT_PARA_TYPE_CAPABILITY = 2;
public static final BGPType MSG_TYPE = BGPType.OPEN;
public static final short AFI = 16388;
public static final byte SAFI = 71;
public static final byte RES = 0;
public static final int FOUR_OCTET_AS_NUM_CAPA_TYPE = 65;
public static final byte[] MARKER = new byte[]{(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff};
......@@ -79,6 +85,7 @@ public class BGPOpenMsgVer4 implements BGPOpenMsg {
private short asNumber;
private short holdTime;
private int bgpId;
private boolean isLargeAsCapabilitySet;
private LinkedList<BGPValueType> capabilityTlv;
public static final BGPOpenMsgVer4.Reader READER = new Reader();
......@@ -98,18 +105,12 @@ public class BGPOpenMsgVer4 implements BGPOpenMsg {
/**
* Constructor to initialize all variables of BGP Open message.
*
* @param bgpMsgHeader
* BGP Header in open message
* @param version
* BGP version in open message
* @param holdTime
* hold time in open message
* @param asNumber
* AS number in open message
* @param bgpId
* BGP identifier in open message
* @param capabilityTlv
* capabilities in open message
* @param bgpMsgHeader BGP Header in open message
* @param version BGP version in open message
* @param holdTime hold time in open message
* @param asNumber AS number in open message
* @param bgpId BGP identifier in open message
* @param capabilityTlv capabilities in open message
*/
public BGPOpenMsgVer4(BGPHeader bgpMsgHeader, byte version, short asNumber, short holdTime,
int bgpId, LinkedList<BGPValueType> capabilityTlv) {
......@@ -236,7 +237,44 @@ public class BGPOpenMsgVer4 implements BGPOpenMsg {
LinkedList<BGPValueType> capabilityTlv = new LinkedList<>();
// TODO: Capability parsing
while (cb.readableBytes() > 0) {
BGPValueType tlv;
short type = cb.readByte();
short length = cb.readByte();
switch (type) {
case FourOctetAsNumCapabilityTlv.TYPE:
log.debug("FourOctetAsNumCapabilityTlv");
if (FourOctetAsNumCapabilityTlv.LENGTH != length) {
throw new BGPParseException("Invalid length received for FourOctetAsNumCapabilityTlv.");
}
if (length > cb.readableBytes()) {
throw new BGPParseException("Four octet as num tlv length"
+ " is more than readableBytes.");
}
int as4Num = cb.readInt();
tlv = new FourOctetAsNumCapabilityTlv(as4Num);
break;
case MultiProtocolExtnCapabilityTlv.TYPE:
log.debug("MultiProtocolExtnCapabilityTlv");
if (MultiProtocolExtnCapabilityTlv.LENGTH != length) {
throw new BGPParseException("Invalid length received for MultiProtocolExtnCapabilityTlv.");
}
if (length > cb.readableBytes()) {
throw new BGPParseException("BGP LS tlv length is more than readableBytes.");
}
short afi = cb.readShort();
byte res = cb.readByte();
byte safi = cb.readByte();
tlv = new MultiProtocolExtnCapabilityTlv(afi, res, safi);
break;
default:
log.debug("Warning: Unsupported TLV: " + type);
cb.skipBytes(length);
continue;
}
capabilityTlv.add(tlv);
}
return capabilityTlv;
}
......@@ -253,6 +291,8 @@ public class BGPOpenMsgVer4 implements BGPOpenMsg {
private short asNumber;
private boolean isBgpIdSet = false;
private int bgpId;
private boolean isLargeAsCapabilityTlvSet = false;
private boolean isLsCapabilityTlvSet = false;
LinkedList<BGPValueType> capabilityTlv = new LinkedList<>();
......@@ -269,7 +309,18 @@ public class BGPOpenMsgVer4 implements BGPOpenMsg {
throw new BGPParseException("BGPID is not set (mandatory)");
}
// TODO: capabilities build
if (this.isLargeAsCapabilityTlvSet) {
BGPValueType tlv;
int iValue = this.getAsNumber();
tlv = new FourOctetAsNumCapabilityTlv(iValue);
this.capabilityTlv.add(tlv);
}
if (this.isLsCapabilityTlvSet) {
BGPValueType tlv;
tlv = new MultiProtocolExtnCapabilityTlv(AFI, RES, SAFI);
this.capabilityTlv.add(tlv);
}
return new BGPOpenMsgVer4(bgpMsgHeader, PACKET_VERSION, this.asNumber, holdTime, this.bgpId,
this.capabilityTlv);
......@@ -342,6 +393,18 @@ public class BGPOpenMsgVer4 implements BGPOpenMsg {
this.capabilityTlv = capabilityTlv;
return this;
}
@Override
public Builder setLargeAsCapabilityTlv(boolean isLargeAsCapabilitySet) {
this.isLargeAsCapabilityTlvSet = isLargeAsCapabilitySet;
return this;
}
@Override
public Builder setLsCapabilityTlv(boolean isLsCapabilitySet) {
this.isLsCapabilityTlvSet = isLsCapabilitySet;
return this;
}
}
@Override
......@@ -364,6 +427,7 @@ public class BGPOpenMsgVer4 implements BGPOpenMsg {
public void write(ChannelBuffer cb, BGPOpenMsgVer4 message) throws BGPParseException {
int optParaLen = 0;
int as4num = 0;
int startIndex = cb.writerIndex();
......@@ -377,8 +441,29 @@ public class BGPOpenMsgVer4 implements BGPOpenMsg {
// write version in 1-octet
cb.writeByte(message.version);
// TODO : Write AS number based on capabilities
// get as4num if LS Capability is set
if (message.isLargeAsCapabilitySet) {
LinkedList<BGPValueType> capabilityTlv = message
.getCapabilityTlv();
ListIterator<BGPValueType> listIterator = capabilityTlv
.listIterator();
while (listIterator.hasNext()) {
BGPValueType tlv = listIterator.next();
if (tlv.getType() == FOUR_OCTET_AS_NUM_CAPA_TYPE) {
as4num = ((FourOctetAsNumCapabilityTlv) tlv).getInt();
break;
}
}
}
if ((message.isLargeAsCapabilitySet) && (as4num > 65535)) {
// write As number as AS_TRANS
cb.writeShort(AS_TRANS);
} else {
// write AS number in next 2-octet
cb.writeShort(message.asNumber);
}
// write HoldTime in next 2-octet
cb.writeShort(message.holdTime);
......
/*
* Copyright 2015 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.bgpio.types;
import java.util.Objects;
import org.jboss.netty.buffer.ChannelBuffer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.MoreObjects;
/**
* Provides FourOctetAsNumCapabilityTlv Capability Tlv.
*/
public class FourOctetAsNumCapabilityTlv implements BGPValueType {
/**
* support to indicate its support for four-octet AS numbers -CAPABILITY TLV format.
*/
protected static final Logger log = LoggerFactory
.getLogger(FourOctetAsNumCapabilityTlv.class);
public static final byte TYPE = 65;
public static final byte LENGTH = 4;
private final int rawValue;
/**
* constructor to initialize rawValue.
* @param rawValue FourOctetAsNumCapabilityTlv
*/
public FourOctetAsNumCapabilityTlv(int rawValue) {
this.rawValue = rawValue;
}
/**
* constructor to initialize raw.
* @param raw AS number
* @return object of FourOctetAsNumCapabilityTlv
*/
public static FourOctetAsNumCapabilityTlv of(final int raw) {
return new FourOctetAsNumCapabilityTlv(raw);
}
/**
* Returns value of TLV.
* @return int value of rawValue
*/
public int getInt() {
return rawValue;
}
@Override
public short getType() {
return TYPE;
}
@Override
public int hashCode() {
return Objects.hash(rawValue);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof FourOctetAsNumCapabilityTlv) {
FourOctetAsNumCapabilityTlv other = (FourOctetAsNumCapabilityTlv) obj;
return Objects.equals(rawValue, other.rawValue);
}
return false;
}
@Override
public int write(ChannelBuffer cb) {
int iLenStartIndex = cb.writerIndex();
cb.writeByte(TYPE);
cb.writeByte(LENGTH);
cb.writeInt(rawValue);
return cb.writerIndex() - iLenStartIndex;
}
/**
* Reads the channel buffer and returns object of FourOctetAsNumCapabilityTlv.
* @param cb type of channel buffer
* @return object of FourOctetAsNumCapabilityTlv
*/
public static FourOctetAsNumCapabilityTlv read(ChannelBuffer cb) {
return FourOctetAsNumCapabilityTlv.of(cb.readInt());
}
@Override
public String toString() {
return MoreObjects.toStringHelper(getClass())
.add("Type", TYPE)
.add("Length", LENGTH)
.add("Value", rawValue).toString();
}
}
/*
* Copyright 2015 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.bgpio.types;
import java.util.Objects;
import org.jboss.netty.buffer.ChannelBuffer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.MoreObjects;
/**
* Provides MultiProtocolExtnCapabilityTlv.
*/
public class MultiProtocolExtnCapabilityTlv implements BGPValueType {
/*
0 7 15 23 31
+-------+-------+-------+-------+
| AFI | Res | SAFI |
+-------+-------+-------+-------+
Multiprotocol Extensions CAPABILITY TLV format
REFERENCE : RFC 4760
*/
protected static final Logger log = LoggerFactory
.getLogger(MultiProtocolExtnCapabilityTlv.class);
public static final byte TYPE = 1;
public static final byte LENGTH = 4;
private final short afi;
private final byte res;
private final byte safi;
/**
* Constructor to initialize variables.
* @param afi Address Family Identifiers
* @param res reserved field
* @param safi Subsequent Address Family Identifier
*/
public MultiProtocolExtnCapabilityTlv(short afi, byte res, byte safi) {
this.afi = afi;
this.res = res;
this.safi = safi;
}
/**
* Returns object of MultiProtocolExtnCapabilityTlv.
* @param afi Address Family Identifiers
* @param res reserved field
* @param safi Subsequent Address Family Identifier
* @return object of MultiProtocolExtnCapabilityTlv
*/
public static MultiProtocolExtnCapabilityTlv of(short afi, byte res,
byte safi) {
return new MultiProtocolExtnCapabilityTlv(afi, res, safi);
}
/**
* Returns afi Address Family Identifiers value.
* @return afi Address Family Identifiers value
*/
public short getAFI() {
return afi;
}
/**
* Returns res reserved field value.
* @return res reserved field value
*/
public byte getRes() {
return res;
}
/**
* Returns safi Subsequent Address Family Identifier value.
* @return safi Subsequent Address Family Identifier value
*/
public byte getSAFI() {
return safi;
}
@Override
public short getType() {
return TYPE;
}
@Override
public int hashCode() {
return Objects.hash(afi, res, safi);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof MultiProtocolExtnCapabilityTlv) {
MultiProtocolExtnCapabilityTlv other = (MultiProtocolExtnCapabilityTlv) obj;
return Objects.equals(this.afi, other.afi)
&& Objects.equals(this.res, other.res)
&& Objects.equals(this.safi, other.safi);
}
return false;
}
@Override
public int write(ChannelBuffer cb) {
int iLenStartIndex = cb.writerIndex();
cb.writeByte(TYPE);
cb.writeByte(LENGTH);
// write afi
cb.writeShort(afi);
// write res
cb.writeByte(res);
// write safi
cb.writeByte(safi);
return cb.writerIndex() - iLenStartIndex;
}
/**
* Reads from channel buffer and returns object of MultiprotocolCapabilityTlv.
* @param cb of type channel buffer
* @return object of MultiProtocolExtnCapabilityTlv
*/
public static BGPValueType read(ChannelBuffer cb) {
short afi = cb.readShort();
byte res = cb.readByte();
byte safi = cb.readByte();
return new MultiProtocolExtnCapabilityTlv(afi, res, safi);
}
@Override
public String toString() {
return MoreObjects.toStringHelper(getClass())
.add("Type", TYPE)
.add("Length", LENGTH)
.add("AFI", afi)
.add("Reserved", res)
.add("SAFI", safi).toString();
}
}