diff --git a/apps/routing/common/src/main/java/org/onosproject/routing/bgp/BgpOpen.java b/apps/routing/common/src/main/java/org/onosproject/routing/bgp/BgpOpen.java
new file mode 100644
index 0000000..e5d4821
--- /dev/null
+++ b/apps/routing/common/src/main/java/org/onosproject/routing/bgp/BgpOpen.java
@@ -0,0 +1,508 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.routing.bgp;
+
+import org.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 Param Type
+                    String errorMsg = "Malformed Capabilities Optional "
+                            + "Parameter Type " + paramType;
+                    throw new BgpMessage.BgpParseException(errorMsg);
+                }
+                int paramEnd = message.readerIndex() + paramLen;
+                // Parse Capabilities
+                while (message.readerIndex() < paramEnd) {
+                    if (paramEnd - message.readerIndex() <
+                            BgpConstants.Open.Capabilities.MIN_LENGTH) {
+                        String errorMsg = "Malformed Capabilities";
+                        throw new BgpMessage.BgpParseException(errorMsg);
+                    }
+                    int capabCode = message.readUnsignedByte();
+                    int capabLen = message.readUnsignedByte();
+                    if (message.readerIndex() + capabLen > paramEnd) {
+                        // ERROR: Malformed Capability
+                        String errorMsg = "Malformed Capability instance with "
+                                + "code " + capabCode;
+                        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;
+    }
+}
