diff --git a/sdx-l3/src/main/java/org/onosproject/sdxl3/SdxL3.java b/sdx-l3/src/main/java/org/onosproject/sdxl3/SdxL3.java
new file mode 100644
index 0000000..f01cd80
--- /dev/null
+++ b/sdx-l3/src/main/java/org/onosproject/sdxl3/SdxL3.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright 2014-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.sdxl3;
+
+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.onlab.packet.Ethernet;
+import org.onosproject.app.ApplicationService;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.incubator.component.ComponentService;
+import org.onosproject.incubator.net.intf.InterfaceService;
+import org.onosproject.net.config.NetworkConfigService;
+import org.onosproject.net.edge.EdgePortService;
+import org.onosproject.net.host.HostService;
+import org.onosproject.net.packet.InboundPacket;
+import org.onosproject.net.packet.PacketContext;
+import org.onosproject.net.packet.PacketProcessor;
+import org.onosproject.net.packet.PacketService;
+import org.onosproject.routing.IntentSynchronizationAdminService;
+import org.onosproject.routing.IntentSynchronizationService;
+import org.onosproject.routing.RoutingService;
+import org.onosproject.routing.config.BgpConfig;
+import org.slf4j.Logger;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Component for the SDX-L3 application.
+ */
+@Component(immediate = true)
+public class SdxL3  {
+
+    public static final String SDX_L3_APP = "org.onosproject.sdxl3";
+
+    private final Logger log = getLogger(getClass());
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected ApplicationService applicationService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected NetworkConfigService networkConfigService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected InterfaceService interfaceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected IntentSynchronizationService intentSynchronizer;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected IntentSynchronizationAdminService intentSynchronizerAdmin;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected ComponentService componentService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected PacketService packetService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected EdgePortService edgeService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected HostService hostService;
+
+    protected ArpHandler arpHandler = null;
+
+    private InternalPacketProcessor processor = null;
+
+    private ApplicationId appId;
+
+    private static List<String> components = new ArrayList<>();
+    static {
+        components.add("org.onosproject.routing.bgp.BgpSessionManager");
+        components.add("org.onosproject.routing.impl.Router");
+        components.add(org.onosproject.sdxl3.impl.PeerConnectivityManager.class.getName());
+        components.add(org.onosproject.sdxl3.SdxL3Fib.class.getName());
+    }
+
+    @Activate
+    protected void activate() {
+        components.forEach(name -> componentService.activate(appId, name));
+
+        appId = coreService.registerApplication(SDX_L3_APP);
+
+        ApplicationId routerAppId = coreService.getAppId(RoutingService.ROUTER_APP_ID);
+        BgpConfig bgpConfig =
+                networkConfigService.getConfig(routerAppId, RoutingService.CONFIG_CLASS);
+
+        arpHandler = new ArpHandler(bgpConfig,
+                edgeService,
+                hostService,
+                packetService,
+                interfaceService);
+        processor = new InternalPacketProcessor();
+        packetService.addProcessor(processor, PacketProcessor.director(2));
+
+        // TODO fix removing intents
+        applicationService.registerDeactivateHook(appId,
+                intentSynchronizerAdmin::removeIntents);
+
+        log.info("SDX-L3 started");
+    }
+
+    @Deactivate
+    protected void deactivate() {
+        components.forEach(name -> componentService.deactivate(appId, name));
+
+        packetService.removeProcessor(processor);
+
+        log.info("SDX-L3 stopped");
+    }
+
+    private class InternalPacketProcessor implements PacketProcessor {
+        @Override
+        public void process(PacketContext context) {
+
+            if (context.isHandled()) {
+                return;
+            }
+
+            InboundPacket pkt = context.inPacket();
+            Ethernet ethernet = pkt.parsed();
+            if (ethernet.getEtherType() == Ethernet.TYPE_ARP) {
+                arpHandler.processPacketIn(pkt);
+            }
+        }
+    }
+
+}
diff --git a/sdx-l3/src/main/java/org/onosproject/sdxl3/SdxL3ArpHandler.java b/sdx-l3/src/main/java/org/onosproject/sdxl3/SdxL3ArpHandler.java
new file mode 100644
index 0000000..795d301
--- /dev/null
+++ b/sdx-l3/src/main/java/org/onosproject/sdxl3/SdxL3ArpHandler.java
@@ -0,0 +1,535 @@
+/*
+ * Copyright 2016 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.sdxl3;
+
+import org.onlab.packet.ARP;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.ICMP6;
+import org.onlab.packet.IPv6;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip6Address;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onlab.packet.ndp.NeighborAdvertisement;
+import org.onlab.packet.ndp.NeighborDiscoveryOptions;
+import org.onlab.packet.ndp.NeighborSolicitation;
+import org.onosproject.incubator.net.intf.Interface;
+import org.onosproject.incubator.net.intf.InterfaceService;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.Host;
+import org.onosproject.net.edge.EdgePortService;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.host.HostService;
+import org.onosproject.net.packet.DefaultOutboundPacket;
+import org.onosproject.net.packet.InboundPacket;
+import org.onosproject.net.packet.PacketService;
+import org.onosproject.routing.config.BgpConfig;
+
+import java.nio.ByteBuffer;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.net.HostId.hostId;
+import static org.onosproject.security.AppGuard.checkPermission;
+import static org.onosproject.security.AppPermission.Type.PACKET_WRITE;
+
+public class SdxL3ArpHandler {
+
+    private static final String REQUEST_NULL = "ARP or NDP request cannot be null.";
+    private static final String MSG_NOT_REQUEST = "Message is not an ARP or NDP request";
+
+    private BgpConfig bgpConfig;
+    private EdgePortService edgeService;
+    private HostService hostService;
+    private PacketService packetService;
+    private InterfaceService interfaceService;
+
+    private enum Protocol {
+        ARP, NDP
+    }
+
+    private enum MessageType {
+        REQUEST, REPLY
+    }
+
+    /**
+     * Creates an ArpHandler object.
+     *
+     */
+    public SdxL3ArpHandler(BgpConfig bgpConfig,
+                           EdgePortService edgeService,
+                           HostService hostService,
+                           PacketService packetService,
+                           InterfaceService interfaceService) {
+        this.bgpConfig = bgpConfig;
+        this.edgeService = edgeService;
+        this.hostService = hostService;
+        this.packetService = packetService;
+        this.interfaceService = interfaceService;
+    }
+
+    /**
+     * Processes incoming ARP packets.
+     *
+     * @param pkt incoming packet
+     */
+    public void processPacketIn(InboundPacket pkt) {
+        checkPermission(PACKET_WRITE);
+
+        Ethernet eth = pkt.parsed();
+        checkNotNull(eth, REQUEST_NULL);
+
+        ConnectPoint inPort = pkt.receivedFrom();
+        MessageContext context = createContext(eth, inPort);
+        if (context != null) {
+            replyInternal(context);
+        }
+    }
+
+    /**
+     * Handles a request message also when it concerns an SDX peering address.
+     *
+     * If the MAC address of the target is known, we can reply directly to the
+     * requestor. Otherwise, we forward the request out other ports in an
+     * attempt to find the correct host.
+     *
+     * @param context request message context to process
+     */
+    private void replyInternal(MessageContext context) {
+        checkNotNull(context);
+        checkArgument(context.type() == MessageType.REQUEST, MSG_NOT_REQUEST);
+
+        if (hasIpAddress(context.inPort())) {
+            // If the request came from outside the network, only reply if it was
+            // for one of our external addresses.
+
+            interfaceService.getInterfacesByPort(context.inPort())
+                    .stream()
+                    .filter(intf -> intf.ipAddresses()
+                            .stream()
+                            .anyMatch(ia -> ia.ipAddress().equals(context.target())))
+                    .forEach(intf -> buildAndSendReply(context, intf.mac()));
+
+            if (!isPeerAddress(context.sender()) || !isPeerAddress(context.target())) {
+                // Only care about requests from/towards external BGP peers
+                return;
+            }
+        }
+
+        // See if we have the target host in the host store
+        Set<Host> hosts = hostService.getHostsByIp(context.target());
+
+        Host dst = null;
+        Host src = hostService.getHost(hostId(context.srcMac(), context.vlan()));
+
+        for (Host host : hosts) {
+            if (host.vlan().equals(context.vlan())) {
+                dst = host;
+                break;
+            }
+        }
+
+        if (src != null && dst != null) {
+            // We know the target host so we can respond
+            buildAndSendReply(context, dst.mac());
+            return;
+        }
+
+        // If the source address matches one of our external addresses
+        // it could be a request from an internal host to an external
+        // address. Forward it over to the correct port.
+        boolean matched = false;
+        Set<Interface> interfaces = interfaceService.getInterfacesByIp(context.sender());
+        for (Interface intf : interfaces) {
+            if (intf.vlan().equals(context.vlan())) {
+                matched = true;
+                sendTo(context.packet(), intf.connectPoint());
+                break;
+            }
+        }
+
+        if (matched) {
+            return;
+        }
+
+        // If the packets has a vlanId look if there are some other
+        // interfaces in the configuration on the same vlan and broadcast
+        // the packet out just of through those interfaces.
+        VlanId vlanId = context.vlan();
+
+        Set<Interface> filteredVlanInterfaces =
+                filterVlanInterfacesNoIp(interfaceService.getInterfacesByVlan(vlanId));
+
+        if (vlanId != null
+                && !vlanId.equals(VlanId.NONE)
+                && confContainsVlans(vlanId, context.inPort())) {
+            vlanFlood(context.packet(), filteredVlanInterfaces, context.inPort);
+            return;
+        }
+
+        // The request couldn't be resolved.
+        // Flood the request on all ports except the incoming port.
+        flood(context.packet(), context.inPort());
+    }
+
+    private boolean isPeerAddress(IpAddress ip) {
+        return bgpConfig.bgpSpeakers()
+                .stream()
+                .flatMap(speaker -> speaker.peers().stream())
+                .anyMatch(peerAddress -> peerAddress.equals(ip));
+    }
+
+    private Set<Interface> filterVlanInterfacesNoIp(Set<Interface> vlanInterfaces) {
+        return vlanInterfaces
+                .stream()
+                .filter(intf -> intf.ipAddresses().isEmpty())
+                .collect(Collectors.toSet());
+    }
+
+    /**
+     * States if the interface configuration contains more than one interface configured
+     * on a specific vlan, including the interface passed as argument.
+     *
+     * @param vlanId the vlanid to look for in the interface configuration
+     * @param connectPoint the connect point to exclude from the search
+     * @return true if interfaces are found. False otherwise
+     */
+    private boolean confContainsVlans(VlanId vlanId, ConnectPoint connectPoint) {
+        Set<Interface> vlanInterfaces = interfaceService.getInterfacesByVlan(vlanId);
+        return interfaceService.getInterfacesByVlan(vlanId)
+                .stream()
+                .anyMatch(intf -> intf.connectPoint().equals(connectPoint) && intf.ipAddresses().isEmpty())
+                && vlanInterfaces.size() > 1;
+    }
+
+    /**
+     * Builds and sends a reply message given a request context and the resolved
+     * MAC address to answer with.
+     *
+     * @param context message context of request
+     * @param targetMac MAC address to be given in the response
+     */
+    private void buildAndSendReply(MessageContext context, MacAddress targetMac) {
+        switch (context.protocol()) {
+            case ARP:
+                sendTo(ARP.buildArpReply((Ip4Address) context.target(),
+                        targetMac, context.packet()), context.inPort());
+                break;
+            case NDP:
+                sendTo(buildNdpReply((Ip6Address) context.target(), targetMac,
+                        context.packet()), context.inPort());
+                break;
+            default:
+                break;
+        }
+    }
+
+    /**
+     * Outputs a packet out a specific port.
+     *
+     * @param packet  the packet to send
+     * @param outPort the port to send it out
+     */
+    private void sendTo(Ethernet packet, ConnectPoint outPort) {
+        sendTo(outPort, ByteBuffer.wrap(packet.serialize()));
+    }
+
+    /**
+     * Outputs a packet out a specific port.
+     *
+     * @param outPort port to send it out
+     * @param packet packet to send
+     */
+    private void sendTo(ConnectPoint outPort, ByteBuffer packet) {
+        if (!edgeService.isEdgePoint(outPort)) {
+            // Sanity check to make sure we don't send the packet out an
+            // internal port and create a loop (could happen due to
+            // misconfiguration).
+            return;
+        }
+
+        TrafficTreatment.Builder builder = DefaultTrafficTreatment.builder();
+        builder.setOutput(outPort.port());
+        packetService.emit(new DefaultOutboundPacket(outPort.deviceId(),
+                builder.build(), packet));
+    }
+
+    /**
+     * Returns whether the given port has any IP addresses configured or not.
+     *
+     * @param connectPoint the port to check
+     * @return true if the port has at least one IP address configured,
+     * false otherwise
+     */
+    private boolean hasIpAddress(ConnectPoint connectPoint) {
+        return interfaceService.getInterfacesByPort(connectPoint)
+                .stream()
+                .flatMap(intf -> intf.ipAddresses().stream())
+                .findAny()
+                .isPresent();
+    }
+
+    /**
+     * Returns whether the given port has any VLAN configured or not.
+     *
+     * @param connectPoint the port to check
+     * @return true if the port has at least one VLAN configured,
+     * false otherwise
+     */
+    private boolean hasVlan(ConnectPoint connectPoint) {
+        return interfaceService.getInterfacesByPort(connectPoint)
+                .stream()
+                .filter(intf -> !intf.vlan().equals(VlanId.NONE))
+                .findAny()
+                .isPresent();
+    }
+
+    /**
+     * Flood the arp request at all edges on a specifc VLAN.
+     *
+     * @param request the arp request
+     * @param dsts the destination interfaces
+     * @param inPort the connect point the arp request was received on
+     */
+    private void vlanFlood(Ethernet request, Set<Interface> dsts, ConnectPoint inPort) {
+        TrafficTreatment.Builder builder = null;
+        ByteBuffer buf = ByteBuffer.wrap(request.serialize());
+
+        for (Interface intf : dsts) {
+            ConnectPoint cPoint = intf.connectPoint();
+            if (cPoint.equals(inPort)) {
+                continue;
+            }
+
+            builder = DefaultTrafficTreatment.builder();
+            builder.setOutput(cPoint.port());
+            packetService.emit(new DefaultOutboundPacket(cPoint.deviceId(),
+                    builder.build(), buf));
+        }
+    }
+
+    /**
+     * Flood the arp request at all edges in the network.
+     *
+     * @param request the arp request
+     * @param inPort  the connect point the arp request was received on
+     */
+    private void flood(Ethernet request, ConnectPoint inPort) {
+        TrafficTreatment.Builder builder = null;
+        ByteBuffer buf = ByteBuffer.wrap(request.serialize());
+
+        for (ConnectPoint connectPoint : edgeService.getEdgePoints()) {
+            if (hasIpAddress(connectPoint)
+                    || hasVlan(connectPoint)
+                    || connectPoint.equals(inPort)) {
+                continue;
+            }
+
+            builder = DefaultTrafficTreatment.builder();
+            builder.setOutput(connectPoint.port());
+            packetService.emit(new DefaultOutboundPacket(connectPoint.deviceId(),
+                    builder.build(), buf));
+        }
+    }
+
+    /**
+     * Builds an Neighbor Discovery reply based on a request.
+     *
+     * @param srcIp   the IP address to use as the reply source
+     * @param srcMac  the MAC address to use as the reply source
+     * @param request the Neighbor Solicitation request we got
+     * @return an Ethernet frame containing the Neighbor Advertisement reply
+     */
+    private Ethernet buildNdpReply(Ip6Address srcIp, MacAddress srcMac,
+                                   Ethernet request) {
+        Ethernet eth = new Ethernet();
+        eth.setDestinationMACAddress(request.getSourceMAC());
+        eth.setSourceMACAddress(srcMac);
+        eth.setEtherType(Ethernet.TYPE_IPV6);
+        eth.setVlanID(request.getVlanID());
+
+        IPv6 requestIp = (IPv6) request.getPayload();
+        IPv6 ipv6 = new IPv6();
+        ipv6.setSourceAddress(srcIp.toOctets());
+        ipv6.setDestinationAddress(requestIp.getSourceAddress());
+        ipv6.setHopLimit((byte) 255);
+
+        ICMP6 icmp6 = new ICMP6();
+        icmp6.setIcmpType(ICMP6.NEIGHBOR_ADVERTISEMENT);
+        icmp6.setIcmpCode((byte) 0);
+
+        NeighborAdvertisement nadv = new NeighborAdvertisement();
+        nadv.setTargetAddress(srcIp.toOctets());
+        nadv.setSolicitedFlag((byte) 1);
+        nadv.setOverrideFlag((byte) 1);
+        nadv.addOption(NeighborDiscoveryOptions.TYPE_TARGET_LL_ADDRESS,
+                srcMac.toBytes());
+
+        icmp6.setPayload(nadv);
+        ipv6.setPayload(icmp6);
+        eth.setPayload(ipv6);
+        return eth;
+    }
+
+    /**
+     * Attempts to create a MessageContext for the given Ethernet frame. If the
+     * frame is a valid ARP or NDP request or response, a context will be
+     * created.
+     *
+     * @param eth input Ethernet frame
+     * @param inPort in port
+     * @return MessageContext if the packet was ARP or NDP, otherwise null
+     */
+    private MessageContext createContext(Ethernet eth, ConnectPoint inPort) {
+        if (eth.getEtherType() == Ethernet.TYPE_ARP) {
+            return createArpContext(eth, inPort);
+        } else if (eth.getEtherType() == Ethernet.TYPE_IPV6) {
+            return createNdpContext(eth, inPort);
+        }
+
+        return null;
+    }
+
+    /**
+     * Extracts context information from ARP packets.
+     *
+     * @param eth input Ethernet frame that is thought to be ARP
+     * @param inPort in port
+     * @return MessageContext object if the packet was a valid ARP packet,
+     * otherwise null
+     */
+    private MessageContext createArpContext(Ethernet eth, ConnectPoint inPort) {
+        if (eth.getEtherType() != Ethernet.TYPE_ARP) {
+            return null;
+        }
+
+        ARP arp = (ARP) eth.getPayload();
+
+        IpAddress target = Ip4Address.valueOf(arp.getTargetProtocolAddress());
+        IpAddress sender = Ip4Address.valueOf(arp.getSenderProtocolAddress());
+
+        MessageType type;
+        if (arp.getOpCode() == ARP.OP_REQUEST) {
+            type = MessageType.REQUEST;
+        } else if (arp.getOpCode() == ARP.OP_REPLY) {
+            type = MessageType.REPLY;
+        } else {
+            return null;
+        }
+
+        return new MessageContext(eth, inPort, Protocol.ARP, type, target, sender);
+    }
+
+    /**
+     * Extracts context information from NDP packets.
+     *
+     * @param eth input Ethernet frame that is thought to be NDP
+     * @param inPort in port
+     * @return MessageContext object if the packet was a valid NDP packet,
+     * otherwise null
+     */
+    private MessageContext createNdpContext(Ethernet eth, ConnectPoint inPort) {
+        if (eth.getEtherType() != Ethernet.TYPE_IPV6) {
+            return null;
+        }
+        IPv6 ipv6 = (IPv6) eth.getPayload();
+
+        if (ipv6.getNextHeader() != IPv6.PROTOCOL_ICMP6) {
+            return null;
+        }
+        ICMP6 icmpv6 = (ICMP6) ipv6.getPayload();
+
+        IpAddress sender = Ip6Address.valueOf(ipv6.getSourceAddress());
+        IpAddress target = null;
+
+        MessageType type;
+        if (icmpv6.getIcmpType() == ICMP6.NEIGHBOR_SOLICITATION) {
+            type = MessageType.REQUEST;
+            NeighborSolicitation nsol = (NeighborSolicitation) icmpv6.getPayload();
+            target = Ip6Address.valueOf(nsol.getTargetAddress());
+        } else if (icmpv6.getIcmpType() == ICMP6.NEIGHBOR_ADVERTISEMENT) {
+            type = MessageType.REPLY;
+        } else {
+            return null;
+        }
+
+        return new MessageContext(eth, inPort, Protocol.NDP, type, target, sender);
+    }
+
+    /**
+     * Provides context information for a particular ARP or NDP message, with
+     * a unified interface to access data regardless of protocol.
+     */
+    private class MessageContext {
+        private Protocol protocol;
+        private MessageType type;
+
+        private IpAddress target;
+        private IpAddress sender;
+
+        private Ethernet eth;
+        private ConnectPoint inPort;
+
+
+        public MessageContext(Ethernet eth, ConnectPoint inPort,
+                              Protocol protocol, MessageType type,
+                              IpAddress target, IpAddress sender) {
+            this.eth = eth;
+            this.inPort = inPort;
+            this.protocol = protocol;
+            this.type = type;
+            this.target = target;
+            this.sender = sender;
+        }
+
+        public ConnectPoint inPort() {
+            return inPort;
+        }
+
+        public Ethernet packet() {
+            return eth;
+        }
+
+        public Protocol protocol() {
+            return protocol;
+        }
+
+        public MessageType type() {
+            return type;
+        }
+
+        public VlanId vlan() {
+            return VlanId.vlanId(eth.getVlanID());
+        }
+
+        public MacAddress srcMac() {
+            return MacAddress.valueOf(eth.getSourceMACAddress());
+        }
+
+        public IpAddress target() {
+            return target;
+        }
+
+        public IpAddress sender() {
+            return sender;
+        }
+    }
+
+}
diff --git a/sdx-l3/src/main/java/org/onosproject/sdxl3/SdxL3Fib.java b/sdx-l3/src/main/java/org/onosproject/sdxl3/SdxL3Fib.java
new file mode 100644
index 0000000..68829e1
--- /dev/null
+++ b/sdx-l3/src/main/java/org/onosproject/sdxl3/SdxL3Fib.java
@@ -0,0 +1,253 @@
+/*
+ * Copyright 2014-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.sdxl3;
+
+import com.google.common.collect.ImmutableList;
+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.onlab.packet.Ethernet;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.incubator.net.intf.Interface;
+import org.onosproject.incubator.net.intf.InterfaceService;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.intent.Constraint;
+import org.onosproject.net.intent.Key;
+import org.onosproject.net.intent.MultiPointToSinglePointIntent;
+import org.onosproject.net.intent.constraint.PartialFailureConstraint;
+import org.onosproject.routing.FibListener;
+import org.onosproject.routing.FibUpdate;
+import org.onosproject.routing.IntentSynchronizationService;
+import org.onosproject.routing.RoutingService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+/**
+ * FIB component of SDX-L3.
+ */
+@Component(immediate = true, enabled = false)
+public class SdxL3Fib {
+    private Logger log = LoggerFactory.getLogger(getClass());
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected InterfaceService interfaceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected IntentSynchronizationService intentSynchronizer;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected RoutingService routingService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected PeerConnectivityService peerConnectivity;
+
+    private final InternalFibListener fibListener = new InternalFibListener();
+
+    private static final int PRIORITY_OFFSET = 100;
+    private static final int PRIORITY_MULTIPLIER = 5;
+    protected static final ImmutableList<Constraint> CONSTRAINTS
+            = ImmutableList.of(new PartialFailureConstraint());
+
+    private final Map<IpPrefix, MultiPointToSinglePointIntent> routeIntents
+            = new ConcurrentHashMap<>();
+
+    private ApplicationId appId;
+
+    @Activate
+    public void activate() {
+        appId = coreService.getAppId(SdxL3.SDX_L3_APP);
+
+        routingService.addFibListener(fibListener);
+        routingService.start();
+    }
+
+    @Deactivate
+    public void deactivate() {
+        // TODO remove listener
+        routingService.stop();
+    }
+
+    private void update(Collection<FibUpdate> updates, Collection<FibUpdate> withdraws) {
+        int submitCount = 0, withdrawCount = 0;
+        //
+        // NOTE: Semantically, we MUST withdraw existing intents before
+        // submitting new intents.
+        //
+        synchronized (this) {
+            MultiPointToSinglePointIntent intent;
+
+            //
+            // Prepare the Intent batch operations for the intents to withdraw
+            //
+            for (FibUpdate withdraw : withdraws) {
+                checkArgument(withdraw.type() == FibUpdate.Type.DELETE,
+                        "FibUpdate with wrong type in withdraws list");
+
+                IpPrefix prefix = withdraw.entry().prefix();
+                intent = routeIntents.remove(prefix);
+                if (intent == null) {
+                    log.trace("SDX-L3 No intent in routeIntents to delete " +
+                            "for prefix: {}", prefix);
+                    continue;
+                }
+                intentSynchronizer.withdraw(intent);
+                withdrawCount++;
+            }
+
+            //
+            // Prepare the Intent batch operations for the intents to submit
+            //
+            for (FibUpdate update : updates) {
+                checkArgument(update.type() == FibUpdate.Type.UPDATE,
+                        "FibUpdate with wrong type in updates list");
+
+                IpPrefix prefix = update.entry().prefix();
+                intent = generateRouteIntent(prefix, update.entry().nextHopIp(),
+                        update.entry().nextHopMac());
+
+                if (intent == null) {
+                    // This preserves the old semantics - if an intent can't be
+                    // generated, we don't do anything with that prefix. But
+                    // perhaps we should withdraw the old intent anyway?
+                    continue;
+                }
+
+                routeIntents.put(prefix, intent);
+                intentSynchronizer.submit(intent);
+                submitCount++;
+            }
+
+            log.debug("SDX-L3 submitted {}/{}, withdrew = {}/{}", submitCount,
+                    updates.size(), withdrawCount, withdraws.size());
+        }
+    }
+
+    /**
+     * Generates a route intent for a prefix, the next hop IP address, and
+     * the next hop MAC address.
+     * <p/>
+     * This method will find the egress interface for the intent.
+     * Intent will match dst IP prefix and rewrite dst MAC address at all other
+     * border switches, then forward packets according to dst MAC address.
+     *
+     * @param prefix            IP prefix of the route to add
+     * @param nextHopIpAddress  IP address of the next hop
+     * @param nextHopMacAddress MAC address of the next hop
+     * @return the generated intent, or null if no intent should be submitted
+     */
+    private MultiPointToSinglePointIntent generateRouteIntent(
+            IpPrefix prefix,
+            IpAddress nextHopIpAddress,
+            MacAddress nextHopMacAddress) {
+
+        // Find the attachment point (egress interface) of the next hop
+        Interface egressInterface = peerConnectivity.getInterfaceForPeer(nextHopIpAddress);
+
+        if (egressInterface == null) {
+            log.warn("No outgoing interface found for {}",
+                    nextHopIpAddress);
+            return null;
+        }
+
+        // Generate the intent itself
+        Set<ConnectPoint> ingressPorts = new HashSet<>();
+        ConnectPoint egressPort = egressInterface.connectPoint();
+        log.debug("Generating intent for prefix {}, next hop mac {}",
+                prefix, nextHopMacAddress);
+
+        for (Interface intf : interfaceService.getInterfaces()) {
+            // TODO this should be only peering interfaces
+            if (!intf.connectPoint().equals(egressInterface.connectPoint())) {
+                ConnectPoint srcPort = intf.connectPoint();
+                ingressPorts.add(srcPort);
+            }
+        }
+
+        // Match the destination IP prefix at the first hop
+        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+        if (prefix.isIp4()) {
+            selector.matchEthType(Ethernet.TYPE_IPV4);
+            // if it is default route, then we do not need match destination
+            // IP address
+            if (prefix.prefixLength() != 0) {
+                selector.matchIPDst(prefix);
+            }
+        } else {
+            selector.matchEthType(Ethernet.TYPE_IPV6);
+            // if it is default route, then we do not need match destination
+            // IP address
+            if (prefix.prefixLength() != 0) {
+                selector.matchIPv6Dst(prefix);
+            }
+
+        }
+
+        // Rewrite the destination MAC address
+        TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder()
+                .setEthDst(nextHopMacAddress);
+        if (!egressInterface.vlan().equals(VlanId.NONE)) {
+            treatment.setVlanId(egressInterface.vlan());
+            // If we set VLAN ID, we have to make sure a VLAN tag exists.
+            // TODO support no VLAN -> VLAN routing
+            selector.matchVlanId(VlanId.ANY);
+        }
+
+        int priority =
+                prefix.prefixLength() * PRIORITY_MULTIPLIER + PRIORITY_OFFSET;
+        Key key = Key.of(prefix.toString(), appId);
+        return MultiPointToSinglePointIntent.builder()
+                .appId(appId)
+                .key(key)
+                .selector(selector.build())
+                .treatment(treatment.build())
+                .ingressPoints(ingressPorts)
+                .egressPoint(egressPort)
+                .priority(priority)
+                .constraints(CONSTRAINTS)
+                .build();
+    }
+
+    private class InternalFibListener implements FibListener {
+        @Override
+        public void update(Collection<FibUpdate> updates, Collection<FibUpdate> withdraws) {
+            SdxL3Fib.this.update(updates, withdraws);
+        }
+    }
+
+}
diff --git a/sdx-l3/src/main/java/org/onosproject/sdxl3/SdxL3PeerService.java b/sdx-l3/src/main/java/org/onosproject/sdxl3/SdxL3PeerService.java
new file mode 100644
index 0000000..6a2542c
--- /dev/null
+++ b/sdx-l3/src/main/java/org/onosproject/sdxl3/SdxL3PeerService.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2014-2016 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.sdxl3;
+
+import org.onlab.packet.IpAddress;
+import org.onosproject.incubator.net.intf.Interface;
+
+/*
+ * Service for managing peers connections
+ */
+public interface SdxL3PeerService {
+
+    String CONFIG_KEY = "bgpPeers";
+
+    /**
+     * Returns the interface used as connection point to peer.
+     *
+     * @param peeringAddress IP address of peer
+     * @return interface to the peer
+     */
+    Interface getInterfaceForPeer(IpAddress peeringAddress);
+}
diff --git a/sdx-l3/src/main/java/org/onosproject/sdxl3/cli/BgpPeersListCommand.java b/sdx-l3/src/main/java/org/onosproject/sdxl3/cli/BgpPeersListCommand.java
new file mode 100644
index 0000000..09f237b
--- /dev/null
+++ b/sdx-l3/src/main/java/org/onosproject/sdxl3/cli/BgpPeersListCommand.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2014-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.sdxl3.cli;
+
+import com.google.common.collect.Lists;
+import org.apache.karaf.shell.commands.Command;
+import org.onlab.packet.IpAddress;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.net.config.NetworkConfigService;
+import org.onosproject.routing.RoutingService;
+import org.onosproject.routing.config.BgpConfig;
+import org.onosproject.sdxl3.SdxL3;
+import org.onosproject.sdxl3.config.BgpPeersConfig;
+
+import java.util.Comparator;
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * Lists the BGP peers configured in the system.
+ */
+@Command(scope = "onos", name = "bgp-peers",
+        description = "Lists all BGP peers")
+public class BgpPeersListCommand extends AbstractShellCommand {
+
+    private static final String FORMAT = "ip=%s, interface=%s";
+    private static final String NAME_FORMAT = "%s: " + FORMAT;
+    private static final String AUTO_SELECTION = "auto";
+    public static final String NO_PEERS = "No peers configured";
+
+    private static final Comparator<BgpPeersConfig.PeerConfig> PEER_COMPARATOR =
+            Comparator.comparing(p -> p.ip());
+    public static final String EMPTY = "";
+
+    @Override
+    protected void execute() {
+        NetworkConfigService configService = get(NetworkConfigService.class);
+        CoreService coreService = get(CoreService.class);
+
+        ApplicationId routerAppId = coreService.getAppId(RoutingService.ROUTER_APP_ID);
+        BgpConfig bgpConfig = configService.getConfig(routerAppId, RoutingService.CONFIG_CLASS);
+
+        ApplicationId sdxL3AppId = coreService.getAppId(SdxL3.SDX_L3_APP);
+        BgpPeersConfig peersConfig = configService.
+                getConfig(sdxL3AppId, BgpPeersConfig.class);
+
+        if (bgpConfig == null && peersConfig == null) {
+            print(NO_PEERS);
+            return;
+        }
+
+        List<IpAddress> peeringAddresses = Lists.newArrayList();
+        if (bgpConfig != null) {
+            peeringAddresses = getPeeringAddresses(bgpConfig);
+        }
+
+        List<BgpPeersConfig.PeerConfig> bgpPeers =
+                Lists.newArrayList();
+        if (peersConfig != null) {
+            bgpPeers.addAll(peersConfig.bgpPeers());
+        }
+
+        bgpPeers = mergePeers(peeringAddresses, bgpPeers);
+
+        if (bgpPeers.isEmpty()) {
+            print(NO_PEERS);
+            return;
+        }
+
+        bgpPeers.sort(PEER_COMPARATOR);
+        bgpPeers.forEach(p -> {
+            if (p.name().isPresent()) {
+                if (p.interfaceName() != EMPTY) {
+                    print(NAME_FORMAT, p.name().get(), p.ip(), p.interfaceName());
+                } else {
+                    print(NAME_FORMAT, p.name().get(), p.ip(), AUTO_SELECTION);
+                }
+            } else if (p.interfaceName() != EMPTY) {
+                print(FORMAT, p.ip(), p.interfaceName());
+            } else {
+                print(FORMAT, p.ip(), AUTO_SELECTION);
+            }
+        });
+    }
+
+    private List<IpAddress> getPeeringAddresses(BgpConfig bgpConfig) {
+        List<IpAddress> peeringAddresses = Lists.newArrayList();
+
+        List<BgpConfig.BgpSpeakerConfig> bgpSpeakers =
+                Lists.newArrayList(bgpConfig.bgpSpeakers());
+        bgpSpeakers.forEach(
+                s -> peeringAddresses.addAll(s.peers()));
+
+        return peeringAddresses;
+    }
+
+    private List<BgpPeersConfig.PeerConfig> mergePeers(
+            List<IpAddress> peeringAddresses,
+            List<BgpPeersConfig.PeerConfig> bgpPeers) {
+        peeringAddresses.forEach(a -> {
+            boolean exists = bgpPeers.stream()
+                    .filter(p -> p.ip().equals(a))
+                    .findAny().isPresent();
+            if (!exists) {
+                bgpPeers.add(new BgpPeersConfig
+                        .PeerConfig(Optional.<String>empty(), a, EMPTY));
+            }
+        });
+
+        return bgpPeers;
+    }
+}
diff --git a/sdx-l3/src/main/java/org/onosproject/sdxl3/cli/package-info.java b/sdx-l3/src/main/java/org/onosproject/sdxl3/cli/package-info.java
new file mode 100644
index 0000000..a5216de
--- /dev/null
+++ b/sdx-l3/src/main/java/org/onosproject/sdxl3/cli/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2014-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.
+ */
+
+/**
+ * SDX-L3 command-line handlers.
+ */
+package org.onosproject.sdxl3.cli;
diff --git a/sdx-l3/src/main/java/org/onosproject/sdxl3/config/BgpPeersConfig.java b/sdx-l3/src/main/java/org/onosproject/sdxl3/config/BgpPeersConfig.java
new file mode 100644
index 0000000..dd89aed
--- /dev/null
+++ b/sdx-l3/src/main/java/org/onosproject/sdxl3/config/BgpPeersConfig.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2014-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.sdxl3.config;
+
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.google.common.collect.Sets;
+import org.onlab.packet.IpAddress;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.config.Config;
+
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+public class BgpPeersConfig extends Config<ApplicationId> {
+    public static final String NAME = "name";
+    public static final String IP = "ip";
+    public static final String INTERFACE = "interface";
+
+    /**
+     * Gets the set of configured BGP peers.
+     *
+     * @return BGP peers
+     */
+    public Set<PeerConfig> bgpPeers() {
+        Set<PeerConfig> peers = Sets.newHashSet();
+
+        ArrayNode peersNode = array;
+        peersNode.forEach(jsonNode -> {
+            Optional<String> name;
+            if (jsonNode.get(NAME) == null) {
+                name = Optional.empty();
+            } else {
+                name = Optional.of(jsonNode.get(NAME).asText());
+            }
+
+            peers.add(new PeerConfig(name,
+                    IpAddress.valueOf(jsonNode.path(IP).asText()),
+                    jsonNode.path(INTERFACE).asText()));
+        });
+
+        return peers;
+    }
+
+    /**
+     * Gets the interface name configured for a given BGP peer.
+     *
+     * @param peerAddress IP address of the peer
+     * @return interface name
+     */
+
+    public String getInterfaceNameForPeer(IpAddress peerAddress) {
+        Optional<PeerConfig> match = bgpPeers()
+                .stream()
+                .filter(p -> p.ip().equals(peerAddress))
+                .findAny();
+
+        if (match.isPresent()) {
+            return match.get().interfaceName();
+        } else {
+            return null;
+        }
+    }
+
+
+    /**
+     * Configuration for a BGP peer.
+     */
+    public static class PeerConfig {
+
+        private Optional<String> name;
+        private IpAddress ip;
+        private String interfaceName;
+
+        public PeerConfig(Optional<String> name, IpAddress ip, String interfaceName) {
+            this.name = checkNotNull(name);
+            this.ip = checkNotNull(ip);
+            this.interfaceName = checkNotNull(interfaceName);
+        }
+
+        public Optional<String> name() {
+            return name;
+        }
+
+        public IpAddress ip() {
+            return ip;
+        }
+
+        public String interfaceName() {
+            return interfaceName;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if (obj instanceof PeerConfig) {
+                final PeerConfig that = (PeerConfig) obj;
+                return Objects.equals(this.name, that.name) &&
+                        Objects.equals(this.ip, that.ip) &&
+                        Objects.equals(this.interfaceName, that.interfaceName);
+            }
+            return false;
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(name, ip, interfaceName);
+        }
+    }
+}
diff --git a/sdx-l3/src/main/java/org/onosproject/sdxl3/config/package-info.java b/sdx-l3/src/main/java/org/onosproject/sdxl3/config/package-info.java
new file mode 100644
index 0000000..ebcfa19
--- /dev/null
+++ b/sdx-l3/src/main/java/org/onosproject/sdxl3/config/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2014-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.
+ */
+
+/**
+ * BGP peers configuration interfaces.
+ */
+package org.onosproject.sdxl3.config;
\ No newline at end of file
diff --git a/sdx-l3/src/main/java/org/onosproject/sdxl3/impl/SdxL3PeerManager.java b/sdx-l3/src/main/java/org/onosproject/sdxl3/impl/SdxL3PeerManager.java
new file mode 100644
index 0000000..b881ca2
--- /dev/null
+++ b/sdx-l3/src/main/java/org/onosproject/sdxl3/impl/SdxL3PeerManager.java
@@ -0,0 +1,460 @@
+/*
+ * Copyright 2016 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.sdxl3.impl;
+
+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.Ethernet;
+import org.onlab.packet.IPv4;
+import org.onlab.packet.IPv6;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.TpPort;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.incubator.net.intf.Interface;
+import org.onosproject.incubator.net.intf.InterfaceService;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.config.ConfigFactory;
+import org.onosproject.net.config.NetworkConfigEvent;
+import org.onosproject.net.config.NetworkConfigListener;
+import org.onosproject.net.config.NetworkConfigRegistry;
+import org.onosproject.net.config.NetworkConfigService;
+import org.onosproject.net.config.basics.SubjectFactories;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.host.InterfaceIpAddress;
+import org.onosproject.net.intent.IntentUtils;
+import org.onosproject.net.intent.Key;
+import org.onosproject.net.intent.PointToPointIntent;
+import org.onosproject.routing.IntentSynchronizationService;
+import org.onosproject.routing.RoutingService;
+import org.onosproject.routing.config.BgpConfig;
+import org.onosproject.sdxl3.PeerConnectivityService;
+import org.onosproject.sdxl3.SdxL3;
+import org.onosproject.sdxl3.config.BgpPeersConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Manages the connectivity requirements between peers.
+ */
+@Service
+@Component(immediate = true, enabled = false)
+public class SdxL3PeerManager implements SdxL3PeerService {
+
+    private static final String CONFIG_KEY = "bgpPeers";
+
+    private static final int PRIORITY_OFFSET = 1000;
+
+    private static final String SUFFIX_DST = "dst";
+    private static final String SUFFIX_SRC = "src";
+    private static final String SUFFIX_ICMP = "icmp";
+
+    private static final Logger log = LoggerFactory.getLogger(
+            PeerConnectivityManager.class);
+
+    private static final short BGP_PORT = 179;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected NetworkConfigService configService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected InterfaceService interfaceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected IntentSynchronizationService intentSynchronizer;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected NetworkConfigRegistry registry;
+
+    private ConfigFactory configFactory =
+            new ConfigFactory(SubjectFactories.APP_SUBJECT_FACTORY,
+                    BgpPeersConfig.class, CONFIG_KEY) {
+                @Override
+                public BgpPeersConfig createConfig() {
+                    return new BgpPeersConfig();
+                }
+            };
+
+    private ApplicationId sdxAppId;
+    private ApplicationId routerAppId;
+
+    private final Map<Key, PointToPointIntent> peerIntents = new HashMap<>();
+
+    private final InternalNetworkConfigListener configListener
+            = new InternalNetworkConfigListener();
+
+    @Activate
+    public void activate() {
+        sdxAppId = coreService.getAppId(SdxL3.SDX_L3_APP);
+        routerAppId = coreService.getAppId(RoutingService.ROUTER_APP_ID);
+
+        registry.registerConfigFactory(configFactory);
+
+        configService.addListener(configListener);
+
+        setUpConnectivity();
+
+        log.info("Connectivity with BGP peers established");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        configService.removeListener(configListener);
+
+        log.info("Connectivity with BGP peers stopped");
+    }
+
+    /**
+     * Sets up paths to establish connectivity between all internal
+     * BGP speakers and external BGP peers.
+     */
+    private void setUpConnectivity() {
+        BgpConfig config = configService.getConfig(routerAppId, RoutingService.CONFIG_CLASS);
+
+        if (config == null) {
+            log.warn("No BgpConfig found");
+            return;
+        }
+
+        Map<Key, PointToPointIntent> existingIntents = new HashMap<>(peerIntents);
+
+        for (BgpConfig.BgpSpeakerConfig bgpSpeaker : config.bgpSpeakers()) {
+            log.debug("Start to set up BGP paths for BGP speaker: {}",
+                    bgpSpeaker);
+
+            buildSpeakerIntents(bgpSpeaker).forEach(i -> {
+                PointToPointIntent intent = existingIntents.remove(i.key());
+                if (intent == null || !IntentUtils.intentsAreEqual(i, intent)) {
+                    peerIntents.put(i.key(), i);
+                    intentSynchronizer.submit(i);
+                }
+            });
+        }
+
+        // Remove any remaining intents that we used to have that we don't need
+        // anymore
+        existingIntents.values().forEach(i -> {
+            peerIntents.remove(i.key());
+            intentSynchronizer.withdraw(i);
+        });
+    }
+
+    private Collection<PointToPointIntent> buildSpeakerIntents(BgpConfig.BgpSpeakerConfig speaker) {
+        List<PointToPointIntent> intents = new ArrayList<>();
+
+        for (IpAddress peerAddress : speaker.peers()) {
+            Interface peeringInterface = getInterfaceForPeer(peerAddress);
+
+            if (peeringInterface == null) {
+                log.debug("No peering interface found for peer {} on speaker {}",
+                        peerAddress, speaker);
+                continue;
+            }
+
+            IpAddress peeringAddress = null;
+            for (InterfaceIpAddress address : peeringInterface.ipAddresses()) {
+                if (address.subnetAddress().contains(peerAddress)) {
+                    peeringAddress = address.ipAddress();
+                    break;
+                }
+            }
+
+            checkNotNull(peeringAddress);
+
+            intents.addAll(buildIntents(speaker.connectPoint(), peeringAddress,
+                    peeringInterface.connectPoint(), peerAddress));
+        }
+
+        return intents;
+    }
+
+    private Interface getConfiguredInterfaceForPeer(IpAddress peerAddress) {
+        if (sdxAppId == null) {
+            return null;
+        }
+
+        BgpPeersConfig config = configService.getConfig(sdxAppId, BgpPeersConfig.class);
+        if (config == null) {
+            return null;
+        }
+
+        String intfName = config.getInterfaceNameForPeer(peerAddress);
+        if (intfName != null) {
+            return interfaceService.getInterfaceByName(intfName);
+        }
+        return null;
+    }
+
+    /**
+     * Builds the required intents between the two pairs of connect points and
+     * IP addresses.
+     *
+     * @param portOne the first connect point
+     * @param ipOne the first IP address
+     * @param portTwo the second connect point
+     * @param ipTwo the second IP address
+     * @return the intents to install
+     */
+    private Collection<PointToPointIntent> buildIntents(ConnectPoint portOne,
+                                                        IpAddress ipOne,
+                                                        ConnectPoint portTwo,
+                                                        IpAddress ipTwo) {
+
+        List<PointToPointIntent> intents = new ArrayList<>();
+
+        TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment();
+        TrafficSelector selector;
+        Key key;
+
+        byte tcpProtocol;
+        byte icmpProtocol;
+
+        if (ipOne.isIp4()) {
+            tcpProtocol = IPv4.PROTOCOL_TCP;
+            icmpProtocol = IPv4.PROTOCOL_ICMP;
+        } else {
+            tcpProtocol = IPv6.PROTOCOL_TCP;
+            icmpProtocol = IPv6.PROTOCOL_ICMP6;
+        }
+
+        // Path from BGP speaker to BGP peer matching destination TCP port 179
+        selector = buildSelector(tcpProtocol,
+                ipOne,
+                ipTwo,
+                null,
+                BGP_PORT);
+
+        key = buildKey(ipOne, ipTwo, SUFFIX_DST);
+
+        intents.add(PointToPointIntent.builder()
+                .appId(sdxAppId)
+                .key(key)
+                .selector(selector)
+                .treatment(treatment)
+                .ingressPoint(portOne)
+                .egressPoint(portTwo)
+                .priority(PRIORITY_OFFSET)
+                .build());
+
+        // Path from BGP speaker to BGP peer matching source TCP port 179
+        selector = buildSelector(tcpProtocol,
+                ipOne,
+                ipTwo,
+                BGP_PORT,
+                null);
+
+        key = buildKey(ipOne, ipTwo, SUFFIX_SRC);
+
+        intents.add(PointToPointIntent.builder()
+                .appId(sdxAppId)
+                .key(key)
+                .selector(selector)
+                .treatment(treatment)
+                .ingressPoint(portOne)
+                .egressPoint(portTwo)
+                .priority(PRIORITY_OFFSET)
+                .build());
+
+        // Path from BGP peer to BGP speaker matching destination TCP port 179
+        selector = buildSelector(tcpProtocol,
+                ipTwo,
+                ipOne,
+                null,
+                BGP_PORT);
+
+        key = buildKey(ipTwo, ipOne, SUFFIX_DST);
+
+        intents.add(PointToPointIntent.builder()
+                .appId(sdxAppId)
+                .key(key)
+                .selector(selector)
+                .treatment(treatment)
+                .ingressPoint(portTwo)
+                .egressPoint(portOne)
+                .priority(PRIORITY_OFFSET)
+                .build());
+
+        // Path from BGP peer to BGP speaker matching source TCP port 179
+        selector = buildSelector(tcpProtocol,
+                ipTwo,
+                ipOne,
+                BGP_PORT,
+                null);
+
+        key = buildKey(ipTwo, ipOne, SUFFIX_SRC);
+
+        intents.add(PointToPointIntent.builder()
+                .appId(sdxAppId)
+                .key(key)
+                .selector(selector)
+                .treatment(treatment)
+                .ingressPoint(portTwo)
+                .egressPoint(portOne)
+                .priority(PRIORITY_OFFSET)
+                .build());
+
+        // ICMP path from BGP speaker to BGP peer
+        selector = buildSelector(icmpProtocol,
+                ipOne,
+                ipTwo,
+                null,
+                null);
+
+        key = buildKey(ipOne, ipTwo, SUFFIX_ICMP);
+
+        intents.add(PointToPointIntent.builder()
+                .appId(sdxAppId)
+                .key(key)
+                .selector(selector)
+                .treatment(treatment)
+                .ingressPoint(portOne)
+                .egressPoint(portTwo)
+                .priority(PRIORITY_OFFSET)
+                .build());
+
+        // ICMP path from BGP peer to BGP speaker
+        selector = buildSelector(icmpProtocol,
+                ipTwo,
+                ipOne,
+                null,
+                null);
+
+        key = buildKey(ipTwo, ipOne, SUFFIX_ICMP);
+
+        intents.add(PointToPointIntent.builder()
+                .appId(sdxAppId)
+                .key(key)
+                .selector(selector)
+                .treatment(treatment)
+                .ingressPoint(portTwo)
+                .egressPoint(portOne)
+                .priority(PRIORITY_OFFSET)
+                .build());
+
+        return intents;
+    }
+
+    /**
+     * Builds a traffic selector based on the set of input parameters.
+     *
+     * @param ipProto IP protocol
+     * @param srcIp source IP address
+     * @param dstIp destination IP address
+     * @param srcTcpPort source TCP port, or null if shouldn't be set
+     * @param dstTcpPort destination TCP port, or null if shouldn't be set
+     * @return the new traffic selector
+     */
+    private TrafficSelector buildSelector(byte ipProto, IpAddress srcIp,
+                                          IpAddress dstIp, Short srcTcpPort,
+                                          Short dstTcpPort) {
+        TrafficSelector.Builder builder = DefaultTrafficSelector.builder().matchIPProtocol(ipProto);
+
+        if (dstIp.isIp4()) {
+            builder.matchEthType(Ethernet.TYPE_IPV4)
+                    .matchIPSrc(IpPrefix.valueOf(srcIp, IpPrefix.MAX_INET_MASK_LENGTH))
+                    .matchIPDst(IpPrefix.valueOf(dstIp, IpPrefix.MAX_INET_MASK_LENGTH));
+        } else {
+            builder.matchEthType(Ethernet.TYPE_IPV6)
+                    .matchIPv6Src(IpPrefix.valueOf(srcIp, IpPrefix.MAX_INET6_MASK_LENGTH))
+                    .matchIPv6Dst(IpPrefix.valueOf(dstIp, IpPrefix.MAX_INET6_MASK_LENGTH));
+        }
+
+        if (srcTcpPort != null) {
+            builder.matchTcpSrc(TpPort.tpPort(srcTcpPort));
+        }
+
+        if (dstTcpPort != null) {
+            builder.matchTcpDst(TpPort.tpPort(dstTcpPort));
+        }
+
+        return builder.build();
+    }
+
+    /**
+     * Builds an intent Key for a point-to-point intent based off the source
+     * and destination IP address, as well as a suffix String to distinguish
+     * between different types of intents between the same source and
+     * destination.
+     *
+     * @param srcIp source IP address
+     * @param dstIp destination IP address
+     * @param suffix suffix string
+     * @return intent key
+     */
+    private Key buildKey(IpAddress srcIp, IpAddress dstIp, String suffix) {
+        String keyString = new StringBuilder()
+                .append(srcIp.toString())
+                .append("-")
+                .append(dstIp.toString())
+                .append("-")
+                .append(suffix)
+                .toString();
+
+        return Key.of(keyString, sdxAppId);
+    }
+
+    @Override
+    public Interface getInterfaceForPeer(IpAddress peeringAddress) {
+        Interface peeringInterface = getConfiguredInterfaceForPeer(peeringAddress);
+        if (peeringInterface == null) {
+            peeringInterface = interfaceService.getMatchingInterface(peeringAddress);
+        }
+        return peeringInterface;
+    }
+
+    private class InternalNetworkConfigListener implements NetworkConfigListener {
+
+        @Override
+        public void event(NetworkConfigEvent event) {
+            switch (event.type()) {
+            case CONFIG_REGISTERED:
+                break;
+            case CONFIG_UNREGISTERED:
+                break;
+            case CONFIG_ADDED:
+            case CONFIG_UPDATED:
+            case CONFIG_REMOVED:
+                if (event.configClass() == RoutingService.CONFIG_CLASS) {
+                    setUpConnectivity();
+                }
+                break;
+            default:
+                break;
+            }
+        }
+    }
+
+}
diff --git a/sdx-l3/src/main/java/org/onosproject/sdxl3/impl/package-info.java b/sdx-l3/src/main/java/org/onosproject/sdxl3/impl/package-info.java
new file mode 100644
index 0000000..d172822
--- /dev/null
+++ b/sdx-l3/src/main/java/org/onosproject/sdxl3/impl/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2016 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 BGP peers connectivity functionality.
+ */
+package org.onosproject.sdxl3.impl;
\ No newline at end of file
diff --git a/sdx-l3/src/main/java/org/onosproject/sdxl3/package-info.java b/sdx-l3/src/main/java/org/onosproject/sdxl3/package-info.java
new file mode 100644
index 0000000..eb7b599
--- /dev/null
+++ b/sdx-l3/src/main/java/org/onosproject/sdxl3/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2014-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.
+ */
+
+/**
+ * SDX-L3 application for GEANT.
+ */
+package org.onosproject.sdxl3;
diff --git a/sdx-l3/src/main/resources/OSGI-INF/blueprint/shell-config.xml b/sdx-l3/src/main/resources/OSGI-INF/blueprint/shell-config.xml
new file mode 100644
index 0000000..4757f78
--- /dev/null
+++ b/sdx-l3/src/main/resources/OSGI-INF/blueprint/shell-config.xml
@@ -0,0 +1,23 @@
+<!--
+  ~ Copyright 2014-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.sdxl3.cli.BgpPeersListCommand"/>
+      </command>
+  </command-bundle>
+</blueprint>
diff --git a/sdx-l3/src/main/resources/config-examples/README b/sdx-l3/src/main/resources/config-examples/README
new file mode 100644
index 0000000..061d0c6
--- /dev/null
+++ b/sdx-l3/src/main/resources/config-examples/README
@@ -0,0 +1,2 @@
+The SDX-L3 configuration should be copied to network configuration file:
+  $ONOS_HOME/tools/package/config/network-cfg.json
diff --git a/sdx-l3/src/main/resources/config-examples/network-cfg.json b/sdx-l3/src/main/resources/config-examples/network-cfg.json
new file mode 100644
index 0000000..a51ef92
--- /dev/null
+++ b/sdx-l3/src/main/resources/config-examples/network-cfg.json
@@ -0,0 +1,72 @@
+{
+  "ports" : {
+    "of:00000000000000a1/1" : {
+      "interfaces" : [
+        {
+          "name" : "AS1-conn1",
+          "ips"  : [ "10.0.1.101/24" ],
+          "mac"  : "00:00:00:00:00:01"
+        }
+      ]
+    },
+    "of:00000000000000a2/1" : {
+      "interfaces" : [
+        {
+          "name" : "AS1-conn2",
+          "ips"  : [ "10.0.1.101/24" ],
+          "mac"  : "00:00:00:00:00:01"
+        }
+      ]
+    },
+    "of:00000000000000a5/1" : {
+      "interfaces" : [
+        {
+          "name" : "AS3-conn1",
+          "ips"  : [ "10.0.3.101/24" ],
+          "mac"  : "00:00:00:00:00:01"
+        }
+      ]
+    },
+    "of:00000000000000a6/1" : {
+      "interfaces" : [
+        {
+          "name" : "AS4-conn1",
+          "ips"  : [ "10.0.4.101/24" ],
+          "mac"  : "00:00:00:00:00:01"
+        }
+      ]
+    }
+  },
+  "apps" : {
+    "org.onosproject.sdxl3" : {
+      "bgpPeers" : [
+        {
+          "name" : "AS1-Router1",
+          "ip" : "10.0.1.1",
+          "interface" : "AS1-conn1"
+        },
+        {
+          "name" : "AS1-Router2",
+          "ip" : "10.0.1.129",
+          "interface" : "AS1-conn2"
+        }
+      ]
+    },
+    "org.onosproject.router" : {
+      "bgp" : {
+        "bgpSpeakers" : [
+          {
+            "name" : "bgp",
+            "connectPoint" : "of:00000000000000a3/1",
+            "peers" : [
+              "10.0.1.1",
+              "10.0.1.129",
+              "10.0.3.1",
+              "10.0.4.1"
+            ]
+          }
+        ]
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/sdx-l3/src/main/resources/config-examples/route-server_network-cfg.json b/sdx-l3/src/main/resources/config-examples/route-server_network-cfg.json
new file mode 100644
index 0000000..c2ea2e3
--- /dev/null
+++ b/sdx-l3/src/main/resources/config-examples/route-server_network-cfg.json
@@ -0,0 +1,52 @@
+{
+  "ports" : {
+    "of:00000000000000a1/1" : {
+      "interfaces" : [
+        {
+          "name" : "AS 65001",
+          "ips"  : [ "10.0.0.3/24" ],
+          "mac"  : "00:00:00:00:00:01"
+        }
+      ]
+    },
+    "of:00000000000000a1/2" : {
+      "interfaces" : [
+        {
+          "name" : "AS 65002",
+          "ips"  : [ "10.0.0.3/24" ],
+          "mac"  : "00:00:00:00:00:01"
+        }
+      ]
+    }
+  },
+  "apps" : {
+    "org.onosproject.sdxl3" : {
+      "bgpPeers" : [
+        {
+          "name" : "AS65001-R1",
+          "ip" : "10.0.0.1",
+          "interface" : "AS 65001"
+        },
+        {
+          "name" : "AS65002-R2",
+          "ip" : "10.0.0.2",
+          "interface" : "AS 65002"
+        }
+      ]
+    },
+    "org.onosproject.router" : {
+      "bgp" : {
+        "bgpSpeakers" : [
+          {
+            "name" : "bgp",
+            "connectPoint" : "of:00000000000000a1/3",
+            "peers" : [
+              "10.0.0.1",
+              "10.0.0.2"
+            ]
+          }
+        ]
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/sdx-l3/src/test/java/org/onosproject/sdxl3/BgpPeersConfigTest.java b/sdx-l3/src/test/java/org/onosproject/sdxl3/BgpPeersConfigTest.java
new file mode 100644
index 0000000..fc2a6ed
--- /dev/null
+++ b/sdx-l3/src/test/java/org/onosproject/sdxl3/BgpPeersConfigTest.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2014-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.sdxl3;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.collect.Sets;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.IpAddress;
+import org.onosproject.TestApplicationId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.incubator.net.config.basics.ConfigException;
+import org.onosproject.net.config.Config;
+import org.onosproject.net.config.ConfigApplyDelegate;
+import org.onosproject.sdxl3.config.BgpPeersConfig;
+
+import java.util.Optional;
+import java.util.Set;
+
+import static junit.framework.TestCase.assertEquals;
+
+public class BgpPeersConfigTest {
+    private static final ApplicationId APP_ID =
+            new TestApplicationId(SdxL3.SDX_L3_APP);
+    private static final String KEY = "key";
+
+    public static final String NAME1 = "peer1";
+    public static final String IP1_STRING = "10.0.1.1";
+    public static final IpAddress IP1 = IpAddress.valueOf(IP1_STRING);
+    public static final String INTF1 = "conn_point1";
+
+    public static final String IP2_STRING = "10.0.2.1";
+    public static final IpAddress IP2 = IpAddress.valueOf(IP2_STRING);
+    public static final String INTF2 = "conn_point2";
+
+    private static final String JSON_TREE = "[{" +
+            "\"" + BgpPeersConfig.NAME + "\" : \"" + NAME1 + "\", " +
+            "\"" + BgpPeersConfig.IP + "\" : \"" + IP1_STRING + "\", " +
+            "\"" + BgpPeersConfig.INTERFACE + "\" : \"" + INTF1 + "\"}, " +
+            "{ \"" + BgpPeersConfig.IP + "\" : \"" + IP2_STRING + "\", " +
+            "\"" + BgpPeersConfig.INTERFACE + "\" : \"" + INTF2 + "\"}] ";
+
+    BgpPeersConfig peersConfig = new BgpPeersConfig();
+
+    private final ConfigApplyDelegate delegate = new MockCfgDelegate();
+    private final ObjectMapper mapper = new ObjectMapper();
+
+    @Before
+    public void setUp()  throws Exception {
+        JsonNode node = new ObjectMapper().readTree(JSON_TREE);
+        peersConfig.init(APP_ID, KEY, node, mapper, delegate);
+    }
+
+    /**
+     * Tests if peers can be retrieved from JSON.
+     */
+    @Test
+    public void testBgpPeers() throws Exception {
+        assertEquals(createPeers(), peersConfig.bgpPeers());
+    }
+
+    /**
+     * Tests if interface name can be retrieved for given peer's IP.
+     */
+    @Test
+    public void testGetInterfaceNameForPeer() throws Exception {
+        assertEquals(INTF1, peersConfig.getInterfaceNameForPeer(IP1));
+    }
+
+    private Set<BgpPeersConfig.PeerConfig> createPeers() throws ConfigException {
+        Set<BgpPeersConfig.PeerConfig> peers = Sets.newHashSet();
+
+        peers.add(new BgpPeersConfig.PeerConfig(Optional.of(NAME1), IP1, INTF1));
+        peers.add(new BgpPeersConfig.PeerConfig(Optional.empty(), IP2, INTF2));
+
+        return peers;
+    }
+
+    private class MockCfgDelegate implements ConfigApplyDelegate {
+
+        @Override
+        public void onApply(@SuppressWarnings("rawtypes") Config config) {
+            config.apply();
+        }
+
+    }
+}
+
