[ONOS-4242] Capability support for wide community
Change-Id: Ib29a4aeddde863d3ecf281cea8d31c6a945834bd
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 7f4f59a..40c63d4 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
@@ -55,9 +55,9 @@
import java.net.UnknownHostException;
import java.nio.channels.ClosedChannelException;
import java.util.Collections;
-import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
+import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.RejectedExecutionException;
/**
@@ -85,6 +85,7 @@
static final short AFI = 16388;
static final byte RES = 0;
static final byte SAFI = 71;
+ static final byte MAX_UNSUPPORTED_CAPABILITY = 5;
// State needs to be volatile because the HandshakeTimeoutHandler
// needs to check if the handshake is complete
@@ -520,7 +521,7 @@
byte errorSubCode = errMsg.getErrorSubCode();
ChannelBuffer tempCb = errMsg.getData();
if (tempCb != null) {
- int dataLength = tempCb.capacity();
+ int dataLength = tempCb.readableBytes();
data = new byte[dataLength];
tempCb.readBytes(data, 0, dataLength);
}
@@ -685,7 +686,8 @@
.setLsCapabilityTlv(bgpconfig.getLsCapability())
.setLargeAsCapabilityTlv(bgpconfig.getLargeASCapability())
.setFlowSpecCapabilityTlv(flowSpecStatus)
- .setVpnFlowSpecCapabilityTlv(vpnFlowSpecStatus).build();
+ .setVpnFlowSpecCapabilityTlv(vpnFlowSpecStatus)
+ .setFlowSpecRpdCapabilityTlv(bgpconfig.flowSpecRpdCapability()).build();
log.debug("Sending open message to {}", channel.getRemoteAddress());
channel.write(Collections.singletonList(msg));
@@ -786,20 +788,28 @@
List<BgpValueType> capabilityTlv = openmsg.getCapabilityTlv();
ListIterator<BgpValueType> listIterator = capabilityTlv.listIterator();
- List<BgpValueType> unSupportedCapabilityTlv = new LinkedList<>();
+ List<BgpValueType> unSupportedCapabilityTlv = new CopyOnWriteArrayList<BgpValueType>();
ListIterator<BgpValueType> unSupportedCaplistIterator = unSupportedCapabilityTlv.listIterator();
BgpValueType tempTlv;
boolean isLargeAsCapabilityCfg = h.bgpconfig.getLargeASCapability();
+ boolean isFlowSpecRpdCapabilityCfg = h.bgpconfig.flowSpecRpdCapability();
boolean isLsCapabilityCfg = h.bgpconfig.getLsCapability();
- boolean isFlowSpecCapabilityCfg = false;
+ boolean isFlowSpecIpv4CapabilityCfg = false;
+ boolean isFlowSpecVpnv4CapabilityCfg = false;
MultiProtocolExtnCapabilityTlv tempCapability;
boolean isMultiProtocolLsCapability = false;
+ boolean isMultiProtocolFlowSpecRpdCapability = false;
boolean isMultiProtocolFlowSpecCapability = false;
boolean isMultiProtocolVpnFlowSpecCapability = false;
BgpCfg.FlowSpec flowSpec = h.bgpconfig.flowSpecCapability();
- if (flowSpec != BgpCfg.FlowSpec.NONE) {
- isFlowSpecCapabilityCfg = true;
+ if (flowSpec == BgpCfg.FlowSpec.IPV4) {
+ isFlowSpecIpv4CapabilityCfg = true;
+ } else if (flowSpec == BgpCfg.FlowSpec.VPNV4) {
+ isFlowSpecVpnv4CapabilityCfg = true;
+ } else if (flowSpec == BgpCfg.FlowSpec.IPV4_VPNV4) {
+ isFlowSpecIpv4CapabilityCfg = true;
+ isFlowSpecVpnv4CapabilityCfg = true;
}
while (listIterator.hasNext()) {
@@ -817,6 +827,10 @@
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;
@@ -843,13 +857,15 @@
}
}
- if ((isFlowSpecCapabilityCfg)) {
+ if (isFlowSpecIpv4CapabilityCfg) {
if (!isMultiProtocolFlowSpecCapability) {
tempTlv = new MultiProtocolExtnCapabilityTlv(Constants.AFI_FLOWSPEC_VALUE,
RES, Constants.SAFI_FLOWSPEC_VALUE);
unSupportedCapabilityTlv.add(tempTlv);
}
+ }
+ if (isFlowSpecVpnv4CapabilityCfg) {
if (!isMultiProtocolVpnFlowSpecCapability) {
tempTlv = new MultiProtocolExtnCapabilityTlv(Constants.AFI_FLOWSPEC_VALUE,
RES, Constants.VPN_SAFI_FLOWSPEC_VALUE);
@@ -864,7 +880,16 @@
}
}
- if (unSupportedCapabilityTlv.size() == 3) {
+ if ((isFlowSpecRpdCapabilityCfg)) {
+ if (!isMultiProtocolFlowSpecRpdCapability) {
+ tempTlv = new MultiProtocolExtnCapabilityTlv(Constants.AFI_FLOWSPEC_RPD_VALUE,
+ RES, Constants.SAFI_FLOWSPEC_RPD_VALUE,
+ Constants.RPD_CAPABILITY_SEND_VALUE);
+ unSupportedCapabilityTlv.add(tempTlv);
+ }
+ }
+
+ if (unSupportedCapabilityTlv.size() == MAX_UNSUPPORTED_CAPABILITY) {
ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
while (unSupportedCaplistIterator.hasNext()) {
BgpValueType tlv = unSupportedCaplistIterator.next();
diff --git a/protocols/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpConfig.java b/protocols/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpConfig.java
index 6073559..bbeea48 100755
--- a/protocols/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpConfig.java
+++ b/protocols/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpConfig.java
@@ -57,6 +57,7 @@
private BgpConnectPeer connectPeer;
private BgpPeerManagerImpl peerManager;
private BgpController bgpController;
+ private boolean rpdCapability;
/*
* Constructor to initialize the values.
@@ -129,6 +130,16 @@
}
@Override
+ public boolean flowSpecRpdCapability() {
+ return this.rpdCapability;
+ }
+
+ @Override
+ public void setFlowSpecRpdCapability(boolean rpdCapability) {
+ this.rpdCapability = rpdCapability;
+ }
+
+ @Override
public String getRouterId() {
if (this.routerId != null) {
return this.routerId.toString();
diff --git a/protocols/bgp/ctl/src/test/java/org/onosproject/bgp/BgpControllerImplTest.java b/protocols/bgp/ctl/src/test/java/org/onosproject/bgp/BgpControllerImplTest.java
index 72d5607..4795d35 100644
--- a/protocols/bgp/ctl/src/test/java/org/onosproject/bgp/BgpControllerImplTest.java
+++ b/protocols/bgp/ctl/src/test/java/org/onosproject/bgp/BgpControllerImplTest.java
@@ -72,6 +72,7 @@
import org.onosproject.bgpio.types.MultiProtocolExtnCapabilityTlv;
import org.onosproject.bgpio.types.IsIsPseudonode;
import org.onosproject.bgpio.types.RouteDistinguisher;
+import org.onosproject.bgpio.util.Constants;
/**
* Test case for BGPControllerImpl.
@@ -299,6 +300,29 @@
assertThat(result, is(true));
}
+ @Test
+ public void bgpOpenMessageTest8() throws InterruptedException {
+ // Open message with route policy distribution capability
+ short afi = Constants.AFI_FLOWSPEC_RPD_VALUE;
+ byte res = 0;
+ byte safi = Constants.SAFI_FLOWSPEC_RPD_VALUE;
+ peer1.peerChannelHandler.asNumber = 200;
+ peer1.peerChannelHandler.version = 4;
+ peer1.peerChannelHandler.holdTime = 120;
+
+ bgpControllerImpl.getConfig().setFlowSpecRpdCapability(true);
+ BgpValueType tempTlv1 = new MultiProtocolExtnCapabilityTlv(afi, res, safi);
+ peer1.peerChannelHandler.capabilityTlv.add(tempTlv1);
+
+ peer1.connect(connectToSocket);
+
+ boolean result;
+ result = peer1.peerFrameDecoder.receivedOpenMessageLatch.await(
+ MESSAGE_TIMEOUT_MS,
+ TimeUnit.MILLISECONDS);
+ assertThat(result, is(true));
+ }
+
/**
* Peer1 has Node NLRI (MpReach).
*/