Added APIs to allow other modules to request ARP information from the Proxy ARP module
diff --git a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/IProxyArpService.java b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/IProxyArpService.java
index 1ff91e1..4632aba 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/IProxyArpService.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/IProxyArpService.java
@@ -24,7 +24,7 @@
* @param ipAddress
* @return
*/
- public byte[] lookupMac(InetAddress ipAddress);
+ public byte[] getMacAddress(InetAddress ipAddress);
/**
* Tell the IProxyArpService to send an ARP request for the IP address.
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 538bb41..5c2a2b9 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java
@@ -114,6 +114,17 @@
}, 0, ARP_REQUEST_TIMEOUT_THREAD_PERIOD);
}
+ private void storeRequester(InetAddress address, IArpRequester requester) {
+ synchronized (arpRequests) {
+ if (arpRequests.get(address) == null) {
+ arpRequests.put(address, new ArpRequest());
+ }
+ ArpRequest request = arpRequests.get(address);
+
+ request.addRequester(requester);
+ }
+ }
+
@Override
public String getName() {
return "ProxyArpManager";
@@ -179,23 +190,11 @@
return;
}
- synchronized (arpRequests) {
- //arpRequests.putIfAbsent(target,
- //Collections.synchronizedSet(new HashSet<ArpRequest>()));
- // new ArpRequest());
- //Set<ArpRequest> requesters = arpRequests.get(target);
- if (arpRequests.get(target) == null) {
- arpRequests.put(target, new ArpRequest());
- }
- ArpRequest request = arpRequests.get(target);
-
- request.addRequester(new HostArpRequester(this, arp,
- sw.getId(), pi.getInPort()));
- }
-
+ storeRequester(target, new HostArpRequester(this, arp, sw.getId(),
+ pi.getInPort()));
//Flood the request out edge ports
- broadcastArpRequestOutEdge(pi, sw.getId(), pi.getInPort());
+ broadcastArpRequestOutEdge(pi.getPacketData(), sw.getId(), pi.getInPort());
}
else {
//We know the address, so send a reply
@@ -292,7 +291,35 @@
}
}
- private void broadcastArpRequestOutEdge(OFPacketIn pi, long inSwitch, short inPort){
+ private void sendArpRequestForAddress(InetAddress ipAddress) {
+ byte[] zeroIpv4 = {0x0, 0x0, 0x0, 0x0};
+ byte[] zeroMac = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
+ byte[] broadcastMac = {(byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
+ (byte)0xff, (byte)0xff, (byte)0xff};
+
+ ARP arpRequest = new ARP();
+
+ arpRequest.setHardwareType(ARP.HW_TYPE_ETHERNET)
+ .setProtocolType(ARP.PROTO_TYPE_IP)
+ .setHardwareAddressLength((byte)Ethernet.DATALAYER_ADDRESS_LENGTH)
+ .setProtocolAddressLength((byte)4) //can't find the constant anywhere
+ .setOpCode(ARP.OP_REQUEST)
+ .setSenderHardwareAddress(zeroMac)
+ .setSenderProtocolAddress(zeroIpv4)
+ .setTargetHardwareAddress(zeroMac)
+ .setTargetProtocolAddress(ipAddress.getAddress());
+
+ Ethernet eth = new Ethernet();
+ eth.setDestinationMACAddress(arpRequest.getSenderHardwareAddress())
+ .setSourceMACAddress(broadcastMac)
+ .setEtherType(Ethernet.TYPE_ARP)
+ .setPayload(arpRequest);
+
+ broadcastArpRequestOutEdge(eth.serialize(), 0, OFPort.OFPP_NONE.getValue());
+ }
+
+ //private void broadcastArpRequestOutEdge(OFPacketIn pi, long inSwitch, short inPort){
+ private void broadcastArpRequestOutEdge(byte[] arpRequest, long inSwitch, short inPort) {
for (IOFSwitch sw : floodlightProvider.getSwitches().values()){
Collection<Short> enabledPorts = sw.getEnabledPortNumbers();
Set<Short> linkPorts = topology.getPortsWithLinks(sw.getId());
@@ -306,7 +333,7 @@
OFPacketOut po = new OFPacketOut();
po.setInPort(OFPort.OFPP_NONE)
.setBufferId(-1)
- .setPacketData(pi.getPacketData());
+ .setPacketData(arpRequest);
List<OFAction> actions = new ArrayList<OFAction>();
@@ -326,7 +353,7 @@
short actionsLength = (short) (actions.size() * OFActionOutput.MINIMUM_LENGTH);
po.setActionsLength(actionsLength);
po.setLengthU(OFPacketOut.MINIMUM_LENGTH + actionsLength
- + pi.getPacketData().length);
+ + arpRequest.length);
List<OFMessage> msgList = new ArrayList<OFMessage>();
msgList.add(po);
@@ -394,7 +421,7 @@
//TODO this should be put somewhere more central. I use it in BgpRoute as well.
//We need a HexString.toHexString() equivalent.
- private String bytesToStringAddr(byte[] bytes){
+ private String bytesToStringAddr(byte[] bytes) {
InetAddress addr;
try {
addr = InetAddress.getByAddress(bytes);
@@ -407,12 +434,20 @@
}
- public byte[] lookupMac(InetAddress ipAddress){
- //TODO implement
- return null;
+ public byte[] getMacAddress(InetAddress ipAddress) {
+ return lookupArpTable(ipAddress.getAddress());
}
- public byte[] sendArpRequest(InetAddress ipAddress, IArpRequester requester){
- //TODO implement
+
+ public byte[] sendArpRequest(InetAddress ipAddress, IArpRequester requester) {
+ byte[] lookupMac;
+ if ((lookupMac = lookupArpTable(ipAddress.getAddress())) == null) {
+ return lookupMac;
+ }
+
+ sendArpRequestForAddress(ipAddress);
+
+ storeRequester(ipAddress, requester);
+
return null;
}
}