[ONOS-4240] Support wide community optional path attribute
Change-Id: I667cf229b02c8bcb0d4defd953bcde1595d03802
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 b55b178..a273b99 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
@@ -32,6 +32,7 @@
import org.onosproject.bgpio.types.MultiProtocolExtnCapabilityTlv;
import org.onosproject.bgpio.util.Validation;
import org.onosproject.bgpio.util.Constants;
+import org.onosproject.bgpio.types.RpdCapabilityTlv;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -256,26 +257,36 @@
int as4Num = cb.readInt();
tlv = new FourOctetAsNumCapabilityTlv(as4Num);
break;
+ case RpdCapabilityTlv.TYPE:
+ log.debug("RpdCapability");
+ if (RpdCapabilityTlv.LENGTH != length) {
+ throw new BgpParseException("Invalid length received for RpdCapability.");
+ }
+ if (length > cb.readableBytes()) {
+ throw new BgpParseException("Four octet as num tlv length"
+ + " is more than readableBytes.");
+ }
+ short rpdAfi = cb.readShort();
+ byte rpdAsafi = cb.readByte();
+ byte sendReceive = cb.readByte();
+ tlv = new RpdCapabilityTlv(sendReceive);
+ 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();
- if ((afi == Constants.AFI_FLOWSPEC_RPD_VALUE) && (safi == Constants.SAFI_FLOWSPEC_RPD_VALUE)) {
- if ((MultiProtocolExtnCapabilityTlv.LENGTH + 1) != length) {
- throw new BgpParseException("Invalid length received for MultiProtocolExtnCapabilityTlv.");
- }
- tlv = new MultiProtocolExtnCapabilityTlv(afi, res, safi, cb.readByte());
- } else {
- if (MultiProtocolExtnCapabilityTlv.LENGTH != length) {
- throw new BgpParseException("Invalid length received for MultiProtocolExtnCapabilityTlv.");
- }
- tlv = new MultiProtocolExtnCapabilityTlv(afi, res, safi);
- }
+ tlv = new MultiProtocolExtnCapabilityTlv(afi, res, safi);
+
break;
default:
log.debug("Warning: Unsupported TLV: " + type);
@@ -358,9 +369,7 @@
if (this.isFlowSpecRpdCapabilityTlvSet) {
BgpValueType tlv;
- tlv = new MultiProtocolExtnCapabilityTlv(Constants.AFI_FLOWSPEC_RPD_VALUE,
- RES, Constants.SAFI_FLOWSPEC_RPD_VALUE,
- Constants.RPD_CAPABILITY_SEND_VALUE);
+ tlv = new RpdCapabilityTlv(Constants.RPD_CAPABILITY_SEND_VALUE);
this.capabilityTlv.add(tlv);
}
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BgpPathAttributes.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BgpPathAttributes.java
index d60adce..9f8ec82 100644
--- a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BgpPathAttributes.java
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BgpPathAttributes.java
@@ -36,6 +36,7 @@
import org.onosproject.bgpio.util.UnSupportedAttribute;
import org.onosproject.bgpio.util.Validation;
import org.onosproject.bgpio.util.Constants;
+import org.onosproject.bgpio.types.attr.WideCommunity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -149,6 +150,9 @@
case EXTENDED_COMMUNITY_TYPE:
pathAttribute = BgpExtendedCommunity.read(cb);
break;
+ case WideCommunity.TYPE:
+ pathAttribute = WideCommunity.read(cb);
+ break;
default:
//skip bytes for unsupported attribute types
UnSupportedAttribute.read(cb);
@@ -214,6 +218,10 @@
BgpExtendedCommunity extendedCommunity = (BgpExtendedCommunity) attr;
extendedCommunity.write(cb);
break;
+ case WideCommunity.TYPE:
+ WideCommunity wideCommunity = (WideCommunity) attr;
+ wideCommunity.write(cb);
+ break;
case MpReachNlri.MPREACHNLRI_TYPE:
MpReachNlri mpReach = (MpReachNlri) attr;
mpReach.write(cb);
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/MultiProtocolExtnCapabilityTlv.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/MultiProtocolExtnCapabilityTlv.java
index 832cd59..1231214 100644
--- a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/MultiProtocolExtnCapabilityTlv.java
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/MultiProtocolExtnCapabilityTlv.java
@@ -19,7 +19,6 @@
import org.jboss.netty.buffer.ChannelBuffer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.onosproject.bgpio.util.Constants;
import java.util.Objects;
@@ -46,7 +45,6 @@
private final short afi;
private final byte res;
private final byte safi;
- private final byte rpdSendReceive;
/**
* Constructor to initialize variables.
@@ -58,24 +56,6 @@
this.afi = afi;
this.res = res;
this.safi = safi;
- this.rpdSendReceive = Constants.RPD_CAPABILITY_SEND_VALUE;
- }
-
- /**
- * Constructor to initialize variables.
- * @param afi Address Family Identifiers
- * @param res reserved field
- * @param safi Subsequent Address Family Identifier
- * @param rpdSendReceive indicates whether the sender is
- (a) willing to receive Route Policies via BGP FLowSpec from its peer (value 1).
- (b) would like to send Route Policies via BGP FLowSpec to its peer (value 2).
- (c) both (value 3).
- */
- public MultiProtocolExtnCapabilityTlv(short afi, byte res, byte safi, byte rpdSendReceive) {
- this.afi = afi;
- this.res = res;
- this.safi = safi;
- this.rpdSendReceive = rpdSendReceive;
}
/**
@@ -140,16 +120,9 @@
@Override
public int write(ChannelBuffer cb) {
- boolean isFsRpd = false;
int iLenStartIndex = cb.writerIndex();
cb.writeByte(TYPE);
-
- if ((afi == Constants.AFI_FLOWSPEC_RPD_VALUE) && (safi == Constants.SAFI_FLOWSPEC_RPD_VALUE)) {
- cb.writeByte(LENGTH + 1);
- isFsRpd = true;
- } else {
- cb.writeByte(LENGTH);
- }
+ cb.writeByte(LENGTH);
// write afi
cb.writeShort(afi);
@@ -160,11 +133,6 @@
// write safi
cb.writeByte(safi);
- if (isFsRpd) {
- // write Send/Receive (1 octet)
- cb.writeByte(rpdSendReceive);
- }
-
return cb.writerIndex() - iLenStartIndex;
}
@@ -177,10 +145,6 @@
short afi = cb.readShort();
byte res = cb.readByte();
byte safi = cb.readByte();
-
- if ((afi == Constants.AFI_FLOWSPEC_RPD_VALUE) && (safi == Constants.SAFI_FLOWSPEC_RPD_VALUE)) {
- return new MultiProtocolExtnCapabilityTlv(afi, res, safi, cb.readByte());
- }
return new MultiProtocolExtnCapabilityTlv(afi, res, safi);
}
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/RpdCapabilityTlv.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/RpdCapabilityTlv.java
new file mode 100644
index 0000000..1542d33
--- /dev/null
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/RpdCapabilityTlv.java
@@ -0,0 +1,126 @@
+/*
+ * 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.bgpio.types;
+
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.bgpio.util.Constants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides implementation of BGP route policy distribution capability tlv.
+ */
+public class RpdCapabilityTlv implements BgpValueType {
+
+ protected static final Logger log = LoggerFactory
+ .getLogger(RpdCapabilityTlv.class);
+
+ public static final byte TYPE = (byte) 129;
+ public static final byte LENGTH = 4;
+ private short afi = Constants.AFI_FLOWSPEC_RPD_VALUE;
+ private byte sAfi = Constants.SAFI_FLOWSPEC_RPD_VALUE;
+
+ private final byte sendReceive;
+
+ /**
+ * Creates instance of route policy distribution capability.
+ * @param sendReceive value indicate wherether flow route is only for receive or send or both.
+ */
+ public RpdCapabilityTlv(byte sendReceive) {
+ this.sendReceive = sendReceive;
+ }
+
+ /**
+ * Creates instance of RpdCapabilityTlv.
+ * @param sendReceive value indicate wherether flow route is only for receive or send or both.
+ * @return object of RpdCapabilityTlv
+ */
+ public static RpdCapabilityTlv of(final byte sendReceive) {
+ return new RpdCapabilityTlv(sendReceive);
+ }
+
+ /**
+ * Returns value of send receive field of route policy distribution capability.
+ * @return send receive value of route policy distribution capability
+ */
+ public byte sendReceive() {
+ return sendReceive;
+ }
+
+ @Override
+ public short getType() {
+ return TYPE;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(sendReceive);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof RpdCapabilityTlv) {
+ RpdCapabilityTlv other = (RpdCapabilityTlv) obj;
+ return Objects.equals(sendReceive, other.sendReceive);
+ }
+ return false;
+ }
+
+ @Override
+ public int write(ChannelBuffer cb) {
+ int iLenStartIndex = cb.writerIndex();
+ cb.writeByte(TYPE);
+ cb.writeByte(LENGTH);
+ cb.writeShort(afi);
+ cb.writeByte(sAfi);
+ cb.writeByte(sendReceive);
+ return cb.writerIndex() - iLenStartIndex;
+ }
+
+ /**
+ * Reads the channel buffer and returns object of RpdCapabilityTlv.
+ * @param cb type of channel buffer
+ * @return object of RpdCapabilityTlv
+ */
+ public static RpdCapabilityTlv read(ChannelBuffer cb) {
+ short afi = cb.readShort();
+ byte sAfi = cb.readByte();
+ return RpdCapabilityTlv.of(cb.readByte());
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass())
+ .add("Type", TYPE)
+ .add("Length", LENGTH)
+ .add("afi", afi)
+ .add("safi", sAfi)
+ .add("sendReceive", sendReceive).toString();
+ }
+
+ @Override
+ public int compareTo(Object o) {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+}
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/util/Constants.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/util/Constants.java
index 0bb5e7b..bd3edbf 100644
--- a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/util/Constants.java
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/util/Constants.java
@@ -43,8 +43,8 @@
/* TODO: The Capability Code
for this capability is to be specified by the IANA.*/
public static final short AFI_FLOWSPEC_RPD_VALUE = 1;
- public static final byte SAFI_FLOWSPEC_RPD_VALUE = (byte) 200;
- public static final byte VPN_SAFI_FLOWSPEC_RDP_VALUE = (byte) 201;
+ public static final byte SAFI_FLOWSPEC_RPD_VALUE = (byte) 133;
+ public static final byte VPN_SAFI_FLOWSPEC_RDP_VALUE = (byte) 134;
public static final byte RPD_CAPABILITY_RECEIVE_VALUE = 0;
public static final byte RPD_CAPABILITY_SEND_VALUE = 1;
diff --git a/protocols/bgp/bgpio/src/test/java/org/onosproject/bgpio/protocol/BgpOpenMsgTest.java b/protocols/bgp/bgpio/src/test/java/org/onosproject/bgpio/protocol/BgpOpenMsgTest.java
index 2d01fe8..7cfe080 100755
--- a/protocols/bgp/bgpio/src/test/java/org/onosproject/bgpio/protocol/BgpOpenMsgTest.java
+++ b/protocols/bgp/bgpio/src/test/java/org/onosproject/bgpio/protocol/BgpOpenMsgTest.java
@@ -315,12 +315,13 @@
// OPEN Message with capabilities.
byte[] openMsg = 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, 0x00, 0x38, 0x01, 0x04, 0x00,
- 0x64, 0x00, (byte) 0xb4, (byte) 0xc0, (byte) 0xa8, 0x07, 0x35, 0x1b, 0x02, 0x19,
- 0x01, 0x04, 0x00, 0x01, 0x00, 0x01, 0x01, 0x04, 0x40, 0x04, 0x00, 0x47, 0x01,
- 0x04, 0x00, 0x01, 0x00, (byte) 0x85, 0x01, 0x05, 0x00, 0x01, 0x00, (byte) 0xc8,
- 0x00 }; // Four Octet AS Number-CAPABILITY-TLV
+ (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+ (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+ 0x00, 0x3d, 0x01, 0x04, 0x00, (byte) 0xc8, 0x00, (byte) 0xb4, (byte) 0xc0,
+ (byte) 0xa8, 0x07, 0x35, 0x20, 0x02, 0x1e, 0x01,
+ 0x04, 00, 0x01, 0x00, 0x01, 0x41, 0x04, 0x00, 0x00, 0x00, (byte) 0xc8, 0x01,
+ 0x04, 0x40, 0x04, 0x00, 0x47, 0x01, 0x04, 0x00, 0x01, 0x00, (byte) 0x85,
+ (byte) 0x81, 0x04, 0x00, 0x01, (byte) 0x85, 0x01 }; //RPD capability
byte[] testOpenMsg;
ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
@@ -352,12 +353,13 @@
// OPEN Message with invalid message type.
byte[] openMsg = 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, 0x00, 0x38, 0x01, 0x04, 0x00,
- 0x64, 0x00, (byte) 0xb4, (byte) 0xc0, (byte) 0xa8, 0x07, 0x35, 0x1b, 0x02, 0x19,
- 0x01, 0x04, 0x00, 0x01, 0x00, 0x01, 0x01, 0x04, 0x40, 0x04, 0x00, 0x47, 0x01,
- 0x04, 0x00, 0x01, 0x00, (byte) 0x85, 0x01, 0x04, 0x00, 0x01, 0x00, (byte) 0xc8,
- 0x00 };
+ (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+ (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+ 0x00, 0x3d, 0x01, 0x04, 0x00, (byte) 0xc8, 0x00, (byte) 0xb4, (byte) 0xc0,
+ (byte) 0xa8, 0x07, 0x35, 0x20, 0x02, 0x1e, 0x01, 0x04, 00, 0x01, 0x00, 0x01, 0x41,
+ 0x04, 0x00, 0x00, 0x00, (byte) 0xc8, 0x01, 0x04, 0x40, 0x04, 0x00,
+ 0x47, 0x01, 0x04, 0x00, 0x01, 0x00, (byte) 0x85,
+ (byte) 0x81, 0x05, 0x00, 0x01, (byte) 0x85, 0x01 }; //RPD capability
ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
buffer.writeBytes(openMsg);
diff --git a/protocols/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpChannelHandler.java b/protocols/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpChannelHandler.java
index 40c63d4..7a05f31 100755
--- a/protocols/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpChannelHandler.java
+++ b/protocols/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpChannelHandler.java
@@ -44,6 +44,7 @@
import org.onosproject.bgpio.types.BgpValueType;
import org.onosproject.bgpio.types.FourOctetAsNumCapabilityTlv;
import org.onosproject.bgpio.types.MultiProtocolExtnCapabilityTlv;
+import org.onosproject.bgpio.types.RpdCapabilityTlv;
import org.onosproject.bgpio.util.Constants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -784,7 +785,9 @@
log.debug("capabilityValidation");
boolean isFourOctetCapabilityExits = false;
+ boolean isRpdCapabilityExits = false;
int capAsNum = 0;
+ byte sendReceive = 0;
List<BgpValueType> capabilityTlv = openmsg.getCapabilityTlv();
ListIterator<BgpValueType> listIterator = capabilityTlv.listIterator();
@@ -798,7 +801,6 @@
boolean isFlowSpecVpnv4CapabilityCfg = false;
MultiProtocolExtnCapabilityTlv tempCapability;
boolean isMultiProtocolLsCapability = false;
- boolean isMultiProtocolFlowSpecRpdCapability = false;
boolean isMultiProtocolFlowSpecCapability = false;
boolean isMultiProtocolVpnFlowSpecCapability = false;
BgpCfg.FlowSpec flowSpec = h.bgpconfig.flowSpecCapability();
@@ -827,15 +829,16 @@
if (SAFI == tempCapability.getSafi()) {
isMultiProtocolLsCapability = true;
}
-
- if (Constants.SAFI_FLOWSPEC_RPD_VALUE == tempCapability.getSafi()) {
- isMultiProtocolFlowSpecRpdCapability = true;
- }
}
if (tlv.getType() == FOUR_OCTET_AS_NUM_CAPA_TYPE) {
isFourOctetCapabilityExits = true;
capAsNum = ((FourOctetAsNumCapabilityTlv) tlv).getInt();
}
+
+ if (tlv.getType() == RpdCapabilityTlv.TYPE) {
+ isRpdCapabilityExits = true;
+ sendReceive = ((RpdCapabilityTlv) tlv).sendReceive();
+ }
}
if (isFourOctetCapabilityExits) {
@@ -850,6 +853,12 @@
}
}
+ if (isRpdCapabilityExits) {
+ if (sendReceive > 2) {
+ throw new BgpParseException(BgpErrorType.OPEN_MESSAGE_ERROR, BgpErrorType.UNSUPPORTED_CAPABILITY, null);
+ }
+ }
+
if ((isLsCapabilityCfg)) {
if (!isMultiProtocolLsCapability) {
tempTlv = new MultiProtocolExtnCapabilityTlv(AFI, RES, SAFI);
@@ -881,10 +890,8 @@
}
if ((isFlowSpecRpdCapabilityCfg)) {
- if (!isMultiProtocolFlowSpecRpdCapability) {
- tempTlv = new MultiProtocolExtnCapabilityTlv(Constants.AFI_FLOWSPEC_RPD_VALUE,
- RES, Constants.SAFI_FLOWSPEC_RPD_VALUE,
- Constants.RPD_CAPABILITY_SEND_VALUE);
+ if (!isRpdCapabilityExits) {
+ tempTlv = new RpdCapabilityTlv(Constants.RPD_CAPABILITY_SEND_VALUE);
unSupportedCapabilityTlv.add(tempTlv);
}
}