[ONOS-2594] Channel handle to manage session handling with BGP peers

Change-Id: I6c58c674aa17e2a86b063e248af589d524ec5fe3
diff --git a/bgp/api/src/main/java/org/onosproject/bgp/controller/BGPController.java b/bgp/api/src/main/java/org/onosproject/bgp/controller/BGPController.java
index 49432aa..faa1de3 100755
--- a/bgp/api/src/main/java/org/onosproject/bgp/controller/BGPController.java
+++ b/bgp/api/src/main/java/org/onosproject/bgp/controller/BGPController.java
@@ -16,6 +16,9 @@
 
 package org.onosproject.bgp.controller;
 
+import java.util.Map;
+
+import org.onosproject.bgpio.exceptions.BGPParseException;
 import org.onosproject.bgpio.protocol.BGPMessage;
 
 /**
@@ -52,8 +55,9 @@
      *
      * @param bgpId id of the peer the message arrived on
      * @param msg the message to process.
+     * @throws BGPParseException on data processing error
      */
-    void processBGPPacket(BGPId bgpId, BGPMessage msg);
+    void processBGPPacket(BGPId bgpId, BGPMessage msg) throws BGPParseException;
 
     /**
      * Close all connected BGP peers.
@@ -73,5 +77,19 @@
      *
      * @return the integer number
      */
-    int getBGPConnNumber();
+    int connectedPeerCount();
+
+    /**
+     * Return BGP peer manager.
+     *
+     * @return BGPPeerManager peer manager instance
+     */
+    BgpPeerManager peerManager();
+
+    /**
+     * Return BGP connected peers.
+     *
+     * @return connectedPeers connected peers
+     */
+    Map<BGPId, BGPPeer> connectedPeers();
 }
\ No newline at end of file
diff --git a/bgp/api/src/main/java/org/onosproject/bgp/controller/BGPPeer.java b/bgp/api/src/main/java/org/onosproject/bgp/controller/BGPPeer.java
index 1b022c7..aafaf06 100755
--- a/bgp/api/src/main/java/org/onosproject/bgp/controller/BGPPeer.java
+++ b/bgp/api/src/main/java/org/onosproject/bgp/controller/BGPPeer.java
@@ -16,30 +16,16 @@
 package org.onosproject.bgp.controller;
 import java.util.List;
 import org.jboss.netty.channel.Channel;
+import org.onosproject.bgpio.protocol.BGPFactory;
 import org.onosproject.bgpio.protocol.BGPMessage;
-import org.onosproject.bgpio.protocol.BGPVersion;
 
 /**
- * Represents the peer side of an bgp peer.
+ * Represents the peer side of an BGP peer.
  *
  */
 public interface BGPPeer {
 
     /**
-     * Sets the BGP version for this bgp peer.
-     *
-     * @param bgpVersion the version to set.
-     */
-    void setBgpPeerVersion(BGPVersion bgpVersion);
-
-    /**
-     * Gets the BGP version for this bgp peer.
-     *
-     * @return bgp identifier.
-     */
-    int getBgpPeerIdentifier();
-
-    /**
      * Sets the associated Netty channel for this bgp peer.
      *
      * @param channel the Netty channel
@@ -54,27 +40,6 @@
     Channel getChannel();
 
     /**
-     * Sets the AS Number for this bgp peer.
-     *
-     * @param peerASNum the autonomous system number value to set.
-     */
-    void setBgpPeerASNum(short peerASNum);
-
-    /**
-     * Sets the hold time for this bgp peer.
-     *
-     * @param peerHoldTime the hold timer value to set.
-     */
-    void setBgpPeerHoldTime(short peerHoldTime);
-
-    /**
-     * Sets the peer identifier value.
-     *
-     * @param peerIdentifier the bgp peer identifier value.
-     */
-    void setBgpPeerIdentifier(int peerIdentifier);
-
-    /**
      * Sets whether the bgp peer is connected.
      *
      * @param connected whether the bgp peer is connected
@@ -82,15 +47,6 @@
     void setConnected(boolean connected);
 
     /**
-     * Initialises the behaviour.
-     *
-     * @param bgpId id of bgp peer
-     * @param bgpVersion BGP version
-     * @param pktStats packet statistics
-     */
-    void init(BGPId bgpId, BGPVersion bgpVersion, BGPPacketStats pktStats);
-
-    /**
      * Checks whether the handshake is complete.
      *
      * @return true is finished, false if not.
@@ -112,18 +68,11 @@
     void sendMessage(List<BGPMessage> msgs);
 
     /**
-     * Gets a string version of the ID for this bgp peer.
+     * Provides the factory for BGP version.
      *
-     * @return string version of the ID
+     * @return BGP version specific factory.
      */
-    String getStringId();
-
-    /**
-     * Gets the ipAddress of the peer.
-     *
-     * @return the peer bgpId in IPAddress format
-     */
-    BGPId getBGPId();
+    BGPFactory factory();
 
     /**
      * Checks if the bgp peer is still connected.
@@ -146,16 +95,9 @@
     String channelId();
 
     /**
-     * Gets the negotiated hold time.
+     * Return the BGP session info.
      *
-     * @return the negotiated hold time
+     * @return sessionInfo bgp session info
      */
-    int getNegotiatedHoldTime();
-
-    /**
-     * Sets negotiated hold time for the peer.
-     *
-     * @param negotiatedHoldTime negotiated hold time
-     */
-    void setNegotiatedHoldTime(short negotiatedHoldTime);
+    BgpSessionInfo sessionInfo();
 }
