Abstraction to help applications write logic to handle ARP + NDP packets.

The idea is to allow applications to contribute NeighbourMessageHandlers to
handle ARP/NDP packets coming from a particular ConnectPoint, Interface or with
a particular traffic selector. Applications can contribute different handlers
for different ports, because they know how those ports will be used. Also,
multiple applications can contribute handlers for different ports/interfaces
without having to have one ARP handler for the entire network. The framework
provides actions that the handler can choose to take - flood, proxy, reply, drop.
The handler is free to implement some other action if none of these fit what it
needs to do. The framework also handles many of the common tasks for ARP handlers,
like parsing packets, abstracting the differences between ARP and NDP, implementing
actions like replying to a request. This allows handlers to be very simple and
easy to understand and implement.

Change-Id: I313c723e9ebc3d0816eb79870ee0536780e7a640
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/neighbour/DefaultNeighbourMessageHandler.java b/incubator/api/src/main/java/org/onosproject/incubator/net/neighbour/DefaultNeighbourMessageHandler.java
new file mode 100644
index 0000000..3686c47
--- /dev/null
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/neighbour/DefaultNeighbourMessageHandler.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.incubator.net.neighbour;
+
+import org.onosproject.net.Host;
+import org.onosproject.net.host.HostService;
+
+import java.util.Set;
+
+import static org.onosproject.net.HostId.hostId;
+
+/**
+ * Default neighbour message handler which implements basic proxying on a flat
+ * L2 network (i.e. ProxyArp behaviour).
+ */
+public class DefaultNeighbourMessageHandler implements NeighbourMessageHandler {
+    @Override
+    public void handleMessage(NeighbourMessageContext context, HostService hostService) {
+        // See if we have the target host in the host store
+        Set<Host> hosts = hostService.getHostsByIp(context.target());
+
+        Host dst = null;
+        Host src = hostService.getHost(hostId(context.srcMac(), context.vlan()));
+
+        for (Host host : hosts) {
+            if (host.vlan().equals(context.vlan())) {
+                dst = host;
+                break;
+            }
+        }
+
+        if (src != null && dst != null) {
+            // We know the target host so we can respond
+            context.reply(dst.mac());
+            return;
+        }
+
+        // The request couldn't be resolved.
+        // Flood the request on all ports except the incoming port.
+        context.flood();
+    }
+}
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/neighbour/NeighbourMessageActions.java b/incubator/api/src/main/java/org/onosproject/incubator/net/neighbour/NeighbourMessageActions.java
new file mode 100644
index 0000000..3332e92
--- /dev/null
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/neighbour/NeighbourMessageActions.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.incubator.net.neighbour;
+
+import com.google.common.annotations.Beta;
+import org.onlab.packet.MacAddress;
+import org.onosproject.incubator.net.intf.Interface;
+import org.onosproject.net.ConnectPoint;
+
+/**
+ * Performs actions on a neighbour message contexts.
+ */
+@Beta
+public interface NeighbourMessageActions {
+
+    /**
+     * Replies to an incoming request with the given MAC address.
+     *
+     * @param context incoming message context
+     * @param targetMac target MAC address.
+     */
+    void reply(NeighbourMessageContext context, MacAddress targetMac);
+
+    /**
+     * Proxies the incoming message to the given connect point.
+     *
+     * @param context incoming message context
+     * @param outPort port to send the message out
+     */
+    void proxy(NeighbourMessageContext context, ConnectPoint outPort);
+
+    /**
+     * Proxies the incoming message to a given interface.
+     *
+     * @param context incoming message context
+     * @param outIntf interface to send the message out. The message will be
+     *                modified to fit the parameters of the outgoing interface.
+     */
+    void proxy(NeighbourMessageContext context, Interface outIntf);
+
+    /**
+     * Floods the incoming message to all edge ports except the in port.
+     *
+     * @param context incoming message context
+     */
+    void flood(NeighbourMessageContext context);
+
+    /**
+     * Drops the incoming message.
+     *
+     * @param context incoming message context
+     */
+    void drop(NeighbourMessageContext context);
+}
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/neighbour/NeighbourMessageContext.java b/incubator/api/src/main/java/org/onosproject/incubator/net/neighbour/NeighbourMessageContext.java
new file mode 100644
index 0000000..307a783
--- /dev/null
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/neighbour/NeighbourMessageContext.java
@@ -0,0 +1,189 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.incubator.net.neighbour;
+
+import com.google.common.annotations.Beta;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.incubator.net.intf.Interface;
+import org.onosproject.net.ConnectPoint;
+
+import static com.google.common.base.Preconditions.checkState;
+
+/**
+ * Context of an incoming neighbor message (e.g. ARP, NDP).
+ *
+ * <p>This includes information about the message accessible through a
+ * protocol-agnostic interface, as well as mechanisms to perform an action in
+ * response to the incoming message.</p>
+ */
+@Beta
+public class NeighbourMessageContext {
+
+    private final NeighbourProtocol protocol;
+    private final NeighbourMessageType type;
+
+    private final IpAddress target;
+    private final IpAddress sender;
+
+    private final Ethernet eth;
+    private final ConnectPoint inPort;
+
+    private final NeighbourMessageActions actions;
+
+    /**
+     * Creates a new neighbour message context.
+     *
+     * @param actions actions
+     * @param eth ethernet frame
+     * @param inPort incoming port
+     * @param protocol message protocol
+     * @param type message type
+     * @param target target IP address
+     * @param sender sender IP address
+     */
+    public NeighbourMessageContext(NeighbourMessageActions actions,
+                                   Ethernet eth, ConnectPoint inPort,
+                                   NeighbourProtocol protocol, NeighbourMessageType type,
+                                   IpAddress target, IpAddress sender) {
+        this.actions = actions;
+        this.eth = eth;
+        this.inPort = inPort;
+        this.protocol = protocol;
+        this.type = type;
+        this.target = target;
+        this.sender = sender;
+    }
+
+    /**
+     * Gets the port where the packet came in to the network.
+     *
+     * @return connect point
+     */
+    public ConnectPoint inPort() {
+        return inPort;
+    }
+
+    /**
+     * Gets the full parsed representation of the packet.
+     *
+     * @return ethernet header
+     */
+    public Ethernet packet() {
+        return eth;
+    }
+
+    /**
+     * Gets the protocol of the packet.
+     *
+     * @return protocol
+     */
+    public NeighbourProtocol protocol() {
+        return protocol;
+    }
+
+    /**
+     * Gets the message type of the packet.
+     *
+     * @return message type
+     */
+    public NeighbourMessageType type() {
+        return type;
+    }
+
+    /**
+     * Gets the vlan of the packet, if any.
+     *
+     * @return vlan
+     */
+    public VlanId vlan() {
+        return VlanId.vlanId(eth.getVlanID());
+    }
+
+    /**
+     * Gets the source MAC address of the message.
+     *
+     * @return source MAC address
+     */
+    public MacAddress srcMac() {
+        return MacAddress.valueOf(eth.getSourceMACAddress());
+    }
+
+    /**
+     * Gets the target IP address of the message.
+     *
+     * @return target IP address
+     */
+    public IpAddress target() {
+        return target;
+    }
+
+    /**
+     * Gets the source IP address of the message.
+     *
+     * @return source IP address
+     */
+    public IpAddress sender() {
+        return sender;
+    }
+
+    /**
+     * Proxies the message to a given output port.
+     *
+     * @param outPort output port
+     */
+    public void proxy(ConnectPoint outPort) {
+        actions.proxy(this, outPort);
+    }
+
+    /**
+     * Proxies the message to a given interface.
+     *
+     * @param outIntf output interface
+     */
+    public void proxy(Interface outIntf) {
+        actions.proxy(this, outIntf);
+    }
+
+    /**
+     * Replies to the request message with a given MAC address.
+     *
+     * @param targetMac target MAC address
+     */
+    public void reply(MacAddress targetMac) {
+        checkState(type == NeighbourMessageType.REQUEST, "can only reply to requests");
+
+        actions.reply(this, targetMac);
+    }
+
+    /**
+     * Floods the incoming message out all ports except the input port.
+     */
+    public void flood() {
+        actions.flood(this);
+    }
+
+    /**
+     * Drops the incoming message.
+     */
+    public void drop() {
+        actions.drop(this);
+    }
+
+}
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/neighbour/NeighbourMessageHandler.java b/incubator/api/src/main/java/org/onosproject/incubator/net/neighbour/NeighbourMessageHandler.java
new file mode 100644
index 0000000..e638642
--- /dev/null
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/neighbour/NeighbourMessageHandler.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.incubator.net.neighbour;
+
+import com.google.common.annotations.Beta;
+import org.onosproject.net.host.HostService;
+
+/**
+ * Handler for an incoming neighbour message.
+ *
+ * <p>An application may implement this interface in order to provide their own
+ * logic for handling particular neighbour messages.</p>
+ */
+@Beta
+public interface NeighbourMessageHandler {
+
+    /**
+     * Handles a neighbour message.
+     *
+     * @param context neighbour message context
+     * @param hostService host service
+     */
+    void handleMessage(NeighbourMessageContext context, HostService hostService);
+}
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/neighbour/NeighbourMessageType.java b/incubator/api/src/main/java/org/onosproject/incubator/net/neighbour/NeighbourMessageType.java
new file mode 100644
index 0000000..85778bd
--- /dev/null
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/neighbour/NeighbourMessageType.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.incubator.net.neighbour;
+
+import com.google.common.annotations.Beta;
+
+/**
+ * Neighbour message type.
+ */
+@Beta
+public enum NeighbourMessageType {
+    /**
+     * Request message.
+     */
+    REQUEST,
+
+    /**
+     * Reply message.
+     */
+    REPLY
+}
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/neighbour/NeighbourProtocol.java b/incubator/api/src/main/java/org/onosproject/incubator/net/neighbour/NeighbourProtocol.java
new file mode 100644
index 0000000..d6ceadb
--- /dev/null
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/neighbour/NeighbourProtocol.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.incubator.net.neighbour;
+
+import com.google.common.annotations.Beta;
+
+/**
+ * Enumerates protocols used for neighbour discover/address resolution.
+ */
+@Beta
+public enum NeighbourProtocol {
+
+    /**
+     * Address Resolution Protocol (IPv4).
+     */
+    ARP,
+
+    /**
+     * Neighbor Discovery Protocol (IPv6).
+     */
+    NDP
+}
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/neighbour/NeighbourResolutionService.java b/incubator/api/src/main/java/org/onosproject/incubator/net/neighbour/NeighbourResolutionService.java
new file mode 100644
index 0000000..f7adb04
--- /dev/null
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/neighbour/NeighbourResolutionService.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.incubator.net.neighbour;
+
+import com.google.common.annotations.Beta;
+import org.onosproject.incubator.net.intf.Interface;
+import org.onosproject.net.ConnectPoint;
+
+/**
+ * Provides a means of registering logic for handling neighbour messages.
+ */
+@Beta
+public interface NeighbourResolutionService {
+
+    /**
+     * Registers a neighbour message handler for all neighbour messages
+     * incoming on the given connect point.
+     *
+     * @param connectPoint connect point
+     * @param handler neighbour message handler
+     */
+    void registerNeighbourHandler(ConnectPoint connectPoint, NeighbourMessageHandler handler);
+
+    /**
+     * Registers a neighbour message handler for all neighbour messages incoming
+     * on the given interface. Neighbour packets must match the fields of the
+     * interface in order to be handled by this message handler.
+     *
+     * @param intf interface
+     * @param handler neighbour message handler
+     */
+    void registerNeighbourHandler(Interface intf, NeighbourMessageHandler handler);
+
+}
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/neighbour/package-info.java b/incubator/api/src/main/java/org/onosproject/incubator/net/neighbour/package-info.java
new file mode 100644
index 0000000..7982eee
--- /dev/null
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/neighbour/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Neighbour message (ARP, NDP) handling.
+ */
+package org.onosproject.incubator.net.neighbour;