sdn-ip reactive routing

   This module can handle 3 cases:
   (1) one host wants to talk to another host, both two hosts are in SDN network.
   (2) one host in SDN network wants to talk to another host in Internet.
   (3) one host from Internet wants to talk to another host in SDN network.
   In all cases, we use MultiPointToSinglePointIntent.

Change-Id: I80dd954bd608e52b45b993f3c27e67636a7105d9
diff --git a/apps/routing-api/src/main/java/org/onosproject/routing/IntentRequestListener.java b/apps/routing-api/src/main/java/org/onosproject/routing/IntentRequestListener.java
new file mode 100644
index 0000000..2d1bb31
--- /dev/null
+++ b/apps/routing-api/src/main/java/org/onosproject/routing/IntentRequestListener.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.routing;
+
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onosproject.net.ConnectPoint;
+
+/**
+ * An interface to process intent requests.
+ */
+public interface IntentRequestListener {
+
+    /**
+     * Sets up connectivity for packet from Internet to a host in local
+     * SDN network.
+     *
+     * @param dstIpAddress IP address of destination host in local SDN network
+     */
+    void setUpConnectivityInternetToHost(IpAddress dstIpAddress);
+
+    /**
+     * Sets up the connectivity for two hosts in local SDN network.
+     *
+     * @param dstIpAddress the destination IP address
+     * @param srcIpAddress the source IP address
+     * @param srcMacAddress the source MAC address
+     * @param srcConnectPoint the connectPoint of the source host
+     */
+    void setUpConnectivityHostToHost(IpAddress dstIpAddress,
+                                     IpAddress srcIpAddress,
+                                     MacAddress srcMacAddress,
+                                     ConnectPoint srcConnectPoint);
+
+    /**
+     * Adds one new ingress connect point into ingress points of an existing
+     * intent and resubmits the new intent.
+     * <p>
+     * If there is already an intent for an IP prefix in the system, we do not
+     * need to create a new one, we only need to update this existing intent by
+     * adding more ingress points.
+     * </p>
+     *
+     * @param ipPrefix the IP prefix used to search the existing
+     *        MultiPointToSinglePointIntent
+     * @param ingressConnectPoint the ingress connect point to be added into
+     *        the exiting intent
+     */
+    void updateExistingMp2pIntent(IpPrefix ipPrefix,
+                                  ConnectPoint ingressConnectPoint);
+
+    /**
+     * Checks whether there is a MultiPointToSinglePointIntent in memory for a
+     * given IP prefix.
+     *
+     * @param ipPrefix the IP prefix used to search the existing
+     *        MultiPointToSinglePointIntent
+     * @return true if there is a MultiPointToSinglePointIntent, otherwise false
+     */
+    boolean mp2pIntentExists(IpPrefix ipPrefix);
+
+}
diff --git a/apps/routing-api/src/main/java/org/onosproject/routing/RoutingService.java b/apps/routing-api/src/main/java/org/onosproject/routing/RoutingService.java
index fdd4f2c..4356984 100644
--- a/apps/routing-api/src/main/java/org/onosproject/routing/RoutingService.java
+++ b/apps/routing-api/src/main/java/org/onosproject/routing/RoutingService.java
@@ -17,17 +17,92 @@
 
 import java.util.Collection;
 
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onosproject.net.ConnectPoint;
+
 /**
  * Provides a way of interacting with the RIB management component.
  */
 public interface RoutingService {
 
     /**
-     * Starts the routing service.
-     *
-     * @param listener listener to send FIB updates to
+     * Specifies the type of an IP address or an IP prefix location.
      */
-    public void start(FibListener listener);
+    public static enum LocationType {
+        /**
+         * The location of an IP address or an IP prefix is in local SDN network.
+         */
+        LOCAL,
+        /**
+         * The location of an IP address or an IP prefix is outside local SDN network.
+         */
+        INTERNET,
+        /**
+         * There is no route for this IP address or IP prefix.
+         */
+        NO_ROUTE
+    }
+
+    /**
+     * Specifies the type of traffic.
+     * <p>
+     * We classify traffic by the first packet of each traffic.
+     * </p>
+     */
+    public enum TrafficType {
+        /**
+         * Traffic from a host located in local SDN network wants to
+         * communicate with destination host located in Internet (outside
+         * local SDN network).
+         */
+        HOST_TO_INTERNET,
+        /**
+         * Traffic from Internet wants to communicate with a host located
+         * in local SDN network.
+         */
+        INTERNET_TO_HOST,
+        /**
+         * Both the source host and destination host of a traffic are in
+         * local SDN network.
+         */
+        HOST_TO_HOST,
+        /**
+         * Traffic from Internet wants to traverse local SDN network.
+         */
+        INTERNET_TO_INTERNET,
+        /**
+         * Any traffic wants to communicate with a destination which has
+         * no route, or traffic from Internet wants to access a local private
+         * IP address.
+         */
+        DROP,
+        /**
+         * Traffic does not belong to the types above.
+         */
+        UNKNOWN
+    }
+
+    /**
+     * Starts the routing service.
+     */
+    public void start();
+
+    /**
+     * Adds FIB listener.
+     *
+     * @param fibListener listener to send FIB updates to
+     */
+    public void addFibListener(FibListener fibListener);
+
+    /**
+     * Adds intent creation and submission listener.
+     *
+     * @param intentRequestListener listener to send intent creation and
+     *        submission request to
+     */
+    public void addIntentRequestListener(IntentRequestListener
+                                         intentRequestListener);
 
     /**
      * Stops the routing service.
@@ -47,4 +122,43 @@
      * @return the SDN-IP IPv6 routes
      */
     public Collection<RouteEntry> getRoutes6();
+
+    /**
+     * Evaluates the location of an IP address and returns the location type.
+     *
+     * @param ipAddress the IP address to evaluate
+     * @return the IP address location type
+     */
+    public LocationType getLocationType(IpAddress ipAddress);
+
+    /**
+     * Finds out the route entry which has the longest matchable IP prefix.
+     *
+     * @param ipAddress IP address used to find out longest matchable IP prefix
+     * @return a route entry which has the longest matchable IP prefix if
+     * found, otherwise null
+     */
+    public RouteEntry getLongestMatchableRouteEntry(IpAddress ipAddress);
+
+    /**
+     * Finds out the egress connect point where to emit the first packet
+     * based on destination IP address.
+     *
+     * @param dstIpAddress the destination IP address
+     * @return the egress connect point if found, otherwise null
+     */
+    public ConnectPoint getEgressConnectPoint(IpAddress dstIpAddress);
+
+    /**
+     * Routes packet reactively.
+     *
+     * @param dstIpAddress the destination IP address of a packet
+     * @param srcIpAddress the source IP address of a packet
+     * @param srcConnectPoint the connect point where a packet comes from
+     * @param srcMacAddress the source MAC address of a packet
+     */
+    public void packetReactiveProcessor(IpAddress dstIpAddress,
+                                        IpAddress srcIpAddress,
+                                        ConnectPoint srcConnectPoint,
+                                        MacAddress srcMacAddress);
 }