diff --git a/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpSessionInfo.java b/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpSessionInfo.java
new file mode 100755
index 0000000..17753ff
--- /dev/null
+++ b/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpSessionInfo.java
@@ -0,0 +1,70 @@
+/*
+ * 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.bgp.controller;
+
+import org.onosproject.bgpio.protocol.BGPVersion;
+
+/**
+ * Abstraction of an BGP session info. Maintian session parameters obtained during session creation.
+ */
+public interface BgpSessionInfo {
+    /**
+     * Gets the bgp session type iBGP/eBGP.
+     *
+     * @return isiBGPSession, true if session is of type internal, otherwise false.
+     */
+    boolean isIbgpSession();
+
+    /**
+     * Gets the negotiated hold time for the session.
+     *
+     * @return negotiated hold time.
+     */
+    short negotiatedholdTime();
+
+    /**
+     * Gets the BGP ID of BGP peer.
+     *
+     * @return bgp ID.
+     */
+    BGPId remoteBgpId();
+
+    /**
+     * Gets the BGP version of peer.
+     *
+     * @return bgp version.
+     */
+    BGPVersion remoteBgpVersion();
+
+    /**
+     * Gets the BGP remote bgp AS number.
+     *
+     * @return remoteBgpASNum peer AS number.
+     */
+    long remoteBgpASNum();
+
+    /**
+     * Gets the BGP peer hold time.
+     *
+     * @return bgp hold time.
+     */
+    short remoteBgpHoldTime();
+
+    /**
+     * Gets the BGP version for this bgp peer.
+     *
+     * @return bgp identifier.
+     */
+    int remoteBgpIdentifier();
+}
diff --git a/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPChannelHandler.java b/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPChannelHandler.java
index c17736e..4e419c8 100755
--- a/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPChannelHandler.java
+++ b/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPChannelHandler.java
@@ -20,6 +20,7 @@
 import java.net.InetSocketAddress;
 import java.net.SocketAddress;
 import java.nio.channels.ClosedChannelException;
+import java.util.Collections;
 import java.util.Date;
 import java.util.List;
 import java.util.concurrent.RejectedExecutionException;
@@ -32,15 +33,18 @@
 import org.jboss.netty.handler.timeout.IdleStateAwareChannelHandler;
 import org.jboss.netty.handler.timeout.ReadTimeoutException;
 import org.jboss.netty.handler.timeout.ReadTimeoutHandler;
+import org.onlab.packet.Ip4Address;
 import org.onlab.packet.IpAddress;
 import org.onosproject.bgp.controller.BGPCfg;
+import org.onosproject.bgp.controller.BGPController;
 import org.onosproject.bgp.controller.BGPId;
 import org.onosproject.bgp.controller.BGPPeer;
 import org.onosproject.bgp.controller.BGPPeerCfg;
-import org.onosproject.bgp.controller.impl.BGPControllerImpl.BGPPeerManager;
+import org.onosproject.bgp.controller.impl.BGPControllerImpl.BGPPeerManagerImpl;
 import org.onosproject.bgpio.exceptions.BGPParseException;
+import org.onosproject.bgpio.protocol.BGPFactory;
 import org.onosproject.bgpio.protocol.BGPMessage;
-//import org.onosproject.bgpio.protocol.BGPOpenMsg;
+import org.onosproject.bgpio.protocol.BGPOpenMsg;
 import org.onosproject.bgpio.protocol.BGPType;
 import org.onosproject.bgpio.protocol.BGPVersion;
 import org.slf4j.Logger;
@@ -56,11 +60,11 @@
     static final int BGP_MAX_KEEPALIVE_INTERVAL = 3;
     private BGPPeer bgpPeer;
     private BGPId thisbgpId;
-    Channel channel;
+    private Channel channel;
     private BGPKeepAliveTimer keepAliveTimer = null;
     private short peerHoldTime = 0;
     private short negotiatedHoldTime = 0;
-    private short peerAsNum;
+    private long peerAsNum;
     private int peerIdentifier;
     private BGPPacketStatsImpl bgpPacketStats;
     static final int MAX_WRONG_COUNT_PACKET = 5;
@@ -72,13 +76,17 @@
     // When a bgp peer with a ip addresss is found (i.e we already have a
     // connected peer with the same ip), the new peer is immediately
     // disconnected. At that point netty callsback channelDisconnected() which
-    // proceeds to cleaup peer state - we need to ensure that it does not cleanup
+    // proceeds to cleaup peer state - we need to ensure that it does not
+    // cleanup
     // peer state for the older (still connected) peer
     private volatile Boolean duplicateBGPIdFound;
     // Indicates the bgp version used by this bgp peer
     protected BGPVersion bgpVersion;
-    private BGPControllerImpl bgpControllerImpl;
-    private BGPPeerManager peerManager;
+    private BGPController bgpController;
+    protected BGPFactory factory4;
+    private boolean isIbgpSession;
+    private BgpSessionInfoImpl sessionInfo;
+    private BGPPeerManagerImpl peerManager;
     private InetSocketAddress inetAddress;
     private IpAddress ipAddress;
     private SocketAddress address;
@@ -88,15 +96,16 @@
     /**
      * Create a new unconnected BGPChannelHandler.
      *
-     * @param bgpCtrlImpl bgp controller implementation object
+     * @param bgpController bgp controller
      */
