diff --git a/apps/routing/pom.xml b/apps/routing/pom.xml
new file mode 100644
index 0000000..8656ebb
--- /dev/null
+++ b/apps/routing/pom.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>onos-apps</artifactId>
+        <groupId>org.onosproject</groupId>
+        <version>1.1.0-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>onos-app-routing</artifactId>
+
+    <packaging>bundle</packaging>
+    <description>Libraries for routing applications</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-app-routing-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-cli</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+	<dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onlab-thirdparty</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.karaf.shell</groupId>
+            <artifactId>org.apache.karaf.shell.console</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onlab-junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.easymock</groupId>
+            <artifactId>easymock</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+    </dependencies>
+
+</project>
diff --git a/apps/routing/src/main/java/org/onosproject/routing/Router.java b/apps/routing/src/main/java/org/onosproject/routing/Router.java
new file mode 100644
index 0000000..494c190
--- /dev/null
+++ b/apps/routing/src/main/java/org/onosproject/routing/Router.java
@@ -0,0 +1,523 @@
+/*
+ * Copyright 2014 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;
+
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.Multimaps;
+import com.google.common.collect.SetMultimap;
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
+import com.googlecode.concurrenttrees.common.KeyValuePair;
+import com.googlecode.concurrenttrees.radix.node.concrete.DefaultByteArrayNodeFactory;
+import com.googlecode.concurrenttrees.radixinverted.ConcurrentInvertedRadixTree;
+import com.googlecode.concurrenttrees.radixinverted.InvertedRadixTree;
+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.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onosproject.net.Host;
+import org.onosproject.net.host.HostEvent;
+import org.onosproject.net.host.HostListener;
+import org.onosproject.net.host.HostService;
+import org.onosproject.routingapi.BgpService;
+import org.onosproject.routingapi.FibEntry;
+import org.onosproject.routingapi.FibListener;
+import org.onosproject.routingapi.FibUpdate;
+import org.onosproject.routingapi.RouteEntry;
+import org.onosproject.routingapi.RouteListener;
+import org.onosproject.routingapi.RouteUpdate;
+import org.onosproject.routingapi.RoutingService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.LinkedBlockingQueue;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * This class processes route updates and maintains a Routing Information Base
+ * (RIB). After route updates have been processed and next hops have been
+ * resolved, FIB updates are sent to any listening FIB components.
+ */
+@Component(immediate = true)
+@Service
+public class Router implements RoutingService {
+
+    private static final Logger log = LoggerFactory.getLogger(Router.class);
+
+    // Route entries are stored in a radix tree.
+    // The key in this tree is the binary string of prefix of the route.
+    private InvertedRadixTree<RouteEntry> ribTable4;
+    private InvertedRadixTree<RouteEntry> ribTable6;
+
+    // Stores all incoming route updates in a queue.
+    private final BlockingQueue<Collection<RouteUpdate>> routeUpdatesQueue
+            = new LinkedBlockingQueue<>();
+
+    // Next-hop IP address to route entry mapping for next hops pending MAC resolution
+    private SetMultimap<IpAddress, RouteEntry> routesWaitingOnArp;
+
+    // The IPv4 address to MAC address mapping
+    private final Map<IpAddress, MacAddress> ip2Mac = new ConcurrentHashMap<>();
+
+    private FibListener fibComponent;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected HostService hostService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected BgpService bgpService;
+
+    private ExecutorService bgpUpdatesExecutor;
+    private final HostListener hostListener = new InternalHostListener();
+
+    @Activate
+    public void activate() {
+        ribTable4 = new ConcurrentInvertedRadixTree<>(
+                new DefaultByteArrayNodeFactory());
+        ribTable6 = new ConcurrentInvertedRadixTree<>(
+                new DefaultByteArrayNodeFactory());
+        routesWaitingOnArp = Multimaps.synchronizedSetMultimap(
+                HashMultimap.<IpAddress, RouteEntry>create());
+
+        bgpUpdatesExecutor = Executors.newSingleThreadExecutor(
+                new ThreadFactoryBuilder()
+                .setNameFormat("sdnip-bgp-updates-%d").build());
+    }
+
+    @Deactivate
+    public void deactivate() {
+        log.debug("Stopped");
+    }
+
+    @Override
+    public void start(FibListener listener) {
+        this.fibComponent = checkNotNull(listener);
+        this.hostService.addListener(hostListener);
+
+        bgpService.start(new InternalRouteListener(), 2000);
+
+        bgpUpdatesExecutor.execute(new Runnable() {
+            @Override
+            public void run() {
+                doUpdatesThread();
+            }
+        });
+    }
+
+    @Override
+    public void stop() {
+        bgpService.stop();
+
+        this.hostService.removeListener(hostListener);
+
+        // Stop the thread(s)
+        bgpUpdatesExecutor.shutdownNow();
+
+        synchronized (this) {
+            // Cleanup all local state
+            ribTable4 = new ConcurrentInvertedRadixTree<>(
+                new DefaultByteArrayNodeFactory());
+            ribTable6 = new ConcurrentInvertedRadixTree<>(
+                new DefaultByteArrayNodeFactory());
+            routeUpdatesQueue.clear();
+            routesWaitingOnArp.clear();
+            ip2Mac.clear();
+        }
+    }
+
+    /**
+     * Entry point for route updates.
+     *
+     * @param routeUpdates collection of route updates to process
+     */
+    private void update(Collection<RouteUpdate> routeUpdates) {
+        try {
+            routeUpdatesQueue.put(routeUpdates);
+        } catch (InterruptedException e) {
+            log.debug("Interrupted while putting on routeUpdatesQueue", e);
+            Thread.currentThread().interrupt();
+        }
+    }
+
+    /**
+     * Thread for handling route updates.
+     */
+    private void doUpdatesThread() {
+        boolean interrupted = false;
+        try {
+            while (!interrupted) {
+                try {
+                    Collection<RouteUpdate> routeUpdates =
+                        routeUpdatesQueue.take();
+                    processRouteUpdates(routeUpdates);
+                } catch (InterruptedException e) {
+                    log.debug("Interrupted while taking from updates queue", e);
+                    interrupted = true;
+                } catch (Exception e) {
+                    log.debug("exception", e);
+                }
+            }
+        } finally {
+            if (interrupted) {
+                Thread.currentThread().interrupt();
+            }
+        }
+    }
+
+    /**
+     * Gets all IPv4 routes from the RIB.
+     *
+     * @return all IPv4 routes from the RIB
+     */
+    public Collection<RouteEntry> getRoutes4() {
+        Iterator<KeyValuePair<RouteEntry>> it =
+            ribTable4.getKeyValuePairsForKeysStartingWith("").iterator();
+
+        List<RouteEntry> routes = new LinkedList<>();
+
+        while (it.hasNext()) {
+            KeyValuePair<RouteEntry> entry = it.next();
+            routes.add(entry.getValue());
+        }
+
+        return routes;
+    }
+
+    /**
+     * Gets all IPv6 routes from the RIB.
+     *
+     * @return all IPv6 routes from the RIB
+     */
+    public Collection<RouteEntry> getRoutes6() {
+        Iterator<KeyValuePair<RouteEntry>> it =
+            ribTable6.getKeyValuePairsForKeysStartingWith("").iterator();
+
+        List<RouteEntry> routes = new LinkedList<>();
+
+        while (it.hasNext()) {
+            KeyValuePair<RouteEntry> entry = it.next();
+            routes.add(entry.getValue());
+        }
+
+        return routes;
+    }
+
+    /**
+     * Finds a route in the RIB for a prefix. The prefix can be either IPv4 or
+     * IPv6.
+     *
+     * @param prefix the prefix to use
+     * @return the route if found, otherwise null
+     */
+    RouteEntry findRibRoute(IpPrefix prefix) {
+        String binaryString = RouteEntry.createBinaryString(prefix);
+        if (prefix.version() == Ip4Address.VERSION) {
+            // IPv4
+            return ribTable4.getValueForExactKey(binaryString);
+        }
+        // IPv6
+        return ribTable6.getValueForExactKey(binaryString);
+    }
+
+    /**
+     * Adds a route to the RIB. The route can be either IPv4 or IPv6.
+     *
+     * @param routeEntry the route entry to use
+     */
+    void addRibRoute(RouteEntry routeEntry) {
+        if (routeEntry.prefix().version() == Ip4Address.VERSION) {
+            // IPv4
+            ribTable4.put(RouteEntry.createBinaryString(routeEntry.prefix()),
+                          routeEntry);
+        } else {
+            // IPv6
+            ribTable6.put(RouteEntry.createBinaryString(routeEntry.prefix()),
+                          routeEntry);
+        }
+    }
+
+    /**
+     * Removes a route for a prefix from the RIB. 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 removeRibRoute(IpPrefix prefix) {
+        if (prefix.version() == Ip4Address.VERSION) {
+            // IPv4
+            return ribTable4.remove(RouteEntry.createBinaryString(prefix));
+        }
+        // IPv6
+        return ribTable6.remove(RouteEntry.createBinaryString(prefix));
+    }
+
+    /**
+     * Processes route updates.
+     *
+     * @param routeUpdates the route updates to process
+     */
+    void processRouteUpdates(Collection<RouteUpdate> routeUpdates) {
+        synchronized (this) {
+            Collection<IpPrefix> withdrawPrefixes = new LinkedList<>();
+            Collection<FibUpdate> fibUpdates = new LinkedList<>();
+            Collection<FibUpdate> fibWithdraws = new LinkedList<>();
+
+            for (RouteUpdate update : routeUpdates) {
+                switch (update.type()) {
+                case UPDATE:
+                    FibEntry fib = processRouteAdd(update.routeEntry(),
+                                                    withdrawPrefixes);
+                    if (fib != null) {
+                        fibUpdates.add(new FibUpdate(FibUpdate.Type.UPDATE, fib));
+                    }
+
+                    break;
+                case DELETE:
+                    processRouteDelete(update.routeEntry(), withdrawPrefixes);
+
+                    break;
+                default:
+                    log.error("Unknown update Type: {}", update.type());
+                    break;
+                }
+            }
+
+            withdrawPrefixes.forEach(p -> fibWithdraws.add(new FibUpdate(
+                    FibUpdate.Type.DELETE, new FibEntry(p, null, null))));
+
+            if (!fibUpdates.isEmpty() || !fibWithdraws.isEmpty()) {
+                fibComponent.update(fibUpdates, fibWithdraws);
+            }
+        }
+    }
+
+    /**
+     * Processes adding a route entry.
+     * <p>
+     * The route entry is added to the radix tree. If there was an existing
+     * next hop for this prefix, but the next hop was different, then the
+     * old route entry is deleted.
+     * </p>
+     * <p>
+     * NOTE: Currently, we don't handle routes if the next hop is within the
+     * SDN domain.
+     * </p>
+     *
+     * @param routeEntry the route entry to add
+     * @param withdrawPrefixes the collection of accumulated prefixes whose
+     * intents will be withdrawn
+     * @return the corresponding FIB entry change, or null
+     */
+    private FibEntry processRouteAdd(
+                RouteEntry routeEntry,
+                Collection<IpPrefix> withdrawPrefixes) {
+        log.debug("Processing route add: {}", routeEntry);
+
+        // Find the old next-hop if we are updating an old route entry
+        IpAddress oldNextHop = null;
+        RouteEntry oldRouteEntry = findRibRoute(routeEntry.prefix());
+        if (oldRouteEntry != null) {
+            oldNextHop = oldRouteEntry.nextHop();
+        }
+
+        // Add the new route to the RIB
+        addRibRoute(routeEntry);
+
+        if (oldNextHop != null) {
+            if (oldNextHop.equals(routeEntry.nextHop())) {
+                return null;            // No change
+            }
+            //
+            // Update an existing nexthop for the prefix.
+            // We need to remove the old flows for this prefix from the
+            // switches before the new flows are added.
+            //
+            withdrawPrefixes.add(routeEntry.prefix());
+        }
+
+        if (routeEntry.nextHop().isZero()) {
+            // Route originated by SDN domain
+            // We don't handle these at the moment
+            log.debug("Own route {} to {}",
+                      routeEntry.prefix(), routeEntry.nextHop());
+            return null;
+        }
+
+        //
+        // Find the MAC address of next hop router for this route entry.
+        // If the MAC address can not be found in ARP cache, then this prefix
+        // will be put in routesWaitingOnArp queue. Otherwise, generate
+        // a new route intent.
+        //
+
+        // Monitor the IP address for updates of the MAC address
+        hostService.startMonitoringIp(routeEntry.nextHop());
+
+        // Check if we know the MAC address of the next hop
+        MacAddress nextHopMacAddress = ip2Mac.get(routeEntry.nextHop());
+        if (nextHopMacAddress == null) {
+            Set<Host> hosts = hostService.getHostsByIp(routeEntry.nextHop());
+            if (!hosts.isEmpty()) {
+                nextHopMacAddress = hosts.iterator().next().mac();
+            }
+            if (nextHopMacAddress != null) {
+                ip2Mac.put(routeEntry.nextHop(), nextHopMacAddress);
+            }
+        }
+        if (nextHopMacAddress == null) {
+            routesWaitingOnArp.put(routeEntry.nextHop(), routeEntry);
+            return null;
+        }
+        return new FibEntry(routeEntry.prefix(), routeEntry.nextHop(),
+                             nextHopMacAddress);
+    }
+
+    /**
+     * Processes the deletion of a route entry.
+     * <p>
+     * The prefix for the routing entry is removed from radix tree.
+     * If the operation is successful, the prefix is added to the collection
+     * of prefixes whose intents that will be withdrawn.
+     * </p>
+     *
+     * @param routeEntry the route entry to delete
+     * @param withdrawPrefixes the collection of accumulated prefixes whose
+     * intents will be withdrawn
+     */
+    private void processRouteDelete(RouteEntry routeEntry,
+                                    Collection<IpPrefix> withdrawPrefixes) {
+        log.debug("Processing route delete: {}", routeEntry);
+        boolean isRemoved = removeRibRoute(routeEntry.prefix());
+
+        if (isRemoved) {
+            //
+            // Only withdraw intents if an entry was actually removed from the
+            // tree. If no entry was removed, the <prefix, nexthop> wasn't
+            // there so it's probably already been removed and we don't
+            // need to do anything.
+            //
+            withdrawPrefixes.add(routeEntry.prefix());
+        }
+
+        routesWaitingOnArp.remove(routeEntry.nextHop(), routeEntry);
+    }
+
+    /**
+     * Signals the Router that the MAC to IP mapping has potentially been
+     * updated. This has the effect of updating the MAC address for any
+     * installed prefixes if it has changed, as well as installing any pending
+     * prefixes that were waiting for MAC resolution.
+     *
+     * @param ipAddress the IP address that an event was received for
+     * @param macAddress the most recently known MAC address for the IP address
+     */
+    private void updateMac(IpAddress ipAddress, MacAddress macAddress) {
+        log.debug("Received updated MAC info: {} => {}", ipAddress,
+                  macAddress);
+
+        //
+        // We synchronize on "this" to prevent changes to the Radix tree
+        // while we're pushing intents. If the tree changes, the
+        // tree and the intents could get out of sync.
+        //
+        synchronized (this) {
+            Collection<FibUpdate> submitFibEntries = new LinkedList<>();
+
+            Set<RouteEntry> routesToPush =
+                routesWaitingOnArp.removeAll(ipAddress);
+
+            for (RouteEntry routeEntry : routesToPush) {
+                // These will always be adds
+                RouteEntry foundRouteEntry = findRibRoute(routeEntry.prefix());
+                if (foundRouteEntry != null &&
+                    foundRouteEntry.nextHop().equals(routeEntry.nextHop())) {
+                    // We only push FIB updates if the prefix is still in the
+                    // radix tree and the next hop is the same as our entry.
+                    // The prefix could have been removed while we were waiting
+                    // for the ARP, or the next hop could have changed.
+                    submitFibEntries.add(new FibUpdate(FibUpdate.Type.UPDATE,
+                                                       new FibEntry(routeEntry.prefix(),
+                                                       ipAddress, macAddress)));
+                } else {
+                    log.debug("{} has been revoked before the MAC was resolved",
+                              routeEntry);
+                }
+            }
+
+            if (!submitFibEntries.isEmpty()) {
+                fibComponent.update(submitFibEntries, Collections.emptyList());
+            }
+
+            ip2Mac.put(ipAddress, macAddress);
+        }
+    }
+
+    /**
+     * Listener for host events.
+     */
+    class InternalHostListener implements HostListener {
+        @Override
+        public void event(HostEvent event) {
+            log.debug("Received HostEvent {}", event);
+
+            Host host = event.subject();
+            switch (event.type()) {
+            case HOST_ADDED:
+                // FALLTHROUGH
+            case HOST_UPDATED:
+                for (IpAddress ipAddress : host.ipAddresses()) {
+                    updateMac(ipAddress, host.mac());
+                }
+                break;
+            case HOST_REMOVED:
+                for (IpAddress ipAddress : host.ipAddresses()) {
+                    ip2Mac.remove(ipAddress);
+                }
+                break;
+            default:
+                break;
+            }
+        }
+    }
+
+    /**
+     * Listener for route events.
+     */
+    private class InternalRouteListener implements RouteListener {
+        @Override
+        public void update(Collection<RouteUpdate> routeUpdates) {
+            Router.this.update(routeUpdates);
+        }
+    }
+}
diff --git a/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpConstants.java b/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpConstants.java
new file mode 100644
index 0000000..96d74e2
--- /dev/null
+++ b/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpConstants.java
@@ -0,0 +1,553 @@
+/*
+ * Copyright 2014 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;
+
+/**
+ * BGP related constants.
+ */
+public final class BgpConstants {
+    /**
+     * Default constructor.
+     * <p>
+     * The constructor is private to prevent creating an instance of
+     * this utility class.
+     */
+    private BgpConstants() {
+    }
+
+    /** BGP port number (RFC 4271). */
+    public static final int BGP_PORT = 179;
+
+    /** BGP version. */
+    public static final int BGP_VERSION = 4;
+
+    /** BGP OPEN message type. */
+    public static final int BGP_TYPE_OPEN = 1;
+
+    /** BGP UPDATE message type. */
+    public static final int BGP_TYPE_UPDATE = 2;
+
+    /** BGP NOTIFICATION message type. */
+    public static final int BGP_TYPE_NOTIFICATION = 3;
+
+    /** BGP KEEPALIVE message type. */
+    public static final int BGP_TYPE_KEEPALIVE = 4;
+
+    /** BGP Header Marker field length. */
+    public static final int BGP_HEADER_MARKER_LENGTH = 16;
+
+    /** BGP Header length. */
+    public static final int BGP_HEADER_LENGTH = 19;
+
+    /** BGP message maximum length. */
+    public static final int BGP_MESSAGE_MAX_LENGTH = 4096;
+
+    /** BGP OPEN message minimum length (BGP Header included). */
+    public static final int BGP_OPEN_MIN_LENGTH = 29;
+
+    /** BGP UPDATE message minimum length (BGP Header included). */
+    public static final int BGP_UPDATE_MIN_LENGTH = 23;
+
+    /** BGP NOTIFICATION message minimum length (BGP Header included). */
+    public static final int BGP_NOTIFICATION_MIN_LENGTH = 21;
+
+    /** BGP KEEPALIVE message expected length (BGP Header included). */
+    public static final int BGP_KEEPALIVE_EXPECTED_LENGTH = 19;
+
+    /** BGP KEEPALIVE messages transmitted per Hold interval. */
+    public static final int BGP_KEEPALIVE_PER_HOLD_INTERVAL = 3;
+
+    /** BGP KEEPALIVE messages minimum Holdtime (in seconds). */
+    public static final int BGP_KEEPALIVE_MIN_HOLDTIME = 3;
+
+    /** BGP KEEPALIVE messages minimum transmission interval (in seconds). */
+    public static final int BGP_KEEPALIVE_MIN_INTERVAL = 1;
+
+    /** BGP AS 0 (zero) value. See draft-ietf-idr-as0-06.txt Internet Draft. */
+    public static final long BGP_AS_0 = 0;
+
+    /**
+     * BGP OPEN related constants.
+     */
+    public static final class Open {
+        /**
+         * Default constructor.
+         * <p>
+         * The constructor is private to prevent creating an instance of
+         * this utility class.
+         */
+        private Open() {
+        }
+
+        /**
+         * BGP OPEN: Optional Parameters related constants.
+         */
+        public static final class OptionalParameters {
+        }
+
+        /**
+         * BGP OPEN: Capabilities related constants (RFC 5492).
+         */
+        public static final class Capabilities {
+            /** BGP OPEN Optional Parameter Type: Capabilities. */
+            public static final int TYPE = 2;
+
+            /** BGP OPEN Optional Parameter minimum length. */
+            public static final int MIN_LENGTH = 2;
+
+            /**
+             * BGP OPEN: Multiprotocol Extensions Capabilities (RFC 4760).
+             */
+            public static final class MultiprotocolExtensions {
+                /** BGP OPEN Multiprotocol Extensions code. */
+                public static final int CODE = 1;
+
+                /** BGP OPEN Multiprotocol Extensions length. */
+                public static final int LENGTH = 4;
+
+                /** BGP OPEN Multiprotocol Extensions AFI: IPv4. */
+                public static final int AFI_IPV4 = 1;
+
+                /** BGP OPEN Multiprotocol Extensions AFI: IPv6. */
+                public static final int AFI_IPV6 = 2;
+
+                /** BGP OPEN Multiprotocol Extensions SAFI: unicast. */
+                public static final int SAFI_UNICAST = 1;
+
+                /** BGP OPEN Multiprotocol Extensions SAFI: multicast. */
+                public static final int SAFI_MULTICAST = 2;
+            }
+
+            /**
+             * BGP OPEN: Support for 4-octet AS Number Capability (RFC 6793).
+             */
+            public static final class As4Octet {
+                /** BGP OPEN Support for 4-octet AS Number Capability code. */
+                public static final int CODE = 65;
+
+                /** BGP OPEN 4-octet AS Number Capability length. */
+                public static final int LENGTH = 4;
+            }
+        }
+    }
+
+    /**
+     * BGP UPDATE related constants.
+     */
+    public static final class Update {
+        /**
+         * Default constructor.
+         * <p>
+         * The constructor is private to prevent creating an instance of
+         * this utility class.
+         */
+        private Update() {
+        }
+
+        /**
+         * BGP UPDATE: ORIGIN related constants.
+         */
+        public static final class Origin {
+            /**
+             * Default constructor.
+             * <p>
+             * The constructor is private to prevent creating an instance of
+             * this utility class.
+             */
+            private Origin() {
+            }
+
+            /** BGP UPDATE Attributes Type Code ORIGIN. */
+            public static final int TYPE = 1;
+
+            /** BGP UPDATE Attributes Type Code ORIGIN length. */
+            public static final int LENGTH = 1;
+
+            /** BGP UPDATE ORIGIN: IGP. */
+            public static final int IGP = 0;
+
+            /** BGP UPDATE ORIGIN: EGP. */
+            public static final int EGP = 1;
+
+            /** BGP UPDATE ORIGIN: INCOMPLETE. */
+            public static final int INCOMPLETE = 2;
+
+            /**
+             * Gets the BGP UPDATE origin type as a string.
+             *
+             * @param type the BGP UPDATE origin type
+             * @return the BGP UPDATE origin type as a string
+             */
+            public static String typeToString(int type) {
+                String typeString = "UNKNOWN";
+
+                switch (type) {
+                case IGP:
+                    typeString = "IGP";
+                    break;
+                case EGP:
+                    typeString = "EGP";
+                    break;
+                case INCOMPLETE:
+                    typeString = "INCOMPLETE";
+                    break;
+                default:
+                    break;
+                }
+                return typeString;
+            }
+        }
+
+        /**
+         * BGP UPDATE: AS_PATH related constants.
+         */
+        public static final class AsPath {
+            /**
+             * Default constructor.
+             * <p>
+             * The constructor is private to prevent creating an instance of
+             * this utility class.
+             */
+            private AsPath() {
+            }
+
+            /** BGP UPDATE Attributes Type Code AS_PATH. */
+            public static final int TYPE = 2;
+
+            /** BGP AS length. */
+            public static final int AS_LENGTH = 2;
+
+            /** BGP 4 Octet AS length (RFC 6793). */
+            public static final int AS_4OCTET_LENGTH = 4;
+
+            /** BGP UPDATE AS_PATH Type: AS_SET. */
+            public static final int AS_SET = 1;
+
+            /** BGP UPDATE AS_PATH Type: AS_SEQUENCE. */
+            public static final int AS_SEQUENCE = 2;
+
+            /** BGP UPDATE AS_PATH Type: AS_CONFED_SEQUENCE. */
+            public static final int AS_CONFED_SEQUENCE = 3;
+
+            /** BGP UPDATE AS_PATH Type: AS_CONFED_SET. */
+            public static final int AS_CONFED_SET = 4;
+
+            /**
+             * Gets the BGP AS_PATH type as a string.
+             *
+             * @param type the BGP AS_PATH type
+             * @return the BGP AS_PATH type as a string
+             */
+            public static String typeToString(int type) {
+                String typeString = "UNKNOWN";
+
+                switch (type) {
+                case AS_SET:
+                    typeString = "AS_SET";
+                    break;
+                case AS_SEQUENCE:
+                    typeString = "AS_SEQUENCE";
+                    break;
+                case AS_CONFED_SEQUENCE:
+                    typeString = "AS_CONFED_SEQUENCE";
+                    break;
+                case AS_CONFED_SET:
+                    typeString = "AS_CONFED_SET";
+                    break;
+                default:
+                    break;
+                }
+                return typeString;
+            }
+        }
+
+        /**
+         * BGP UPDATE: NEXT_HOP related constants.
+         */
+        public static final class NextHop {
+            /**
+             * Default constructor.
+             * <p>
+             * The constructor is private to prevent creating an instance of
+             * this utility class.
+             */
+            private NextHop() {
+            }
+
+            /** BGP UPDATE Attributes Type Code NEXT_HOP. */
+            public static final int TYPE = 3;
+
+            /** BGP UPDATE Attributes Type Code NEXT_HOP length. */
+            public static final int LENGTH = 4;
+        }
+
+        /**
+         * BGP UPDATE: MULTI_EXIT_DISC related constants.
+         */
+        public static final class MultiExitDisc {
+            /**
+             * Default constructor.
+             * <p>
+             * The constructor is private to prevent creating an instance of
+             * this utility class.
+             */
+            private MultiExitDisc() {
+            }
+
+            /** BGP UPDATE Attributes Type Code MULTI_EXIT_DISC. */
+            public static final int TYPE = 4;
+
+            /** BGP UPDATE Attributes Type Code MULTI_EXIT_DISC length. */
+            public static final int LENGTH = 4;
+
+            /** BGP UPDATE Attributes lowest MULTI_EXIT_DISC value. */
+            public static final int LOWEST_MULTI_EXIT_DISC = 0;
+        }
+
+        /**
+         * BGP UPDATE: LOCAL_PREF related constants.
+         */
+        public static final class LocalPref {
+            /**
+             * Default constructor.
+             * <p>
+             * The constructor is private to prevent creating an instance of
+             * this utility class.
+             */
+            private LocalPref() {
+            }
+
+            /** BGP UPDATE Attributes Type Code LOCAL_PREF. */
+            public static final int TYPE = 5;
+
+            /** BGP UPDATE Attributes Type Code LOCAL_PREF length. */
+            public static final int LENGTH = 4;
+        }
+
+        /**
+         * BGP UPDATE: ATOMIC_AGGREGATE related constants.
+         */
+        public static final class AtomicAggregate {
+            /**
+             * Default constructor.
+             * <p>
+             * The constructor is private to prevent creating an instance of
+             * this utility class.
+             */
+            private AtomicAggregate() {
+            }
+
+            /** BGP UPDATE Attributes Type Code ATOMIC_AGGREGATE. */
+            public static final int TYPE = 6;
+
+            /** BGP UPDATE Attributes Type Code ATOMIC_AGGREGATE length. */
+            public static final int LENGTH = 0;
+        }
+
+        /**
+         * BGP UPDATE: AGGREGATOR related constants.
+         */
+        public static final class Aggregator {
+            /**
+             * Default constructor.
+             * <p>
+             * The constructor is private to prevent creating an instance of
+             * this utility class.
+             */
+            private Aggregator() {
+            }
+
+            /** BGP UPDATE Attributes Type Code AGGREGATOR. */
+            public static final int TYPE = 7;
+
+            /** BGP UPDATE Attributes Type Code AGGREGATOR length. */
+            public static final int LENGTH = 6;
+        }
+
+        /**
+         * BGP UPDATE: MP_REACH_NLRI related constants.
+         */
+        public static final class MpReachNlri {
+            /**
+             * Default constructor.
+             * <p>
+             * The constructor is private to prevent creating an instance of
+             * this utility class.
+             */
+            private MpReachNlri() {
+            }
+
+            /** BGP UPDATE Attributes Type Code MP_REACH_NLRI. */
+            public static final int TYPE = 14;
+
+            /** BGP UPDATE Attributes Type Code MP_REACH_NLRI min length. */
+            public static final int MIN_LENGTH = 5;
+        }
+
+        /**
+         * BGP UPDATE: MP_UNREACH_NLRI related constants.
+         */
+        public static final class MpUnreachNlri {
+            /**
+             * Default constructor.
+             * <p>
+             * The constructor is private to prevent creating an instance of
+             * this utility class.
+             */
+            private MpUnreachNlri() {
+            }
+
+            /** BGP UPDATE Attributes Type Code MP_UNREACH_NLRI. */
+            public static final int TYPE = 15;
+
+            /** BGP UPDATE Attributes Type Code MP_UNREACH_NLRI min length. */
+            public static final int MIN_LENGTH = 3;
+        }
+    }
+
+    /**
+     * BGP NOTIFICATION related constants.
+     */
+    public static final class Notifications {
+        /**
+         * Default constructor.
+         * <p>
+         * The constructor is private to prevent creating an instance of
+         * this utility class.
+         */
+        private Notifications() {
+        }
+
+        /**
+         * BGP NOTIFICATION: Message Header Error constants.
+         */
+        public static final class MessageHeaderError {
+            /**
+             * Default constructor.
+             * <p>
+             * The constructor is private to prevent creating an instance of
+             * this utility class.
+             */
+            private MessageHeaderError() {
+            }
+
+            /** Message Header Error code. */
+            public static final int ERROR_CODE = 1;
+
+            /** Message Header Error subcode: Connection Not Synchronized. */
+            public static final int CONNECTION_NOT_SYNCHRONIZED = 1;
+
+            /** Message Header Error subcode: Bad Message Length. */
+            public static final int BAD_MESSAGE_LENGTH = 2;
+
+            /** Message Header Error subcode: Bad Message Type. */
+            public static final int BAD_MESSAGE_TYPE = 3;
+        }
+
+        /**
+         * BGP NOTIFICATION: OPEN Message Error constants.
+         */
+        public static final class OpenMessageError {
+            /**
+             * Default constructor.
+             * <p>
+             * The constructor is private to prevent creating an instance of
+             * this utility class.
+             */
+            private OpenMessageError() {
+            }
+
+            /** OPEN Message Error code. */
+            public static final int ERROR_CODE = 2;
+
+            /** OPEN Message Error subcode: Unsupported Version Number. */
+            public static final int UNSUPPORTED_VERSION_NUMBER = 1;
+
+            /** OPEN Message Error subcode: Bad PEER AS. */
+            public static final int BAD_PEER_AS = 2;
+
+            /** OPEN Message Error subcode: Unacceptable Hold Time. */
+            public static final int UNACCEPTABLE_HOLD_TIME = 6;
+        }
+
+        /**
+         * BGP NOTIFICATION: UPDATE Message Error constants.
+         */
+        public static final class UpdateMessageError {
+            /**
+             * Default constructor.
+             * <p>
+             * The constructor is private to prevent creating an instance of
+             * this utility class.
+             */
+            private UpdateMessageError() {
+            }
+
+            /** UPDATE Message Error code. */
+            public static final int ERROR_CODE = 3;
+
+            /** UPDATE Message Error subcode: Malformed Attribute List. */
+            public static final int MALFORMED_ATTRIBUTE_LIST = 1;
+
+            /** UPDATE Message Error subcode: Unrecognized Well-known Attribute. */
+            public static final int UNRECOGNIZED_WELL_KNOWN_ATTRIBUTE = 2;
+
+            /** UPDATE Message Error subcode: Missing Well-known Attribute. */
+            public static final int MISSING_WELL_KNOWN_ATTRIBUTE = 3;
+
+           /** UPDATE Message Error subcode: Attribute Flags Error. */
+            public static final int ATTRIBUTE_FLAGS_ERROR = 4;
+
+            /** UPDATE Message Error subcode: Attribute Length Error. */
+            public static final int ATTRIBUTE_LENGTH_ERROR = 5;
+
+            /** UPDATE Message Error subcode: Invalid ORIGIN Attribute. */
+            public static final int INVALID_ORIGIN_ATTRIBUTE = 6;
+
+            /** UPDATE Message Error subcode: Invalid NEXT_HOP Attribute. */
+            public static final int INVALID_NEXT_HOP_ATTRIBUTE = 8;
+
+            /** UPDATE Message Error subcode: Optional Attribute Error. Unused. */
+            public static final int OPTIONAL_ATTRIBUTE_ERROR = 9;
+
+            /** UPDATE Message Error subcode: Invalid Network Field. */
+            public static final int INVALID_NETWORK_FIELD = 10;
+
+            /** UPDATE Message Error subcode: Malformed AS_PATH. */
+            public static final int MALFORMED_AS_PATH = 11;
+        }
+
+        /**
+         * BGP NOTIFICATION: Hold Timer Expired constants.
+         */
+        public static final class HoldTimerExpired {
+            /**
+             * Default constructor.
+             * <p>
+             * The constructor is private to prevent creating an instance of
+             * this utility class.
+             */
+            private HoldTimerExpired() {
+            }
+
+            /** Hold Timer Expired code. */
+            public static final int ERROR_CODE = 4;
+        }
+
+        /** BGP NOTIFICATION message Error subcode: Unspecific. */
+        public static final int ERROR_SUBCODE_UNSPECIFIC = 0;
+    }
+}
diff --git a/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpFrameDecoder.java b/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpFrameDecoder.java
new file mode 100644
index 0000000..053d0bf
--- /dev/null
+++ b/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpFrameDecoder.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright 2014 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.jboss.netty.buffer.ChannelBuffer;
+import org.jboss.netty.buffer.ChannelBuffers;
+import org.jboss.netty.channel.Channel;
+import org.jboss.netty.channel.ChannelHandlerContext;
+import org.jboss.netty.handler.codec.frame.FrameDecoder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Class for handling the decoding of the BGP messages.
+ */
+class BgpFrameDecoder extends FrameDecoder {
+    private static final Logger log =
+        LoggerFactory.getLogger(BgpFrameDecoder.class);
+
+    private final BgpSession bgpSession;
+
+    /**
+     * Constructor for a given BGP Session.
+     *
+     * @param bgpSession the BGP session state to use.
+     */
+    BgpFrameDecoder(BgpSession bgpSession) {
+        this.bgpSession = bgpSession;
+    }
+
+    @Override
+    protected Object decode(ChannelHandlerContext ctx,
+                            Channel channel,
+                            ChannelBuffer buf) throws Exception {
+        //
+        // NOTE: If we close the channel during the decoding, we might still
+        // see some incoming messages while the channel closing is completed.
+        //
+        if (bgpSession.isClosed()) {
+            return null;
+        }
+
+        log.trace("BGP Peer: decode(): remoteAddr = {} localAddr = {} " +
+                  "messageSize = {}",
+                  ctx.getChannel().getRemoteAddress(),
+                  ctx.getChannel().getLocalAddress(),
+                  buf.readableBytes());
+
+        // Test for minimum length of the BGP message
+        if (buf.readableBytes() < BgpConstants.BGP_HEADER_LENGTH) {
+            // No enough data received
+            return null;
+        }
+
+        //
+        // Mark the current buffer position in case we haven't received
+        // the whole message.
+        //
+        buf.markReaderIndex();
+
+        //
+        // Read and check the BGP message Marker field: it must be all ones
+        // (See RFC 4271, Section 4.1)
+        //
+        byte[] marker = new byte[BgpConstants.BGP_HEADER_MARKER_LENGTH];
+        buf.readBytes(marker);
+        for (int i = 0; i < marker.length; i++) {
+            if (marker[i] != (byte) 0xff) {
+                log.debug("BGP RX Error: invalid marker {} at position {}",
+                          marker[i], i);
+                //
+                // ERROR: Connection Not Synchronized
+                //
+                // Send NOTIFICATION and close the connection
+                int errorCode = BgpConstants.Notifications.MessageHeaderError.ERROR_CODE;
+                int errorSubcode =
+                    BgpConstants.Notifications.MessageHeaderError.CONNECTION_NOT_SYNCHRONIZED;
+                ChannelBuffer txMessage =
+                    BgpNotification.prepareBgpNotification(errorCode,
+                                                           errorSubcode,
+                                                           null);
+                ctx.getChannel().write(txMessage);
+                bgpSession.closeSession(ctx);
+                return null;
+            }
+        }
+
+        //
+        // Read and check the BGP message Length field
+        //
+        int length = buf.readUnsignedShort();
+        if ((length < BgpConstants.BGP_HEADER_LENGTH) ||
+            (length > BgpConstants.BGP_MESSAGE_MAX_LENGTH)) {
+            log.debug("BGP RX Error: invalid Length field {}. " +
+                      "Must be between {} and {}",
+                      length,
+                      BgpConstants.BGP_HEADER_LENGTH,
+                      BgpConstants.BGP_MESSAGE_MAX_LENGTH);
+            //
+            // ERROR: Bad Message Length
+            //
+            // Send NOTIFICATION and close the connection
+            ChannelBuffer txMessage =
+                BgpNotification.prepareBgpNotificationBadMessageLength(length);
+            ctx.getChannel().write(txMessage);
+            bgpSession.closeSession(ctx);
+            return null;
+        }
+
+        //
+        // Test whether the rest of the message is received:
+        // So far we have read the Marker (16 octets) and the
+        // Length (2 octets) fields.
+        //
+        int remainingMessageLen =
+            length - BgpConstants.BGP_HEADER_MARKER_LENGTH - 2;
+        if (buf.readableBytes() < remainingMessageLen) {
+            // No enough data received
+            buf.resetReaderIndex();
+            return null;
+        }
+
+        //
+        // Read the BGP message Type field, and process based on that type
+        //
+        int type = buf.readUnsignedByte();
+        remainingMessageLen--;      // Adjust after reading the type
+        ChannelBuffer message = buf.readBytes(remainingMessageLen);
+
+        //
+        // Process the remaining of the message based on the message type
+        //
+        switch (type) {
+        case BgpConstants.BGP_TYPE_OPEN:
+            BgpOpen.processBgpOpen(bgpSession, ctx, message);
+            break;
+        case BgpConstants.BGP_TYPE_UPDATE:
+            BgpUpdate.processBgpUpdate(bgpSession, ctx, message);
+            break;
+        case BgpConstants.BGP_TYPE_NOTIFICATION:
+            BgpNotification.processBgpNotification(bgpSession, ctx, message);
+            break;
+        case BgpConstants.BGP_TYPE_KEEPALIVE:
+            BgpKeepalive.processBgpKeepalive(bgpSession, ctx, message);
+            break;
+        default:
+            //
+            // ERROR: Bad Message Type
+            //
+            // Send NOTIFICATION and close the connection
+            int errorCode = BgpConstants.Notifications.MessageHeaderError.ERROR_CODE;
+            int errorSubcode = BgpConstants.Notifications.MessageHeaderError.BAD_MESSAGE_TYPE;
+            ChannelBuffer data = ChannelBuffers.buffer(1);
+            data.writeByte(type);
+            ChannelBuffer txMessage =
+                BgpNotification.prepareBgpNotification(errorCode, errorSubcode,
+                                                       data);
+            ctx.getChannel().write(txMessage);
+            bgpSession.closeSession(ctx);
+            return null;
+        }
+        return null;
+    }
+}
diff --git a/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpInfoService.java b/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpInfoService.java
new file mode 100644
index 0000000..d7914e6
--- /dev/null
+++ b/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpInfoService.java
@@ -0,0 +1,45 @@
+/*
+ * 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.routing.bgp;
+
+import java.util.Collection;
+
+/**
+ * Provides information about BGP peering and routes.
+ */
+public interface BgpInfoService {
+
+    /**
+     * Gets the BGP sessions.
+     *
+     * @return the BGP sessions
+     */
+    public Collection<BgpSession> getBgpSessions();
+
+    /**
+     * Gets the selected IPv4 BGP routes among all BGP sessions.
+     *
+     * @return the selected IPv4 BGP routes among all BGP sessions
+     */
+    public Collection<BgpRouteEntry> getBgpRoutes4();
+
+    /**
+     * Gets the selected IPv6 BGP routes among all BGP sessions.
+     *
+     * @return the selected IPv6 BGP routes among all BGP sessions
+     */
+    public Collection<BgpRouteEntry> getBgpRoutes6();
+}
diff --git a/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpKeepalive.java b/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpKeepalive.java
new file mode 100644
index 0000000..186dfeda
--- /dev/null
+++ b/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpKeepalive.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2014 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.jboss.netty.buffer.ChannelBuffer;
+import org.jboss.netty.buffer.ChannelBuffers;
+import org.jboss.netty.channel.ChannelHandlerContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A class for handling BGP KEEPALIVE messages.
+ */
+final class BgpKeepalive {
+    private static final Logger log =
+        LoggerFactory.getLogger(BgpKeepalive.class);
+
+    /**
+     * Default constructor.
+     * <p>
+     * The constructor is private to prevent creating an instance of
+     * this utility class.
+     */
+    private BgpKeepalive() {
+    }
+
+    /**
+     * Processes BGP KEEPALIVE message.
+     *
+     * @param bgpSession the BGP Session to use
+     * @param ctx the Channel Handler Context
+     * @param message the message to process
+     */
+    static void processBgpKeepalive(BgpSession bgpSession,
+                                    ChannelHandlerContext ctx,
+                                    ChannelBuffer message) {
+        if (message.readableBytes() + BgpConstants.BGP_HEADER_LENGTH !=
+            BgpConstants.BGP_KEEPALIVE_EXPECTED_LENGTH) {
+            log.debug("BGP RX KEEPALIVE Error from {}: " +
+                      "Invalid total message length {}. Expected {}",
+                      bgpSession.remoteInfo().address(),
+                      message.readableBytes() + BgpConstants.BGP_HEADER_LENGTH,
+                      BgpConstants.BGP_KEEPALIVE_EXPECTED_LENGTH);
+            //
+            // ERROR: Bad Message Length
+            //
+            // Send NOTIFICATION and close the connection
+            ChannelBuffer txMessage =
+                BgpNotification.prepareBgpNotificationBadMessageLength(
+                message.readableBytes() + BgpConstants.BGP_HEADER_LENGTH);
+            ctx.getChannel().write(txMessage);
+            bgpSession.closeSession(ctx);
+            return;
+        }
+
+        //
+        // Parse the KEEPALIVE message: nothing to do
+        //
+        log.trace("BGP RX KEEPALIVE message from {}",
+                  bgpSession.remoteInfo().address());
+
+        // Start the Session Timeout timer
+        bgpSession.restartSessionTimeoutTimer(ctx);
+    }
+
+    /**
+     * Prepares BGP KEEPALIVE message.
+     *
+     * @return the message to transmit (BGP header included)
+     */
+    static ChannelBuffer prepareBgpKeepalive() {
+        ChannelBuffer message =
+            ChannelBuffers.buffer(BgpConstants.BGP_MESSAGE_MAX_LENGTH);
+
+        //
+        // Prepare the KEEPALIVE message payload: nothing to do
+        //
+        return BgpMessage.prepareBgpMessage(BgpConstants.BGP_TYPE_KEEPALIVE,
+                                            message);
+    }
+}
diff --git a/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpMessage.java b/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpMessage.java
new file mode 100644
index 0000000..63a5dbd
--- /dev/null
+++ b/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpMessage.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2014 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.jboss.netty.buffer.ChannelBuffer;
+import org.jboss.netty.buffer.ChannelBuffers;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A class for preparing BGP messages.
+ */
+final class BgpMessage {
+    private static final Logger log =
+        LoggerFactory.getLogger(BgpMessage.class);
+
+    /**
+     * Default constructor.
+     * <p>
+     * The constructor is private to prevent creating an instance of
+     * this utility class.
+     */
+    private BgpMessage() {
+    }
+
+    /**
+     * Prepares BGP message.
+     *
+     * @param type the BGP message type
+     * @param payload the message payload to transmit (BGP header excluded)
+     * @return the message to transmit (BGP header included)
+     */
+    static ChannelBuffer prepareBgpMessage(int type, ChannelBuffer payload) {
+        ChannelBuffer message =
+            ChannelBuffers.buffer(BgpConstants.BGP_HEADER_LENGTH +
+                                  payload.readableBytes());
+
+        // Write the marker
+        for (int i = 0; i < BgpConstants.BGP_HEADER_MARKER_LENGTH; i++) {
+            message.writeByte(0xff);
+        }
+
+        // Write the rest of the BGP header
+        message.writeShort(BgpConstants.BGP_HEADER_LENGTH +
+                           payload.readableBytes());
+        message.writeByte(type);
+
+        // Write the payload
+        message.writeBytes(payload);
+        return message;
+    }
+
+    /**
+     * An exception indicating a parsing error of the BGP message.
+     */
+    static final class BgpParseException extends Exception {
+        /**
+         * Default constructor.
+         */
+        private BgpParseException() {
+            super();
+        }
+
+        /**
+         * Constructor for a specific exception details message.
+         *
+         * @param message the message with the exception details
+         */
+        BgpParseException(String message) {
+            super(message);
+        }
+    }
+}
diff --git a/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpNotification.java b/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpNotification.java
new file mode 100644
index 0000000..16ec951
--- /dev/null
+++ b/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpNotification.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2014 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.jboss.netty.buffer.ChannelBuffer;
+import org.jboss.netty.buffer.ChannelBuffers;
+import org.jboss.netty.channel.ChannelHandlerContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A class for handling BGP NOTIFICATION messages.
+ */
+final class BgpNotification {
+    private static final Logger log =
+        LoggerFactory.getLogger(BgpNotification.class);
+
+    /**
+     * Default constructor.
+     * <p>
+     * The constructor is private to prevent creating an instance of
+     * this utility class.
+     */
+    private BgpNotification() {
+    }
+
+    /**
+     * Processes BGP NOTIFICATION message.
+     *
+     * @param bgpSession the BGP Session to use
+     * @param ctx the Channel Handler Context
+     * @param message the message to process
+     */
+    static void processBgpNotification(BgpSession bgpSession,
+                                       ChannelHandlerContext ctx,
+                                       ChannelBuffer message) {
+        int minLength =
+            BgpConstants.BGP_NOTIFICATION_MIN_LENGTH - BgpConstants.BGP_HEADER_LENGTH;
+        if (message.readableBytes() < minLength) {
+            log.debug("BGP RX NOTIFICATION Error from {}: " +
+                      "Message length {} too short. Must be at least {}",
+                      bgpSession.remoteInfo().address(),
+                      message.readableBytes(), minLength);
+            //
+            // ERROR: Bad Message Length
+            //
+            // NOTE: We do NOT send NOTIFICATION in response to a notification
+            return;
+        }
+
+        //
+        // Parse the NOTIFICATION message
+        //
+        int errorCode = message.readUnsignedByte();
+        int errorSubcode = message.readUnsignedByte();
+        int dataLength = message.readableBytes();
+
+        log.debug("BGP RX NOTIFICATION message from {}: Error Code {} " +
+                  "Error Subcode {} Data Length {}",
+                  bgpSession.remoteInfo().address(), errorCode, errorSubcode,
+                  dataLength);
+
+        //
+        // NOTE: If the peer sent a NOTIFICATION, we leave it to the peer to
+        // close the connection.
+        //
+
+        // Start the Session Timeout timer
+        bgpSession.restartSessionTimeoutTimer(ctx);
+    }
+
+    /**
+     * Prepares BGP NOTIFICATION message.
+     *
+     * @param errorCode the BGP NOTIFICATION Error Code
+     * @param errorSubcode the BGP NOTIFICATION Error Subcode if applicable,
+     * otherwise BgpConstants.Notifications.ERROR_SUBCODE_UNSPECIFIC
+     * @param data the BGP NOTIFICATION Data if applicable, otherwise null
+     * @return the message to transmit (BGP header included)
+     */
+    static ChannelBuffer prepareBgpNotification(int errorCode,
+                                                int errorSubcode,
+                                                ChannelBuffer data) {
+        ChannelBuffer message =
+            ChannelBuffers.buffer(BgpConstants.BGP_MESSAGE_MAX_LENGTH);
+
+        //
+        // Prepare the NOTIFICATION message payload
+        //
+        message.writeByte(errorCode);
+        message.writeByte(errorSubcode);
+        if (data != null) {
+            message.writeBytes(data);
+        }
+        return BgpMessage.prepareBgpMessage(BgpConstants.BGP_TYPE_NOTIFICATION,
+                                            message);
+    }
+
+    /**
+     * Prepares BGP NOTIFICATION message: Bad Message Length.
+     *
+     * @param length the erroneous Length field
+     * @return the message to transmit (BGP header included)
+     */
+    static ChannelBuffer prepareBgpNotificationBadMessageLength(int length) {
+        int errorCode = BgpConstants.Notifications.MessageHeaderError.ERROR_CODE;
+        int errorSubcode = BgpConstants.Notifications.MessageHeaderError.BAD_MESSAGE_LENGTH;
+        ChannelBuffer data = ChannelBuffers.buffer(2);
+        data.writeShort(length);
+
+        return prepareBgpNotification(errorCode, errorSubcode, data);
+    }
+}
diff --git a/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpOpen.java b/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpOpen.java
new file mode 100644
index 0000000..3216aec
--- /dev/null
+++ b/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpOpen.java
@@ -0,0 +1,497 @@
+/*
+ * Copyright 2014 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.jboss.netty.buffer.ChannelBuffer;
+import org.jboss.netty.buffer.ChannelBuffers;
+import org.jboss.netty.channel.ChannelHandlerContext;
+import org.onlab.packet.Ip4Address;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A class for handling BGP OPEN messages.
+ */
+final class BgpOpen {
+    private static final Logger log = LoggerFactory.getLogger(BgpOpen.class);
+
+    /**
+     * Default constructor.
+     * <p>
+     * The constructor is private to prevent creating an instance of
+     * this utility class.
+     */
+    private BgpOpen() {
+    }
+
+    /**
+     * Processes BGP OPEN message.
+     *
+     * @param bgpSession the BGP Session to use
+     * @param ctx the Channel Handler Context
+     * @param message the message to process
+     */
+    static void processBgpOpen(BgpSession bgpSession,
+                               ChannelHandlerContext ctx,
+                               ChannelBuffer message) {
+        int minLength =
+            BgpConstants.BGP_OPEN_MIN_LENGTH - BgpConstants.BGP_HEADER_LENGTH;
+        if (message.readableBytes() < minLength) {
+            log.debug("BGP RX OPEN Error from {}: " +
+                      "Message length {} too short. Must be at least {}",
+                      bgpSession.remoteInfo().address(),
+                      message.readableBytes(), minLength);
+            //
+            // ERROR: Bad Message Length
+            //
+            // Send NOTIFICATION and close the connection
+            ChannelBuffer txMessage =
+                BgpNotification.prepareBgpNotificationBadMessageLength(
+                        message.readableBytes() + BgpConstants.BGP_HEADER_LENGTH);
+            ctx.getChannel().write(txMessage);
+            bgpSession.closeSession(ctx);
+            return;
+        }
+
+        //
+        // Parse the OPEN message
+        //
+        // Remote BGP version
+        int remoteBgpVersion = message.readUnsignedByte();
+        if (remoteBgpVersion != BgpConstants.BGP_VERSION) {
+            log.debug("BGP RX OPEN Error from {}: " +
+                      "Unsupported BGP version {}. Should be {}",
+                      bgpSession.remoteInfo().address(), remoteBgpVersion,
+                      BgpConstants.BGP_VERSION);
+            //
+            // ERROR: Unsupported Version Number
+            //
+            // Send NOTIFICATION and close the connection
+            int errorCode = BgpConstants.Notifications.OpenMessageError.ERROR_CODE;
+            int errorSubcode = BgpConstants.Notifications.OpenMessageError.UNSUPPORTED_VERSION_NUMBER;
+            ChannelBuffer data = ChannelBuffers.buffer(2);
+            data.writeShort(BgpConstants.BGP_VERSION);
+            ChannelBuffer txMessage =
+                BgpNotification.prepareBgpNotification(errorCode, errorSubcode,
+                                                       data);
+            ctx.getChannel().write(txMessage);
+            bgpSession.closeSession(ctx);
+            return;
+        }
+        bgpSession.remoteInfo().setBgpVersion(remoteBgpVersion);
+
+        // Remote AS number
+        long remoteAs = message.readUnsignedShort();
+        bgpSession.remoteInfo().setAsNumber(remoteAs);
+        //
+        // NOTE: Currently, the local AS number is always set to the remote AS.
+        // This is done, because the peer setup is always iBGP.
+        // In the future, the local AS number should be configured as part
+        // of an explicit BGP peering configuration.
+        //
+        bgpSession.localInfo().setAsNumber(remoteAs);
+
+        // Remote Hold Time
+        long remoteHoldtime = message.readUnsignedShort();
+        if ((remoteHoldtime != 0) &&
+            (remoteHoldtime < BgpConstants.BGP_KEEPALIVE_MIN_HOLDTIME)) {
+            log.debug("BGP RX OPEN Error from {}: " +
+                      "Unacceptable Hold Time field {}. " +
+                      "Should be 0 or at least {}",
+                      bgpSession.remoteInfo().address(), remoteHoldtime,
+                      BgpConstants.BGP_KEEPALIVE_MIN_HOLDTIME);
+            //
+            // ERROR: Unacceptable Hold Time
+            //
+            // Send NOTIFICATION and close the connection
+            int errorCode = BgpConstants.Notifications.OpenMessageError.ERROR_CODE;
+            int errorSubcode = BgpConstants.Notifications.OpenMessageError.UNACCEPTABLE_HOLD_TIME;
+            ChannelBuffer txMessage =
+                BgpNotification.prepareBgpNotification(errorCode, errorSubcode,
+                                                       null);
+            ctx.getChannel().write(txMessage);
+            bgpSession.closeSession(ctx);
+            return;
+        }
+        bgpSession.remoteInfo().setHoldtime(remoteHoldtime);
+        //
+        // NOTE: Currently. the local BGP Holdtime is always set to the remote
+        // BGP holdtime.
+        // In the future, the local BGP Holdtime should be configured as part
+        // of an explicit BGP peering configuration.
+        //
+        bgpSession.localInfo().setHoldtime(remoteHoldtime);
+
+        // Remote BGP Identifier
+        Ip4Address remoteBgpId =
+            Ip4Address.valueOf((int) message.readUnsignedInt());
+        bgpSession.remoteInfo().setBgpId(remoteBgpId);
+
+        // Parse the Optional Parameters
+        try {
+            parseOptionalParameters(bgpSession, ctx, message);
+        } catch (BgpMessage.BgpParseException e) {
+            // ERROR: Error parsing optional parameters
+            log.debug("BGP RX OPEN Error from {}: " +
+                      "Exception parsing Optional Parameters: {}",
+                      bgpSession.remoteInfo().address(), e);
+            //
+            // ERROR: Invalid Optional Parameters: Unspecific
+            //
+            // Send NOTIFICATION and close the connection
+            int errorCode = BgpConstants.Notifications.OpenMessageError.ERROR_CODE;
+            int errorSubcode = BgpConstants.Notifications.ERROR_SUBCODE_UNSPECIFIC;
+            ChannelBuffer txMessage =
+                BgpNotification.prepareBgpNotification(errorCode, errorSubcode,
+                                                       null);
+            ctx.getChannel().write(txMessage);
+            bgpSession.closeSession(ctx);
+            return;
+        }
+
+        //
+        // NOTE: Prepare the BGP OPEN message before the original local AS
+        // is overwritten by the 4-octet AS number
+        //
+        ChannelBuffer txOpenMessage = prepareBgpOpen(bgpSession.localInfo());
+
+        //
+        // Use the 4-octet AS number in lieu of the "My AS" field
+        // See RFC 6793, Section 4.1, second paragraph.
+        //
+        if (bgpSession.remoteInfo().as4OctetCapability()) {
+            long as4Number = bgpSession.remoteInfo().as4Number();
+            bgpSession.remoteInfo().setAsNumber(as4Number);
+            bgpSession.localInfo().setAsNumber(as4Number);
+        }
+
+        //
+        // Verify that the AS number is same for all other BGP Sessions
+        // NOTE: This check applies only for our use-case where all BGP
+        // sessions are iBGP.
+        //
+        for (BgpSession bs : bgpSession.getBgpSessionManager().getBgpSessions()) {
+            if ((bs.remoteInfo().asNumber() != 0) &&
+                (bgpSession.remoteInfo().asNumber() !=
+                 bs.remoteInfo().asNumber())) {
+                log.debug("BGP RX OPEN Error from {}: Bad Peer AS {}. " +
+                          "Expected {}",
+                          bgpSession.remoteInfo().address(),
+                          bgpSession.remoteInfo().asNumber(),
+                          bs.remoteInfo().asNumber());
+                //
+                // ERROR: Bad Peer AS
+                //
+                // Send NOTIFICATION and close the connection
+                int errorCode = BgpConstants.Notifications.OpenMessageError.ERROR_CODE;
+                int errorSubcode = BgpConstants.Notifications.OpenMessageError.BAD_PEER_AS;
+                ChannelBuffer txMessage =
+                    BgpNotification.prepareBgpNotification(errorCode,
+                                                           errorSubcode, null);
+                ctx.getChannel().write(txMessage);
+                bgpSession.closeSession(ctx);
+                return;
+            }
+        }
+
+        log.debug("BGP RX OPEN message from {}: " +
+                  "BGPv{} AS {} BGP-ID {} Holdtime {}",
+                  bgpSession.remoteInfo().address(),
+                  bgpSession.remoteInfo().bgpVersion(),
+                  bgpSession.remoteInfo().asNumber(),
+                  bgpSession.remoteInfo().bgpId(),
+                  bgpSession.remoteInfo().holdtime());
+
+        // Send my OPEN followed by KEEPALIVE
+        ctx.getChannel().write(txOpenMessage);
+        //
+        ChannelBuffer txMessage = BgpKeepalive.prepareBgpKeepalive();
+        ctx.getChannel().write(txMessage);
+
+        // Start the KEEPALIVE timer
+        bgpSession.restartKeepaliveTimer(ctx);
+
+        // Start the Session Timeout timer
+        bgpSession.restartSessionTimeoutTimer(ctx);
+    }
+
+    /**
+     * Prepares BGP OPEN message.
+     *
+     * @param localInfo the BGP Session local information to use
+     * @return the message to transmit (BGP header included)
+     */
+    static ChannelBuffer prepareBgpOpen(BgpSessionInfo localInfo) {
+        ChannelBuffer message =
+            ChannelBuffers.buffer(BgpConstants.BGP_MESSAGE_MAX_LENGTH);
+
+        //
+        // Prepare the OPEN message payload
+        //
+        message.writeByte(localInfo.bgpVersion());
+        message.writeShort((int) localInfo.asNumber());
+        message.writeShort((int) localInfo.holdtime());
+        message.writeInt(localInfo.bgpId().toInt());
+
+        // Prepare the optional BGP Capabilities
+        ChannelBuffer capabilitiesMessage =
+            prepareBgpOpenCapabilities(localInfo);
+        message.writeByte(capabilitiesMessage.readableBytes());
+        message.writeBytes(capabilitiesMessage);
+
+        return BgpMessage.prepareBgpMessage(BgpConstants.BGP_TYPE_OPEN,
+                                            message);
+    }
+
+    /**
+     * Parses BGP OPEN Optional Parameters.
+     *
+     * @param bgpSession the BGP Session to use
+     * @param ctx the Channel Handler Context
+     * @param message the message to process
+     * @throws BgpMessage.BgpParseException
+     */
+    private static void parseOptionalParameters(BgpSession bgpSession,
+                                                ChannelHandlerContext ctx,
+                                                ChannelBuffer message)
+        throws BgpMessage.BgpParseException {
+
+        //
+        // Get and verify the Optional Parameters Length
+        //
+        int optParamLength = message.readUnsignedByte();
+        if (optParamLength > message.readableBytes()) {
+            // ERROR: Invalid Optional Parameter Length
+            String errorMsg = "Invalid Optional Parameter Length field " +
+                optParamLength + ". Remaining Optional Parameters " +
+                message.readableBytes();
+            throw new BgpMessage.BgpParseException(errorMsg);
+        }
+        if (optParamLength == 0) {
+            return;                     // No Optional Parameters
+        }
+
+        //
+        // Parse the Optional Parameters
+        //
+        int optParamEnd = message.readerIndex() + optParamLength;
+        while (message.readerIndex() < optParamEnd) {
+            int paramType = message.readUnsignedByte();
+            if (message.readerIndex() >= optParamEnd) {
+                // ERROR: Malformed Optional Parameters
+                String errorMsg = "Malformed Optional Parameters";
+                throw new BgpMessage.BgpParseException(errorMsg);
+            }
+            int paramLen = message.readUnsignedByte();
+            if (message.readerIndex() + paramLen > optParamEnd) {
+                // ERROR: Malformed Optional Parameters
+                String errorMsg = "Malformed Optional Parameters";
+                throw new BgpMessage.BgpParseException(errorMsg);
+            }
+
+            //
+            // Extract the Optional Parameter Value based on the Parameter Type
+            //
+            switch (paramType) {
+            case BgpConstants.Open.Capabilities.TYPE:
+                // Optional Parameter Type: Capabilities
+                if (paramLen < BgpConstants.Open.Capabilities.MIN_LENGTH) {
+                    // ERROR: Malformed Capability
+                    String errorMsg = "Malformed Capability Type " + paramType;
+                    throw new BgpMessage.BgpParseException(errorMsg);
+                }
+                int capabEnd = message.readerIndex() + paramLen;
+                int capabCode = message.readUnsignedByte();
+                int capabLen = message.readUnsignedByte();
+                if (message.readerIndex() + capabLen > capabEnd) {
+                    // ERROR: Malformed Capability
+                    String errorMsg = "Malformed Capability Type " + paramType;
+                    throw new BgpMessage.BgpParseException(errorMsg);
+                }
+
+                switch (capabCode) {
+                case BgpConstants.Open.Capabilities.MultiprotocolExtensions.CODE:
+                    // Multiprotocol Extensions Capabilities (RFC 4760)
+                    if (capabLen != BgpConstants.Open.Capabilities.MultiprotocolExtensions.LENGTH) {
+                        // ERROR: Multiprotocol Extension Length Error
+                        String errorMsg = "Multiprotocol Extension Length Error";
+                        throw new BgpMessage.BgpParseException(errorMsg);
+                    }
+                    // Decode the AFI (2 octets) and SAFI (1 octet)
+                    int afi = message.readUnsignedShort();
+                    int reserved = message.readUnsignedByte();
+                    int safi = message.readUnsignedByte();
+                    log.debug("BGP RX OPEN Capability: AFI = {} SAFI = {}",
+                              afi, safi);
+                    //
+                    // Setup the AFI/SAFI in the BgpSession
+                    //
+                    // NOTE: For now we just copy the remote AFI/SAFI setting
+                    // to the local configuration.
+                    //
+                    if (afi == BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV4 &&
+                        safi == BgpConstants.Open.Capabilities.MultiprotocolExtensions.SAFI_UNICAST) {
+                        bgpSession.remoteInfo().setIpv4Unicast();
+                        bgpSession.localInfo().setIpv4Unicast();
+                    } else if (afi == BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV4 &&
+                               safi == BgpConstants.Open.Capabilities.MultiprotocolExtensions.SAFI_MULTICAST) {
+                        bgpSession.remoteInfo().setIpv4Multicast();
+                        bgpSession.localInfo().setIpv4Multicast();
+                    } else if (afi == BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV6 &&
+                               safi == BgpConstants.Open.Capabilities.MultiprotocolExtensions.SAFI_UNICAST) {
+                        bgpSession.remoteInfo().setIpv6Unicast();
+                        bgpSession.localInfo().setIpv6Unicast();
+                    } else if (afi == BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV6 &&
+                               safi == BgpConstants.Open.Capabilities.MultiprotocolExtensions.SAFI_MULTICAST) {
+                        bgpSession.remoteInfo().setIpv6Multicast();
+                        bgpSession.localInfo().setIpv6Multicast();
+                    } else {
+                        log.debug("BGP RX OPEN Capability: Unknown AFI = {} SAFI = {}",
+                                  afi, safi);
+                    }
+                    break;
+
+                case BgpConstants.Open.Capabilities.As4Octet.CODE:
+                    // Support for 4-octet AS Number Capabilities (RFC 6793)
+                    if (capabLen != BgpConstants.Open.Capabilities.As4Octet.LENGTH) {
+                        // ERROR: 4-octet AS Number Capability Length Error
+                        String errorMsg = "4-octet AS Number Capability Length Error";
+                        throw new BgpMessage.BgpParseException(errorMsg);
+                    }
+                    long as4Number = message.readUnsignedInt();
+
+                    bgpSession.remoteInfo().setAs4OctetCapability();
+                    bgpSession.remoteInfo().setAs4Number(as4Number);
+
+                    //
+                    // Copy remote 4-octet AS Number Capabilities and AS
+                    // Number. This is a temporary setting until local AS
+                    // number configuration is supported.
+                    //
+                    bgpSession.localInfo().setAs4OctetCapability();
+                    bgpSession.localInfo().setAs4Number(as4Number);
+                    log.debug("BGP RX OPEN Capability: AS4 Number = {}",
+                              as4Number);
+                    break;
+
+                default:
+                    // Unknown Capability: ignore it
+                    log.debug("BGP RX OPEN Capability Code = {} Length = {}",
+                              capabCode, capabLen);
+                    message.readBytes(capabLen);
+                    break;
+                }
+
+                break;
+
+            default:
+                // Unknown Parameter Type: ignore it
+                log.debug("BGP RX OPEN Parameter Type = {} Length = {}",
+                          paramType, paramLen);
+                message.readBytes(paramLen);
+                break;
+            }
+        }
+    }
+
+    /**
+     * Prepares the Capabilities for the BGP OPEN message.
+     *
+     * @param localInfo the BGP Session local information to use
+     * @return the buffer with the BGP Capabilities to transmit
+     */
+    private static ChannelBuffer prepareBgpOpenCapabilities(
+                                        BgpSessionInfo localInfo) {
+        ChannelBuffer message =
+            ChannelBuffers.buffer(BgpConstants.BGP_MESSAGE_MAX_LENGTH);
+
+        //
+        // Write the Multiprotocol Extensions Capabilities
+        //
+
+        // IPv4 unicast
+        if (localInfo.ipv4Unicast()) {
+            message.writeByte(BgpConstants.Open.Capabilities.TYPE);               // Param type
+            message.writeByte(BgpConstants.Open.Capabilities.MIN_LENGTH +
+                              BgpConstants.Open.Capabilities.MultiprotocolExtensions.LENGTH);  // Param len
+            message.writeByte(
+                    BgpConstants.Open.Capabilities.MultiprotocolExtensions.CODE);    // Capab. code
+            message.writeByte(
+                    BgpConstants.Open.Capabilities.MultiprotocolExtensions.LENGTH);  // Capab. len
+            message.writeShort(
+                    BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV4);
+            message.writeByte(0);               // Reserved field
+            message.writeByte(
+                    BgpConstants.Open.Capabilities.MultiprotocolExtensions.SAFI_UNICAST);
+        }
+        // IPv4 multicast
+        if (localInfo.ipv4Multicast()) {
+            message.writeByte(BgpConstants.Open.Capabilities.TYPE);               // Param type
+            message.writeByte(BgpConstants.Open.Capabilities.MIN_LENGTH +
+                              BgpConstants.Open.Capabilities.MultiprotocolExtensions.LENGTH);  // Param len
+            message.writeByte(
+                    BgpConstants.Open.Capabilities.MultiprotocolExtensions.CODE);    // Capab. code
+            message.writeByte(
+                    BgpConstants.Open.Capabilities.MultiprotocolExtensions.LENGTH);  // Capab. len
+            message.writeShort(
+                    BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV4);
+            message.writeByte(0);               // Reserved field
+            message.writeByte(
+                    BgpConstants.Open.Capabilities.MultiprotocolExtensions.SAFI_MULTICAST);
+        }
+        // IPv6 unicast
+        if (localInfo.ipv6Unicast()) {
+            message.writeByte(BgpConstants.Open.Capabilities.TYPE);               // Param type
+            message.writeByte(BgpConstants.Open.Capabilities.MIN_LENGTH +
+                              BgpConstants.Open.Capabilities.MultiprotocolExtensions.LENGTH);  // Param len
+            message.writeByte(
+                    BgpConstants.Open.Capabilities.MultiprotocolExtensions.CODE);    // Capab. code
+            message.writeByte(
+                    BgpConstants.Open.Capabilities.MultiprotocolExtensions.LENGTH);  // Capab. len
+            message.writeShort(
+                    BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV6);
+            message.writeByte(0);               // Reserved field
+            message.writeByte(
+                    BgpConstants.Open.Capabilities.MultiprotocolExtensions.SAFI_UNICAST);
+        }
+        // IPv6 multicast
+        if (localInfo.ipv6Multicast()) {
+            message.writeByte(BgpConstants.Open.Capabilities.TYPE);               // Param type
+            message.writeByte(BgpConstants.Open.Capabilities.MIN_LENGTH +
+                              BgpConstants.Open.Capabilities.MultiprotocolExtensions.LENGTH);  // Param len
+            message.writeByte(
+                    BgpConstants.Open.Capabilities.MultiprotocolExtensions.CODE);    // Capab. code
+            message.writeByte(
+                    BgpConstants.Open.Capabilities.MultiprotocolExtensions.LENGTH);  // Capab. len
+            message.writeShort(
+                    BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV6);
+            message.writeByte(0);               // Reserved field
+            message.writeByte(
+                    BgpConstants.Open.Capabilities.MultiprotocolExtensions.SAFI_MULTICAST);
+        }
+
+        // 4 octet AS path capability
+        if (localInfo.as4OctetCapability()) {
+            message.writeByte(BgpConstants.Open.Capabilities.TYPE);               // Param type
+            message.writeByte(BgpConstants.Open.Capabilities.MIN_LENGTH +
+                              BgpConstants.Open.Capabilities.As4Octet.LENGTH);                 // Param len
+            message.writeByte(BgpConstants.Open.Capabilities.As4Octet.CODE);                   // Capab. code
+            message.writeByte(BgpConstants.Open.Capabilities.As4Octet.LENGTH);                 // Capab. len
+            message.writeInt((int) localInfo.as4Number());
+        }
+        return message;
+    }
+}
diff --git a/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpRouteEntry.java b/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpRouteEntry.java
new file mode 100644
index 0000000..e7e7f3c
--- /dev/null
+++ b/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpRouteEntry.java
@@ -0,0 +1,494 @@
+/*
+ * Copyright 2014 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 com.google.common.base.MoreObjects;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.onosproject.routingapi.RouteEntry;
+
+import java.util.ArrayList;
+import java.util.Objects;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Represents a route in BGP.
+ */
+public class BgpRouteEntry extends RouteEntry {
+    private final BgpSession bgpSession; // The BGP Session the route was
+                                         // received on
+    private final byte origin;          // Route ORIGIN: IGP, EGP, INCOMPLETE
+    private final AsPath asPath;        // The AS Path
+    private final long localPref;       // The local preference for the route
+    private long multiExitDisc = BgpConstants.Update.MultiExitDisc.LOWEST_MULTI_EXIT_DISC;
+
+    /**
+     * Class constructor.
+     *
+     * @param bgpSession the BGP Session the route was received on
+     * @param prefix the prefix of the route
+     * @param nextHop the next hop of the route
+     * @param origin the route origin: 0=IGP, 1=EGP, 2=INCOMPLETE
+     * @param asPath the AS path
+     * @param localPref the route local preference
+     */
+    public BgpRouteEntry(BgpSession bgpSession, IpPrefix prefix,
+                         IpAddress nextHop, byte origin,
+                         BgpRouteEntry.AsPath asPath, long localPref) {
+        super(prefix, nextHop);
+        this.bgpSession = checkNotNull(bgpSession);
+        this.origin = origin;
+        this.asPath = checkNotNull(asPath);
+        this.localPref = localPref;
+    }
+
+    /**
+     * Gets the BGP Session the route was received on.
+     *
+     * @return the BGP Session the route was received on
+     */
+    public BgpSession getBgpSession() {
+        return bgpSession;
+    }
+
+    /**
+     * Gets the route origin: 0=IGP, 1=EGP, 2=INCOMPLETE.
+     *
+     * @return the route origin: 0=IGP, 1=EGP, 2=INCOMPLETE
+     */
+    public byte getOrigin() {
+        return origin;
+    }
+
+    /**
+     * Gets the route AS path.
+     *
+     * @return the route AS path
+     */
+    public BgpRouteEntry.AsPath getAsPath() {
+        return asPath;
+    }
+
+    /**
+     * Gets the route local preference.
+     *
+     * @return the route local preference
+     */
+    public long getLocalPref() {
+        return localPref;
+    }
+
+    /**
+     * Gets the route MED (Multi-Exit Discriminator).
+     *
+     * @return the route MED (Multi-Exit Discriminator)
+     */
+    public long getMultiExitDisc() {
+        return multiExitDisc;
+    }
+
+    /**
+     * Sets the route MED (Multi-Exit Discriminator).
+     *
+     * @param multiExitDisc the route MED (Multi-Exit Discriminator) to set
+     */
+    void setMultiExitDisc(long multiExitDisc) {
+        this.multiExitDisc = multiExitDisc;
+    }
+
+    /**
+     * Tests whether the route is originated from the local AS.
+     * <p>
+     * The route is considered originated from the local AS if the AS Path
+     * is empty or if it begins with an AS_SET (after skipping
+     * AS_CONFED_SEQUENCE and AS_CONFED_SET).
+     * </p>
+     *
+     * @return true if the route is originated from the local AS, otherwise
+     * false
+     */
+    boolean isLocalRoute() {
+        PathSegment firstPathSegment = null;
+
+        // Find the first Path Segment by ignoring the AS_CONFED_* segments
+        for (PathSegment pathSegment : asPath.getPathSegments()) {
+            if ((pathSegment.getType() == BgpConstants.Update.AsPath.AS_SET) ||
+                (pathSegment.getType() == BgpConstants.Update.AsPath.AS_SEQUENCE)) {
+                firstPathSegment = pathSegment;
+                break;
+            }
+        }
+        if (firstPathSegment == null) {
+            return true;                // Local route: no path segments
+        }
+        // If the first path segment is AS_SET, the route is considered local
+        if (firstPathSegment.getType() == BgpConstants.Update.AsPath.AS_SET) {
+            return true;
+        }
+
+        return false;                   // The route is not local
+    }
+
+    /**
+     * Gets the BGP Neighbor AS number the route was received from.
+     * <p>
+     * If the router is originated from the local AS, the return value is
+     * zero (BGP_AS_0).
+     * </p>
+     *
+     * @return the BGP Neighbor AS number the route was received from.
+     */
+    long getNeighborAs() {
+        PathSegment firstPathSegment = null;
+
+        if (isLocalRoute()) {
+            return BgpConstants.BGP_AS_0;
+        }
+
+        // Find the first Path Segment by ignoring the AS_CONFED_* segments
+        for (PathSegment pathSegment : asPath.getPathSegments()) {
+            if ((pathSegment.getType() == BgpConstants.Update.AsPath.AS_SET) ||
+                (pathSegment.getType() == BgpConstants.Update.AsPath.AS_SEQUENCE)) {
+                firstPathSegment = pathSegment;
+                break;
+            }
+        }
+        if (firstPathSegment == null) {
+            // NOTE: Shouldn't happen - should be captured by isLocalRoute()
+            return BgpConstants.BGP_AS_0;
+        }
+
+        if (firstPathSegment.getSegmentAsNumbers().isEmpty()) {
+            // NOTE: Shouldn't happen. Should check during the parsing.
+            return BgpConstants.BGP_AS_0;
+        }
+        return firstPathSegment.getSegmentAsNumbers().get(0);
+    }
+
+    /**
+     * Tests whether the AS Path contains a loop.
+     * <p>
+     * The test is done by comparing whether the AS Path contains the
+     * local AS number.
+     * </p>
+     *
+     * @param localAsNumber the local AS number to compare against
+     * @return true if the AS Path contains a loop, otherwise false
+     */
+    boolean hasAsPathLoop(long localAsNumber) {
+        for (PathSegment pathSegment : asPath.getPathSegments()) {
+            for (Long asNumber : pathSegment.getSegmentAsNumbers()) {
+                if (asNumber.equals(localAsNumber)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Compares this BGP route against another BGP route by using the
+     * BGP Decision Process.
+     * <p>
+     * NOTE: The comparison needs to be performed only on routes that have
+     * same IP Prefix.
+     * </p>
+     *
+     * @param other the BGP route to compare against
+     * @return true if this BGP route is better than the other BGP route
+     * or same, otherwise false
+     */
+    boolean isBetterThan(BgpRouteEntry other) {
+        if (this == other) {
+            return true;        // Return true if same route
+        }
+
+        // Compare the LOCAL_PREF values: larger is better
+        if (getLocalPref() != other.getLocalPref()) {
+            return (getLocalPref() > other.getLocalPref());
+        }
+
+        // Compare the AS number in the path: smaller is better
+        if (getAsPath().getAsPathLength() !=
+            other.getAsPath().getAsPathLength()) {
+            return getAsPath().getAsPathLength() <
+                other.getAsPath().getAsPathLength();
+        }
+
+        // Compare the Origin number: lower is better
+        if (getOrigin() != other.getOrigin()) {
+            return (getOrigin() < other.getOrigin());
+        }
+
+        // Compare the MED if the neighbor AS is same: larger is better
+        medLabel: {
+            if (isLocalRoute() || other.isLocalRoute()) {
+                // Compare MEDs for non-local routes only
+                break medLabel;
+            }
+            long thisNeighborAs = getNeighborAs();
+            if (thisNeighborAs != other.getNeighborAs()) {
+                break medLabel;             // AS number is different
+            }
+            if (thisNeighborAs == BgpConstants.BGP_AS_0) {
+                break medLabel;             // Invalid AS number
+            }
+
+            // Compare the MED
+            if (getMultiExitDisc() != other.getMultiExitDisc()) {
+                return (getMultiExitDisc() > other.getMultiExitDisc());
+            }
+        }
+
+        // Compare the peer BGP ID: lower is better
+        Ip4Address peerBgpId = getBgpSession().remoteInfo().bgpId();
+        Ip4Address otherPeerBgpId = other.getBgpSession().remoteInfo().bgpId();
+        if (!peerBgpId.equals(otherPeerBgpId)) {
+            return (peerBgpId.compareTo(otherPeerBgpId) < 0);
+        }
+
+        // Compare the peer BGP address: lower is better
+        Ip4Address peerAddress = getBgpSession().remoteInfo().ip4Address();
+        Ip4Address otherPeerAddress =
+            other.getBgpSession().remoteInfo().ip4Address();
+        if (!peerAddress.equals(otherPeerAddress)) {
+            return (peerAddress.compareTo(otherPeerAddress) < 0);
+        }
+
+        return true;            // Routes are same. Shouldn't happen?
+    }
+
+    /**
+     * A class to represent AS Path Segment.
+     */
+    public static class PathSegment {
+        // Segment type: AS_SET(1), AS_SEQUENCE(2), AS_CONFED_SEQUENCE(3),
+        // AS_CONFED_SET(4)
+        private final byte type;
+        private final ArrayList<Long> segmentAsNumbers;   // Segment AS numbers
+
+        /**
+         * Constructor.
+         *
+         * @param type the Path Segment Type: AS_SET(1), AS_SEQUENCE(2),
+         * AS_CONFED_SEQUENCE(3), AS_CONFED_SET(4)
+         * @param segmentAsNumbers the Segment AS numbers
+         */
+        PathSegment(byte type, ArrayList<Long> segmentAsNumbers) {
+            this.type = type;
+            this.segmentAsNumbers = checkNotNull(segmentAsNumbers);
+        }
+
+        /**
+         * Gets the Path Segment Type: AS_SET(1), AS_SEQUENCE(2),
+         * AS_CONFED_SEQUENCE(3), AS_CONFED_SET(4).
+         *
+         * @return the Path Segment Type: AS_SET(1), AS_SEQUENCE(2),
+         * AS_CONFED_SEQUENCE(3), AS_CONFED_SET(4)
+         */
+        public byte getType() {
+            return type;
+        }
+
+        /**
+         * Gets the Path Segment AS Numbers.
+         *
+         * @return the Path Segment AS Numbers
+         */
+        public ArrayList<Long> getSegmentAsNumbers() {
+            return segmentAsNumbers;
+        }
+
+        @Override
+        public boolean equals(Object other) {
+            if (this == other) {
+                return true;
+            }
+
+            if (!(other instanceof PathSegment)) {
+                return false;
+            }
+
+            PathSegment otherPathSegment = (PathSegment) other;
+            return Objects.equals(this.type, otherPathSegment.type) &&
+                Objects.equals(this.segmentAsNumbers,
+                               otherPathSegment.segmentAsNumbers);
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(type, segmentAsNumbers);
+        }
+
+        @Override
+        public String toString() {
+            return MoreObjects.toStringHelper(getClass())
+                .add("type", BgpConstants.Update.AsPath.typeToString(type))
+                .add("segmentAsNumbers", this.segmentAsNumbers)
+                .toString();
+        }
+    }
+
+    /**
+     * A class to represent AS Path.
+     */
+    public static class AsPath {
+        private final ArrayList<PathSegment> pathSegments;
+        private final int asPathLength;         // Precomputed AS Path Length
+
+        /**
+         * Constructor.
+         *
+         * @param pathSegments the Path Segments of the Path
+         */
+         AsPath(ArrayList<PathSegment> pathSegments) {
+             this.pathSegments = checkNotNull(pathSegments);
+
+             //
+             // Precompute the AS Path Length:
+             // - AS_SET counts as 1
+             // - AS_SEQUENCE counts how many AS numbers are included
+             // - AS_CONFED_SEQUENCE and AS_CONFED_SET are ignored
+             //
+             int pl = 0;
+             for (PathSegment pathSegment : pathSegments) {
+                 switch (pathSegment.getType()) {
+                 case BgpConstants.Update.AsPath.AS_SET:
+                     pl++;              // AS_SET counts as 1
+                     break;
+                 case BgpConstants.Update.AsPath.AS_SEQUENCE:
+                     // Count each AS number
+                     pl += pathSegment.getSegmentAsNumbers().size();
+                     break;
+                 case BgpConstants.Update.AsPath.AS_CONFED_SEQUENCE:
+                     break;             // Ignore
+                 case BgpConstants.Update.AsPath.AS_CONFED_SET:
+                     break;             // Ignore
+                 default:
+                     // NOTE: What to do if the Path Segment type is unknown?
+                     break;
+                 }
+             }
+             asPathLength = pl;
+         }
+
+        /**
+         * Gets the AS Path Segments.
+         *
+         * @return the AS Path Segments
+         */
+        public ArrayList<PathSegment> getPathSegments() {
+            return pathSegments;
+        }
+
+        /**
+         * Gets the AS Path Length as considered by the BGP Decision Process.
+         *
+         * @return the AS Path Length as considered by the BGP Decision Process
+         */
+        int getAsPathLength() {
+            return asPathLength;
+        }
+
+        @Override
+        public boolean equals(Object other) {
+            if (this == other) {
+                return true;
+            }
+
+            if (!(other instanceof AsPath)) {
+                return false;
+            }
+
+            AsPath otherAsPath = (AsPath) other;
+            return Objects.equals(this.pathSegments, otherAsPath.pathSegments);
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(pathSegments);
+        }
+
+        @Override
+        public String toString() {
+            return MoreObjects.toStringHelper(getClass())
+                .add("pathSegments", this.pathSegments)
+                .toString();
+        }
+    }
+
+    /**
+     * Compares whether two objects are equal.
+     * <p>
+     * NOTE: The bgpSession field is excluded from the comparison.
+     * </p>
+     *
+     * @return true if the two objects are equal, otherwise false.
+     */
+    @Override
+    public boolean equals(Object other) {
+        if (this == other) {
+            return true;
+        }
+
+        //
+        // NOTE: Subclasses are considered as change of identity, hence
+        // equals() will return false if the class type doesn't match.
+        //
+        if (other == null || getClass() != other.getClass()) {
+            return false;
+        }
+
+        if (!super.equals(other)) {
+            return false;
+        }
+
+        // NOTE: The bgpSession field is excluded from the comparison
+        BgpRouteEntry otherRoute = (BgpRouteEntry) other;
+        return (this.origin == otherRoute.origin) &&
+            Objects.equals(this.asPath, otherRoute.asPath) &&
+            (this.localPref == otherRoute.localPref) &&
+            (this.multiExitDisc == otherRoute.multiExitDisc);
+    }
+
+    /**
+     * Computes the hash code.
+     * <p>
+     * NOTE: We return the base class hash code to avoid expensive computation
+     * </p>
+     *
+     * @return the object hash code
+     */
+    @Override
+    public int hashCode() {
+        return super.hashCode();
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+            .add("prefix", prefix())
+            .add("nextHop", nextHop())
+            .add("bgpId", bgpSession.remoteInfo().bgpId())
+            .add("origin", BgpConstants.Update.Origin.typeToString(origin))
+            .add("asPath", asPath)
+            .add("localPref", localPref)
+            .add("multiExitDisc", multiExitDisc)
+            .toString();
+    }
+}
diff --git a/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpRouteSelector.java b/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpRouteSelector.java
new file mode 100644
index 0000000..e95aaff
--- /dev/null
+++ b/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpRouteSelector.java
@@ -0,0 +1,202 @@
+/*
+ * 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.routing.bgp;
+
+import org.onlab.packet.IpPrefix;
+import org.onosproject.routingapi.RouteUpdate;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Collection;
+import java.util.LinkedList;
+
+/**
+ * Class to receive and process the BGP routes from each BGP Session/Peer.
+ */
+class BgpRouteSelector {
+    private static final Logger log =
+        LoggerFactory.getLogger(BgpRouteSelector.class);
+
+    private BgpSessionManager bgpSessionManager;
+
+    /**
+     * Constructor.
+     *
+     * @param bgpSessionManager the BGP Session Manager to use
+     */
+    BgpRouteSelector(BgpSessionManager bgpSessionManager) {
+        this.bgpSessionManager = bgpSessionManager;
+    }
+
+    /**
+     * Processes route entry updates: added/updated and deleted route
+     * entries.
+     *
+     * @param bgpSession the BGP session the route entry updates were
+     * received on
+     * @param addedBgpRouteEntries the added/updated route entries to process
+     * @param deletedBgpRouteEntries the deleted route entries to process
+     */
+    synchronized void routeUpdates(BgpSession bgpSession,
+                        Collection<BgpRouteEntry> addedBgpRouteEntries,
+                        Collection<BgpRouteEntry> deletedBgpRouteEntries) {
+        Collection<RouteUpdate> routeUpdates = new LinkedList<>();
+        RouteUpdate routeUpdate;
+
+        if (bgpSessionManager.isShutdown()) {
+            return;         // Ignore any leftover updates if shutdown
+        }
+        // Process the deleted route entries
+        for (BgpRouteEntry bgpRouteEntry : deletedBgpRouteEntries) {
+            routeUpdate = processDeletedRoute(bgpSession, bgpRouteEntry);
+            if (routeUpdate != null) {
+                routeUpdates.add(routeUpdate);
+            }
+        }
+
+        // Process the added/updated route entries
+        for (BgpRouteEntry bgpRouteEntry : addedBgpRouteEntries) {
+            routeUpdate = processAddedRoute(bgpSession, bgpRouteEntry);
+            if (routeUpdate != null) {
+                routeUpdates.add(routeUpdate);
+            }
+        }
+        bgpSessionManager.getRouteListener().update(routeUpdates);
+    }
+
+    /**
+     * Processes an added/updated route entry.
+     *
+     * @param bgpSession the BGP session the route entry update was received on
+     * @param bgpRouteEntry the added/updated route entry
+     * @return the result route update that should be forwarded to the
+     * Route Listener, or null if no route update should be forwarded
+     */
+    private RouteUpdate processAddedRoute(BgpSession bgpSession,
+                                          BgpRouteEntry bgpRouteEntry) {
+        RouteUpdate routeUpdate;
+        BgpRouteEntry bestBgpRouteEntry =
+            bgpSessionManager.findBgpRoute(bgpRouteEntry.prefix());
+
+        //
+        // Install the new route entry if it is better than the
+        // current best route.
+        //
+        if ((bestBgpRouteEntry == null) ||
+            bgpRouteEntry.isBetterThan(bestBgpRouteEntry)) {
+            bgpSessionManager.addBgpRoute(bgpRouteEntry);
+            routeUpdate =
+                new RouteUpdate(RouteUpdate.Type.UPDATE, bgpRouteEntry);
+            return routeUpdate;
+        }
+
+        //
+        // If the route entry arrived on the same BGP Session as
+        // the current best route, then elect the next best route
+        // and install it.
+        //
+        if (bestBgpRouteEntry.getBgpSession() !=
+            bgpRouteEntry.getBgpSession()) {
+            return null;            // Nothing to do
+        }
+
+        // Find the next best route
+        bestBgpRouteEntry = findBestBgpRoute(bgpRouteEntry.prefix());
+        if (bestBgpRouteEntry == null) {
+            //
+            // TODO: Shouldn't happen. Install the new route as a
+            // pre-caution.
+            //
+            log.debug("BGP next best route for prefix {} is missing. " +
+                      "Adding the route that is currently processed.",
+                      bgpRouteEntry.prefix());
+            bestBgpRouteEntry = bgpRouteEntry;
+        }
+
+        // Install the next best route
+        bgpSessionManager.addBgpRoute(bestBgpRouteEntry);
+        routeUpdate = new RouteUpdate(RouteUpdate.Type.UPDATE,
+                                      bestBgpRouteEntry);
+        return routeUpdate;
+    }
+
+    /**
+     * Processes a deleted route entry.
+     *
+     * @param bgpSession the BGP session the route entry update was received on
+     * @param bgpRouteEntry the deleted route entry
+     * @return the result route update that should be forwarded to the
+     * Route Listener, or null if no route update should be forwarded
+     */
+    private RouteUpdate processDeletedRoute(BgpSession bgpSession,
+                                            BgpRouteEntry bgpRouteEntry) {
+        RouteUpdate routeUpdate;
+        BgpRouteEntry bestBgpRouteEntry =
+            bgpSessionManager.findBgpRoute(bgpRouteEntry.prefix());
+
+        //
+        // Remove the route entry only if it was the best one.
+        // Install the the next best route if it exists.
+        //
+        // NOTE: We intentionally use "==" instead of method equals(),
+        // because we need to check whether this is same object.
+        //
+        if (bgpRouteEntry != bestBgpRouteEntry) {
+            return null;            // Nothing to do
+        }
+
+        //
+        // Find the next best route
+        //
+        bestBgpRouteEntry = findBestBgpRoute(bgpRouteEntry.prefix());
+        if (bestBgpRouteEntry != null) {
+            // Install the next best route
+            bgpSessionManager.addBgpRoute(bestBgpRouteEntry);
+            routeUpdate = new RouteUpdate(RouteUpdate.Type.UPDATE,
+                                          bestBgpRouteEntry);
+            return routeUpdate;
+        }
+
+        //
+        // No route found. Remove the route entry
+        //
+        bgpSessionManager.removeBgpRoute(bgpRouteEntry.prefix());
+        routeUpdate = new RouteUpdate(RouteUpdate.Type.DELETE, bgpRouteEntry);
+        return routeUpdate;
+    }
+
+    /**
+     * Finds the best route entry among all BGP Sessions.
+     *
+     * @param prefix the prefix of the route
+     * @return the best route if found, otherwise null
+     */
+    private BgpRouteEntry findBestBgpRoute(IpPrefix prefix) {
+        BgpRouteEntry bestRoute = null;
+
+        // Iterate across all BGP Sessions and select the best route
+        for (BgpSession bgpSession : bgpSessionManager.getBgpSessions()) {
+            BgpRouteEntry route = bgpSession.findBgpRoute(prefix);
+            if (route == null) {
+                continue;
+            }
+            if ((bestRoute == null) || route.isBetterThan(bestRoute)) {
+                bestRoute = route;
+            }
+        }
+        return bestRoute;
+    }
+}
diff --git a/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpSession.java b/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpSession.java
new file mode 100644
index 0000000..e0a2617
--- /dev/null
+++ b/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpSession.java
@@ -0,0 +1,473 @@
+/*
+ * Copyright 2014 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.jboss.netty.buffer.ChannelBuffer;
+import org.jboss.netty.channel.ChannelHandlerContext;
+import org.jboss.netty.channel.ChannelStateEvent;
+import org.jboss.netty.channel.ExceptionEvent;
+import org.jboss.netty.channel.SimpleChannelHandler;
+import org.jboss.netty.util.HashedWheelTimer;
+import org.jboss.netty.util.Timeout;
+import org.jboss.netty.util.Timer;
+import org.jboss.netty.util.TimerTask;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip4Prefix;
+import org.onlab.packet.Ip6Prefix;
+import org.onlab.packet.IpPrefix;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Class for handling the BGP peer sessions.
+ * There is one instance per each BGP peer session.
+ */
+public class BgpSession extends SimpleChannelHandler {
+    private static final Logger log =
+        LoggerFactory.getLogger(BgpSession.class);
+
+    private final BgpSessionManager bgpSessionManager;
+
+    // Local flag to indicate the session is closed.
+    // It is used to avoid the Netty's asynchronous closing of a channel.
+    private boolean isClosed = false;
+
+    // BGP session info: local and remote
+    private final BgpSessionInfo localInfo;     // BGP session local info
+    private final BgpSessionInfo remoteInfo;    // BGP session remote info
+
+    // Timers state
+    private Timer timer = new HashedWheelTimer();
+    private volatile Timeout keepaliveTimeout;  // Periodic KEEPALIVE
+    private volatile Timeout sessionTimeout;    // Session timeout
+
+    // BGP RIB-IN routing entries from this peer
+    private ConcurrentMap<Ip4Prefix, BgpRouteEntry> bgpRibIn4 =
+        new ConcurrentHashMap<>();
+    private ConcurrentMap<Ip6Prefix, BgpRouteEntry> bgpRibIn6 =
+        new ConcurrentHashMap<>();
+
+    /**
+     * Constructor for a given BGP Session Manager.
+     *
+     * @param bgpSessionManager the BGP Session Manager to use
+     */
+    BgpSession(BgpSessionManager bgpSessionManager) {
+        this.bgpSessionManager = bgpSessionManager;
+        this.localInfo = new BgpSessionInfo();
+        this.remoteInfo = new BgpSessionInfo();
+
+        // NOTE: We support only BGP4
+        this.localInfo.setBgpVersion(BgpConstants.BGP_VERSION);
+    }
+
+    /**
+     * Gets the BGP Session Manager.
+     *
+     * @return the BGP Session Manager
+     */
+    BgpSessionManager getBgpSessionManager() {
+        return bgpSessionManager;
+    }
+
+    /**
+     * Gets the BGP Session local information.
+     *
+     * @return the BGP Session local information.
+     */
+    public BgpSessionInfo localInfo() {
+        return localInfo;
+    }
+
+    /**
+     * Gets the BGP Session remote information.
+     *
+     * @return the BGP Session remote information.
+     */
+    public BgpSessionInfo remoteInfo() {
+        return remoteInfo;
+    }
+
+    /**
+     * Gets the BGP Multiprotocol Extensions for the session.
+     *
+     * @return true if the BGP Multiprotocol Extensions are enabled for the
+     * session, otherwise false
+     */
+    public boolean mpExtensions() {
+        return remoteInfo.mpExtensions() && localInfo.mpExtensions();
+    }
+
+    /**
+     * Gets the BGP session 4 octet AS path capability.
+     *
+     * @return true when the BGP session is 4 octet AS path capable
+     */
+    public boolean isAs4OctetCapable() {
+        return remoteInfo.as4OctetCapability() &&
+            localInfo.as4OctetCapability();
+    }
+
+    /**
+     * Gets the IPv4 BGP RIB-IN routing entries.
+     *
+     * @return the IPv4 BGP RIB-IN routing entries
+     */
+    public Collection<BgpRouteEntry> getBgpRibIn4() {
+        return bgpRibIn4.values();
+    }
+
+    /**
+     * Gets the IPv6 BGP RIB-IN routing entries.
+     *
+     * @return the IPv6 BGP RIB-IN routing entries
+     */
+    public Collection<BgpRouteEntry> getBgpRibIn6() {
+        return bgpRibIn6.values();
+    }
+
+    /**
+     * Finds an IPv4 BGP routing entry for a prefix in the IPv4 BGP RIB-IN.
+     *
+     * @param prefix the IPv4 prefix of the route to search for
+     * @return the IPv4 BGP routing entry if found, otherwise null
+     */
+    public BgpRouteEntry findBgpRoute(Ip4Prefix prefix) {
+        return bgpRibIn4.get(prefix);
+    }
+
+    /**
+     * Finds an IPv6 BGP routing entry for a prefix in the IPv6 BGP RIB-IN.
+     *
+     * @param prefix the IPv6 prefix of the route to search for
+     * @return the IPv6 BGP routing entry if found, otherwise null
+     */
+    public BgpRouteEntry findBgpRoute(Ip6Prefix prefix) {
+        return bgpRibIn6.get(prefix);
+    }
+
+    /**
+     * Finds a BGP routing entry for a prefix in the BGP RIB-IN. The prefix
+     * can be either IPv4 or IPv6.
+     *
+     * @param prefix the IP prefix of the route to search for
+     * @return the BGP routing entry if found, otherwise null
+     */
+    public BgpRouteEntry findBgpRoute(IpPrefix prefix) {
+        if (prefix.version() == Ip4Address.VERSION) {
+            // IPv4 prefix
+            Ip4Prefix ip4Prefix = prefix.getIp4Prefix();
+            return bgpRibIn4.get(ip4Prefix);
+        }
+
+        // IPv6 prefix
+        Ip6Prefix ip6Prefix = prefix.getIp6Prefix();
+        return bgpRibIn6.get(ip6Prefix);
+    }
+
+    /**
+     * 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.version() == Ip4Address.VERSION) {
+            // IPv4 route
+            Ip4Prefix ip4Prefix = bgpRouteEntry.prefix().getIp4Prefix();
+            bgpRibIn4.put(ip4Prefix, bgpRouteEntry);
+        } else {
+            // IPv6 route
+            Ip6Prefix ip6Prefix = bgpRouteEntry.prefix().getIp6Prefix();
+            bgpRibIn6.put(ip6Prefix, bgpRouteEntry);
+        }
+    }
+
+    /**
+     * Removes an IPv4 BGP route for a prefix.
+     *
+     * @param prefix the prefix to use
+     * @return true if the route was found and removed, otherwise false
+     */
+    boolean removeBgpRoute(Ip4Prefix prefix) {
+        return (bgpRibIn4.remove(prefix) != null);
+    }
+
+    /**
+     * Removes an IPv6 BGP route for a prefix.
+     *
+     * @param prefix the prefix to use
+     * @return true if the route was found and removed, otherwise false
+     */
+    boolean removeBgpRoute(Ip6Prefix prefix) {
+        return (bgpRibIn6.remove(prefix) != null);
+    }
+
+    /**
+     * 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.version() == Ip4Address.VERSION) {
+            return (bgpRibIn4.remove(prefix.getIp4Prefix()) != null);   // IPv4
+        }
+        return (bgpRibIn6.remove(prefix.getIp6Prefix()) != null);       // IPv6
+    }
+
+    /**
+     * Tests whether the session is closed.
+     * <p>
+     * NOTE: We use this method to avoid the Netty's asynchronous closing
+     * of a channel.
+     * </p>
+     * @return true if the session is closed
+     */
+    boolean isClosed() {
+        return isClosed;
+    }
+
+    /**
+     * Closes the session.
+     *
+     * @param ctx the Channel Handler Context
+     */
+    void closeSession(ChannelHandlerContext ctx) {
+        timer.stop();
+        closeChannel(ctx);
+    }
+
+    /**
+     * Closes the Netty channel.
+     *
+     * @param ctx the Channel Handler Context
+     */
+    void closeChannel(ChannelHandlerContext ctx) {
+        isClosed = true;
+        ctx.getChannel().close();
+    }
+
+    @Override
+    public void channelOpen(ChannelHandlerContext ctx,
+                            ChannelStateEvent channelEvent) {
+        bgpSessionManager.addSessionChannel(channelEvent.getChannel());
+    }
+
+    @Override
+    public void channelClosed(ChannelHandlerContext ctx,
+                              ChannelStateEvent channelEvent) {
+        bgpSessionManager.removeSessionChannel(channelEvent.getChannel());
+    }
+
+    @Override
+    public void channelConnected(ChannelHandlerContext ctx,
+                                 ChannelStateEvent channelEvent) {
+        localInfo.setAddress(ctx.getChannel().getLocalAddress());
+        remoteInfo.setAddress(ctx.getChannel().getRemoteAddress());
+
+        // Assign the local and remote IPv4 addresses
+        InetAddress inetAddr;
+        if (localInfo.address() instanceof InetSocketAddress) {
+            inetAddr = ((InetSocketAddress) localInfo.address()).getAddress();
+            localInfo.setIp4Address(Ip4Address.valueOf(inetAddr.getAddress()));
+        }
+        if (remoteInfo.address() instanceof InetSocketAddress) {
+            inetAddr = ((InetSocketAddress) remoteInfo.address()).getAddress();
+            remoteInfo.setIp4Address(Ip4Address.valueOf(inetAddr.getAddress()));
+        }
+
+        log.debug("BGP Session Connected from {} on {}",
+                  remoteInfo.address(), localInfo.address());
+        if (!bgpSessionManager.peerConnected(this)) {
+            log.debug("Cannot setup BGP Session Connection from {}. Closing...",
+                      remoteInfo.address());
+            ctx.getChannel().close();
+        }
+
+        //
+        // Assign the local BGP ID
+        // NOTE: This should be configuration-based
+        //
+        localInfo.setBgpId(bgpSessionManager.getMyBgpId());
+    }
+
+    @Override
+    public void channelDisconnected(ChannelHandlerContext ctx,
+                                    ChannelStateEvent channelEvent) {
+        log.debug("BGP Session Disconnected from {} on {}",
+                  ctx.getChannel().getRemoteAddress(),
+                  ctx.getChannel().getLocalAddress());
+        processChannelDisconnected();
+    }
+
+    @Override
+    public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) {
+        log.debug("BGP Session Exception Caught from {} on {}: {}",
+                  ctx.getChannel().getRemoteAddress(),
+                  ctx.getChannel().getLocalAddress(),
+                  e);
+        processChannelDisconnected();
+    }
+
+    /**
+     * Processes the channel being disconnected.
+     */
+    private void processChannelDisconnected() {
+        //
+        // Withdraw the routes advertised by this BGP peer
+        //
+        // NOTE: We must initialize the RIB-IN before propagating the withdraws
+        // for further processing. Otherwise, the BGP Decision Process
+        // will use those routes again.
+        //
+        Collection<BgpRouteEntry> deletedRoutes4 = bgpRibIn4.values();
+        Collection<BgpRouteEntry> deletedRoutes6 = bgpRibIn6.values();
+        bgpRibIn4 = new ConcurrentHashMap<>();
+        bgpRibIn6 = new ConcurrentHashMap<>();
+
+        // Push the updates to the BGP Merged RIB
+        BgpRouteSelector bgpRouteSelector =
+            bgpSessionManager.getBgpRouteSelector();
+        Collection<BgpRouteEntry> addedRoutes = Collections.emptyList();
+        bgpRouteSelector.routeUpdates(this, addedRoutes, deletedRoutes4);
+        bgpRouteSelector.routeUpdates(this, addedRoutes, deletedRoutes6);
+
+        bgpSessionManager.peerDisconnected(this);
+    }
+
+    /**
+     * Restarts the BGP KeepaliveTimer.
+     *
+     * @param ctx the Channel Handler Context to use
+     */
+    void restartKeepaliveTimer(ChannelHandlerContext ctx) {
+        long localKeepaliveInterval = 0;
+
+        //
+        // Compute the local Keepalive interval
+        //
+        if (localInfo.holdtime() != 0) {
+            localKeepaliveInterval = Math.max(localInfo.holdtime() /
+                         BgpConstants.BGP_KEEPALIVE_PER_HOLD_INTERVAL,
+                         BgpConstants.BGP_KEEPALIVE_MIN_INTERVAL);
+        }
+
+        // Restart the Keepalive timer
+        if (localKeepaliveInterval == 0) {
+            return;                 // Nothing to do
+        }
+        keepaliveTimeout = timer.newTimeout(new TransmitKeepaliveTask(ctx),
+                                            localKeepaliveInterval,
+                                            TimeUnit.SECONDS);
+    }
+
+    /**
+     * Task class for transmitting KEEPALIVE messages.
+     */
+    private final class TransmitKeepaliveTask implements TimerTask {
+        private final ChannelHandlerContext ctx;
+
+        /**
+         * Constructor for given Channel Handler Context.
+         *
+         * @param ctx the Channel Handler Context to use
+         */
+        TransmitKeepaliveTask(ChannelHandlerContext ctx) {
+            this.ctx = ctx;
+        }
+
+        @Override
+        public void run(Timeout timeout) throws Exception {
+            if (timeout.isCancelled()) {
+                return;
+            }
+            if (!ctx.getChannel().isOpen()) {
+                return;
+            }
+
+            // Transmit the KEEPALIVE
+            ChannelBuffer txMessage = BgpKeepalive.prepareBgpKeepalive();
+            ctx.getChannel().write(txMessage);
+
+            // Restart the KEEPALIVE timer
+            restartKeepaliveTimer(ctx);
+        }
+    }
+
+    /**
+     * Restarts the BGP Session Timeout Timer.
+     *
+     * @param ctx the Channel Handler Context to use
+     */
+    void restartSessionTimeoutTimer(ChannelHandlerContext ctx) {
+        if (remoteInfo.holdtime() == 0) {
+            return;                 // Nothing to do
+        }
+        if (sessionTimeout != null) {
+            sessionTimeout.cancel();
+        }
+        sessionTimeout = timer.newTimeout(new SessionTimeoutTask(ctx),
+                                          remoteInfo.holdtime(),
+                                          TimeUnit.SECONDS);
+    }
+
+    /**
+     * Task class for BGP Session timeout.
+     */
+    private final class SessionTimeoutTask implements TimerTask {
+        private final ChannelHandlerContext ctx;
+
+        /**
+         * Constructor for given Channel Handler Context.
+         *
+         * @param ctx the Channel Handler Context to use
+         */
+        SessionTimeoutTask(ChannelHandlerContext ctx) {
+            this.ctx = ctx;
+        }
+
+        @Override
+        public void run(Timeout timeout) throws Exception {
+            if (timeout.isCancelled()) {
+                return;
+            }
+            if (!ctx.getChannel().isOpen()) {
+                return;
+            }
+
+            log.debug("BGP Session Timeout: peer {}", remoteInfo.address());
+            //
+            // ERROR: Invalid Optional Parameter Length field: Unspecific
+            //
+            // Send NOTIFICATION and close the connection
+            int errorCode = BgpConstants.Notifications.HoldTimerExpired.ERROR_CODE;
+            int errorSubcode = BgpConstants.Notifications.ERROR_SUBCODE_UNSPECIFIC;
+            ChannelBuffer txMessage =
+                BgpNotification.prepareBgpNotification(errorCode, errorSubcode,
+                                                       null);
+            ctx.getChannel().write(txMessage);
+            closeChannel(ctx);
+        }
+    }
+}
diff --git a/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpSessionInfo.java b/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpSessionInfo.java
new file mode 100644
index 0000000..a127455
--- /dev/null
+++ b/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpSessionInfo.java
@@ -0,0 +1,272 @@
+/*
+ * 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.routing.bgp;
+
+import org.onlab.packet.Ip4Address;
+
+import java.net.SocketAddress;
+
+/**
+ * Class for keeping information about a BGP session.
+ *
+ * There are two instances per each BGP peer session: one to keep the local
+ * information about the BGP session, and another to keep information about
+ * the remote BGP peer.
+ */
+public class BgpSessionInfo {
+    private SocketAddress address;              // IP addr/port
+    private Ip4Address ip4Address;              // IPv4 address
+    private int bgpVersion;                     // 1 octet
+    private long asNumber;                      // AS number: 2 octets
+    private long as4Number;                     // AS4 number: 4 octets
+    private long holdtime;                      // 2 octets
+    private Ip4Address bgpId;                   // 4 octets -> IPv4 address
+    private boolean mpExtensions;               // Multiprotocol Extensions
+                                                // enabled: RFC 4760
+    private boolean ipv4Unicast;                // IPv4/UNICAST AFI/SAFI
+    private boolean ipv4Multicast;              // IPv4/MULTICAST AFI/SAFI
+    private boolean ipv6Unicast;                // IPv6/UNICAST AFI/SAFI
+    private boolean ipv6Multicast;              // IPv6/MULTICAST AFI/SAFI
+    private boolean as4OctetCapability;         // AS 4 octet path capability
+
+    /**
+     * Gets the BGP session address: local or remote.
+     *
+     * @return the BGP session address
+     */
+    public SocketAddress address() {
+        return this.address;
+    }
+
+    /**
+     * Sets the BGP session address: local or remote.
+     *
+     * @param address the BGP session address to set
+     */
+    public void setAddress(SocketAddress address) {
+        this.address = address;
+    }
+
+    /**
+     * Gets the BGP session IPv4 address: local or remote.
+     *
+     * @return the BGP session IPv4 address
+     */
+    public Ip4Address ip4Address() {
+        return this.ip4Address;
+    }
+
+    /**
+     * Sets the BGP session IPv4 address: local or remote.
+     *
+     * @param ip4Address the BGP session IPv4 address to set
+     */
+    public void setIp4Address(Ip4Address ip4Address) {
+        this.ip4Address = ip4Address;
+    }
+
+    /**
+     * Gets the BGP session BGP version: local or remote.
+     *
+     * @return the BGP session BGP version
+     */
+    public int bgpVersion() {
+        return this.bgpVersion;
+    }
+
+    /**
+     * Sets the BGP session BGP version: local or remote.
+     *
+     * @param bgpVersion the BGP session BGP version to set
+     */
+    public void setBgpVersion(int bgpVersion) {
+        this.bgpVersion = bgpVersion;
+    }
+
+    /**
+     * Gets the BGP session AS number: local or remote.
+     *
+     * @return the BGP session AS number
+     */
+    public long asNumber() {
+        return this.asNumber;
+    }
+
+    /**
+     * Sets the BGP session AS number: local or remote.
+     *
+     * @param asNumber the BGP session AS number to set
+     */
+    public void setAsNumber(long asNumber) {
+        this.asNumber = asNumber;
+    }
+
+    /**
+     * Gets the BGP session AS4 number: local or remote.
+     *
+     * @return the BGP session AS4 number
+     */
+    public long as4Number() {
+        return this.as4Number;
+    }
+
+    /**
+     * Sets the BGP session AS4 number: local or remote.
+     *
+     * @param as4Number the BGP session AS4 number to set
+     */
+    public void setAs4Number(long as4Number) {
+        this.as4Number = as4Number;
+    }
+
+    /**
+     * Gets the BGP session holdtime: local or remote.
+     *
+     * @return the BGP session holdtime
+     */
+    public long holdtime() {
+        return this.holdtime;
+    }
+
+    /**
+     * Sets the BGP session holdtime: local or remote.
+     *
+     * @param holdtime the BGP session holdtime to set
+     */
+    public void setHoldtime(long holdtime) {
+        this.holdtime = holdtime;
+    }
+
+    /**
+     * Gets the BGP session BGP Identifier as an IPv4 address: local or remote.
+     *
+     * @return the BGP session BGP Identifier as an IPv4 address
+     */
+    public Ip4Address bgpId() {
+        return this.bgpId;
+    }
+
+    /**
+     * Sets the BGP session BGP Identifier as an IPv4 address: local or remote.
+     *
+     * @param bgpId the BGP session BGP Identifier to set
+     */
+    public void setBgpId(Ip4Address bgpId) {
+        this.bgpId = bgpId;
+    }
+
+    /**
+     * Gets the BGP Multiprotocol Extensions: local or remote.
+     *
+     * @return true if the BGP Multiprotocol Extensions are enabled, otherwise
+     * false
+     */
+    public boolean mpExtensions() {
+        return this.mpExtensions;
+    }
+
+    /**
+     * Gets the BGP session AFI/SAFI configuration for IPv4 unicast: local or
+     * remote.
+     *
+     * @return the BGP session AFI/SAFI configuration for IPv4 unicast
+     */
+    public boolean ipv4Unicast() {
+        return ipv4Unicast;
+    }
+
+    /**
+     * Sets the BGP session AFI/SAFI configuration for IPv4 unicast: local or
+     * remote.
+     */
+    public void setIpv4Unicast() {
+        this.mpExtensions = true;
+        this.ipv4Unicast = true;
+    }
+
+    /**
+     * Gets the BGP session AFI/SAFI configuration for IPv4 multicast: local or
+     * remote.
+     *
+     * @return the BGP session AFI/SAFI configuration for IPv4 multicast
+     */
+    public boolean ipv4Multicast() {
+        return ipv4Multicast;
+    }
+
+    /**
+     * Sets the BGP session AFI/SAFI configuration for IPv4 multicast: local or
+     * remote.
+     */
+    public void setIpv4Multicast() {
+        this.mpExtensions = true;
+        this.ipv4Multicast = true;
+    }
+
+    /**
+     * Gets the BGP session AFI/SAFI configuration for IPv6 unicast: local or
+     * remote.
+     *
+     * @return the BGP session AFI/SAFI configuration for IPv6 unicast
+     */
+    public boolean ipv6Unicast() {
+        return ipv6Unicast;
+    }
+
+    /**
+     * Sets the BGP session AFI/SAFI configuration for IPv6 unicast: local or
+     * remote.
+     */
+    void setIpv6Unicast() {
+        this.mpExtensions = true;
+        this.ipv6Unicast = true;
+    }
+
+    /**
+     * Gets the BGP session AFI/SAFI configuration for IPv6 multicast: local or
+     * remote.
+     *
+     * @return the BGP session AFI/SAFI configuration for IPv6 multicast
+     */
+    public boolean ipv6Multicast() {
+        return ipv6Multicast;
+    }
+
+    /**
+     * Sets the BGP session AFI/SAFI configuration for IPv6 multicast: local or
+     * remote.
+     */
+    public void setIpv6Multicast() {
+        this.mpExtensions = true;
+        this.ipv6Multicast = true;
+    }
+
+    /**
+     * Gets the BGP session 4 octet AS path capability: local or remote.
+     *
+     * @return true when the BGP session has 4 octet AS path capability
+     */
+    public boolean as4OctetCapability() {
+        return this.as4OctetCapability;
+    }
+
+    /**
+     * Sets the BGP session 4 octet AS path capability.
+     */
+    public void setAs4OctetCapability() {
+        this.as4OctetCapability = true;
+    }
+}
diff --git a/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpSessionManager.java b/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpSessionManager.java
new file mode 100644
index 0000000..cfd0081
--- /dev/null
+++ b/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpSessionManager.java
@@ -0,0 +1,296 @@
+/*
+ * Copyright 2014 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.Component;
+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.routingapi.BgpService;
+import org.onosproject.routingapi.RouteListener;
+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.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static java.util.concurrent.Executors.newCachedThreadPool;
+import static org.onlab.util.Tools.namedThreads;
+
+/**
+ * BGP Session Manager class.
+ */
+@Component(immediate = true)
+@Service
+public class BgpSessionManager implements BgpInfoService, BgpService {
+    private static final Logger log =
+            LoggerFactory.getLogger(BgpSessionManager.class);
+
+    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 RouteListener routeListener;
+
+    /**
+     * 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 route listener.
+     *
+     * @return the route listener to use
+     */
+    RouteListener getRouteListener() {
+        return routeListener;
+    }
+
+    /**
+     * Gets the BGP sessions.
+     *
+     * @return the BGP sessions
+     */
+    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
+     */
+    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
+     */
+    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.version() == Ip4Address.VERSION) {
+            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.version() == Ip4Address.VERSION) {
+            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.version() == Ip4Address.VERSION) {
+            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;
+    }
+
+    @Override
+    public void start(RouteListener routeListener, int listenPortNumber) {
+        log.debug("BGP Session Manager start.");
+        isShutdown = false;
+
+        this.routeListener = checkNotNull(routeListener);
+
+        ChannelFactory channelFactory = new NioServerSocketChannelFactory(
+                newCachedThreadPool(namedThreads("onos-bgp-sm-boss-%d")),
+                newCachedThreadPool(namedThreads("onos-bgp-sm-worker-%d")));
+        ChannelPipelineFactory pipelineFactory = new ChannelPipelineFactory() {
+            @Override
+            public ChannelPipeline getPipeline() throws Exception {
+                // 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(listenPortNumber);
+
+        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);
+        }
+    }
+
+    @Override
+    public void stop() {
+        isShutdown = true;
+        allChannels.close().awaitUninterruptibly();
+        serverBootstrap.releaseExternalResources();
+    }
+}
diff --git a/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpUpdate.java b/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpUpdate.java
new file mode 100644
index 0000000..e9abd9c
--- /dev/null
+++ b/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpUpdate.java
@@ -0,0 +1,1695 @@
+/*
+ * Copyright 2014 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.commons.lang3.tuple.Pair;
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.jboss.netty.buffer.ChannelBuffers;
+import org.jboss.netty.channel.ChannelHandlerContext;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip4Prefix;
+import org.onlab.packet.Ip6Address;
+import org.onlab.packet.Ip6Prefix;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * A class for handling BGP UPDATE messages.
+ */
+final class BgpUpdate {
+    private static final Logger log = LoggerFactory.getLogger(BgpUpdate.class);
+
+    /**
+     * Default constructor.
+     * <p>
+     * The constructor is private to prevent creating an instance of
+     * this utility class.
+     */
+    private BgpUpdate() {
+    }
+
+    /**
+     * Processes BGP UPDATE message.
+     *
+     * @param bgpSession the BGP Session to use
+     * @param ctx the Channel Handler Context
+     * @param message the message to process
+     */
+    static void processBgpUpdate(BgpSession bgpSession,
+                                 ChannelHandlerContext ctx,
+                                 ChannelBuffer message) {
+        DecodedBgpRoutes decodedBgpRoutes = new DecodedBgpRoutes();
+
+        int minLength =
+            BgpConstants.BGP_UPDATE_MIN_LENGTH - BgpConstants.BGP_HEADER_LENGTH;
+        if (message.readableBytes() < minLength) {
+            log.debug("BGP RX UPDATE Error from {}: " +
+                      "Message length {} too short. Must be at least {}",
+                      bgpSession.remoteInfo().address(),
+                      message.readableBytes(), minLength);
+            //
+            // ERROR: Bad Message Length
+            //
+            // Send NOTIFICATION and close the connection
+            ChannelBuffer txMessage =
+                BgpNotification.prepareBgpNotificationBadMessageLength(
+                message.readableBytes() + BgpConstants.BGP_HEADER_LENGTH);
+            ctx.getChannel().write(txMessage);
+            bgpSession.closeSession(ctx);
+            return;
+        }
+
+        log.debug("BGP RX UPDATE message from {}",
+                  bgpSession.remoteInfo().address());
+
+        //
+        // Parse the UPDATE message
+        //
+
+        //
+        // Parse the Withdrawn Routes
+        //
+        int withdrawnRoutesLength = message.readUnsignedShort();
+        if (withdrawnRoutesLength > message.readableBytes()) {
+            // ERROR: Malformed Attribute List
+            actionsBgpUpdateMalformedAttributeList(bgpSession, ctx);
+            return;
+        }
+        Collection<Ip4Prefix> withdrawnPrefixes = null;
+        try {
+            withdrawnPrefixes = parsePackedIp4Prefixes(withdrawnRoutesLength,
+                                                       message);
+        } catch (BgpMessage.BgpParseException e) {
+            // ERROR: Invalid Network Field
+            log.debug("Exception parsing Withdrawn Prefixes from BGP peer {}: ",
+                      bgpSession.remoteInfo().bgpId(), e);
+            actionsBgpUpdateInvalidNetworkField(bgpSession, ctx);
+            return;
+        }
+        for (Ip4Prefix prefix : withdrawnPrefixes) {
+            log.debug("BGP RX UPDATE message WITHDRAWN from {}: {}",
+                      bgpSession.remoteInfo().address(), prefix);
+            BgpRouteEntry bgpRouteEntry = bgpSession.findBgpRoute(prefix);
+            if (bgpRouteEntry != null) {
+                decodedBgpRoutes.deletedUnicastRoutes4.put(prefix,
+                                                           bgpRouteEntry);
+            }
+        }
+
+        //
+        // Parse the Path Attributes
+        //
+        try {
+            parsePathAttributes(bgpSession, ctx, message, decodedBgpRoutes);
+        } catch (BgpMessage.BgpParseException e) {
+            log.debug("Exception parsing Path Attributes from BGP peer {}: ",
+                      bgpSession.remoteInfo().bgpId(), e);
+            // NOTE: The session was already closed, so nothing else to do
+            return;
+        }
+
+        //
+        // Update the BGP RIB-IN
+        //
+        for (Ip4Prefix ip4Prefix :
+                 decodedBgpRoutes.deletedUnicastRoutes4.keySet()) {
+            bgpSession.removeBgpRoute(ip4Prefix);
+        }
+        //
+        for (BgpRouteEntry bgpRouteEntry :
+                 decodedBgpRoutes.addedUnicastRoutes4.values()) {
+            bgpSession.addBgpRoute(bgpRouteEntry);
+        }
+        //
+        for (Ip6Prefix ip6Prefix :
+                 decodedBgpRoutes.deletedUnicastRoutes6.keySet()) {
+            bgpSession.removeBgpRoute(ip6Prefix);
+        }
+        //
+        for (BgpRouteEntry bgpRouteEntry :
+                 decodedBgpRoutes.addedUnicastRoutes6.values()) {
+            bgpSession.addBgpRoute(bgpRouteEntry);
+        }
+
+        //
+        // Push the updates to the BGP Merged RIB
+        //
+        BgpRouteSelector bgpRouteSelector =
+            bgpSession.getBgpSessionManager().getBgpRouteSelector();
+        bgpRouteSelector.routeUpdates(bgpSession,
+                                decodedBgpRoutes.addedUnicastRoutes4.values(),
+                                decodedBgpRoutes.deletedUnicastRoutes4.values());
+        bgpRouteSelector.routeUpdates(bgpSession,
+                                decodedBgpRoutes.addedUnicastRoutes6.values(),
+                                decodedBgpRoutes.deletedUnicastRoutes6.values());
+
+        // Start the Session Timeout timer
+        bgpSession.restartSessionTimeoutTimer(ctx);
+    }
+
+    /**
+     * Parse BGP Path Attributes from the BGP UPDATE message.
+     *
+     * @param bgpSession the BGP Session to use
+     * @param ctx the Channel Handler Context
+     * @param message the message to parse
+     * @param decodedBgpRoutes the container to store the decoded BGP Route
+     * Entries. It might already contain some route entries such as withdrawn
+     * IPv4 prefixes
+     * @throws BgpMessage.BgpParseException
+     */
+    // CHECKSTYLE IGNORE MethodLength FOR NEXT 300 LINES
+    private static void parsePathAttributes(
+                                        BgpSession bgpSession,
+                                        ChannelHandlerContext ctx,
+                                        ChannelBuffer message,
+                                        DecodedBgpRoutes decodedBgpRoutes)
+        throws BgpMessage.BgpParseException {
+
+        //
+        // Parsed values
+        //
+        Short origin = -1;                      // Mandatory
+        BgpRouteEntry.AsPath asPath = null;     // Mandatory
+        // Legacy NLRI (RFC 4271). Mandatory NEXT_HOP if legacy NLRI is used
+        MpNlri legacyNlri = new MpNlri(
+                BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV4,
+                                       BgpConstants.Open.Capabilities.MultiprotocolExtensions.SAFI_UNICAST);
+        long multiExitDisc =                    // Optional
+            BgpConstants.Update.MultiExitDisc.LOWEST_MULTI_EXIT_DISC;
+        Long localPref = null;                  // Mandatory
+        Long aggregatorAsNumber = null;         // Optional: unused
+        Ip4Address aggregatorIpAddress = null;  // Optional: unused
+        Collection<MpNlri> mpNlriReachList = new ArrayList<>();   // Optional
+        Collection<MpNlri> mpNlriUnreachList = new ArrayList<>(); // Optional
+
+        //
+        // Get and verify the Path Attributes Length
+        //
+        int pathAttributeLength = message.readUnsignedShort();
+        if (pathAttributeLength > message.readableBytes()) {
+            // ERROR: Malformed Attribute List
+            actionsBgpUpdateMalformedAttributeList(bgpSession, ctx);
+            String errorMsg = "Malformed Attribute List";
+            throw new BgpMessage.BgpParseException(errorMsg);
+        }
+        if (pathAttributeLength == 0) {
+            return;
+        }
+
+        //
+        // Parse the Path Attributes
+        //
+        int pathAttributeEnd = message.readerIndex() + pathAttributeLength;
+        while (message.readerIndex() < pathAttributeEnd) {
+            int attrFlags = message.readUnsignedByte();
+            if (message.readerIndex() >= pathAttributeEnd) {
+                // ERROR: Malformed Attribute List
+                actionsBgpUpdateMalformedAttributeList(bgpSession, ctx);
+                String errorMsg = "Malformed Attribute List";
+                throw new BgpMessage.BgpParseException(errorMsg);
+            }
+            int attrTypeCode = message.readUnsignedByte();
+
+            // The Attribute Flags
+            boolean optionalBit =       ((0x80 & attrFlags) != 0);
+            boolean transitiveBit =     ((0x40 & attrFlags) != 0);
+            boolean partialBit =        ((0x20 & attrFlags) != 0);
+            boolean extendedLengthBit = ((0x10 & attrFlags) != 0);
+
+            // The Attribute Length
+            int attrLen = 0;
+            int attrLenOctets = 1;
+            if (extendedLengthBit) {
+                attrLenOctets = 2;
+            }
+            if (message.readerIndex() + attrLenOctets > pathAttributeEnd) {
+                // ERROR: Malformed Attribute List
+                actionsBgpUpdateMalformedAttributeList(bgpSession, ctx);
+                String errorMsg = "Malformed Attribute List";
+                throw new BgpMessage.BgpParseException(errorMsg);
+            }
+            if (extendedLengthBit) {
+                attrLen = message.readUnsignedShort();
+            } else {
+                attrLen = message.readUnsignedByte();
+            }
+            if (message.readerIndex() + attrLen > pathAttributeEnd) {
+                // ERROR: Malformed Attribute List
+                actionsBgpUpdateMalformedAttributeList(bgpSession, ctx);
+                String errorMsg = "Malformed Attribute List";
+                throw new BgpMessage.BgpParseException(errorMsg);
+            }
+
+            // Verify the Attribute Flags
+            verifyBgpUpdateAttributeFlags(bgpSession, ctx, attrTypeCode,
+                                          attrLen, attrFlags, message);
+
+            //
+            // Extract the Attribute Value based on the Attribute Type Code
+            //
+            switch (attrTypeCode) {
+
+            case BgpConstants.Update.Origin.TYPE:
+                // Attribute Type Code ORIGIN
+                origin = parseAttributeTypeOrigin(bgpSession, ctx,
+                                                  attrTypeCode, attrLen,
+                                                  attrFlags, message);
+                break;
+
+            case BgpConstants.Update.AsPath.TYPE:
+                // Attribute Type Code AS_PATH
+                asPath = parseAttributeTypeAsPath(bgpSession, ctx,
+                                                  attrTypeCode, attrLen,
+                                                  attrFlags, message);
+                break;
+
+            case BgpConstants.Update.NextHop.TYPE:
+                // Attribute Type Code NEXT_HOP
+                legacyNlri.nextHop4 =
+                    parseAttributeTypeNextHop(bgpSession, ctx,
+                                              attrTypeCode, attrLen,
+                                              attrFlags, message);
+                break;
+
+            case BgpConstants.Update.MultiExitDisc.TYPE:
+                // Attribute Type Code MULTI_EXIT_DISC
+                multiExitDisc =
+                    parseAttributeTypeMultiExitDisc(bgpSession, ctx,
+                                                    attrTypeCode, attrLen,
+                                                    attrFlags, message);
+                break;
+
+            case BgpConstants.Update.LocalPref.TYPE:
+                // Attribute Type Code LOCAL_PREF
+                localPref =
+                    parseAttributeTypeLocalPref(bgpSession, ctx,
+                                                attrTypeCode, attrLen,
+                                                attrFlags, message);
+                break;
+
+            case BgpConstants.Update.AtomicAggregate.TYPE:
+                // Attribute Type Code ATOMIC_AGGREGATE
+                parseAttributeTypeAtomicAggregate(bgpSession, ctx,
+                                                  attrTypeCode, attrLen,
+                                                  attrFlags, message);
+                // Nothing to do: this attribute is primarily informational
+                break;
+
+            case BgpConstants.Update.Aggregator.TYPE:
+                // Attribute Type Code AGGREGATOR
+                Pair<Long, Ip4Address> aggregator =
+                    parseAttributeTypeAggregator(bgpSession, ctx,
+                                                 attrTypeCode, attrLen,
+                                                 attrFlags, message);
+                aggregatorAsNumber = aggregator.getLeft();
+                aggregatorIpAddress = aggregator.getRight();
+                break;
+
+            case BgpConstants.Update.MpReachNlri.TYPE:
+                // Attribute Type Code MP_REACH_NLRI
+                MpNlri mpNlriReach =
+                    parseAttributeTypeMpReachNlri(bgpSession, ctx,
+                                                  attrTypeCode,
+                                                  attrLen,
+                                                  attrFlags, message);
+                if (mpNlriReach != null) {
+                    mpNlriReachList.add(mpNlriReach);
+                }
+                break;
+
+            case BgpConstants.Update.MpUnreachNlri.TYPE:
+                // Attribute Type Code MP_UNREACH_NLRI
+                MpNlri mpNlriUnreach =
+                    parseAttributeTypeMpUnreachNlri(bgpSession, ctx,
+                                                    attrTypeCode, attrLen,
+                                                    attrFlags, message);
+                if (mpNlriUnreach != null) {
+                    mpNlriUnreachList.add(mpNlriUnreach);
+                }
+                break;
+
+            default:
+                // NOTE: Parse any new Attribute Types if needed
+                if (!optionalBit) {
+                    // ERROR: Unrecognized Well-known Attribute
+                    actionsBgpUpdateUnrecognizedWellKnownAttribute(
+                        bgpSession, ctx, attrTypeCode, attrLen, attrFlags,
+                        message);
+                    String errorMsg = "Unrecognized Well-known Attribute: " +
+                        attrTypeCode;
+                    throw new BgpMessage.BgpParseException(errorMsg);
+                }
+
+                // Skip the data from the unrecognized attribute
+                log.debug("BGP RX UPDATE message from {}: " +
+                          "Unrecognized Attribute Type {}",
+                          bgpSession.remoteInfo().address(), attrTypeCode);
+                message.skipBytes(attrLen);
+                break;
+            }
+        }
+
+        //
+        // Parse the NLRI (Network Layer Reachability Information)
+        //
+        int nlriLength = message.readableBytes();
+        try {
+            Collection<Ip4Prefix> addedPrefixes4 =
+                parsePackedIp4Prefixes(nlriLength, message);
+            // Store it inside the legacy NLRI wrapper
+            legacyNlri.nlri4 = addedPrefixes4;
+        } catch (BgpMessage.BgpParseException e) {
+            // ERROR: Invalid Network Field
+            log.debug("Exception parsing NLRI from BGP peer {}: ",
+                      bgpSession.remoteInfo().bgpId(), e);
+            actionsBgpUpdateInvalidNetworkField(bgpSession, ctx);
+            // Rethrow the exception
+            throw e;
+        }
+
+        // Verify the Well-known Attributes
+        verifyBgpUpdateWellKnownAttributes(bgpSession, ctx, origin, asPath,
+                                           localPref, legacyNlri,
+                                           mpNlriReachList);
+
+        //
+        // Generate the deleted routes
+        //
+        for (MpNlri mpNlri : mpNlriUnreachList) {
+            BgpRouteEntry bgpRouteEntry;
+
+            // The deleted IPv4 routes
+            for (Ip4Prefix prefix : mpNlri.nlri4) {
+                bgpRouteEntry = bgpSession.findBgpRoute(prefix);
+                if (bgpRouteEntry != null) {
+                    decodedBgpRoutes.deletedUnicastRoutes4.put(prefix,
+                                                               bgpRouteEntry);
+                }
+            }
+
+            // The deleted IPv6 routes
+            for (Ip6Prefix prefix : mpNlri.nlri6) {
+                bgpRouteEntry = bgpSession.findBgpRoute(prefix);
+                if (bgpRouteEntry != null) {
+                    decodedBgpRoutes.deletedUnicastRoutes6.put(prefix,
+                                                               bgpRouteEntry);
+                }
+            }
+        }
+
+        //
+        // Generate the added routes
+        //
+        mpNlriReachList.add(legacyNlri);
+        for (MpNlri mpNlri : mpNlriReachList) {
+            BgpRouteEntry bgpRouteEntry;
+
+            // The added IPv4 routes
+            for (Ip4Prefix prefix : mpNlri.nlri4) {
+                bgpRouteEntry =
+                    new BgpRouteEntry(bgpSession, prefix, mpNlri.nextHop4,
+                                      origin.byteValue(), asPath, localPref);
+                bgpRouteEntry.setMultiExitDisc(multiExitDisc);
+                if (bgpRouteEntry.hasAsPathLoop(bgpSession.localInfo().asNumber())) {
+                    log.debug("BGP RX UPDATE message IGNORED from {}: {} " +
+                              "nextHop {}: contains AS Path loop",
+                              bgpSession.remoteInfo().address(), prefix,
+                              mpNlri.nextHop4);
+                    continue;
+                } else {
+                    log.debug("BGP RX UPDATE message ADDED from {}: {} nextHop {}",
+                              bgpSession.remoteInfo().address(), prefix,
+                              mpNlri.nextHop4);
+                }
+                // Remove from the collection of deleted routes
+                decodedBgpRoutes.deletedUnicastRoutes4.remove(prefix);
+                decodedBgpRoutes.addedUnicastRoutes4.put(prefix,
+                                                         bgpRouteEntry);
+            }
+
+            // The added IPv6 routes
+            for (Ip6Prefix prefix : mpNlri.nlri6) {
+                bgpRouteEntry =
+                    new BgpRouteEntry(bgpSession, prefix, mpNlri.nextHop6,
+                                      origin.byteValue(), asPath, localPref);
+                bgpRouteEntry.setMultiExitDisc(multiExitDisc);
+                if (bgpRouteEntry.hasAsPathLoop(bgpSession.localInfo().asNumber())) {
+                    log.debug("BGP RX UPDATE message IGNORED from {}: {} " +
+                              "nextHop {}: contains AS Path loop",
+                              bgpSession.remoteInfo().address(), prefix,
+                              mpNlri.nextHop6);
+                    continue;
+                } else {
+                    log.debug("BGP RX UPDATE message ADDED from {}: {} nextHop {}",
+                              bgpSession.remoteInfo().address(), prefix,
+                              mpNlri.nextHop6);
+                }
+                // Remove from the collection of deleted routes
+                decodedBgpRoutes.deletedUnicastRoutes6.remove(prefix);
+                decodedBgpRoutes.addedUnicastRoutes6.put(prefix,
+                                                         bgpRouteEntry);
+            }
+        }
+    }
+
+    /**
+     * Verifies BGP UPDATE Well-known Attributes.
+     *
+     * @param bgpSession the BGP Session to use
+     * @param ctx the Channel Handler Context
+     * @param origin the ORIGIN well-known mandatory attribute
+     * @param asPath the AS_PATH well-known mandatory attribute
+     * @param localPref the LOCAL_PREF required attribute
+     * @param legacyNlri the legacy NLRI. Encapsulates the NEXT_HOP well-known
+     * mandatory attribute (mandatory if legacy NLRI is used).
+     * @param mpNlriReachList the Multiprotocol NLRI attributes
+     * @throws BgpMessage.BgpParseException
+     */
+    private static void verifyBgpUpdateWellKnownAttributes(
+                                BgpSession bgpSession,
+                                ChannelHandlerContext ctx,
+                                Short origin,
+                                BgpRouteEntry.AsPath asPath,
+                                Long localPref,
+                                MpNlri legacyNlri,
+                                Collection<MpNlri> mpNlriReachList)
+        throws BgpMessage.BgpParseException {
+        boolean hasNlri = false;
+        boolean hasLegacyNlri = false;
+
+        //
+        // Convenience flags that are used to check for missing attributes.
+        //
+        // NOTE: The hasLegacyNlri flag is always set to true if the
+        // Multiprotocol Extensions are not enabled, even if the UPDATE
+        // message doesn't contain the legacy NLRI (per RFC 4271).
+        //
+        if (!bgpSession.mpExtensions()) {
+            hasNlri = true;
+            hasLegacyNlri = true;
+        } else {
+            if (!legacyNlri.nlri4.isEmpty()) {
+                hasNlri = true;
+                hasLegacyNlri = true;
+            }
+            if (!mpNlriReachList.isEmpty()) {
+                hasNlri = true;
+            }
+        }
+
+        //
+        // Check for Missing Well-known Attributes
+        //
+        if (hasNlri && ((origin == null) || (origin == -1))) {
+            // Missing Attribute Type Code ORIGIN
+            int type = BgpConstants.Update.Origin.TYPE;
+            actionsBgpUpdateMissingWellKnownAttribute(bgpSession, ctx, type);
+            String errorMsg = "Missing Well-known Attribute: ORIGIN";
+            throw new BgpMessage.BgpParseException(errorMsg);
+        }
+        if (hasNlri && (asPath == null)) {
+            // Missing Attribute Type Code AS_PATH
+            int type = BgpConstants.Update.AsPath.TYPE;
+            actionsBgpUpdateMissingWellKnownAttribute(bgpSession, ctx, type);
+            String errorMsg = "Missing Well-known Attribute: AS_PATH";
+            throw new BgpMessage.BgpParseException(errorMsg);
+        }
+        if (hasNlri && (localPref == null)) {
+            // Missing Attribute Type Code LOCAL_PREF
+            // NOTE: Required for iBGP
+            int type = BgpConstants.Update.LocalPref.TYPE;
+            actionsBgpUpdateMissingWellKnownAttribute(bgpSession, ctx, type);
+            String errorMsg = "Missing Well-known Attribute: LOCAL_PREF";
+            throw new BgpMessage.BgpParseException(errorMsg);
+        }
+        if (hasLegacyNlri && (legacyNlri.nextHop4 == null)) {
+            // Missing Attribute Type Code NEXT_HOP
+            int type = BgpConstants.Update.NextHop.TYPE;
+            actionsBgpUpdateMissingWellKnownAttribute(bgpSession, ctx, type);
+            String errorMsg = "Missing Well-known Attribute: NEXT_HOP";
+            throw new BgpMessage.BgpParseException(errorMsg);
+        }
+    }
+
+    /**
+     * Verifies the BGP UPDATE Attribute Flags.
+     *
+     * @param bgpSession the BGP Session to use
+     * @param ctx the Channel Handler Context
+     * @param attrTypeCode the attribute type code
+     * @param attrLen the attribute length (in octets)
+     * @param attrFlags the attribute flags
+     * @param message the message to parse
+     * @throws BgpMessage.BgpParseException
+     */
+    private static void verifyBgpUpdateAttributeFlags(
+                                BgpSession bgpSession,
+                                ChannelHandlerContext ctx,
+                                int attrTypeCode,
+                                int attrLen,
+                                int attrFlags,
+                                ChannelBuffer message)
+        throws BgpMessage.BgpParseException {
+
+        //
+        // Assign the Attribute Type Name and the Well-known flag
+        //
+        String typeName = "UNKNOWN";
+        boolean isWellKnown = false;
+        switch (attrTypeCode) {
+        case BgpConstants.Update.Origin.TYPE:
+            isWellKnown = true;
+            typeName = "ORIGIN";
+            break;
+        case BgpConstants.Update.AsPath.TYPE:
+            isWellKnown = true;
+            typeName = "AS_PATH";
+            break;
+        case BgpConstants.Update.NextHop.TYPE:
+            isWellKnown = true;
+            typeName = "NEXT_HOP";
+            break;
+        case BgpConstants.Update.MultiExitDisc.TYPE:
+            isWellKnown = false;
+            typeName = "MULTI_EXIT_DISC";
+            break;
+        case BgpConstants.Update.LocalPref.TYPE:
+            isWellKnown = true;
+            typeName = "LOCAL_PREF";
+            break;
+        case BgpConstants.Update.AtomicAggregate.TYPE:
+            isWellKnown = true;
+            typeName = "ATOMIC_AGGREGATE";
+            break;
+        case BgpConstants.Update.Aggregator.TYPE:
+            isWellKnown = false;
+            typeName = "AGGREGATOR";
+            break;
+        case BgpConstants.Update.MpReachNlri.TYPE:
+            isWellKnown = false;
+            typeName = "MP_REACH_NLRI";
+            break;
+        case BgpConstants.Update.MpUnreachNlri.TYPE:
+            isWellKnown = false;
+            typeName = "MP_UNREACH_NLRI";
+            break;
+        default:
+            isWellKnown = false;
+            typeName = "UNKNOWN(" + attrTypeCode + ")";
+            break;
+        }
+
+        //
+        // Verify the Attribute Flags
+        //
+        boolean optionalBit =       ((0x80 & attrFlags) != 0);
+        boolean transitiveBit =     ((0x40 & attrFlags) != 0);
+        boolean partialBit =        ((0x20 & attrFlags) != 0);
+        if ((isWellKnown && optionalBit) ||
+            (isWellKnown && (!transitiveBit)) ||
+            (isWellKnown && partialBit) ||
+            (optionalBit && (!transitiveBit) && partialBit)) {
+            //
+            // ERROR: The Optional bit cannot be set for Well-known attributes
+            // ERROR: The Transtive bit MUST be 1 for well-known attributes
+            // ERROR: The Partial bit MUST be 0 for well-known attributes
+            // ERROR: The Partial bit MUST be 0 for optional non-transitive
+            //        attributes
+            //
+            actionsBgpUpdateAttributeFlagsError(
+                bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message);
+            String errorMsg = "Attribute Flags Error for " + typeName + ": " +
+                attrFlags;
+            throw new BgpMessage.BgpParseException(errorMsg);
+        }
+    }
+
+    /**
+     * Parses BGP UPDATE Attribute Type ORIGIN.
+     *
+     * @param bgpSession the BGP Session to use
+     * @param ctx the Channel Handler Context
+     * @param attrTypeCode the attribute type code
+     * @param attrLen the attribute length (in octets)
+     * @param attrFlags the attribute flags
+     * @param message the message to parse
+     * @return the parsed ORIGIN value
+     * @throws BgpMessage.BgpParseException
+     */
+    private static short parseAttributeTypeOrigin(
+                                BgpSession bgpSession,
+                                ChannelHandlerContext ctx,
+                                int attrTypeCode,
+                                int attrLen,
+                                int attrFlags,
+                                ChannelBuffer message)
+        throws BgpMessage.BgpParseException {
+
+        // Check the Attribute Length
+        if (attrLen != BgpConstants.Update.Origin.LENGTH) {
+            // ERROR: Attribute Length Error
+            actionsBgpUpdateAttributeLengthError(
+                bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message);
+            String errorMsg = "Attribute Length Error";
+            throw new BgpMessage.BgpParseException(errorMsg);
+        }
+
+        message.markReaderIndex();
+        short origin = message.readUnsignedByte();
+        switch (origin) {
+        case BgpConstants.Update.Origin.IGP:
+            // FALLTHROUGH
+        case BgpConstants.Update.Origin.EGP:
+            // FALLTHROUGH
+        case BgpConstants.Update.Origin.INCOMPLETE:
+            break;
+        default:
+            // ERROR: Invalid ORIGIN Attribute
+            message.resetReaderIndex();
+            actionsBgpUpdateInvalidOriginAttribute(
+                bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message,
+                origin);
+            String errorMsg = "Invalid ORIGIN Attribute: " + origin;
+            throw new BgpMessage.BgpParseException(errorMsg);
+        }
+
+        return origin;
+    }
+
+    /**
+     * Parses BGP UPDATE Attribute AS Path.
+     *
+     * @param bgpSession the BGP Session to use
+     * @param ctx the Channel Handler Context
+     * @param attrTypeCode the attribute type code
+     * @param attrLen the attribute length (in octets)
+     * @param attrFlags the attribute flags
+     * @param message the message to parse
+     * @return the parsed AS Path
+     * @throws BgpMessage.BgpParseException
+     */
+    private static BgpRouteEntry.AsPath parseAttributeTypeAsPath(
+                                                BgpSession bgpSession,
+                                                ChannelHandlerContext ctx,
+                                                int attrTypeCode,
+                                                int attrLen,
+                                                int attrFlags,
+                                                ChannelBuffer message)
+        throws BgpMessage.BgpParseException {
+        ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>();
+
+        //
+        // Parse the message
+        //
+        while (attrLen > 0) {
+            if (attrLen < 2) {
+                // ERROR: Malformed AS_PATH
+                actionsBgpUpdateMalformedAsPath(bgpSession, ctx);
+                String errorMsg = "Malformed AS Path";
+                throw new BgpMessage.BgpParseException(errorMsg);
+            }
+            // Get the Path Segment Type and Length (in number of ASes)
+            short pathSegmentType = message.readUnsignedByte();
+            short pathSegmentLength = message.readUnsignedByte();
+            attrLen -= 2;
+
+            // Verify the Path Segment Type
+            switch (pathSegmentType) {
+            case BgpConstants.Update.AsPath.AS_SET:
+                // FALLTHROUGH
+            case BgpConstants.Update.AsPath.AS_SEQUENCE:
+                // FALLTHROUGH
+            case BgpConstants.Update.AsPath.AS_CONFED_SEQUENCE:
+                // FALLTHROUGH
+            case BgpConstants.Update.AsPath.AS_CONFED_SET:
+                break;
+            default:
+                // ERROR: Invalid Path Segment Type
+                //
+                // NOTE: The BGP Spec (RFC 4271) doesn't contain Error Subcode
+                // for "Invalid Path Segment Type", hence we return
+                // the error as "Malformed AS_PATH".
+                //
+                actionsBgpUpdateMalformedAsPath(bgpSession, ctx);
+                String errorMsg =
+                    "Invalid AS Path Segment Type: " + pathSegmentType;
+                throw new BgpMessage.BgpParseException(errorMsg);
+            }
+
+            // 4-octet AS number handling.
+            int asPathLen;
+            if (bgpSession.isAs4OctetCapable()) {
+                asPathLen = BgpConstants.Update.AsPath.AS_4OCTET_LENGTH;
+            } else {
+                asPathLen = BgpConstants.Update.AsPath.AS_LENGTH;
+            }
+
+            // Parse the AS numbers
+            if (asPathLen * pathSegmentLength > attrLen) {
+                // ERROR: Malformed AS_PATH
+                actionsBgpUpdateMalformedAsPath(bgpSession, ctx);
+                String errorMsg = "Malformed AS Path";
+                throw new BgpMessage.BgpParseException(errorMsg);
+            }
+            attrLen -= (asPathLen * pathSegmentLength);
+            ArrayList<Long> segmentAsNumbers = new ArrayList<>();
+            while (pathSegmentLength-- > 0) {
+                long asNumber;
+                if (asPathLen == BgpConstants.Update.AsPath.AS_4OCTET_LENGTH) {
+                    asNumber = message.readUnsignedInt();
+                } else {
+                    asNumber = message.readUnsignedShort();
+                }
+                segmentAsNumbers.add(asNumber);
+            }
+
+            BgpRouteEntry.PathSegment pathSegment =
+                new BgpRouteEntry.PathSegment((byte) pathSegmentType,
+                                              segmentAsNumbers);
+            pathSegments.add(pathSegment);
+        }
+
+        return new BgpRouteEntry.AsPath(pathSegments);
+    }
+
+    /**
+     * Parses BGP UPDATE Attribute Type NEXT_HOP.
+     *
+     * @param bgpSession the BGP Session to use
+     * @param ctx the Channel Handler Context
+     * @param attrTypeCode the attribute type code
+     * @param attrLen the attribute length (in octets)
+     * @param attrFlags the attribute flags
+     * @param message the message to parse
+     * @return the parsed NEXT_HOP value
+     * @throws BgpMessage.BgpParseException
+     */
+    private static Ip4Address parseAttributeTypeNextHop(
+                                        BgpSession bgpSession,
+                                        ChannelHandlerContext ctx,
+                                        int attrTypeCode,
+                                        int attrLen,
+                                        int attrFlags,
+                                        ChannelBuffer message)
+        throws BgpMessage.BgpParseException {
+
+        // Check the Attribute Length
+        if (attrLen != BgpConstants.Update.NextHop.LENGTH) {
+            // ERROR: Attribute Length Error
+            actionsBgpUpdateAttributeLengthError(
+                bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message);
+            String errorMsg = "Attribute Length Error";
+            throw new BgpMessage.BgpParseException(errorMsg);
+        }
+
+        message.markReaderIndex();
+        Ip4Address nextHopAddress =
+            Ip4Address.valueOf((int) message.readUnsignedInt());
+        //
+        // Check whether the NEXT_HOP IP address is semantically correct.
+        // As per RFC 4271, Section 6.3:
+        //
+        //  a) It MUST NOT be the IP address of the receiving speaker
+        //  b) In the case of an EBGP ....
+        //
+        // Here we check only (a), because (b) doesn't apply for us: all our
+        // peers are iBGP.
+        //
+        if (nextHopAddress.equals(bgpSession.localInfo().ip4Address())) {
+            // ERROR: Invalid NEXT_HOP Attribute
+            message.resetReaderIndex();
+            actionsBgpUpdateInvalidNextHopAttribute(
+                bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message,
+                nextHopAddress);
+            String errorMsg = "Invalid NEXT_HOP Attribute: " + nextHopAddress;
+            throw new BgpMessage.BgpParseException(errorMsg);
+        }
+
+        return nextHopAddress;
+    }
+
+    /**
+     * Parses BGP UPDATE Attribute Type MULTI_EXIT_DISC.
+     *
+     * @param bgpSession the BGP Session to use
+     * @param ctx the Channel Handler Context
+     * @param attrTypeCode the attribute type code
+     * @param attrLen the attribute length (in octets)
+     * @param attrFlags the attribute flags
+     * @param message the message to parse
+     * @return the parsed MULTI_EXIT_DISC value
+     * @throws BgpMessage.BgpParseException
+     */
+    private static long parseAttributeTypeMultiExitDisc(
+                                BgpSession bgpSession,
+                                ChannelHandlerContext ctx,
+                                int attrTypeCode,
+                                int attrLen,
+                                int attrFlags,
+                                ChannelBuffer message)
+        throws BgpMessage.BgpParseException {
+
+        // Check the Attribute Length
+        if (attrLen != BgpConstants.Update.MultiExitDisc.LENGTH) {
+            // ERROR: Attribute Length Error
+            actionsBgpUpdateAttributeLengthError(
+                bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message);
+            String errorMsg = "Attribute Length Error";
+            throw new BgpMessage.BgpParseException(errorMsg);
+        }
+
+        long multiExitDisc = message.readUnsignedInt();
+        return multiExitDisc;
+    }
+
+    /**
+     * Parses BGP UPDATE Attribute Type LOCAL_PREF.
+     *
+     * @param bgpSession the BGP Session to use
+     * @param ctx the Channel Handler Context
+     * @param attrTypeCode the attribute type code
+     * @param attrLen the attribute length (in octets)
+     * @param attrFlags the attribute flags
+     * @param message the message to parse
+     * @return the parsed LOCAL_PREF value
+     * @throws BgpMessage.BgpParseException
+     */
+    private static long parseAttributeTypeLocalPref(
+                                BgpSession bgpSession,
+                                ChannelHandlerContext ctx,
+                                int attrTypeCode,
+                                int attrLen,
+                                int attrFlags,
+                                ChannelBuffer message)
+        throws BgpMessage.BgpParseException {
+
+        // Check the Attribute Length
+        if (attrLen != BgpConstants.Update.LocalPref.LENGTH) {
+            // ERROR: Attribute Length Error
+            actionsBgpUpdateAttributeLengthError(
+                bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message);
+            String errorMsg = "Attribute Length Error";
+            throw new BgpMessage.BgpParseException(errorMsg);
+        }
+
+        long localPref = message.readUnsignedInt();
+        return localPref;
+    }
+
+    /**
+     * Parses BGP UPDATE Attribute Type ATOMIC_AGGREGATE.
+     *
+     * @param bgpSession the BGP Session to use
+     * @param ctx the Channel Handler Context
+     * @param attrTypeCode the attribute type code
+     * @param attrLen the attribute length (in octets)
+     * @param attrFlags the attribute flags
+     * @param message the message to parse
+     * @throws BgpMessage.BgpParseException
+     */
+    private static void parseAttributeTypeAtomicAggregate(
+                                BgpSession bgpSession,
+                                ChannelHandlerContext ctx,
+                                int attrTypeCode,
+                                int attrLen,
+                                int attrFlags,
+                                ChannelBuffer message)
+        throws BgpMessage.BgpParseException {
+
+        // Check the Attribute Length
+        if (attrLen != BgpConstants.Update.AtomicAggregate.LENGTH) {
+            // ERROR: Attribute Length Error
+            actionsBgpUpdateAttributeLengthError(
+                bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message);
+            String errorMsg = "Attribute Length Error";
+            throw new BgpMessage.BgpParseException(errorMsg);
+        }
+
+        // Nothing to do: this attribute is primarily informational
+    }
+
+    /**
+     * Parses BGP UPDATE Attribute Type AGGREGATOR.
+     *
+     * @param bgpSession the BGP Session to use
+     * @param ctx the Channel Handler Context
+     * @param attrTypeCode the attribute type code
+     * @param attrLen the attribute length (in octets)
+     * @param attrFlags the attribute flags
+     * @param message the message to parse
+     * @return the parsed AGGREGATOR value: a tuple of <AS-Number, IP-Address>
+     * @throws BgpMessage.BgpParseException
+     */
+    private static Pair<Long, Ip4Address> parseAttributeTypeAggregator(
+                                                BgpSession bgpSession,
+                                                ChannelHandlerContext ctx,
+                                                int attrTypeCode,
+                                                int attrLen,
+                                                int attrFlags,
+                                                ChannelBuffer message)
+        throws BgpMessage.BgpParseException {
+
+        // Check the Attribute Length
+        if (attrLen != BgpConstants.Update.Aggregator.LENGTH) {
+            // ERROR: Attribute Length Error
+            actionsBgpUpdateAttributeLengthError(
+                bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message);
+            String errorMsg = "Attribute Length Error";
+            throw new BgpMessage.BgpParseException(errorMsg);
+        }
+
+        // The AGGREGATOR AS number
+        long aggregatorAsNumber = message.readUnsignedShort();
+        // The AGGREGATOR IP address
+        Ip4Address aggregatorIpAddress =
+            Ip4Address.valueOf((int) message.readUnsignedInt());
+
+        Pair<Long, Ip4Address> aggregator = Pair.of(aggregatorAsNumber,
+                                                    aggregatorIpAddress);
+        return aggregator;
+    }
+
+    /**
+     * Parses BGP UPDATE Attribute Type MP_REACH_NLRI.
+     *
+     * @param bgpSession the BGP Session to use
+     * @param ctx the Channel Handler Context
+     * @param attrTypeCode the attribute type code
+     * @param attrLen the attribute length (in octets)
+     * @param attrFlags the attribute flags
+     * @param message the message to parse
+     * @return the parsed MP_REACH_NLRI information if recognized, otherwise
+     * null
+     * @throws BgpMessage.BgpParseException
+     */
+    private static MpNlri parseAttributeTypeMpReachNlri(
+                                                BgpSession bgpSession,
+                                                ChannelHandlerContext ctx,
+                                                int attrTypeCode,
+                                                int attrLen,
+                                                int attrFlags,
+                                                ChannelBuffer message)
+        throws BgpMessage.BgpParseException {
+        int attributeEnd = message.readerIndex() + attrLen;
+
+        // Check the Attribute Length
+        if (attrLen < BgpConstants.Update.MpReachNlri.MIN_LENGTH) {
+            // ERROR: Attribute Length Error
+            actionsBgpUpdateAttributeLengthError(
+                bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message);
+            String errorMsg = "Attribute Length Error";
+            throw new BgpMessage.BgpParseException(errorMsg);
+        }
+
+        message.markReaderIndex();
+        int afi = message.readUnsignedShort();
+        int safi = message.readUnsignedByte();
+        int nextHopLen = message.readUnsignedByte();
+
+        //
+        // Verify the AFI/SAFI, and skip the attribute if not recognized.
+        // NOTE: Currently, we support only IPv4/IPv6 UNICAST
+        //
+        if (((afi != BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV4) &&
+             (afi != BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV6)) ||
+            (safi != BgpConstants.Open.Capabilities.MultiprotocolExtensions.SAFI_UNICAST)) {
+            // Skip the attribute
+            message.resetReaderIndex();
+            message.skipBytes(attrLen);
+            return null;
+        }
+
+        //
+        // Verify the next-hop length
+        //
+        int expectedNextHopLen = 0;
+        switch (afi) {
+        case BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV4:
+            expectedNextHopLen = Ip4Address.BYTE_LENGTH;
+            break;
+        case BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV6:
+            expectedNextHopLen = Ip6Address.BYTE_LENGTH;
+            break;
+        default:
+            // UNREACHABLE
+            break;
+        }
+        if (nextHopLen != expectedNextHopLen) {
+            // ERROR: Optional Attribute Error
+            message.resetReaderIndex();
+            actionsBgpUpdateOptionalAttributeError(
+                bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message);
+            String errorMsg = "Invalid next-hop network address length. " +
+                "Received " + nextHopLen + " expected " + expectedNextHopLen;
+            throw new BgpMessage.BgpParseException(errorMsg);
+        }
+        // NOTE: We use "+ 1" to take into account the Reserved field (1 octet)
+        if (message.readerIndex() + nextHopLen + 1 >= attributeEnd) {
+            // ERROR: Optional Attribute Error
+            message.resetReaderIndex();
+            actionsBgpUpdateOptionalAttributeError(
+                bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message);
+            String errorMsg = "Malformed next-hop network address";
+            throw new BgpMessage.BgpParseException(errorMsg);
+        }
+
+        //
+        // Get the Next-hop address, skip the Reserved field, and get the NLRI
+        //
+        byte[] nextHopBuffer = new byte[nextHopLen];
+        message.readBytes(nextHopBuffer, 0, nextHopLen);
+        int reserved = message.readUnsignedByte();
+        MpNlri mpNlri = new MpNlri(afi, safi);
+        try {
+            switch (afi) {
+            case BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV4:
+                // The next-hop address
+                mpNlri.nextHop4 = Ip4Address.valueOf(nextHopBuffer);
+                // The NLRI
+                mpNlri.nlri4 = parsePackedIp4Prefixes(
+                                        attributeEnd - message.readerIndex(),
+                                        message);
+                break;
+            case BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV6:
+                // The next-hop address
+                mpNlri.nextHop6 = Ip6Address.valueOf(nextHopBuffer);
+                // The NLRI
+                mpNlri.nlri6 = parsePackedIp6Prefixes(
+                                        attributeEnd - message.readerIndex(),
+                                        message);
+                break;
+            default:
+                // UNREACHABLE
+                break;
+            }
+        } catch (BgpMessage.BgpParseException e) {
+            // ERROR: Optional Attribute Error
+            message.resetReaderIndex();
+            actionsBgpUpdateOptionalAttributeError(
+                bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message);
+            String errorMsg = "Malformed network layer reachability information";
+            throw new BgpMessage.BgpParseException(errorMsg);
+        }
+
+        return mpNlri;
+    }
+
+    /**
+     * Parses BGP UPDATE Attribute Type MP_UNREACH_NLRI.
+     *
+     * @param bgpSession the BGP Session to use
+     * @param ctx the Channel Handler Context
+     * @param attrTypeCode the attribute type code
+     * @param attrLen the attribute length (in octets)
+     * @param attrFlags the attribute flags
+     * @param message the message to parse
+     * @return the parsed MP_UNREACH_NLRI information if recognized, otherwise
+     * null
+     * @throws BgpMessage.BgpParseException
+     */
+    private static MpNlri parseAttributeTypeMpUnreachNlri(
+                                                BgpSession bgpSession,
+                                                ChannelHandlerContext ctx,
+                                                int attrTypeCode,
+                                                int attrLen,
+                                                int attrFlags,
+                                                ChannelBuffer message)
+        throws BgpMessage.BgpParseException {
+        int attributeEnd = message.readerIndex() + attrLen;
+
+        // Check the Attribute Length
+        if (attrLen < BgpConstants.Update.MpUnreachNlri.MIN_LENGTH) {
+            // ERROR: Attribute Length Error
+            actionsBgpUpdateAttributeLengthError(
+                bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message);
+            String errorMsg = "Attribute Length Error";
+            throw new BgpMessage.BgpParseException(errorMsg);
+        }
+
+        message.markReaderIndex();
+        int afi = message.readUnsignedShort();
+        int safi = message.readUnsignedByte();
+
+        //
+        // Verify the AFI/SAFI, and skip the attribute if not recognized.
+        // NOTE: Currently, we support only IPv4/IPv6 UNICAST
+        //
+        if (((afi != BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV4) &&
+             (afi != BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV6)) ||
+            (safi != BgpConstants.Open.Capabilities.MultiprotocolExtensions.SAFI_UNICAST)) {
+            // Skip the attribute
+            message.resetReaderIndex();
+            message.skipBytes(attrLen);
+            return null;
+        }
+
+        //
+        // Get the Withdrawn Routes
+        //
+        MpNlri mpNlri = new MpNlri(afi, safi);
+        try {
+            switch (afi) {
+            case BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV4:
+                // The Withdrawn Routes
+                mpNlri.nlri4 = parsePackedIp4Prefixes(
+                                        attributeEnd - message.readerIndex(),
+                                        message);
+                break;
+            case BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV6:
+                // The Withdrawn Routes
+                mpNlri.nlri6 = parsePackedIp6Prefixes(
+                                        attributeEnd - message.readerIndex(),
+                                        message);
+                break;
+            default:
+                // UNREACHABLE
+                break;
+            }
+        } catch (BgpMessage.BgpParseException e) {
+            // ERROR: Optional Attribute Error
+            message.resetReaderIndex();
+            actionsBgpUpdateOptionalAttributeError(
+                bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message);
+            String errorMsg = "Malformed withdrawn routes";
+            throw new BgpMessage.BgpParseException(errorMsg);
+        }
+
+        return mpNlri;
+    }
+
+    /**
+     * Parses a message that contains encoded IPv4 network prefixes.
+     * <p>
+     * The IPv4 prefixes are encoded in the form:
+     * <Length, Prefix> where Length is the length in bits of the IPv4 prefix,
+     * and Prefix is the IPv4 prefix (padded with trailing bits to the end
+     * of an octet).
+     *
+     * @param totalLength the total length of the data to parse
+     * @param message the message with data to parse
+     * @return a collection of parsed IPv4 network prefixes
+     * @throws BgpMessage.BgpParseException
+     */
+    private static Collection<Ip4Prefix> parsePackedIp4Prefixes(
+                                                int totalLength,
+                                                ChannelBuffer message)
+        throws BgpMessage.BgpParseException {
+        Collection<Ip4Prefix> result = new ArrayList<>();
+
+        if (totalLength == 0) {
+            return result;
+        }
+
+        // Parse the data
+        byte[] buffer = new byte[Ip4Address.BYTE_LENGTH];
+        int dataEnd = message.readerIndex() + totalLength;
+        while (message.readerIndex() < dataEnd) {
+            int prefixBitlen = message.readUnsignedByte();
+            int prefixBytelen = (prefixBitlen + 7) / 8;     // Round-up
+            if (message.readerIndex() + prefixBytelen > dataEnd) {
+                String errorMsg = "Malformed Network Prefixes";
+                throw new BgpMessage.BgpParseException(errorMsg);
+            }
+
+            message.readBytes(buffer, 0, prefixBytelen);
+            Ip4Prefix prefix = Ip4Prefix.valueOf(Ip4Address.valueOf(buffer),
+                                                 prefixBitlen);
+            result.add(prefix);
+        }
+
+        return result;
+    }
+
+    /**
+     * Parses a message that contains encoded IPv6 network prefixes.
+     * <p>
+     * The IPv6 prefixes are encoded in the form:
+     * <Length, Prefix> where Length is the length in bits of the IPv6 prefix,
+     * and Prefix is the IPv6 prefix (padded with trailing bits to the end
+     * of an octet).
+     *
+     * @param totalLength the total length of the data to parse
+     * @param message the message with data to parse
+     * @return a collection of parsed IPv6 network prefixes
+     * @throws BgpMessage.BgpParseException
+     */
+    private static Collection<Ip6Prefix> parsePackedIp6Prefixes(
+                                                int totalLength,
+                                                ChannelBuffer message)
+        throws BgpMessage.BgpParseException {
+        Collection<Ip6Prefix> result = new ArrayList<>();
+
+        if (totalLength == 0) {
+            return result;
+        }
+
+        // Parse the data
+        byte[] buffer = new byte[Ip6Address.BYTE_LENGTH];
+        int dataEnd = message.readerIndex() + totalLength;
+        while (message.readerIndex() < dataEnd) {
+            int prefixBitlen = message.readUnsignedByte();
+            int prefixBytelen = (prefixBitlen + 7) / 8;     // Round-up
+            if (message.readerIndex() + prefixBytelen > dataEnd) {
+                String errorMsg = "Malformed Network Prefixes";
+                throw new BgpMessage.BgpParseException(errorMsg);
+            }
+
+            message.readBytes(buffer, 0, prefixBytelen);
+            Ip6Prefix prefix = Ip6Prefix.valueOf(Ip6Address.valueOf(buffer),
+                                                 prefixBitlen);
+            result.add(prefix);
+        }
+
+        return result;
+    }
+
+    /**
+     * Applies the appropriate actions after detecting BGP UPDATE
+     * Invalid Network Field Error: send NOTIFICATION and close the channel.
+     *
+     * @param bgpSession the BGP Session to use
+     * @param ctx the Channel Handler Context
+     */
+    private static void actionsBgpUpdateInvalidNetworkField(
+                                BgpSession bgpSession,
+                                ChannelHandlerContext ctx) {
+        log.debug("BGP RX UPDATE Error from {}: Invalid Network Field",
+                  bgpSession.remoteInfo().address());
+
+        //
+        // ERROR: Invalid Network Field
+        //
+        // Send NOTIFICATION and close the connection
+        int errorCode = BgpConstants.Notifications.UpdateMessageError.ERROR_CODE;
+        int errorSubcode = BgpConstants.Notifications.UpdateMessageError.INVALID_NETWORK_FIELD;
+        ChannelBuffer txMessage =
+            BgpNotification.prepareBgpNotification(errorCode, errorSubcode,
+                                                   null);
+        ctx.getChannel().write(txMessage);
+        bgpSession.closeSession(ctx);
+    }
+
+    /**
+     * Applies the appropriate actions after detecting BGP UPDATE
+     * Malformed Attribute List Error: send NOTIFICATION and close the channel.
+     *
+     * @param bgpSession the BGP Session to use
+     * @param ctx the Channel Handler Context
+     */
+    private static void actionsBgpUpdateMalformedAttributeList(
+                                BgpSession bgpSession,
+                                ChannelHandlerContext ctx) {
+        log.debug("BGP RX UPDATE Error from {}: Malformed Attribute List",
+                  bgpSession.remoteInfo().address());
+
+        //
+        // ERROR: Malformed Attribute List
+        //
+        // Send NOTIFICATION and close the connection
+        int errorCode = BgpConstants.Notifications.UpdateMessageError.ERROR_CODE;
+        int errorSubcode = BgpConstants.Notifications.UpdateMessageError.MALFORMED_ATTRIBUTE_LIST;
+        ChannelBuffer txMessage =
+            BgpNotification.prepareBgpNotification(errorCode, errorSubcode,
+                                                   null);
+        ctx.getChannel().write(txMessage);
+        bgpSession.closeSession(ctx);
+    }
+
+    /**
+     * Applies the appropriate actions after detecting BGP UPDATE
+     * Missing Well-known Attribute Error: send NOTIFICATION and close the
+     * channel.
+     *
+     * @param bgpSession the BGP Session to use
+     * @param ctx the Channel Handler Context
+     * @param missingAttrTypeCode the missing attribute type code
+     */
+    private static void actionsBgpUpdateMissingWellKnownAttribute(
+                                BgpSession bgpSession,
+                                ChannelHandlerContext ctx,
+                                int missingAttrTypeCode) {
+        log.debug("BGP RX UPDATE Error from {}: Missing Well-known Attribute: {}",
+                  bgpSession.remoteInfo().address(), missingAttrTypeCode);
+
+        //
+        // ERROR: Missing Well-known Attribute
+        //
+        // Send NOTIFICATION and close the connection
+        int errorCode = BgpConstants.Notifications.UpdateMessageError.ERROR_CODE;
+        int errorSubcode = BgpConstants.Notifications.UpdateMessageError.MISSING_WELL_KNOWN_ATTRIBUTE;
+        ChannelBuffer data = ChannelBuffers.buffer(1);
+        data.writeByte(missingAttrTypeCode);
+        ChannelBuffer txMessage =
+            BgpNotification.prepareBgpNotification(errorCode, errorSubcode,
+                                                   data);
+        ctx.getChannel().write(txMessage);
+        bgpSession.closeSession(ctx);
+    }
+
+    /**
+     * Applies the appropriate actions after detecting BGP UPDATE
+     * Invalid ORIGIN Attribute Error: send NOTIFICATION and close the channel.
+     *
+     * @param bgpSession the BGP Session to use
+     * @param ctx the Channel Handler Context
+     * @param attrTypeCode the attribute type code
+     * @param attrLen the attribute length (in octets)
+     * @param attrFlags the attribute flags
+     * @param message the message with the data
+     * @param origin the ORIGIN attribute value
+     */
+    private static void actionsBgpUpdateInvalidOriginAttribute(
+                                BgpSession bgpSession,
+                                ChannelHandlerContext ctx,
+                                int attrTypeCode,
+                                int attrLen,
+                                int attrFlags,
+                                ChannelBuffer message,
+                                short origin) {
+        log.debug("BGP RX UPDATE Error from {}: Invalid ORIGIN Attribute",
+                  bgpSession.remoteInfo().address());
+
+        //
+        // ERROR: Invalid ORIGIN Attribute
+        //
+        // Send NOTIFICATION and close the connection
+        int errorCode = BgpConstants.Notifications.UpdateMessageError.ERROR_CODE;
+        int errorSubcode = BgpConstants.Notifications.UpdateMessageError.INVALID_ORIGIN_ATTRIBUTE;
+        ChannelBuffer data =
+            prepareBgpUpdateNotificationDataPayload(attrTypeCode, attrLen,
+                                                    attrFlags, message);
+        ChannelBuffer txMessage =
+            BgpNotification.prepareBgpNotification(errorCode, errorSubcode,
+                                                   data);
+        ctx.getChannel().write(txMessage);
+        bgpSession.closeSession(ctx);
+    }
+
+    /**
+     * Applies the appropriate actions after detecting BGP UPDATE
+     * Attribute Flags Error: send NOTIFICATION and close the channel.
+     *
+     * @param bgpSession the BGP Session to use
+     * @param ctx the Channel Handler Context
+     * @param attrTypeCode the attribute type code
+     * @param attrLen the attribute length (in octets)
+     * @param attrFlags the attribute flags
+     * @param message the message with the data
+     */
+    private static void actionsBgpUpdateAttributeFlagsError(
+                                BgpSession bgpSession,
+                                ChannelHandlerContext ctx,
+                                int attrTypeCode,
+                                int attrLen,
+                                int attrFlags,
+                                ChannelBuffer message) {
+        log.debug("BGP RX UPDATE Error from {}: Attribute Flags Error",
+                  bgpSession.remoteInfo().address());
+
+        //
+        // ERROR: Attribute Flags Error
+        //
+        // Send NOTIFICATION and close the connection
+        int errorCode = BgpConstants.Notifications.UpdateMessageError.ERROR_CODE;
+        int errorSubcode = BgpConstants.Notifications.UpdateMessageError.ATTRIBUTE_FLAGS_ERROR;
+        ChannelBuffer data =
+            prepareBgpUpdateNotificationDataPayload(attrTypeCode, attrLen,
+                                                    attrFlags, message);
+        ChannelBuffer txMessage =
+            BgpNotification.prepareBgpNotification(errorCode, errorSubcode,
+                                                   data);
+        ctx.getChannel().write(txMessage);
+        bgpSession.closeSession(ctx);
+    }
+
+    /**
+     * Applies the appropriate actions after detecting BGP UPDATE
+     * Invalid NEXT_HOP Attribute Error: send NOTIFICATION and close the
+     * channel.
+     *
+     * @param bgpSession the BGP Session to use
+     * @param ctx the Channel Handler Context
+     * @param attrTypeCode the attribute type code
+     * @param attrLen the attribute length (in octets)
+     * @param attrFlags the attribute flags
+     * @param message the message with the data
+     * @param nextHop the NEXT_HOP attribute value
+     */
+    private static void actionsBgpUpdateInvalidNextHopAttribute(
+                                BgpSession bgpSession,
+                                ChannelHandlerContext ctx,
+                                int attrTypeCode,
+                                int attrLen,
+                                int attrFlags,
+                                ChannelBuffer message,
+                                Ip4Address nextHop) {
+        log.debug("BGP RX UPDATE Error from {}: Invalid NEXT_HOP Attribute {}",
+                  bgpSession.remoteInfo().address(), nextHop);
+
+        //
+        // ERROR: Invalid NEXT_HOP Attribute
+        //
+        // Send NOTIFICATION and close the connection
+        int errorCode = BgpConstants.Notifications.UpdateMessageError.ERROR_CODE;
+        int errorSubcode = BgpConstants.Notifications.UpdateMessageError.INVALID_NEXT_HOP_ATTRIBUTE;
+        ChannelBuffer data =
+            prepareBgpUpdateNotificationDataPayload(attrTypeCode, attrLen,
+                                                    attrFlags, message);
+        ChannelBuffer txMessage =
+            BgpNotification.prepareBgpNotification(errorCode, errorSubcode,
+                                                   data);
+        ctx.getChannel().write(txMessage);
+        bgpSession.closeSession(ctx);
+    }
+
+    /**
+     * Applies the appropriate actions after detecting BGP UPDATE
+     * Unrecognized Well-known Attribute Error: send NOTIFICATION and close
+     * the channel.
+     *
+     * @param bgpSession the BGP Session to use
+     * @param ctx the Channel Handler Context
+     * @param attrTypeCode the attribute type code
+     * @param attrLen the attribute length (in octets)
+     * @param attrFlags the attribute flags
+     * @param message the message with the data
+     */
+    private static void actionsBgpUpdateUnrecognizedWellKnownAttribute(
+                                BgpSession bgpSession,
+                                ChannelHandlerContext ctx,
+                                int attrTypeCode,
+                                int attrLen,
+                                int attrFlags,
+                                ChannelBuffer message) {
+        log.debug("BGP RX UPDATE Error from {}: " +
+                  "Unrecognized Well-known Attribute Error: {}",
+                  bgpSession.remoteInfo().address(), attrTypeCode);
+
+        //
+        // ERROR: Unrecognized Well-known Attribute
+        //
+        // Send NOTIFICATION and close the connection
+        int errorCode = BgpConstants.Notifications.UpdateMessageError.ERROR_CODE;
+        int errorSubcode =
+            BgpConstants.Notifications.UpdateMessageError.UNRECOGNIZED_WELL_KNOWN_ATTRIBUTE;
+        ChannelBuffer data =
+            prepareBgpUpdateNotificationDataPayload(attrTypeCode, attrLen,
+                                                    attrFlags, message);
+        ChannelBuffer txMessage =
+            BgpNotification.prepareBgpNotification(errorCode, errorSubcode,
+                                                   data);
+        ctx.getChannel().write(txMessage);
+        bgpSession.closeSession(ctx);
+    }
+
+    /**
+     * Applies the appropriate actions after detecting BGP UPDATE
+     * Optional Attribute Error: send NOTIFICATION and close
+     * the channel.
+     *
+     * @param bgpSession the BGP Session to use
+     * @param ctx the Channel Handler Context
+     * @param attrTypeCode the attribute type code
+     * @param attrLen the attribute length (in octets)
+     * @param attrFlags the attribute flags
+     * @param message the message with the data
+     */
+    private static void actionsBgpUpdateOptionalAttributeError(
+                                BgpSession bgpSession,
+                                ChannelHandlerContext ctx,
+                                int attrTypeCode,
+                                int attrLen,
+                                int attrFlags,
+                                ChannelBuffer message) {
+        log.debug("BGP RX UPDATE Error from {}: Optional Attribute Error: {}",
+                  bgpSession.remoteInfo().address(), attrTypeCode);
+
+        //
+        // ERROR: Optional Attribute Error
+        //
+        // Send NOTIFICATION and close the connection
+        int errorCode = BgpConstants.Notifications.UpdateMessageError.ERROR_CODE;
+        int errorSubcode =
+            BgpConstants.Notifications.UpdateMessageError.OPTIONAL_ATTRIBUTE_ERROR;
+        ChannelBuffer data =
+            prepareBgpUpdateNotificationDataPayload(attrTypeCode, attrLen,
+                                                    attrFlags, message);
+        ChannelBuffer txMessage =
+            BgpNotification.prepareBgpNotification(errorCode, errorSubcode,
+                                                   data);
+        ctx.getChannel().write(txMessage);
+        bgpSession.closeSession(ctx);
+    }
+
+    /**
+     * Applies the appropriate actions after detecting BGP UPDATE
+     * Attribute Length Error: send NOTIFICATION and close the channel.
+     *
+     * @param bgpSession the BGP Session to use
+     * @param ctx the Channel Handler Context
+     * @param attrTypeCode the attribute type code
+     * @param attrLen the attribute length (in octets)
+     * @param attrFlags the attribute flags
+     * @param message the message with the data
+     */
+    private static void actionsBgpUpdateAttributeLengthError(
+                                BgpSession bgpSession,
+                                ChannelHandlerContext ctx,
+                                int attrTypeCode,
+                                int attrLen,
+                                int attrFlags,
+                                ChannelBuffer message) {
+        log.debug("BGP RX UPDATE Error from {}: Attribute Length Error",
+                  bgpSession.remoteInfo().address());
+
+        //
+        // ERROR: Attribute Length Error
+        //
+        // Send NOTIFICATION and close the connection
+        int errorCode = BgpConstants.Notifications.UpdateMessageError.ERROR_CODE;
+        int errorSubcode = BgpConstants.Notifications.UpdateMessageError.ATTRIBUTE_LENGTH_ERROR;
+        ChannelBuffer data =
+            prepareBgpUpdateNotificationDataPayload(attrTypeCode, attrLen,
+                                                    attrFlags, message);
+        ChannelBuffer txMessage =
+            BgpNotification.prepareBgpNotification(errorCode, errorSubcode,
+                                                   data);
+        ctx.getChannel().write(txMessage);
+        bgpSession.closeSession(ctx);
+    }
+
+    /**
+     * Applies the appropriate actions after detecting BGP UPDATE
+     * Malformed AS_PATH Error: send NOTIFICATION and close the channel.
+     *
+     * @param bgpSession the BGP Session to use
+     * @param ctx the Channel Handler Context
+     */
+    private static void actionsBgpUpdateMalformedAsPath(
+                                BgpSession bgpSession,
+                                ChannelHandlerContext ctx) {
+        log.debug("BGP RX UPDATE Error from {}: Malformed AS Path",
+                  bgpSession.remoteInfo().address());
+
+        //
+        // ERROR: Malformed AS_PATH
+        //
+        // Send NOTIFICATION and close the connection
+        int errorCode = BgpConstants.Notifications.UpdateMessageError.ERROR_CODE;
+        int errorSubcode = BgpConstants.Notifications.UpdateMessageError.MALFORMED_AS_PATH;
+        ChannelBuffer txMessage =
+            BgpNotification.prepareBgpNotification(errorCode, errorSubcode,
+                                                   null);
+        ctx.getChannel().write(txMessage);
+        bgpSession.closeSession(ctx);
+    }
+
+    /**
+     * Prepares BGP UPDATE Notification data payload.
+     *
+     * @param attrTypeCode the attribute type code
+     * @param attrLen the attribute length (in octets)
+     * @param attrFlags the attribute flags
+     * @param message the message with the data
+     * @return the buffer with the data payload for the BGP UPDATE Notification
+     */
+    private static ChannelBuffer prepareBgpUpdateNotificationDataPayload(
+                                        int attrTypeCode,
+                                        int attrLen,
+                                        int attrFlags,
+                                        ChannelBuffer message) {
+        // Compute the attribute length field octets
+        boolean extendedLengthBit = ((0x10 & attrFlags) != 0);
+        int attrLenOctets = 1;
+        if (extendedLengthBit) {
+            attrLenOctets = 2;
+        }
+        ChannelBuffer data =
+            ChannelBuffers.buffer(attrLen + attrLenOctets + 1);
+        data.writeByte(attrTypeCode);
+        if (extendedLengthBit) {
+            data.writeShort(attrLen);
+        } else {
+            data.writeByte(attrLen);
+        }
+        data.writeBytes(message, attrLen);
+        return data;
+    }
+
+    /**
+     * Helper class for storing Multiprotocol Network Layer Reachability
+     * information.
+     */
+    private static final class MpNlri {
+        private final int afi;
+        private final int safi;
+        private Ip4Address nextHop4;
+        private Ip6Address nextHop6;
+        private Collection<Ip4Prefix> nlri4 = new ArrayList<>();
+        private Collection<Ip6Prefix> nlri6 = new ArrayList<>();
+
+        /**
+         * Constructor.
+         *
+         * @param afi the Address Family Identifier
+         * @param safi the Subsequent Address Family Identifier
+         */
+        private MpNlri(int afi, int safi) {
+            this.afi = afi;
+            this.safi = safi;
+        }
+    }
+
+    /**
+     * Helper class for storing decoded BGP routing information.
+     */
+    private static final class DecodedBgpRoutes {
+        private final Map<Ip4Prefix, BgpRouteEntry> addedUnicastRoutes4 =
+            new HashMap<>();
+        private final Map<Ip6Prefix, BgpRouteEntry> addedUnicastRoutes6 =
+            new HashMap<>();
+        private final Map<Ip4Prefix, BgpRouteEntry> deletedUnicastRoutes4 =
+            new HashMap<>();
+        private final Map<Ip6Prefix, BgpRouteEntry> deletedUnicastRoutes6 =
+            new HashMap<>();
+    }
+}
diff --git a/apps/routing/src/main/java/org/onosproject/routing/bgp/package-info.java b/apps/routing/src/main/java/org/onosproject/routing/bgp/package-info.java
new file mode 100644
index 0000000..e4259b6
--- /dev/null
+++ b/apps/routing/src/main/java/org/onosproject/routing/bgp/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2014 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.
+ */
+
+/**
+ * Implementation of the BGP protocol.
+ */
+package org.onosproject.routing.bgp;
diff --git a/apps/routing/src/main/java/org/onosproject/routing/cli/BgpNeighborsListCommand.java b/apps/routing/src/main/java/org/onosproject/routing/cli/BgpNeighborsListCommand.java
new file mode 100644
index 0000000..b3cb6d0
--- /dev/null
+++ b/apps/routing/src/main/java/org/onosproject/routing/cli/BgpNeighborsListCommand.java
@@ -0,0 +1,183 @@
+/*
+ * Copyright 2014 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.cli;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.commands.Option;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.routing.bgp.BgpInfoService;
+import org.onosproject.routing.bgp.BgpSession;
+
+import java.util.Collection;
+
+/**
+ * Command to show the BGP neighbors.
+ */
+@Command(scope = "onos", name = "bgp-neighbors",
+         description = "Lists the BGP neighbors")
+public class BgpNeighborsListCommand extends AbstractShellCommand {
+    @Option(name = "-n", aliases = "--neighbor",
+            description = "BGP neighbor to display information about",
+            required = false, multiValued = false)
+    private String bgpNeighbor;
+
+    private static final String FORMAT_NEIGHBOR_LINE1 =
+        "BGP neighbor is %s, remote AS %d, local AS %d";
+    private static final String FORMAT_NEIGHBOR_LINE2 =
+        "  Remote router ID %s, IP %s, BGP version %d, Hold time %d";
+    private static final String FORMAT_NEIGHBOR_LINE3 =
+        "  Remote AFI/SAFI IPv4 Unicast %s Multicast %s, IPv6 Unicast %s Multicast %s";
+    private static final String FORMAT_NEIGHBOR_LINE4 =
+        "  Local  router ID %s, IP %s, BGP version %d, Hold time %d";
+    private static final String FORMAT_NEIGHBOR_LINE5 =
+        "  Local  AFI/SAFI IPv4 Unicast %s Multicast %s, IPv6 Unicast %s Multicast %s";
+    private static final String FORMAT_NEIGHBOR_LINE6 =
+        "  4 Octet AS Capability: %s %s";
+
+    @Override
+    protected void execute() {
+        BgpInfoService service = AbstractShellCommand.get(BgpInfoService.class);
+        Collection<BgpSession> bgpSessions = service.getBgpSessions();
+
+        if (bgpNeighbor != null) {
+            // Print a single neighbor (if found)
+            BgpSession foundBgpSession = null;
+            for (BgpSession bgpSession : bgpSessions) {
+                if (bgpSession.remoteInfo().bgpId().toString().equals(bgpNeighbor)) {
+                    foundBgpSession = bgpSession;
+                    break;
+                }
+            }
+            if (foundBgpSession != null) {
+                printNeighbor(foundBgpSession);
+            } else {
+                print("BGP neighbor %s not found", bgpNeighbor);
+            }
+            return;
+        }
+
+        // Print all neighbors
+        printNeighbors(bgpSessions);
+    }
+
+    /**
+     * Prints all BGP neighbors.
+     *
+     * @param bgpSessions the BGP sessions for the neighbors to print
+     */
+    private void printNeighbors(Collection<BgpSession> bgpSessions) {
+        if (outputJson()) {
+            print("%s", json(bgpSessions));
+        } else {
+            for (BgpSession bgpSession : bgpSessions) {
+                printNeighbor(bgpSession);
+            }
+        }
+    }
+
+    /**
+     * Prints a BGP neighbor.
+     *
+     * @param bgpSession the BGP session for the neighbor to print
+     */
+    private void printNeighbor(BgpSession bgpSession) {
+        print(FORMAT_NEIGHBOR_LINE1,
+              bgpSession.remoteInfo().bgpId().toString(),
+              bgpSession.remoteInfo().asNumber(),
+              bgpSession.localInfo().asNumber());
+        print(FORMAT_NEIGHBOR_LINE2,
+              bgpSession.remoteInfo().bgpId().toString(),
+              bgpSession.remoteInfo().address().toString(),
+              bgpSession.remoteInfo().bgpVersion(),
+              bgpSession.remoteInfo().holdtime());
+        print(FORMAT_NEIGHBOR_LINE3,
+              bgpSession.remoteInfo().ipv4Unicast() ? "YES" : "NO",
+              bgpSession.remoteInfo().ipv4Multicast() ? "YES" : "NO",
+              bgpSession.remoteInfo().ipv6Unicast() ? "YES" : "NO",
+              bgpSession.remoteInfo().ipv6Multicast() ? "YES" : "NO");
+        print(FORMAT_NEIGHBOR_LINE4,
+              bgpSession.localInfo().bgpId().toString(),
+              bgpSession.localInfo().address().toString(),
+              bgpSession.localInfo().bgpVersion(),
+              bgpSession.localInfo().holdtime());
+        print(FORMAT_NEIGHBOR_LINE5,
+              bgpSession.localInfo().ipv4Unicast() ? "YES" : "NO",
+              bgpSession.localInfo().ipv4Multicast() ? "YES" : "NO",
+              bgpSession.localInfo().ipv6Unicast() ? "YES" : "NO",
+              bgpSession.localInfo().ipv6Multicast() ? "YES" : "NO");
+        if (bgpSession.localInfo().as4OctetCapability() ||
+            bgpSession.remoteInfo().as4OctetCapability()) {
+            print(FORMAT_NEIGHBOR_LINE6,
+                  bgpSession.localInfo().as4OctetCapability() ? "Advertised" : "",
+                  bgpSession.remoteInfo().as4OctetCapability() ? "Received" : "");
+        }
+    }
+
+    /**
+     * Produces a JSON array of BGP neighbors.
+     *
+     * @param bgpSessions the BGP sessions with the data
+     * @return JSON array with the neighbors
+     */
+    private JsonNode json(Collection<BgpSession> bgpSessions) {
+        ObjectMapper mapper = new ObjectMapper();
+        ArrayNode result = mapper.createArrayNode();
+
+        for (BgpSession bgpSession : bgpSessions) {
+            result.add(json(mapper, bgpSession));
+        }
+        return result;
+    }
+
+    /**
+     * Produces JSON object for a BGP neighbor.
+     *
+     * @param mapper the JSON object mapper to use
+     * @param bgpSession the BGP session with the data
+     * @return JSON object for the route
+     */
+    private ObjectNode json(ObjectMapper mapper, BgpSession bgpSession) {
+        ObjectNode result = mapper.createObjectNode();
+
+        result.put("remoteAddress", bgpSession.remoteInfo().address().toString());
+        result.put("remoteBgpVersion", bgpSession.remoteInfo().bgpVersion());
+        result.put("remoteAs", bgpSession.remoteInfo().asNumber());
+        result.put("remoteAs4", bgpSession.remoteInfo().as4Number());
+        result.put("remoteHoldtime", bgpSession.remoteInfo().holdtime());
+        result.put("remoteBgpId", bgpSession.remoteInfo().bgpId().toString());
+        result.put("remoteIpv4Unicast", bgpSession.remoteInfo().ipv4Unicast());
+        result.put("remoteIpv4Multicast", bgpSession.remoteInfo().ipv4Multicast());
+        result.put("remoteIpv6Unicast", bgpSession.remoteInfo().ipv6Unicast());
+        result.put("remoteIpv6Multicast", bgpSession.remoteInfo().ipv6Multicast());
+        //
+        result.put("localAddress", bgpSession.localInfo().address().toString());
+        result.put("localBgpVersion", bgpSession.localInfo().bgpVersion());
+        result.put("localAs", bgpSession.localInfo().asNumber());
+        result.put("localAs4", bgpSession.localInfo().as4Number());
+        result.put("localHoldtime", bgpSession.localInfo().holdtime());
+        result.put("localBgpId", bgpSession.localInfo().bgpId().toString());
+        result.put("localIpv4Unicast", bgpSession.localInfo().ipv4Unicast());
+        result.put("localIpv4Multicast", bgpSession.localInfo().ipv4Multicast());
+        result.put("localIpv6Unicast", bgpSession.localInfo().ipv6Unicast());
+        result.put("localIpv6Multicast", bgpSession.localInfo().ipv6Multicast());
+
+        return result;
+    }
+}
diff --git a/apps/routing/src/main/java/org/onosproject/routing/cli/BgpRoutesListCommand.java b/apps/routing/src/main/java/org/onosproject/routing/cli/BgpRoutesListCommand.java
new file mode 100644
index 0000000..3b032c0
--- /dev/null
+++ b/apps/routing/src/main/java/org/onosproject/routing/cli/BgpRoutesListCommand.java
@@ -0,0 +1,283 @@
+/*
+ * Copyright 2014 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.cli;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.commands.Option;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.routing.bgp.BgpConstants.Update;
+import org.onosproject.routing.bgp.BgpInfoService;
+import org.onosproject.routing.bgp.BgpRouteEntry;
+import org.onosproject.routing.bgp.BgpSession;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+/**
+ * Command to show the routes learned through BGP.
+ */
+@Command(scope = "onos", name = "bgp-routes",
+         description = "Lists all BGP best routes")
+public class BgpRoutesListCommand extends AbstractShellCommand {
+    @Option(name = "-s", aliases = "--summary",
+            description = "BGP routes summary",
+            required = false, multiValued = false)
+    private boolean routesSummary = false;
+
+    @Option(name = "-n", aliases = "--neighbor",
+            description = "Routes from a BGP neighbor",
+            required = false, multiValued = false)
+    private String bgpNeighbor;
+
+    private static final String FORMAT_SUMMARY_V4 =
+        "Total BGP IPv4 routes = %d";
+    private static final String FORMAT_SUMMARY_V6 =
+        "Total BGP IPv6 routes = %d";
+    private static final String FORMAT_HEADER =
+        "   Network            Next Hop        Origin LocalPref       MED BGP-ID";
+    private static final String FORMAT_ROUTE_LINE1 =
+        "   %-18s %-15s %6s %9s %9s %-15s";
+    private static final String FORMAT_ROUTE_LINE2 =
+        "                      AsPath %s";
+
+    @Override
+    protected void execute() {
+        BgpInfoService service = AbstractShellCommand.get(BgpInfoService.class);
+
+        // Print summary of the routes
+        if (routesSummary) {
+            printSummary(service.getBgpRoutes4(), service.getBgpRoutes6());
+            return;
+        }
+
+        BgpSession foundBgpSession = null;
+        if (bgpNeighbor != null) {
+            // Print the routes from a single neighbor (if found)
+            for (BgpSession bgpSession : service.getBgpSessions()) {
+                if (bgpSession.remoteInfo().bgpId().toString().equals(bgpNeighbor)) {
+                    foundBgpSession = bgpSession;
+                    break;
+                }
+            }
+            if (foundBgpSession == null) {
+                print("BGP neighbor %s not found", bgpNeighbor);
+                return;
+            }
+        }
+
+        // Print the routes
+        if (foundBgpSession != null) {
+            printRoutes(foundBgpSession.getBgpRibIn4(),
+                        foundBgpSession.getBgpRibIn6());
+        } else {
+            printRoutes(service.getBgpRoutes4(), service.getBgpRoutes6());
+        }
+    }
+
+    /**
+     * Prints summary of the routes.
+     *
+     * @param routes4 the IPv4 routes
+     * @param routes6 the IPv6 routes
+     */
+    private void printSummary(Collection<BgpRouteEntry> routes4,
+                              Collection<BgpRouteEntry> routes6) {
+        if (outputJson()) {
+            ObjectMapper mapper = new ObjectMapper();
+            ObjectNode result = mapper.createObjectNode();
+            result.put("totalRoutes4", routes4.size());
+            result.put("totalRoutes6", routes6.size());
+            print("%s", result);
+        } else {
+            print(FORMAT_SUMMARY_V4, routes4.size());
+            print(FORMAT_SUMMARY_V6, routes6.size());
+        }
+    }
+
+    /**
+     * Prints all routes.
+     *
+     * @param routes4 the IPv4 routes to print
+     * @param routes6 the IPv6 routes to print
+     */
+    private void printRoutes(Collection<BgpRouteEntry> routes4,
+                             Collection<BgpRouteEntry> routes6) {
+        if (outputJson()) {
+            ObjectMapper mapper = new ObjectMapper();
+            ObjectNode result = mapper.createObjectNode();
+            result.put("routes4", json(routes4));
+            result.put("routes6", json(routes6));
+            print("%s", result);
+        } else {
+            // The IPv4 routes
+            print(FORMAT_HEADER);
+            for (BgpRouteEntry route : routes4) {
+                printRoute(route);
+            }
+            print(FORMAT_SUMMARY_V4, routes4.size());
+            print("");                  // Empty separator line
+            // The IPv6 routes
+            print(FORMAT_HEADER);
+            for (BgpRouteEntry route : routes6) {
+                printRoute(route);
+            }
+            print(FORMAT_SUMMARY_V6, routes6.size());
+        }
+    }
+
+    /**
+     * Prints a BGP route.
+     *
+     * @param route the route to print
+     */
+    private void printRoute(BgpRouteEntry route) {
+        if (route != null) {
+            print(FORMAT_ROUTE_LINE1, route.prefix(), route.nextHop(),
+                  Update.Origin.typeToString(route.getOrigin()),
+                  route.getLocalPref(), route.getMultiExitDisc(),
+                  route.getBgpSession().remoteInfo().bgpId());
+            print(FORMAT_ROUTE_LINE2, asPath4Cli(route.getAsPath()));
+        }
+    }
+
+    /**
+     * Formats the AS Path as a string that can be shown on the CLI.
+     *
+     * @param asPath the AS Path to format
+     * @return the AS Path as a string
+     */
+    private String asPath4Cli(BgpRouteEntry.AsPath asPath) {
+        ArrayList<BgpRouteEntry.PathSegment> pathSegments =
+            asPath.getPathSegments();
+
+        if (pathSegments.isEmpty()) {
+            return "[none]";
+        }
+
+        final StringBuilder builder = new StringBuilder();
+        for (BgpRouteEntry.PathSegment pathSegment : pathSegments) {
+            String prefix = null;
+            String suffix = null;
+            switch (pathSegment.getType()) {
+            case Update.AsPath.AS_SET:
+                prefix = "[AS-Set";
+                suffix = "]";
+                break;
+            case Update.AsPath.AS_SEQUENCE:
+                break;
+            case Update.AsPath.AS_CONFED_SEQUENCE:
+                prefix = "[AS-Confed-Seq";
+                suffix = "]";
+                break;
+            case Update.AsPath.AS_CONFED_SET:
+                prefix = "[AS-Confed-Set";
+                suffix = "]";
+                break;
+            default:
+                builder.append(String.format("(type = %s)",
+                        Update.AsPath.typeToString(pathSegment.getType())));
+                break;
+            }
+
+            if (prefix != null) {
+                if (builder.length() > 0) {
+                    builder.append(" ");        // Separator
+                }
+                builder.append(prefix);
+            }
+            // Print the AS numbers
+            for (Long asn : pathSegment.getSegmentAsNumbers()) {
+                if (builder.length() > 0) {
+                    builder.append(" ");        // Separator
+                }
+                builder.append(String.format("%d", asn));
+            }
+            if (suffix != null) {
+                // No need for separator
+                builder.append(prefix);
+            }
+        }
+        return builder.toString();
+    }
+
+    /**
+     * Produces a JSON array of routes.
+     *
+     * @param routes the routes with the data
+     * @return JSON array with the routes
+     */
+    private JsonNode json(Collection<BgpRouteEntry> routes) {
+        ObjectMapper mapper = new ObjectMapper();
+        ArrayNode result = mapper.createArrayNode();
+
+        for (BgpRouteEntry route : routes) {
+            result.add(json(mapper, route));
+        }
+        return result;
+    }
+
+    /**
+     * Produces JSON object for a route.
+     *
+     * @param mapper the JSON object mapper to use
+     * @param route the route with the data
+     * @return JSON object for the route
+     */
+    private ObjectNode json(ObjectMapper mapper, BgpRouteEntry route) {
+        ObjectNode result = mapper.createObjectNode();
+
+        result.put("prefix", route.prefix().toString());
+        result.put("nextHop", route.nextHop().toString());
+        result.put("bgpId",
+                   route.getBgpSession().remoteInfo().bgpId().toString());
+        result.put("origin", Update.Origin.typeToString(route.getOrigin()));
+        result.put("asPath", json(mapper, route.getAsPath()));
+        result.put("localPref", route.getLocalPref());
+        result.put("multiExitDisc", route.getMultiExitDisc());
+
+        return result;
+    }
+
+    /**
+     * Produces JSON object for an AS path.
+     *
+     * @param mapper the JSON object mapper to use
+     * @param asPath the AS path with the data
+     * @return JSON object for the AS path
+     */
+    private ObjectNode json(ObjectMapper mapper, BgpRouteEntry.AsPath asPath) {
+        ObjectNode result = mapper.createObjectNode();
+        ArrayNode pathSegmentsJson = mapper.createArrayNode();
+        for (BgpRouteEntry.PathSegment pathSegment : asPath.getPathSegments()) {
+            ObjectNode pathSegmentJson = mapper.createObjectNode();
+            pathSegmentJson.put("type",
+                                Update.AsPath.typeToString(pathSegment.getType()));
+            ArrayNode segmentAsNumbersJson = mapper.createArrayNode();
+            for (Long asNumber : pathSegment.getSegmentAsNumbers()) {
+                segmentAsNumbersJson.add(asNumber);
+            }
+            pathSegmentJson.put("segmentAsNumbers", segmentAsNumbersJson);
+            pathSegmentsJson.add(pathSegmentJson);
+        }
+        result.put("pathSegments", pathSegmentsJson);
+
+        return result;
+    }
+}
diff --git a/apps/routing/src/main/java/org/onosproject/routing/cli/RoutesListCommand.java b/apps/routing/src/main/java/org/onosproject/routing/cli/RoutesListCommand.java
new file mode 100644
index 0000000..6c9d688
--- /dev/null
+++ b/apps/routing/src/main/java/org/onosproject/routing/cli/RoutesListCommand.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright 2014 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.cli;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.commands.Option;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.routingapi.RouteEntry;
+import org.onosproject.routingapi.RoutingService;
+
+import java.util.Collection;
+
+/**
+ * Command to show the list of routes in SDN-IP's routing table.
+ */
+@Command(scope = "onos", name = "routes",
+        description = "Lists all SDN-IP best routes")
+public class RoutesListCommand extends AbstractShellCommand {
+    @Option(name = "-s", aliases = "--summary",
+            description = "SDN-IP routes summary",
+            required = false, multiValued = false)
+    private boolean routesSummary = false;
+
+    private static final String FORMAT_SUMMARY_V4 =
+        "Total SDN-IP IPv4 routes = %d";
+    private static final String FORMAT_SUMMARY_V6 =
+        "Total SDN-IP IPv6 routes = %d";
+    private static final String FORMAT_HEADER =
+        "   Network            Next Hop";
+    private static final String FORMAT_ROUTE =
+        "   %-18s %-15s";
+
+    @Override
+    protected void execute() {
+        RoutingService service = AbstractShellCommand.get(RoutingService.class);
+
+        // Print summary of the routes
+        if (routesSummary) {
+            printSummary(service.getRoutes4(), service.getRoutes6());
+            return;
+        }
+
+        // Print all routes
+        printRoutes(service.getRoutes4(), service.getRoutes6());
+    }
+
+    /**
+     * Prints summary of the routes.
+     *
+     * @param routes4 the IPv4 routes
+     * @param routes6 the IPv6 routes
+     */
+    private void printSummary(Collection<RouteEntry> routes4,
+                              Collection<RouteEntry> routes6) {
+        if (outputJson()) {
+            ObjectMapper mapper = new ObjectMapper();
+            ObjectNode result = mapper.createObjectNode();
+            result.put("totalRoutes4", routes4.size());
+            result.put("totalRoutes6", routes6.size());
+            print("%s", result);
+        } else {
+            print(FORMAT_SUMMARY_V4, routes4.size());
+            print(FORMAT_SUMMARY_V6, routes6.size());
+        }
+    }
+
+    /**
+     * Prints all routes.
+     *
+     * @param routes4 the IPv4 routes to print
+     * @param routes6 the IPv6 routes to print
+     */
+    private void printRoutes(Collection<RouteEntry> routes4,
+                             Collection<RouteEntry> routes6) {
+        if (outputJson()) {
+            ObjectMapper mapper = new ObjectMapper();
+            ObjectNode result = mapper.createObjectNode();
+            result.put("routes4", json(routes4));
+            result.put("routes6", json(routes6));
+            print("%s", result);
+        } else {
+            // The IPv4 routes
+            print(FORMAT_HEADER);
+            for (RouteEntry route : routes4) {
+                printRoute(route);
+            }
+            print(FORMAT_SUMMARY_V4, routes4.size());
+            print("");                  // Empty separator line
+            // The IPv6 routes
+            print(FORMAT_HEADER);
+            for (RouteEntry route : routes6) {
+                printRoute(route);
+            }
+            print(FORMAT_SUMMARY_V6, routes6.size());
+        }
+    }
+
+    /**
+     * Prints a route.
+     *
+     * @param route the route to print
+     */
+    private void printRoute(RouteEntry route) {
+        if (route != null) {
+            print(FORMAT_ROUTE, route.prefix(), route.nextHop());
+        }
+    }
+
+    /**
+     * Produces a JSON array of routes.
+     *
+     * @param routes the routes with the data
+     * @return JSON array with the routes
+     */
+    private JsonNode json(Collection<RouteEntry> routes) {
+        ObjectMapper mapper = new ObjectMapper();
+        ArrayNode result = mapper.createArrayNode();
+
+        for (RouteEntry route : routes) {
+            result.add(json(mapper, route));
+        }
+        return result;
+    }
+
+    /**
+     * Produces JSON object for a route.
+     *
+     * @param mapper the JSON object mapper to use
+     * @param route the route with the data
+     * @return JSON object for the route
+     */
+    private ObjectNode json(ObjectMapper mapper, RouteEntry route) {
+        ObjectNode result = mapper.createObjectNode();
+
+        result.put("prefix", route.prefix().toString());
+        result.put("nextHop", route.nextHop().toString());
+
+        return result;
+    }
+}
diff --git a/apps/routing/src/main/resources/OSGI-INF/blueprint/shell-config.xml b/apps/routing/src/main/resources/OSGI-INF/blueprint/shell-config.xml
new file mode 100644
index 0000000..5ef971d
--- /dev/null
+++ b/apps/routing/src/main/resources/OSGI-INF/blueprint/shell-config.xml
@@ -0,0 +1,29 @@
+<!--
+  ~ 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.
+  -->
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+
+  <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
+    <command>
+      <action class="org.onosproject.routing.cli.BgpNeighborsListCommand"/>
+    </command>
+    <command>
+      <action class="org.onosproject.routing.cli.BgpRoutesListCommand"/>
+    </command>
+    <command>
+      <action class="org.onosproject.routing.cli.RoutesListCommand"/>
+    </command>
+  </command-bundle>
+</blueprint>
diff --git a/apps/routing/src/test/java/org/onosproject/routing/RouterAsyncArpTest.java b/apps/routing/src/test/java/org/onosproject/routing/RouterAsyncArpTest.java
new file mode 100644
index 0000000..d9a5ce9
--- /dev/null
+++ b/apps/routing/src/test/java/org/onosproject/routing/RouterAsyncArpTest.java
@@ -0,0 +1,215 @@
+/*
+ * Copyright 2014 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;
+
+import com.google.common.collect.Sets;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip4Prefix;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultHost;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Host;
+import org.onosproject.net.HostId;
+import org.onosproject.net.HostLocation;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.host.HostEvent;
+import org.onosproject.net.host.HostListener;
+import org.onosproject.net.host.HostService;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.routing.Router.InternalHostListener;
+import org.onosproject.routingapi.BgpService;
+import org.onosproject.routingapi.FibEntry;
+import org.onosproject.routingapi.FibListener;
+import org.onosproject.routingapi.FibUpdate;
+import org.onosproject.routingapi.RouteEntry;
+import org.onosproject.routingapi.RouteListener;
+import org.onosproject.routingapi.RouteUpdate;
+
+import java.util.Collections;
+
+import static org.easymock.EasyMock.*;
+
+/**
+* This class tests adding a route and updating a route.
+* The HostService module answers the MAC address asynchronously.
+*/
+public class RouterAsyncArpTest {
+
+    private HostService hostService;
+    private FibListener fibListener;
+
+    private static final ConnectPoint SW1_ETH1 = new ConnectPoint(
+            DeviceId.deviceId("of:0000000000000001"),
+            PortNumber.portNumber(1));
+
+    private static final ConnectPoint SW2_ETH1 = new ConnectPoint(
+            DeviceId.deviceId("of:0000000000000002"),
+            PortNumber.portNumber(1));
+
+    private static final ConnectPoint SW3_ETH1 = new ConnectPoint(
+            DeviceId.deviceId("of:0000000000000003"),
+            PortNumber.portNumber(1));
+
+    private Router router;
+    private InternalHostListener internalHostListener;
+
+    @Before
+    public void setUp() throws Exception {
+        hostService = createMock(HostService.class);
+
+        BgpService bgpService = createMock(BgpService.class);
+        bgpService.start(anyObject(RouteListener.class), anyInt());
+        bgpService.stop();
+        replay(bgpService);
+
+        fibListener = createMock(FibListener.class);
+
+        router = new Router();
+        router.hostService = hostService;
+        router.bgpService = bgpService;
+        router.activate();
+
+        router.start(fibListener);
+
+        internalHostListener = router.new InternalHostListener();
+    }
+
+    @After
+    public void tearDown() {
+        // Called during shutdown
+        reset(hostService);
+        hostService.removeListener(anyObject(HostListener.class));
+
+        router.stop();
+    }
+
+    /**
+     * Tests adding a route entry with asynchronous HostService replies.
+     */
+    @Test
+    public void testRouteAdd() {
+        // Construct a route entry
+        IpPrefix prefix = Ip4Prefix.valueOf("1.1.1.0/24");
+        IpAddress nextHopIp = Ip4Address.valueOf("192.168.10.1");
+
+        RouteEntry routeEntry = new RouteEntry(prefix, nextHopIp);
+
+        // Host service will reply with no hosts when asked
+        reset(hostService);
+        expect(hostService.getHostsByIp(anyObject(IpAddress.class))).andReturn(
+                Collections.emptySet()).anyTimes();
+        hostService.startMonitoringIp(IpAddress.valueOf("192.168.10.1"));
+        replay(hostService);
+
+
+        // Initially when we add the route, no FIB update will be sent
+        replay(fibListener);
+
+        router.processRouteUpdates(Collections.singletonList(
+                new RouteUpdate(RouteUpdate.Type.UPDATE, routeEntry)));
+
+        verify(fibListener);
+
+
+        // Now when we send the event, we expect the FIB update to be sent
+        reset(fibListener);
+        FibEntry fibEntry = new FibEntry(prefix, nextHopIp,
+                                         MacAddress.valueOf("00:00:00:00:00:01"));
+
+        fibListener.update(Collections.singletonList(new FibUpdate(
+                FibUpdate.Type.UPDATE, fibEntry)), Collections.emptyList());
+        replay(fibListener);
+
+        Host host = new DefaultHost(ProviderId.NONE, HostId.NONE,
+                                    MacAddress.valueOf("00:00:00:00:00:01"), VlanId.NONE,
+                                    new HostLocation(
+                                            SW1_ETH1.deviceId(),
+                                            SW1_ETH1.port(), 1),
+                                    Sets.newHashSet(IpAddress.valueOf("192.168.10.1")));
+
+        // Send in the host event
+        internalHostListener.event(
+                new HostEvent(HostEvent.Type.HOST_ADDED, host));
+
+        verify(fibListener);
+    }
+
+    /**
+     * Tests updating a route entry with asynchronous HostService replies.
+     */
+    @Test
+    public void testRouteUpdate() {
+        // Add a route
+        testRouteAdd();
+
+        // Construct a route entry
+        IpPrefix prefix = Ip4Prefix.valueOf("1.1.1.0/24");
+        IpAddress nextHopIp = Ip4Address.valueOf("192.168.20.1");
+
+        RouteEntry routeEntry = new RouteEntry(prefix, nextHopIp);
+
+        // Host service will reply with no hosts when asked
+        reset(hostService);
+        expect(hostService.getHostsByIp(anyObject(IpAddress.class))).andReturn(
+                Collections.emptySet()).anyTimes();
+        hostService.startMonitoringIp(IpAddress.valueOf("192.168.20.1"));
+        replay(hostService);
+
+
+        // Initially when we add the route, the DELETE FIB update will be sent
+        // but the UPDATE FIB update will come later when the MAC is resolved
+        reset(fibListener);
+
+        fibListener.update(Collections.emptyList(), Collections.singletonList(new FibUpdate(
+                FibUpdate.Type.DELETE, new FibEntry(prefix, null, null))));
+        replay(fibListener);
+
+        router.processRouteUpdates(Collections.singletonList(
+                new RouteUpdate(RouteUpdate.Type.UPDATE, routeEntry)));
+
+        verify(fibListener);
+
+
+        // Now when we send the event, we expect the FIB update to be sent
+        reset(fibListener);
+        FibEntry fibEntry = new FibEntry(prefix, nextHopIp,
+                                         MacAddress.valueOf("00:00:00:00:00:02"));
+
+        fibListener.update(Collections.singletonList(new FibUpdate(
+                FibUpdate.Type.UPDATE, fibEntry)), Collections.emptyList());
+        replay(fibListener);
+
+        Host host = new DefaultHost(ProviderId.NONE, HostId.NONE,
+                                    MacAddress.valueOf("00:00:00:00:00:02"), VlanId.NONE,
+                                    new HostLocation(
+                                            SW1_ETH1.deviceId(),
+                                            SW1_ETH1.port(), 1),
+                                    Sets.newHashSet(IpAddress.valueOf("192.168.20.1")));
+
+        // Send in the host event
+        internalHostListener.event(
+                new HostEvent(HostEvent.Type.HOST_ADDED, host));
+
+        verify(fibListener);
+    }
+}
diff --git a/apps/routing/src/test/java/org/onosproject/routing/RouterTest.java b/apps/routing/src/test/java/org/onosproject/routing/RouterTest.java
new file mode 100644
index 0000000..176c159
--- /dev/null
+++ b/apps/routing/src/test/java/org/onosproject/routing/RouterTest.java
@@ -0,0 +1,269 @@
+/*
+ * Copyright 2014 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;
+
+import com.google.common.collect.Sets;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip4Prefix;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultHost;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Host;
+import org.onosproject.net.HostId;
+import org.onosproject.net.HostLocation;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.host.HostListener;
+import org.onosproject.net.host.HostService;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.routingapi.BgpService;
+import org.onosproject.routingapi.FibEntry;
+import org.onosproject.routingapi.FibListener;
+import org.onosproject.routingapi.FibUpdate;
+import org.onosproject.routingapi.RouteEntry;
+import org.onosproject.routingapi.RouteListener;
+import org.onosproject.routingapi.RouteUpdate;
+
+import java.util.Collections;
+
+import static org.easymock.EasyMock.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * This class tests adding a route, updating a route, deleting a route,
+ * and adding a route whose next hop is the local BGP speaker.
+ * <p/>
+ * The HostService answers requests synchronously.
+ */
+public class RouterTest {
+
+    private HostService hostService;
+
+    private FibListener fibListener;
+
+    private static final ConnectPoint SW1_ETH1 = new ConnectPoint(
+            DeviceId.deviceId("of:0000000000000001"),
+            PortNumber.portNumber(1));
+
+    private static final ConnectPoint SW2_ETH1 = new ConnectPoint(
+            DeviceId.deviceId("of:0000000000000002"),
+            PortNumber.portNumber(1));
+
+    private static final ConnectPoint SW3_ETH1 = new ConnectPoint(
+            DeviceId.deviceId("of:0000000000000003"),
+            PortNumber.portNumber(1));
+
+    private static final ConnectPoint SW4_ETH1 = new ConnectPoint(
+            DeviceId.deviceId("of:0000000000000004"),
+            PortNumber.portNumber(1));
+
+    private Router router;
+
+    @Before
+    public void setUp() throws Exception {
+        setUpHostService();
+
+        BgpService bgpService = createMock(BgpService.class);
+        bgpService.start(anyObject(RouteListener.class), anyInt());
+        bgpService.stop();
+        replay(bgpService);
+
+        fibListener = createMock(FibListener.class);
+
+        router = new Router();
+        router.hostService = hostService;
+        router.bgpService = bgpService;
+        router.activate();
+
+        router.start(fibListener);
+    }
+
+    @After
+    public void tearDown() {
+        router.stop();
+    }
+
+    /**
+     * Sets up the host service with details of some hosts.
+     */
+    private void setUpHostService() {
+        hostService = createMock(HostService.class);
+
+        hostService.addListener(anyObject(HostListener.class));
+        expectLastCall().anyTimes();
+
+        IpAddress host1Address = IpAddress.valueOf("192.168.10.1");
+        Host host1 = new DefaultHost(ProviderId.NONE, HostId.NONE,
+                MacAddress.valueOf("00:00:00:00:00:01"), VlanId.NONE,
+                new HostLocation(SW1_ETH1, 1),
+                Sets.newHashSet(host1Address));
+
+        expect(hostService.getHostsByIp(host1Address))
+                .andReturn(Sets.newHashSet(host1)).anyTimes();
+        hostService.startMonitoringIp(host1Address);
+        expectLastCall().anyTimes();
+
+
+        IpAddress host2Address = IpAddress.valueOf("192.168.20.1");
+        Host host2 = new DefaultHost(ProviderId.NONE, HostId.NONE,
+                MacAddress.valueOf("00:00:00:00:00:02"), VlanId.NONE,
+                new HostLocation(SW2_ETH1, 1),
+                Sets.newHashSet(host2Address));
+
+        expect(hostService.getHostsByIp(host2Address))
+                .andReturn(Sets.newHashSet(host2)).anyTimes();
+        hostService.startMonitoringIp(host2Address);
+        expectLastCall().anyTimes();
+
+        // Next hop on a VLAN
+        IpAddress host3Address = IpAddress.valueOf("192.168.40.1");
+        Host host3 = new DefaultHost(ProviderId.NONE, HostId.NONE,
+                MacAddress.valueOf("00:00:00:00:00:03"), VlanId.vlanId((short) 1),
+                new HostLocation(SW4_ETH1, 1),
+                Sets.newHashSet(host3Address));
+
+        expect(hostService.getHostsByIp(host3Address))
+                .andReturn(Sets.newHashSet(host3)).anyTimes();
+        hostService.startMonitoringIp(host3Address);
+        expectLastCall().anyTimes();
+
+        // Called during shutdown
+        hostService.removeListener(anyObject(HostListener.class));
+
+        replay(hostService);
+    }
+
+    /**
+     * Tests adding a route entry.
+     */
+    @Test
+    public void testRouteAdd() {
+        // Construct a route entry
+        IpPrefix prefix = Ip4Prefix.valueOf("1.1.1.0/24");
+        IpAddress nextHopIp = Ip4Address.valueOf("192.168.10.1");
+
+        RouteEntry routeEntry = new RouteEntry(prefix, nextHopIp);
+
+        // Expected FIB entry
+        FibEntry fibEntry = new FibEntry(prefix, nextHopIp,
+                                         MacAddress.valueOf("00:00:00:00:00:01"));
+
+        fibListener.update(Collections.singletonList(new FibUpdate(
+                FibUpdate.Type.UPDATE, fibEntry)), Collections.emptyList());
+
+        replay(fibListener);
+
+        router.processRouteUpdates(Collections.singletonList(
+                new RouteUpdate(RouteUpdate.Type.UPDATE, routeEntry)));
+
+        verify(fibListener);
+    }
+
+    /**
+     * Tests updating a route entry.
+     */
+    @Test
+    public void testRouteUpdate() {
+        // Firstly add a route
+        testRouteAdd();
+
+        // Route entry with updated next hop for the original prefix
+        RouteEntry routeEntryUpdate = new RouteEntry(
+                Ip4Prefix.valueOf("1.1.1.0/24"),
+                Ip4Address.valueOf("192.168.20.1"));
+
+        // The old FIB entry will be withdrawn
+        FibEntry withdrawFibEntry = new FibEntry(
+                Ip4Prefix.valueOf("1.1.1.0/24"), null, null);
+
+        // A new FIB entry will be added
+        FibEntry updateFibEntry = new FibEntry(
+                Ip4Prefix.valueOf("1.1.1.0/24"),
+                Ip4Address.valueOf("192.168.20.1"),
+                MacAddress.valueOf("00:00:00:00:00:02"));
+
+        reset(fibListener);
+        fibListener.update(Collections.singletonList(new FibUpdate(
+                                    FibUpdate.Type.UPDATE, updateFibEntry)),
+                           Collections.singletonList(new FibUpdate(
+                                    FibUpdate.Type.DELETE, withdrawFibEntry)));
+
+        replay(fibListener);
+
+        router.processRouteUpdates(Collections.singletonList(new RouteUpdate(
+                RouteUpdate.Type.UPDATE, routeEntryUpdate)));
+
+        verify(fibListener);
+    }
+
+    /**
+     * Tests deleting a route entry.
+     */
+    @Test
+    public void testRouteDelete() {
+        // Firstly add a route
+        testRouteAdd();
+
+        RouteEntry deleteRouteEntry = new RouteEntry(
+                Ip4Prefix.valueOf("1.1.1.0/24"),
+                Ip4Address.valueOf("192.168.10.1"));
+
+        FibEntry deleteFibEntry = new FibEntry(
+                Ip4Prefix.valueOf("1.1.1.0/24"), null, null);
+
+        reset(fibListener);
+        fibListener.update(Collections.emptyList(), Collections.singletonList(
+                new FibUpdate(FibUpdate.Type.DELETE, deleteFibEntry)));
+
+        replay(fibListener);
+
+        router.processRouteUpdates(Collections.singletonList(
+                new RouteUpdate(RouteUpdate.Type.DELETE, deleteRouteEntry)));
+
+        verify(fibListener);
+    }
+
+    /**
+     * Tests adding a route whose next hop is the local BGP speaker.
+     */
+    @Test
+    public void testLocalRouteAdd() {
+        // Construct a route entry, the next hop is the local BGP speaker
+        RouteEntry routeEntry = new RouteEntry(
+                Ip4Prefix.valueOf("1.1.1.0/24"),
+                Ip4Address.valueOf("0.0.0.0"));
+
+        // No methods on the FIB listener should be called
+        replay(fibListener);
+
+        // Call the processRouteUpdates() method in Router class
+        RouteUpdate routeUpdate = new RouteUpdate(RouteUpdate.Type.UPDATE,
+                                                  routeEntry);
+        router.processRouteUpdates(Collections.singletonList(routeUpdate));
+
+        // Verify
+        assertEquals(1, router.getRoutes4().size());
+        assertTrue(router.getRoutes4().contains(routeEntry));
+        verify(fibListener);
+    }
+}
diff --git a/apps/routing/src/test/java/org/onosproject/routing/bgp/AsPathTest.java b/apps/routing/src/test/java/org/onosproject/routing/bgp/AsPathTest.java
new file mode 100644
index 0000000..2414eb2
--- /dev/null
+++ b/apps/routing/src/test/java/org/onosproject/routing/bgp/AsPathTest.java
@@ -0,0 +1,233 @@
+/*
+ * Copyright 2014 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.hamcrest.Matchers;
+import org.junit.Test;
+
+import java.util.ArrayList;
+
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.not;
+import static org.junit.Assert.assertThat;
+
+/**
+ * Unit tests for the BgpRouteEntry.AsPath class.
+ */
+public class AsPathTest {
+    /**
+     * Generates Path Segments.
+     *
+     * @return the generated Path Segments
+     */
+    private ArrayList<BgpRouteEntry.PathSegment> generatePathSegments() {
+        ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>();
+        byte pathSegmentType;
+        ArrayList<Long> segmentAsNumbers;
+        BgpRouteEntry.PathSegment pathSegment;
+
+        pathSegmentType = (byte) BgpConstants.Update.AsPath.AS_CONFED_SEQUENCE;
+        segmentAsNumbers = new ArrayList<>();
+        segmentAsNumbers.add((long) 1);
+        segmentAsNumbers.add((long) 2);
+        segmentAsNumbers.add((long) 3);
+        pathSegment =
+            new BgpRouteEntry.PathSegment(pathSegmentType, segmentAsNumbers);
+        pathSegments.add(pathSegment);
+        //
+        pathSegmentType = (byte) BgpConstants.Update.AsPath.AS_CONFED_SET;
+        segmentAsNumbers = new ArrayList<>();
+        segmentAsNumbers.add((long) 4);
+        segmentAsNumbers.add((long) 5);
+        segmentAsNumbers.add((long) 6);
+        pathSegment =
+            new BgpRouteEntry.PathSegment(pathSegmentType, segmentAsNumbers);
+        pathSegments.add(pathSegment);
+        //
+        pathSegmentType = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE;
+        segmentAsNumbers = new ArrayList<>();
+        segmentAsNumbers.add((long) 7);
+        segmentAsNumbers.add((long) 8);
+        segmentAsNumbers.add((long) 9);
+        pathSegment =
+            new BgpRouteEntry.PathSegment(pathSegmentType, segmentAsNumbers);
+        pathSegments.add(pathSegment);
+        //
+        pathSegmentType = (byte) BgpConstants.Update.AsPath.AS_SET;
+        segmentAsNumbers = new ArrayList<>();
+        segmentAsNumbers.add((long) 10);
+        segmentAsNumbers.add((long) 11);
+        segmentAsNumbers.add((long) 12);
+        pathSegment =
+            new BgpRouteEntry.PathSegment(pathSegmentType, segmentAsNumbers);
+        pathSegments.add(pathSegment);
+
+        return pathSegments;
+    }
+
+    /**
+     * Generates an AS Path.
+     *
+     * @return a generated AS Path
+     */
+    private BgpRouteEntry.AsPath generateAsPath() {
+        ArrayList<BgpRouteEntry.PathSegment> pathSegments =
+            generatePathSegments();
+        BgpRouteEntry.AsPath asPath = new BgpRouteEntry.AsPath(pathSegments);
+
+        return asPath;
+    }
+
+    /**
+     * Tests valid class constructor.
+     */
+    @Test
+    public void testConstructor() {
+        BgpRouteEntry.AsPath asPath = generateAsPath();
+
+        String expectedString =
+            "AsPath{pathSegments=[" +
+            "PathSegment{type=AS_CONFED_SEQUENCE, segmentAsNumbers=[1, 2, 3]}, " +
+            "PathSegment{type=AS_CONFED_SET, segmentAsNumbers=[4, 5, 6]}, " +
+            "PathSegment{type=AS_SEQUENCE, segmentAsNumbers=[7, 8, 9]}, " +
+            "PathSegment{type=AS_SET, segmentAsNumbers=[10, 11, 12]}]}";
+        assertThat(asPath.toString(), is(expectedString));
+    }
+
+    /**
+     * Tests invalid class constructor for null Path Segments.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testInvalidConstructorNullPathSegments() {
+        ArrayList<BgpRouteEntry.PathSegment> pathSegments = null;
+        new BgpRouteEntry.AsPath(pathSegments);
+    }
+
+    /**
+     * Tests getting the fields of an AS Path.
+     */
+    @Test
+    public void testGetFields() {
+        // Create the fields to compare against
+        ArrayList<BgpRouteEntry.PathSegment> pathSegments =
+            generatePathSegments();
+
+        // Generate the entry to test
+        BgpRouteEntry.AsPath asPath = generateAsPath();
+
+        assertThat(asPath.getPathSegments(), is(pathSegments));
+    }
+
+    /**
+     * Tests getting the AS Path Length.
+     */
+    @Test
+    public void testGetAsPathLength() {
+        //
+        // NOTE:
+        //  - AS_CONFED_SEQUENCE and AS_CONFED_SET are excluded
+        //  - AS_SET counts as a single hop
+        //
+        BgpRouteEntry.AsPath asPath = generateAsPath();
+        assertThat(asPath.getAsPathLength(), is(4));
+
+        // Create an empty AS Path
+        ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>();
+        asPath = new BgpRouteEntry.AsPath(pathSegments);
+        assertThat(asPath.getAsPathLength(), is(0));
+    }
+
+    /**
+     * Tests equality of {@link BgpRouteEntry.AsPath}.
+     */
+    @Test
+    public void testEquality() {
+        BgpRouteEntry.AsPath asPath1 = generateAsPath();
+        BgpRouteEntry.AsPath asPath2 = generateAsPath();
+
+        assertThat(asPath1, is(asPath2));
+    }
+
+    /**
+     * Tests non-equality of {@link BgpRouteEntry.AsPath}.
+     */
+    @Test
+    public void testNonEquality() {
+        BgpRouteEntry.AsPath asPath1 = generateAsPath();
+
+        // Setup AS Path 2
+        ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>();
+        byte pathSegmentType;
+        ArrayList<Long> segmentAsNumbers;
+        BgpRouteEntry.PathSegment pathSegment;
+
+        pathSegmentType = (byte) BgpConstants.Update.AsPath.AS_CONFED_SEQUENCE;
+        segmentAsNumbers = new ArrayList<>();
+        segmentAsNumbers.add((long) 1);
+        segmentAsNumbers.add((long) 2);
+        segmentAsNumbers.add((long) 3);
+        pathSegment =
+            new BgpRouteEntry.PathSegment(pathSegmentType, segmentAsNumbers);
+        pathSegments.add(pathSegment);
+        //
+        pathSegmentType = (byte) BgpConstants.Update.AsPath.AS_CONFED_SET;
+        segmentAsNumbers = new ArrayList<>();
+        segmentAsNumbers.add((long) 4);
+        segmentAsNumbers.add((long) 5);
+        segmentAsNumbers.add((long) 6);
+        pathSegment =
+            new BgpRouteEntry.PathSegment(pathSegmentType, segmentAsNumbers);
+        pathSegments.add(pathSegment);
+        //
+        pathSegmentType = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE;
+        segmentAsNumbers = new ArrayList<>();
+        segmentAsNumbers.add((long) 7);
+        segmentAsNumbers.add((long) 8);
+        segmentAsNumbers.add((long) 9);
+        pathSegment =
+            new BgpRouteEntry.PathSegment(pathSegmentType, segmentAsNumbers);
+        pathSegments.add(pathSegment);
+        //
+        pathSegmentType = (byte) BgpConstants.Update.AsPath.AS_SET;
+        segmentAsNumbers = new ArrayList<>();
+        segmentAsNumbers.add((long) 10);
+        segmentAsNumbers.add((long) 111);                       // Different
+        segmentAsNumbers.add((long) 12);
+        pathSegment =
+            new BgpRouteEntry.PathSegment(pathSegmentType, segmentAsNumbers);
+        pathSegments.add(pathSegment);
+        //
+        BgpRouteEntry.AsPath asPath2 = new BgpRouteEntry.AsPath(pathSegments);
+
+        assertThat(asPath1, Matchers.is(not(asPath2)));
+    }
+
+    /**
+     * Tests object string representation.
+     */
+    @Test
+    public void testToString() {
+        BgpRouteEntry.AsPath asPath = generateAsPath();
+
+        String expectedString =
+            "AsPath{pathSegments=[" +
+            "PathSegment{type=AS_CONFED_SEQUENCE, segmentAsNumbers=[1, 2, 3]}, " +
+            "PathSegment{type=AS_CONFED_SET, segmentAsNumbers=[4, 5, 6]}, " +
+            "PathSegment{type=AS_SEQUENCE, segmentAsNumbers=[7, 8, 9]}, " +
+            "PathSegment{type=AS_SET, segmentAsNumbers=[10, 11, 12]}]}";
+        assertThat(asPath.toString(), is(expectedString));
+    }
+}
diff --git a/apps/routing/src/test/java/org/onosproject/routing/bgp/BgpRouteEntryTest.java b/apps/routing/src/test/java/org/onosproject/routing/bgp/BgpRouteEntryTest.java
new file mode 100644
index 0000000..ab72b6f
--- /dev/null
+++ b/apps/routing/src/test/java/org/onosproject/routing/bgp/BgpRouteEntryTest.java
@@ -0,0 +1,520 @@
+/*
+ * Copyright 2014 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.easymock.EasyMock;
+import org.hamcrest.Matchers;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip4Prefix;
+
+import java.util.ArrayList;
+
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.not;
+import static org.junit.Assert.assertThat;
+
+/**
+ * Unit tests for the BgpRouteEntry class.
+ */
+public class BgpRouteEntryTest {
+    private BgpSession bgpSession;
+    private static final Ip4Address BGP_SESSION_BGP_ID =
+        Ip4Address.valueOf("10.0.0.1");
+    private static final Ip4Address BGP_SESSION_IP_ADDRESS =
+        Ip4Address.valueOf("20.0.0.1");
+
+    private BgpSession bgpSession2;
+    private static final Ip4Address BGP_SESSION_BGP_ID2 =
+        Ip4Address.valueOf("10.0.0.2");
+    private static final Ip4Address BGP_SESSION_IP_ADDRESS2 =
+        Ip4Address.valueOf("20.0.0.1");
+
+    private BgpSession bgpSession3;
+    private static final Ip4Address BGP_SESSION_BGP_ID3 =
+        Ip4Address.valueOf("10.0.0.1");
+    private static final Ip4Address BGP_SESSION_IP_ADDRESS3 =
+        Ip4Address.valueOf("20.0.0.2");
+
+    private final BgpSessionInfo localInfo = new BgpSessionInfo();
+    private final BgpSessionInfo remoteInfo = new BgpSessionInfo();
+
+    private final BgpSessionInfo localInfo2 = new BgpSessionInfo();
+    private final BgpSessionInfo remoteInfo2 = new BgpSessionInfo();
+
+    private final BgpSessionInfo localInfo3 = new BgpSessionInfo();
+    private final BgpSessionInfo remoteInfo3 = new BgpSessionInfo();
+
+    @Before
+    public void setUp() throws Exception {
+        // Mock objects for testing
+        bgpSession = EasyMock.createMock(BgpSession.class);
+        bgpSession2 = EasyMock.createMock(BgpSession.class);
+        bgpSession3 = EasyMock.createMock(BgpSession.class);
+
+        // Setup the BGP Sessions
+        remoteInfo.setIp4Address(BGP_SESSION_IP_ADDRESS);
+        remoteInfo2.setIp4Address(BGP_SESSION_IP_ADDRESS2);
+        remoteInfo3.setIp4Address(BGP_SESSION_IP_ADDRESS3);
+        remoteInfo.setBgpId(BGP_SESSION_BGP_ID);
+        remoteInfo2.setBgpId(BGP_SESSION_BGP_ID2);
+        remoteInfo3.setBgpId(BGP_SESSION_BGP_ID3);
+
+        EasyMock.expect(bgpSession.localInfo()).andReturn(localInfo).anyTimes();
+        EasyMock.expect(bgpSession.remoteInfo()).andReturn(remoteInfo).anyTimes();
+        EasyMock.expect(bgpSession2.localInfo()).andReturn(localInfo2).anyTimes();
+        EasyMock.expect(bgpSession2.remoteInfo()).andReturn(remoteInfo2).anyTimes();
+        EasyMock.expect(bgpSession3.localInfo()).andReturn(localInfo3).anyTimes();
+        EasyMock.expect(bgpSession3.remoteInfo()).andReturn(remoteInfo3).anyTimes();
+
+        EasyMock.replay(bgpSession);
+        EasyMock.replay(bgpSession2);
+        EasyMock.replay(bgpSession3);
+    }
+
+    /**
+     * Generates a BGP Route Entry.
+     *
+     * @return a generated BGP Route Entry
+     */
+    private BgpRouteEntry generateBgpRouteEntry() {
+        Ip4Prefix prefix = Ip4Prefix.valueOf("1.2.3.0/24");
+        Ip4Address nextHop = Ip4Address.valueOf("5.6.7.8");
+        byte origin = BgpConstants.Update.Origin.IGP;
+        // Setup the AS Path
+        ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>();
+        byte pathSegmentType1 = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE;
+        ArrayList<Long> segmentAsNumbers1 = new ArrayList<>();
+        segmentAsNumbers1.add((long) 1);
+        segmentAsNumbers1.add((long) 2);
+        segmentAsNumbers1.add((long) 3);
+        BgpRouteEntry.PathSegment pathSegment1 =
+            new BgpRouteEntry.PathSegment(pathSegmentType1, segmentAsNumbers1);
+        pathSegments.add(pathSegment1);
+        //
+        byte pathSegmentType2 = (byte) BgpConstants.Update.AsPath.AS_SET;
+        ArrayList<Long> segmentAsNumbers2 = new ArrayList<>();
+        segmentAsNumbers2.add((long) 4);
+        segmentAsNumbers2.add((long) 5);
+        segmentAsNumbers2.add((long) 6);
+        BgpRouteEntry.PathSegment pathSegment2 =
+            new BgpRouteEntry.PathSegment(pathSegmentType2, segmentAsNumbers2);
+        pathSegments.add(pathSegment2);
+        //
+        BgpRouteEntry.AsPath asPath = new BgpRouteEntry.AsPath(pathSegments);
+        //
+        long localPref = 100;
+        long multiExitDisc = 20;
+
+        BgpRouteEntry bgpRouteEntry =
+            new BgpRouteEntry(bgpSession, prefix, nextHop, origin, asPath,
+                              localPref);
+        bgpRouteEntry.setMultiExitDisc(multiExitDisc);
+
+        return bgpRouteEntry;
+    }
+
+    /**
+     * Tests valid class constructor.
+     */
+    @Test
+    public void testConstructor() {
+        BgpRouteEntry bgpRouteEntry = generateBgpRouteEntry();
+
+        String expectedString =
+            "BgpRouteEntry{prefix=1.2.3.0/24, nextHop=5.6.7.8, " +
+            "bgpId=10.0.0.1, origin=IGP, asPath=AsPath{pathSegments=" +
+            "[PathSegment{type=AS_SEQUENCE, segmentAsNumbers=[1, 2, 3]}, " +
+            "PathSegment{type=AS_SET, segmentAsNumbers=[4, 5, 6]}]}, " +
+            "localPref=100, multiExitDisc=20}";
+        assertThat(bgpRouteEntry.toString(), is(expectedString));
+    }
+
+    /**
+     * Tests invalid class constructor for null BGP Session.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testInvalidConstructorNullBgpSession() {
+        BgpSession bgpSessionNull = null;
+        Ip4Prefix prefix = Ip4Prefix.valueOf("1.2.3.0/24");
+        Ip4Address nextHop = Ip4Address.valueOf("5.6.7.8");
+        byte origin = BgpConstants.Update.Origin.IGP;
+        // Setup the AS Path
+        ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>();
+        BgpRouteEntry.AsPath asPath = new BgpRouteEntry.AsPath(pathSegments);
+        //
+        long localPref = 100;
+
+        new BgpRouteEntry(bgpSessionNull, prefix, nextHop, origin, asPath,
+                    localPref);
+    }
+
+    /**
+     * Tests invalid class constructor for null AS Path.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testInvalidConstructorNullAsPath() {
+        Ip4Prefix prefix = Ip4Prefix.valueOf("1.2.3.0/24");
+        Ip4Address nextHop = Ip4Address.valueOf("5.6.7.8");
+        byte origin = BgpConstants.Update.Origin.IGP;
+        BgpRouteEntry.AsPath asPath = null;
+        long localPref = 100;
+
+        new BgpRouteEntry(bgpSession, prefix, nextHop, origin, asPath,
+                    localPref);
+    }
+
+    /**
+     * Tests getting the fields of a BGP route entry.
+     */
+    @Test
+    public void testGetFields() {
+        // Create the fields to compare against
+        Ip4Prefix prefix = Ip4Prefix.valueOf("1.2.3.0/24");
+        Ip4Address nextHop = Ip4Address.valueOf("5.6.7.8");
+        byte origin = BgpConstants.Update.Origin.IGP;
+        // Setup the AS Path
+        ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>();
+        byte pathSegmentType1 = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE;
+        ArrayList<Long> segmentAsNumbers1 = new ArrayList<>();
+        segmentAsNumbers1.add((long) 1);
+        segmentAsNumbers1.add((long) 2);
+        segmentAsNumbers1.add((long) 3);
+        BgpRouteEntry.PathSegment pathSegment1 =
+            new BgpRouteEntry.PathSegment(pathSegmentType1, segmentAsNumbers1);
+        pathSegments.add(pathSegment1);
+        //
+        byte pathSegmentType2 = (byte) BgpConstants.Update.AsPath.AS_SET;
+        ArrayList<Long> segmentAsNumbers2 = new ArrayList<>();
+        segmentAsNumbers2.add((long) 4);
+        segmentAsNumbers2.add((long) 5);
+        segmentAsNumbers2.add((long) 6);
+        BgpRouteEntry.PathSegment pathSegment2 =
+            new BgpRouteEntry.PathSegment(pathSegmentType2, segmentAsNumbers2);
+        pathSegments.add(pathSegment2);
+        //
+        BgpRouteEntry.AsPath asPath = new BgpRouteEntry.AsPath(pathSegments);
+        //
+        long localPref = 100;
+        long multiExitDisc = 20;
+
+        // Generate the entry to test
+        BgpRouteEntry bgpRouteEntry = generateBgpRouteEntry();
+
+        assertThat(bgpRouteEntry.prefix(), is(prefix));
+        assertThat(bgpRouteEntry.nextHop(), is(nextHop));
+        assertThat(bgpRouteEntry.getBgpSession(), is(bgpSession));
+        assertThat(bgpRouteEntry.getOrigin(), is(origin));
+        assertThat(bgpRouteEntry.getAsPath(), is(asPath));
+        assertThat(bgpRouteEntry.getLocalPref(), is(localPref));
+        assertThat(bgpRouteEntry.getMultiExitDisc(), is(multiExitDisc));
+    }
+
+    /**
+     * Tests whether a BGP route entry is a local route.
+     */
+    @Test
+    public void testIsLocalRoute() {
+        //
+        // Test non-local route
+        //
+        BgpRouteEntry bgpRouteEntry = generateBgpRouteEntry();
+        assertThat(bgpRouteEntry.isLocalRoute(), is(false));
+
+        //
+        // Test local route with AS Path that begins with AS_SET
+        //
+        Ip4Prefix prefix = Ip4Prefix.valueOf("1.2.3.0/24");
+        Ip4Address nextHop = Ip4Address.valueOf("5.6.7.8");
+        byte origin = BgpConstants.Update.Origin.IGP;
+        // Setup the AS Path
+        ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>();
+        byte pathSegmentType1 = (byte) BgpConstants.Update.AsPath.AS_SET;
+        ArrayList<Long> segmentAsNumbers1 = new ArrayList<>();
+        segmentAsNumbers1.add((long) 1);
+        segmentAsNumbers1.add((long) 2);
+        segmentAsNumbers1.add((long) 3);
+        BgpRouteEntry.PathSegment pathSegment1 =
+            new BgpRouteEntry.PathSegment(pathSegmentType1, segmentAsNumbers1);
+        pathSegments.add(pathSegment1);
+        //
+        byte pathSegmentType2 = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE;
+        ArrayList<Long> segmentAsNumbers2 = new ArrayList<>();
+        segmentAsNumbers2.add((long) 4);
+        segmentAsNumbers2.add((long) 5);
+        segmentAsNumbers2.add((long) 6);
+        BgpRouteEntry.PathSegment pathSegment2 =
+            new BgpRouteEntry.PathSegment(pathSegmentType2, segmentAsNumbers2);
+        pathSegments.add(pathSegment2);
+        //
+        BgpRouteEntry.AsPath asPath = new BgpRouteEntry.AsPath(pathSegments);
+        //
+        long localPref = 100;
+        long multiExitDisc = 20;
+        //
+        bgpRouteEntry =
+            new BgpRouteEntry(bgpSession, prefix, nextHop, origin, asPath,
+                              localPref);
+        bgpRouteEntry.setMultiExitDisc(multiExitDisc);
+        assertThat(bgpRouteEntry.isLocalRoute(), is(true));
+
+        //
+        // Test local route with empty AS Path
+        //
+        pathSegments = new ArrayList<>();
+        asPath = new BgpRouteEntry.AsPath(pathSegments);
+        bgpRouteEntry =
+            new BgpRouteEntry(bgpSession, prefix, nextHop, origin, asPath,
+                              localPref);
+        bgpRouteEntry.setMultiExitDisc(multiExitDisc);
+        assertThat(bgpRouteEntry.isLocalRoute(), is(true));
+    }
+
+    /**
+     * Tests getting the BGP Neighbor AS number for a route.
+     */
+    @Test
+    public void testGetNeighborAs() {
+        //
+        // Get neighbor AS for non-local route
+        //
+        BgpRouteEntry bgpRouteEntry = generateBgpRouteEntry();
+        assertThat(bgpRouteEntry.getNeighborAs(), is((long) 1));
+
+        //
+        // Get neighbor AS for a local route
+        //
+        Ip4Prefix prefix = Ip4Prefix.valueOf("1.2.3.0/24");
+        Ip4Address nextHop = Ip4Address.valueOf("5.6.7.8");
+        byte origin = BgpConstants.Update.Origin.IGP;
+        // Setup the AS Path
+        ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>();
+        BgpRouteEntry.AsPath asPath = new BgpRouteEntry.AsPath(pathSegments);
+        //
+        long localPref = 100;
+        long multiExitDisc = 20;
+        //
+        bgpRouteEntry =
+            new BgpRouteEntry(bgpSession, prefix, nextHop, origin, asPath,
+                              localPref);
+        bgpRouteEntry.setMultiExitDisc(multiExitDisc);
+        assertThat(bgpRouteEntry.getNeighborAs(), is(BgpConstants.BGP_AS_0));
+    }
+
+    /**
+     * Tests whether a BGP route entry has AS Path loop.
+     */
+    @Test
+    public void testHasAsPathLoop() {
+        BgpRouteEntry bgpRouteEntry = generateBgpRouteEntry();
+
+        // Test for loops: test each AS number in the interval [1, 6]
+        for (int i = 1; i <= 6; i++) {
+            assertThat(bgpRouteEntry.hasAsPathLoop(i), is(true));
+        }
+
+        // Test for non-loops
+        assertThat(bgpRouteEntry.hasAsPathLoop(500), is(false));
+    }
+
+    /**
+     * Tests the BGP Decision Process comparison of BGP routes.
+     */
+    @Test
+    public void testBgpDecisionProcessComparison() {
+        BgpRouteEntry bgpRouteEntry1 = generateBgpRouteEntry();
+        BgpRouteEntry bgpRouteEntry2 = generateBgpRouteEntry();
+
+        //
+        // Compare two routes that are same
+        //
+        assertThat(bgpRouteEntry1.isBetterThan(bgpRouteEntry2), is(true));
+        assertThat(bgpRouteEntry2.isBetterThan(bgpRouteEntry1), is(true));
+
+        //
+        // Compare two routes with different LOCAL_PREF
+        //
+        Ip4Prefix prefix = Ip4Prefix.valueOf("1.2.3.0/24");
+        Ip4Address nextHop = Ip4Address.valueOf("5.6.7.8");
+        byte origin = BgpConstants.Update.Origin.IGP;
+        // Setup the AS Path
+        ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>();
+        byte pathSegmentType1 = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE;
+        ArrayList<Long> segmentAsNumbers1 = new ArrayList<>();
+        segmentAsNumbers1.add((long) 1);
+        segmentAsNumbers1.add((long) 2);
+        segmentAsNumbers1.add((long) 3);
+        BgpRouteEntry.PathSegment pathSegment1 =
+            new BgpRouteEntry.PathSegment(pathSegmentType1, segmentAsNumbers1);
+        pathSegments.add(pathSegment1);
+        //
+        byte pathSegmentType2 = (byte) BgpConstants.Update.AsPath.AS_SET;
+        ArrayList<Long> segmentAsNumbers2 = new ArrayList<>();
+        segmentAsNumbers2.add((long) 4);
+        segmentAsNumbers2.add((long) 5);
+        segmentAsNumbers2.add((long) 6);
+        BgpRouteEntry.PathSegment pathSegment2 =
+            new BgpRouteEntry.PathSegment(pathSegmentType2, segmentAsNumbers2);
+        pathSegments.add(pathSegment2);
+        //
+        BgpRouteEntry.AsPath asPath = new BgpRouteEntry.AsPath(pathSegments);
+        //
+        long localPref = 50;                                    // Different
+        long multiExitDisc = 20;
+        bgpRouteEntry2 =
+            new BgpRouteEntry(bgpSession, prefix, nextHop, origin, asPath,
+                              localPref);
+        bgpRouteEntry2.setMultiExitDisc(multiExitDisc);
+        //
+        assertThat(bgpRouteEntry1.isBetterThan(bgpRouteEntry2), is(true));
+        assertThat(bgpRouteEntry2.isBetterThan(bgpRouteEntry1), is(false));
+        localPref = bgpRouteEntry1.getLocalPref();              // Restore
+
+        //
+        // Compare two routes with different AS_PATH length
+        //
+        ArrayList<BgpRouteEntry.PathSegment> pathSegments2 = new ArrayList<>();
+        pathSegments2.add(pathSegment1);
+        // Different AS Path
+        BgpRouteEntry.AsPath asPath2 = new BgpRouteEntry.AsPath(pathSegments2);
+        bgpRouteEntry2 =
+            new BgpRouteEntry(bgpSession, prefix, nextHop, origin, asPath2,
+                              localPref);
+        bgpRouteEntry2.setMultiExitDisc(multiExitDisc);
+        //
+        assertThat(bgpRouteEntry1.isBetterThan(bgpRouteEntry2), is(false));
+        assertThat(bgpRouteEntry2.isBetterThan(bgpRouteEntry1), is(true));
+
+        //
+        // Compare two routes with different ORIGIN
+        //
+        origin = BgpConstants.Update.Origin.EGP;                // Different
+        bgpRouteEntry2 =
+            new BgpRouteEntry(bgpSession, prefix, nextHop, origin, asPath,
+                              localPref);
+        bgpRouteEntry2.setMultiExitDisc(multiExitDisc);
+        //
+        assertThat(bgpRouteEntry1.isBetterThan(bgpRouteEntry2), is(true));
+        assertThat(bgpRouteEntry2.isBetterThan(bgpRouteEntry1), is(false));
+        origin = bgpRouteEntry1.getOrigin();                    // Restore
+
+        //
+        // Compare two routes with different MULTI_EXIT_DISC
+        //
+        multiExitDisc = 10;                                     // Different
+        bgpRouteEntry2 =
+            new BgpRouteEntry(bgpSession, prefix, nextHop, origin, asPath,
+                              localPref);
+        bgpRouteEntry2.setMultiExitDisc(multiExitDisc);
+        //
+        assertThat(bgpRouteEntry1.isBetterThan(bgpRouteEntry2), is(true));
+        assertThat(bgpRouteEntry2.isBetterThan(bgpRouteEntry1), is(false));
+        multiExitDisc = bgpRouteEntry1.getMultiExitDisc();      // Restore
+
+        //
+        // Compare two routes with different BGP ID
+        //
+        bgpRouteEntry2 =
+            new BgpRouteEntry(bgpSession2, prefix, nextHop, origin, asPath,
+                              localPref);
+        bgpRouteEntry2.setMultiExitDisc(multiExitDisc);
+        //
+        assertThat(bgpRouteEntry1.isBetterThan(bgpRouteEntry2), is(true));
+        assertThat(bgpRouteEntry2.isBetterThan(bgpRouteEntry1), is(false));
+
+        //
+        // Compare two routes with different BGP address
+        //
+        bgpRouteEntry2 =
+            new BgpRouteEntry(bgpSession3, prefix, nextHop, origin, asPath,
+                              localPref);
+        bgpRouteEntry2.setMultiExitDisc(multiExitDisc);
+        //
+        assertThat(bgpRouteEntry1.isBetterThan(bgpRouteEntry2), is(true));
+        assertThat(bgpRouteEntry2.isBetterThan(bgpRouteEntry1), is(false));
+    }
+
+    /**
+     * Tests equality of {@link BgpRouteEntry}.
+     */
+    @Test
+    public void testEquality() {
+        BgpRouteEntry bgpRouteEntry1 = generateBgpRouteEntry();
+        BgpRouteEntry bgpRouteEntry2 = generateBgpRouteEntry();
+
+        assertThat(bgpRouteEntry1, is(bgpRouteEntry2));
+    }
+
+    /**
+     * Tests non-equality of {@link BgpRouteEntry}.
+     */
+    @Test
+    public void testNonEquality() {
+        BgpRouteEntry bgpRouteEntry1 = generateBgpRouteEntry();
+
+        // Setup BGP Route 2
+        Ip4Prefix prefix = Ip4Prefix.valueOf("1.2.3.0/24");
+        Ip4Address nextHop = Ip4Address.valueOf("5.6.7.8");
+        byte origin = BgpConstants.Update.Origin.IGP;
+        // Setup the AS Path
+        ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>();
+        byte pathSegmentType1 = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE;
+        ArrayList<Long> segmentAsNumbers1 = new ArrayList<>();
+        segmentAsNumbers1.add((long) 1);
+        segmentAsNumbers1.add((long) 2);
+        segmentAsNumbers1.add((long) 3);
+        BgpRouteEntry.PathSegment pathSegment1 =
+            new BgpRouteEntry.PathSegment(pathSegmentType1, segmentAsNumbers1);
+        pathSegments.add(pathSegment1);
+        //
+        byte pathSegmentType2 = (byte) BgpConstants.Update.AsPath.AS_SET;
+        ArrayList<Long> segmentAsNumbers2 = new ArrayList<>();
+        segmentAsNumbers2.add((long) 4);
+        segmentAsNumbers2.add((long) 5);
+        segmentAsNumbers2.add((long) 6);
+        BgpRouteEntry.PathSegment pathSegment2 =
+            new BgpRouteEntry.PathSegment(pathSegmentType2, segmentAsNumbers2);
+        pathSegments.add(pathSegment2);
+        //
+        BgpRouteEntry.AsPath asPath = new BgpRouteEntry.AsPath(pathSegments);
+        //
+        long localPref = 500;                                   // Different
+        long multiExitDisc = 20;
+        BgpRouteEntry bgpRouteEntry2 =
+            new BgpRouteEntry(bgpSession, prefix, nextHop, origin, asPath,
+                              localPref);
+        bgpRouteEntry2.setMultiExitDisc(multiExitDisc);
+
+        assertThat(bgpRouteEntry1, Matchers.is(not(bgpRouteEntry2)));
+    }
+
+    /**
+     * Tests object string representation.
+     */
+    @Test
+    public void testToString() {
+        BgpRouteEntry bgpRouteEntry = generateBgpRouteEntry();
+
+        String expectedString =
+            "BgpRouteEntry{prefix=1.2.3.0/24, nextHop=5.6.7.8, " +
+            "bgpId=10.0.0.1, origin=IGP, asPath=AsPath{pathSegments=" +
+            "[PathSegment{type=AS_SEQUENCE, segmentAsNumbers=[1, 2, 3]}, " +
+            "PathSegment{type=AS_SET, segmentAsNumbers=[4, 5, 6]}]}, " +
+            "localPref=100, multiExitDisc=20}";
+        assertThat(bgpRouteEntry.toString(), is(expectedString));
+    }
+}
diff --git a/apps/routing/src/test/java/org/onosproject/routing/bgp/BgpSessionManagerTest.java b/apps/routing/src/test/java/org/onosproject/routing/bgp/BgpSessionManagerTest.java
new file mode 100644
index 0000000..c73eaff
--- /dev/null
+++ b/apps/routing/src/test/java/org/onosproject/routing/bgp/BgpSessionManagerTest.java
@@ -0,0 +1,876 @@
+/*
+ * Copyright 2014 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 com.google.common.net.InetAddresses;
+import org.hamcrest.Description;
+import org.hamcrest.TypeSafeMatcher;
+import org.jboss.netty.bootstrap.ClientBootstrap;
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.jboss.netty.channel.Channel;
+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.socket.nio.NioClientSocketChannelFactory;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.junit.TestUtils;
+import org.onlab.junit.TestUtils.TestUtilsException;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip4Prefix;
+import org.onosproject.routingapi.RouteListener;
+import org.onosproject.routingapi.RouteUpdate;
+
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+import static org.hamcrest.Matchers.hasSize;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.junit.Assert.assertThat;
+
+/**
+ * Unit tests for the BgpSessionManager class.
+ */
+public class BgpSessionManagerTest {
+    private static final Ip4Address IP_LOOPBACK_ID =
+        Ip4Address.valueOf("127.0.0.1");
+    private static final Ip4Address BGP_PEER1_ID =
+        Ip4Address.valueOf("10.0.0.1");
+    private static final Ip4Address BGP_PEER2_ID =
+        Ip4Address.valueOf("10.0.0.2");
+    private static final Ip4Address BGP_PEER3_ID =
+        Ip4Address.valueOf("10.0.0.3");
+    private static final Ip4Address NEXT_HOP1_ROUTER =
+        Ip4Address.valueOf("10.20.30.41");
+    private static final Ip4Address NEXT_HOP2_ROUTER =
+        Ip4Address.valueOf("10.20.30.42");
+    private static final Ip4Address NEXT_HOP3_ROUTER =
+        Ip4Address.valueOf("10.20.30.43");
+
+    private static final long DEFAULT_LOCAL_PREF = 10;
+    private static final long BETTER_LOCAL_PREF = 20;
+    private static final long DEFAULT_MULTI_EXIT_DISC = 20;
+    private static final long BETTER_MULTI_EXIT_DISC = 30;
+
+    BgpRouteEntry.AsPath asPathShort;
+    BgpRouteEntry.AsPath asPathLong;
+
+    // Timeout waiting for a message to be received
+    private static final int MESSAGE_TIMEOUT_MS = 5000; // 5s
+
+    // The BGP Session Manager to test
+    private BgpSessionManager bgpSessionManager;
+
+    // Remote Peer state
+    private final Collection<TestBgpPeer> peers = new LinkedList<>();
+    TestBgpPeer peer1;
+    TestBgpPeer peer2;
+    TestBgpPeer peer3;
+
+    // Local BGP per-peer session state
+    BgpSession bgpSession1;
+    BgpSession bgpSession2;
+    BgpSession bgpSession3;
+
+    // The socket that the remote peers should connect to
+    private InetSocketAddress connectToSocket;
+
+    private final DummyRouteListener dummyRouteListener =
+        new DummyRouteListener();
+
+    /**
+     * Dummy implementation for the RouteListener interface.
+     */
+    private class DummyRouteListener implements RouteListener {
+        @Override
+        public void update(Collection<RouteUpdate> routeUpdate) {
+            // Nothing to do
+        }
+    }
+
+    /**
+     * A class to capture the state for a BGP peer.
+     */
+    private final class TestBgpPeer {
+        private final Ip4Address peerId;
+        private ClientBootstrap peerBootstrap;
+        private TestBgpPeerChannelHandler peerChannelHandler;
+        private TestBgpPeerFrameDecoder peerFrameDecoder =
+            new TestBgpPeerFrameDecoder();
+
+        /**
+         * Constructor.
+         *
+         * @param peerId the peer ID
+         */
+        private TestBgpPeer(Ip4Address peerId) {
+            this.peerId = peerId;
+            peerChannelHandler = new TestBgpPeerChannelHandler(peerId);
+        }
+
+        /**
+         * Starts up the BGP peer and connects it to the tested SDN-IP
+         * instance.
+         *
+         * @param connectToSocket the socket to connect to
+         */
+        private void connect(InetSocketAddress connectToSocket)
+            throws InterruptedException {
+            //
+            // Setup the BGP Peer, i.e., the "remote" BGP router that will
+            // initiate the BGP connection, send BGP UPDATE messages, etc.
+            //
+            ChannelFactory channelFactory =
+                new NioClientSocketChannelFactory(
+                        Executors.newCachedThreadPool(),
+                        Executors.newCachedThreadPool());
+            ChannelPipelineFactory pipelineFactory =
+                new ChannelPipelineFactory() {
+                    @Override
+                    public ChannelPipeline getPipeline() throws Exception {
+                        // Setup the transmitting pipeline
+                        ChannelPipeline pipeline = Channels.pipeline();
+                        pipeline.addLast("TestBgpPeerFrameDecoder",
+                                         peerFrameDecoder);
+                        pipeline.addLast("TestBgpPeerChannelHandler",
+                                         peerChannelHandler);
+                        return pipeline;
+                    }
+                };
+
+            peerBootstrap = new ClientBootstrap(channelFactory);
+            peerBootstrap.setOption("child.keepAlive", true);
+            peerBootstrap.setOption("child.tcpNoDelay", true);
+            peerBootstrap.setPipelineFactory(pipelineFactory);
+            peerBootstrap.connect(connectToSocket);
+
+            boolean result;
+            // Wait until the OPEN message is received
+            result = peerFrameDecoder.receivedOpenMessageLatch.await(
+                MESSAGE_TIMEOUT_MS,
+                TimeUnit.MILLISECONDS);
+            assertThat(result, is(true));
+            // Wait until the KEEPALIVE message is received
+            result = peerFrameDecoder.receivedKeepaliveMessageLatch.await(
+                MESSAGE_TIMEOUT_MS,
+                TimeUnit.MILLISECONDS);
+            assertThat(result, is(true));
+
+            for (BgpSession bgpSession : bgpSessionManager.getBgpSessions()) {
+                if (bgpSession.remoteInfo().bgpId().equals(BGP_PEER1_ID)) {
+                    bgpSession1 = bgpSession;
+                }
+                if (bgpSession.remoteInfo().bgpId().equals(BGP_PEER2_ID)) {
+                    bgpSession2 = bgpSession;
+                }
+                if (bgpSession.remoteInfo().bgpId().equals(BGP_PEER3_ID)) {
+                    bgpSession3 = bgpSession;
+                }
+            }
+        }
+    }
+
+    /**
+     * Class that implements a matcher for BgpRouteEntry by considering
+     * the BGP peer the entry was received from.
+     */
+    private static final class BgpRouteEntryAndPeerMatcher
+        extends TypeSafeMatcher<Collection<BgpRouteEntry>> {
+        private final BgpRouteEntry bgpRouteEntry;
+
+        private BgpRouteEntryAndPeerMatcher(BgpRouteEntry bgpRouteEntry) {
+            this.bgpRouteEntry = bgpRouteEntry;
+        }
+
+        @Override
+        public boolean matchesSafely(Collection<BgpRouteEntry> entries) {
+            for (BgpRouteEntry entry : entries) {
+                if (bgpRouteEntry.equals(entry) &&
+                    bgpRouteEntry.getBgpSession() == entry.getBgpSession()) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        @Override
+        public void describeTo(Description description) {
+            description.appendText("BGP route entry lookup for entry \"").
+                appendText(bgpRouteEntry.toString()).
+                appendText("\"");
+        }
+    }
+
+    /**
+     * A helper method used for testing whether a collection of
+     * BGP route entries contains an entry from a specific BGP peer.
+     *
+     * @param bgpRouteEntry the BGP route entry to test
+     * @return an instance of BgpRouteEntryAndPeerMatcher that implements
+     * the matching logic
+     */
+    private static BgpRouteEntryAndPeerMatcher hasBgpRouteEntry(
+        BgpRouteEntry bgpRouteEntry) {
+        return new BgpRouteEntryAndPeerMatcher(bgpRouteEntry);
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        peer1 = new TestBgpPeer(BGP_PEER1_ID);
+        peer2 = new TestBgpPeer(BGP_PEER2_ID);
+        peer3 = new TestBgpPeer(BGP_PEER3_ID);
+        peers.clear();
+        peers.add(peer1);
+        peers.add(peer2);
+        peers.add(peer3);
+
+        //
+        // Setup the BGP Session Manager to test, and start listening for BGP
+        // connections.
+        //
+        bgpSessionManager = new BgpSessionManager();
+        // NOTE: We use port 0 to bind on any available port
+        bgpSessionManager.start(dummyRouteListener, 0);
+
+        // Get the port number the BGP Session Manager is listening on
+        Channel serverChannel = TestUtils.getField(bgpSessionManager,
+                                                   "serverChannel");
+        SocketAddress socketAddress = serverChannel.getLocalAddress();
+        InetSocketAddress inetSocketAddress =
+            (InetSocketAddress) socketAddress;
+        InetAddress connectToAddress = InetAddresses.forString("127.0.0.1");
+        connectToSocket = new InetSocketAddress(connectToAddress,
+                                                inetSocketAddress.getPort());
+
+        //
+        // Setup the AS Paths
+        //
+        ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>();
+        byte pathSegmentType1 = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE;
+        ArrayList<Long> segmentAsNumbers1 = new ArrayList<>();
+        segmentAsNumbers1.add((long) 65010);
+        segmentAsNumbers1.add((long) 65020);
+        segmentAsNumbers1.add((long) 65030);
+        BgpRouteEntry.PathSegment pathSegment1 =
+            new BgpRouteEntry.PathSegment(pathSegmentType1, segmentAsNumbers1);
+        pathSegments.add(pathSegment1);
+        asPathShort = new BgpRouteEntry.AsPath(new ArrayList(pathSegments));
+        //
+        byte pathSegmentType2 = (byte) BgpConstants.Update.AsPath.AS_SET;
+        ArrayList<Long> segmentAsNumbers2 = new ArrayList<>();
+        segmentAsNumbers2.add((long) 65041);
+        segmentAsNumbers2.add((long) 65042);
+        segmentAsNumbers2.add((long) 65043);
+        BgpRouteEntry.PathSegment pathSegment2 =
+            new BgpRouteEntry.PathSegment(pathSegmentType2, segmentAsNumbers2);
+        pathSegments.add(pathSegment2);
+        //
+        asPathLong = new BgpRouteEntry.AsPath(pathSegments);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        bgpSessionManager.stop();
+        bgpSessionManager = null;
+    }
+
+    /**
+     * Gets BGP RIB-IN routes by waiting until they are received.
+     * <p>
+     * NOTE: We keep checking once every 10ms the number of received routes,
+     * up to 5 seconds.
+     * </p>
+     *
+     * @param bgpSession the BGP session that is expected to receive the
+     * routes
+     * @param expectedRoutes the expected number of routes
+     * @return the BGP RIB-IN routes as received within the expected
+     * time interval
+     */
+    private Collection<BgpRouteEntry> waitForBgpRibIn(BgpSession bgpSession,
+                                                      long expectedRoutes)
+        throws InterruptedException {
+        Collection<BgpRouteEntry> bgpRibIn = bgpSession.getBgpRibIn4();
+
+        final int maxChecks = 500;              // Max wait of 5 seconds
+        for (int i = 0; i < maxChecks; i++) {
+            if (bgpRibIn.size() == expectedRoutes) {
+                break;
+            }
+            Thread.sleep(10);
+            bgpRibIn = bgpSession.getBgpRibIn4();
+        }
+
+        return bgpRibIn;
+    }
+
+    /**
+     * Gets BGP merged routes by waiting until they are received.
+     * <p>
+     * NOTE: We keep checking once every 10ms the number of received routes,
+     * up to 5 seconds.
+     * </p>
+     *
+     * @param expectedRoutes the expected number of routes
+     * @return the BGP Session Manager routes as received within the expected
+     * time interval
+     */
+    private Collection<BgpRouteEntry> waitForBgpRoutes(long expectedRoutes)
+        throws InterruptedException {
+        Collection<BgpRouteEntry> bgpRoutes =
+            bgpSessionManager.getBgpRoutes4();
+
+        final int maxChecks = 500;              // Max wait of 5 seconds
+        for (int i = 0; i < maxChecks; i++) {
+            if (bgpRoutes.size() == expectedRoutes) {
+                break;
+            }
+            Thread.sleep(10);
+            bgpRoutes = bgpSessionManager.getBgpRoutes4();
+        }
+
+        return bgpRoutes;
+    }
+
+    /**
+     * Gets a merged BGP route by waiting until it is received.
+     * <p>
+     * NOTE: We keep checking once every 10ms whether the route is received,
+     * up to 5 seconds.
+     * </p>
+     *
+     * @param expectedRoute the expected route
+     * @return the merged BGP route if received within the expected time
+     * interval, otherwise null
+     */
+    private BgpRouteEntry waitForBgpRoute(BgpRouteEntry expectedRoute)
+        throws InterruptedException {
+        Collection<BgpRouteEntry> bgpRoutes =
+            bgpSessionManager.getBgpRoutes4();
+
+        final int maxChecks = 500;              // Max wait of 5 seconds
+        for (int i = 0; i < maxChecks; i++) {
+            for (BgpRouteEntry bgpRouteEntry : bgpRoutes) {
+                if (bgpRouteEntry.equals(expectedRoute) &&
+                    bgpRouteEntry.getBgpSession() ==
+                    expectedRoute.getBgpSession()) {
+                    return bgpRouteEntry;
+                }
+            }
+            Thread.sleep(10);
+            bgpRoutes = bgpSessionManager.getBgpRoutes4();
+        }
+
+        return null;
+    }
+
+    /**
+     * Tests that the BGP OPEN messages have been exchanged, followed by
+     * KEEPALIVE.
+     * <p>
+     * The BGP Peer opens the sessions and transmits OPEN Message, eventually
+     * followed by KEEPALIVE. The tested BGP listener should respond by
+     * OPEN Message, followed by KEEPALIVE.
+     * </p>
+     *
+     * @throws TestUtilsException TestUtils error
+     */
+    @Test
+    public void testExchangedBgpOpenMessages()
+            throws InterruptedException, TestUtilsException {
+        // Initiate the connections
+        peer1.connect(connectToSocket);
+        peer2.connect(connectToSocket);
+        peer3.connect(connectToSocket);
+
+        //
+        // Test the fields from the BGP OPEN message:
+        // BGP version, AS number, BGP ID
+        //
+        for (TestBgpPeer peer : peers) {
+            assertThat(peer.peerFrameDecoder.remoteInfo.bgpVersion(),
+                       is(BgpConstants.BGP_VERSION));
+            assertThat(peer.peerFrameDecoder.remoteInfo.bgpId(),
+                       is(IP_LOOPBACK_ID));
+            assertThat(peer.peerFrameDecoder.remoteInfo.asNumber(),
+                       is(TestBgpPeerChannelHandler.PEER_AS));
+        }
+
+        //
+        // Test that the BgpSession instances have been created
+        //
+        assertThat(bgpSessionManager.getMyBgpId(), is(IP_LOOPBACK_ID));
+        assertThat(bgpSessionManager.getBgpSessions(), hasSize(3));
+        assertThat(bgpSession1, notNullValue());
+        assertThat(bgpSession2, notNullValue());
+        assertThat(bgpSession3, notNullValue());
+        for (BgpSession bgpSession : bgpSessionManager.getBgpSessions()) {
+            long sessionAs = bgpSession.localInfo().asNumber();
+            assertThat(sessionAs, is(TestBgpPeerChannelHandler.PEER_AS));
+        }
+    }
+
+
+    /**
+     * Tests that the BGP OPEN with Capability messages have been exchanged,
+     * followed by KEEPALIVE.
+     * <p>
+     * The BGP Peer opens the sessions and transmits OPEN Message, eventually
+     * followed by KEEPALIVE. The tested BGP listener should respond by
+     * OPEN Message, followed by KEEPALIVE.
+     * </p>
+     *
+     * @throws TestUtilsException TestUtils error
+     */
+    @Test
+    public void testExchangedBgpOpenCapabilityMessages()
+            throws InterruptedException, TestUtilsException {
+        //
+        // Setup the BGP Capabilities for all peers
+        //
+        for (TestBgpPeer peer : peers) {
+            peer.peerChannelHandler.localInfo.setIpv4Unicast();
+            peer.peerChannelHandler.localInfo.setIpv4Multicast();
+            peer.peerChannelHandler.localInfo.setIpv6Unicast();
+            peer.peerChannelHandler.localInfo.setIpv6Multicast();
+            peer.peerChannelHandler.localInfo.setAs4OctetCapability();
+            peer.peerChannelHandler.localInfo.setAs4Number(
+                TestBgpPeerChannelHandler.PEER_AS4);
+        }
+
+        // Initiate the connections
+        peer1.connect(connectToSocket);
+        peer2.connect(connectToSocket);
+        peer3.connect(connectToSocket);
+
+        //
+        // Test the fields from the BGP OPEN message:
+        // BGP version, BGP ID
+        //
+        for (TestBgpPeer peer : peers) {
+            assertThat(peer.peerFrameDecoder.remoteInfo.bgpVersion(),
+                       is(BgpConstants.BGP_VERSION));
+            assertThat(peer.peerFrameDecoder.remoteInfo.bgpId(),
+                       is(IP_LOOPBACK_ID));
+        }
+
+        //
+        // Test that the BgpSession instances have been created,
+        // and contain the appropriate BGP session information.
+        //
+        assertThat(bgpSessionManager.getMyBgpId(), is(IP_LOOPBACK_ID));
+        assertThat(bgpSessionManager.getBgpSessions(), hasSize(3));
+        assertThat(bgpSession1, notNullValue());
+        assertThat(bgpSession2, notNullValue());
+        assertThat(bgpSession3, notNullValue());
+        for (BgpSession bgpSession : bgpSessionManager.getBgpSessions()) {
+            BgpSessionInfo localInfo = bgpSession.localInfo();
+            assertThat(localInfo.ipv4Unicast(), is(true));
+            assertThat(localInfo.ipv4Multicast(), is(true));
+            assertThat(localInfo.ipv6Unicast(), is(true));
+            assertThat(localInfo.ipv6Multicast(), is(true));
+            assertThat(localInfo.as4OctetCapability(), is(true));
+            assertThat(localInfo.asNumber(),
+                       is(TestBgpPeerChannelHandler.PEER_AS4));
+            assertThat(localInfo.as4Number(),
+                       is(TestBgpPeerChannelHandler.PEER_AS4));
+        }
+    }
+
+    /**
+     * Tests that the BGP UPDATE messages have been received and processed.
+     */
+    @Test
+    public void testProcessedBgpUpdateMessages() throws InterruptedException {
+        ChannelBuffer message;
+        BgpRouteEntry bgpRouteEntry;
+        Collection<BgpRouteEntry> bgpRibIn1;
+        Collection<BgpRouteEntry> bgpRibIn2;
+        Collection<BgpRouteEntry> bgpRibIn3;
+        Collection<BgpRouteEntry> bgpRoutes;
+
+        // Initiate the connections
+        peer1.connect(connectToSocket);
+        peer2.connect(connectToSocket);
+        peer3.connect(connectToSocket);
+
+        // Prepare routes to add/delete
+        Collection<Ip4Prefix> addedRoutes = new LinkedList<>();
+        Collection<Ip4Prefix> withdrawnRoutes = new LinkedList<>();
+
+        //
+        // Add and delete some routes
+        //
+        addedRoutes.add(Ip4Prefix.valueOf("0.0.0.0/0"));
+        addedRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8"));
+        addedRoutes.add(Ip4Prefix.valueOf("30.0.0.0/16"));
+        addedRoutes.add(Ip4Prefix.valueOf("40.0.0.0/24"));
+        addedRoutes.add(Ip4Prefix.valueOf("50.0.0.0/32"));
+        withdrawnRoutes.add(Ip4Prefix.valueOf("60.0.0.0/8"));
+        withdrawnRoutes.add(Ip4Prefix.valueOf("70.0.0.0/16"));
+        withdrawnRoutes.add(Ip4Prefix.valueOf("80.0.0.0/24"));
+        withdrawnRoutes.add(Ip4Prefix.valueOf("90.0.0.0/32"));
+        // Write the routes
+        message = peer1.peerChannelHandler.prepareBgpUpdate(
+                        NEXT_HOP1_ROUTER,
+                        DEFAULT_LOCAL_PREF,
+                        DEFAULT_MULTI_EXIT_DISC,
+                        asPathLong,
+                        addedRoutes,
+                        withdrawnRoutes);
+        peer1.peerChannelHandler.savedCtx.getChannel().write(message);
+        //
+        // Check that the routes have been received, processed and stored
+        //
+        bgpRibIn1 = waitForBgpRibIn(bgpSession1, 5);
+        assertThat(bgpRibIn1, hasSize(5));
+        bgpRoutes = waitForBgpRoutes(5);
+        assertThat(bgpRoutes, hasSize(5));
+        //
+        bgpRouteEntry =
+            new BgpRouteEntry(bgpSession1,
+                              Ip4Prefix.valueOf("0.0.0.0/0"),
+                              NEXT_HOP1_ROUTER,
+                              (byte) BgpConstants.Update.Origin.IGP,
+                              asPathLong,
+                              DEFAULT_LOCAL_PREF);
+        bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
+        assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
+        assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
+        //
+        bgpRouteEntry =
+            new BgpRouteEntry(bgpSession1,
+                              Ip4Prefix.valueOf("20.0.0.0/8"),
+                              NEXT_HOP1_ROUTER,
+                              (byte) BgpConstants.Update.Origin.IGP,
+                              asPathLong,
+                              DEFAULT_LOCAL_PREF);
+        bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
+        assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
+        assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
+        //
+        bgpRouteEntry =
+            new BgpRouteEntry(bgpSession1,
+                              Ip4Prefix.valueOf("30.0.0.0/16"),
+                              NEXT_HOP1_ROUTER,
+                              (byte) BgpConstants.Update.Origin.IGP,
+                              asPathLong,
+                              DEFAULT_LOCAL_PREF);
+        bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
+        assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
+        assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
+        //
+        bgpRouteEntry =
+            new BgpRouteEntry(bgpSession1,
+                              Ip4Prefix.valueOf("40.0.0.0/24"),
+                              NEXT_HOP1_ROUTER,
+                              (byte) BgpConstants.Update.Origin.IGP,
+                              asPathLong,
+                              DEFAULT_LOCAL_PREF);
+        bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
+        assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
+        assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
+        //
+        bgpRouteEntry =
+            new BgpRouteEntry(bgpSession1,
+                              Ip4Prefix.valueOf("50.0.0.0/32"),
+                              NEXT_HOP1_ROUTER,
+                              (byte) BgpConstants.Update.Origin.IGP,
+                              asPathLong,
+                              DEFAULT_LOCAL_PREF);
+        bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
+        assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
+        assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
+
+        //
+        // Delete some routes
+        //
+        addedRoutes = new LinkedList<>();
+        withdrawnRoutes = new LinkedList<>();
+        withdrawnRoutes.add(Ip4Prefix.valueOf("0.0.0.0/0"));
+        withdrawnRoutes.add(Ip4Prefix.valueOf("50.0.0.0/32"));
+        // Write the routes
+        message = peer1.peerChannelHandler.prepareBgpUpdate(
+                        NEXT_HOP1_ROUTER,
+                        DEFAULT_LOCAL_PREF,
+                        DEFAULT_MULTI_EXIT_DISC,
+                        asPathLong,
+                        addedRoutes,
+                        withdrawnRoutes);
+        peer1.peerChannelHandler.savedCtx.getChannel().write(message);
+        //
+        // Check that the routes have been received, processed and stored
+        //
+        bgpRibIn1 = waitForBgpRibIn(bgpSession1, 3);
+        assertThat(bgpRibIn1, hasSize(3));
+        bgpRoutes = waitForBgpRoutes(3);
+        assertThat(bgpRoutes, hasSize(3));
+        //
+        bgpRouteEntry =
+            new BgpRouteEntry(bgpSession1,
+                              Ip4Prefix.valueOf("20.0.0.0/8"),
+                              NEXT_HOP1_ROUTER,
+                              (byte) BgpConstants.Update.Origin.IGP,
+                              asPathLong,
+                              DEFAULT_LOCAL_PREF);
+        bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
+        assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
+        assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
+        //
+        bgpRouteEntry =
+            new BgpRouteEntry(bgpSession1,
+                              Ip4Prefix.valueOf("30.0.0.0/16"),
+                              NEXT_HOP1_ROUTER,
+                              (byte) BgpConstants.Update.Origin.IGP,
+                              asPathLong,
+                              DEFAULT_LOCAL_PREF);
+        bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
+        assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
+        assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
+        //
+        bgpRouteEntry =
+            new BgpRouteEntry(bgpSession1,
+                              Ip4Prefix.valueOf("40.0.0.0/24"),
+                              NEXT_HOP1_ROUTER,
+                              (byte) BgpConstants.Update.Origin.IGP,
+                              asPathLong,
+                              DEFAULT_LOCAL_PREF);
+        bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
+        assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
+        assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
+
+
+        // Close the channels and test there are no routes
+        peer1.peerChannelHandler.closeChannel();
+        peer2.peerChannelHandler.closeChannel();
+        peer3.peerChannelHandler.closeChannel();
+        bgpRoutes = waitForBgpRoutes(0);
+        assertThat(bgpRoutes, hasSize(0));
+    }
+
+    /**
+     * Tests the BGP route preference.
+     */
+    @Test
+    public void testBgpRoutePreference() throws InterruptedException {
+        ChannelBuffer message;
+        BgpRouteEntry bgpRouteEntry;
+        Collection<BgpRouteEntry> bgpRibIn1;
+        Collection<BgpRouteEntry> bgpRibIn2;
+        Collection<BgpRouteEntry> bgpRibIn3;
+        Collection<BgpRouteEntry> bgpRoutes;
+        Collection<Ip4Prefix> addedRoutes = new LinkedList<>();
+        Collection<Ip4Prefix> withdrawnRoutes = new LinkedList<>();
+
+        // Initiate the connections
+        peer1.connect(connectToSocket);
+        peer2.connect(connectToSocket);
+        peer3.connect(connectToSocket);
+
+        //
+        // Setup the initial set of routes to Peer1
+        //
+        addedRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8"));
+        addedRoutes.add(Ip4Prefix.valueOf("30.0.0.0/16"));
+        // Write the routes
+        message = peer1.peerChannelHandler.prepareBgpUpdate(
+                        NEXT_HOP1_ROUTER,
+                        DEFAULT_LOCAL_PREF,
+                        DEFAULT_MULTI_EXIT_DISC,
+                        asPathLong,
+                        addedRoutes,
+                        withdrawnRoutes);
+        peer1.peerChannelHandler.savedCtx.getChannel().write(message);
+        bgpRoutes = waitForBgpRoutes(2);
+        assertThat(bgpRoutes, hasSize(2));
+
+        //
+        // Add a route entry to Peer2 with a better LOCAL_PREF
+        //
+        addedRoutes = new LinkedList<>();
+        withdrawnRoutes = new LinkedList<>();
+        addedRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8"));
+        // Write the routes
+        message = peer2.peerChannelHandler.prepareBgpUpdate(
+                        NEXT_HOP2_ROUTER,
+                        BETTER_LOCAL_PREF,
+                        DEFAULT_MULTI_EXIT_DISC,
+                        asPathLong,
+                        addedRoutes,
+                        withdrawnRoutes);
+        peer2.peerChannelHandler.savedCtx.getChannel().write(message);
+        //
+        // Check that the routes have been received, processed and stored
+        //
+        bgpRibIn2 = waitForBgpRibIn(bgpSession2, 1);
+        assertThat(bgpRibIn2, hasSize(1));
+        bgpRoutes = waitForBgpRoutes(2);
+        assertThat(bgpRoutes, hasSize(2));
+        //
+        bgpRouteEntry =
+            new BgpRouteEntry(bgpSession2,
+                              Ip4Prefix.valueOf("20.0.0.0/8"),
+                              NEXT_HOP2_ROUTER,
+                              (byte) BgpConstants.Update.Origin.IGP,
+                              asPathLong,
+                              BETTER_LOCAL_PREF);
+        bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
+        assertThat(bgpRibIn2, hasBgpRouteEntry(bgpRouteEntry));
+        assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
+
+        //
+        // Add a route entry to Peer3 with a shorter AS path
+        //
+        addedRoutes = new LinkedList<>();
+        withdrawnRoutes = new LinkedList<>();
+        addedRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8"));
+        // Write the routes
+        message = peer3.peerChannelHandler.prepareBgpUpdate(
+                        NEXT_HOP3_ROUTER,
+                        BETTER_LOCAL_PREF,
+                        DEFAULT_MULTI_EXIT_DISC,
+                        asPathShort,
+                        addedRoutes,
+                        withdrawnRoutes);
+        peer3.peerChannelHandler.savedCtx.getChannel().write(message);
+        //
+        // Check that the routes have been received, processed and stored
+        //
+        bgpRibIn3 = waitForBgpRibIn(bgpSession3, 1);
+        assertThat(bgpRibIn3, hasSize(1));
+        bgpRoutes = waitForBgpRoutes(2);
+        assertThat(bgpRoutes, hasSize(2));
+        //
+        bgpRouteEntry =
+            new BgpRouteEntry(bgpSession3,
+                              Ip4Prefix.valueOf("20.0.0.0/8"),
+                              NEXT_HOP3_ROUTER,
+                              (byte) BgpConstants.Update.Origin.IGP,
+                              asPathShort,
+                              BETTER_LOCAL_PREF);
+        bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
+        assertThat(bgpRibIn3, hasBgpRouteEntry(bgpRouteEntry));
+        assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
+
+        //
+        // Cleanup in preparation for next test: delete old route entry from
+        // Peer2
+        //
+        addedRoutes = new LinkedList<>();
+        withdrawnRoutes = new LinkedList<>();
+        withdrawnRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8"));
+        // Write the routes
+        message = peer2.peerChannelHandler.prepareBgpUpdate(
+                        NEXT_HOP2_ROUTER,
+                        BETTER_LOCAL_PREF,
+                        BETTER_MULTI_EXIT_DISC,
+                        asPathShort,
+                        addedRoutes,
+                        withdrawnRoutes);
+        peer2.peerChannelHandler.savedCtx.getChannel().write(message);
+        //
+        // Check that the routes have been received, processed and stored
+        //
+        bgpRibIn2 = waitForBgpRibIn(bgpSession2, 0);
+        assertThat(bgpRibIn2, hasSize(0));
+
+        //
+        // Add a route entry to Peer2 with a better MED
+        //
+        addedRoutes = new LinkedList<>();
+        withdrawnRoutes = new LinkedList<>();
+        addedRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8"));
+        // Write the routes
+        message = peer2.peerChannelHandler.prepareBgpUpdate(
+                        NEXT_HOP2_ROUTER,
+                        BETTER_LOCAL_PREF,
+                        BETTER_MULTI_EXIT_DISC,
+                        asPathShort,
+                        addedRoutes,
+                        withdrawnRoutes);
+        peer2.peerChannelHandler.savedCtx.getChannel().write(message);
+        //
+        // Check that the routes have been received, processed and stored
+        //
+        bgpRibIn2 = waitForBgpRibIn(bgpSession2, 1);
+        assertThat(bgpRibIn2, hasSize(1));
+        bgpRoutes = waitForBgpRoutes(2);
+        assertThat(bgpRoutes, hasSize(2));
+        //
+        bgpRouteEntry =
+            new BgpRouteEntry(bgpSession2,
+                              Ip4Prefix.valueOf("20.0.0.0/8"),
+                              NEXT_HOP2_ROUTER,
+                              (byte) BgpConstants.Update.Origin.IGP,
+                              asPathShort,
+                              BETTER_LOCAL_PREF);
+        bgpRouteEntry.setMultiExitDisc(BETTER_MULTI_EXIT_DISC);
+        assertThat(bgpRibIn2, hasBgpRouteEntry(bgpRouteEntry));
+        assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
+
+        //
+        // Add a route entry to Peer1 with a better (lower) BGP ID
+        //
+        addedRoutes = new LinkedList<>();
+        withdrawnRoutes = new LinkedList<>();
+        addedRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8"));
+        withdrawnRoutes.add(Ip4Prefix.valueOf("30.0.0.0/16"));
+        // Write the routes
+        message = peer1.peerChannelHandler.prepareBgpUpdate(
+                        NEXT_HOP1_ROUTER,
+                        BETTER_LOCAL_PREF,
+                        BETTER_MULTI_EXIT_DISC,
+                        asPathShort,
+                        addedRoutes,
+                        withdrawnRoutes);
+        peer1.peerChannelHandler.savedCtx.getChannel().write(message);
+        //
+        // Check that the routes have been received, processed and stored
+        //
+        bgpRibIn1 = waitForBgpRibIn(bgpSession1, 1);
+        assertThat(bgpRibIn1, hasSize(1));
+        bgpRoutes = waitForBgpRoutes(1);
+        assertThat(bgpRoutes, hasSize(1));
+        //
+        bgpRouteEntry =
+            new BgpRouteEntry(bgpSession1,
+                              Ip4Prefix.valueOf("20.0.0.0/8"),
+                              NEXT_HOP1_ROUTER,
+                              (byte) BgpConstants.Update.Origin.IGP,
+                              asPathShort,
+                              BETTER_LOCAL_PREF);
+        bgpRouteEntry.setMultiExitDisc(BETTER_MULTI_EXIT_DISC);
+        assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
+        assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
+
+
+        // Close the channels and test there are no routes
+        peer1.peerChannelHandler.closeChannel();
+        peer2.peerChannelHandler.closeChannel();
+        peer3.peerChannelHandler.closeChannel();
+        bgpRoutes = waitForBgpRoutes(0);
+        assertThat(bgpRoutes, hasSize(0));
+    }
+}
diff --git a/apps/routing/src/test/java/org/onosproject/routing/bgp/PathSegmentTest.java b/apps/routing/src/test/java/org/onosproject/routing/bgp/PathSegmentTest.java
new file mode 100644
index 0000000..4c6c5fc
--- /dev/null
+++ b/apps/routing/src/test/java/org/onosproject/routing/bgp/PathSegmentTest.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2014 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.hamcrest.Matchers;
+import org.junit.Test;
+
+import java.util.ArrayList;
+
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.not;
+import static org.junit.Assert.assertThat;
+
+/**
+ * Unit tests for the BgpRouteEntry.PathSegment class.
+ */
+public class PathSegmentTest {
+    /**
+     * Generates a Path Segment.
+     *
+     * @return a generated PathSegment
+     */
+    private BgpRouteEntry.PathSegment generatePathSegment() {
+        byte pathSegmentType = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE;
+        ArrayList<Long> segmentAsNumbers = new ArrayList<>();
+        segmentAsNumbers.add((long) 1);
+        segmentAsNumbers.add((long) 2);
+        segmentAsNumbers.add((long) 3);
+        BgpRouteEntry.PathSegment pathSegment =
+            new BgpRouteEntry.PathSegment(pathSegmentType, segmentAsNumbers);
+
+        return pathSegment;
+    }
+
+    /**
+     * Tests valid class constructor.
+     */
+    @Test
+    public void testConstructor() {
+        BgpRouteEntry.PathSegment pathSegment = generatePathSegment();
+
+        String expectedString =
+            "PathSegment{type=AS_SEQUENCE, segmentAsNumbers=[1, 2, 3]}";
+        assertThat(pathSegment.toString(), is(expectedString));
+    }
+
+    /**
+     * Tests invalid class constructor for null Segment AS Numbers.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testInvalidConstructorNullSegmentAsNumbers() {
+        byte pathSegmentType = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE;
+        ArrayList<Long> segmentAsNumbers = null;
+        new BgpRouteEntry.PathSegment(pathSegmentType, segmentAsNumbers);
+    }
+
+    /**
+     * Tests getting the fields of a Path Segment.
+     */
+    @Test
+    public void testGetFields() {
+        // Create the fields to compare against
+        byte pathSegmentType = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE;
+        ArrayList<Long> segmentAsNumbers = new ArrayList<>();
+        segmentAsNumbers.add((long) 1);
+        segmentAsNumbers.add((long) 2);
+        segmentAsNumbers.add((long) 3);
+
+        // Generate the entry to test
+        BgpRouteEntry.PathSegment pathSegment = generatePathSegment();
+
+        assertThat(pathSegment.getType(), is(pathSegmentType));
+        assertThat(pathSegment.getSegmentAsNumbers(), is(segmentAsNumbers));
+    }
+
+    /**
+     * Tests equality of {@link BgpRouteEntry.PathSegment}.
+     */
+    @Test
+    public void testEquality() {
+        BgpRouteEntry.PathSegment pathSegment1 = generatePathSegment();
+        BgpRouteEntry.PathSegment pathSegment2 = generatePathSegment();
+
+        assertThat(pathSegment1, is(pathSegment2));
+    }
+
+    /**
+     * Tests non-equality of {@link BgpRouteEntry.PathSegment}.
+     */
+    @Test
+    public void testNonEquality() {
+        BgpRouteEntry.PathSegment pathSegment1 = generatePathSegment();
+
+        // Setup Path Segment 2
+        byte pathSegmentType = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE;
+        ArrayList<Long> segmentAsNumbers = new ArrayList<>();
+        segmentAsNumbers.add((long) 1);
+        segmentAsNumbers.add((long) 22);                        // Different
+        segmentAsNumbers.add((long) 3);
+        //
+        BgpRouteEntry.PathSegment pathSegment2 =
+            new BgpRouteEntry.PathSegment(pathSegmentType, segmentAsNumbers);
+
+        assertThat(pathSegment1, Matchers.is(not(pathSegment2)));
+    }
+
+    /**
+     * Tests object string representation.
+     */
+    @Test
+    public void testToString() {
+        BgpRouteEntry.PathSegment pathSegment = generatePathSegment();
+
+        String expectedString =
+            "PathSegment{type=AS_SEQUENCE, segmentAsNumbers=[1, 2, 3]}";
+        assertThat(pathSegment.toString(), is(expectedString));
+    }
+}
diff --git a/apps/routing/src/test/java/org/onosproject/routing/bgp/TestBgpPeerChannelHandler.java b/apps/routing/src/test/java/org/onosproject/routing/bgp/TestBgpPeerChannelHandler.java
new file mode 100644
index 0000000..ac887aa
--- /dev/null
+++ b/apps/routing/src/test/java/org/onosproject/routing/bgp/TestBgpPeerChannelHandler.java
@@ -0,0 +1,207 @@
+/*
+ * Copyright 2014 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.jboss.netty.buffer.ChannelBuffer;
+import org.jboss.netty.buffer.ChannelBuffers;
+import org.jboss.netty.channel.ChannelHandlerContext;
+import org.jboss.netty.channel.ChannelStateEvent;
+import org.jboss.netty.channel.SimpleChannelHandler;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip4Prefix;
+
+import java.util.Collection;
+
+/**
+ * Class for handling the remote BGP Peer session.
+ */
+class TestBgpPeerChannelHandler extends SimpleChannelHandler {
+    static final long PEER_AS = 65001;
+    static final long PEER_AS4 = 0x12345678;
+    static final int PEER_HOLDTIME = 120;       // 120 seconds
+
+    final BgpSessionInfo localInfo = new BgpSessionInfo();
+    ChannelHandlerContext savedCtx;
+
+    /**
+     * Constructor for given BGP ID.
+     *
+     * @param bgpId the BGP ID to use
+     */
+    TestBgpPeerChannelHandler(Ip4Address bgpId) {
+        this.localInfo.setBgpVersion(BgpConstants.BGP_VERSION);
+        this.localInfo.setBgpId(bgpId);
+        this.localInfo.setAsNumber(PEER_AS);
+        this.localInfo.setHoldtime(PEER_HOLDTIME);
+    }
+
+    /**
+     * Closes the channel.
+     */
+    void closeChannel() {
+        savedCtx.getChannel().close();
+    }
+
+    @Override
+    public void channelConnected(ChannelHandlerContext ctx,
+                                 ChannelStateEvent channelEvent) {
+        this.savedCtx = ctx;
+        // Prepare and transmit BGP OPEN message
+        ChannelBuffer message = BgpOpen.prepareBgpOpen(localInfo);
+        ctx.getChannel().write(message);
+
+        // Prepare and transmit BGP KEEPALIVE message
+        message = BgpKeepalive.prepareBgpKeepalive();
+        ctx.getChannel().write(message);
+    }
+
+    @Override
+    public void channelDisconnected(ChannelHandlerContext ctx,
+                                    ChannelStateEvent channelEvent) {
+        // Nothing to do
+    }
+
+    /**
+     * Prepares BGP UPDATE message.
+     *
+     * @param nextHopRouter the next-hop router address for the routes to add
+     * @param localPref the local preference for the routes to use
+     * @param multiExitDisc the MED value
+     * @param asPath the AS path for the routes to add
+     * @param addedRoutes the routes to add
+     * @param withdrawnRoutes the routes to withdraw
+     * @return the message to transmit (BGP header included)
+     */
+    ChannelBuffer prepareBgpUpdate(Ip4Address nextHopRouter,
+                                   long localPref,
+                                   long multiExitDisc,
+                                   BgpRouteEntry.AsPath asPath,
+                                   Collection<Ip4Prefix> addedRoutes,
+                                   Collection<Ip4Prefix> withdrawnRoutes) {
+        int attrFlags;
+        ChannelBuffer message =
+            ChannelBuffers.buffer(BgpConstants.BGP_MESSAGE_MAX_LENGTH);
+        ChannelBuffer pathAttributes =
+            ChannelBuffers.buffer(BgpConstants.BGP_MESSAGE_MAX_LENGTH);
+
+        // Encode the Withdrawn Routes
+        ChannelBuffer encodedPrefixes = encodePackedPrefixes(withdrawnRoutes);
+        message.writeShort(encodedPrefixes.readableBytes());
+        message.writeBytes(encodedPrefixes);
+
+        // Encode the Path Attributes
+        // ORIGIN: IGP
+        attrFlags = 0x40;                               // Transitive flag
+        pathAttributes.writeByte(attrFlags);
+        pathAttributes.writeByte(BgpConstants.Update.Origin.TYPE);
+        pathAttributes.writeByte(1);                    // Data length
+        pathAttributes.writeByte(BgpConstants.Update.Origin.IGP);
+
+        // AS_PATH: asPath
+        attrFlags = 0x40;                               // Transitive flag
+        pathAttributes.writeByte(attrFlags);
+        pathAttributes.writeByte(BgpConstants.Update.AsPath.TYPE);
+        ChannelBuffer encodedAsPath = encodeAsPath(asPath);
+        pathAttributes.writeByte(encodedAsPath.readableBytes()); // Data length
+        pathAttributes.writeBytes(encodedAsPath);
+        // NEXT_HOP: nextHopRouter
+        attrFlags = 0x40;                               // Transitive flag
+        pathAttributes.writeByte(attrFlags);
+        pathAttributes.writeByte(BgpConstants.Update.NextHop.TYPE);
+        pathAttributes.writeByte(4);                    // Data length
+        pathAttributes.writeInt(nextHopRouter.toInt()); // Next-hop router
+        // LOCAL_PREF: localPref
+        attrFlags = 0x40;                               // Transitive flag
+        pathAttributes.writeByte(attrFlags);
+        pathAttributes.writeByte(BgpConstants.Update.LocalPref.TYPE);
+        pathAttributes.writeByte(4);                    // Data length
+        pathAttributes.writeInt((int) localPref);       // Preference value
+        // MULTI_EXIT_DISC: multiExitDisc
+        attrFlags = 0x80;                               // Optional
+                                                        // Non-Transitive flag
+        pathAttributes.writeByte(attrFlags);
+        pathAttributes.writeByte(BgpConstants.Update.MultiExitDisc.TYPE);
+        pathAttributes.writeByte(4);                    // Data length
+        pathAttributes.writeInt((int) multiExitDisc);   // Preference value
+        // The NLRI prefixes
+        encodedPrefixes = encodePackedPrefixes(addedRoutes);
+
+        // Write the Path Attributes, beginning with its length
+        message.writeShort(pathAttributes.readableBytes());
+        message.writeBytes(pathAttributes);
+        message.writeBytes(encodedPrefixes);
+
+        return BgpMessage.prepareBgpMessage(BgpConstants.BGP_TYPE_UPDATE,
+                                            message);
+    }
+
+    /**
+     * Encodes a collection of IPv4 network prefixes in a packed format.
+     * <p>
+     * The IPv4 prefixes are encoded in the form:
+     * <Length, Prefix> where Length is the length in bits of the IPv4 prefix,
+     * and Prefix is the IPv4 prefix (padded with trailing bits to the end
+     * of an octet).
+     *
+     * @param prefixes the prefixes to encode
+     * @return the buffer with the encoded prefixes
+     */
+    private ChannelBuffer encodePackedPrefixes(Collection<Ip4Prefix> prefixes) {
+        ChannelBuffer message =
+            ChannelBuffers.buffer(BgpConstants.BGP_MESSAGE_MAX_LENGTH);
+
+        // Write each of the prefixes
+        for (Ip4Prefix prefix : prefixes) {
+            int prefixBitlen = prefix.prefixLength();
+            int prefixBytelen = (prefixBitlen + 7) / 8;         // Round-up
+            message.writeByte(prefixBitlen);
+
+            Ip4Address address = prefix.address();
+            long value = address.toInt() & 0xffffffffL;
+            for (int i = 0; i < Ip4Address.BYTE_LENGTH; i++) {
+                if (prefixBytelen-- == 0) {
+                    break;
+                }
+                long nextByte =
+                    (value >> ((Ip4Address.BYTE_LENGTH - i - 1) * 8)) & 0xff;
+                message.writeByte((int) nextByte);
+            }
+        }
+
+        return message;
+    }
+
+    /**
+     * Encodes an AS path.
+     *
+     * @param asPath the AS path to encode
+     * @return the buffer with the encoded AS path
+     */
+    private ChannelBuffer encodeAsPath(BgpRouteEntry.AsPath asPath) {
+        ChannelBuffer message =
+            ChannelBuffers.buffer(BgpConstants.BGP_MESSAGE_MAX_LENGTH);
+
+        for (BgpRouteEntry.PathSegment pathSegment : asPath.getPathSegments()) {
+            message.writeByte(pathSegment.getType());
+            message.writeByte(pathSegment.getSegmentAsNumbers().size());
+            for (Long asNumber : pathSegment.getSegmentAsNumbers()) {
+                message.writeShort(asNumber.intValue());
+            }
+        }
+
+        return message;
+    }
+}
diff --git a/apps/routing/src/test/java/org/onosproject/routing/bgp/TestBgpPeerFrameDecoder.java b/apps/routing/src/test/java/org/onosproject/routing/bgp/TestBgpPeerFrameDecoder.java
new file mode 100644
index 0000000..9747ea9
--- /dev/null
+++ b/apps/routing/src/test/java/org/onosproject/routing/bgp/TestBgpPeerFrameDecoder.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright 2014 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.jboss.netty.buffer.ChannelBuffer;
+import org.jboss.netty.channel.Channel;
+import org.jboss.netty.channel.ChannelHandlerContext;
+import org.jboss.netty.handler.codec.frame.FrameDecoder;
+import org.onlab.packet.Ip4Address;
+
+import java.util.concurrent.CountDownLatch;
+
+/**
+ * Class for handling the decoding of the BGP messages at the remote
+ * BGP peer session.
+ */
+class TestBgpPeerFrameDecoder extends FrameDecoder {
+    final BgpSessionInfo remoteInfo = new BgpSessionInfo();
+
+    final CountDownLatch receivedOpenMessageLatch = new CountDownLatch(1);
+    final CountDownLatch receivedKeepaliveMessageLatch = new CountDownLatch(1);
+
+    @Override
+    protected Object decode(ChannelHandlerContext ctx,
+                            Channel channel,
+                            ChannelBuffer buf) throws Exception {
+        // Test for minimum length of the BGP message
+        if (buf.readableBytes() < BgpConstants.BGP_HEADER_LENGTH) {
+            // No enough data received
+            return null;
+        }
+
+        //
+        // Mark the current buffer position in case we haven't received
+        // the whole message.
+        //
+        buf.markReaderIndex();
+
+        //
+        // Read and check the BGP message Marker field: it must be all ones
+        //
+        byte[] marker = new byte[BgpConstants.BGP_HEADER_MARKER_LENGTH];
+        buf.readBytes(marker);
+        for (int i = 0; i < marker.length; i++) {
+            if (marker[i] != (byte) 0xff) {
+                // ERROR: Connection Not Synchronized. Close the channel.
+                ctx.getChannel().close();
+                return null;
+            }
+        }
+
+        //
+        // Read and check the BGP message Length field
+        //
+        int length = buf.readUnsignedShort();
+        if ((length < BgpConstants.BGP_HEADER_LENGTH) ||
+            (length > BgpConstants.BGP_MESSAGE_MAX_LENGTH)) {
+            // ERROR: Bad Message Length. Close the channel.
+            ctx.getChannel().close();
+            return null;
+        }
+
+        //
+        // Test whether the rest of the message is received:
+        // So far we have read the Marker (16 octets) and the
+        // Length (2 octets) fields.
+        //
+        int remainingMessageLen =
+            length - BgpConstants.BGP_HEADER_MARKER_LENGTH - 2;
+        if (buf.readableBytes() < remainingMessageLen) {
+            // No enough data received
+            buf.resetReaderIndex();
+            return null;
+        }
+
+        //
+        // Read the BGP message Type field, and process based on that type
+        //
+        int type = buf.readUnsignedByte();
+        remainingMessageLen--;      // Adjust after reading the type
+        ChannelBuffer message = buf.readBytes(remainingMessageLen);
+
+        //
+        // Process the remaining of the message based on the message type
+        //
+        switch (type) {
+        case BgpConstants.BGP_TYPE_OPEN:
+            processBgpOpen(ctx, message);
+            break;
+        case BgpConstants.BGP_TYPE_UPDATE:
+            // NOTE: Not used as part of the test, because ONOS does not
+            // originate UPDATE messages.
+            break;
+        case BgpConstants.BGP_TYPE_NOTIFICATION:
+            // NOTE: Not used as part of the testing (yet)
+            break;
+        case BgpConstants.BGP_TYPE_KEEPALIVE:
+            processBgpKeepalive(ctx, message);
+            break;
+        default:
+            // ERROR: Bad Message Type. Close the channel.
+            ctx.getChannel().close();
+            return null;
+        }
+
+        return null;
+    }
+
+    /**
+     * Processes BGP OPEN message.
+     *
+     * @param ctx the Channel Handler Context.
+     * @param message the message to process.
+     */
+    private void processBgpOpen(ChannelHandlerContext ctx,
+                                ChannelBuffer message) {
+        int minLength =
+            BgpConstants.BGP_OPEN_MIN_LENGTH - BgpConstants.BGP_HEADER_LENGTH;
+        if (message.readableBytes() < minLength) {
+            // ERROR: Bad Message Length. Close the channel.
+            ctx.getChannel().close();
+            return;
+        }
+
+        //
+        // Parse the OPEN message
+        //
+        remoteInfo.setBgpVersion(message.readUnsignedByte());
+        remoteInfo.setAsNumber(message.readUnsignedShort());
+        remoteInfo.setHoldtime(message.readUnsignedShort());
+        remoteInfo.setBgpId(Ip4Address.valueOf((int) message.readUnsignedInt()));
+        // Optional Parameters
+        int optParamLen = message.readUnsignedByte();
+        if (message.readableBytes() < optParamLen) {
+            // ERROR: Bad Message Length. Close the channel.
+            ctx.getChannel().close();
+            return;
+        }
+        message.readBytes(optParamLen);             // NOTE: data ignored
+
+        // BGP OPEN message successfully received
+        receivedOpenMessageLatch.countDown();
+    }
+
+    /**
+     * Processes BGP KEEPALIVE message.
+     *
+     * @param ctx the Channel Handler Context.
+     * @param message the message to process.
+     */
+    private void processBgpKeepalive(ChannelHandlerContext ctx,
+                                     ChannelBuffer message) {
+        if (message.readableBytes() + BgpConstants.BGP_HEADER_LENGTH !=
+            BgpConstants.BGP_KEEPALIVE_EXPECTED_LENGTH) {
+            // ERROR: Bad Message Length. Close the channel.
+            ctx.getChannel().close();
+            return;
+        }
+        // BGP KEEPALIVE message successfully received
+        receivedKeepaliveMessageLatch.countDown();
+    }
+}
