Began implementing IPC with Hazelcast in order to broadcast ARP via other ONOS nodes
diff --git a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/IArpEventHandler.java b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/IArpEventHandler.java
new file mode 100644
index 0000000..51d92bd
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/IArpEventHandler.java
@@ -0,0 +1,11 @@
+package net.onrc.onos.ofcontroller.proxyarp;
+
+public interface IArpEventHandler {
+
+ /**
+ * Notify the ARP event handler that an ARP request has been received.
+ * @param id The string ID of the ARP request
+ * @param arpRequest The ARP request packet
+ */
+ public void arpRequestNotification(byte[] arpRequest);
+}
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 a5dabc9..4d261a2 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java
@@ -17,16 +17,18 @@
import net.floodlightcontroller.core.IFloodlightProviderService;
import net.floodlightcontroller.core.IOFMessageListener;
import net.floodlightcontroller.core.IOFSwitch;
-import net.floodlightcontroller.devicemanager.IDeviceService;
import net.floodlightcontroller.packet.ARP;
import net.floodlightcontroller.packet.Ethernet;
import net.floodlightcontroller.packet.IPv4;
import net.floodlightcontroller.restserver.IRestApiService;
import net.floodlightcontroller.topology.ITopologyService;
import net.floodlightcontroller.util.MACAddress;
+import net.onrc.onos.datagrid.IDatagridService;
import net.onrc.onos.ofcontroller.bgproute.Interface;
import net.onrc.onos.ofcontroller.core.IDeviceStorage;
import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IDeviceObject;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyService.ITopoLinkService;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyService.ITopoSwitchService;
import net.onrc.onos.ofcontroller.core.config.IConfigInfoService;
import net.onrc.onos.ofcontroller.core.internal.DeviceStorageImpl;
@@ -46,7 +48,8 @@
import com.google.common.collect.SetMultimap;
import com.google.common.net.InetAddresses;
-public class ProxyArpManager implements IProxyArpService, IOFMessageListener {
+public class ProxyArpManager implements IProxyArpService, IOFMessageListener,
+ IArpEventHandler {
private final static Logger log = LoggerFactory.getLogger(ProxyArpManager.class);
private final long ARP_TIMER_PERIOD = 60000; //ms (== 1 min)
@@ -55,11 +58,13 @@
private IFloodlightProviderService floodlightProvider;
private ITopologyService topology;
- private IDeviceService deviceService;
+ private IDatagridService datagrid;
private IConfigInfoService configService;
private IRestApiService restApi;
private IDeviceStorage deviceStorage;
+ private ITopoSwitchService topoSwitchService;
+ private ITopoLinkService topoLinkService;
private short vlan;
private static final short NO_VLAN = 0;
@@ -124,11 +129,11 @@
*/
public void init(IFloodlightProviderService floodlightProvider,
- ITopologyService topology, IDeviceService deviceService,
+ ITopologyService topology, IDatagridService datagrid,
IConfigInfoService config, IRestApiService restApi){
this.floodlightProvider = floodlightProvider;
this.topology = topology;
- this.deviceService = deviceService;
+ this.datagrid = datagrid;
this.configService = config;
this.restApi = restApi;
@@ -145,6 +150,8 @@
restApi.addRestletRoutable(new ArpWebRoutable());
floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this);
+ datagrid.registerArpEventHandler(this);
+
deviceStorage = new DeviceStorageImpl();
deviceStorage.init("");
@@ -232,9 +239,10 @@
public Command receive(
IOFSwitch sw, OFMessage msg, FloodlightContext cntx) {
- if (msg.getType() != OFType.PACKET_IN){
- return Command.CONTINUE;
- }
+ //if (msg.getType() != OFType.PACKET_IN){
+ //return Command.CONTINUE;
+ //}
+ log.debug("received packet");
OFPacketIn pi = (OFPacketIn) msg;
@@ -243,13 +251,13 @@
if (eth.getEtherType() == Ethernet.TYPE_ARP){
ARP arp = (ARP) eth.getPayload();
-
+ log.debug("etharp {}", arp);
if (arp.getOpCode() == ARP.OP_REQUEST) {
//TODO check what the DeviceManager does about propagating
//or swallowing ARPs. We want to go after DeviceManager in the
//chain but we really need it to CONTINUE ARP packets so we can
//get them.
- handleArpRequest(sw, pi, arp);
+ handleArpRequest(sw, pi, arp, eth);
}
else if (arp.getOpCode() == ARP.OP_REPLY) {
//handleArpReply(sw, pi, arp);
@@ -261,7 +269,7 @@
return Command.CONTINUE;
}
- private void handleArpRequest(IOFSwitch sw, OFPacketIn pi, ARP arp) {
+ private void handleArpRequest(IOFSwitch sw, OFPacketIn pi, ARP arp, Ethernet eth) {
if (log.isTraceEnabled()) {
log.trace("ARP request received for {}",
inetAddressToString(arp.getTargetProtocolAddress()));
@@ -302,8 +310,10 @@
IDeviceObject targetDevice =
deviceStorage.getDeviceByIP(InetAddresses.coerceToInteger(target));
+ log.debug("targetDevice: {}", targetDevice);
+
if (targetDevice != null) {
- //We have the device in our database, so send a reply
+ // We have the device in our database, so send a reply
MACAddress macAddress = MACAddress.valueOf(targetDevice.getMACAddress());
if (log.isTraceEnabled()) {
@@ -315,6 +325,16 @@
sendArpReply(arp, sw.getId(), pi.getInPort(), macAddress);
}
+ else {
+ // We don't know the device so broadcast the request out
+ // the edge of the network
+
+ //Record where the request came from so we know where to send the reply
+ arpRequests.put(target, new ArpRequest(
+ new HostArpRequester(arp, sw.getId(), pi.getInPort()), false));
+
+ sendArpRequestToEdge(eth, pi);
+ }
/*if (macAddress == null){
//MAC address is not in our ARP cache.
@@ -459,6 +479,27 @@
}
}
+ private void sendArpRequestToEdge(Ethernet arpRequest, OFPacketIn pi) {
+ // Pull the topology from the network map and find edge ports
+ /*for (ISwitchObject swObject : topoSwitchService.getActiveSwitches()) {
+ //List<Link> linksOnSwitch = topoLinkService.getLinksOnSwitch(swObject.getDPID());
+
+ Set<IPortObject> edgePorts = new HashSet<IPortObject>();
+
+ for (IPortObject portObject : swObject.getPorts()) {
+ if (!portObject.getLinkedPorts().iterator().hasNext()) {
+ edgePorts.add(portObject);
+ }
+ }
+
+
+ }*/
+ //log.debug("Sending ARP request for {} to other ONOS instances",
+ //HexString.toHexString(arpRequest.getTargetProtocolAddress()));
+ //log.debug("Sent request bytes: {}", );
+ datagrid.sendArpRequest(arpRequest.serialize());
+ }
+
private void broadcastArpRequestOutEdge(byte[] arpRequest, long inSwitch, short inPort) {
for (IOFSwitch sw : floodlightProvider.getSwitches().values()){
Collection<Short> enabledPorts = sw.getEnabledPortNumbers();
@@ -637,4 +678,14 @@
public List<String> getMappings() {
return arpCache.getMappings();
}
+
+ /*
+ * IArpEventHandler methods
+ */
+
+ @Override
+ public void arpRequestNotification(byte[] arpRequest) {
+ log.debug("Received ARP notification from other instances");
+ broadcastArpRequestOutEdge(arpRequest, Long.MAX_VALUE, Short.MAX_VALUE);
+ }
}