diff --git a/apps/routing/common/src/main/java/org/onosproject/routing/bgp/BgpSessionManager.java b/apps/routing/common/src/main/java/org/onosproject/routing/bgp/BgpSessionManager.java
new file mode 100644
index 0000000..a8cf5d8
--- /dev/null
+++ b/apps/routing/common/src/main/java/org/onosproject/routing/bgp/BgpSessionManager.java
@@ -0,0 +1,353 @@
+/*
+ * Copyright 2017-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.routing.bgp;
+
+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.Modified;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.jboss.netty.bootstrap.ServerBootstrap;
+import org.jboss.netty.channel.Channel;
+import org.jboss.netty.channel.ChannelException;
+import org.jboss.netty.channel.ChannelFactory;
+import org.jboss.netty.channel.ChannelPipeline;
+import org.jboss.netty.channel.ChannelPipelineFactory;
+import org.jboss.netty.channel.Channels;
+import org.jboss.netty.channel.group.ChannelGroup;
+import org.jboss.netty.channel.group.DefaultChannelGroup;
+import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip4Prefix;
+import org.onlab.packet.Ip6Prefix;
+import org.onlab.packet.IpPrefix;
+import org.onosproject.incubator.net.routing.Route;
+import org.onosproject.incubator.net.routing.RouteAdminService;
+import org.osgi.service.component.ComponentContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.util.Collection;
+import java.util.Dictionary;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import static java.util.concurrent.Executors.newCachedThreadPool;
+import static org.onlab.util.Tools.groupedThreads;
+
+/**
+ * BGP Session Manager class.
+ */
+@Component(immediate = true, enabled = false)
+@Service
+public class BgpSessionManager implements BgpInfoService {
+    private static final Logger log =
+            LoggerFactory.getLogger(BgpSessionManager.class);
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected RouteAdminService routeService;
+
+    boolean isShutdown = true;
+    private Channel serverChannel;     // Listener for incoming BGP connections
+    private ServerBootstrap serverBootstrap;
+    private ChannelGroup allChannels = new DefaultChannelGroup();
+    private ConcurrentMap<SocketAddress, BgpSession> bgpSessions =
+            new ConcurrentHashMap<>();
+    private Ip4Address myBgpId;        // Same BGP ID for all peers
+
+    private BgpRouteSelector bgpRouteSelector = new BgpRouteSelector(this);
+    private ConcurrentMap<Ip4Prefix, BgpRouteEntry> bgpRoutes4 =
+            new ConcurrentHashMap<>();
+    private ConcurrentMap<Ip6Prefix, BgpRouteEntry> bgpRoutes6 =
+            new ConcurrentHashMap<>();
+
+    private static final int DEFAULT_BGP_PORT = 2000;
+    private int bgpPort;
+
+    @Activate
+    protected void activate(ComponentContext context) {
+        readComponentConfiguration(context);
+        start();
+        log.info("BgpSessionManager started");
+    }
+
+    @Deactivate
+    protected void deactivate() {
+        stop();
+        log.info("BgpSessionManager stopped");
+    }
+
+    /**
+     * Extracts properties from the component configuration context.
+     *
+     * @param context the component context
+     */
+    private void readComponentConfiguration(ComponentContext context) {
+        Dictionary<?, ?> properties = context.getProperties();
+        try {
+            String strPort = (String) properties.get("bgpPort");
+            if (strPort != null) {
+                bgpPort = Integer.parseInt(strPort);
+            } else {
+                bgpPort = DEFAULT_BGP_PORT;
+            }
+        } catch (NumberFormatException | ClassCastException e) {
+            bgpPort = DEFAULT_BGP_PORT;
+        }
+        log.debug("BGP port is set to {}", bgpPort);
+    }
+
+    @Modified
+    public void modified(ComponentContext context) {
+        // Blank @Modified method to catch modifications to the context.
+        // If no @Modified method exists, it seems @Activate is called again
+        // when the context is modified.
+    }
+
+    /**
+     * Checks whether the BGP Session Manager is shutdown.
+     *
+     * @return true if the BGP Session Manager is shutdown, otherwise false
+     */
+    boolean isShutdown() {
+        return this.isShutdown;
+    }
+
+    /**
+     * Gets the BGP sessions.
+     *
+     * @return the BGP sessions
+     */
+    @Override
+    public Collection<BgpSession> getBgpSessions() {
+        return bgpSessions.values();
+    }
+
+    /**
+     * Gets the selected IPv4 BGP routes among all BGP sessions.
+     *
+     * @return the selected IPv4 BGP routes among all BGP sessions
+     */
+    @Override
+    public Collection<BgpRouteEntry> getBgpRoutes4() {
+        return bgpRoutes4.values();
+    }
+
+    /**
+     * Gets the selected IPv6 BGP routes among all BGP sessions.
+     *
+     * @return the selected IPv6 BGP routes among all BGP sessions
+     */
+    @Override
+    public Collection<BgpRouteEntry> getBgpRoutes6() {
+        return bgpRoutes6.values();
+    }
+
+    /**
+     * Finds a BGP route for a prefix. The prefix can be either IPv4 or IPv6.
+     *
+     * @param prefix the prefix to use
+     * @return the BGP route if found, otherwise null
+     */
+    BgpRouteEntry findBgpRoute(IpPrefix prefix) {
+        if (prefix.isIp4()) {
+            return bgpRoutes4.get(prefix.getIp4Prefix());               // IPv4
+        }
+        return bgpRoutes6.get(prefix.getIp6Prefix());                   // IPv6
+    }
+
+    /**
+     * Adds a BGP route. The route can be either IPv4 or IPv6.
+     *
+     * @param bgpRouteEntry the BGP route entry to use
+     */
+    void addBgpRoute(BgpRouteEntry bgpRouteEntry) {
+        if (bgpRouteEntry.isIp4()) {
+            bgpRoutes4.put(bgpRouteEntry.prefix().getIp4Prefix(),       // IPv4
+                           bgpRouteEntry);
+        } else {
+            bgpRoutes6.put(bgpRouteEntry.prefix().getIp6Prefix(),       // IPv6
+                           bgpRouteEntry);
+        }
+    }
+
+    /**
+     * Removes a BGP route for a prefix. The prefix can be either IPv4 or IPv6.
+     *
+     * @param prefix the prefix to use
+     * @return true if the route was found and removed, otherwise false
+     */
+    boolean removeBgpRoute(IpPrefix prefix) {
+        if (prefix.isIp4()) {
+            return (bgpRoutes4.remove(prefix.getIp4Prefix()) != null);  // IPv4
+        }
+        return (bgpRoutes6.remove(prefix.getIp6Prefix()) != null);      // IPv6
+    }
+
+    /**
+     * Adds the channel for a BGP session.
+     *
+     * @param channel the channel to add
+     */
+    void addSessionChannel(Channel channel) {
+        allChannels.add(channel);
+    }
+
+    /**
+     * Removes the channel for a BGP session.
+     *
+     * @param channel the channel to remove
+     */
+    void removeSessionChannel(Channel channel) {
+        allChannels.remove(channel);
+    }
+
+    /**
+     * Processes the connection from a BGP peer.
+     *
+     * @param bgpSession the BGP session for the peer
+     * @return true if the connection can be established, otherwise false
+     */
+    boolean peerConnected(BgpSession bgpSession) {
+
+        // Test whether there is already a session from the same remote
+        if (bgpSessions.get(bgpSession.remoteInfo().address()) != null) {
+            return false;               // Duplicate BGP session
+        }
+        bgpSessions.put(bgpSession.remoteInfo().address(), bgpSession);
+
+        //
+        // If the first connection, set my BGP ID to the local address
+        // of the socket.
+        //
+        if (bgpSession.localInfo().address() instanceof InetSocketAddress) {
+            InetAddress inetAddr =
+                ((InetSocketAddress) bgpSession.localInfo().address()).getAddress();
+            Ip4Address ip4Address = Ip4Address.valueOf(inetAddr.getAddress());
+            updateMyBgpId(ip4Address);
+        }
+        return true;
+    }
+
+    /**
+     * Processes the disconnection from a BGP peer.
+     *
+     * @param bgpSession the BGP session for the peer
+     */
+    void peerDisconnected(BgpSession bgpSession) {
+        bgpSessions.remove(bgpSession.remoteInfo().address());
+    }
+
+    /**
+     * Conditionally updates the local BGP ID if it wasn't set already.
+     * <p/>
+     * NOTE: A BGP instance should use same BGP ID across all BGP sessions.
+     *
+     * @param ip4Address the IPv4 address to use as BGP ID
+     */
+    private synchronized void updateMyBgpId(Ip4Address ip4Address) {
+        if (myBgpId == null) {
+            myBgpId = ip4Address;
+            log.debug("BGP: My BGP ID is {}", myBgpId);
+        }
+    }
+
+    /**
+     * Gets the local BGP Identifier as an IPv4 address.
+     *
+     * @return the local BGP Identifier as an IPv4 address
+     */
+    Ip4Address getMyBgpId() {
+        return myBgpId;
+    }
+
+    /**
+     * Gets the BGP Route Selector.
+     *
+     * @return the BGP Route Selector
+     */
+    BgpRouteSelector getBgpRouteSelector() {
+        return bgpRouteSelector;
+    }
+
+    /**
+     * Sends updates routes to the route service.
+     *
+     * @param updates routes to update
+     */
+    void update(Collection<Route> updates) {
+        routeService.update(updates);
+    }
+
+    /**
+     * Sends withdrawn routes to the routes service.
+     *
+     * @param withdraws routes to withdraw
+     */
+    void withdraw(Collection<Route> withdraws) {
+        routeService.withdraw(withdraws);
+    }
+
+
+    public void start() {
+        log.debug("BGP Session Manager start.");
+        isShutdown = false;
+
+        ChannelFactory channelFactory = new NioServerSocketChannelFactory(
+                newCachedThreadPool(groupedThreads("onos/bgp", "sm-boss-%d", log)),
+                newCachedThreadPool(groupedThreads("onos/bgp", "sm-worker-%d", log)));
+        ChannelPipelineFactory pipelineFactory = () -> {
+            // Allocate a new session per connection
+            BgpSession bgpSessionHandler =
+                    new BgpSession(BgpSessionManager.this);
+            BgpFrameDecoder bgpFrameDecoder =
+                    new BgpFrameDecoder(bgpSessionHandler);
+
+            // Setup the processing pipeline
+            ChannelPipeline pipeline = Channels.pipeline();
+            pipeline.addLast("BgpFrameDecoder", bgpFrameDecoder);
+            pipeline.addLast("BgpSession", bgpSessionHandler);
+            return pipeline;
+        };
+        InetSocketAddress listenAddress =
+                new InetSocketAddress(bgpPort);
+
+        serverBootstrap = new ServerBootstrap(channelFactory);
+        // serverBootstrap.setOptions("reuseAddr", true);
+        serverBootstrap.setOption("child.keepAlive", true);
+        serverBootstrap.setOption("child.tcpNoDelay", true);
+        serverBootstrap.setPipelineFactory(pipelineFactory);
+        try {
+            serverChannel = serverBootstrap.bind(listenAddress);
+            allChannels.add(serverChannel);
+        } catch (ChannelException e) {
+            log.debug("Exception binding to BGP port {}: ",
+                      listenAddress.getPort(), e);
+        }
+    }
+
+    public void stop() {
+        isShutdown = true;
+        allChannels.close().awaitUninterruptibly();
+        serverBootstrap.releaseExternalResources();
+    }
+}