diff --git a/apps/routing-api/src/main/java/org/onosproject/routing/config/LocalIpPrefixEntry.java b/apps/routing-api/src/main/java/org/onosproject/routing/config/LocalIpPrefixEntry.java
new file mode 100644
index 0000000..a2f3c8c
--- /dev/null
+++ b/apps/routing-api/src/main/java/org/onosproject/routing/config/LocalIpPrefixEntry.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.routing.config;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.common.base.MoreObjects;
+
+import java.util.Objects;
+
+import org.onlab.packet.IpPrefix;
+
+/**
+ * Configuration details for an IP prefix entry.
+ */
+public class LocalIpPrefixEntry {
+    private final IpPrefix ipPrefix;
+    private final IpPrefixType type;
+
+    /**
+     * Specifies the type of local IP prefix.
+     */
+    public enum IpPrefixType {
+        /**
+         * Public IP prefixes should be exchanged by eBGP.
+         */
+        PUBLIC,
+        /**
+         * Private IP prefixes should be used only locally and not exchanged
+         * by eBGP.
+         */
+        PRIVATE,
+        /**
+         * For IP prefixes in blacklist.
+         */
+        BLACK_LIST
+    }
+
+    /**
+     * Creates a new IP prefix entry.
+     *
+     * @param ipPrefix an IP prefix as a String
+     * @param type an IP prefix type as an IpPrefixType
+     */
+    public LocalIpPrefixEntry(@JsonProperty("ipPrefix") String ipPrefix,
+                              @JsonProperty("type") IpPrefixType type) {
+        this.ipPrefix = IpPrefix.valueOf(ipPrefix);
+        this.type = type;
+    }
+
+    /**
+     * Gets the IP prefix of the IP prefix entry.
+     *
+     * @return the IP prefix
+     */
+    public IpPrefix ipPrefix() {
+        return ipPrefix;
+    }
+
+    /**
+     * Gets the IP prefix type of the IP prefix entry.
+     *
+     * @return the IP prefix type
+     */
+    public IpPrefixType ipPrefixType() {
+        return type;
+    }
+
+    /**
+     * Tests whether the IP version of this entry is IPv4.
+     *
+     * @return true if the IP version of this entry is IPv4, otherwise false.
+     */
+    public boolean isIp4() {
+        return ipPrefix.isIp4();
+    }
+
+    /**
+     * Tests whether the IP version of this entry is IPv6.
+     *
+     * @return true if the IP version of this entry is IPv6, otherwise false.
+     */
+    public boolean isIp6() {
+        return ipPrefix.isIp6();
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(ipPrefix, type);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+
+        if (!(obj instanceof LocalIpPrefixEntry)) {
+            return false;
+        }
+
+        LocalIpPrefixEntry that = (LocalIpPrefixEntry) obj;
+        return Objects.equals(this.ipPrefix, that.ipPrefix)
+                && Objects.equals(this.type, that.type);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("ipPrefix", ipPrefix)
+                .add("ipPrefixType", type)
+                .toString();
+    }
+}
diff --git a/apps/routing-api/src/main/java/org/onosproject/routing/config/RoutingConfigurationService.java b/apps/routing-api/src/main/java/org/onosproject/routing/config/RoutingConfigurationService.java
index 113daa7..a306328 100644
--- a/apps/routing-api/src/main/java/org/onosproject/routing/config/RoutingConfigurationService.java
+++ b/apps/routing-api/src/main/java/org/onosproject/routing/config/RoutingConfigurationService.java
@@ -16,6 +16,7 @@
 package org.onosproject.routing.config;
 
 import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
 import org.onosproject.net.ConnectPoint;
 
 import java.util.Map;
@@ -41,6 +42,22 @@
     public Map<IpAddress, BgpPeer> getBgpPeers();
 
     /**
+     * Evaluates whether an IP address belongs to local SDN network.
+     *
+     * @param ipAddress the IP address to evaluate
+     * @return true if the IP address belongs to local SDN network, otherwise false
+     */
+    public boolean isIpAddressLocal(IpAddress ipAddress);
+
+    /**
+     * Evaluates whether an IP prefix belongs to local SDN network.
+     *
+     * @param ipPrefix the IP prefix to evaluate
+     * @return true if the IP prefix belongs to local SDN network, otherwise false
+     */
+    public boolean isIpPrefixLocal(IpPrefix ipPrefix);
+
+    /**
      * Retrieves the entire set of interfaces in the network.
      *
      * @return the set of interfaces