diff --git a/apps/openstacknetworking/openstackswitching/src/main/java/org/onosproject/openstacknetworking/switching/OpenstackArpHandler.java b/apps/openstacknetworking/openstackswitching/src/main/java/org/onosproject/openstacknetworking/switching/OpenstackArpHandler.java
new file mode 100644
index 0000000..415b6d2
--- /dev/null
+++ b/apps/openstacknetworking/openstackswitching/src/main/java/org/onosproject/openstacknetworking/switching/OpenstackArpHandler.java
@@ -0,0 +1,163 @@
+/*
+* Copyright 2015-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.openstacknetworking.switching;
+
+import org.onlab.packet.ARP;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onosproject.net.Host;
+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.openstacknetworking.OpenstackNetworkingService;
+import org.onosproject.openstacknetworking.OpenstackPort;
+import org.onosproject.openstacknetworking.OpenstackPortInfo;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import java.nio.ByteBuffer;
+import java.util.Collection;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Handles ARP packet from VMs.
+ */
+public class OpenstackArpHandler {
+
+    private static Logger log = LoggerFactory
+            .getLogger(OpenstackArpHandler.class);
+    private static final MacAddress GATEWAY_MAC = MacAddress.valueOf("1f:1f:1f:1f:1f:1f");
+    private PacketService packetService;
+    private OpenstackNetworkingService openstackService;
+    private HostService hostService;
+
+    /**
+     * Returns OpenstackArpHandler reference.
+     *
+     * @param openstackService OpenstackNetworkingService reference
+     * @param packetService PacketService reference
+     * @param hostService host service
+     */
+    public OpenstackArpHandler(OpenstackNetworkingService openstackService, PacketService packetService,
+                               HostService hostService) {
+        this.openstackService = openstackService;
+        this.packetService = packetService;
+        this.hostService = hostService;
+    }
+
+    /**
+     * Processes ARP request packets.
+     * It checks if the target IP is owned by a known host first and then ask to
+     * OpenStack if it's not. This ARP proxy does not support overlapping IP.
+     *
+     * @param pkt ARP request packet
+     */
+    public void processPacketIn(InboundPacket pkt, Collection<OpenstackPortInfo> openstackPortInfoCollection) {
+        Ethernet ethRequest = pkt.parsed();
+        ARP arp = (ARP) ethRequest.getPayload();
+
+        if (arp.getOpCode() != ARP.OP_REQUEST) {
+            return;
+        }
+
+        IpAddress sourceIp = Ip4Address.valueOf(arp.getSenderProtocolAddress());
+        MacAddress srcMac = MacAddress.valueOf(arp.getSenderHardwareAddress());
+        OpenstackPortInfo portInfo = openstackPortInfoCollection.stream()
+                .filter(p -> p.ip().equals(sourceIp) && p.mac().equals(srcMac)).findFirst().orElse(null);
+        IpAddress targetIp = Ip4Address.valueOf(arp.getTargetProtocolAddress());
+
+        MacAddress dstMac;
+
+        if (targetIp.equals(portInfo == null ? null : portInfo.gatewayIP())) {
+            dstMac = GATEWAY_MAC;
+        } else {
+            dstMac = getMacFromHostService(targetIp);
+            if (dstMac == null) {
+                dstMac = getMacFromOpenstack(targetIp);
+            }
+        }
+
+        if (dstMac == null) {
+            log.debug("Failed to find MAC address for {}", targetIp.toString());
+            return;
+        }
+
+        Ethernet ethReply = ARP.buildArpReply(targetIp.getIp4Address(),
+                                              dstMac,
+                                              ethRequest);
+
+        TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                .setOutput(pkt.receivedFrom().port())
+                .build();
+
+        packetService.emit(new DefaultOutboundPacket(
+                pkt.receivedFrom().deviceId(),
+                treatment,
+                ByteBuffer.wrap(ethReply.serialize())));
+    }
+
+    /**
+     * Returns MAC address of a host with a given target IP address by asking to
+     * OpenStack. It does not support overlapping IP.
+     *
+     * @param targetIp target ip address
+     * @return mac address, or null if it fails to fetch the mac
+     */
+    private MacAddress getMacFromOpenstack(IpAddress targetIp) {
+        checkNotNull(targetIp);
+
+        OpenstackPort openstackPort = openstackService.ports()
+                .stream()
+                .filter(port -> port.fixedIps().containsValue(targetIp))
+                .findFirst()
+                .orElse(null);
+
+        if (openstackPort != null) {
+            log.debug("Found MAC from OpenStack for {}", targetIp.toString());
+            return openstackPort.macAddress();
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Returns MAC address of a host with a given target IP address by asking to
+     * host service. It does not support overlapping IP.
+     *
+     * @param targetIp target ip
+     * @return mac address, or null if it fails to find the mac
+     */
+    private MacAddress getMacFromHostService(IpAddress targetIp) {
+        checkNotNull(targetIp);
+
+        Host host = hostService.getHostsByIp(targetIp)
+                .stream()
+                .findFirst()
+                .orElse(null);
+
+        if (host != null) {
+            log.debug("Found MAC from host service for {}", targetIp.toString());
+            return host.mac();
+        } else {
+            return null;
+        }
+    }
+}
diff --git a/apps/openstacknetworking/openstackswitching/src/main/java/org/onosproject/openstacknetworking/switching/OpenstackSwitchingManager.java b/apps/openstacknetworking/openstackswitching/src/main/java/org/onosproject/openstacknetworking/switching/OpenstackSwitchingManager.java
new file mode 100644
index 0000000..52b0436
--- /dev/null
+++ b/apps/openstacknetworking/openstackswitching/src/main/java/org/onosproject/openstacknetworking/switching/OpenstackSwitchingManager.java
@@ -0,0 +1,491 @@
+/*
+ * Copyright 2015-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.openstacknetworking.switching;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+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.Ip4Address;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.dhcp.DhcpService;
+import org.onosproject.event.AbstractEvent;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Host;
+import org.onosproject.net.Port;
+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.device.DeviceEvent;
+import org.onosproject.net.device.DeviceListener;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.driver.DriverService;
+import org.onosproject.net.flowobjective.FlowObjectiveService;
+import org.onosproject.net.host.HostEvent;
+import org.onosproject.net.host.HostListener;
+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.openstacknetworking.OpenstackNetwork;
+import org.onosproject.openstacknetworking.OpenstackNetworkingConfig;
+import org.onosproject.openstacknetworking.OpenstackNetworkingService;
+import org.onosproject.openstacknetworking.OpenstackPort;
+import org.onosproject.openstacknetworking.OpenstackPortInfo;
+import org.onosproject.openstacknetworking.OpenstackSecurityGroup;
+import org.onosproject.openstacknetworking.OpenstackSubnet;
+import org.onosproject.openstacknetworking.OpenstackSwitchingService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import java.util.List;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import static org.onosproject.net.config.basics.SubjectFactories.APP_SUBJECT_FACTORY;
+import static org.onlab.util.Tools.groupedThreads;
+
+@Service
+@Component(immediate = true)
+/**
+ * Populates forwarding rules for VMs created by Openstack.
+ */
+public class OpenstackSwitchingManager implements OpenstackSwitchingService {
+
+    private final Logger log = LoggerFactory
+            .getLogger(getClass());
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected PacketService packetService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DeviceService deviceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected HostService hostService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected FlowObjectiveService flowObjectiveService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DhcpService dhcpService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected NetworkConfigRegistry cfgService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DriverService driverService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected OpenstackNetworkingService openstackService;
+
+    public static final String PORTNAME_PREFIX_VM = "tap";
+    public static final String PORTNAME_PREFIX_ROUTER = "qr-";
+    public static final String PORTNAME_PREFIX_TUNNEL = "vxlan";
+    public static final String PORTNAME = "portName";
+    private static final String ROUTER_INTERFACE = "network:router_interface";
+    public static final String DEVICE_OWNER_GATEWAY = "network:router_gateway";
+
+    private ApplicationId appId;
+    private boolean doNotPushFlows;
+    private Ip4Address neutronServer;
+    private Ip4Address keystoneServer;
+    private String userName;
+    private String password;
+    private String physicalRouterMac;
+    private OpenstackArpHandler arpHandler;
+
+    private ExecutorService deviceEventExcutorService =
+            Executors.newSingleThreadExecutor(groupedThreads("onos/openstackswitching", "device-event"));
+    private ExecutorService networkEventExcutorService =
+            Executors.newSingleThreadExecutor(groupedThreads("onos/openstackswitching", "config-event"));
+
+    private InternalPacketProcessor internalPacketProcessor = new InternalPacketProcessor();
+    private InternalDeviceListener internalDeviceListener = new InternalDeviceListener();
+    private InternalConfigListener internalConfigListener = new InternalConfigListener();
+    private InternalHostListener internalHostListener = new InternalHostListener();
+
+
+    private final Set<ConfigFactory> factories = ImmutableSet.of(
+            new ConfigFactory<ApplicationId, OpenstackNetworkingConfig>(APP_SUBJECT_FACTORY,
+                    OpenstackNetworkingConfig.class,
+                    "openstackswitching") {
+                @Override
+                public OpenstackNetworkingConfig createConfig() {
+                    return new OpenstackNetworkingConfig();
+                }
+            }
+    );
+
+
+    private Map<String, OpenstackPortInfo> openstackPortInfoMap = Maps.newHashMap();
+
+    @Activate
+    protected void activate() {
+        appId = coreService
+                .registerApplication("org.onosproject.openstackswitching");
+
+        factories.forEach(cfgService::registerConfigFactory);
+        packetService.addProcessor(internalPacketProcessor, PacketProcessor.director(1));
+        deviceService.addListener(internalDeviceListener);
+        hostService.addListener(internalHostListener);
+        cfgService.addListener(internalConfigListener);
+
+        internalConfigListener.configureNetwork();
+
+        log.info("Started");
+    }
+
+    @Deactivate
+    protected void deactivate() {
+        packetService.removeProcessor(internalPacketProcessor);
+        deviceService.removeListener(internalDeviceListener);
+        cfgService.removeListener(internalConfigListener);
+        factories.forEach(cfgService::unregisterConfigFactory);
+
+        deviceEventExcutorService.shutdown();
+
+        log.info("Stopped");
+    }
+
+    @Override
+    public void createPorts(OpenstackPort openstackPort) {
+
+        if (!openstackPort.deviceOwner().equals(ROUTER_INTERFACE)
+            && !openstackPort.deviceOwner().equals(DEVICE_OWNER_GATEWAY)) {
+            if (!openstackPort.fixedIps().isEmpty()) {
+                registerDhcpInfo(openstackPort);
+            }
+        }
+
+        if (!openstackPort.securityGroups().isEmpty()) {
+            openstackPort.securityGroups().forEach(sgId -> {
+                OpenstackSecurityGroup sg = openstackService.getSecurityGroup(sgId);
+                log.debug("SecurityGroup : {}", sg.toString());
+            });
+        }
+    }
+
+    @Override
+    public void removePort(String uuid) {
+        // When VMs are remvoed, the flow rules for the VMs are removed using ONOS port update event.
+        // But, when router is removed, no ONOS port event occurs and we need to use Neutron port event.
+        // Here we should not touch any rules for VMs.
+        log.debug("port {} was removed", uuid);
+
+        String routerPortName = PORTNAME_PREFIX_ROUTER + uuid.substring(0, 11);
+        OpenstackPortInfo routerPortInfo = openstackPortInfoMap.get(routerPortName);
+        if (routerPortInfo != null) {
+            dhcpService.removeStaticMapping(routerPortInfo.mac());
+            if (!doNotPushFlows) {
+                deviceService.getPorts(routerPortInfo.deviceId()).forEach(port -> {
+                    String pName = port.annotations().value("portName");
+                    if (pName.equals(routerPortName)) {
+                        OpenstackSwitchingRulePopulator rulePopulator =
+                                new OpenstackSwitchingRulePopulator(appId, flowObjectiveService,
+                                        deviceService, openstackService, driverService);
+
+                        rulePopulator.removeSwitchingRules(doNotPushFlows, port, openstackPortInfoMap);
+                        openstackPortInfoMap.remove(routerPortName);
+                        return;
+                    }
+                });
+            }
+        }
+    }
+
+    @Override
+    public void updatePort(OpenstackPort openstackPort) {
+    }
+
+    @Override
+    public void createNetwork(OpenstackNetwork openstackNetwork) {
+    }
+
+    @Override
+    public void createSubnet(OpenstackSubnet openstackSubnet) {
+    }
+
+    @Override
+    public Map<String, OpenstackPortInfo> openstackPortInfo() {
+        return ImmutableMap.copyOf(this.openstackPortInfoMap);
+    }
+
+    private void processDeviceAdded(Device device) {
+        log.debug("device {} is added", device.id());
+    }
+
+    private void processPortUpdated(Device device, Port port) {
+        if (!port.annotations().value(PORTNAME).equals(PORTNAME_PREFIX_TUNNEL) && !doNotPushFlows) {
+            if (port.isEnabled() || port.annotations().value(PORTNAME).startsWith(PORTNAME_PREFIX_ROUTER)) {
+                OpenstackSwitchingRulePopulator rulePopulator =
+                        new OpenstackSwitchingRulePopulator(appId, flowObjectiveService,
+                                deviceService, openstackService, driverService);
+
+                rulePopulator.populateSwitchingRules(doNotPushFlows, device, port);
+                updatePortMap(device.id(), port, openstackService.networks(), openstackService.subnets(),
+                        rulePopulator.openstackPort(port));
+
+                //In case portupdate event is driven by vm shutoff from openstack
+            } else if (!port.isEnabled() && openstackPortInfoMap.containsKey(port.annotations().value(PORTNAME))) {
+                log.debug("Flowrules according to the port {} were removed", port.number().toString());
+                OpenstackSwitchingRulePopulator rulePopulator =
+                        new OpenstackSwitchingRulePopulator(appId, flowObjectiveService,
+                                deviceService, openstackService, driverService);
+
+                rulePopulator.removeSwitchingRules(doNotPushFlows, port, openstackPortInfoMap);
+                dhcpService.removeStaticMapping(openstackPortInfoMap.get(port.annotations().value(PORTNAME)).mac());
+                openstackPortInfoMap.remove(port.annotations().value(PORTNAME));
+            }
+        }
+    }
+
+    private void processPortRemoved(Device device, Port port) {
+        log.debug("port {} is removed", port.toString());
+    }
+
+    private void initializeFlowRules() {
+        OpenstackSwitchingRulePopulator rulePopulator =
+                new OpenstackSwitchingRulePopulator(appId, flowObjectiveService,
+                        deviceService, openstackService, driverService);
+
+        Collection<OpenstackNetwork> networks = openstackService.networks();
+        Collection<OpenstackSubnet> subnets = openstackService.subnets();
+
+        deviceService.getDevices().forEach(device -> {
+                    log.debug("device {} num of ports {} ", device.id(),
+                            deviceService.getPorts(device.id()).size());
+                    deviceService.getPorts(device.id()).stream()
+                            .filter(port -> port.annotations().value(PORTNAME).startsWith(PORTNAME_PREFIX_VM) ||
+                                    port.annotations().value(PORTNAME).startsWith(PORTNAME_PREFIX_ROUTER))
+                            .forEach(vmPort -> {
+                                        OpenstackPort osPort = rulePopulator.openstackPort(vmPort);
+                                        if (osPort != null && !osPort.deviceOwner().equals(DEVICE_OWNER_GATEWAY)) {
+                                            if (!doNotPushFlows) {
+                                                rulePopulator.populateSwitchingRules(doNotPushFlows, device, vmPort);
+                                                updatePortMap(device.id(), vmPort, networks, subnets, osPort);
+                                            }
+                                            registerDhcpInfo(osPort);
+                                        } else {
+                                            log.warn("No openstackPort information for port {}", vmPort);
+                                        }
+                                    }
+                            );
+                }
+        );
+    }
+
+    private void updatePortMap(DeviceId deviceId, Port port, Collection<OpenstackNetwork> networks,
+                               Collection<OpenstackSubnet> subnets, OpenstackPort openstackPort) {
+        long vni = Long.parseLong(networks.stream()
+                .filter(n -> n.id().equals(openstackPort.networkId()))
+                .findAny().orElse(null).segmentId());
+
+        OpenstackSubnet openstackSubnet = subnets.stream()
+                .filter(n -> n.networkId().equals(openstackPort.networkId()))
+                .findFirst().get();
+
+        Ip4Address gatewayIPAddress = Ip4Address.valueOf(openstackSubnet.gatewayIp());
+
+        OpenstackPortInfo.Builder portBuilder = OpenstackPortInfo.builder()
+                .setDeviceId(deviceId)
+                .setHostIp((Ip4Address) openstackPort.fixedIps().values().stream().findFirst().orElse(null))
+                .setHostMac(openstackPort.macAddress())
+                .setVni(vni)
+                .setGatewayIP(gatewayIPAddress);
+
+        openstackPortInfoMap.putIfAbsent(port.annotations().value(PORTNAME),
+                portBuilder.build());
+    }
+
+    private void processHostRemoved(Host host) {
+        log.debug("host {} was removed", host.toString());
+    }
+
+    private void registerDhcpInfo(OpenstackPort openstackPort) {
+        Ip4Address ip4Address;
+        Ip4Address subnetMask;
+        Ip4Address gatewayIPAddress;
+        Ip4Address dhcpServer;
+        Ip4Address domainServer;
+        OpenstackSubnet openstackSubnet;
+
+        ip4Address = (Ip4Address) openstackPort.fixedIps().values().stream().findFirst().orElse(null);
+
+        openstackSubnet = openstackService.subnets().stream()
+                .filter(n -> n.networkId().equals(openstackPort.networkId()))
+                .findFirst().get();
+
+        subnetMask = Ip4Address.valueOf(buildSubnetMask(openstackSubnet.cidr()));
+        gatewayIPAddress = Ip4Address.valueOf(openstackSubnet.gatewayIp());
+        dhcpServer = gatewayIPAddress;
+        // TODO: supports multiple DNS servers
+        if (openstackSubnet.dnsNameservers().isEmpty()) {
+            domainServer = Ip4Address.valueOf("8.8.8.8");
+        } else {
+            domainServer = openstackSubnet.dnsNameservers().get(0);
+        }
+        List<Ip4Address> options = Lists.newArrayList();
+        options.add(subnetMask);
+        options.add(dhcpServer);
+        options.add(gatewayIPAddress);
+        options.add(domainServer);
+
+        dhcpService.setStaticMapping(openstackPort.macAddress(), ip4Address, true, options);
+    }
+
+    private byte[] buildSubnetMask(String cidr) {
+        int prefix;
+        String[] parts = cidr.split("/");
+        prefix = Integer.parseInt(parts[1]);
+        int mask = 0xffffffff << (32 - prefix);
+        byte[] bytes = new byte[]{(byte) (mask >>> 24),
+                (byte) (mask >> 16 & 0xff), (byte) (mask >> 8 & 0xff), (byte) (mask & 0xff)};
+
+        return bytes;
+    }
+
+
+
+    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 != null && ethernet.getEtherType() == Ethernet.TYPE_ARP) {
+                arpHandler.processPacketIn(pkt, openstackPortInfoMap.values());
+            }
+        }
+    }
+
+    private class InternalHostListener implements HostListener {
+
+        @Override
+        public void event(HostEvent hostEvent) {
+            deviceEventExcutorService.execute(new InternalEventHandler(hostEvent));
+        }
+    }
+
+    private class InternalDeviceListener implements DeviceListener {
+
+        @Override
+        public void event(DeviceEvent deviceEvent) {
+            deviceEventExcutorService.execute(new InternalEventHandler(deviceEvent));
+        }
+    }
+
+    private class InternalEventHandler implements Runnable {
+
+        volatile AbstractEvent event;
+
+        InternalEventHandler(AbstractEvent event) {
+            this.event = event;
+        }
+
+        @Override
+        public void run() {
+
+            if (event instanceof  DeviceEvent) {
+                DeviceEvent deviceEvent = (DeviceEvent) event;
+
+                switch (deviceEvent.type()) {
+                    case DEVICE_ADDED:
+                        processDeviceAdded((Device) deviceEvent.subject());
+                        break;
+                    case DEVICE_AVAILABILITY_CHANGED:
+                        Device device = (Device) deviceEvent.subject();
+                        if (deviceService.isAvailable(device.id())) {
+                            processDeviceAdded(device);
+                        }
+                        break;
+                    case PORT_ADDED:
+                        processPortUpdated((Device) deviceEvent.subject(), deviceEvent.port());
+                        break;
+                    case PORT_UPDATED:
+                        processPortUpdated((Device) deviceEvent.subject(), deviceEvent.port());
+                        break;
+                    case PORT_REMOVED:
+                        processPortRemoved((Device) deviceEvent.subject(), deviceEvent.port());
+                        break;
+                    default:
+                        break;
+                }
+            } else if (event instanceof HostEvent) {
+                HostEvent hostEvent = (HostEvent) event;
+
+                switch (hostEvent.type()) {
+                    case HOST_REMOVED:
+                        processHostRemoved((Host) hostEvent.subject());
+                        break;
+                    default:
+                        break;
+                }
+            }
+        }
+    }
+
+    private class InternalConfigListener implements NetworkConfigListener {
+
+        public void configureNetwork() {
+            OpenstackNetworkingConfig cfg =
+                    cfgService.getConfig(appId, OpenstackNetworkingConfig.class);
+            if (cfg == null) {
+                log.error("There is no openstack server information in config.");
+                return;
+            }
+
+            doNotPushFlows = cfg.doNotPushFlows();
+            physicalRouterMac = cfg.physicalRouterMac();
+            openstackService.setConfigurations(cfg.neutronServer(), cfg.keystoneServer(),
+                    cfg.userName(), cfg.password());
+            arpHandler = new OpenstackArpHandler(openstackService, packetService, hostService);
+            initializeFlowRules();
+        }
+
+        @Override
+        public void event(NetworkConfigEvent event) {
+            if (((event.type() == NetworkConfigEvent.Type.CONFIG_ADDED ||
+            event.type() == NetworkConfigEvent.Type.CONFIG_UPDATED)) &&
+                    event.configClass().equals(OpenstackNetworkingConfig.class)) {
+
+                log.info("Network configuration changed");
+                networkEventExcutorService.execute(this::configureNetwork);
+            }
+        }
+    }
+}
diff --git a/apps/openstacknetworking/openstackswitching/src/main/java/org/onosproject/openstacknetworking/switching/OpenstackSwitchingRulePopulator.java b/apps/openstacknetworking/openstackswitching/src/main/java/org/onosproject/openstacknetworking/switching/OpenstackSwitchingRulePopulator.java
new file mode 100644
index 0000000..258b24c
--- /dev/null
+++ b/apps/openstacknetworking/openstackswitching/src/main/java/org/onosproject/openstacknetworking/switching/OpenstackSwitchingRulePopulator.java
@@ -0,0 +1,500 @@
+/*
+* Copyright 2015 Open Networking Laboratory
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package org.onosproject.openstacknetworking.switching;
+
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.Ip4Address;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Port;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.behaviour.ExtensionTreatmentResolver;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.driver.DefaultDriverData;
+import org.onosproject.net.driver.DefaultDriverHandler;
+import org.onosproject.net.driver.Driver;
+import org.onosproject.net.driver.DriverHandler;
+import org.onosproject.net.driver.DriverService;
+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.flow.instructions.ExtensionTreatment;
+import org.onosproject.net.flow.instructions.ExtensionPropertyException;
+import org.onosproject.net.flow.instructions.ExtensionTreatmentType;
+import org.onosproject.net.flowobjective.DefaultForwardingObjective;
+import org.onosproject.net.flowobjective.FlowObjectiveService;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.openstacknetworking.OpenstackNetwork;
+import org.onosproject.openstacknetworking.OpenstackNetworkingService;
+import org.onosproject.openstacknetworking.OpenstackPort;
+import org.onosproject.openstacknetworking.OpenstackPortInfo;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ * Populates switching flow rules.
+ */
+public class OpenstackSwitchingRulePopulator {
+
+    private static Logger log = LoggerFactory
+            .getLogger(OpenstackSwitchingRulePopulator.class);
+    private static final int SWITCHING_RULE_PRIORITY = 30000;
+    private static final int EAST_WEST_ROUTING_RULE_PRIORITY = 29000;
+    private static final int TUNNELTAG_RULE_PRIORITY = 30000;
+
+    private FlowObjectiveService flowObjectiveService;
+    private DriverService driverService;
+    private DeviceService deviceService;
+    private ApplicationId appId;
+
+    private Collection<OpenstackNetwork> openstackNetworkList;
+    private Collection<OpenstackPort> openstackPortList;
+
+    /**
+     * Creates OpenstackSwitchingRulPopulator.
+     *
+     * @param appId application id
+     * @param flowObjectiveService FlowObjectiveService reference
+     * @param deviceService DeviceService reference
+     * @param driverService DriverService reference
+     */
+    public OpenstackSwitchingRulePopulator(ApplicationId appId,
+                                           FlowObjectiveService flowObjectiveService,
+                                           DeviceService deviceService,
+                                           OpenstackNetworkingService openstackService,
+                                           DriverService driverService) {
+        this.flowObjectiveService = flowObjectiveService;
+        this.deviceService = deviceService;
+        this.driverService = driverService;
+        this.appId = appId;
+
+        openstackNetworkList = openstackService.networks();
+        openstackPortList = openstackService.ports();
+    }
+
+
+    /**
+     * Populates flow rules for the VM created.
+     *
+     * @param doNotPushFlow true to suppress push of initial flows
+     * @param device device to populate rules to
+     * @param port port for the VM created
+     */
+    public void populateSwitchingRules(boolean doNotPushFlow, Device device, Port port) {
+        if (doNotPushFlow) {
+            return;
+        }
+        populateFlowRulesForTunnelTag(device, port);
+        populateFlowRulesForTrafficToSameCnode(device, port);
+        populateFlowRulesForTrafficToDifferentCnode(device, port);
+    }
+
+    /**
+     * Populate the flow rules for tagging tunnelId according to which inport is came from.
+     *
+     * @param device device to put the rules
+     * @param port port info of the VM
+     */
+    private void populateFlowRulesForTunnelTag(Device device, Port port) {
+        Ip4Address vmIp = getFixedIpAddressForPort(port.annotations().value("portName"));
+        String portName = port.annotations().value("portName");
+        String vni = getVniForPort(portName);
+
+        if (vmIp != null) {
+            setFlowRuleForTunnelTag(device.id(), port, vni);
+        }
+    }
+
+    private void setFlowRuleForTunnelTag(DeviceId deviceId, Port port, String vni) {
+
+        TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
+        TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
+
+        sBuilder.matchEthType(Ethernet.TYPE_IPV4)
+                .matchInPort(port.number());
+
+        tBuilder.setTunnelId(Long.parseLong(vni));
+
+        ForwardingObjective fo = DefaultForwardingObjective.builder()
+                .withSelector(sBuilder.build())
+                .withTreatment(tBuilder.build())
+                .withPriority(TUNNELTAG_RULE_PRIORITY)
+                .withFlag(ForwardingObjective.Flag.SPECIFIC)
+                .fromApp(appId)
+                .add();
+
+        flowObjectiveService.forward(deviceId, fo);
+    }
+
+    /**
+     * Populates the flow rules for traffic to VMs in the same Cnode as the sender.
+     *
+     * @param device device to put the rules
+     * @param port port info of the VM
+     */
+    private void populateFlowRulesForTrafficToSameCnode(Device device, Port port) {
+        Ip4Address vmIp = getFixedIpAddressForPort(port.annotations().value("portName"));
+        String portName = port.annotations().value("portName");
+        String vni = getVniForPort(portName);
+
+        if (vmIp != null) {
+            setFlowRuleForVMsInSameCnode(vmIp, device.id(), port, vni);
+        }
+    }
+
+    /**
+     * Sets the flow rules for traffic between VMs in the same Cnode.
+     *
+     * @param ip4Address VM IP address
+     * @param id device ID to put rules
+     * @param port VM port
+     * @param vni VM VNI
+     */
+    private void setFlowRuleForVMsInSameCnode(Ip4Address ip4Address, DeviceId id,
+                                              Port port, String vni) {
+
+        //For L2 Switching Case
+        TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
+        TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
+
+        sBuilder.matchEthType(Ethernet.TYPE_IPV4)
+                .matchIPDst(ip4Address.toIpPrefix())
+                .matchTunnelId(Long.parseLong(vni));
+
+        tBuilder.setOutput(port.number());
+
+        ForwardingObjective fo = DefaultForwardingObjective.builder()
+                .withSelector(sBuilder.build())
+                .withTreatment(tBuilder.build())
+                .withPriority(SWITCHING_RULE_PRIORITY)
+                .withFlag(ForwardingObjective.Flag.SPECIFIC)
+                .fromApp(appId)
+                .add();
+
+        flowObjectiveService.forward(id, fo);
+    }
+
+    /**
+     * Populates the flow rules for traffic to VMs in different Cnode using
+     * Nicira extention.
+     *
+     * @param device device to put rules
+     * @param port port information of the VM
+     */
+    private void populateFlowRulesForTrafficToDifferentCnode(Device device, Port port) {
+        String portName = port.annotations().value("portName");
+        String channelId = device.annotations().value("channelId");
+        Ip4Address hostIpAddress = Ip4Address.valueOf(channelId.split(":")[0]);
+        Ip4Address fixedIp = getFixedIpAddressForPort(portName);
+        String vni = getVniForPort(portName);
+        deviceService.getAvailableDevices().forEach(d -> {
+            if (!d.equals(device)) {
+                deviceService.getPorts(d.id()).forEach(p -> {
+                    String pName = p.annotations().value("portName");
+                    if (!p.equals(port) && vni.equals(getVniForPort(pName))) {
+                        String cidx = d.annotations().value("channelId");
+                        Ip4Address hostIpx = Ip4Address.valueOf(cidx.split(":")[0]);
+                        Ip4Address fixedIpx = getFixedIpAddressForPort(pName);
+                        if (port.isEnabled() ||
+                                port.annotations().value("portName").startsWith(
+                                        OpenstackSwitchingManager.PORTNAME_PREFIX_ROUTER)) {
+                            setVxLanFlowRule(vni, device.id(), hostIpx, fixedIpx);
+                            setVxLanFlowRule(vni, d.id(), hostIpAddress, fixedIp);
+                        }
+                    }
+                });
+            }
+        });
+    }
+
+    /**
+     * Sets the flow rules between traffic from VMs in different Cnode.
+     *
+     * @param vni  VNI
+     * @param deviceId device ID
+     * @param hostIp host IP of the VM
+     * @param vmIp fixed IP of the VM
+     */
+    private void setVxLanFlowRule(String vni, DeviceId deviceId, Ip4Address hostIp,
+                                  Ip4Address vmIp) {
+        TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
+        TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
+
+        sBuilder.matchEthType(Ethernet.TYPE_IPV4)
+                .matchTunnelId(Long.parseLong(vni))
+                .matchIPDst(vmIp.toIpPrefix());
+        tBuilder.extension(buildNiciraExtenstion(deviceId, hostIp), deviceId)
+                .setOutput(getTunnelPort(deviceId));
+
+        ForwardingObjective fo = DefaultForwardingObjective.builder()
+                .withSelector(sBuilder.build())
+                .withTreatment(tBuilder.build())
+                .withPriority(SWITCHING_RULE_PRIORITY)
+                .withFlag(ForwardingObjective.Flag.SPECIFIC)
+                .fromApp(appId)
+                .add();
+
+        flowObjectiveService.forward(deviceId, fo);
+    }
+
+    /**
+     * Returns OpenstackPort object for the Port reference given.
+     *
+     * @param port Port object
+     * @return OpenstackPort reference, or null when not found
+     */
+    public OpenstackPort openstackPort(Port port) {
+        String uuid = port.annotations().value("portName").substring(3);
+        return openstackPortList.stream().filter(p -> p.id().startsWith(uuid))
+                .findAny().orElse(null);
+    }
+
+    /**
+     * Remove flows rules for the removed VM.
+     *
+     * @param doNotPushFlows true to suppress push of initial flows
+     * @param removedPort removedport info
+     * @param openstackPortInfoMap openstackPortInfoMap
+     */
+    public void removeSwitchingRules(boolean doNotPushFlows, Port removedPort, Map<String,
+            OpenstackPortInfo> openstackPortInfoMap) {
+        if (doNotPushFlows) {
+            return;
+        }
+        OpenstackPortInfo openstackPortInfo = openstackPortInfoMap
+                .get(removedPort.annotations().value("portName"));
+
+        DeviceId deviceId = openstackPortInfo.deviceId();
+        Ip4Address vmIp = openstackPortInfo.ip();
+        PortNumber portNumber = removedPort.number();
+        long vni = openstackPortInfo.vni();
+
+        removeFlowRuleForTunnelTag(deviceId, portNumber);
+        removeFlowRuleForVMsInSameCnode(deviceId, vmIp, vni);
+        removeFlowRuleForVMsInDiffrentCnode(removedPort, deviceId, vmIp, vni, openstackPortInfoMap);
+    }
+
+    /**
+     * Removes flow rules for tagging tunnelId.
+     *
+     * @param deviceId device id
+     * @param portNumber port number
+     */
+    private void removeFlowRuleForTunnelTag(DeviceId deviceId, PortNumber portNumber) {
+        TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
+        TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
+
+        sBuilder.matchEthType(Ethernet.TYPE_IPV4)
+                .matchInPort(portNumber);
+
+        ForwardingObjective fo = DefaultForwardingObjective.builder()
+                .withSelector(sBuilder.build())
+                .withTreatment(tBuilder.build())
+                .withPriority(TUNNELTAG_RULE_PRIORITY)
+                .withFlag(ForwardingObjective.Flag.SPECIFIC)
+                .fromApp(appId)
+                .remove();
+
+        flowObjectiveService.forward(deviceId, fo);
+    }
+
+    /**
+     * Removes the flow rules for traffic between VMs in the same Cnode.
+     *
+     * @param deviceId device id on which removed VM was run
+     * @param vmIp ip of the removed VM
+     * @param vni vni which removed VM was belonged
+     */
+    private void removeFlowRuleForVMsInSameCnode(DeviceId deviceId, Ip4Address vmIp, long vni) {
+        TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
+
+        sBuilder.matchEthType(Ethernet.TYPE_IPV4)
+                .matchIPDst(vmIp.toIpPrefix())
+                .matchTunnelId(vni);
+
+        ForwardingObjective fo = DefaultForwardingObjective.builder()
+                .withSelector(sBuilder.build())
+                .withTreatment(DefaultTrafficTreatment.builder().build())
+                .withFlag(ForwardingObjective.Flag.SPECIFIC)
+                .withPriority(SWITCHING_RULE_PRIORITY)
+                .fromApp(appId)
+                .remove();
+
+        flowObjectiveService.forward(deviceId, fo);
+    }
+
+    /**
+     * Removes the flow rules for traffic between VMs in the different Cnode.
+     *
+     * @param removedPort removedport info
+     * @param deviceId device id on which removed VM was run
+     * @param vmIp ip of the removed VM
+     * @param vni vni which removed VM was belonged
+     * @param openstackPortInfoMap openstackPortInfoMap
+     */
+    private void removeFlowRuleForVMsInDiffrentCnode(Port removedPort, DeviceId deviceId, Ip4Address vmIp,
+                                                     long vni, Map<String, OpenstackPortInfo> openstackPortInfoMap) {
+
+        final boolean anyPortRemainedInSameCnode
+                = checkIfAnyPortRemainedInSameCnode(removedPort, deviceId, vni, openstackPortInfoMap);
+
+        openstackPortInfoMap.forEach((port, portInfo) -> {
+            if (portInfo.vni() == vni && !portInfo.deviceId().equals(deviceId)) {
+                removeVxLanFlowRule(portInfo.deviceId(), vmIp, vni);
+                if (!anyPortRemainedInSameCnode) {
+                    removeVxLanFlowRule(deviceId, portInfo.ip(), vni);
+                }
+            }
+        });
+    }
+
+    /**
+     * Removes the flow rules between traffic from VMs in different Cnode.
+     *
+     * @param deviceId device id
+     * @param vmIp ip
+     * @param vni vni which removed VM was belonged
+     */
+    private void removeVxLanFlowRule(DeviceId deviceId, Ip4Address vmIp, long vni) {
+        TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
+
+        sBuilder.matchEthType(Ethernet.TYPE_IPV4)
+                .matchTunnelId(vni)
+                .matchIPDst(vmIp.toIpPrefix());
+
+        ForwardingObjective fo = DefaultForwardingObjective.builder()
+                .withSelector(sBuilder.build())
+                .withTreatment(DefaultTrafficTreatment.builder().build())
+                .withFlag(ForwardingObjective.Flag.SPECIFIC)
+                .withPriority(SWITCHING_RULE_PRIORITY)
+                .fromApp(appId)
+                .remove();
+
+        flowObjectiveService.forward(deviceId, fo);
+    }
+
+    /**
+     * Checks if there is any port remained with same vni at the device, on which the removed VM was run.
+     *
+     * @param removedPort removedport info
+     * @param deviceId device id on which removed VM was run
+     * @param vni vni which removed VM was belonged
+     * @param openstackPortInfoMap openstackPortInfoMap
+     * @return true if there is, false otherwise
+     */
+    private boolean checkIfAnyPortRemainedInSameCnode(Port removedPort, DeviceId deviceId, long vni,
+                                                    Map<String, OpenstackPortInfo> openstackPortInfoMap) {
+
+        for (Map.Entry<String, OpenstackPortInfo> entry : openstackPortInfoMap.entrySet()) {
+            if (!removedPort.annotations().value("portName").equals(entry.getKey())) {
+                if (entry.getValue().vni() == vni && entry.getValue().deviceId().equals(deviceId)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Returns the VNI of the VM of the port.
+     *
+     * @param portName VM port
+     * @return VNI
+     */
+    private String getVniForPort(String portName) {
+        String uuid = portName.substring(3);
+        OpenstackPort port = openstackPortList.stream()
+                .filter(p -> p.id().startsWith(uuid))
+                .findAny().orElse(null);
+        if (port == null) {
+            log.debug("No port information for port {}", portName);
+            return null;
+        }
+
+        OpenstackNetwork network = openstackNetworkList.stream()
+                .filter(n -> n.id().equals(port.networkId()))
+                .findAny().orElse(null);
+        if (network == null) {
+            log.warn("No VNI information for network {}", port.networkId());
+            return null;
+        }
+
+        return network.segmentId();
+    }
+
+    /**
+     * Returns the Fixed IP address of the VM.
+     *
+     * @param portName VM port info
+     * @return IP address of the VM
+     */
+    private Ip4Address getFixedIpAddressForPort(String portName) {
+
+        String uuid = portName.substring(3);
+        OpenstackPort port = openstackPortList.stream()
+                .filter(p -> p.id().startsWith(uuid))
+                .findFirst().orElse(null);
+
+        if (port == null) {
+            log.error("There is no port information for port name {}", portName);
+            return null;
+        }
+
+        if (port.fixedIps().isEmpty()) {
+            log.error("There is no fixed IP info in the port information");
+            return null;
+        }
+
+        return (Ip4Address) port.fixedIps().values().toArray()[0];
+    }
+
+    private ExtensionTreatment buildNiciraExtenstion(DeviceId id, Ip4Address hostIp) {
+        Driver driver = driverService.getDriver(id);
+        DriverHandler driverHandler = new DefaultDriverHandler(new DefaultDriverData(driver, id));
+        ExtensionTreatmentResolver resolver = driverHandler.behaviour(ExtensionTreatmentResolver.class);
+
+        ExtensionTreatment extensionInstruction =
+                resolver.getExtensionInstruction(
+                        ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_TUNNEL_DST.type());
+
+        try {
+            extensionInstruction.setPropertyValue("tunnelDst", hostIp);
+        } catch (ExtensionPropertyException e) {
+            log.error("Error setting Nicira extension setting {}", e);
+        }
+
+        return  extensionInstruction;
+    }
+
+    private PortNumber getTunnelPort(DeviceId deviceId) {
+        Port port = deviceService.getPorts(deviceId).stream()
+                .filter(p -> p.annotations().value("portName").equals(
+                        OpenstackSwitchingManager.PORTNAME_PREFIX_TUNNEL))
+                .findAny().orElse(null);
+
+        if (port == null) {
+            log.error("No TunnelPort was created.");
+            return null;
+        }
+        return port.number();
+    }
+}
diff --git a/apps/openstacknetworking/openstackswitching/src/main/java/org/onosproject/openstacknetworking/switching/package-info.java b/apps/openstacknetworking/openstackswitching/src/main/java/org/onosproject/openstacknetworking/switching/package-info.java
new file mode 100644
index 0000000..6dc1996
--- /dev/null
+++ b/apps/openstacknetworking/openstackswitching/src/main/java/org/onosproject/openstacknetworking/switching/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2015-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.
+ */
+
+/**
+ * OpenStack switch implementation.
+ */
+package org.onosproject.openstacknetworking.switching;
