Implemented ARP reply notifications when a new device is written to the database. Created an ArpMessage class which is the object put into hazelcast for both requests and replies
diff --git a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java
index 5a8ed08..85fd618 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java
@@ -17,6 +17,7 @@
import net.floodlightcontroller.core.IFloodlightProviderService;
import net.floodlightcontroller.core.IOFMessageListener;
import net.floodlightcontroller.core.IOFSwitch;
+import net.floodlightcontroller.devicemanager.IDevice;
import net.floodlightcontroller.packet.ARP;
import net.floodlightcontroller.packet.Ethernet;
import net.floodlightcontroller.packet.IPv4;
@@ -481,11 +482,21 @@
private void sendToOtherNodes(Ethernet eth, OFPacketIn pi) {
ARP arp = (ARP) eth.getPayload();
+
if (log.isTraceEnabled()) {
log.trace("Sending ARP request for {} to other ONOS instances",
inetAddressToString(arp.getTargetProtocolAddress()));
}
- datagrid.sendArpRequest(eth.serialize());
+
+ InetAddress targetAddress;
+ try {
+ targetAddress = InetAddress.getByAddress(arp.getTargetProtocolAddress());
+ } catch (UnknownHostException e) {
+ log.error("Unknown host", e);
+ return;
+ }
+
+ datagrid.sendArpRequest(ArpMessage.newRequest(targetAddress, eth.serialize()));
}
private void broadcastArpRequestOutEdge(byte[] arpRequest, long inSwitch, short inPort) {
@@ -710,9 +721,48 @@
*/
@Override
- public void arpRequestNotification(byte[] arpRequest) {
+ public void arpRequestNotification(ArpMessage arpMessage) {
log.debug("Received ARP notification from other instances");
- //broadcastArpRequestOutEdge(arpRequest, Long.MAX_VALUE, Short.MAX_VALUE);
- broadcastArpRequestOutMyEdge(arpRequest);
+
+ switch (arpMessage.getType()){
+ case REQUEST:
+ broadcastArpRequestOutMyEdge(arpMessage.getPacket());
+ break;
+ case REPLY:
+ sendArpReplyToWaitingRequesters(arpMessage.getAddress());
+ break;
+ }
+ }
+
+ private void sendArpReplyToWaitingRequesters(InetAddress address) {
+ log.debug("Sending ARP reply for {} to requesters",
+ address.getHostAddress());
+
+ //See if anyone's waiting for this ARP reply
+ Set<ArpRequest> requests = arpRequests.get(address);
+
+ //Synchronize on the Multimap while using an iterator for one of the sets
+ List<ArpRequest> requestsToSend = new ArrayList<ArpRequest>(requests.size());
+ synchronized (arpRequests) {
+ Iterator<ArpRequest> it = requests.iterator();
+ while (it.hasNext()) {
+ ArpRequest request = it.next();
+ it.remove();
+ requestsToSend.add(request);
+ }
+ }
+
+ IDeviceObject deviceObject = deviceStorage.getDeviceByIP(
+ InetAddresses.coerceToInteger(address));
+
+ MACAddress mac = MACAddress.valueOf(deviceObject.getMACAddress());
+
+ log.debug("Found {} at {} in network map",
+ address.getHostAddress(), mac);
+
+ //Don't hold an ARP lock while dispatching requests
+ for (ArpRequest request : requestsToSend) {
+ request.dispatchReply(address, mac);
+ }
}
}