[ONOS-3857] BGP Update message builder.
Change-Id: I02d750f662602fc51b090e6beb89d73d5eb36436
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpFactory.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpFactory.java
index 11a85ff..d4e83fa 100755
--- a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpFactory.java
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpFactory.java
@@ -45,6 +45,13 @@
BgpNotificationMsg.Builder notificationMessageBuilder();
/**
+ * Gets the builder object for a update message.
+ *
+ * @return builder object for update message
+ */
+ BgpUpdateMsg.Builder updateMessageBuilder();
+
+ /**
* Gets the BGP message reader.
*
* @return BGP message reader
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpOpenMsg.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpOpenMsg.java
index 94ec223..dfd4419 100644
--- a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpOpenMsg.java
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpOpenMsg.java
@@ -121,6 +121,24 @@
*/
Builder setLsCapabilityTlv(boolean isLsCapabilitySet);
+ /**
+ * Sets flow specification capability and return its builder.
+ *
+ * @param isFlowSpecCapabilitySet boolean value to know whether flow specification capability is set or not
+ *
+ * @return builder by setting capabilities
+ */
+ Builder setFlowSpecCapabilityTlv(boolean isFlowSpecCapabilitySet);
+
+ /**
+ * Sets VPN flow specification capability and return its builder.
+ *
+ * @param isVpnFlowSpecCapabilitySet boolean value to know whether flow spec capability is set or not
+ *
+ * @return builder by setting capabilities
+ */
+ Builder setVpnFlowSpecCapabilityTlv(boolean isVpnFlowSpecCapabilitySet);
+
@Override
Builder setHeader(BgpHeader bgpMsgHeader);
}
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpUpdateMsg.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpUpdateMsg.java
index d79a423..23dd7d5 100644
--- a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpUpdateMsg.java
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpUpdateMsg.java
@@ -18,13 +18,47 @@
import java.util.List;
+import org.jboss.netty.buffer.ChannelBuffer;
import org.onlab.packet.IpPrefix;
import org.onosproject.bgpio.protocol.ver4.BgpPathAttributes;
+import org.onosproject.bgpio.protocol.flowspec.BgpFlowSpecDetails;
+import org.onosproject.bgpio.types.BgpValueType;
+import org.onosproject.bgpio.types.BgpHeader;
/**
* Abstraction of an entity providing BGP Update Message.
*/
public interface BgpUpdateMsg extends BgpMessage {
+
+ @Override
+ BgpVersion getVersion();
+
+ @Override
+ BgpType getType();
+
+ @Override
+ void writeTo(ChannelBuffer channelBuffer);
+
+ @Override
+ BgpHeader getHeader();
+
+ /**
+ * Builder interface with set functions to build update message.
+ */
+ interface Builder extends BgpMessage.Builder {
+ @Override
+ BgpUpdateMsg build();
+
+ Builder setBgpPathAttributes(List<BgpValueType> attributes);
+
+ Builder setNlriIdentifier(short afi, byte safi);
+
+ Builder setBgpFlowSpecComponents(BgpFlowSpecDetails flowSpecComponents);
+
+ @Override
+ Builder setHeader(BgpHeader bgpMsgHeader);
+ }
+
/**
* Returns path attributes in BGP Update Message.
*
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BgpFactoryVer4.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BgpFactoryVer4.java
index c57832b..bf2ccdf 100755
--- a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BgpFactoryVer4.java
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BgpFactoryVer4.java
@@ -22,6 +22,7 @@
import org.onosproject.bgpio.protocol.BgpMessageReader;
import org.onosproject.bgpio.protocol.BgpNotificationMsg;
import org.onosproject.bgpio.protocol.BgpOpenMsg;
+import org.onosproject.bgpio.protocol.BgpUpdateMsg;
import org.onosproject.bgpio.protocol.BgpVersion;
/**
@@ -47,6 +48,11 @@
}
@Override
+ public BgpUpdateMsg.Builder updateMessageBuilder() {
+ return new BgpUpdateMsgVer4.Builder();
+ }
+
+ @Override
public BgpMessageReader<BgpMessage> getReader() {
return BgpMessageVer4.READER;
}
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BgpOpenMsgVer4.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BgpOpenMsgVer4.java
index 359eec2..2cc9f7a 100644
--- a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BgpOpenMsgVer4.java
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BgpOpenMsgVer4.java
@@ -31,6 +31,7 @@
import org.onosproject.bgpio.types.FourOctetAsNumCapabilityTlv;
import org.onosproject.bgpio.types.MultiProtocolExtnCapabilityTlv;
import org.onosproject.bgpio.util.Validation;
+import org.onosproject.bgpio.util.Constants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -293,6 +294,8 @@
private int bgpId;
private boolean isLargeAsCapabilityTlvSet = false;
private boolean isLsCapabilityTlvSet = false;
+ private boolean isFlowSpecCapabilityTlvSet = false;
+ private boolean isVpnFlowSpecCapabilityTlvSet = false;
LinkedList<BgpValueType> capabilityTlv = new LinkedList<>();
@@ -322,6 +325,20 @@
this.capabilityTlv.add(tlv);
}
+ if (this.isFlowSpecCapabilityTlvSet) {
+ BgpValueType tlv;
+ tlv = new MultiProtocolExtnCapabilityTlv(Constants.AFI_FLOWSPEC_VALUE,
+ RES, Constants.SAFI_FLOWSPEC_VALUE);
+ this.capabilityTlv.add(tlv);
+ }
+
+ if (this.isVpnFlowSpecCapabilityTlvSet) {
+ BgpValueType tlv;
+ tlv = new MultiProtocolExtnCapabilityTlv(Constants.AFI_FLOWSPEC_VALUE,
+ RES, Constants.VPN_SAFI_FLOWSPEC_VALUE);
+ this.capabilityTlv.add(tlv);
+ }
+
return new BgpOpenMsgVer4(bgpMsgHeader, PACKET_VERSION, this.asNumber, holdTime, this.bgpId,
this.capabilityTlv);
}
@@ -370,6 +387,18 @@
this.isLsCapabilityTlvSet = isLsCapabilitySet;
return this;
}
+
+ @Override
+ public Builder setFlowSpecCapabilityTlv(boolean isFlowSpecCapabilitySet) {
+ this.isFlowSpecCapabilityTlvSet = isFlowSpecCapabilitySet;
+ return this;
+ }
+
+ @Override
+ public Builder setVpnFlowSpecCapabilityTlv(boolean isVpnFlowSpecCapabilitySet) {
+ this.isVpnFlowSpecCapabilityTlvSet = isVpnFlowSpecCapabilitySet;
+ return this;
+ }
}
@Override
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BgpUpdateMsgVer4.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BgpUpdateMsgVer4.java
index 4d6af59..7b3264e 100644
--- a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BgpUpdateMsgVer4.java
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BgpUpdateMsgVer4.java
@@ -22,12 +22,17 @@
import org.onlab.packet.IpPrefix;
import org.onosproject.bgpio.exceptions.BgpParseException;
import org.onosproject.bgpio.protocol.BgpMessageReader;
+import org.onosproject.bgpio.protocol.BgpMessageWriter;
import org.onosproject.bgpio.protocol.BgpType;
import org.onosproject.bgpio.protocol.BgpUpdateMsg;
+import org.onosproject.bgpio.protocol.BgpVersion;
+import org.onosproject.bgpio.protocol.flowspec.BgpFlowSpecDetails;
import org.onosproject.bgpio.types.BgpErrorType;
import org.onosproject.bgpio.types.BgpHeader;
+import org.onosproject.bgpio.util.Constants;
import org.onosproject.bgpio.util.Validation;
-import org.onosproject.bgpio.protocol.BgpVersion;
+
+import org.onosproject.bgpio.types.BgpValueType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -72,16 +77,26 @@
public static final byte PACKET_VERSION = 4;
//Withdrawn Routes Length(2) + Total Path Attribute Length(2)
public static final int PACKET_MINIMUM_LENGTH = 4;
+ public static final int MARKER_LENGTH = 16;
public static final int BYTE_IN_BITS = 8;
public static final int MIN_LEN_AFTER_WITHDRW_ROUTES = 2;
public static final int MINIMUM_COMMON_HEADER_LENGTH = 19;
public static final BgpType MSG_TYPE = BgpType.UPDATE;
+ public static 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};
+ public static final BgpHeader DEFAULT_UPDATE_HEADER = new BgpHeader(marker,
+ (short) PACKET_MINIMUM_LENGTH, (byte) 0X02);
public static final BgpUpdateMsgVer4.Reader READER = new Reader();
private List<IpPrefix> withdrawnRoutes;
private BgpPathAttributes bgpPathAttributes;
private BgpHeader bgpHeader;
private List<IpPrefix> nlri;
+ private BgpFlowSpecDetails bgpFlowSpecComponents;
+ private short afi;
+ private byte safi;
/**
* Constructor to initialize parameters for BGP Update message.
@@ -99,6 +114,15 @@
this.nlri = nlri;
}
+ public BgpUpdateMsgVer4(BgpHeader bgpHeader, short afi, byte safi, BgpPathAttributes bgpPathAttributes,
+ BgpFlowSpecDetails bgpFlowSpecComponents) {
+ this.bgpHeader = bgpHeader;
+ this.bgpFlowSpecComponents = bgpFlowSpecComponents;
+ this.bgpPathAttributes = bgpPathAttributes;
+ this.afi = afi;
+ this.safi = safi;
+ }
+
/**
* Reader reads BGP Update Message from the channel buffer.
*/
@@ -163,6 +187,82 @@
}
/**
+ * Builder class for BGP update message.
+ */
+ static class Builder implements BgpUpdateMsg.Builder {
+ BgpHeader bgpMsgHeader = null;
+ BgpFlowSpecDetails bgpFlowSpecComponents;
+ BgpPathAttributes bgpPathAttributes;
+ private short afi;
+ private byte safi;
+
+ @Override
+ public BgpUpdateMsg build() /* throws BgpParseException */ {
+ BgpHeader bgpMsgHeader = DEFAULT_UPDATE_HEADER;
+
+ return new BgpUpdateMsgVer4(bgpMsgHeader, afi, safi, bgpPathAttributes, bgpFlowSpecComponents);
+ }
+
+ @Override
+ public Builder setHeader(BgpHeader bgpMsgHeader) {
+ this.bgpMsgHeader = bgpMsgHeader;
+ return this;
+ }
+
+ @Override
+ public Builder setBgpFlowSpecComponents(BgpFlowSpecDetails bgpFlowSpecComponents) {
+ this.bgpFlowSpecComponents = bgpFlowSpecComponents;
+ return this;
+ }
+
+ @Override
+ public Builder setBgpPathAttributes(List<BgpValueType> attributes) {
+ this.bgpPathAttributes = new BgpPathAttributes(attributes);
+ return this;
+ }
+
+ @Override
+ public Builder setNlriIdentifier(short afi, byte safi) {
+ this.afi = afi;
+ this.safi = safi;
+ return this;
+ }
+ }
+
+ public static final Writer WRITER = new Writer();
+
+ /**
+ * Writer class for writing BGP update message to channel buffer.
+ */
+ public static class Writer implements BgpMessageWriter<BgpUpdateMsgVer4> {
+
+ @Override
+ public void write(ChannelBuffer cb, BgpUpdateMsgVer4 message) throws BgpParseException {
+
+ int startIndex = cb.writerIndex();
+
+ // write common header and get msg length index
+ int msgLenIndex = message.bgpHeader.write(cb);
+
+ if (msgLenIndex <= 0) {
+ throw new BgpParseException("Unable to write message header.");
+ }
+
+ if ((message.afi == Constants.AFI_FLOWSPEC_VALUE) && (message.safi == Constants.SAFI_FLOWSPEC_VALUE)) {
+ //unfeasible route length
+ cb.writeShort(0);
+ }
+
+ // TODO: write path attributes
+
+ // write UPDATE Object Length
+ int length = cb.writerIndex() - startIndex;
+ cb.setShort(msgLenIndex, (short) length);
+ message.bgpHeader.setLength((short) length);
+ }
+ }
+
+ /**
* Parses NLRI from channel buffer.
*
* @param cb channelBuffer
@@ -248,8 +348,12 @@
}
@Override
- public void writeTo(ChannelBuffer channelBuffer) throws BgpParseException {
- //Not to be implemented as of now
+ public void writeTo(ChannelBuffer channelBuffer) {
+ try {
+ WRITER.write(channelBuffer, this);
+ } catch (BgpParseException e) {
+ log.debug("[writeTo] Error: " + e.toString());
+ }
}
@Override