-    BGPChannelHandler(BGPControllerImpl bgpCtrlImpl) {
-        this.bgpControllerImpl = bgpCtrlImpl;
-        this.peerManager = bgpCtrlImpl.getPeerManager();
+    BGPChannelHandler(BGPController bgpController) {
+        this.bgpController = bgpController;
+        this.peerManager = (BGPPeerManagerImpl) bgpController.peerManager();
         this.state = ChannelState.IDLE;
+        this.factory4 = Controller.getBGPMessageFactory4();
         this.duplicateBGPIdFound = Boolean.FALSE;
         this.bgpPacketStats = new BGPPacketStatsImpl();
-        this.bgpconfig = bgpCtrlImpl.getConfig();
+        this.bgpconfig = bgpController.getConfig();
     }
 
     // To disconnect peer session.
@@ -133,11 +142,11 @@
                     log.debug("Sending keep alive message in OPENSENT state");
                     h.bgpPacketStats.addInPacket();
 
-                    // TODO: initialize openmessage BGPOpenMsg pOpenmsg = (BGPOpenMsg) m;
-                    // TODO: initialize identifier from open messgae h.peerIdentifier = pOpenmsg.getBgpId();
+                    BGPOpenMsg pOpenmsg = (BGPOpenMsg) m;
+                    h.peerIdentifier = pOpenmsg.getBgpId();
 
                     // validate capabilities and open msg
-                    if (h.openMsgValidation(h)) {
+                    if (h.openMsgValidation(h, pOpenmsg)) {
                         log.debug("Sending handshake OPEN message");
 
                         /*
@@ -145,7 +154,7 @@
                          * value of the Hold Timer by using the smaller of its configured Hold Time and the Hold Time
                          * received in the OPEN message
                          */
-                        // TODO: initialize holdtime from open message h.peerHoldTime = pOpenmsg.getHoldTime();
+                        h.peerHoldTime = pOpenmsg.getHoldTime();
                         if (h.peerHoldTime < h.bgpconfig.getHoldTime()) {
                             h.channel.getPipeline().replace("holdTime",
                                                             "holdTime",
@@ -155,7 +164,8 @@
 
                         log.info("Hold Time : " + h.peerHoldTime);
 
-                        // TODO: get AS number for open message update AS number
+                        // update AS number
+                        h.peerAsNum = pOpenmsg.getAsNumber();
                     }
 
                     // Send keepalive message to peer.
@@ -180,10 +190,11 @@
                 } else {
                     h.bgpPacketStats.addInPacket();
 
-                    // TODO: initialize open message BGPOpenMsg pOpenmsg = (BGPOpenMsg) m;
+                    BGPOpenMsg pOpenmsg = (BGPOpenMsg) m;
+                    h.peerIdentifier = pOpenmsg.getBgpId();
 
                     // Validate open message
-                    if (h.openMsgValidation(h)) {
+                    if (h.openMsgValidation(h, pOpenmsg)) {
                         log.debug("Sending handshake OPEN message");
 
                         /*
@@ -191,7 +202,7 @@
                          * value of the Hold Timer by using the smaller of its configured Hold Time and the Hold Time
                          * received in the OPEN message
                          */
-                        // TODO: get hold time from open message h.peerHoldTime = pOpenmsg.getHoldTime();
+                        h.peerHoldTime = pOpenmsg.getHoldTime();
                         if (h.peerHoldTime < h.bgpconfig.getHoldTime()) {
                             h.channel.getPipeline().replace("holdTime",
                                                             "holdTime",
@@ -201,7 +212,8 @@
 
                         log.debug("Hold Time : " + h.peerHoldTime);
 
-                        //TODO: update AS number form open messsage update AS number
+                        // update AS number
+                        h.peerAsNum = pOpenmsg.getAsNumber();
 
                         h.sendHandshakeOpenMessage();
                         h.bgpPacketStats.addOutPacket();
@@ -229,20 +241,17 @@
                     final InetSocketAddress inetAddress = (InetSocketAddress) h.address;
                     h.thisbgpId = BGPId.bgpId(IpAddress.valueOf(inetAddress.getAddress()));
 
-                    h.bgpPeer = h.peerManager.getBGPPeerInstance(h.thisbgpId, h.bgpVersion, h.bgpPacketStats);
-                    // set the status fo bgp as connected
+                    // set session parameters
+                    h.negotiatedHoldTime = (h.peerHoldTime < h.bgpconfig.getHoldTime()) ? h.peerHoldTime
+                                                                                        : h.bgpconfig.getHoldTime();
+                    h.sessionInfo = new BgpSessionInfoImpl(h.thisbgpId, h.bgpVersion, h.peerAsNum, h.peerHoldTime,
+                                                           h.peerIdentifier, h.negotiatedHoldTime, h.isIbgpSession);
+
+                    h.bgpPeer = h.peerManager.getBGPPeerInstance(h.bgpController, h.sessionInfo, h.bgpPacketStats);
+                    // set the status of bgp as connected
                     h.bgpPeer.setConnected(true);
                     h.bgpPeer.setChannel(h.channel);
 
-                    // set specific parameters to bgp peer
-                    h.bgpPeer.setBgpPeerVersion(h.bgpVersion);
-                    h.bgpPeer.setBgpPeerASNum(h.peerAsNum);
-                    h.bgpPeer.setBgpPeerHoldTime(h.peerHoldTime);
-                    h.bgpPeer.setBgpPeerIdentifier(h.peerIdentifier);
-
-                    h.negotiatedHoldTime = (h.peerHoldTime < h.bgpconfig.getHoldTime()) ? h.peerHoldTime : h.bgpconfig
-                            .getHoldTime();
-                    h.bgpPeer.setNegotiatedHoldTime(h.negotiatedHoldTime);
                     /*
                      * RFC 4271, When an OPEN message is received, sends a KEEPALIVE message, If the negotiated hold
                      * time value is zero, then the HoldTimer and KeepaliveTimer are not started. A reasonable maximum
@@ -251,8 +260,8 @@
                     h.sendKeepAliveMessage();
 
                     if (h.negotiatedHoldTime != 0) {
-                        h.keepAliveTimer
-                            = new BGPKeepAliveTimer(h, (h.negotiatedHoldTime / BGP_MAX_KEEPALIVE_INTERVAL));
+                        h.keepAliveTimer = new BGPKeepAliveTimer(h,
+                                                                 (h.negotiatedHoldTime / BGP_MAX_KEEPALIVE_INTERVAL));
                     }
 
                     h.bgpPacketStats.addOutPacket();
@@ -360,7 +369,7 @@
         }
 
         // if connection is already established close channel
-        if (peerManager.isPeerConnected(peerAddr)) {
+        if (peerManager.isPeerConnected(BGPId.bgpId(IpAddress.valueOf(peerAddr)))) {
             log.debug("Duplicate connection received, peer {}", peerAddr);
             channel.close();
             return;
@@ -507,11 +516,12 @@
     /**
      * To handle the BGP message.
      *
-     * @param m BGP message
+     * @param m bgp message
+     * @throws BGPParseException throw exception
      */
     private void dispatchMessage(BGPMessage m) throws BGPParseException {
         bgpPacketStats.addInPacket();
-        bgpControllerImpl.processBGPPacket(thisbgpId, m);
+        bgpController.processBGPPacket(thisbgpId, m);
     }
 
     /**
@@ -557,10 +567,16 @@
     /**
      * Send handshake open message to the peer.
      *
-     * @throws IOException ,BGPParseException
+     * @throws IOException, BGPParseException
      */
     private void sendHandshakeOpenMessage() throws IOException, BGPParseException {
-        // TODO: send open message.
+        int bgpId;
+
+        bgpId = Ip4Address.valueOf(bgpconfig.getRouterId()).toInt();
+        BGPMessage msg = factory4.openMessageBuilder().setAsNumber((short) bgpconfig.getAsNumber())
+                .setHoldTime(bgpconfig.getHoldTime()).setBgpId(bgpId).build();
+        log.debug("Sending open message to {}", channel.getRemoteAddress());
+        channel.write(Collections.singletonList(msg));
 
     }
 
@@ -572,7 +588,9 @@
      */
     synchronized void sendKeepAliveMessage() throws IOException, BGPParseException {
 
-        // TODO: send keep alive message.
+        BGPMessage msg = factory4.keepaliveMessageBuilder().build();
+        log.debug("Sending keepalive message to {}", channel.getRemoteAddress());
+        channel.write(Collections.singletonList(msg));
     }
 
     /**
@@ -621,10 +639,11 @@
      * Open message validation.
      *
      * @param h channel handler
+     * @param pOpenmsg open message
      * @return true if validation succeed, otherwise false
      * @throws BGPParseException when received invalid message
      */
-    public boolean openMsgValidation(BGPChannelHandler h) throws BGPParseException {
+    public boolean openMsgValidation(BGPChannelHandler h, BGPOpenMsg pOpenmsg) throws BGPParseException {
         // TODO: Open message validation.
         return true;
     }
diff --git a/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPControllerImpl.java b/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPControllerImpl.java
index d8378e3..08c1fa2 100755
--- a/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPControllerImpl.java
+++ b/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPControllerImpl.java
@@ -16,25 +16,21 @@
 
 package org.onosproject.bgp.controller.impl;
 
-import static org.onlab.util.Tools.groupedThreads;
-
 import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantLock;
+
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Deactivate;
 import org.apache.felix.scr.annotations.Service;
-import org.onlab.packet.IpAddress;
 import org.onosproject.bgp.controller.BGPCfg;
 import org.onosproject.bgp.controller.BGPController;
 import org.onosproject.bgp.controller.BGPId;
-import org.onosproject.bgp.controller.BGPPacketStats;
 import org.onosproject.bgp.controller.BGPPeer;
+import org.onosproject.bgp.controller.BgpPeerManager;
+import org.onosproject.bgpio.exceptions.BGPParseException;
 import org.onosproject.bgpio.protocol.BGPMessage;
-import org.onosproject.bgpio.protocol.BGPVersion;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -44,16 +40,9 @@
 
     private static final Logger log = LoggerFactory.getLogger(BGPControllerImpl.class);
 
-    private final ExecutorService executorMsgs = Executors.newFixedThreadPool(32,
-                                                                              groupedThreads("onos/bgp",
-                                                                                      "event-stats-%d"));
-
-    private final ExecutorService executorBarrier = Executors.newFixedThreadPool(4,
-                                                                                 groupedThreads("onos/bgp",
-                                                                                                "event-barrier-%d"));
     protected ConcurrentHashMap<BGPId, BGPPeer> connectedPeers = new ConcurrentHashMap<BGPId, BGPPeer>();
 
-    protected BGPPeerManager peerManager = new BGPPeerManager();
+    protected BGPPeerManagerImpl peerManager = new BGPPeerManagerImpl();
     final Controller ctrl = new Controller(this);
 
     private BGPConfig bgpconfig = new BGPConfig();
@@ -84,11 +73,11 @@
 
     @Override
     public void writeMsg(BGPId bgpId, BGPMessage msg) {
-        // TODO: Send message
+        this.getPeer(bgpId).sendMessage(msg);
     }
 
     @Override
-    public void processBGPPacket(BGPId bgpId, BGPMessage msg) {
+    public void processBGPPacket(BGPId bgpId, BGPMessage msg) throws BGPParseException {
 
         switch (msg.getType()) {
         case OPEN:
@@ -122,18 +111,12 @@
      * Implementation of an BGP Peer which is responsible for keeping track of connected peers and the state in which
      * they are.
      */
-    public class BGPPeerManager {
+    public class BGPPeerManagerImpl implements BgpPeerManager {
 
-        private final Logger log = LoggerFactory.getLogger(BGPPeerManager.class);
+        private final Logger log = LoggerFactory.getLogger(BGPPeerManagerImpl.class);
         private final Lock peerLock = new ReentrantLock();
 
-        /**
-         * Add a BGP peer that has just connected to the system.
-         *
-         * @param bgpId the id of bgp peer to add
-         * @param bgpPeer the actual bgp peer object.
-         * @return true if added, false otherwise.
-         */
+        @Override
         public boolean addConnectedPeer(BGPId bgpId, BGPPeer bgpPeer) {
 
             if (connectedPeers.get(bgpId) != null) {
@@ -147,119 +130,49 @@
             }
         }
 
-        /**
-         * Checks if the activation for this bgp peer is valid.
-         *
-         * @param bgpId the id of bgp peer to check
-         * @return true if valid, false otherwise
-         */
+        @Override
         public boolean isPeerConnected(BGPId bgpId) {
             if (connectedPeers.get(bgpId) == null) {
-                this.log.error("Trying to activate peer but is not in " + "connected peer: bgpIp {}. Aborting ..",
-                               bgpId.toString());
+                this.log.error("Is peer connected: bgpIp {}.", bgpId.toString());
                 return false;
             }
 
             return true;
         }
 
-        /**
-         * Checks if the activation for this bgp peer is valid.
-         *
-         * @param routerid the routerid of bgp peer to check
-         * @return true if valid, false otherwise
-         */
-        public boolean isPeerConnected(String routerid) {
-
-            final BGPId bgpId;
-            bgpId = BGPId.bgpId(IpAddress.valueOf(routerid));
-
-            if (connectedPeers.get(bgpId) != null) {
-                this.log.info("Peer connection exist ");
-                return true;
-            }
-            this.log.info("Initiate connect request to " + "peer: bgpIp {}", bgpId.toString());
-
-            return false;
-        }
-
-        /**
-         * Clear all state in controller peer maps for a bgp peer that has
-         * disconnected from the local controller.
-         *
-         * @param bgpId the id of bgp peer to remove.
-         */
+        @Override
         public void removeConnectedPeer(BGPId bgpId) {
             connectedPeers.remove(bgpId);
         }
 
-        /**
-         * Clear all state in controller peer maps for a bgp peer that has
-         * disconnected from the local controller.
-         *
-         * @param routerid the router id of bgp peer to remove.
-         */
-        public void removeConnectedPeer(String routerid) {
-            final BGPId bgpId;
-
-            bgpId = BGPId.bgpId(IpAddress.valueOf(routerid));
-
-            connectedPeers.remove(bgpId);
-        }
-
-        /**
-          * Gets bgp peer for connected peer map.
-          *
-          * @param routerid router id
-          * @return peer if available, null otherwise
-          */
-        public BGPPeer getPeer(String routerid) {
-            final BGPId bgpId;
-            bgpId = BGPId.bgpId(IpAddress.valueOf(routerid));
-
+        @Override
+        public BGPPeer getPeer(BGPId bgpId) {
             return connectedPeers.get(bgpId);
         }
 
         /**
-          * Gets bgp peer instance.
-          *
-          * @param bgpId bgp identifier.
-          * @param pv bgp version.
-          * @param pktStats packet statistics.
-          * @return BGPPeer peer instance.
-          */
-        public BGPPeer getBGPPeerInstance(BGPId bgpId, BGPVersion pv, BGPPacketStats pktStats) {
-            BGPPeer bgpPeer = new BGPPeerImpl();
-            bgpPeer.init(bgpId, pv, pktStats);
+         * Gets bgp peer instance.
+         *
+         * @param bgpController controller instance.
+         * @param sessionInfo bgp session info.
+         * @param pktStats packet statistics.
+         * @return BGPPeer peer instance.
+         */
+        public BGPPeer getBGPPeerInstance(BGPController bgpController, BgpSessionInfoImpl sessionInfo,
+                                          BGPPacketStatsImpl pktStats) {
+            BGPPeer bgpPeer = new BGPPeerImpl(bgpController, sessionInfo, pktStats);
             return bgpPeer;
         }
 
     }
 
-    /**
-      * Gets controller instance.
-      *
-      * @return Controller instance.
-      */
-    public Controller getController() {
-        return ctrl;
-    }
-
-    /**
-      * Gets connected peers.
-      *
-      * @return connectedPeers from connected Peers Map.
-      */
-    public ConcurrentHashMap<BGPId, BGPPeer> getConnectedPeers() {
+    @Override
+    public ConcurrentHashMap<BGPId, BGPPeer> connectedPeers() {
         return connectedPeers;
     }
 
-    /**
-      * Gets peer manager.
-      *
-      * @return peerManager.
-      */
-    public BGPPeerManager getPeerManager() {
+    @Override
+    public BGPPeerManagerImpl peerManager() {
         return peerManager;
     }
 
@@ -269,7 +182,7 @@
     }
 
     @Override
-    public int getBGPConnNumber() {
+    public int connectedPeerCount() {
         return connectedPeers.size();
     }
-}
\ No newline at end of file
+}
diff --git a/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPPeerImpl.java b/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPPeerImpl.java
index 212b24d..45f7463 100755
--- a/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPPeerImpl.java
+++ b/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPPeerImpl.java
@@ -24,11 +24,12 @@
 
 import org.jboss.netty.channel.Channel;
 import org.onlab.packet.IpAddress;
-import org.onosproject.bgp.controller.BGPId;
-import org.onosproject.bgp.controller.BGPPacketStats;
+import org.onosproject.bgp.controller.BGPController;
 import org.onosproject.bgp.controller.BGPPeer;
+import org.onosproject.bgp.controller.BgpSessionInfo;
+import org.onosproject.bgpio.protocol.BGPFactories;
+import org.onosproject.bgpio.protocol.BGPFactory;
 import org.onosproject.bgpio.protocol.BGPMessage;
-import org.onosproject.bgpio.protocol.BGPVersion;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -43,19 +44,31 @@
 
     private static final String SHUTDOWN_MSG = "Worker has already been shutdown";
 
+    private BGPController bgpController;
     private Channel channel;
     protected String channelId;
     private boolean connected;
     protected boolean isHandShakeComplete = false;
-    public BGPSessionInfo sessionInfo;
+    private BgpSessionInfo sessionInfo;
     private BGPPacketStatsImpl pktStats;
 
+
     @Override
-    public void init(BGPId bgpId, BGPVersion bgpVersion, BGPPacketStats pktStats) {
-        this.sessionInfo.setRemoteBgpId(bgpId);
-        this.sessionInfo.setRemoteBgpVersion(bgpVersion);
-        this.pktStats = (BGPPacketStatsImpl) pktStats;
-        this.sessionInfo = new BGPSessionInfo();
+    public BgpSessionInfo sessionInfo() {
+        return sessionInfo;
+    }
+
+    /**
+     * Initialize peer.
+     *
+     *@param bgpController controller instance
+     *@param sessionInfo bgp session info
+     *@param pktStats packet statistics
+     */
+    public BGPPeerImpl(BGPController bgpController, BgpSessionInfo sessionInfo, BGPPacketStatsImpl pktStats) {
+        this.bgpController = bgpController;
+        this.sessionInfo = sessionInfo;
+        this.pktStats = pktStats;
     }
 
     // ************************
@@ -129,53 +142,9 @@
         return channelId;
     }
 
-    // ************************
-    // BGP Peer features related
-    // ************************
-
     @Override
-    public final BGPId getBGPId() {
-        return this.sessionInfo.getRemoteBgpId();
-    };
-
-    @Override
-    public final String getStringId() {
-        return this.sessionInfo.getRemoteBgpId().toString();
-    }
-
-    @Override
-    public final void setBgpPeerVersion(BGPVersion peerVersion) {
-        this.sessionInfo.setRemoteBgpVersion(peerVersion);
-    }
-
-    @Override
-    public void setBgpPeerASNum(short peerASNum) {
-        this.sessionInfo.setRemoteBgpASNum(peerASNum);
-    }
-
-    @Override
-    public void setBgpPeerHoldTime(short peerHoldTime) {
-        this.sessionInfo.setRemoteBgpHoldTime(peerHoldTime);
-    }
-
-    @Override
-    public void setBgpPeerIdentifier(int peerIdentifier) {
-        this.sessionInfo.setRemoteBgpIdentifier(peerIdentifier);
-    }
-
-    @Override
-    public int getBgpPeerIdentifier() {
-        return this.sessionInfo.getRemoteBgpIdentifier();
-    }
-
-    @Override
-    public int getNegotiatedHoldTime() {
-        return this.sessionInfo.getNegotiatedholdTime();
-    }
-
-    @Override
-    public void setNegotiatedHoldTime(short negotiatedHoldTime) {
-        this.sessionInfo.setNegotiatedholdTime(negotiatedHoldTime);
+    public BGPFactory factory() {
+        return BGPFactories.getFactory(sessionInfo.remoteBgpVersion());
     }
 
     @Override
@@ -185,7 +154,8 @@
 
     @Override
     public String toString() {
-        return MoreObjects.toStringHelper(getClass()).omitNullValues().add("channel", channelId())
-                .add("bgpId", getBGPId()).toString();
+        return MoreObjects.toStringHelper(getClass()).omitNullValues()
+                                       .add("channel", channelId())
+                                       .add("bgpId", sessionInfo().remoteBgpId()).toString();
     }
 }
diff --git a/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPPipelineFactory.java b/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPPipelineFactory.java
index b2ca507..e6f09f2 100755
--- a/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPPipelineFactory.java
+++ b/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPPipelineFactory.java
@@ -23,6 +23,7 @@
 import org.jboss.netty.util.ExternalResourceReleasable;
 import org.jboss.netty.util.HashedWheelTimer;
 import org.jboss.netty.util.Timer;
+import org.onosproject.bgp.controller.BGPController;
 
 /**
  * Creates a ChannelPipeline for a server-side bgp channel.
@@ -32,30 +33,36 @@
 
     static final Timer TIMER = new HashedWheelTimer();
     protected ReadTimeoutHandler readTimeoutHandler;
-    BGPControllerImpl bgpCtrlImpl;
+    private boolean isBgpServ;
+    private BGPController bgpController;
 
     /**
      * Constructor to initialize the values.
      *
-     * @param ctrlImpl parent ctrlImpl
-     * @param isServBgp if it is a server or not
+     * @param bgpController parent controller
+     * @param isBgpServ if it is a server or remote peer
      */
-    public BGPPipelineFactory(BGPControllerImpl ctrlImpl, boolean isServBgp) {
+    public BGPPipelineFactory(BGPController bgpController, boolean isBgpServ) {
         super();
-        bgpCtrlImpl = ctrlImpl;
-        /* hold time*/
-        readTimeoutHandler = new ReadTimeoutHandler(TIMER, bgpCtrlImpl.getConfig().getHoldTime());
+        this.isBgpServ = isBgpServ;
+        this.bgpController = bgpController;
+        /* hold time */
+        this.readTimeoutHandler = new ReadTimeoutHandler(TIMER, bgpController.getConfig().getHoldTime());
     }
 
     @Override
     public ChannelPipeline getPipeline() throws Exception {
-        BGPChannelHandler handler = new BGPChannelHandler(bgpCtrlImpl);
+        BGPChannelHandler handler = new BGPChannelHandler(bgpController);
 
         ChannelPipeline pipeline = Channels.pipeline();
         pipeline.addLast("bgpmessagedecoder", new BGPMessageDecoder());
         pipeline.addLast("bgpmessageencoder", new BGPMessageEncoder());
         pipeline.addLast("holdTime", readTimeoutHandler);
-        pipeline.addLast("PassiveHandler", handler);
+        if (isBgpServ) {
+            pipeline.addLast("PassiveHandler", handler);
+        } else {
+            pipeline.addLast("ActiveHandler", handler);
+        }
 
         return pipeline;
     }
diff --git a/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPSessionInfo.java b/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPSessionInfo.java
deleted file mode 100755
index 207d783..0000000
--- a/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPSessionInfo.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * 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.bgp.controller.impl;
-
-import org.onosproject.bgp.controller.BGPId;
-import org.onosproject.bgpio.protocol.BGPVersion;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Class maintains BGP peer session info.
- */
-public class BGPSessionInfo {
-
-    protected final Logger log = LoggerFactory.getLogger(BGPSessionInfo.class);
-    private BGPId remoteBgpId;
-    private BGPVersion remoteBgpVersion;
-    private short remoteBgpASNum;
-    private short remoteBgpholdTime;
-    private int remoteBgpIdentifier;
-    private short negotiatedholdTime;
-
-    /**
-     * Gets the negotiated hold time for the session.
-     *
-     * @return negotiated hold time.
-     */
-    public short getNegotiatedholdTime() {
-        return negotiatedholdTime;
-    }
-
-    /**
-     * Sets the negotiated hold time for the session.
-     *
-     * @param negotiatedholdTime negotiated hold time.
-     */
-    public void setNegotiatedholdTime(short negotiatedholdTime) {
-        this.negotiatedholdTime = negotiatedholdTime;
-    }
-
-    /**
-     * Gets the BGP ID of BGP peer.
-     *
-     * @return bgp ID.
-     */
-    public BGPId getRemoteBgpId() {
-        return remoteBgpId;
-    }
-
-    /**
-     * Sets the BGP ID of bgp peer.
-     *
-     * @param bgpId BGP ID to set.
-     */
-    public void setRemoteBgpId(BGPId bgpId) {
-        log.debug("Remote BGP ID {}", bgpId);
-        this.remoteBgpId = bgpId;
-    }
-
-    /**
-     * Gets the BGP version of peer.
-     *
-     * @return bgp version.
-     */
-    public BGPVersion getRemoteBgpVersion() {
-        return remoteBgpVersion;
-    }
-
-    /**
-     * Sets the BGP version for this bgp peer.
-     *
-     * @param bgpVersion bgp version to set.
-     */
-    public void setRemoteBgpVersion(BGPVersion bgpVersion) {
-        log.debug("Remote BGP version {}", bgpVersion);
-        this.remoteBgpVersion = bgpVersion;
-    }
-
-    /**
-     * Gets the BGP remote bgp AS number.
-     *
-     * @return remoteBgpASNum peer AS number.
-     */
-    public short getRemoteBgpASNum() {
-        return remoteBgpASNum;
-    }
-
-    /**
-     * Sets the AS Number for this bgp peer.
-     *
-     * @param bgpASNum the autonomous system number value to set.
-     */
-    public void setRemoteBgpASNum(short bgpASNum) {
-        log.debug("Remote BGP AS number {}", bgpASNum);
-        this.remoteBgpASNum = bgpASNum;
-    }
-
-    /**
-     * Gets the BGP peer hold time.
-     *
-     * @return bgp hold time.
-     */
-    public short getRemoteBgpHoldTime() {
-        return remoteBgpholdTime;
-    }
-
-    /**
-     * Sets the hold time for this bgp peer.
-     *
-     * @param holdTime the hold timer value to set.
-     */
-    public void setRemoteBgpHoldTime(short holdTime) {
-        log.debug("Remote BGP HoldTime {}", holdTime);
-        this.remoteBgpholdTime = holdTime;
-    }
-
-    /**
-     * Gets the BGP version for this bgp peer.
-     *
-     * @return bgp identifier.
-     */
-    public int getRemoteBgpIdentifier() {
-        return remoteBgpIdentifier;
-    }
-
-    /**
-     * Sets the peer identifier value.
-     *
-     * @param bgpIdentifier the bgp peer identifier value.
-     */
-    public void setRemoteBgpIdentifier(int bgpIdentifier) {
-        log.debug("Remote BGP Identifier {}", bgpIdentifier);
-        this.remoteBgpIdentifier = bgpIdentifier;
-    }
-}
diff --git a/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpSessionInfoImpl.java b/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpSessionInfoImpl.java
new file mode 100755
index 0000000..6705b46
--- /dev/null
+++ b/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpSessionInfoImpl.java
@@ -0,0 +1,93 @@
+/*
+ * 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.bgp.controller.impl;
+
+import org.onosproject.bgp.controller.BGPId;
+import org.onosproject.bgp.controller.BgpSessionInfo;
+import org.onosproject.bgpio.protocol.BGPVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Class maintains BGP peer session info.
+ */
+public class BgpSessionInfoImpl implements BgpSessionInfo {
+
+    protected final Logger log = LoggerFactory.getLogger(BgpSessionInfoImpl.class);
+    private BGPId remoteBgpId;
+    private BGPVersion remoteBgpVersion;
+    private long remoteBgpASNum;
+    private short remoteBgpholdTime;
+    private int remoteBgpIdentifier;
+    private short negotiatedholdTime;
+    private boolean isIbgpSession;
+
+    /**
+     * Initialize session info.
+     *
+     *@param remoteBgpId remote peer id
+     *@param remoteBgpVersion remote peer version
+     *@param remoteBgpASNum remote peer AS number
+     *@param remoteBgpholdTime remote peer hold time
+     *@param remoteBgpIdentifier remote peer identifier
+     *@param negotiatedholdTime negotiated hold time
+     *@param isIbgpSession session type ibgp/ebgp
+     */
+    public BgpSessionInfoImpl(BGPId remoteBgpId, BGPVersion remoteBgpVersion, long remoteBgpASNum,
+                              short remoteBgpholdTime, int remoteBgpIdentifier, short negotiatedholdTime,
+                              boolean isIbgpSession) {
+        this.remoteBgpId = remoteBgpId;
+        this.remoteBgpVersion = remoteBgpVersion;
+        this.remoteBgpASNum = remoteBgpASNum;
+        this.remoteBgpholdTime = remoteBgpholdTime;
+        this.remoteBgpIdentifier = remoteBgpIdentifier;
+        this.negotiatedholdTime = negotiatedholdTime;
+        this.isIbgpSession = isIbgpSession;
+    }
+
+    @Override
+    public boolean isIbgpSession() {
+        return isIbgpSession;
+    }
+
+    @Override
+    public short negotiatedholdTime() {
+        return negotiatedholdTime;
+    }
+
+    @Override
+    public BGPId remoteBgpId() {
+        return remoteBgpId;
+    }
+
+    @Override
+    public BGPVersion remoteBgpVersion() {
+        return remoteBgpVersion;
+    }
+
+    @Override
+    public long remoteBgpASNum() {
+        return remoteBgpASNum;
+    }
+
+    @Override
+    public short remoteBgpHoldTime() {
+        return remoteBgpholdTime;
+    }
+
+    @Override
+    public int remoteBgpIdentifier() {
+        return remoteBgpIdentifier;
+    }
+}
diff --git a/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/Controller.java b/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/Controller.java
index 402e8c9..5eed3cf 100755
--- a/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/Controller.java
+++ b/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/Controller.java
@@ -29,6 +29,10 @@
 import org.jboss.netty.channel.group.ChannelGroup;
 import org.jboss.netty.channel.group.DefaultChannelGroup;
 import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
+import org.onosproject.bgp.controller.BGPController;
+import org.onosproject.bgpio.protocol.BGPFactories;
+import org.onosproject.bgpio.protocol.BGPFactory;
+import org.onosproject.bgpio.protocol.BGPVersion;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -38,31 +42,41 @@
  */
 public class Controller {
 
-    protected static final Logger log = LoggerFactory.getLogger(Controller.class);
+    private static final Logger log = LoggerFactory.getLogger(Controller.class);
+
+    private static final BGPFactory FACTORY4 = BGPFactories.getFactory(BGPVersion.BGP_4);
 
     private ChannelGroup cg;
 
     // Configuration options
     private static final short BGP_PORT_NUM = 179;
-    private int workerThreads = 16;
+    private final int workerThreads = 16;
 
     // Start time of the controller
-    protected long systemStartTime;
+    private long systemStartTime;
 
     private NioServerSocketChannelFactory serverExecFactory;
+    private BGPController bgpController;
 
     // Perf. related configuration
-    protected static final int SEND_BUFFER_SIZE = 4 * 1024 * 1024;
-
-    BGPControllerImpl bgpCtrlImpl;
+    private static final int SEND_BUFFER_SIZE = 4 * 1024 * 1024;
 
     /**
-     * Constructor to initialize parameter.
+     * Constructor to initialize the values.
      *
-     * @param bgpCtrlImpl BGP controller Impl instance
+     * @param bgpController bgp controller instance
      */
-    public Controller(BGPControllerImpl bgpCtrlImpl) {
-        this.bgpCtrlImpl = bgpCtrlImpl;
+    public Controller(BGPController bgpController) {
+        this.bgpController = bgpController;
+    }
+
+    /**
+     * Returns factory version for processing BGP messages.
+     *
+     * @return instance of factory version
+     */
+    static BGPFactory getBGPMessageFactory4() {
+        return FACTORY4;
     }
 
     // ***************
@@ -95,7 +109,7 @@
             bootstrap.setOption("child.tcpNoDelay", true);
             bootstrap.setOption("child.sendBufferSize", Controller.SEND_BUFFER_SIZE);
 
-            ChannelPipelineFactory pfact = new BGPPipelineFactory(bgpCtrlImpl, true);
+            ChannelPipelineFactory pfact = new BGPPipelineFactory(bgpController, true);
 
             bootstrap.setPipelineFactory(pfact);
             InetSocketAddress sa = new InetSocketAddress(getBgpPortNum());