[ONOS-3845] BGP support flow specification capability on peer basis.

Change-Id: Iae0f617f72213a4f1664dcf6e904b01ac7460816
diff --git a/protocols/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpCfg.java b/protocols/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpCfg.java
index 70a5c9e..dac1ee8 100755
--- a/protocols/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpCfg.java
+++ b/protocols/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpCfg.java
@@ -73,20 +73,6 @@
     void setLsCapability(boolean lscapability);
 
     /**
-     * Get the status of the flow specification support for this BGP speaker.
-     *
-     * @return true if the flow specification is supported otherwise false
-     */
-    boolean flowSpecCapability();
-
-    /**
-     * Set the flow specification support to this BGP speaker.
-     *
-     * @param flowSpecCapability BGP flow specification capability support
-     */
-    void setFlowSpecCapability(boolean flowSpecCapability);
-
-    /**
      * Get the status of the 32 bit AS support for this BGP speaker.
      *
      * @return true if the 32 bit AS number is supported else false
diff --git a/protocols/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpPeerCfg.java b/protocols/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpPeerCfg.java
index 2fb970f..e519404 100755
--- a/protocols/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpPeerCfg.java
+++ b/protocols/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpPeerCfg.java
@@ -58,6 +58,24 @@
         INVALID
     }
 
+    enum FlowSpec {
+
+        /**
+         * Signifies that peer support IPV4 flow specification.
+         */
+        IPV4,
+
+        /**
+         *  Signifies that peer support VPNV4 flow specification.
+         */
+        VPNV4,
+
+        /**
+         * Signifies that peer flow specification support disabled.
+         */
+        NONE
+    }
+
     /**
      * Returns the connection State information of the peer.
      *
@@ -177,4 +195,18 @@
      * @return peer connect instance
      */
     BgpConnectPeer connectPeer();
+
+    /**
+     * Gets the flow specification capability.
+     *
+     * @return flow specification status
+     */
+    public FlowSpec flowSpecStatus();
+
+    /**
+     * sets the flow specification capability.
+     *
+     * @param flowSpecStatus flow specification status
+     */
+    public void setFlowSpecStatus(FlowSpec flowSpecStatus);
 }
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 cbdb553..d2c8098 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
@@ -665,11 +665,23 @@
      */
     private void sendHandshakeOpenMessage() throws IOException, BgpParseException {
         int bgpId;
+        boolean flowSpecStatus = false;
+        boolean vpnFlowSpecStatus = false;
 
         bgpId = Ip4Address.valueOf(bgpconfig.getRouterId()).toInt();
+        BgpPeerConfig peerConfig = (BgpPeerConfig) bgpconfig.displayPeers(peerAddr);
+        if (peerConfig.flowSpecStatus() == BgpPeerCfg.FlowSpec.IPV4) {
+            flowSpecStatus = true;
+        } else if (peerConfig.flowSpecStatus() == BgpPeerCfg.FlowSpec.VPNV4) {
+            vpnFlowSpecStatus = true;
+        }
+
         BgpMessage msg = factory4.openMessageBuilder().setAsNumber((short) bgpconfig.getAsNumber())
-                .setHoldTime(bgpconfig.getHoldTime()).setBgpId(bgpId).setLsCapabilityTlv(bgpconfig.getLsCapability())
-                .setLargeAsCapabilityTlv(bgpconfig.getLargeASCapability()).build();
+                .setHoldTime(bgpconfig.getHoldTime()).setBgpId(bgpId)
+                .setLsCapabilityTlv(bgpconfig.getLsCapability())
+                .setLargeAsCapabilityTlv(bgpconfig.getLargeASCapability())
+                .setFlowSpecCapabilityTlv(flowSpecStatus)
+                .setVpnFlowSpecCapabilityTlv(vpnFlowSpecStatus).build();
         log.debug("Sending open message to {}", channel.getRemoteAddress());
         channel.write(Collections.singletonList(msg));
 
@@ -775,12 +787,17 @@
         BgpValueType tempTlv;
         boolean isLargeAsCapabilityCfg = h.bgpconfig.getLargeASCapability();
         boolean isLsCapabilityCfg = h.bgpconfig.getLsCapability();
-        boolean isFlowSpecCapabilityCfg = h.bgpconfig.flowSpecCapability();
+        boolean isFlowSpecCapabilityCfg = false;
         MultiProtocolExtnCapabilityTlv tempCapability;
         boolean isMultiProtocolLsCapability = false;
         boolean isMultiProtocolFlowSpecCapability = false;
         boolean isMultiProtocolVpnFlowSpecCapability = false;
 
+        BgpPeerConfig peerConfig = (BgpPeerConfig) h.bgpconfig.displayPeers(peerAddr);
+        if (peerConfig.flowSpecStatus() != BgpPeerCfg.FlowSpec.NONE) {
+            isFlowSpecCapabilityCfg = true;
+        }
+
         while (listIterator.hasNext()) {
             BgpValueType tlv = listIterator.next();
             if (tlv.getType() == MULTI_PROTOCOL_EXTN_CAPA_TYPE) {
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 405241b..1c846eb 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
@@ -47,7 +47,6 @@
     private int localAs;
     private int maxSession;
     private boolean lsCapability;
-    private boolean flowSpecCapability;
     private short holdTime;
     private boolean largeAs = false;
     private int maxConnRetryTime;
@@ -120,16 +119,6 @@
     }
 
     @Override
-    public boolean flowSpecCapability() {
-        return this.flowSpecCapability;
-    }
-
-    @Override
-    public void setFlowSpecCapability(boolean vpnFlowSpecCapability) {
-        this.flowSpecCapability = flowSpecCapability;
-    }
-
-    @Override
     public String getRouterId() {
         if (this.routerId != null) {
             return this.routerId.toString();
diff --git a/protocols/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpPeerConfig.java b/protocols/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpPeerConfig.java
index a8eaee3..65cd485 100755
--- a/protocols/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpPeerConfig.java
+++ b/protocols/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpPeerConfig.java
@@ -30,6 +30,7 @@
     private State state;
     private boolean selfInitiated;
     private BgpConnectPeer connectPeer;
+    private FlowSpec flowSpecStatus = FlowSpec.NONE;
 
     /**
      * Constructor to initialize the values.
@@ -118,4 +119,14 @@
     public void setConnectPeer(BgpConnectPeer connectPeer) {
         this.connectPeer = connectPeer;
     }
+
+    @Override
+    public FlowSpec flowSpecStatus() {
+        return flowSpecStatus;
+    }
+
+    @Override
+    public void setFlowSpecStatus(FlowSpec flowSpecStatus) {
+        this.flowSpecStatus = flowSpecStatus;
+    }
 }