diff --git a/apps/simplefabric/app/BUCK b/apps/simplefabric/app/BUCK
new file mode 100644
index 0000000..104aee1
--- /dev/null
+++ b/apps/simplefabric/app/BUCK
@@ -0,0 +1,23 @@
+COMPILE_DEPS = [
+    '//lib:CORE_DEPS',
+    '//lib:JACKSON',
+    '//lib:concurrent-trees',
+    '//lib:javax.ws.rs-api',
+    '//lib:org.apache.karaf.shell.console',
+    '//cli:onos-cli',
+    '//utils/rest:onlab-rest',
+    '//apps/simplefabric/api:onos-apps-simplefabric-api',
+]
+
+TEST_DEPS = [
+    '//lib:TEST_ADAPTERS',
+]
+
+osgi_jar_with_tests (
+    api_description = 'REST API for Simple Fabric',
+    api_package = 'org.onosproject.simplefabric.web',
+    api_title = 'Simple Fabric API',
+    deps = COMPILE_DEPS,
+    test_deps = TEST_DEPS,
+    web_context = '/onos/v1/simplefabric',
+)
\ No newline at end of file
diff --git a/apps/simplefabric/app/BUILD b/apps/simplefabric/app/BUILD
new file mode 100644
index 0000000..9d93d06
--- /dev/null
+++ b/apps/simplefabric/app/BUILD
@@ -0,0 +1,12 @@
+COMPILE_DEPS = CORE_DEPS + JACKSON + CLI + REST + [
+    "//apps/simplefabric/api:onos-apps-simplefabric-api",
+    "@concurrent_trees//jar",
+]
+
+osgi_jar_with_tests(
+    api_description = "REST API for Simple Fabric",
+    api_package = "org.onosproject.simplefabric.web",
+    api_title = "Simple Fabric API",
+    web_context = "/onos/v1/simplefabric",
+    deps = COMPILE_DEPS,
+)
diff --git a/apps/simplefabric/app/app.xml b/apps/simplefabric/app/app.xml
new file mode 100644
index 0000000..3898661
--- /dev/null
+++ b/apps/simplefabric/app/app.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  -->
+<app name="org.onosproject.simplefabric" origin="Open Networking Foundation" 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/app/features.xml b/apps/simplefabric/app/features.xml
new file mode 100644
index 0000000..c9ac9f5
--- /dev/null
+++ b/apps/simplefabric/app/features.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+  ~ 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.
+  -->
+<features xmlns="http://karaf.apache.org/xmlns/features/v1.2.0" name="${project.artifactId}-${project.version}">
+    <feature name="onos-apps-simplefabric" version="${project.version}"
+             description="${project.description}">
+        <feature>onos-api</feature>
+        <bundle>mvn:${project.groupId}/onos-apps-simplefabric/${project.version}</bundle>
+    </feature>
+</features>
diff --git a/apps/simplefabric/app/src/main/java/org/onosproject/simplefabric/RouteTools.java b/apps/simplefabric/app/src/main/java/org/onosproject/simplefabric/RouteTools.java
new file mode 100644
index 0000000..b14438a
--- /dev/null
+++ b/apps/simplefabric/app/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/app/src/main/java/org/onosproject/simplefabric/SimpleFabricCommand.java b/apps/simplefabric/app/src/main/java/org/onosproject/simplefabric/SimpleFabricCommand.java
new file mode 100644
index 0000000..75db695
--- /dev/null
+++ b/apps/simplefabric/app/src/main/java/org/onosproject/simplefabric/SimpleFabricCommand.java
@@ -0,0 +1,69 @@
+/*
+ * 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.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.simplefabric.api.SimpleFabricService;
+
+/**
+ * CLI to interact with the SIMPLE_FABRIC application.
+ */
+@Command(scope = "onos", name = "simpleFabric",
+         description = "Manages the SimpleFabric application")
+public class SimpleFabricCommand extends AbstractShellCommand {
+
+    @Argument(index = 0, name = "command",
+              description = "Command: show|intents|reactive-intents|refresh|flush",
+              required = true, multiValued = false)
+    String command = null;
+
+    @Override
+    protected void execute() {
+
+        SimpleFabricService simpleFabric = get(SimpleFabricService.class);
+
+        if (command == null) {
+            print("command not found", command);
+            return;
+        }
+        switch (command) {
+        case "show":
+            simpleFabric.dumpToStream("show", System.out);
+            break;
+        case "intents":
+            simpleFabric.dumpToStream("intents", System.out);
+            break;
+        case "reactive-intents":
+            simpleFabric.dumpToStream("reactive-intents", System.out);
+            break;
+        case "refresh":
+            simpleFabric.triggerRefresh();
+            System.out.println("simple fabric refresh triggered");
+            break;
+        case "flush":
+            simpleFabric.triggerFlush();
+            System.out.println("simple fabric flush triggered");
+            break;
+        default:
+            System.out.println("unknown command: " + command);
+            break;
+        }
+    }
+
+}
+
diff --git a/apps/simplefabric/app/src/main/java/org/onosproject/simplefabric/SimpleFabricCommandCompleter.java b/apps/simplefabric/app/src/main/java/org/onosproject/simplefabric/SimpleFabricCommandCompleter.java
new file mode 100644
index 0000000..f497721
--- /dev/null
+++ b/apps/simplefabric/app/src/main/java/org/onosproject/simplefabric/SimpleFabricCommandCompleter.java
@@ -0,0 +1,52 @@
+/*
+ * 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.Lists;
+import org.apache.karaf.shell.console.completer.ArgumentCompleter;
+import org.onosproject.cli.AbstractChoicesCompleter;
+
+import java.util.List;
+import java.util.Arrays;
+import java.util.Collections;
+
+/**
+ * SimpleFabric command completer.
+ */
+public class SimpleFabricCommandCompleter extends AbstractChoicesCompleter {
+
+    private static final List<String> COMMAND_LIST =
+        Arrays.asList("show", "intents", "reactive-intents", "refresh", "flush");
+
+    @Override
+    public List<String> choices() {
+        ArgumentCompleter.ArgumentList argumentList = getArgumentList();
+        if (argumentList == null) {
+            return Collections.emptyList();
+        }
+        List<String> argList = Lists.newArrayList(argumentList.getArguments());
+        String argOne = null;
+        if (argList.size() > 1) {
+            argOne = argList.get(1);
+        }
+        if (COMMAND_LIST.contains(argOne)) {
+            return Collections.emptyList();
+        } else {
+            return COMMAND_LIST;
+        }
+    }
+}
+
diff --git a/apps/simplefabric/app/src/main/java/org/onosproject/simplefabric/SimpleFabricConfig.java b/apps/simplefabric/app/src/main/java/org/onosproject/simplefabric/SimpleFabricConfig.java
new file mode 100644
index 0000000..fada766
--- /dev/null
+++ b/apps/simplefabric/app/src/main/java/org/onosproject/simplefabric/SimpleFabricConfig.java
@@ -0,0 +1,161 @@
+/*
+ * 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.onosproject.simplefabric.api.IpSubnet;
+import org.onosproject.simplefabric.api.L2Network;
+import org.onosproject.simplefabric.api.Route;
+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 L2BROADCAST = "l2Broadcast";
+    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();
+            }
+            boolean l2Broadcast = true;
+            if (jsonNode.hasNonNull(L2BROADCAST)) {
+                l2Broadcast = jsonNode.get(L2BROADCAST).asBoolean();
+            }
+            try {
+                l2Networks.add(new L2Network(
+                        jsonNode.get(NAME).asText(), ifaces, EncapsulationType.enumFromString(encapsulation),
+                        l2Forward, l2Broadcast));
+            } 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/app/src/main/java/org/onosproject/simplefabric/SimpleFabricL2Forward.java b/apps/simplefabric/app/src/main/java/org/onosproject/simplefabric/SimpleFabricL2Forward.java
new file mode 100644
index 0000000..45a9fdd
--- /dev/null
+++ b/apps/simplefabric/app/src/main/java/org/onosproject/simplefabric/SimpleFabricL2Forward.java
@@ -0,0 +1,441 @@
+/*
+ * 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.onosproject.simplefabric.api.L2Network;
+import org.onosproject.simplefabric.api.SimpleFabricEvent;
+import org.onosproject.simplefabric.api.SimpleFabricListener;
+import org.onosproject.simplefabric.api.SimpleFabricService;
+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 (interfaces.size() < 2 || !l2Network.l2Forward() || !l2Network.l2Broadcast()) {
+            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 ("intents".equals(subject)) {
+            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/app/src/main/java/org/onosproject/simplefabric/SimpleFabricManager.java b/apps/simplefabric/app/src/main/java/org/onosproject/simplefabric/SimpleFabricManager.java
new file mode 100644
index 0000000..445fb71
--- /dev/null
+++ b/apps/simplefabric/app/src/main/java/org/onosproject/simplefabric/SimpleFabricManager.java
@@ -0,0 +1,670 @@
+/*
+ * 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.onosproject.simplefabric.api.IpSubnet;
+import org.onosproject.simplefabric.api.L2Network;
+import org.onosproject.simplefabric.api.Route;
+import org.onosproject.simplefabric.api.SimpleFabricEvent;
+import org.onosproject.simplefabric.api.SimpleFabricListener;
+import org.onosproject.simplefabric.api.SimpleFabricService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.nio.ByteBuffer;
+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 simple fabric 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 = findAvailableDeviceHostInterface(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 boolean isVMac(MacAddress mac) {
+        return virtualGatewayIpMacMap.containsValue(mac);
+    }
+
+    @Override
+    public boolean isL2NetworkInterface(Interface intf) {
+        return l2NetworkInterfaces.contains(intf);
+    }
+
+    @Override
+    public MacAddress findVMacForIp(IpAddress ip) {
+        return virtualGatewayIpMacMap.get(ip);
+    }
+
+    @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) {
+        if (ip.isIp4()) {
+            return ip4SubnetTable.getValueForLongestKeyPrefixing(
+                     createBinaryString(IpPrefix.valueOf(ip, Ip4Address.BIT_LENGTH)));
+        } else {
+            return ip6SubnetTable.getValueForLongestKeyPrefixing(
+                     createBinaryString(IpPrefix.valueOf(ip, Ip6Address.BIT_LENGTH)));
+        }
+    }
+
+    @Override
+    public Route findBorderRoute(IpAddress ip) {
+        // ASSUME: ipAddress is out of ipSubnet
+        if (ip.isIp4()) {
+            return ip4BorderRouteTable.getValueForLongestKeyPrefixing(
+                     createBinaryString(IpPrefix.valueOf(ip, Ip4Address.BIT_LENGTH)));
+        } else {
+            return ip6BorderRouteTable.getValueForLongestKeyPrefixing(
+                     createBinaryString(IpPrefix.valueOf(ip, Ip6Address.BIT_LENGTH)));
+        }
+    }
+
+
+    @Override
+    public Interface findHostInterface(Host host) {
+        return interfaceService.getInterfaces().stream()
+                .filter(iface -> iface.connectPoint().equals(host.location()) &&
+                                 iface.vlan().equals(host.vlan()))
+                .findFirst()
+                .orElse(null);
+    }
+
+    private Interface findAvailableDeviceHostInterface(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 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 ("show".equals(subject)) {
+            out.println("Static Configuration Flag:");
+            out.println("    ALLOW_IPV6="
+                        + SimpleFabricService.ALLOW_IPV6);
+            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 {
+        @Override
+        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) {
+                            log.warn("run thread interrupted", e);
+                            Thread.currentThread().interrupt();
+                        }
+                    }
+                    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/app/src/main/java/org/onosproject/simplefabric/SimpleFabricNeighbour.java b/apps/simplefabric/app/src/main/java/org/onosproject/simplefabric/SimpleFabricNeighbour.java
new file mode 100644
index 0000000..1b5330c
--- /dev/null
+++ b/apps/simplefabric/app/src/main/java/org/onosproject/simplefabric/SimpleFabricNeighbour.java
@@ -0,0 +1,244 @@
+/*
+ * 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.onosproject.simplefabric.api.L2Network;
+import org.onosproject.simplefabric.api.SimpleFabricEvent;
+import org.onosproject.simplefabric.api.SimpleFabricListener;
+import org.onosproject.simplefabric.api.SimpleFabricService;
+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.findVMacForIp(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.findVMacForIp(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.findHostInterface(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/app/src/main/java/org/onosproject/simplefabric/SimpleFabricReactiveRouting.java b/apps/simplefabric/app/src/main/java/org/onosproject/simplefabric/SimpleFabricReactiveRouting.java
new file mode 100644
index 0000000..4f83ae3
--- /dev/null
+++ b/apps/simplefabric/app/src/main/java/org/onosproject/simplefabric/SimpleFabricReactiveRouting.java
@@ -0,0 +1,989 @@
+/*
+ * 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.FilteredConnectPoint;
+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.intf.Interface;
+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.simplefabric.api.IpSubnet;
+import org.onosproject.simplefabric.api.L2Network;
+import org.onosproject.simplefabric.api.Route;
+import org.onosproject.simplefabric.api.SimpleFabricEvent;
+import org.onosproject.simplefabric.api.SimpleFabricListener;
+import org.onosproject.simplefabric.api.SimpleFabricService;
+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(),
+                                                                               l2Network));
+                }
+                // 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 isDstLocalSubnet, 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, isDstLocalSubnet, 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, L2Network l2Network) {
+        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 (Interface iface : l2Network.interfaces()) {
+            if (iface.connectPoint().deviceId().equals(deviceId)) {
+                treatment.setOutput(iface.connectPoint().port());
+            }
+        }
+        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<FilteredConnectPoint> newIngressPoints = new HashSet<>();
+            boolean ingressPointChanged = false;
+            for (FilteredConnectPoint cp : intent.filteredIngressPoints()) {
+                if (deviceService.isAvailable(cp.connectPoint().deviceId()) &&
+                    (simpleFabric.findL2Network(cp.connectPoint(), VlanId.NONE) != null ||
+                     (simpleFabric.REACTIVE_ALLOW_LINK_CP &&
+                      !linkService.getIngressLinks(cp.connectPoint()).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())
+                        .filteredIngressPoints(newIngressPoints)
+                        .filteredEgressPoint(intent.filteredEgressPoint())
+                        .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.findVMacForIp(dstIp);
+        if (mac == null || !simpleFabric.isVMac(ethPkt.getDestinationMAC())) {
+            /* Destination MAC should be any of virtual gateway macs */
+            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 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("unknown srcIp; drop: srcCp={} srcIp={} dstIp={} ipProto={}",
+                         srcCp, srcIp, dstIp, ipProto);
+                return;
+            }
+            srcPrefix = route.prefix();
+            srcNextHop = route.nextHop();
+            borderRoutePrefixLength = route.prefix().prefixLength();
+        }
+        IpSubnet dstSubnet = simpleFabric.findIpSubnet(dstIp);
+        if (dstSubnet == null) {
+            Route route = simpleFabric.findBorderRoute(dstIp);
+            if (route == null) {
+                log.warn("unknown dstIp; drop: srcCp={} srcIp={} dstIp={} ipProto={}",
+                         srcCp, srcIp, dstIp, ipProto);
+                return;
+            }
+            dstPrefix = route.prefix();
+            dstNextHop = route.nextHop();
+            borderRoutePrefixLength = route.prefix().prefixLength();
+        }
+
+        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,
+                          dstSubnet != null, 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 isDstLocalSubnet, int borderRoutePrefixLength) {
+        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);
+            }
+        }
+
+        Key key;
+        String keyProtoTag = "";
+        if (simpleFabric.REACTIVE_MATCH_IP_PROTO) {
+            keyProtoTag = "-p" + ipProto;
+        }
+        if (simpleFabric.REACTIVE_SINGLE_TO_SINGLE) {
+            // allocate intent per (srcPrefix, dstPrefix)
+            key = Key.of(srcPrefix.toString() + "-to-" + dstPrefix.toString() + keyProtoTag, reactiveAppId);
+        } else {
+            // allocate intent per (srcDeviceId, dstPrefix)
+            key = Key.of(srcCp.deviceId().toString() + "-to-" +  dstPrefix.toString() + keyProtoTag, reactiveAppId);
+        }
+
+        // check and merge already existing ingress points
+        Set<FilteredConnectPoint> ingressPoints = new HashSet<>();
+        MultiPointToSinglePointIntent existingIntent = (MultiPointToSinglePointIntent) intentService.getIntent(key);
+        if (existingIntent != null) {
+            ingressPoints.addAll(existingIntent.filteredIngressPoints());
+            if (!ingressPoints.add(new FilteredConnectPoint(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(new FilteredConnectPoint(srcCp));
+        }
+
+        // priority for forwarding case
+        int priority = reactivePriority(true, isDstLocalSubnet, borderRoutePrefixLength);
+
+        MultiPointToSinglePointIntent newIntent = MultiPointToSinglePointIntent.builder()
+            .key(key)
+            .appId(reactiveAppId)
+            .selector(selector.build())
+            .treatment(treatment)
+            .filteredIngressPoints(ingressPoints)
+            .filteredEgressPoint(new FilteredConnectPoint(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 isDstLocalSubnet, int borderRoutePrefixLength) {
+        if (isDstLocalSubnet) {  // -> dst:localSubnet
+            if (isForward) {
+                return simpleFabric.PRI_REACTIVE_LOCAL_FORWARD;
+            } else {  // isInterncept
+                return simpleFabric.PRI_REACTIVE_LOCAL_INTERCEPT;
+            }
+        } else {  // -> dst:boarderRouteNextHop
+            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 ("intents".equals(subject)) {
+            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 ("reactive-intents".equals(subject)) {
+            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/app/src/main/java/org/onosproject/simplefabric/SimpleFabricWebApplication.java b/apps/simplefabric/app/src/main/java/org/onosproject/simplefabric/SimpleFabricWebApplication.java
new file mode 100644
index 0000000..d82de73
--- /dev/null
+++ b/apps/simplefabric/app/src/main/java/org/onosproject/simplefabric/SimpleFabricWebApplication.java
@@ -0,0 +1,32 @@
+/*
+ * 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.rest.AbstractWebApplication;
+
+import java.util.Set;
+
+/**
+ * SIMPLE_FABRIC REST API web application.
+ */
+public class SimpleFabricWebApplication extends AbstractWebApplication {
+    @Override
+    public Set<Class<?>> getClasses() {
+        return getClasses(SimpleFabricWebResource.class);
+    }
+}
+
diff --git a/apps/simplefabric/app/src/main/java/org/onosproject/simplefabric/SimpleFabricWebResource.java b/apps/simplefabric/app/src/main/java/org/onosproject/simplefabric/SimpleFabricWebResource.java
new file mode 100644
index 0000000..3274a3e
--- /dev/null
+++ b/apps/simplefabric/app/src/main/java/org/onosproject/simplefabric/SimpleFabricWebResource.java
@@ -0,0 +1,109 @@
+/*
+ * 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.rest.AbstractWebResource;
+import org.onosproject.simplefabric.api.SimpleFabricService;
+
+import java.io.ByteArrayOutputStream;
+import javax.ws.rs.GET;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.core.Response;
+
+/**
+ * Manage SIMPLE_FABRIC Status.
+ */
+@Path("")
+public class SimpleFabricWebResource extends AbstractWebResource {
+
+    /**
+     * SIMPLE_FABRIC Show Status; dummy for now.
+     *
+     * @return 200 OK
+     */
+    @GET
+    @Path("status")
+    public Response queryStatus() {
+        return Response.ok("ok").build();
+    }
+
+    /**
+     * SIMPLE_FABRIC Show Configurations.
+     *
+     * @return 200 OK
+     */
+    @GET
+    @Path("show")
+    public Response queryShow() {
+        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        get(SimpleFabricService.class).dumpToStream("show", outputStream);
+        return Response.ok(outputStream.toString()).build();
+    }
+
+    /**
+     * SIMPLE_FABRIC Intents Infos.
+     *
+     * @return 200 OK
+     */
+    @GET
+    @Path("intents")
+    public Response queryIntents() {
+        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        get(SimpleFabricService.class).dumpToStream("intents", outputStream);
+        return Response.ok(outputStream.toString()).build();
+    }
+
+    /**
+     * SIMPLE_FABRIC Reactive Intents Infos.
+     *
+     * @return 200 OK
+     */
+    @GET
+    @Path("reactive-intents")
+    public Response queryReactiveIntents() {
+        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        get(SimpleFabricService.class).dumpToStream("reactive-intents", outputStream);
+        return Response.ok(outputStream.toString()).build();
+    }
+
+    /**
+     * Trigger SimpleFabric Service Refresh.
+     *
+     * @return 204 No Content
+     */
+    @PUT
+    @Path("refresh")
+    public Response triggerRefresh() {
+        get(SimpleFabricService.class).triggerRefresh();
+        return Response.status(204).build();
+    }
+
+    /**
+     * Trigger SimpleFabric Service Flush Reactive Intents.
+     *
+     * @return 204 No Content
+     */
+    @PUT
+    @Path("flush")
+    public Response triggerFlush() {
+        get(SimpleFabricService.class).triggerFlush();
+        return Response.status(204).build();
+    }
+
+}
+
diff --git a/apps/simplefabric/app/src/main/java/org/onosproject/simplefabric/package-info.java b/apps/simplefabric/app/src/main/java/org/onosproject/simplefabric/package-info.java
new file mode 100644
index 0000000..1e591a4
--- /dev/null
+++ b/apps/simplefabric/app/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;
diff --git a/apps/simplefabric/app/src/main/resources/OSGI-INF/blueprint/shell-config.xml b/apps/simplefabric/app/src/main/resources/OSGI-INF/blueprint/shell-config.xml
new file mode 100644
index 0000000..7b6893b
--- /dev/null
+++ b/apps/simplefabric/app/src/main/resources/OSGI-INF/blueprint/shell-config.xml
@@ -0,0 +1,28 @@
+<!--
+  ~ 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.
+  -->
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+
+    <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
+        <command>
+            <action class="org.onosproject.simplefabric.SimpleFabricCommand"/>
+            <completers>
+                <ref component-id="SimpleFabricCommandCompleter"/>
+            </completers>
+        </command>
+    </command-bundle>
+ 
+    <bean id="SimpleFabricCommandCompleter" class="org.onosproject.simplefabric.SimpleFabricCommandCompleter"/>
+</blueprint>
diff --git a/apps/simplefabric/app/src/main/webapp/WEB-INF/web.xml b/apps/simplefabric/app/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..e136671
--- /dev/null
+++ b/apps/simplefabric/app/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  -->
+<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
+         xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+         id="ONOS" version="2.5">
+    <display-name>Simple Fabric application REST API</display-name>
+
+    <security-constraint>
+        <web-resource-collection>
+            <web-resource-name>Secured</web-resource-name>
+            <url-pattern>/*</url-pattern>
+        </web-resource-collection>
+        <auth-constraint>
+            <role-name>admin</role-name>
+            <role-name>viewer</role-name>
+        </auth-constraint>
+    </security-constraint>
+
+    <security-role>
+        <role-name>admin</role-name>
+        <role-name>viewer</role-name>
+    </security-role>
+
+    <login-config>
+        <auth-method>BASIC</auth-method>
+        <realm-name>karaf</realm-name>
+    </login-config>
+
+    <servlet>
+        <servlet-name>JAX-RS Service</servlet-name>
+        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
+        <init-param>
+            <param-name>javax.ws.rs.Application</param-name>
+            <param-value>org.onosproject.simplefabric.SimpleFabricWebApplication</param-value>
+        </init-param>
+        <load-on-startup>1</load-on-startup>
+    </servlet>
+
+    <servlet-mapping>
+        <servlet-name>JAX-RS Service</servlet-name>
+        <url-pattern>/*</url-pattern>
+    </servlet-mapping>
+
+</web-app>
