diff --git a/apps/pom.xml b/apps/pom.xml
index af59d8b..ea20970 100644
--- a/apps/pom.xml
+++ b/apps/pom.xml
@@ -100,6 +100,7 @@
         <module>cfm</module>
         <module>routeradvertisement</module>
         <module>t3</module>
+        <module>simplefabric</module>
     </modules>
 
     <properties>
diff --git a/apps/simplefabric/BUCK b/apps/simplefabric/BUCK
new file mode 100644
index 0000000..8125580
--- /dev/null
+++ b/apps/simplefabric/BUCK
@@ -0,0 +1,27 @@
+COMPILE_DEPS = [
+    '//lib:CORE_DEPS',
+    '//lib:JACKSON',
+    '//lib:concurrent-trees',
+]
+
+BUNDLES = [
+    '//apps/simplefabric:onos-apps-simplefabric',
+]
+
+TEST_DEPS = [
+    '//lib:TEST_ADAPTERS',
+]
+
+osgi_jar_with_tests (
+    deps = COMPILE_DEPS,
+    test_deps = TEST_DEPS,
+)
+
+onos_app (
+  title = 'SimpleFabric',
+  category = 'Traffic Steering',
+  url = 'http://onosproject.org',
+  included_bundles = BUNDLES,
+  description = 'Simple Fabric application',
+  required_apps = [ 'org.onosproject.openflow-base', 'org.onosproject.lldpprovider', 'org.onosproject.hostprovider' ],
+)
diff --git a/apps/simplefabric/app.xml b/apps/simplefabric/app.xml
new file mode 100644
index 0000000..df5cc60
--- /dev/null
+++ b/apps/simplefabric/app.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2017-present Open Networking Laboratory
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<app name="org.onosproject.simplefabric" origin="ON.Lab" version="${project.version}"
+     category="Traffic Steering" url="http://onosproject.org" title="Simple Leaf-Spine Network App"
+     featuresRepo="mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features"
+     features="${project.artifactId}" apps="org.onosproject.openflow-base,org.onosproject.lldpprovider,org.onosproject.hostprovider">
+    <description>${project.description}</description>
+    <artifact>mvn:${project.groupId}/${project.artifactId}/${project.version}</artifact>
+</app>
diff --git a/apps/simplefabric/features.xml b/apps/simplefabric/features.xml
new file mode 100644
index 0000000..9ab23de
--- /dev/null
+++ b/apps/simplefabric/features.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+  ~ Copyright 2017-present Open Networking Laboratory
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<features xmlns="http://karaf.apache.org/xmlns/features/v1.2.0" name="${project.artifactId}-${project.version}">
+    <feature name="onos-app-simplefabric" version="${project.version}"
+             description="${project.description}">
+        <feature>onos-api</feature>
+        <bundle>mvn:${project.groupId}/onos-app-simplefabric/${project.version}</bundle>
+    </feature>
+</features>
diff --git a/apps/simplefabric/mininet-simplefabric.py b/apps/simplefabric/mininet-simplefabric.py
new file mode 100755
index 0000000..dafbbc6
--- /dev/null
+++ b/apps/simplefabric/mininet-simplefabric.py
@@ -0,0 +1,94 @@
+#!/usr/bin/python
+# Mininet model for Simple Leaf-Spine Network
+
+# Copyright 2017-present Open Networking Foundation
+#
+# 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.
+
+from mininet.topo import Topo
+from mininet.net import Mininet
+from mininet.node import Host, OVSSwitch, RemoteController
+from mininet.log import setLogLevel
+from mininet.cli import CLI
+
+
+"Create custom topo."
+
+net = Mininet()
+
+# Add leaf switch and hosts in rack 1
+# subnet: 10.0.1.0/24
+s10 = net.addSwitch('s10', dpid='0000000000000011')
+h11 = net.addHost('h11', mac='00:00:10:00:01:11', ip='10.0.1.11/24', defaultRoute='via 10.0.1.1')
+h12 = net.addHost('h12', mac='00:00:10:00:01:12', ip='10.0.1.12/24', defaultRoute='via 10.0.1.1')
+h13 = net.addHost('h13', mac='00:00:10:00:01:13', ip='10.0.1.13/24', defaultRoute='via 10.0.1.1')
+h14 = net.addHost('h14', mac='00:00:10:00:01:14', ip='10.0.1.14/24', defaultRoute='via 10.0.1.1')
+d11 = net.addHost('d11', mac='00:00:10:00:01:a1', ip='10.0.1.111/24', defaultRoute='via 10.0.1.1')
+d12 = net.addHost('d12', mac='00:00:10:00:01:a2', ip='10.0.1.112/24', defaultRoute='via 10.0.1.1')
+net.addLink(s10, h11)
+net.addLink(s10, h12)
+net.addLink(s10, h13)
+net.addLink(s10, h14)
+net.addLink(s10, d11)
+net.addLink(s10, d12)
+
+# Add leaf switch and hosts in rack 2
+# subnet: 10.0.2.0/24
+s20 = net.addSwitch('s20', dpid='0000000000000012')
+h21 = net.addHost('h21', mac='00:00:10:00:02:21', ip='10.0.2.21/24', defaultRoute='via 10.0.2.1')
+h22 = net.addHost('h22', mac='00:00:10:00:02:22', ip='10.0.2.22/24', defaultRoute='via 10.0.2.1')
+h23 = net.addHost('h23', mac='00:00:10:00:02:23', ip='10.0.2.23/24', defaultRoute='via 10.0.2.1')
+h24 = net.addHost('h24', mac='00:00:10:00:02:24', ip='10.0.2.24/24', defaultRoute='via 10.0.2.1')
+d21 = net.addHost('d21', mac='00:00:10:00:02:b1', ip='10.0.2.221/24', defaultRoute='via 10.0.2.1')
+d22 = net.addHost('d22', mac='00:00:10:00:02:b2', ip='10.0.2.222/24', defaultRoute='via 10.0.2.1')
+net.addLink(s20, h21)
+net.addLink(s20, h22)
+net.addLink(s20, h23)
+net.addLink(s20, h24)
+net.addLink(s20, d21)
+net.addLink(s20, d22)
+
+# Add spine switches and nat
+# subnet: 10.0.0.0/16
+ss1 = net.addSwitch('ss1', dpid='0000000000000021')
+ss2 = net.addSwitch('ss2', dpid='0000000000000022')
+net.addLink(ss1, s10)
+net.addLink(ss1, s20)
+net.addLink(ss2, s10)
+net.addLink(ss2, s20)
+
+# Add External Router
+#h31 = net.addHost('h31', mac='00:00:10:00:00:31', ip='10.0.0.31/24', defaultRoute='via 10.0.0.1')
+#h32 = net.addHost('h32', mac='00:00:10:00:00:32', ip='10.0.0.32/24', defaultRoute='via 10.0.0.1')
+#net.addLink(ss1, h31);
+#net.addLink(ss2, h32);
+
+# Add ONOS/RemoteController; set your ONOS node ip address
+net.addController(RemoteController('c1', ip='10.10.108.140'))
+
+# Main
+setLogLevel('info')
+net.start()
+
+# reveal hosts to switches
+#for h in [h11, h12, h13, h14, d11, d12] :
+#  net.ping(hosts=[h, h31], timeout='1')
+#  net.ping(hosts=[h, h31], timeout='1')
+#for h in [h21, h22, h23, h24, d21, d22] :
+#  net.ping(hosts=[h, h32], timeout='1')
+#  net.ping(hosts=[h, h32], timeout='1')
+
+# do interactive shell
+CLI(net)
+net.stop()
+
diff --git a/apps/simplefabric/network-cfg.json b/apps/simplefabric/network-cfg.json
new file mode 100644
index 0000000..f988497
--- /dev/null
+++ b/apps/simplefabric/network-cfg.json
@@ -0,0 +1,56 @@
+{
+
+  "devices":{
+    "of:0000000000000011":{ "basic":{ "name":"LS1", "latitude":35, "longitude":-100 } },
+    "of:0000000000000012":{ "basic":{ "name":"LS2", "latitude":35, "longitude":-90  } },
+    "of:0000000000000021":{ "basic":{ "name":"SS1", "latitude":40, "longitude":-100 } },
+    "of:0000000000000022":{ "basic":{ "name":"SS2", "latitude":40, "longitude":-90  } }
+  },
+
+  "ports" : {
+    "of:0000000000000011/1" : { "interfaces" : [ { "name" : "h11" } ] },
+    "of:0000000000000011/2" : { "interfaces" : [ { "name" : "h12" } ] },
+    "of:0000000000000011/3" : { "interfaces" : [ { "name" : "h13" } ] },
+    "of:0000000000000011/4" : { "interfaces" : [ { "name" : "h14" } ] },
+    "of:0000000000000011/5" : { "interfaces" : [ { "name" : "d11" } ] },
+    "of:0000000000000011/6" : { "interfaces" : [ { "name" : "d12" } ] },
+    "of:0000000000000011/7" : { "interfaces" : [ { "name" : "LS1_SS1" } ] },
+    "of:0000000000000011/8" : { "interfaces" : [ { "name" : "LS1_SS2" } ] },
+
+    "of:0000000000000012/1" : { "interfaces" : [ { "name" : "h21" } ] } ,
+    "of:0000000000000012/2" : { "interfaces" : [ { "name" : "h22" } ] },
+    "of:0000000000000012/3" : { "interfaces" : [ { "name" : "h23" } ] },
+    "of:0000000000000012/4" : { "interfaces" : [ { "name" : "h24" } ] },
+    "of:0000000000000012/5" : { "interfaces" : [ { "name" : "d21" } ] },
+    "of:0000000000000012/6" : { "interfaces" : [ { "name" : "d22" } ] },
+    "of:0000000000000012/7" : { "interfaces" : [ { "name" : "LS2_SS1" } ] },
+    "of:0000000000000012/8" : { "interfaces" : [ { "name" : "LS2_SS2" } ] },
+
+    "of:0000000000000021/1" : { "interfaces" : [ { "name" : "SS1_LS1" } ] },
+    "of:0000000000000021/2" : { "interfaces" : [ { "name" : "SS1_LS2" } ] },
+
+    "of:0000000000000022/1" : { "interfaces" : [ { "name" : "SS2_LS1" } ] },
+    "of:0000000000000022/2" : { "interfaces" : [ { "name" : "SS2_LS2" } ] }
+
+  },
+
+  "apps" : {
+    "org.onosproject.simplefabric" : {
+      "simpleFabric" : {
+        "l2Networks" : [
+          { "name" : "LEAF1", "interfaces" : ["h11", "h12", "h13", "h14", "d11", "d12" ], "l2Forward" : true },
+          { "name" : "LEAF2", "interfaces" : ["h21", "h22", "h23", "h24", "d21", "d22" ], "l2Forward" : true }
+        ],
+        "ipSubnets" : [
+           { "ipPrefix" : "10.0.1.0/24", "gatewayIp" : "10.0.1.1", "gatewayMac" : "00:00:10:00:01:01", "l2NetworkName" : "LEAF1" },
+           { "ipPrefix" : "10.0.2.0/24", "gatewayIp" : "10.0.2.1", "gatewayMac" : "00:00:10:00:02:01", "l2NetworkName" : "LEAF2" }
+        ],
+        "borderRoutes" : [
+           { "ipPrefix" : "0.0.0.0/0", "nextHop" : "10.0.1.2" }
+        ]
+      }
+    }
+  }
+
+}
+
diff --git a/apps/simplefabric/pom.xml b/apps/simplefabric/pom.xml
new file mode 100644
index 0000000..ef36955
--- /dev/null
+++ b/apps/simplefabric/pom.xml
@@ -0,0 +1,154 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2017-present Open Networking Laboratory
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.onosproject</groupId>
+        <artifactId>onos-apps</artifactId>
+        <version>1.12.0-SNAPSHOT</version>
+        <relativePath>../../onos</relativePath>
+    </parent>
+
+    <artifactId>onos-app-simplefabric</artifactId>
+    <packaging>bundle</packaging>
+
+    <description>Simple Fabric Application for Leaf-Spine L2/L3 Network</description>
+
+    <properties>
+        <onos.app.name>org.onosproject.simplefabric</onos.app.name>
+        <onos.app.category>Traffic Steering</onos.app.category>
+        <onos.app.title>Simple Fabric App</onos.app.title>
+        <onos.app.url>http://onosproject.org</onos.app.url>
+
+        <web.context>/onos/v1/simplefabric</web.context>
+        <api.version>1.0.0</api.version>
+        <api.title>Simple Fabric Application REST API</api.title>
+        <api.description>APIs for interacting with the Simple Fabric application.</api.description>
+        <api.package>org.onosproject.simplefabric</api.package>
+    </properties>
+
+    <dependencies>
+
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onlab-misc</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onlab-junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-api</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-cli</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-core-serializers</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-core-net</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-rest</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.scr.annotations</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.karaf.shell</groupId>
+            <artifactId>org.apache.karaf.shell.console</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.easymock</groupId>
+            <artifactId>easymock</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+    </dependencies>
+
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <extensions>true</extensions>
+                <configuration>
+                    <instructions>
+                        <_wab>src/main/webapp/</_wab>
+                        <Include-Resource>
+                            WEB-INF/classes/apidoc/swagger.json=target/swagger.json,
+                            {maven-resources}
+                        </Include-Resource>
+                        <Bundle-SymbolicName>
+                            ${project.groupId}.${project.artifactId}
+                        </Bundle-SymbolicName>
+                        <Import-Package>
+                            *,org.glassfish.jersey.servlet
+                        </Import-Package>
+                        <Web-ContextPath>${web.context}</Web-ContextPath>
+                    </instructions>
+                </configuration>
+            </plugin>
+
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-scr-plugin</artifactId>
+            </plugin>
+
+            <plugin>
+                <groupId>org.onosproject</groupId>
+                <artifactId>onos-maven-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
diff --git a/apps/simplefabric/src/main/java/org/onosproject/simplefabric/IpSubnet.java b/apps/simplefabric/src/main/java/org/onosproject/simplefabric/IpSubnet.java
new file mode 100644
index 0000000..596c659
--- /dev/null
+++ b/apps/simplefabric/src/main/java/org/onosproject/simplefabric/IpSubnet.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.simplefabric;
+
+import com.google.common.base.MoreObjects;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onosproject.net.EncapsulationType;
+
+import java.util.Objects;
+
+/**
+ * Configuration details for an ip subnet entry.
+ */
+public class IpSubnet {
+    private final IpPrefix ipPrefix;
+    private final IpAddress gatewayIp;
+    private final MacAddress gatewayMac;
+    private EncapsulationType encapsulation;
+    private final String l2NetworkName;
+
+    /**
+     * Creates a new ip subnet entry.
+     *
+     * @param ipPrefix  an ip subnet
+     * @param gatewayIp IP of the virtual gateway
+     * @param gatewayMac MacAddress of the virtual gateway
+     * @param encapsulation EnacaptulatioType for routes related to this subnet
+     * @param l2NetworkName Name of L2 Network this subnet is bound
+     */
+    public IpSubnet(IpPrefix ipPrefix, IpAddress gatewayIp, MacAddress gatewayMac,
+                    EncapsulationType encapsulation, String l2NetworkName) {
+        this.ipPrefix = ipPrefix;
+        this.gatewayIp = gatewayIp;
+        this.gatewayMac = gatewayMac;
+        this.encapsulation = EncapsulationType.NONE;
+        this.l2NetworkName = l2NetworkName;
+    }
+
+    /**
+     * Gets the ip subnet of the ip subnet entry.
+     *
+     * @return the ip subnet
+     */
+    public IpPrefix ipPrefix() {
+        return ipPrefix;
+    }
+
+    /**
+     * Gets the virtual gateway IP address of the ip subnet entry.
+     *
+     * @return the virtual gateway IP address
+     */
+    public IpAddress gatewayIp() {
+        return gatewayIp;
+    }
+
+    /**
+     * Gets the virtual gateway Mac address of the ip subnet entry.
+     *
+     * @return the virtuai gateway Mac address
+     */
+    public MacAddress gatewayMac() {
+        return gatewayMac;
+    }
+
+    /**
+     * Gets the encapsulation type of ip subnet entry.
+     *
+     * @return the encapsulation type
+     */
+    public EncapsulationType encapsulation() {
+        return encapsulation;
+    }
+
+    /**
+     * Gets the name of L2 Network this subnet is bound.
+     *
+     * @return the l2Network name this subnet is allocated
+     */
+    public String l2NetworkName() {
+        return l2NetworkName;
+    }
+
+    /**
+     * Tests whether the IP version of this entry is IPv4.
+     *
+     * @return true if the IP version of this entry is IPv4, otherwise false.
+     */
+    public boolean isIp4() {
+        return ipPrefix.isIp4();
+    }
+
+    /**
+     * Tests whether the IP version of this entry is IPv6.
+     *
+     * @return true if the IP version of this entry is IPv6, otherwise false.
+     */
+    public boolean isIp6() {
+        return ipPrefix.isIp6();
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(ipPrefix, gatewayIp, gatewayMac, encapsulation, l2NetworkName);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (!(obj instanceof IpSubnet)) {
+            return false;
+        }
+        IpSubnet that = (IpSubnet) obj;
+        return Objects.equals(this.ipPrefix, that.ipPrefix)
+               && Objects.equals(this.gatewayIp, that.gatewayIp)
+               && Objects.equals(this.gatewayMac, that.gatewayMac)
+               && Objects.equals(this.encapsulation, that.encapsulation)
+               && Objects.equals(this.l2NetworkName, that.l2NetworkName);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("ipPrefix", ipPrefix)
+                .add("gatewayIp", gatewayIp)
+                .add("gatewayMac", gatewayMac)
+                .add("encapsulation", encapsulation)
+                .add("l2NetworkName", l2NetworkName)
+                .toString();
+    }
+}
diff --git a/apps/simplefabric/src/main/java/org/onosproject/simplefabric/L2Network.java b/apps/simplefabric/src/main/java/org/onosproject/simplefabric/L2Network.java
new file mode 100644
index 0000000..31e8cc0
--- /dev/null
+++ b/apps/simplefabric/src/main/java/org/onosproject/simplefabric/L2Network.java
@@ -0,0 +1,287 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.simplefabric;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+import org.onlab.packet.VlanId;
+import org.onosproject.net.intf.Interface;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Host;
+import org.onosproject.net.HostId;
+import org.onosproject.net.EncapsulationType;
+
+import java.util.Collection;
+import java.util.Objects;
+import java.util.Set;
+
+
+/**
+ * Class stores a L2Network information.
+ */
+public final class L2Network {
+
+    private String name;                  // also for network configuration
+    private Set<String> interfaceNames;   // also for network configuration
+    private EncapsulationType encapsulation;  // also for network configuration
+    private boolean l2Forward;            // do l2Forward (default:true) or not
+
+    /* status variables */
+    private Set<Interface> interfaces;    // available interfaces from interfaceNames
+    private Set<HostId> hostIds;          // available hosts from interfaces
+    private boolean dirty;
+
+    /**
+     * Constructs a L2Network data for Config value.
+     *
+     * @param name the given name
+     * @param ifaceNames the interface names
+     * @param encapsulation the encapsulation type
+     * @param l2Forward flag for l2Forward intents to be installed or not
+     */
+    L2Network(String name, Collection<String> ifaceNames, EncapsulationType encapsulation, boolean l2Forward) {
+        this.name = name;
+        this.interfaceNames = Sets.newHashSet();
+        this.interfaceNames.addAll(ifaceNames);
+        this.encapsulation = encapsulation;
+        this.l2Forward = (SimpleFabricService.ALLOW_ETH_ADDRESS_SELECTOR) ? l2Forward : false;
+        this.interfaces = Sets.newHashSet();
+        this.hostIds = Sets.newHashSet();
+        this.dirty = false;
+    }
+
+    /**
+     * Constructs a L2Network data by given name and encapsulation type.
+     *
+     * @param name the given name
+     * @param encapsulation the encapsulation type
+     */
+    private L2Network(String name, EncapsulationType encapsulation) {
+        this.name = name;
+        this.interfaceNames = Sets.newHashSet();
+        this.encapsulation = encapsulation;
+        this.l2Forward = (SimpleFabricService.ALLOW_ETH_ADDRESS_SELECTOR) ? true : false;
+        this.interfaces = Sets.newHashSet();
+        this.hostIds = Sets.newHashSet();
+        this.dirty = false;
+    }
+
+    /**
+     * Creates a L2Network data by given name.
+     * The encapsulation type of the L2Network will be NONE.
+     *
+     * @param name the given name
+     * @return the L2Network data
+     */
+    public static L2Network of(String name) {
+        Objects.requireNonNull(name);
+        return new L2Network(name, EncapsulationType.NONE);
+    }
+
+    /**
+     * Creates a copy of L2Network data.
+     *
+     * @param l2Network the L2Network data
+     * @return the copy of the L2Network data
+     */
+    public static L2Network of(L2Network l2Network) {
+        Objects.requireNonNull(l2Network);
+        L2Network l2NetworkCopy = new L2Network(l2Network.name(), l2Network.encapsulation());
+        l2NetworkCopy.interfaceNames.addAll(l2Network.interfaceNames());
+        l2NetworkCopy.l2Forward = (SimpleFabricService.ALLOW_ETH_ADDRESS_SELECTOR) ? l2Network.l2Forward() : false;
+        l2NetworkCopy.interfaces.addAll(l2Network.interfaces());
+        l2NetworkCopy.hostIds.addAll(l2Network.hostIds());
+        l2NetworkCopy.setDirty(l2Network.dirty());
+        return l2NetworkCopy;
+    }
+
+    // field queries
+
+    /**
+     * Gets L2Network name.
+     *
+     * @return the name of L2Network
+     */
+    public String name() {
+        return name;
+    }
+
+    /**
+     * Gets L2Network interfaceNames.
+     *
+     * @return the interfaceNames of L2Network
+     */
+    public Set<String> interfaceNames() {
+        return ImmutableSet.copyOf(interfaceNames);
+    }
+
+    /**
+     * Gets L2Network encapsulation type.
+     *
+     * @return the encapsulation type of L2Network
+     */
+    public EncapsulationType encapsulation() {
+        return encapsulation;
+    }
+
+    /**
+     * Gets L2Network l2Forward flag.
+     *
+     * @return the l2Forward flag of L2Network
+     */
+    public boolean l2Forward() {
+        return l2Forward;
+    }
+
+    /**
+     * Gets L2Network interfaces.
+     *
+     * @return the interfaces of L2Network
+     */
+    public Set<Interface> interfaces() {
+        return ImmutableSet.copyOf(interfaces);
+    }
+
+    /**
+     * Gets L2Network hosts.
+     *
+     * @return the hosts of L2Network
+     */
+    public Set<HostId> hostIds() {
+        return ImmutableSet.copyOf(hostIds);
+    }
+
+    /**
+     * Gets L2Network dirty flag.
+     *
+     * @return the dirty flag of L2Network
+     */
+    public boolean dirty() {
+        return dirty;
+    }
+
+    /**
+     * Checks if the interface is of L2Network.
+     *
+     * @param iface the interface to be checked
+     * @return true if L2Network contains the interface
+     */
+    public boolean contains(Interface iface) {
+        return interfaces.contains(iface);
+    }
+
+    /**
+     * Checks if the ConnectPoint and Vlan is of L2Network.
+     *
+     * @param port the ConnectPoint to be checked
+     * @param vlanId the VlanId of the ConnectPoint to be checked
+     * @return true if L2Network contains the interface of the ConnnectPoint and VlanId
+     */
+    public boolean contains(ConnectPoint port, VlanId vlanId) {
+        for (Interface iface : interfaces) {
+            if (iface.connectPoint().equals(port) && iface.vlan().equals(vlanId)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Checks if the DeviceId is of L2Network.
+     *
+     * @param deviceId the DeviceId to be checked
+     * @return true if L2Network contains any interface of the DeviceId
+     */
+    public boolean contains(DeviceId deviceId) {
+        for (Interface iface : interfaces) {
+            if (iface.connectPoint().deviceId().equals(deviceId)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Adds interface to L2Network.
+     *
+     * @param iface the Interface to be added
+     */
+    public void addInterface(Interface iface) {
+        Objects.requireNonNull(iface);
+        if (interfaces.add(iface)) {
+            setDirty(true);
+        }
+    }
+
+    /**
+     * Adds host to L2Network.
+     *
+     * @param host the Host to be added
+     */
+    public void addHost(Host host) {
+        Objects.requireNonNull(host);
+        if (hostIds.add(host.id())) {
+            setDirty(true);
+        }
+    }
+
+    /**
+     * Sets L2Network dirty flag.
+     *
+     * @param newDirty the dirty flag to be set
+     */
+    public void setDirty(boolean newDirty) {
+        dirty = newDirty;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("name", name)
+                .add("interfaceNames", interfaceNames)
+                .add("encapsulation", encapsulation)
+                .add("l2Forward", l2Forward)
+                .add("interfaces", interfaces)
+                .add("hostIds", hostIds)
+                .add("dirty", dirty)
+                .toString();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (!(obj instanceof L2Network)) {
+            return false;
+        }
+        L2Network other = (L2Network) obj;
+        return Objects.equals(other.name, this.name)
+               && Objects.equals(other.interfaceNames, this.interfaceNames)
+               && Objects.equals(other.encapsulation, this.encapsulation)
+               && Objects.equals(other.l2Forward, this.l2Forward)
+               && Objects.equals(other.interfaces, this.interfaces)
+               && Objects.equals(other.hostIds, this.hostIds);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(name, interfaces, encapsulation, l2Forward);
+    }
+}
diff --git a/apps/simplefabric/src/main/java/org/onosproject/simplefabric/Route.java b/apps/simplefabric/src/main/java/org/onosproject/simplefabric/Route.java
new file mode 100644
index 0000000..8eabb95
--- /dev/null
+++ b/apps/simplefabric/src/main/java/org/onosproject/simplefabric/Route.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright 2016-present Open Networking Foundation
+ *
+ * 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.
+ */
+/*
+ * local copy of onos/incubator/api/src/main/java/org/onosproject/incubator/net/routing/Route.java
+ * to remove dependency on onos.incubator.routing services, since 2017-08-09.
+ */
+
+package org.onosproject.simplefabric;
+
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.onosproject.cluster.NodeId;
+
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Represents a route.
+ */
+public class Route {
+
+    private static final String VERSION_MISMATCH =
+            "Prefix and next hop must be in the same address family";
+
+    private static final NodeId UNDEFINED = new NodeId("-");
+
+    /**
+     * Source of the route.
+     */
+    public enum Source {
+        /**
+         * Route came from the iBGP route source.
+         */
+        BGP,
+
+        /**
+         * Route came from the FPM route source.
+         */
+        FPM,
+
+        /**
+         * Route can from the static route source.
+         */
+        STATIC,
+
+        /**
+         * Route source was not defined.
+         */
+        UNDEFINED
+    }
+
+    private final Source source;
+    private final IpPrefix prefix;
+    private final IpAddress nextHop;
+    private final NodeId sourceNode;
+
+    /**
+     * Creates a route.
+     *
+     * @param source route source
+     * @param prefix IP prefix
+     * @param nextHop next hop IP address
+     */
+    public Route(Source source, IpPrefix prefix, IpAddress nextHop) {
+        this(source, prefix, nextHop, UNDEFINED);
+    }
+
+    /**
+     * Creates a route.
+     *
+     * @param source route source
+     * @param prefix IP prefix
+     * @param nextHop next hop IP address
+     * @param sourceNode ONOS node the route was sourced from
+     */
+    public Route(Source source, IpPrefix prefix, IpAddress nextHop, NodeId sourceNode) {
+        checkNotNull(prefix);
+        checkNotNull(nextHop);
+        checkArgument(prefix.version().equals(nextHop.version()), VERSION_MISMATCH);
+
+        this.source = checkNotNull(source);
+        this.prefix = prefix;
+        this.nextHop = nextHop;
+        this.sourceNode = checkNotNull(sourceNode);
+    }
+
+    /**
+     * Returns the route source.
+     *
+     * @return route source
+     */
+    public Source source() {
+        return source;
+    }
+
+    /**
+     * Returns the IP prefix of the route.
+     *
+     * @return IP prefix
+     */
+    public IpPrefix prefix() {
+        return prefix;
+    }
+
+    /**
+     * Returns the next hop IP address.
+     *
+     * @return next hop
+     */
+    public IpAddress nextHop() {
+        return nextHop;
+    }
+
+    /**
+     * Returns the ONOS node the route was sourced from.
+     *
+     * @return ONOS node ID
+     */
+    public NodeId sourceNode() {
+        return sourceNode;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(prefix, nextHop);
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if (this == other) {
+            return true;
+        }
+
+        if (!(other instanceof Route)) {
+            return false;
+        }
+
+        Route that = (Route) other;
+
+        return Objects.equals(this.prefix, that.prefix) &&
+                Objects.equals(this.nextHop, that.nextHop);
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(this)
+                .add("prefix", prefix)
+                .add("nextHop", nextHop)
+                .toString();
+    }
+}
diff --git a/apps/simplefabric/src/main/java/org/onosproject/simplefabric/RouteTools.java b/apps/simplefabric/src/main/java/org/onosproject/simplefabric/RouteTools.java
new file mode 100644
index 0000000..b14438a
--- /dev/null
+++ b/apps/simplefabric/src/main/java/org/onosproject/simplefabric/RouteTools.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.
+ */
+/*
+ * local copy of onos/incubator/api/src/main/java/org/onosproject/incubator/net/routing/RouteTools.java
+ * to remove dependency on onos.incubator.routing services, since 2017-08-09.
+ */
+
+package org.onosproject.simplefabric;
+
+import org.onlab.packet.IpPrefix;
+
+/**
+ * Routing tools.
+ */
+public final class RouteTools {
+
+    private RouteTools() {
+    }
+
+    /**
+     * Creates a binary string representation of an IP prefix.
+     *
+     * For each string, we put a extra "0" in the front. The purpose of
+     * doing this is to store the default route inside InvertedRadixTree.
+     *
+     * @param ipPrefix the IP prefix to use
+     * @return the binary string representation
+     */
+    public static String createBinaryString(IpPrefix ipPrefix) {
+        byte[] octets = ipPrefix.address().toOctets();
+        StringBuilder result = new StringBuilder(ipPrefix.prefixLength());
+        result.append("0");
+        for (int i = 0; i < ipPrefix.prefixLength(); i++) {
+            int byteOffset = i / Byte.SIZE;
+            int bitOffset = i % Byte.SIZE;
+            int mask = 1 << (Byte.SIZE - 1 - bitOffset);
+            byte value = octets[byteOffset];
+            boolean isSet = ((value & mask) != 0);
+            result.append(isSet ? "1" : "0");
+        }
+        return result.toString();
+    }
+}
diff --git a/apps/simplefabric/src/main/java/org/onosproject/simplefabric/SimpleFabricConfig.java b/apps/simplefabric/src/main/java/org/onosproject/simplefabric/SimpleFabricConfig.java
new file mode 100644
index 0000000..a6d83b1
--- /dev/null
+++ b/apps/simplefabric/src/main/java/org/onosproject/simplefabric/SimpleFabricConfig.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.simplefabric;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.google.common.collect.Sets;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.config.Config;
+import org.onosproject.net.EncapsulationType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Set;
+
+/**
+ * Configuration object for prefix config.
+ */
+public class SimpleFabricConfig extends Config<ApplicationId> {
+    public static final String KEY = "simpleFabric";
+
+    private static final String L2NETWORKS = "l2Networks";
+    private static final String NAME = "name";
+    private static final String INTERFACES = "interfaces";
+    private static final String ENCAPSULATION = "encapsulation";
+    private static final String L2FORWARD = "l2Forward";
+    private static final String IPSUBNETS = "ipSubnets";
+    private static final String BORDERROUTES = "borderRoutes";
+    private static final String IPPREFIX = "ipPrefix";
+    private static final String GATEWAYIP = "gatewayIp";
+    private static final String GATEWAYMAC = "gatewayMac";
+    private static final String L2NETWORKNAME = "l2NetworkName";
+    private static final String NEXTHOP = "nextHop";
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    /**
+     * Returns all l2Networks in this configuration.
+     *
+     * @return A set of L2Network.
+     */
+    public Set<L2Network> getL2Networks() {
+        Set<L2Network> l2Networks = Sets.newHashSet();
+        JsonNode l2NetworkNode = object.get(L2NETWORKS);
+        if (l2NetworkNode == null) {
+            return l2Networks;
+        }
+
+        l2NetworkNode.forEach(jsonNode -> {
+            Set<String> ifaces = Sets.newHashSet();
+            JsonNode l2NetworkIfaces = jsonNode.path(INTERFACES);
+            if (l2NetworkIfaces == null) {
+                log.warn("simple fabric network config cannot find {}; skip: jsonNode={}", INTERFACES, jsonNode);
+            } else if (!l2NetworkIfaces.toString().isEmpty()) {
+                l2NetworkIfaces.forEach(ifacesNode -> ifaces.add(new String(ifacesNode.asText())));
+            }
+            String encapsulation = "NONE";   // NONE or VLAN
+            if (jsonNode.hasNonNull(ENCAPSULATION)) {
+                encapsulation = jsonNode.get(ENCAPSULATION).asText();
+            }
+            boolean l2Forward = true;
+            if (jsonNode.hasNonNull(L2FORWARD)) {
+                l2Forward = jsonNode.get(L2FORWARD).asBoolean();
+            }
+            try {
+                l2Networks.add(new L2Network(
+                        jsonNode.get(NAME).asText(),
+                        ifaces,
+                        EncapsulationType.enumFromString(encapsulation),
+                        l2Forward));
+            } catch (Exception e) {
+                log.warn("simple fabric network config l2Network parse failed; skip: error={} jsonNode={}", jsonNode);
+            }
+        });
+        return l2Networks;
+    }
+
+    /**
+     * Gets the set of configured local IP subnets.
+     *
+     * @return IP Subnets
+     */
+    public Set<IpSubnet> ipSubnets() {
+        Set<IpSubnet> subnets = Sets.newHashSet();
+        JsonNode subnetsNode = object.get(IPSUBNETS);
+        if (subnetsNode == null) {
+            log.warn("simple fabric network config ipSubnets is null!");
+            return subnets;
+        }
+
+        subnetsNode.forEach(jsonNode -> {
+            String encapsulation = "NONE";   // NONE or VLAN
+            if (jsonNode.hasNonNull(ENCAPSULATION)) {
+                encapsulation = jsonNode.get(ENCAPSULATION).asText();
+            }
+            try {
+                subnets.add(new IpSubnet(
+                        IpPrefix.valueOf(jsonNode.get(IPPREFIX).asText()),
+                        IpAddress.valueOf(jsonNode.get(GATEWAYIP).asText()),
+                        MacAddress.valueOf(jsonNode.get(GATEWAYMAC).asText()),
+                        EncapsulationType.enumFromString(encapsulation),
+                        jsonNode.get(L2NETWORKNAME).asText()));
+            } catch (Exception e) {
+                log.warn("simple fabric network config ipSubnet parse failed; skip: error={} jsonNode={}", jsonNode);
+            }
+        });
+
+        return subnets;
+    }
+
+    /**
+     * Returns all routes in this configuration.
+     *
+     * @return A set of route.
+     */
+    public Set<Route> borderRoutes() {
+        Set<Route> routes = Sets.newHashSet();
+
+        JsonNode routesNode = object.get(BORDERROUTES);
+        if (routesNode == null) {
+            //log.warn("simple fabric network config borderRoutes is null!");
+            return routes;
+        }
+
+        routesNode.forEach(jsonNode -> {
+            try {
+                routes.add(new Route(
+                      Route.Source.STATIC,
+                      IpPrefix.valueOf(jsonNode.path(IPPREFIX).asText()),
+                      IpAddress.valueOf(jsonNode.path(NEXTHOP).asText())));
+            } catch (IllegalArgumentException e) {
+                log.warn("simple fabric network config parse error; skip: {}", jsonNode);
+            }
+        });
+
+        return routes;
+    }
+
+}
diff --git a/apps/simplefabric/src/main/java/org/onosproject/simplefabric/SimpleFabricEvent.java b/apps/simplefabric/src/main/java/org/onosproject/simplefabric/SimpleFabricEvent.java
new file mode 100644
index 0000000..cac1276
--- /dev/null
+++ b/apps/simplefabric/src/main/java/org/onosproject/simplefabric/SimpleFabricEvent.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.simplefabric;
+
+import org.onosproject.event.AbstractEvent;
+
+import java.io.OutputStream;
+import java.io.PrintStream;
+
+/**
+ * Describes an interface event.
+ */
+public class SimpleFabricEvent extends AbstractEvent<SimpleFabricEvent.Type, String> {
+
+    public enum Type {
+        SIMPLE_FABRIC_UPDATED,  /* Indicates topology info has been updated. */
+        SIMPLE_FABRIC_FLUSH,    /* Indicates flush triggered. */
+        SIMPLE_FABRIC_IDLE,     /* Indicates idle check. */
+        SIMPLE_FABRIC_DUMP      /* Indicates to dump info on the subject to output stream. */
+    }
+
+    private PrintStream printStream;  // output stream for SIMPLE_FABRIC_DUMP
+
+    /**
+     * Creates an interface event with type and subject.
+     *
+     * @param type event type
+     * @param subject subject for dump event or dummy
+     */
+    public SimpleFabricEvent(Type type, String subject) {
+        super(type, subject);   /* subject is dummy */
+    }
+
+    /**
+     * Creates an interface event with type, subject and output stream for dump.
+     *
+     * @param type event type
+     * @param subject subject for dump event
+     * @param out output stream to dump out
+     */
+    public SimpleFabricEvent(Type type, String subject, OutputStream out) {
+        super(type, subject);   /* subject is dummy */
+        printStream = new PrintStream(out, true);
+    }
+
+    public PrintStream out() {
+        return printStream;
+    }
+
+}
+
diff --git a/apps/simplefabric/src/main/java/org/onosproject/simplefabric/SimpleFabricL2Forward.java b/apps/simplefabric/src/main/java/org/onosproject/simplefabric/SimpleFabricL2Forward.java
new file mode 100644
index 0000000..41f0253
--- /dev/null
+++ b/apps/simplefabric/src/main/java/org/onosproject/simplefabric/SimpleFabricL2Forward.java
@@ -0,0 +1,437 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.simplefabric;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+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.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.net.intf.Interface;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.EncapsulationType;
+import org.onosproject.net.FilteredConnectPoint;
+import org.onosproject.net.Host;
+import org.onosproject.net.ResourceGroup;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.host.HostService;
+import org.onosproject.net.intent.Constraint;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentService;
+import org.onosproject.net.intent.Key;
+import org.onosproject.net.intent.MultiPointToSinglePointIntent;
+import org.onosproject.net.intent.SinglePointToMultiPointIntent;
+import org.onosproject.net.intent.constraint.EncapsulationConstraint;
+import org.onosproject.net.intent.constraint.PartialFailureConstraint;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Objects;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+
+/**
+ * An implementation of L2NetworkOperationService.
+ * Handles the execution order of the L2 Network operations generated by the
+ * application.
+ */
+@Component(immediate = true, enabled = false)
+public class SimpleFabricL2Forward {
+
+    public static final String BROADCAST = "BCAST";
+    public static final String UNICAST = "UNI";
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+    protected ApplicationId l2ForwardAppId;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected IntentService intentService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected HostService hostService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected SimpleFabricService simpleFabric;
+
+    public static final ImmutableList<Constraint> L2NETWORK_CONSTRAINTS =
+            ImmutableList.of(new PartialFailureConstraint());
+
+    private Map<Key, SinglePointToMultiPointIntent> bctIntentsMap = Maps.newConcurrentMap();
+    private Map<Key, MultiPointToSinglePointIntent> uniIntentsMap = Maps.newConcurrentMap();
+    private Set<Key> toBePurgedIntentKeys = new HashSet<>();
+
+    private final InternalSimpleFabricListener simpleFabricListener = new InternalSimpleFabricListener();
+
+    @Activate
+    public void activate() {
+        l2ForwardAppId = coreService.registerApplication(simpleFabric.L2FORWARD_APP_ID);
+        log.info("simple fabric l2 forwaring starting with l2net app id {}", l2ForwardAppId.toString());
+
+        simpleFabric.addListener(simpleFabricListener);
+
+        refresh();
+        checkIntentsPurge();
+
+        log.info("simple fabric l2forward started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        log.info("simple fabric l2forward stopping");
+
+        simpleFabric.removeListener(simpleFabricListener);
+
+        for (Intent intent : bctIntentsMap.values()) {
+            intentService.withdraw(intent);
+            toBePurgedIntentKeys.add(intent.key());
+        }
+        for (Intent intent : uniIntentsMap.values()) {
+            intentService.withdraw(intent);
+            toBePurgedIntentKeys.add(intent.key());
+        }
+        for (Key key : toBePurgedIntentKeys) {
+            Intent intentToPurge = intentService.getIntent(key);
+            if (intentToPurge != null) {
+                intentService.purge(intentToPurge);
+            }
+        }
+
+        // do not set clear for switch compatibility
+        //bctIntentsMap.clear();
+        //uniIntentsMap.clear();
+
+        log.info("simple fabric l2forward stopped");
+    }
+
+    private void refresh() {
+        log.debug("simple fabric l2forward refresh");
+
+        Map<Key, SinglePointToMultiPointIntent> newBctIntentsMap = Maps.newConcurrentMap();
+        Map<Key, MultiPointToSinglePointIntent> newUniIntentsMap = Maps.newConcurrentMap();
+
+        for (L2Network l2Network : simpleFabric.getL2Networks()) {
+            // scans all l2network regardless of dirty flag
+            // if l2Network.l2Forward == false or number of interfaces() < 2, no Intents generated
+            for (SinglePointToMultiPointIntent intent : buildBrcIntents(l2Network)) {
+                newBctIntentsMap.put(intent.key(), intent);
+            }
+            for (MultiPointToSinglePointIntent intent : buildUniIntents(l2Network, hostsFromL2Network(l2Network))) {
+                newUniIntentsMap.put(intent.key(), intent);
+            }
+            if (l2Network.dirty()) {
+                l2Network.setDirty(false);
+            }
+        }
+
+        boolean bctUpdated = false;
+        for (SinglePointToMultiPointIntent intent : bctIntentsMap.values()) {
+            SinglePointToMultiPointIntent newIntent = newBctIntentsMap.get(intent.key());
+            if (newIntent == null) {
+                log.info("simple fabric l2forward withdraw broadcast intent: {}", intent.key().toString());
+                toBePurgedIntentKeys.add(intent.key());
+                intentService.withdraw(intent);
+                bctUpdated = true;
+            }
+        }
+        for (SinglePointToMultiPointIntent intent : newBctIntentsMap.values()) {
+            SinglePointToMultiPointIntent oldIntent = bctIntentsMap.get(intent.key());
+            if (oldIntent == null ||
+                    !oldIntent.filteredEgressPoints().equals(intent.filteredEgressPoints()) ||
+                    !oldIntent.filteredIngressPoint().equals(intent.filteredIngressPoint()) ||
+                    !oldIntent.selector().equals(intent.selector()) ||
+                    !oldIntent.treatment().equals(intent.treatment()) ||
+                    !oldIntent.constraints().equals(intent.constraints())) {
+                log.info("simple fabric l2forward submit broadcast intent: {}", intent.key().toString());
+                toBePurgedIntentKeys.remove(intent.key());
+                intentService.submit(intent);
+                bctUpdated = true;
+            }
+        }
+
+        boolean uniUpdated = false;
+        for (MultiPointToSinglePointIntent intent : uniIntentsMap.values()) {
+            MultiPointToSinglePointIntent newIntent = newUniIntentsMap.get(intent.key());
+            if (newIntent == null) {
+                log.info("simple fabric l2forward withdraw unicast intent: {}", intent.key().toString());
+                toBePurgedIntentKeys.add(intent.key());
+                intentService.withdraw(intent);
+                uniUpdated = true;
+            }
+        }
+        for (MultiPointToSinglePointIntent intent : newUniIntentsMap.values()) {
+            MultiPointToSinglePointIntent oldIntent = uniIntentsMap.get(intent.key());
+            if (oldIntent == null ||
+                    !oldIntent.filteredEgressPoint().equals(intent.filteredEgressPoint()) ||
+                    !oldIntent.filteredIngressPoints().equals(intent.filteredIngressPoints()) ||
+                    !oldIntent.selector().equals(intent.selector()) ||
+                    !oldIntent.treatment().equals(intent.treatment()) ||
+                    !oldIntent.constraints().equals(intent.constraints())) {
+                log.info("simple fabric l2forward submit unicast intent: {}", intent.key().toString());
+                toBePurgedIntentKeys.remove(intent.key());
+                intentService.submit(intent);
+                uniUpdated = true;
+            }
+        }
+
+        if (bctUpdated) {
+            bctIntentsMap = newBctIntentsMap;
+        }
+        if (uniUpdated) {
+            uniIntentsMap = newUniIntentsMap;
+        }
+    }
+
+    private void checkIntentsPurge() {
+        // check intents to be purge
+        if (!toBePurgedIntentKeys.isEmpty()) {
+            Set<Key> purgedKeys = new HashSet<>();
+            for (Key key : toBePurgedIntentKeys) {
+                Intent intentToPurge = intentService.getIntent(key);
+                if (intentToPurge == null) {
+                    log.info("simple fabric l2forward purged intent: key={}", key.toString());
+                    purgedKeys.add(key);
+                } else {
+                    switch (intentService.getIntentState(key)) {
+                    case FAILED:
+                    case WITHDRAWN:
+                        log.info("simple fabric l2forward try to purge intent: key={}", key.toString());
+                        intentService.purge(intentToPurge);
+                        break;
+                    case INSTALL_REQ:
+                    case INSTALLED:
+                    case INSTALLING:
+                    case RECOMPILING:
+                    case COMPILING:
+                        log.warn("simple fabric l2forward withdraw intent to purge: key={}", key);
+                        intentService.withdraw(intentToPurge);
+                        break;
+                    case WITHDRAW_REQ:
+                    case WITHDRAWING:
+                    case PURGE_REQ:
+                    case CORRUPT:
+                    default:
+                        // no action
+                        break;
+                    }
+                }
+            }
+            toBePurgedIntentKeys.removeAll(purgedKeys);
+        }
+    }
+
+    // Generates Unicast Intents and broadcast Intents for the L2 Network.
+
+    private Set<Intent> generateL2NetworkIntents(L2Network l2Network) {
+        return new ImmutableSet.Builder<Intent>()
+            .addAll(buildBrcIntents(l2Network))
+            .addAll(buildUniIntents(l2Network, hostsFromL2Network(l2Network)))
+            .build();
+    }
+
+    // Build Boadcast Intents for a L2 Network.
+    private Set<SinglePointToMultiPointIntent> buildBrcIntents(L2Network l2Network) {
+        Set<Interface> interfaces = l2Network.interfaces();
+        if (!l2Network.l2Forward() || interfaces.size() < 2) {
+            return ImmutableSet.of();
+        }
+        Set<SinglePointToMultiPointIntent> brcIntents = Sets.newHashSet();
+        ResourceGroup resourceGroup = ResourceGroup.of(l2Network.name());
+
+        // Generates broadcast Intents from any network interface to other
+        // network interface from the L2 Network.
+        interfaces
+            .forEach(src -> {
+            FilteredConnectPoint srcFcp = buildFilteredConnectedPoint(src);
+            Set<FilteredConnectPoint> dstFcps = interfaces.stream()
+                    .filter(iface -> !iface.equals(src))
+                    .map(this::buildFilteredConnectedPoint)
+                    .collect(Collectors.toSet());
+            Key key = buildKey(l2Network.name(), "BCAST", srcFcp.connectPoint(), MacAddress.BROADCAST);
+            TrafficSelector selector = DefaultTrafficSelector.builder()
+                    .matchEthDst(MacAddress.BROADCAST)
+                    .build();
+            SinglePointToMultiPointIntent.Builder intentBuilder = SinglePointToMultiPointIntent.builder()
+                    .appId(l2ForwardAppId)
+                    .key(key)
+                    .selector(selector)
+                    .filteredIngressPoint(srcFcp)
+                    .filteredEgressPoints(dstFcps)
+                    .constraints(buildConstraints(L2NETWORK_CONSTRAINTS, l2Network.encapsulation()))
+                    .priority(SimpleFabricService.PRI_L2NETWORK_BROADCAST)
+                    .resourceGroup(resourceGroup);
+            brcIntents.add(intentBuilder.build());
+        });
+        return brcIntents;
+    }
+
+    // Builds unicast Intents for a L2 Network.
+    private Set<MultiPointToSinglePointIntent> buildUniIntents(L2Network l2Network, Set<Host> hosts) {
+        Set<Interface> interfaces = l2Network.interfaces();
+        if (!l2Network.l2Forward() || interfaces.size() < 2) {
+            return ImmutableSet.of();
+        }
+        Set<MultiPointToSinglePointIntent> uniIntents = Sets.newHashSet();
+        ResourceGroup resourceGroup = ResourceGroup.of(l2Network.name());
+        hosts.forEach(host -> {
+            FilteredConnectPoint hostFcp = buildFilteredConnectedPoint(host);
+            Set<FilteredConnectPoint> srcFcps = interfaces.stream()
+                    .map(this::buildFilteredConnectedPoint)
+                    .filter(fcp -> !fcp.equals(hostFcp))
+                    .collect(Collectors.toSet());
+            Key key = buildKey(l2Network.name(), "UNI", hostFcp.connectPoint(), host.mac());
+            TrafficSelector selector = DefaultTrafficSelector.builder()
+                    .matchEthDst(host.mac()).build();
+            MultiPointToSinglePointIntent.Builder intentBuilder = MultiPointToSinglePointIntent.builder()
+                    .appId(l2ForwardAppId)
+                    .key(key)
+                    .selector(selector)
+                    .filteredIngressPoints(srcFcps)
+                    .filteredEgressPoint(hostFcp)
+                    .constraints(buildConstraints(L2NETWORK_CONSTRAINTS, l2Network.encapsulation()))
+                    .priority(SimpleFabricService.PRI_L2NETWORK_UNICAST)
+                    .resourceGroup(resourceGroup);
+            uniIntents.add(intentBuilder.build());
+        });
+
+        return uniIntents;
+    }
+
+    // Intent generate utilities
+
+    private Set<Host> hostsFromL2Network(L2Network l2Network) {
+        Set<Interface> interfaces = l2Network.interfaces();
+        return interfaces.stream()
+                .map(this::hostsFromInterface)
+                .flatMap(Collection::stream)
+                .collect(Collectors.toSet());
+    }
+
+    private Set<Host> hostsFromInterface(Interface iface) {
+        return hostService.getConnectedHosts(iface.connectPoint())
+                .stream()
+                .filter(host -> host.vlan().equals(iface.vlan()))
+                .collect(Collectors.toSet());
+    }
+
+    private Key buildKey(String l2NetworkName, String type, ConnectPoint cPoint, MacAddress dstMac) {
+        return Key.of(l2NetworkName + "-" + type + "-" + cPoint.toString() + "-" + dstMac, l2ForwardAppId);
+    }
+
+    private List<Constraint> buildConstraints(List<Constraint> constraints, EncapsulationType encapsulation) {
+        if (!encapsulation.equals(EncapsulationType.NONE)) {
+            List<Constraint> newConstraints = new ArrayList<>(constraints);
+            constraints.stream()
+                .filter(c -> c instanceof EncapsulationConstraint)
+                .forEach(newConstraints::remove);
+            newConstraints.add(new EncapsulationConstraint(encapsulation));
+            return ImmutableList.copyOf(newConstraints);
+        }
+        return constraints;
+    }
+
+    private FilteredConnectPoint buildFilteredConnectedPoint(Interface iface) {
+        Objects.requireNonNull(iface);
+        TrafficSelector.Builder trafficSelector = DefaultTrafficSelector.builder();
+
+        if (iface.vlan() != null && !iface.vlan().equals(VlanId.NONE)) {
+            trafficSelector.matchVlanId(iface.vlan());
+        }
+        return new FilteredConnectPoint(iface.connectPoint(), trafficSelector.build());
+    }
+
+    protected FilteredConnectPoint buildFilteredConnectedPoint(Host host) {
+        Objects.requireNonNull(host);
+        TrafficSelector.Builder trafficSelector = DefaultTrafficSelector.builder();
+
+        if (host.vlan() != null && !host.vlan().equals(VlanId.NONE)) {
+            trafficSelector.matchVlanId(host.vlan());
+        }
+        return new FilteredConnectPoint(host.location(), trafficSelector.build());
+    }
+
+    // Dump command handler
+    private void dump(String subject, PrintStream out) {
+        if (subject == "intents") {
+            out.println("L2Forward Broadcast Intents:\n");
+            for (SinglePointToMultiPointIntent intent: bctIntentsMap.values()) {
+                out.println("    " + intent.key().toString()
+                          + ": " + intent.selector().criteria()
+                          + ", [" + intent.filteredIngressPoint().connectPoint()
+                          + "] -> " + intent.filteredEgressPoints().stream()
+                                      .map(FilteredConnectPoint::connectPoint).collect(Collectors.toSet()));
+            }
+            out.println("");
+            out.println("L2Forward Unicast Intents:\n");
+            for (MultiPointToSinglePointIntent intent: uniIntentsMap.values()) {
+                out.println("    " + intent.key().toString()
+                          + ": " + intent.selector().criteria()
+                          + ", [" + intent.filteredIngressPoints().stream()
+                                    .map(FilteredConnectPoint::connectPoint).collect(Collectors.toSet())
+                          + "] -> " + intent.filteredEgressPoint().connectPoint());
+            }
+            out.println("");
+            out.println("L2Forward Intents to Be Purged:\n");
+            for (Key key: toBePurgedIntentKeys) {
+                out.println("    " + key.toString());
+            }
+            out.println("");
+        }
+    }
+
+    // Listener
+    private class InternalSimpleFabricListener implements SimpleFabricListener {
+        @Override
+        public void event(SimpleFabricEvent event) {
+            switch (event.type()) {
+            case SIMPLE_FABRIC_UPDATED:
+                refresh();
+                checkIntentsPurge();
+                break;
+            case SIMPLE_FABRIC_IDLE:
+                refresh();
+                checkIntentsPurge();
+                break;
+            case SIMPLE_FABRIC_DUMP:
+                dump(event.subject(), event.out());
+                break;
+            default:
+                // NOTE: nothing to do on SIMPLE_FABRIC_FLUSH
+                break;
+            }
+        }
+    }
+
+}
diff --git a/apps/simplefabric/src/main/java/org/onosproject/simplefabric/SimpleFabricListener.java b/apps/simplefabric/src/main/java/org/onosproject/simplefabric/SimpleFabricListener.java
new file mode 100644
index 0000000..726d578
--- /dev/null
+++ b/apps/simplefabric/src/main/java/org/onosproject/simplefabric/SimpleFabricListener.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.simplefabric;
+
+import org.onosproject.event.EventListener;
+
+/**
+ * Entity capable of receiving alarm related events.
+ */
+public interface SimpleFabricListener extends EventListener<SimpleFabricEvent> {
+}
+
diff --git a/apps/simplefabric/src/main/java/org/onosproject/simplefabric/SimpleFabricManager.java b/apps/simplefabric/src/main/java/org/onosproject/simplefabric/SimpleFabricManager.java
new file mode 100644
index 0000000..2bb53c9
--- /dev/null
+++ b/apps/simplefabric/src/main/java/org/onosproject/simplefabric/SimpleFabricManager.java
@@ -0,0 +1,687 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.simplefabric;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Maps;
+import com.googlecode.concurrenttrees.radix.node.concrete.DefaultByteArrayNodeFactory;
+import com.googlecode.concurrenttrees.radixinverted.ConcurrentInvertedRadixTree;
+import com.googlecode.concurrenttrees.radixinverted.InvertedRadixTree;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.onlab.packet.ARP;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip6Address;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.IPv6;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onlab.packet.ndp.NeighborSolicitation;
+import org.onosproject.app.ApplicationService;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.component.ComponentService;
+import org.onosproject.event.ListenerRegistry;
+import org.onosproject.net.intf.Interface;
+import org.onosproject.net.intf.InterfaceService;
+import org.onosproject.net.intf.InterfaceListener;
+import org.onosproject.net.intf.InterfaceEvent;
+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.ConnectPoint;
+import org.onosproject.net.device.DeviceEvent;
+import org.onosproject.net.device.DeviceListener;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.Host;
+import org.onosproject.net.host.HostService;
+import org.onosproject.net.host.HostListener;
+import org.onosproject.net.host.HostEvent;
+import org.onosproject.net.packet.PacketService;
+import org.onosproject.net.packet.DefaultOutboundPacket;
+import org.onosproject.net.packet.OutboundPacket;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.nio.ByteBuffer;
+import java.util.Iterator;
+import java.util.HashSet;
+import java.util.Collection;
+import java.util.Set;
+import java.util.Map;
+
+import static org.onosproject.simplefabric.RouteTools.createBinaryString;
+
+
+/**
+ * Reactive routing configuration manager.
+ */
+@Component(immediate = true)
+@Service
+public class SimpleFabricManager extends ListenerRegistry<SimpleFabricEvent, SimpleFabricListener>
+        implements SimpleFabricService {
+
+    private final Logger log = LoggerFactory.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 configService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected NetworkConfigRegistry registry;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DeviceService deviceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected InterfaceService interfaceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected HostService hostService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected PacketService packetService;
+
+    // compoents to be activated within SimpleFabric
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected ComponentService componentService;
+
+    // SimpleFabric variables
+    private ApplicationId appId = null;
+
+    // l2 broadcast networks
+    private Set<L2Network> l2Networks = new HashSet<>();
+    private Set<Interface> l2NetworkInterfaces = new HashSet<>();
+
+    // Subnet table
+    private Set<IpSubnet> ipSubnets = new HashSet<>();
+    private InvertedRadixTree<IpSubnet> ip4SubnetTable =
+                 new ConcurrentInvertedRadixTree<>(new DefaultByteArrayNodeFactory());
+    private InvertedRadixTree<IpSubnet> ip6SubnetTable =
+                 new ConcurrentInvertedRadixTree<>(new DefaultByteArrayNodeFactory());
+
+    // Border Route table
+    private Set<Route> borderRoutes = new HashSet<>();
+    private InvertedRadixTree<Route> ip4BorderRouteTable =
+                 new ConcurrentInvertedRadixTree<>(new DefaultByteArrayNodeFactory());
+    private InvertedRadixTree<Route> ip6BorderRouteTable =
+                 new ConcurrentInvertedRadixTree<>(new DefaultByteArrayNodeFactory());
+
+    // VirtialGateway
+    private Map<IpAddress, MacAddress> virtualGatewayIpMacMap = Maps.newConcurrentMap();
+
+    // Refresh monitor thread
+    private Object refreshMonitor = new Object();
+    private boolean doRefresh = false;
+    private boolean doFlush = false;
+    private InternalRefreshThread refreshThread;
+
+    // Listener for Service Events
+    private final InternalNetworkConfigListener configListener = new InternalNetworkConfigListener();
+    private final InternalDeviceListener deviceListener = new InternalDeviceListener();
+    private final InternalHostListener hostListener = new InternalHostListener();
+    private final InternalInterfaceListener interfaceListener = new InternalInterfaceListener();
+
+    private ConfigFactory<ApplicationId, SimpleFabricConfig> simpleFabricConfigFactory =
+        new ConfigFactory<ApplicationId, SimpleFabricConfig>(
+                SubjectFactories.APP_SUBJECT_FACTORY,
+                SimpleFabricConfig.class, SimpleFabricConfig.KEY) {
+        @Override
+        public SimpleFabricConfig createConfig() {
+            return new SimpleFabricConfig();
+       }
+    };
+
+    @Activate
+    public void activate() {
+        log.info("simple fabric starting");
+
+        if (appId == null) {
+            appId = coreService.registerApplication(APP_ID);
+        }
+
+        // initial refresh
+        refresh();
+
+        configService.addListener(configListener);
+        registry.registerConfigFactory(simpleFabricConfigFactory);
+        deviceService.addListener(deviceListener);
+        hostService.addListener(hostListener);
+
+        componentService.activate(appId, SimpleFabricNeighbour.class.getName());
+        componentService.activate(appId, SimpleFabricReactiveRouting.class.getName());
+        if (SimpleFabricService.ALLOW_ETH_ADDRESS_SELECTOR) {
+            componentService.activate(appId, SimpleFabricL2Forward.class.getName());
+        }
+
+        refreshThread = new InternalRefreshThread();
+        refreshThread.start();
+
+        log.info("simple fabric started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        log.info("simple fabric stopping");
+
+        componentService.deactivate(appId, SimpleFabricNeighbour.class.getName());
+        componentService.deactivate(appId, SimpleFabricReactiveRouting.class.getName());
+        if (SimpleFabricService.ALLOW_ETH_ADDRESS_SELECTOR) {
+            componentService.deactivate(appId, SimpleFabricL2Forward.class.getName());
+        }
+
+        deviceService.removeListener(deviceListener);
+        hostService.removeListener(hostListener);
+        registry.unregisterConfigFactory(simpleFabricConfigFactory);
+        configService.removeListener(configListener);
+
+        refreshThread.stop();
+        refreshThread = null;
+
+        log.info("simple fabric stopped");
+    }
+
+    // Set up from configuration
+    // returns found dirty and refresh listners are called (true) or not (false)
+    private boolean refresh() {
+        log.debug("simple fabric refresh");
+        boolean dirty = false;
+
+        SimpleFabricConfig config = configService.getConfig(coreService.registerApplication(APP_ID),
+                                                            SimpleFabricConfig.class);
+        if (config == null) {
+            log.debug("No reactive routing config available!");
+            return false;
+        }
+
+        // l2Networks
+        Set<L2Network> newL2Networks = new HashSet<>();
+        Set<Interface> newL2NetworkInterfaces = new HashSet<>();
+        for (L2Network newL2NetworkConfig : config.getL2Networks()) {
+            L2Network newL2Network = L2Network.of(newL2NetworkConfig);
+
+            // fill up interfaces and Hosts with active port only
+            for (String ifaceName : newL2NetworkConfig.interfaceNames()) {
+                Interface iface = getInterfaceByName(ifaceName);
+                if (iface != null && deviceService.isAvailable(iface.connectPoint().deviceId())) {
+                     newL2Network.addInterface(iface);
+                     newL2NetworkInterfaces.add(iface);
+                }
+            }
+            for (Host host : hostService.getHosts()) {
+                // consider host with ip only
+                if (!host.ipAddresses().isEmpty()) {
+                    Interface iface = getAvailableDeviceHostInterface(host);
+                    if (iface != null && newL2Network.contains(iface)) {
+                        newL2Network.addHost(host);
+                    }
+                }
+            }
+            newL2Network.setDirty(true);
+
+            // update newL2Network's dirty flags if same entry already exists
+            for (L2Network prevL2Network : l2Networks) {
+                if (prevL2Network.equals(newL2Network)) {
+                    newL2Network.setDirty(prevL2Network.dirty());
+                    break;
+                }
+            }
+            newL2Networks.add(newL2Network);
+        }
+        if (!l2Networks.equals(newL2Networks)) {
+            l2Networks = newL2Networks;
+            dirty = true;
+        }
+        if (!l2NetworkInterfaces.equals(newL2NetworkInterfaces)) {
+            l2NetworkInterfaces = newL2NetworkInterfaces;
+            dirty = true;
+        }
+
+        // ipSubnets
+        Set<IpSubnet> newIpSubnets = config.ipSubnets();
+        InvertedRadixTree<IpSubnet> newIp4SubnetTable =
+                 new ConcurrentInvertedRadixTree<>(new DefaultByteArrayNodeFactory());
+        InvertedRadixTree<IpSubnet> newIp6SubnetTable =
+                 new ConcurrentInvertedRadixTree<>(new DefaultByteArrayNodeFactory());
+        Map<IpAddress, MacAddress> newVirtualGatewayIpMacMap = Maps.newConcurrentMap();
+        for (IpSubnet subnet : newIpSubnets) {
+            if (subnet.ipPrefix().isIp4()) {
+                newIp4SubnetTable.put(createBinaryString(subnet.ipPrefix()), subnet);
+            } else {
+                newIp6SubnetTable.put(createBinaryString(subnet.ipPrefix()), subnet);
+            }
+            newVirtualGatewayIpMacMap.put(subnet.gatewayIp(), subnet.gatewayMac());
+        }
+        if (!ipSubnets.equals(newIpSubnets)) {
+            ipSubnets = newIpSubnets;
+            ip4SubnetTable = newIp4SubnetTable;
+            ip6SubnetTable = newIp6SubnetTable;
+            dirty = true;
+        }
+        if (!virtualGatewayIpMacMap.equals(newVirtualGatewayIpMacMap)) {
+            virtualGatewayIpMacMap = newVirtualGatewayIpMacMap;
+            dirty = true;
+        }
+
+        // borderRoutes config handling
+        Set<Route> newBorderRoutes = config.borderRoutes();
+        if (!borderRoutes.equals(newBorderRoutes)) {
+            InvertedRadixTree<Route> newIp4BorderRouteTable =
+                    new ConcurrentInvertedRadixTree<>(new DefaultByteArrayNodeFactory());
+            InvertedRadixTree<Route> newIp6BorderRouteTable =
+                    new ConcurrentInvertedRadixTree<>(new DefaultByteArrayNodeFactory());
+            for (Route route : newBorderRoutes) {
+                if (route.prefix().isIp4()) {
+                    newIp4BorderRouteTable.put(createBinaryString(route.prefix()), route);
+                } else {
+                    newIp6BorderRouteTable.put(createBinaryString(route.prefix()), route);
+                }
+            }
+            borderRoutes = newBorderRoutes;
+            ip4BorderRouteTable = newIp4BorderRouteTable;
+            ip6BorderRouteTable = newIp6BorderRouteTable;
+            dirty = true;
+        }
+
+        // notify to SimpleFabric listeners
+        if (dirty) {
+            log.info("simple fabric refresh; notify events");
+            process(new SimpleFabricEvent(SimpleFabricEvent.Type.SIMPLE_FABRIC_UPDATED, "updated"));
+        }
+        return dirty;
+    }
+
+    private Interface getInterfaceByName(String interfaceName) {
+        Interface intf = interfaceService.getInterfaces().stream()
+                          .filter(iface -> iface.name().equals(interfaceName))
+                          .findFirst()
+                          .orElse(null);
+        if (intf == null) {
+            log.warn("simple fabric unknown interface name: {}", interfaceName);
+        }
+        return intf;
+    }
+
+    @Override
+    public ApplicationId getAppId() {
+        if (appId == null) {
+            appId = coreService.registerApplication(APP_ID);
+        }
+        return appId;
+    }
+
+    @Override
+    public Collection<L2Network> getL2Networks() {
+        return ImmutableSet.copyOf(l2Networks);
+    }
+
+    @Override
+    public Set<IpSubnet> getIpSubnets() {
+        return ImmutableSet.copyOf(ipSubnets);
+    }
+
+    @Override
+    public Set<Route> getBorderRoutes() {
+        return ImmutableSet.copyOf(borderRoutes);
+    }
+
+    @Override
+    public MacAddress getVMacForIp(IpAddress ip) {
+        return virtualGatewayIpMacMap.get(ip);
+    }
+
+    @Override
+    public boolean isVMac(MacAddress mac) {
+        return virtualGatewayIpMacMap.containsValue(mac);
+    }
+
+    @Override
+    public boolean isL2NetworkInterface(Interface intf) {
+        return l2NetworkInterfaces.contains(intf);
+    }
+
+    @Override
+    public L2Network findL2Network(ConnectPoint port, VlanId vlanId) {
+        for (L2Network l2Network : l2Networks) {
+            if (l2Network.contains(port, vlanId)) {
+                return l2Network;
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public L2Network findL2Network(String name) {
+        for (L2Network l2Network : l2Networks) {
+            if (l2Network.name().equals(name)) {
+                return l2Network;
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public IpSubnet findIpSubnet(IpAddress ip) {
+        Iterator<IpSubnet> it;
+        if (ip.isIp4()) {
+            it = ip4SubnetTable.getValuesForKeysPrefixing(
+                     createBinaryString(IpPrefix.valueOf(ip, Ip4Address.BIT_LENGTH))).iterator();
+        } else {
+            it = ip6SubnetTable.getValuesForKeysPrefixing(
+                     createBinaryString(IpPrefix.valueOf(ip, Ip6Address.BIT_LENGTH))) .iterator();
+        }
+        return (it.hasNext()) ? it.next() : null;
+    }
+
+    @Override
+    public Route findBorderRoute(IpAddress ip) {
+        // ASSUME: ipAddress is out of ipSubnet
+        Iterator<Route> it;
+        if (ip.isIp4()) {
+            it = ip4BorderRouteTable.getValuesForKeysPrefixing(
+                     createBinaryString(IpPrefix.valueOf(ip, Ip4Address.BIT_LENGTH))) .iterator();
+        } else {
+            it = ip6BorderRouteTable.getValuesForKeysPrefixing(
+                     createBinaryString(IpPrefix.valueOf(ip, Ip6Address.BIT_LENGTH))) .iterator();
+        }
+        return (it.hasNext()) ? it.next() : null;
+    }
+
+
+    @Override
+    public Interface getHostInterface(Host host) {
+        return interfaceService.getInterfaces().stream()
+                .filter(iface -> iface.connectPoint().equals(host.location()) &&
+                                 iface.vlan().equals(host.vlan()))
+                .findFirst()
+                .orElse(null);
+    }
+
+    private Interface getAvailableDeviceHostInterface(Host host) {
+        return interfaceService.getInterfaces().stream()
+                .filter(iface -> iface.connectPoint().equals(host.location()) &&
+                                 iface.vlan().equals(host.vlan()))
+                .filter(iface -> deviceService.isAvailable(iface.connectPoint().deviceId()))
+                .findFirst()
+                .orElse(null);
+    }
+
+    @Override
+    public boolean isIpAddressLocal(IpAddress ip) {
+        boolean result;
+        if (ip.isIp4()) {
+            return ip4SubnetTable.getValuesForKeysPrefixing(
+                     createBinaryString(IpPrefix.valueOf(ip, Ip4Address.BIT_LENGTH)))
+                     .iterator().hasNext();
+        } else {
+            return ip6SubnetTable.getValuesForKeysPrefixing(
+                     createBinaryString(IpPrefix.valueOf(ip, Ip6Address.BIT_LENGTH)))
+                     .iterator().hasNext();
+        }
+    }
+
+    @Override
+    public boolean isIpPrefixLocal(IpPrefix ipPrefix) {
+        if (ipPrefix.isIp4()) {
+            return (ip4SubnetTable.getValueForExactKey(createBinaryString(ipPrefix)) != null);
+        } else {
+            return (ip6SubnetTable.getValueForExactKey(createBinaryString(ipPrefix)) != null);
+        }
+    }
+
+    @Override
+    public boolean requestMac(IpAddress ip) {
+        IpSubnet ipSubnet = findIpSubnet(ip);
+        if (ipSubnet == null) {
+            log.warn("simple fabric request mac failed for unknown IpSubnet: {}", ip);
+            return false;
+        }
+        L2Network l2Network = findL2Network(ipSubnet.l2NetworkName());
+        if (l2Network == null) {
+            log.warn("simple fabric request mac failed for unknown l2Network name {}: {}",
+                     ipSubnet.l2NetworkName(), ip);
+            return false;
+        }
+        log.debug("simple fabric send request mac L2Network {}: {}", l2Network.name(), ip);
+        for (Interface iface : l2Network.interfaces()) {
+            Ethernet neighbourReq;
+            if (ip.isIp4()) {
+                neighbourReq = ARP.buildArpRequest(ipSubnet.gatewayMac().toBytes(),
+                                                   ipSubnet.gatewayIp().toOctets(),
+                                                   ip.toOctets(),
+                                                   iface.vlan().toShort());
+            } else {
+                byte[] soliciteIp = IPv6.getSolicitNodeAddress(ip.toOctets());
+                neighbourReq = NeighborSolicitation.buildNdpSolicit(
+                                                   ip.toOctets(),
+                                                   ipSubnet.gatewayIp().toOctets(),
+                                                   soliciteIp,
+                                                   ipSubnet.gatewayMac().toBytes(),
+                                                   IPv6.getMCastMacAddress(soliciteIp),
+                                                   iface.vlan());
+            }
+            TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                                               .setOutput(iface.connectPoint().port()).build();
+            OutboundPacket packet = new DefaultOutboundPacket(iface.connectPoint().deviceId(),
+                                               treatment, ByteBuffer.wrap(neighbourReq.serialize()));
+            packetService.emit(packet);
+        }
+        return true;
+    }
+
+    @Override
+    public void dumpToStream(String subject, OutputStream out) {
+        SimpleFabricEvent event = new SimpleFabricEvent(SimpleFabricEvent.Type.SIMPLE_FABRIC_DUMP, subject, out);
+        dump(event.subject(), event.out());  // dump in itself
+        process(event);  // dump in sub modules
+    }
+
+    // Dump handler
+    protected void dump(String subject, PrintStream out) {
+        if (subject == "show") {
+            out.println("Static Configuration Flag:");
+            out.println("    ALLOW_ETH_ADDRESS_SELECTOR="
+                        + SimpleFabricService.ALLOW_ETH_ADDRESS_SELECTOR);
+            out.println("    REACTIVE_SINGLE_TO_SINGLE="
+                        + SimpleFabricService.REACTIVE_SINGLE_TO_SINGLE);
+            out.println("    REACTIVE_ALLOW_LINK_CP="
+                        + SimpleFabricService.REACTIVE_ALLOW_LINK_CP);
+            out.println("    REACTIVE_HASHED_PATH_SELECTION="
+                        + SimpleFabricService.REACTIVE_HASHED_PATH_SELECTION);
+            out.println("    REACTIVE_MATCH_IP_PROTO="
+                        + SimpleFabricService.REACTIVE_MATCH_IP_PROTO);
+            out.println("");
+            out.println("SimpleFabricAppId:");
+            out.println("    " + getAppId());
+            out.println("");
+            out.println("l2Networks:");
+            for (L2Network l2Network : getL2Networks()) {
+                out.println("    " + l2Network);
+            }
+            out.println("");
+            out.println("ipSubnets:");
+            for (IpSubnet ipSubnet : getIpSubnets()) {
+                out.println("    " + ipSubnet);
+            }
+            out.println("");
+            out.println("borderRoutes:");
+            for (Route route : getBorderRoutes()) {
+                out.println("    " + route);
+            }
+        }
+    }
+
+    // Refresh action thread and notifier
+
+    private class InternalRefreshThread extends Thread {
+        public void run() {
+            while (true) {
+                boolean doRefreshMarked = false;
+                boolean doFlushMarked = false;
+                synchronized (refreshMonitor) {
+                    if (!doRefresh && !doFlush) {
+                        try {
+                            refreshMonitor.wait(IDLE_INTERVAL_MSEC);
+                        } catch (InterruptedException e) {
+                        }
+                    }
+                    doRefreshMarked = doRefresh;
+                    doRefresh = false;
+                    doFlushMarked = doFlush;
+                    doFlush = false;
+                }
+                if (doRefreshMarked) {
+                    try {
+                        refresh();
+                    } catch (Exception e) {
+                        log.warn("simple fabric refresh failed: exception={}", e);
+                    }
+                }
+                if (doFlushMarked) {
+                    try {
+                        log.info("simple fabric flush execute");
+                        process(new SimpleFabricEvent(SimpleFabricEvent.Type.SIMPLE_FABRIC_FLUSH, "flush"));
+                    } catch (Exception e) {
+                        log.warn("simple fabric flush failed: exception={}", e);
+                    }
+                }
+                if (!doRefreshMarked && !doFlushMarked) {
+                    try {
+                        if (!refresh()) {
+                            process(new SimpleFabricEvent(SimpleFabricEvent.Type.SIMPLE_FABRIC_IDLE, "idle"));
+                        }
+                    } catch (Exception e) {
+                        log.warn("simple fabric idle failed: exception={}", e);
+                    }
+                }
+            }
+        }
+    }
+
+    @Override
+    public void triggerRefresh() {
+        synchronized (refreshMonitor) {
+            doRefresh = true;
+            refreshMonitor.notifyAll();
+        }
+    }
+
+    @Override
+    public void triggerFlush() {
+        synchronized (refreshMonitor) {
+            doFlush = true;
+            refreshMonitor.notifyAll();
+        }
+    }
+
+    // Service Listeners
+
+    private class InternalNetworkConfigListener implements NetworkConfigListener {
+        @Override
+        public void event(NetworkConfigEvent event) {
+            switch (event.type()) {
+            case CONFIG_REGISTERED:
+            case CONFIG_UNREGISTERED:
+            case CONFIG_ADDED:
+            case CONFIG_UPDATED:
+            case CONFIG_REMOVED:
+                if (event.configClass().equals(SimpleFabricConfig.class)) {
+                    triggerRefresh();
+                }
+                break;
+            default:
+                break;
+            }
+        }
+    }
+
+    private class InternalDeviceListener implements DeviceListener {
+        @Override
+        public void event(DeviceEvent event) {
+            switch (event.type()) {
+            case DEVICE_ADDED:
+            case DEVICE_AVAILABILITY_CHANGED:
+            case DEVICE_REMOVED:
+            case DEVICE_SUSPENDED:
+            case DEVICE_UPDATED:
+            case PORT_ADDED:
+            case PORT_REMOVED:
+            case PORT_UPDATED:
+            // case PORT_STATS_UPDATED:  IGNORED
+                triggerRefresh();
+                break;
+            default:
+                break;
+            }
+        }
+    }
+
+    private class InternalHostListener implements HostListener {
+        @Override
+        public void event(HostEvent event) {
+            Host host = event.subject();
+            Host prevHost = event.prevSubject();
+            switch (event.type()) {
+            case HOST_MOVED:
+            case HOST_REMOVED:
+            case HOST_ADDED:
+            case HOST_UPDATED:
+                triggerRefresh();
+                break;
+            default:
+                break;
+            }
+        }
+    }
+
+    private class InternalInterfaceListener implements InterfaceListener {
+        @Override
+        public void event(InterfaceEvent event) {
+            Interface iface = event.subject();
+            Interface prevIface = event.prevSubject();
+            switch (event.type()) {
+            case INTERFACE_ADDED:
+            case INTERFACE_REMOVED:
+            case INTERFACE_UPDATED:
+                triggerRefresh();
+                break;
+            default:
+                break;
+            }
+        }
+    }
+
+}
+
diff --git a/apps/simplefabric/src/main/java/org/onosproject/simplefabric/SimpleFabricNeighbour.java b/apps/simplefabric/src/main/java/org/onosproject/simplefabric/SimpleFabricNeighbour.java
new file mode 100644
index 0000000..9d0b3fc
--- /dev/null
+++ b/apps/simplefabric/src/main/java/org/onosproject/simplefabric/SimpleFabricNeighbour.java
@@ -0,0 +1,240 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.simplefabric;
+
+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.MacAddress;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.net.intf.Interface;
+import org.onosproject.net.intf.InterfaceService;
+import org.onosproject.net.neighbour.NeighbourMessageContext;
+import org.onosproject.net.neighbour.NeighbourMessageHandler;
+import org.onosproject.net.neighbour.NeighbourResolutionService;
+import org.onosproject.net.Host;
+import org.onosproject.net.host.HostService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.HashSet;
+import java.util.Objects;
+import java.util.Set;
+
+
+/**
+ * Handles neighbour messages for on behalf of the L2 Network application. Handlers
+ * will be changed automatically by interface or network configuration events.
+ */
+@Component(immediate = true, enabled = false)
+public class SimpleFabricNeighbour {
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+    protected ApplicationId appId;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected HostService hostService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected InterfaceService interfaceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected NeighbourResolutionService neighbourService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected SimpleFabricService simpleFabric;
+
+    private final InternalSimpleFabricListener simpleFabricListener =
+            new InternalSimpleFabricListener();
+
+    private L2NetworkNeighbourMessageHandler neighbourHandler =
+            new L2NetworkNeighbourMessageHandler();
+
+    private Set<Interface> monitoredInterfaces = new HashSet<>();
+
+    @Activate
+    public void activate() {
+        appId = simpleFabric.getAppId();
+        simpleFabric.addListener(simpleFabricListener);
+        refresh();
+        log.info("simple fabric neighbour started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        simpleFabric.removeListener(simpleFabricListener);
+        unregister();
+        monitoredInterfaces.clear();
+        log.info("simple fabric neighbour stoped");
+    }
+
+    /**
+     * Registers neighbour handler to all available interfaces.
+     */
+    protected void refresh() {
+        Set<Interface> interfaces = interfaceService.getInterfaces();
+        // check for new interfaces
+        for (Interface intf : interfaces) {
+            if (!monitoredInterfaces.contains(intf) && simpleFabric.isL2NetworkInterface(intf)) {
+               log.info("simple fabric neighbour register handler: {}", intf);
+               neighbourService.registerNeighbourHandler(intf, neighbourHandler, appId);
+               monitoredInterfaces.add(intf);
+            } else {
+               log.debug("simple fabric neighobur unknown interface: {}", intf);
+            }
+        }
+        // check for removed interfaces
+        Set<Interface> monitoredInterfacesToBeRemoved = new HashSet<>();
+        for (Interface intf : monitoredInterfaces) {
+            if (!interfaces.contains(intf)) {
+               log.info("simple fabric neighbour unregister handler: {}", intf);
+               neighbourService.unregisterNeighbourHandler(intf, neighbourHandler, appId);
+               monitoredInterfacesToBeRemoved.add(intf);
+            }
+        }
+        for (Interface intf : monitoredInterfacesToBeRemoved) {
+            monitoredInterfaces.remove(intf);
+        }
+    }
+
+    /**
+     * Unregisters neighbour handler to all available interfaces.
+     */
+    protected void unregister() {
+        log.info("simple fabric neighbour unregister handler");
+        neighbourService.unregisterNeighbourHandlers(appId);
+    }
+
+    /**
+     * Handles request messages.
+     *
+     * @param context the message context
+     */
+    protected void handleRequest(NeighbourMessageContext context) {
+        MacAddress mac = simpleFabric.getVMacForIp(context.target());
+        if (mac != null) {
+            log.trace("simple fabric neightbour request on virtualGatewayAddress {}; response to {} {} mac={}",
+                      context.target(), context.inPort(), context.vlan(), mac);
+            context.reply(mac);
+            return;
+        }
+        // else forward to corresponding host
+
+        L2Network l2Network = simpleFabric.findL2Network(context.inPort(), context.vlan());
+        if (l2Network != null) {
+            int numForwards = 0;
+            if (!context.dstMac().isBroadcast() && !context.dstMac().isMulticast()) {
+                for (Host host : hostService.getHostsByMac(context.dstMac())) {
+                    log.trace("simple fabric neightbour request forward unicast to {}", host.location());
+                    context.forward(host.location());  // ASSUME: vlan is same
+                    // TODO: may need to check host.location().time()
+                    numForwards++;
+                }
+                if (numForwards > 0) {
+                    return;
+                }
+            }
+            // else do broadcast to all host in the same l2 network
+            log.trace("simple fabric neightbour request forward broadcast: {} {}",
+                     context.inPort(), context.vlan());
+            for (Interface iface : l2Network.interfaces()) {
+                if (!context.inPort().equals(iface.connectPoint())) {
+                    log.trace("simple fabric forward neighbour request broadcast to {}", iface);
+                    context.forward(iface);
+                }
+            }
+        } else {
+            log.warn("simple fabric neightbour request drop: {} {}",
+                     context.inPort(), context.vlan());
+            context.drop();
+        }
+    }
+
+    /**
+     * Handles reply messages between VLAN tagged interfaces.
+     *
+     * @param context the message context
+     * @param hostService the host service
+     */
+    protected void handleReply(NeighbourMessageContext context,
+                               HostService hostService) {
+        // Find target L2 Network, then reply to the host
+        L2Network l2Network = simpleFabric.findL2Network(context.inPort(), context.vlan());
+        if (l2Network != null) {
+            // TODO: need to check and update simpleFabric.L2Network
+            MacAddress mac = simpleFabric.getVMacForIp(context.target());
+            if (mac != null) {
+                log.trace("simple fabric neightbour response message to virtual gateway; drop: {} {} target={}",
+                          context.inPort(), context.vlan(), context.target());
+                context.drop();
+            } else {
+                // forward reply to the hosts of the dstMac
+                Set<Host> hosts = hostService.getHostsByMac(context.dstMac());
+                log.trace("simple fabric neightbour response message forward: {} {} target={} -> {}",
+                          context.inPort(), context.vlan(), context.target(), hosts);
+                hosts.stream()
+                        .map(host -> simpleFabric.getHostInterface(host))
+                        .filter(Objects::nonNull)
+                        .forEach(context::forward);
+            }
+        } else {
+            // this might be happened when we remove an interface from L2 Network
+            // just ignore this message
+            log.warn("simple fabric neightbour response message drop for unknown l2Network: {} {}",
+                     context.inPort(), context.vlan());
+            context.drop();
+        }
+    }
+
+    private class L2NetworkNeighbourMessageHandler implements NeighbourMessageHandler {
+        @Override
+        public void handleMessage(NeighbourMessageContext context,
+                                  HostService hostService) {
+            switch (context.type()) {
+                case REQUEST:
+                    handleRequest(context);
+                    break;
+                case REPLY:
+                    handleReply(context, hostService);
+                    break;
+                default:
+                    log.warn("simple fabric neightor unknown context type: {}", context.type());
+                    break;
+            }
+        }
+    }
+
+    private class InternalSimpleFabricListener implements SimpleFabricListener {
+        @Override
+        public void event(SimpleFabricEvent event) {
+            switch (event.type()) {
+            case SIMPLE_FABRIC_UPDATED:
+                refresh();
+                break;
+            default:
+                break;
+            }
+        }
+    }
+
+}
+
diff --git a/apps/simplefabric/src/main/java/org/onosproject/simplefabric/SimpleFabricReactiveRouting.java b/apps/simplefabric/src/main/java/org/onosproject/simplefabric/SimpleFabricReactiveRouting.java
new file mode 100644
index 0000000..10148c8
--- /dev/null
+++ b/apps/simplefabric/src/main/java/org/onosproject/simplefabric/SimpleFabricReactiveRouting.java
@@ -0,0 +1,977 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.simplefabric;
+
+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.EthType;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.ICMP;
+import org.onlab.packet.ICMP6;
+import org.onlab.packet.IPv4;
+import org.onlab.packet.IPv6;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip4Prefix;
+import org.onlab.packet.Ip6Address;
+import org.onlab.packet.Ip6Prefix;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.net.intf.InterfaceService;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.EncapsulationType;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.flow.DefaultFlowRule;
+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.FlowRule;
+import org.onosproject.net.flow.FlowRuleService;
+import org.onosproject.net.Host;
+import org.onosproject.net.host.HostService;
+import org.onosproject.net.intent.Constraint;
+import org.onosproject.net.intent.constraint.EncapsulationConstraint;
+import org.onosproject.net.intent.constraint.PartialFailureConstraint;
+import org.onosproject.net.intent.constraint.HashedPathSelectionConstraint;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentService;
+import org.onosproject.net.intent.Key;
+import org.onosproject.net.intent.MultiPointToSinglePointIntent;
+import org.onosproject.net.link.LinkService;
+import org.onosproject.net.packet.DefaultOutboundPacket;
+import org.onosproject.net.packet.InboundPacket;
+import org.onosproject.net.packet.OutboundPacket;
+import org.onosproject.net.packet.PacketContext;
+import org.onosproject.net.packet.PacketPriority;
+import org.onosproject.net.packet.PacketProcessor;
+import org.onosproject.net.packet.PacketService;
+import org.onosproject.net.Port;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.PrintStream;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+
+/**
+ * SimpleFabricReactiveRouting handles L3 Reactive Routing.
+ */
+@Component(immediate = true, enabled = false)
+public class SimpleFabricReactiveRouting {
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+    private ApplicationId reactiveAppId;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected PacketService packetService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected InterfaceService interfaceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DeviceService deviceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected LinkService linkService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected HostService hostService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected IntentService intentService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected FlowRuleService flowRuleService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected SimpleFabricService simpleFabric;
+
+    private ImmutableList<Constraint> reactiveConstraints
+            = ImmutableList.of(new PartialFailureConstraint());
+            //= ImmutableList.of();
+            // NOTE: SHOULD NOT use HashedPathSelectionConstraint
+            //       for unpredictable srcCp of Link appears as reactive packet traffic
+
+    private Set<FlowRule> interceptFlowRules = new HashSet<>();
+    private Set<Key> toBePurgedIntentKeys = new HashSet<>();
+            // NOTE: manage purged intents by key for intentService.getIntent() supports key only
+
+    private final InternalSimpleFabricListener simpleFabricListener = new InternalSimpleFabricListener();
+    private ReactiveRoutingProcessor processor = new ReactiveRoutingProcessor();
+
+    @Activate
+    public void activate() {
+        reactiveAppId = coreService.registerApplication(simpleFabric.REACTIVE_APP_ID);
+        log.info("simple fabric reactive routing starting with app id {}", reactiveAppId.toString());
+
+        // NOTE: may not clear at init for MIGHT generate pending_remove garbages
+        //       use flush event from simple fabric cli command
+
+        if (simpleFabric.REACTIVE_HASHED_PATH_SELECTION) {
+            reactiveConstraints = ImmutableList.of(new PartialFailureConstraint(),
+                                                   new HashedPathSelectionConstraint());
+        } else {
+            reactiveConstraints = ImmutableList.of(new PartialFailureConstraint());
+        }
+
+        processor = new ReactiveRoutingProcessor();
+        packetService.addProcessor(processor, PacketProcessor.director(2));
+        simpleFabric.addListener(simpleFabricListener);
+
+        registerIntercepts();
+        refreshIntercepts();
+
+        log.info("simple fabric reactive routing started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        log.info("simple fabric reactive routing stopping");
+
+        packetService.removeProcessor(processor);
+        simpleFabric.removeListener(simpleFabricListener);
+
+        withdrawIntercepts();
+
+        // NOTE: may not clear at init for MIGHT generate pending_remove garbages
+        //       use flush event from simple fabric cli command
+
+        toBePurgedIntentKeys.clear();
+
+        flowRuleService.removeFlowRulesById(reactiveAppId);
+
+        processor = null;
+
+        log.info("simple fabric reactive routing stopped");
+    }
+
+    /**
+     * Request packet in via the PacketService.
+     */
+    private void registerIntercepts() {
+        // register default intercepts on packetService for broder routing intercepts
+
+        packetService.requestPackets(
+            DefaultTrafficSelector.builder().matchEthType(Ethernet.TYPE_IPV4).build(),
+            PacketPriority.REACTIVE, reactiveAppId);
+
+        if (simpleFabric.ALLOW_IPV6) {
+            packetService.requestPackets(
+                DefaultTrafficSelector.builder().matchEthType(Ethernet.TYPE_IPV6).build(),
+                PacketPriority.REACTIVE, reactiveAppId);
+        }
+
+        log.info("simple fabric reactive routing ip packet intercepts started");
+    }
+
+    /**
+     * Cancel request for packet in via PacketService.
+     */
+    private void withdrawIntercepts() {
+        // unregister default intercepts on packetService
+
+        packetService.cancelPackets(
+            DefaultTrafficSelector.builder().matchEthType(Ethernet.TYPE_IPV4).build(),
+            PacketPriority.REACTIVE, reactiveAppId);
+
+        if (simpleFabric.ALLOW_IPV6) {
+            packetService.cancelPackets(
+                DefaultTrafficSelector.builder().matchEthType(Ethernet.TYPE_IPV6).build(),
+                PacketPriority.REACTIVE, reactiveAppId);
+        }
+
+        log.info("simple fabric reactive routing ip packet intercepts stopped");
+    }
+
+    /**
+     * Refresh device flow rules for reative intercepts on local ipSubnets.
+     */
+    private void refreshIntercepts() {
+        Set<FlowRule> newInterceptFlowRules = new HashSet<>();
+        for (Device device : deviceService.getAvailableDevices()) {
+            for (IpSubnet subnet : simpleFabric.getIpSubnets()) {
+                newInterceptFlowRules.add(generateInterceptFlowRule(true, device.id(), subnet.ipPrefix()));
+                // check if this devices has the ipSubnet, then add ip broadcast flue rule
+                L2Network l2Network = simpleFabric.findL2Network(subnet.l2NetworkName());
+                if (l2Network != null && l2Network.contains(device.id())) {
+                    newInterceptFlowRules.add(generateLocalSubnetIpBctFlowRule(device.id(), subnet.ipPrefix()));
+                }
+                // JUST FOR FLOW RULE TEST ONLY
+                //newInterceptFlowRules.add(generateTestFlowRule(device.id(), subnet.ipPrefix()));
+            }
+            for (Route route : simpleFabric.getBorderRoutes()) {
+                newInterceptFlowRules.add(generateInterceptFlowRule(false, device.id(), route.prefix()));
+            }
+        }
+
+        if (!newInterceptFlowRules.equals(interceptFlowRules)) {
+            // NOTE: DO NOT REMOVE INTERCEPT FLOW RULES FOR FAILED DEVICE FLOW UPDATE MIGHT BE BLOCKED
+            /*
+            interceptFlowRules.stream()
+                .filter(rule -> !newInterceptFlowRules.contains(rule))
+                .forEach(rule -> {
+                    flowRuleService.removeFlowRules(rule);
+                    log.info("simple fabric reactive routing remove intercept flow rule: {}", rule);
+                });
+            */
+            newInterceptFlowRules.stream()
+                .filter(rule -> !interceptFlowRules.contains(rule))
+                .forEach(rule -> {
+                    flowRuleService.applyFlowRules(rule);
+                    log.info("simple fabric reactive routing apply intercept flow rule: {}", rule);
+                });
+            interceptFlowRules = newInterceptFlowRules;
+        }
+    }
+
+    private FlowRule generateInterceptFlowRule(boolean isLocalSubnet, DeviceId deviceId, IpPrefix prefix) {
+        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+        if (prefix.isIp4()) {
+            selector.matchEthType(Ethernet.TYPE_IPV4);
+            if (prefix.prefixLength() > 0) {
+                selector.matchIPDst(prefix);
+            }
+        } else {
+            selector.matchEthType(Ethernet.TYPE_IPV6);
+            if (prefix.prefixLength() > 0) {
+                selector.matchIPv6Dst(prefix);
+            }
+        }
+        FlowRule rule = DefaultFlowRule.builder()
+                .forDevice(deviceId)
+                .withPriority(reactivePriority(false, isLocalSubnet, prefix.prefixLength()))
+                .withSelector(selector.build())
+                .withTreatment(DefaultTrafficTreatment.builder().punt().build())
+                .fromApp(reactiveAppId)
+                .makePermanent()
+                .forTable(0).build();
+        return rule;
+    }
+
+    private FlowRule generateLocalSubnetIpBctFlowRule(DeviceId deviceId, IpPrefix prefix) {
+        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+        IpPrefix bctPrefix;
+        if (prefix.isIp4()) {
+            bctPrefix = Ip4Prefix.valueOf(prefix.getIp4Prefix().address().toInt() |
+                                              ~Ip4Address.makeMaskPrefix(prefix.prefixLength()).toInt(),
+                                          Ip4Address.BIT_LENGTH);
+            selector.matchEthType(Ethernet.TYPE_IPV4);
+            selector.matchIPDst(bctPrefix);
+        } else {
+            byte[] p = prefix.getIp6Prefix().address().toOctets();
+            byte[] m = Ip6Address.makeMaskPrefix(prefix.prefixLength()).toOctets();
+            for (int i = 0; i < p.length; i++) {
+                 p[i] |= ~m[i];
+            }
+            bctPrefix = Ip6Prefix.valueOf(p, Ip6Address.BIT_LENGTH);
+            selector.matchEthType(Ethernet.TYPE_IPV6);
+            selector.matchIPv6Dst(bctPrefix);
+        }
+        TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
+        Set<ConnectPoint> newEgressPoints = new HashSet<>();
+        for (Port port : deviceService.getPorts(deviceId)) {
+            treatment.setOutput(port.number());
+        }
+        FlowRule rule = DefaultFlowRule.builder()
+                .forDevice(deviceId)
+                .withPriority(reactivePriority(true, true, bctPrefix.prefixLength()))
+                .withSelector(selector.build())
+                .withTreatment(treatment.build())
+                .fromApp(reactiveAppId)
+                .makePermanent()
+                .forTable(0).build();
+        return rule;
+    }
+
+    /**
+     * Refresh routes by examining network resource status.
+     */
+    private void refreshRouteIntents() {
+        for (Intent entry : intentService.getIntents()) {
+            if (!reactiveAppId.equals(entry.appId())) {
+                continue;
+            }
+
+            MultiPointToSinglePointIntent intent = (MultiPointToSinglePointIntent) entry;
+
+            if (!intentService.isLocal(intent.key())) {
+                if (toBePurgedIntentKeys.contains(intent.key())) {
+                    toBePurgedIntentKeys.remove(intent.key());  // clear non local intent
+                }
+                continue;
+            }
+
+            try {
+                switch (intentService.getIntentState(intent.key())) {
+                //case FAILED:   // failed intent is not auto removed
+                case WITHDRAWN:
+                    log.warn("intent found failed or withdrawn; "
+                             +  "remove and try to purge intent: key={}", intent.key());
+                    // purge intents here without withdraw
+                    intentService.purge(intentService.getIntent(intent.key()));
+                    toBePurgedIntentKeys.add(intent.key());
+                    continue;
+                default: // no action
+                    break;
+                }
+            } catch (Exception e) {
+                log.warn("intent status lookup failed: error={}", e);
+                continue;  // this intent seems invalid; no action
+            }
+
+            // dummy loop to break on remove cases
+            if (!deviceService.isAvailable(intent.egressPoint().deviceId())) {
+                log.info("refresh route intents; remove intent for no device: key={}", intent.key());
+                intentService.withdraw(intentService.getIntent(intent.key()));
+                toBePurgedIntentKeys.add(intent.key());
+                continue;
+            }
+            if (!(simpleFabric.findL2Network(intent.egressPoint(), VlanId.NONE) != null ||
+                  (simpleFabric.REACTIVE_ALLOW_LINK_CP &&
+                   !linkService.getEgressLinks(intent.egressPoint()).isEmpty()))) {
+                log.info("refresh route intents; remove intent for egress point not available: key={}", intent.key());
+                intentService.withdraw(intentService.getIntent(intent.key()));
+                toBePurgedIntentKeys.add(intent.key());
+                continue;
+            }
+
+            // MAY NEED TO CHECK: intent.egressPoint and intent.treatment's dstMac is valid against hosts
+            if (simpleFabric.REACTIVE_SINGLE_TO_SINGLE && !simpleFabric.REACTIVE_ALLOW_LINK_CP) {
+                // single path intent only; no need to check ingress points
+                continue;
+            }
+
+            Set<ConnectPoint> newIngressPoints = new HashSet<>();
+            boolean ingressPointChanged = false;
+            for (ConnectPoint cp : intent.ingressPoints()) {
+                if (deviceService.isAvailable(cp.deviceId()) &&
+                    (simpleFabric.findL2Network(cp, VlanId.NONE) != null ||
+                     (simpleFabric.REACTIVE_ALLOW_LINK_CP &&
+                      !linkService.getIngressLinks(cp).isEmpty()))) {
+                    newIngressPoints.add(cp);
+                } else {
+                    log.info("refresh route ingress cp of "
+                             + "not in 2Networks nor links: {}", cp);
+                    ingressPointChanged = true;
+                }
+            }
+            if (newIngressPoints.isEmpty()) {
+                log.info("refresh route intents; "
+                          + "remove intent for no ingress nor egress point available: key={}", intent.key());
+                intentService.withdraw(intentService.getIntent(intent.key()));
+                toBePurgedIntentKeys.add(intent.key());
+                continue;
+            }
+            // update ingress points
+            if (ingressPointChanged) {
+                MultiPointToSinglePointIntent updatedIntent =
+                    MultiPointToSinglePointIntent.builder()
+                        .appId(reactiveAppId)
+                        .key(intent.key())
+                        .selector(intent.selector())
+                        .treatment(intent.treatment())
+                        .ingressPoints(newIngressPoints)
+                        .egressPoint(intent.egressPoint())
+                        .priority(intent.priority())
+                        .constraints(intent.constraints())
+                        .build();
+                log.info("refresh route update intent: key={} updatedIntent={}",
+                        intent.key(), updatedIntent);
+                toBePurgedIntentKeys.remove(intent.key());   // may remove from old purged entry
+                intentService.submit(updatedIntent);
+            }
+        }
+    }
+
+    private void checkIntentsPurge() {
+        // check intents to be purge
+        if (!toBePurgedIntentKeys.isEmpty()) {
+            Set<Key> removeKeys = new HashSet<>();
+            for (Key key : toBePurgedIntentKeys) {
+                if (!intentService.isLocal(key)) {
+                    removeKeys.add(key);
+                    continue;
+                }
+                Intent intentToPurge = intentService.getIntent(key);
+                if (intentToPurge == null) {
+                    log.info("purged intent: key={}", key);
+                    removeKeys.add(key);
+                } else {
+                    switch (intentService.getIntentState(key)) {
+                    // case FAILED:  // not auto removed
+                    case WITHDRAWN:
+                        log.info("try to purge intent: key={}", key);
+                        intentService.purge(intentToPurge);
+                        break;
+                    case INSTALL_REQ:
+                    case INSTALLED:
+                    case INSTALLING:
+                    case RECOMPILING:
+                    case COMPILING:
+                        log.warn("not to purge for active intent: key={}", key);
+                        removeKeys.add(key);
+                        break;
+                    case WITHDRAW_REQ:
+                    case WITHDRAWING:
+                    case PURGE_REQ:
+                    case CORRUPT:
+                    default:
+                        // no action
+                        break;
+                    }
+                }
+            }
+            toBePurgedIntentKeys.removeAll(removeKeys);
+        }
+    }
+
+    public void withdrawAllReactiveIntents() {
+        // check all intents of this app
+        // NOTE: cli calls are handling within the cli called node only; so should not user inents.isLocal()
+        Set<Intent> myIntents = new HashSet<>();
+        for (Intent intent : intentService.getIntents()) {
+            if (reactiveAppId.equals(intent.appId())) {
+                myIntents.add(intent);
+            }
+        }
+        // withdraw all my intents
+        for (Intent intent : myIntents) {
+            switch (intentService.getIntentState(intent.key())) {
+            case FAILED:
+                intentService.purge(intent);
+                toBePurgedIntentKeys.add(intent.key());
+                break;
+            case WITHDRAWN:
+                intentService.purge(intent);
+                toBePurgedIntentKeys.add(intent.key());
+                break;
+            case INSTALL_REQ:
+            case INSTALLED:
+            case INSTALLING:
+            case RECOMPILING:
+            case COMPILING:
+                intentService.withdraw(intent);
+                toBePurgedIntentKeys.add(intent.key());
+                break;
+            case WITHDRAW_REQ:
+            case WITHDRAWING:
+                toBePurgedIntentKeys.add(intent.key());
+                break;
+            case PURGE_REQ:
+            case CORRUPT:
+            default:
+                // no action
+                break;
+            }
+        }
+    }
+
+    /**
+     * Reactive Packet Handling.
+     */
+    private class ReactiveRoutingProcessor implements PacketProcessor {
+        @Override
+        public void process(PacketContext context) {
+            InboundPacket pkt = context.inPacket();
+            Ethernet ethPkt = pkt.parsed();
+            if (ethPkt == null) {
+                return;
+            }
+            ConnectPoint srcCp = pkt.receivedFrom();
+            IpAddress srcIp;
+            IpAddress dstIp;
+            byte ipProto = 0;  /* 0 or tcp, udp */
+
+            switch (EthType.EtherType.lookup(ethPkt.getEtherType())) {
+            case IPV4:
+                IPv4 ipv4Packet = (IPv4) ethPkt.getPayload();
+                srcIp = IpAddress.valueOf(ipv4Packet.getSourceAddress());
+                dstIp = IpAddress.valueOf(ipv4Packet.getDestinationAddress());
+                ipProto = ipv4Packet.getProtocol();
+                break;
+            case IPV6:
+                IPv6 ipv6Packet = (IPv6) ethPkt.getPayload();
+                srcIp = IpAddress.valueOf(IpAddress.Version.INET6, ipv6Packet.getSourceAddress());
+                dstIp = IpAddress.valueOf(IpAddress.Version.INET6, ipv6Packet.getDestinationAddress());
+                ipProto = ipv6Packet.getNextHeader();
+                break;
+            default:
+                return;  // ignore unknow ether type packets
+            }
+            if (ipProto != 6 && ipProto != 17) {
+                ipProto = 0;  /* handle special for TCP and UDP only */
+            }
+
+            if (!checkVirtualGatewayIpPacket(pkt, srcIp, dstIp)) {
+                ipPacketReactiveProcessor(context, ethPkt, srcCp, srcIp, dstIp, ipProto);
+                // TODO: add ReactiveRouting for dstIp to srcIp with discovered egressCp as srcCp
+            }
+        }
+    }
+
+    /**
+     * handle Packet with dstIp=virtualGatewayIpAddresses.
+     * returns true(handled) or false(not for virtual gateway)
+     */
+    private boolean checkVirtualGatewayIpPacket(InboundPacket pkt, IpAddress srcIp, IpAddress dstIp) {
+        Ethernet ethPkt = pkt.parsed();  // assume valid
+
+        MacAddress mac = simpleFabric.getVMacForIp(dstIp);
+        if (mac == null || !ethPkt.getDestinationMAC().equals(mac)) {
+            return false;
+        } else if (dstIp.isIp4()) {
+            IPv4 ipv4Packet = (IPv4) ethPkt.getPayload();
+            if (ipv4Packet.getProtocol() == IPv4.PROTOCOL_ICMP) {
+                ICMP icmpPacket = (ICMP) ipv4Packet.getPayload();
+
+                if (icmpPacket.getIcmpType() == ICMP.TYPE_ECHO_REQUEST) {
+                    log.info("IPV4 ICMP ECHO request to virtual gateway: "
+                              + "srcIp={} dstIp={} proto={}", srcIp, dstIp, ipv4Packet.getProtocol());
+                    TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                                .setOutput(pkt.receivedFrom().port()).build();
+                    OutboundPacket packet =
+                        new DefaultOutboundPacket(pkt.receivedFrom().deviceId(), treatment,
+                                ByteBuffer.wrap(icmpPacket.buildIcmpReply(pkt.parsed()).serialize()));
+                    packetService.emit(packet);
+                    return true;
+                }
+            }
+            log.warn("IPV4 packet to virtual gateway dropped: "
+                     + "srcIp={} dstIp={} proto={}", srcIp, dstIp, ipv4Packet.getProtocol());
+            return true;
+
+        } else if (dstIp.isIp6()) {
+            // TODO: not tested yet (2017-07-20)
+            IPv6 ipv6Packet = (IPv6) ethPkt.getPayload();
+            if (ipv6Packet.getNextHeader() == IPv6.PROTOCOL_ICMP6) {
+                ICMP6 icmp6Packet = (ICMP6) ipv6Packet.getPayload();
+
+                if (icmp6Packet.getIcmpType() == ICMP6.ECHO_REQUEST) {
+                    log.info("IPV6 ICMP6 ECHO request to virtual gateway: srcIp={} dstIp={} nextHeader={}",
+                             srcIp, dstIp, ipv6Packet.getNextHeader());
+                    TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                                .setOutput(pkt.receivedFrom().port()).build();
+                    OutboundPacket packet =
+                        new DefaultOutboundPacket(pkt.receivedFrom().deviceId(), treatment,
+                                ByteBuffer.wrap(icmp6Packet.buildIcmp6Reply(pkt.parsed()).serialize()));
+                    packetService.emit(packet);
+                    return true;
+                }
+            }
+            log.warn("IPV6 packet to virtual gateway dropped: srcIp={} dstIp={} nextHeader={}",
+                     srcIp, dstIp, ipv6Packet.getNextHeader());
+            return true;
+
+        }
+        return false;  // unknown traffic
+    }
+
+    /**
+     * Routes packet reactively.
+     */
+    private void ipPacketReactiveProcessor(PacketContext context, Ethernet ethPkt, ConnectPoint srcCp,
+                                           IpAddress srcIp, IpAddress dstIp, byte ipProto) {
+        /* check reactive handling and forward packet */
+        log.trace("ip packet: srcCp={} srcIp={} dstIp={} ipProto={}",
+                  srcCp, srcIp, dstIp, ipProto);
+
+        EncapsulationType encap = EncapsulationType.NONE;
+
+        // prefix and nextHop for local Subnet
+        IpPrefix srcPrefix = srcIp.toIpPrefix();
+        IpPrefix dstPrefix = dstIp.toIpPrefix();
+        IpAddress srcNextHop = srcIp;
+        IpAddress dstNextHop = dstIp;
+        MacAddress treatmentSrcMac = ethPkt.getDestinationMAC();
+        int borderRoutePrefixLength = 0;
+        boolean isLocalSubnet = true;
+        boolean updateMac = simpleFabric.isVMac(ethPkt.getDestinationMAC());
+
+        // check subnet local or route
+        IpSubnet srcSubnet = simpleFabric.findIpSubnet(srcIp);
+        if (srcSubnet == null) {
+            Route route = simpleFabric.findBorderRoute(srcIp);
+            if (route == null) {
+                log.warn("route unknown: srcIp={}", srcIp);
+                return;
+            }
+            srcPrefix = route.prefix();
+            srcNextHop = route.nextHop();
+            borderRoutePrefixLength = route.prefix().prefixLength();
+            isLocalSubnet = false;
+        }
+        IpSubnet dstSubnet = simpleFabric.findIpSubnet(dstIp);
+        if (dstSubnet == null) {
+            Route route = simpleFabric.findBorderRoute(dstIp);
+            if (route == null) {
+                log.warn("route unknown: dstIp={}", dstIp);
+                return;
+            }
+            dstPrefix = route.prefix();
+            dstNextHop = route.nextHop();
+            borderRoutePrefixLength = route.prefix().prefixLength();
+            isLocalSubnet = false;
+        }
+
+        if (dstSubnet != null) {
+            // destination is local subnet ip
+            if (SimpleFabricService.ALLOW_ETH_ADDRESS_SELECTOR && dstSubnet.equals(srcSubnet)) {
+                // NOTE: if ALLOW_ETH_ADDRESS_SELECTOR=false; l2Forward is always false
+                L2Network l2Network = simpleFabric.findL2Network(dstSubnet.l2NetworkName());
+                treatmentSrcMac = ethPkt.getSourceMAC();
+                if (l2Network != null && l2Network.l2Forward()) {
+                    // NOTE: no reactive route action but do forward packet for L2Forward do not handle packet
+                    // update mac only if dstMac is virtualGatewayMac, else assume valid mac already for the l2 network
+                    log.info("LOCAL FORWARD ONLY: "
+                             + "srcCp={} srcIp={} dstIp={} srcMac={} dstMac={} vlanId={} ipProto={} updateMac={}",
+                             context.inPacket().receivedFrom(),
+                             srcIp, dstIp, ethPkt.getSourceMAC(), ethPkt.getDestinationMAC(),
+                             ethPkt.getVlanID(), ipProto, updateMac);
+                    forwardPacketToDstIp(context, dstIp, treatmentSrcMac, updateMac);
+                    return;
+                }
+            }
+            encap = dstSubnet.encapsulation();
+            if (encap == EncapsulationType.NONE && srcSubnet != null) {
+               encap = srcSubnet.encapsulation();
+            }
+        } else {
+            // destination is external network
+            if (srcSubnet == null) {
+                // both are externel network
+                log.warn("INVALID PACKET: srcIp and dstIp are both NON-LOCAL: "
+                         + "srcCP={} srcIp={} dstIp={} srcMac={} dstMac={} vlanId={} ipProto={} updateMac={}",
+                         context.inPacket().receivedFrom(),
+                         srcIp, dstIp, ethPkt.getSourceMAC(), ethPkt.getDestinationMAC(),
+                         ethPkt.getVlanID(), ipProto, updateMac);
+                return;
+            }
+            encap = srcSubnet.encapsulation();
+        }
+
+        log.info("REGI AND FORWARD: "
+                 + "srcCP={} srcIp={} dstIp={} srcMac={} dstMac={} vlanId={} ipProto={} updateMac={}",
+                 context.inPacket().receivedFrom(),
+                 srcIp, dstIp, ethPkt.getSourceMAC(), ethPkt.getDestinationMAC(),
+                 ethPkt.getVlanID(), ipProto, updateMac);
+        setUpConnectivity(srcCp, ipProto, srcPrefix, dstPrefix, dstNextHop, treatmentSrcMac, encap, updateMac,
+                          isLocalSubnet, borderRoutePrefixLength);
+        forwardPacketToDstIp(context, dstNextHop, treatmentSrcMac, updateMac);
+    }
+
+    /**
+     * Emits the specified packet onto the network.
+     */
+    private void forwardPacketToDstIp(PacketContext context, IpAddress nextHopIp,
+                                      MacAddress srcMac, boolean updateMac) {
+        Set<Host> hosts = hostService.getHostsByIp(nextHopIp);
+        Host dstHost;
+        if (!hosts.isEmpty()) {
+            dstHost = hosts.iterator().next();
+        } else {
+            // NOTE: hostService.requestMac(nextHopIp); NOT IMPLEMENTED in ONOS HostManager.java; do it myself
+            log.warn("forward packet nextHopIp host_mac unknown: nextHopIp={}", nextHopIp);
+            hostService.startMonitoringIp(nextHopIp);
+            simpleFabric.requestMac(nextHopIp);
+            // CONSIDER: make flood on all port of the dstHost's L2Network
+            return;
+        }
+        TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                .setOutput(dstHost.location().port()).build();
+        OutboundPacket outPacket;
+        if (updateMac) {
+            // NOTE: eth address update by treatment is NOT applied, so update mac myself
+            outPacket = new DefaultOutboundPacket(dstHost.location().deviceId(), treatment,
+                                ByteBuffer.wrap(context.inPacket().parsed()
+                                          .setSourceMACAddress(srcMac)
+                                          .setDestinationMACAddress(dstHost.mac()).serialize()));
+        } else {
+            outPacket = new DefaultOutboundPacket(dstHost.location().deviceId(), treatment,
+                                context.inPacket().unparsed());
+        }
+        // be quiet on normal situation
+        log.info("forward packet: nextHopIP={} srcCP={} dstCP={}",
+                 nextHopIp, context.inPacket().receivedFrom(), dstHost.location());
+        packetService.emit(outPacket);
+    }
+
+    /**
+     * Update intents for connectivity.
+     *
+     * ToHost: dstPrefix = dstHostIp.toIpPrefix(), nextHopIp = destHostIp
+     * ToInternet: dstPrefix = route.prefix(), nextHopIp = route.nextHopIp
+     * returns intent submited or not
+     */
+    private boolean setUpConnectivity(ConnectPoint srcCp, byte ipProto, IpPrefix srcPrefix, IpPrefix dstPrefix,
+                                      IpAddress nextHopIp, MacAddress treatmentSrcMac,
+                                      EncapsulationType encap, boolean updateMac,
+                                      boolean isLocalSubnet, int borderRoutePrefixLength) {
+        Key key;
+        String keyProtoTag = "";
+        if (simpleFabric.REACTIVE_MATCH_IP_PROTO) {
+            keyProtoTag = "-p" + ipProto;
+        }
+        if (simpleFabric.REACTIVE_SINGLE_TO_SINGLE) {
+            key = Key.of(srcPrefix.toString() + "-to-" + dstPrefix.toString() + keyProtoTag, reactiveAppId);
+        } else {
+            key = Key.of(dstPrefix.toString() + keyProtoTag, reactiveAppId);
+        }
+
+        if (!(simpleFabric.findL2Network(srcCp, VlanId.NONE) != null ||
+             (simpleFabric.REACTIVE_ALLOW_LINK_CP && !linkService.getIngressLinks(srcCp).isEmpty()))) {
+            log.warn("NO REGI for srcCp not in L2Network; srcCp={} srcPrefix={} dstPrefix={} nextHopIp={}",
+                      srcCp, srcPrefix, dstPrefix, nextHopIp);
+            return false;
+        }
+
+        MacAddress nextHopMac = null;
+        ConnectPoint egressPoint = null;
+        for (Host host : hostService.getHostsByIp(nextHopIp)) {
+            if (host.mac() != null) {
+                nextHopMac = host.mac();
+                egressPoint = host.location();
+                break;
+            }
+        }
+        if (nextHopMac == null || egressPoint == null) {
+            log.info("NO REGI for unknown nextHop Cp and Mac: srcPrefix={} dstPrefix={} nextHopIp={}",
+                     srcPrefix, dstPrefix, nextHopIp);
+            hostService.startMonitoringIp(nextHopIp);
+            simpleFabric.requestMac(nextHopIp);
+            return false;
+        }
+        TrafficTreatment treatment;
+        if (updateMac && simpleFabric.ALLOW_ETH_ADDRESS_SELECTOR) {
+            treatment = generateSetMacTreatment(nextHopMac, treatmentSrcMac);
+        } else {
+            treatment = DefaultTrafficTreatment.builder().build();
+        }
+
+        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+        if (dstPrefix.isIp4()) {
+            selector.matchEthType(Ethernet.TYPE_IPV4);
+            if (simpleFabric.REACTIVE_SINGLE_TO_SINGLE && srcPrefix.prefixLength() > 0) {
+                selector.matchIPSrc(srcPrefix);
+            }
+            if (dstPrefix.prefixLength() > 0) {
+                selector.matchIPDst(dstPrefix);
+            }
+            if (ipProto != 0 && simpleFabric.REACTIVE_MATCH_IP_PROTO) {
+                selector.matchIPProtocol(ipProto);
+            }
+        } else {
+            selector.matchEthType(Ethernet.TYPE_IPV6);
+            if (simpleFabric.REACTIVE_SINGLE_TO_SINGLE && srcPrefix.prefixLength() > 0) {
+                selector.matchIPv6Src(srcPrefix);
+            }
+            if (dstPrefix.prefixLength() > 0) {
+                selector.matchIPv6Dst(dstPrefix);
+            }
+            if (ipProto != 0 && simpleFabric.REACTIVE_MATCH_IP_PROTO) {
+                selector.matchIPProtocol(ipProto);
+            }
+        }
+
+        // check and merge already existing ingress points
+        Set<ConnectPoint> ingressPoints = new HashSet<>();
+        MultiPointToSinglePointIntent existingIntent = (MultiPointToSinglePointIntent) intentService.getIntent(key);
+        if (existingIntent != null) {
+            ingressPoints.addAll(existingIntent.ingressPoints());
+            if (!ingressPoints.add(srcCp)  // alread exists and dst not changed
+                    && egressPoint.equals(existingIntent.egressPoint())
+                    && treatment.equals(existingIntent.treatment())) {
+                log.warn("srcCP is already in mp2p intent: srcPrefix={} dstPrefix={} srcCp={}",
+                         srcPrefix, dstPrefix, srcCp);
+                return false;
+            }
+            log.info("update mp2p intent: srcPrefix={} dstPrefix={} srcCp={}",
+                     srcPrefix, dstPrefix, srcCp);
+        } else {
+            log.info("create mp2p intent: srcPrefix={} dstPrefix={} srcCp={}",
+                     srcPrefix, dstPrefix, srcCp);
+            ingressPoints.add(srcCp);
+        }
+
+        // priority for forwarding case
+        int priority = reactivePriority(true, isLocalSubnet, borderRoutePrefixLength);
+
+        MultiPointToSinglePointIntent newIntent = MultiPointToSinglePointIntent.builder()
+            .key(key)
+            .appId(reactiveAppId)
+            .selector(selector.build())
+            .treatment(treatment)
+            .ingressPoints(ingressPoints)
+            .egressPoint(egressPoint)
+            .priority(priority)
+            .constraints(buildConstraints(reactiveConstraints, encap))
+            .build();
+        log.info("submmit mp2p intent: srcPrefix={} dstPrefix={} srcCp={} "
+                 + "newIntent={} nextHopIp={} nextHopMac={} priority={}",
+                 srcPrefix, dstPrefix, ingressPoints, newIntent, nextHopIp, nextHopMac, priority);
+        toBePurgedIntentKeys.remove(newIntent.key());
+        intentService.submit(newIntent);
+        return true;
+    }
+
+    // generate treatment to target
+    private TrafficTreatment generateSetMacTreatment(MacAddress dstMac, MacAddress srcMac) {
+        return DefaultTrafficTreatment.builder()
+                   // NOTE: Cisco Switch requires both src and dst mac set
+                   .setEthDst(dstMac)
+                   .setEthSrc(srcMac)
+                   .build();
+    }
+
+    // monitor border peers for routeService lookup to be effective
+    private void monitorBorderPeers() {
+        for (Route route : simpleFabric.getBorderRoutes()) {
+            hostService.startMonitoringIp(route.nextHop());
+            simpleFabric.requestMac(route.nextHop());
+        }
+    }
+
+    // priority calculator
+    private int reactivePriority(boolean isForward, boolean isLocalSubnet, int borderRoutePrefixLength) {
+        if (isLocalSubnet) {  // localSubnet <-> localSubnet
+            if (isForward) {
+                return simpleFabric.PRI_REACTIVE_LOCAL_FORWARD;
+            } else {  // isInterncept
+                return simpleFabric.PRI_REACTIVE_LOCAL_INTERCEPT;
+            }
+        } else {  // isBorder: localSubnet <-> boarderRouteGateway
+            int offset;
+            if (isForward) {
+                offset = simpleFabric.PRI_REACTIVE_BORDER_FORWARD;
+            } else {  // isIntercept
+                offset = simpleFabric.PRI_REACTIVE_BORDER_INTERCEPT;
+            }
+           return simpleFabric.PRI_REACTIVE_BORDER_BASE
+                  + borderRoutePrefixLength * simpleFabric.PRI_REACTIVE_BORDER_STEP + offset;
+        }
+    }
+
+    // constraints generator
+    private List<Constraint> buildConstraints(List<Constraint> constraints, EncapsulationType encap) {
+        if (!encap.equals(EncapsulationType.NONE)) {
+            List<Constraint> newConstraints = new ArrayList<>(constraints);
+            constraints.stream()
+                .filter(c -> c instanceof EncapsulationConstraint)
+                .forEach(newConstraints::remove);
+            newConstraints.add(new EncapsulationConstraint(encap));
+            return ImmutableList.copyOf(newConstraints);
+        }
+        return constraints;
+    }
+
+    // Dump Cli Handler
+    private void dump(String subject, PrintStream out) {
+        if (subject == "intents") {
+            out.println("Reactive Routing Route Intents:\n");
+            for (Intent entry : intentService.getIntents()) {
+                if (reactiveAppId.equals(entry.appId())) {
+                    MultiPointToSinglePointIntent intent = (MultiPointToSinglePointIntent) entry;
+                    out.println("    " + intent.key().toString()
+                                + " to " + intent.egressPoint().toString()
+                                + " set " + intent.treatment().immediate().toString()
+                                + " from " + intent.ingressPoints().toString());
+                }
+            }
+            out.println("");
+
+            out.println("Reactive Routing Intercept Flow Rules:\n");
+            List<FlowRule> rules = new ArrayList(interceptFlowRules);
+            Collections.sort(rules, new Comparator<FlowRule>() {
+                    @Override
+                    public int compare(FlowRule a, FlowRule b) {
+                        int r = a.deviceId().toString().compareTo(b.deviceId().toString());
+                        return (r != 0) ? r : Integer.compare(b.priority(), a.priority());  // descending on priority
+                    }
+                });
+            for (FlowRule rule : rules) {
+                out.println("    device=" + rule.deviceId().toString()
+                          + " priority=" + rule.priority()
+                          + " selector=" + rule.selector().criteria().toString());
+            }
+            out.println("");
+            out.println("Reactive Routing Intents to Be Purged:\n");
+            for (Key key: toBePurgedIntentKeys) {
+                out.println("    " + key.toString());
+            }
+            out.println("");
+
+        } else if (subject == "reactive-intents") {
+            for (Intent entry : intentService.getIntents()) {
+                if (reactiveAppId.equals(entry.appId())) {
+                    MultiPointToSinglePointIntent intent = (MultiPointToSinglePointIntent) entry;
+                    out.println(intent.key().toString()
+                                + " to " + intent.egressPoint().toString()
+                                + " set " + intent.treatment().immediate().toString()
+                                + " from " + intent.ingressPoints().toString());
+                }
+            }
+        }
+    }
+
+    // Listener
+    private class InternalSimpleFabricListener implements SimpleFabricListener {
+        @Override
+        public void event(SimpleFabricEvent event) {
+            switch (event.type()) {
+            case SIMPLE_FABRIC_UPDATED:
+                refreshIntercepts();
+                refreshRouteIntents();
+                checkIntentsPurge();
+                break;
+            case SIMPLE_FABRIC_FLUSH:
+                withdrawAllReactiveIntents();
+                checkIntentsPurge();
+                break;
+            case SIMPLE_FABRIC_IDLE:
+                refreshIntercepts();
+                refreshRouteIntents();
+                checkIntentsPurge();
+                monitorBorderPeers();
+                break;
+            case SIMPLE_FABRIC_DUMP:
+                dump(event.subject(), event.out());
+                break;
+            default:
+                break;
+            }
+        }
+    }
+
+}
+
diff --git a/apps/simplefabric/src/main/java/org/onosproject/simplefabric/SimpleFabricService.java b/apps/simplefabric/src/main/java/org/onosproject/simplefabric/SimpleFabricService.java
new file mode 100644
index 0000000..c27a828
--- /dev/null
+++ b/apps/simplefabric/src/main/java/org/onosproject/simplefabric/SimpleFabricService.java
@@ -0,0 +1,206 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.simplefabric;
+
+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.event.ListenerService;
+import org.onosproject.net.intf.Interface;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.Host;
+
+import java.io.OutputStream;
+import java.util.Set;
+import java.util.Collection;
+
+/**
+ * Provides information about the routing configuration.
+ */
+public interface SimpleFabricService
+        extends ListenerService<SimpleFabricEvent, SimpleFabricListener> {
+
+    // App symbols
+    static final String APP_ID = "org.onosproject.simplefabric";
+    static final String L2FORWARD_APP_ID = "org.onosproject.simplefabric.l2forward";
+    static final String REACTIVE_APP_ID = "org.onosproject.simplefabric.reactive";
+
+    // Priority for l2NetworkRouting: L2NETWORK_UNICAST or L2NETWORK_BROADCAST
+    static final int PRI_L2NETWORK_UNICAST = 601;
+    static final int PRI_L2NETWORK_BROADCAST = 600;
+
+    // Reactive Routing within Local Subnets
+    // ASSUME: local subnets NEVER overlaps each other
+    static final int PRI_REACTIVE_LOCAL_FORWARD = 501;
+    static final int PRI_REACTIVE_LOCAL_INTERCEPT = 500;
+    // Reactive Routing for Border Routes with local subnet
+    // Priority: REACTIVE_BROUTE_BASE + routeIpPrefix * REACTIVE_BROUTE_STEP
+    //           + REACTIVE_BROUTE_FORWARD or REACTIVE_BROUTE_INTERCEPT
+    static final int PRI_REACTIVE_BORDER_BASE = 100;
+    static final int PRI_REACTIVE_BORDER_STEP = 2;
+    static final int PRI_REACTIVE_BORDER_FORWARD = 1;
+    static final int PRI_REACTIVE_BORDER_INTERCEPT = 0;
+
+    // Simple fabric event related timers
+    static final long IDLE_INTERVAL_MSEC = 5000;
+
+    // Feature control parameters
+    static final boolean ALLOW_IPV6 = false;
+    static final boolean ALLOW_ETH_ADDRESS_SELECTOR = true;
+    static final boolean REACTIVE_SINGLE_TO_SINGLE = false;
+    static final boolean REACTIVE_ALLOW_LINK_CP = false;  // MUST BE false (yjlee, 2017-10-18)
+    static final boolean REACTIVE_HASHED_PATH_SELECTION = false;
+    static final boolean REACTIVE_MATCH_IP_PROTO = false;
+
+    /**
+     * Gets appId.
+     *
+     * @return appId of simple fabric app
+     */
+    ApplicationId getAppId();
+
+    /**
+     * Gets all the l2Networks.
+     *
+     * @return all the l2Networks
+     */
+    Collection<L2Network> getL2Networks();
+
+    /**
+     * Retrieves the entire set of ipSubnets configuration.
+     *
+     * @return all the ipSubnets
+     */
+    Set<IpSubnet> getIpSubnets();
+
+    /**
+     * Retrieves the entire set of static routes to outer networks.
+     *
+     * @return the set of static routes to outer networks.
+     */
+    Set<Route> getBorderRoutes();
+
+    /**
+     * Gets Virtual Gateway Mac Address for Local Subnet Virtual Gateway Ip.
+     *
+     * @param ip the ip to check for Virtual Gateway Ip
+     * @return mac address of virtual gateway
+     */
+    MacAddress getVMacForIp(IpAddress ip);
+
+    /**
+     * Evaluates whether a mac is of Virtual Gateway Mac Addresses.
+     *
+     * @param mac the MacAddress to evaluate
+     * @return true if the mac is of any Vitrual Gateway Mac Address of ipSubnets
+     */
+    boolean isVMac(MacAddress mac);
+
+    /**
+     * Evaluates whether an Interface belongs to l2Networks.
+     *
+     * @param intf the interface to evaluate
+     * @return true if the inteface belongs to l2Networks configed, otherwise false
+     */
+    boolean isL2NetworkInterface(Interface intf);
+
+    /**
+     * Finds the L2 Network with given port and vlanId.
+     *
+     * @param port the port to be matched
+     * @param vlanId the vlanId to be matched
+     * @return the L2 Network for specific port and vlanId or null
+     */
+    L2Network findL2Network(ConnectPoint port, VlanId vlanId);
+
+    /**
+     * Finds the L2 Network of the name.
+     *
+     * @param name the name to be matched
+     * @return the L2 Network for specific name
+     */
+    L2Network findL2Network(String name);
+
+    /**
+     * Finds the IpSubnet containing the ipAddress.
+     *
+     * @param ipAddress the ipAddress to be matched
+     * @return the IpSubnet for specific ipAddress
+     */
+    IpSubnet findIpSubnet(IpAddress ipAddress);
+
+    /**
+     * Finds the Border Route containing the ipAddress.
+     * ASSUME: ipAddress is out of ipSubnets
+     *
+     * @param ipAddress the ipAddress to be matched
+     * @return the IpSubnet for specific ipAddress
+     */
+    Route findBorderRoute(IpAddress ipAddress);
+
+    /**
+     * Finds the network interface related to the host.
+     *
+     * @param host the host
+     * @return the interface related to the host
+     */
+    Interface getHostInterface(Host host);
+
+    /**
+     * Evaluates whether an IP address belongs to local SDN network.
+     *
+     * @param ipAddress the IP address to evaluate
+     * @return true if the IP address belongs to local SDN network, otherwise false
+     */
+    boolean isIpAddressLocal(IpAddress ipAddress);
+
+    /**
+     * Evaluates whether an IP prefix belongs to local SDN network.
+     *
+     * @param ipPrefix the IP prefix to evaluate
+     * @return true if the IP prefix belongs to local SDN network, otherwise false
+     */
+    boolean isIpPrefixLocal(IpPrefix ipPrefix);
+
+    /**
+     * Sends Neighbour Query (ARP or NDP) to Find Host Location.
+     *
+     * @param ip the ip address to resolve
+     * @return true if request mac packets are emitted. otherwise false
+     */
+    boolean requestMac(IpAddress ip);
+
+    /**
+     * Sends Dump Event to all SimpleFabricListeners to Dump Info on the Subject.
+     *
+     * @param subject the subject to dump
+     * @param out the output stream to dump
+     */
+    void dumpToStream(String subject, OutputStream out);
+
+    /**
+     * Triggers to send Refresh Notification to all sub modules.
+     */
+    void triggerRefresh();
+
+    /**
+     * Triggers to send Flush Notification to all sub modules.
+     */
+    void triggerFlush();
+
+}
diff --git a/apps/simplefabric/src/main/java/org/onosproject/simplefabric/package-info.java b/apps/simplefabric/src/main/java/org/onosproject/simplefabric/package-info.java
new file mode 100644
index 0000000..1e591a4
--- /dev/null
+++ b/apps/simplefabric/src/main/java/org/onosproject/simplefabric/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.
+ */
+
+/**
+ * Simple Leaf-Spine Network application.
+ */
+package org.onosproject.simplefabric;
