aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4')
-rw-r--r--framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BGPKeepaliveMsgVer4.java15
-rw-r--r--framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BGPNotificationMsgVer4.java266
-rw-r--r--framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BGPOpenMsgVer4.java136
3 files changed, 369 insertions, 48 deletions
diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BGPKeepaliveMsgVer4.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BGPKeepaliveMsgVer4.java
index a6668b3a..10e6bb95 100644
--- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BGPKeepaliveMsgVer4.java
+++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BGPKeepaliveMsgVer4.java
@@ -98,21 +98,6 @@ class BGPKeepaliveMsgVer4 implements BGPKeepaliveMsg {
BGPHeader bgpMsgHeader;
@Override
- public BGPVersion getVersion() {
- return BGPVersion.BGP_4;
- }
-
- @Override
- public BGPType getType() {
- return BGPType.KEEP_ALIVE;
- }
-
- @Override
- public BGPHeader getHeader() {
- return this.bgpMsgHeader;
- }
-
- @Override
public Builder setHeader(BGPHeader bgpMsgHeader) {
this.bgpMsgHeader = bgpMsgHeader;
return this;
diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BGPNotificationMsgVer4.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BGPNotificationMsgVer4.java
new file mode 100644
index 00000000..064deada
--- /dev/null
+++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BGPNotificationMsgVer4.java
@@ -0,0 +1,266 @@
+/*
+ * 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.protocol.ver4;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.bgpio.exceptions.BGPParseException;
+import org.onosproject.bgpio.protocol.BGPMessageReader;
+import org.onosproject.bgpio.protocol.BGPMessageWriter;
+import org.onosproject.bgpio.protocol.BGPNotificationMsg;
+import org.onosproject.bgpio.protocol.BGPType;
+import org.onosproject.bgpio.protocol.BGPVersion;
+import org.onosproject.bgpio.types.BGPErrorType;
+import org.onosproject.bgpio.types.BGPHeader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * A NOTIFICATION message is sent when an error condition is detected. The BGP connection is closed immediately after it
+ * is sent.
+ */
+class BGPNotificationMsgVer4 implements BGPNotificationMsg {
+
+ /*
+ 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
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Error code | Error subcode | Data (variable) |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ REFERENCE : RFC 4271
+ */
+
+ protected static final Logger log = LoggerFactory.getLogger(BGPNotificationMsgVer4.class);
+
+ static final byte PACKET_VERSION = 4;
+ //BGPHeader(19) + Error code(1) + Error subcode(1)
+ static final int TOTAL_MESSAGE_MIN_LENGTH = 21;
+ static final int PACKET_MINIMUM_LENGTH = 2;
+ static final BGPType MSG_TYPE = BGPType.NOTIFICATION;
+ static final byte DEFAULT_ERRORSUBCODE = 0;
+ static final byte[] MARKER = {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01};
+ static final byte MESSAGE_TYPE = 3;
+ static final BGPHeader DEFAULT_MESSAGE_HEADER = new BGPHeader(MARKER, BGPHeader.DEFAULT_HEADER_LENGTH,
+ MESSAGE_TYPE);
+
+ private byte errorCode;
+ private byte errorSubCode;
+ private byte[] data;
+ private BGPHeader bgpHeader;
+ public static final BGPNotificationMsgVer4.Reader READER = new Reader();
+
+ /**
+ * Resets fields.
+ */
+ public BGPNotificationMsgVer4() {
+ this.bgpHeader = null;
+ this.data = null;
+ this.errorCode = 0;
+ this.errorSubCode = 0;
+ }
+
+ /**
+ * Constructor to initialize parameters.
+ *
+ * @param bgpHeader BGP Header in notification message
+ * @param errorCode error code
+ * @param errorSubCode error subcode
+ * @param data field
+ */
+ public BGPNotificationMsgVer4(BGPHeader bgpHeader, byte errorCode, byte errorSubCode, byte[] data) {
+ this.bgpHeader = bgpHeader;
+ this.data = data;
+ this.errorCode = errorCode;
+ this.errorSubCode = errorSubCode;
+ }
+
+ /**
+ * Reader reads BGP Notification Message from the channel buffer.
+ */
+ static class Reader implements BGPMessageReader<BGPNotificationMsg> {
+ @Override
+ public BGPNotificationMsg readFrom(ChannelBuffer cb, BGPHeader bgpHeader) throws BGPParseException {
+ byte errorCode;
+ byte errorSubCode;
+ if (cb.readableBytes() < PACKET_MINIMUM_LENGTH) {
+ throw new BGPParseException("Not enough readable bytes");
+ }
+ errorCode = cb.readByte();
+ errorSubCode = cb.readByte();
+ //Message Length = 21 + Data Length
+ int dataLength = bgpHeader.getLength() - TOTAL_MESSAGE_MIN_LENGTH;
+ byte[] data = new byte[dataLength];
+ cb.readBytes(data, 0, dataLength);
+ return new BGPNotificationMsgVer4(bgpHeader, errorCode, errorSubCode, data);
+ }
+ }
+
+ /**
+ * Builder class for BGP notification message.
+ */
+ static class Builder implements BGPNotificationMsg.Builder {
+ private byte errorCode;
+ private byte errorSubCode;
+ private byte[] data;
+ private BGPHeader bgpHeader;
+ private boolean isErrorCodeSet = false;
+ private boolean isErrorSubCodeSet = false;
+ private boolean isBGPHeaderSet = false;
+
+ @Override
+ public BGPNotificationMsg build() throws BGPParseException {
+ BGPHeader bgpHeader = this.isBGPHeaderSet ? this.bgpHeader : DEFAULT_MESSAGE_HEADER;
+ if (!this.isErrorCodeSet) {
+ throw new BGPParseException("Error code must be present");
+ }
+
+ byte errorSubCode = this.isErrorSubCodeSet ? this.errorSubCode : DEFAULT_ERRORSUBCODE;
+ return new BGPNotificationMsgVer4(bgpHeader, this.errorCode, errorSubCode, this.data);
+ }
+
+ @Override
+ public Builder setErrorCode(byte errorCode) {
+ this.errorCode = errorCode;
+ this.isErrorCodeSet = true;
+ return this;
+ }
+
+ @Override
+ public Builder setErrorSubCode(byte errorSubCode) {
+ this.errorSubCode = errorSubCode;
+ this.isErrorSubCodeSet = true;
+ return this;
+ }
+
+ @Override
+ public Builder setData(byte[] data) {
+ this.data = data;
+ return this;
+ }
+
+ @Override
+ public Builder setNotificationMsgHeader(BGPHeader header) {
+ this.bgpHeader = header;
+ this.isBGPHeaderSet = true;
+ return this;
+ }
+
+ @Override
+ public Builder setHeader(BGPHeader bgpMsgHeader) {
+ this.bgpHeader = bgpMsgHeader;
+ return this;
+ }
+ }
+
+ @Override
+ public BGPVersion getVersion() {
+ return BGPVersion.BGP_4;
+ }
+
+ @Override
+ public BGPType getType() {
+ return BGPType.NOTIFICATION;
+ }
+
+ @Override
+ public void writeTo(ChannelBuffer cb) throws BGPParseException {
+ WRITER.write(cb, this);
+ }
+
+ static final Writer WRITER = new Writer();
+
+ /**
+ * Writer writes BGP notification message to channel buffer.
+ */
+ static class Writer implements BGPMessageWriter<BGPNotificationMsgVer4> {
+ @Override
+ public void write(ChannelBuffer cb, BGPNotificationMsgVer4 message) throws BGPParseException {
+ int msgStartIndex = cb.writerIndex();
+ int headerLenIndex = message.bgpHeader.write(cb);
+ if (headerLenIndex <= 0) {
+ throw new BGPParseException(BGPErrorType.MESSAGE_HEADER_ERROR, (byte) 0, null);
+ }
+ cb.writeByte(message.errorCode);
+ cb.writeByte(message.errorSubCode);
+ cb.writeBytes(message.data);
+
+ //Update message length field in notification message
+ int length = cb.writerIndex() - msgStartIndex;
+ cb.setShort(headerLenIndex, (short) length);
+ message.bgpHeader.setLength((short) length);
+ }
+ }
+
+ @Override
+ public byte getErrorCode() {
+ return this.errorCode;
+ }
+
+ /**
+ * Sets errorcode with specified errorcode.
+ *
+ * @param errorCode field
+ */
+ public void setErrorCode(byte errorCode) {
+ this.errorCode = errorCode;
+ }
+
+ @Override
+ public byte getErrorSubCode() {
+ return this.errorSubCode;
+ }
+
+ /**
+ * Sets error subcode with specified errorSubCode.
+ *
+ * @param errorSubCode field
+ */
+ public void setErrorSubCode(byte errorSubCode) {
+ this.errorSubCode = errorSubCode;
+ }
+
+ @Override
+ public byte[] getData() {
+ return this.data;
+ }
+
+ /**
+ * Sets error data with specified data.
+ *
+ * @param data field
+ */
+ public void setData(byte[] data) {
+ this.data = data;
+ }
+
+ @Override
+ public BGPHeader getHeader() {
+ return this.bgpHeader;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass())
+ .omitNullValues()
+ .add("bgpHeader", bgpHeader)
+ .add("data", data)
+ .add("errorCode", errorCode)
+ .add("errorSubCode", errorSubCode)
+ .toString();
+ }
+} \ No newline at end of file
diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BGPOpenMsgVer4.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BGPOpenMsgVer4.java
index 1348ecfd..b50342d6 100644
--- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BGPOpenMsgVer4.java
+++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BGPOpenMsgVer4.java
@@ -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;
}
@@ -248,11 +286,13 @@ public class BGPOpenMsgVer4 implements BGPOpenMsg {
private boolean isHeaderSet = false;
private BGPHeader bgpMsgHeader;
private boolean isHoldTimeSet = false;
- private short holdTime;
+ private short holdTime;
private boolean isAsNumSet = false;
private short asNumber;
private boolean isBgpIdSet = false;
private int bgpId;
+ private boolean isLargeAsCapabilityTlvSet = false;
+ private boolean isLsCapabilityTlvSet = false;
LinkedList<BGPValueType> capabilityTlv = new LinkedList<>();
@@ -269,34 +309,30 @@ 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);
}
@Override
- public BGPHeader getHeader() {
- return this.bgpMsgHeader;
- }
-
- @Override
public Builder setHeader(BGPHeader bgpMsgHeader) {
this.bgpMsgHeader = bgpMsgHeader;
return this;
}
@Override
- public BGPVersion getVersion() {
- return BGPVersion.BGP_4;
- }
-
- @Override
- public BGPType getType() {
- return MSG_TYPE;
- }
-
- @Override
public short getHoldTime() {
return this.holdTime;
}
@@ -342,6 +378,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 +412,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 +426,29 @@ public class BGPOpenMsgVer4 implements BGPOpenMsg {
// write version in 1-octet
cb.writeByte(message.version);
- // TODO : Write AS number based on capabilities
- cb.writeShort(message.asNumber);
+ // 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);