Reimplemented ARP broadcasting to use the network map to determine whether a port has a link, which prevents issues of devices popping up on link ports between controller domains
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/internal/TopoSwitchServiceImpl.java b/src/main/java/net/onrc/onos/ofcontroller/core/internal/TopoSwitchServiceImpl.java
index 1f39a38..3a324b1 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/core/internal/TopoSwitchServiceImpl.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/internal/TopoSwitchServiceImpl.java
@@ -53,7 +53,11 @@
@Override
public Iterable<IPortObject> getPortsOnSwitch(String dpid) {
- // TODO Auto-generated method stub
+ op.close(); //Commit to ensure we see latest data
+ ISwitchObject switchObject = op.searchSwitch(dpid);
+ if (switchObject != null) {
+ return switchObject.getPorts();
+ }
return null;
}
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 426a455..5a8ed08 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java
@@ -27,10 +27,13 @@
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.INetMapTopologyObjects.IPortObject;
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;
+import net.onrc.onos.ofcontroller.core.internal.TopoLinkServiceImpl;
+import net.onrc.onos.ofcontroller.core.internal.TopoSwitchServiceImpl;
import org.openflow.protocol.OFMessage;
import org.openflow.protocol.OFPacketIn;
@@ -63,7 +66,7 @@
private IRestApiService restApi;
private IDeviceStorage deviceStorage;
- private ITopoSwitchService topoSwitchService;
+ private volatile ITopoSwitchService topoSwitchService;
private ITopoLinkService topoLinkService;
private short vlan;
@@ -141,6 +144,9 @@
arpRequests = Multimaps.synchronizedSetMultimap(
HashMultimap.<InetAddress, ArpRequest>create());
+
+ topoSwitchService = new TopoSwitchServiceImpl();
+ topoLinkService = new TopoLinkServiceImpl();
}
public void startUp() {
@@ -477,7 +483,7 @@
ARP arp = (ARP) eth.getPayload();
if (log.isTraceEnabled()) {
log.trace("Sending ARP request for {} to other ONOS instances",
- HexString.toHexString(arp.getTargetProtocolAddress()));
+ inetAddressToString(arp.getTargetProtocolAddress()));
}
datagrid.sendArpRequest(eth.serialize());
}
@@ -530,6 +536,44 @@
}
}
+ private void broadcastArpRequestOutMyEdge(byte[] arpRequest) {
+ for (IOFSwitch sw : floodlightProvider.getSwitches().values()) {
+
+ OFPacketOut po = new OFPacketOut();
+ po.setInPort(OFPort.OFPP_NONE)
+ .setBufferId(-1)
+ .setPacketData(arpRequest);
+
+ List<OFAction> actions = new ArrayList<OFAction>();
+
+ Iterable<IPortObject> ports
+ = topoSwitchService.getPortsOnSwitch(sw.getStringId());
+ if (ports == null) {
+ continue;
+ }
+
+ for (IPortObject portObject : ports) {
+ if (!portObject.getLinkedPorts().iterator().hasNext()) {
+ actions.add(new OFActionOutput(portObject.getNumber()));
+ }
+ }
+
+ po.setActions(actions);
+ short actionsLength = (short)
+ (actions.size() * OFActionOutput.MINIMUM_LENGTH);
+ po.setActionsLength(actionsLength);
+ po.setLengthU(OFPacketOut.MINIMUM_LENGTH + actionsLength
+ + arpRequest.length);
+
+ try {
+ sw.write(po, null);
+ sw.flush();
+ } catch (IOException e) {
+ log.error("Failure writing packet out to switch", e);
+ }
+ }
+ }
+
private void sendArpRequestOutPort(byte[] arpRequest, long dpid, short port) {
if (log.isTraceEnabled()) {
log.trace("Sending ARP request out {}/{}",
@@ -668,6 +712,7 @@
@Override
public void arpRequestNotification(byte[] arpRequest) {
log.debug("Received ARP notification from other instances");
- broadcastArpRequestOutEdge(arpRequest, Long.MAX_VALUE, Short.MAX_VALUE);
+ //broadcastArpRequestOutEdge(arpRequest, Long.MAX_VALUE, Short.MAX_VALUE);
+ broadcastArpRequestOutMyEdge(arpRequest);
}
}