diff --git a/client-level/fl-ho-cl/.classpath b/client-level/fl-ho-cl/.classpath
index a1f69b2..bd7ea8f 100644
--- a/client-level/fl-ho-cl/.classpath
+++ b/client-level/fl-ho-cl/.classpath
@@ -24,6 +24,7 @@
+
@@ -31,6 +32,5 @@
-
diff --git a/client-level/fl-ho-cl/src/main/java/net/floodlightcontroller/ARPRewrite b/client-level/fl-ho-cl/src/main/java/net/floodlightcontroller/ARPRewrite
deleted file mode 160000
index 06e5cfd..0000000
--- a/client-level/fl-ho-cl/src/main/java/net/floodlightcontroller/ARPRewrite
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 06e5cfd49f1ec2fdfcbad9b7ef032d9c1027e568
diff --git a/client-level/fl-ho-cl/src/main/java/net/floodlightcontroller/ARPRewrite/ARPRewrite.java b/client-level/fl-ho-cl/src/main/java/net/floodlightcontroller/ARPRewrite/ARPRewrite.java
new file mode 100644
index 0000000..7f12fdf
--- /dev/null
+++ b/client-level/fl-ho-cl/src/main/java/net/floodlightcontroller/ARPRewrite/ARPRewrite.java
@@ -0,0 +1,312 @@
+package net.floodlightcontroller.ARPRewrite;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Map;
+
+import net.floodlightcontroller.core.FloodlightContext;
+import net.floodlightcontroller.core.IFloodlightProviderService;
+import net.floodlightcontroller.core.IOFSwitch;
+import net.floodlightcontroller.core.module.FloodlightModuleContext;
+import net.floodlightcontroller.core.module.FloodlightModuleException;
+import net.floodlightcontroller.core.module.IFloodlightModule;
+import net.floodlightcontroller.core.module.IFloodlightService;
+import net.floodlightcontroller.forwarding.Forwarding;
+import net.floodlightcontroller.packet.ARP;
+import net.floodlightcontroller.packet.Ethernet;
+import net.floodlightcontroller.packet.IPacket;
+import net.floodlightcontroller.packet.IPv4;
+import net.floodlightcontroller.routing.IRoutingDecision;
+import net.floodlightcontroller.staticflowentry.IStaticFlowEntryPusherService;
+import net.floodlightcontroller.storage.IStorageSourceService;
+import net.floodlightcontroller.util.MACAddress;
+
+import org.openflow.protocol.OFFlowMod;
+import org.openflow.protocol.OFPacketIn;
+import org.openflow.protocol.OFPacketOut;
+import org.openflow.protocol.OFType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ARPRewrite extends Forwarding implements
+IFloodlightModule {
+ protected static Logger log = LoggerFactory.getLogger(ARPRewrite.class);
+ // proxyArp MAC address - can replace with other values in future
+ public static String TAP_MAC_ADDRESS = "12:51:16:90:8f:ee"; // Tap
+ public static String IFACE1_MAC_ADDRESS = "00:1d:e1:3b:48:1d"; // WiMAX
+ public static String IFACE2_MAC_ADDRESS = "00:23:15:81:8b:f8"; // WiFi
+ public static String IFACE3_MAC_ADDRESS = "00:23:15:81:8b:f8"; // WiFi #2 (Not Used, GEC18)
+ public static String IFACE4_MAC_ADDRESS = "00:1d:e1:3b:48:1d"; // WiMAX #2 (Not Used, GEC18)
+ public static String BROADCAST_MAC = "ff:ff:ff:ff:ff:ff";
+
+ public static String IFACE1_DPID;
+ public static String IFACE2_DPID;
+ public static String IFACE3_DPID;
+ public static String IFACE4_DPID;
+ public static String TAP_DPID;
+
+ protected MACAddress TAP_MAC;
+ protected MACAddress IFACE1_MAC;
+ protected MACAddress IFACE2_MAC;
+ protected MACAddress IFACE3_MAC;
+ protected MACAddress IFACE4_MAC;
+ protected MACAddress BCAST_MAC;
+
+ protected IStaticFlowEntryPusherService sfep;
+ protected IFloodlightProviderService floodlightProvider;
+
+ @Override
+ public Collection> getModuleDependencies() {
+ Collection> l =
+ new ArrayList>();
+ l.add(IFloodlightProviderService.class);
+ l.add(IStorageSourceService.class);
+ l.add(IStaticFlowEntryPusherService.class);
+ return l;
+ }
+
+ @Override
+ public void init(FloodlightModuleContext context)
+ throws FloodlightModuleException {
+
+ sfep = context.getServiceImpl(IStaticFlowEntryPusherService.class);
+ floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
+
+ /* read our config options */
+ Map configOptions = context.getConfigParams(this);
+
+ TAP_MAC_ADDRESS = configOptions.get("tap-mac-address");
+ IFACE1_MAC_ADDRESS = configOptions.get("wimax-mac-address");
+ IFACE2_MAC_ADDRESS = configOptions.get("wifi-mac-address");
+ IFACE3_MAC_ADDRESS = configOptions.get("iface3-mac-address");
+ IFACE4_MAC_ADDRESS = configOptions.get("iface4-mac-address");
+
+ TAP_DPID = configOptions.get("tap-dpid");
+ IFACE1_DPID = configOptions.get("wimax-dpid");
+ IFACE2_DPID = configOptions.get("wifi-dpid");
+ IFACE3_DPID = configOptions.get("iface3-dpid");
+ IFACE4_DPID = configOptions.get("iface4-dpid");
+
+ TAP_MAC = MACAddress.valueOf(TAP_MAC_ADDRESS);
+ IFACE1_MAC = MACAddress.valueOf(IFACE1_MAC_ADDRESS);
+ IFACE2_MAC = MACAddress.valueOf(IFACE2_MAC_ADDRESS);
+ IFACE3_MAC = MACAddress.valueOf(IFACE3_MAC_ADDRESS);
+ IFACE4_MAC = MACAddress.valueOf(IFACE4_MAC_ADDRESS);
+ BCAST_MAC = MACAddress.valueOf(BROADCAST_MAC);
+
+ super.init(context);
+ }
+
+
+ @Override
+ public void startUp(FloodlightModuleContext context) {
+ floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this);
+ }
+
+ @Override
+ public Command processPacketInMessage(IOFSwitch sw, OFPacketIn pi,
+ IRoutingDecision decision, FloodlightContext cntx) {
+ Ethernet eth = IFloodlightProviderService.bcStore.get(cntx,
+ IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
+ if (eth.getEtherType() == Ethernet.TYPE_ARP) {
+
+ // retrieve arp to determine addresses
+ ARP arpPayload = (ARP) eth.getPayload();
+
+ // (1) Get flows from switch
+ // (2) Find flow with matching ingress port
+ // (3) Use matching flow and extract output port
+ // (4) Use switch DPID and use correct (hard-coded) MAC of physical interface on that switch
+ // This is only for ARP. DHCP is ethertype 0x800, which will work with existing flows.
+
+ // (1) Get flows
+ Map flows;
+ //long switchIDAsLong = sw.getId();
+ //String switchIDAsString = Long.toString(switchIDAsLong);
+ //flows = sfep.getFlows("00:00:00:00:00:00:00:0".concat(switchIDAsString)); // This might not convert correctly
+ flows = sfep.getFlows(sw.getStringId()); // This might not convert correctly
+ Collection flowsAsCollection;
+ if (flows != null) {
+ flowsAsCollection = flows.values();
+ } else {
+ log.debug("No flows on switch " + sw.getStringId());
+ return Command.CONTINUE;
+ }
+ short inPort = pi.getInPort();
+ short outPort = 0;
+ log.debug("Packet from switch " + sw.getStringId() + " on port " + inPort);
+
+
+ // (2) and (3) Get output port from matching ingress port
+ if (!flows.isEmpty()) {
+ for (OFFlowMod myFlow : flowsAsCollection) {
+ if (myFlow.getMatch().getInputPort() == inPort) {
+ outPort = myFlow.getOutPort();
+ log.debug("Got (inPort, outPort) pair (" + inPort + ", " + outPort + ")");
+ break;
+ }
+ }
+ } else {
+ log.info("No flows returned for DPID " + sw.getStringId());
+ return Command.CONTINUE;
+ }
+
+ if (outPort == 0) {
+ log.debug("No matching flow found");
+ return Command.CONTINUE;
+ }
+
+ // (4) Determine MAC address to rewrite
+ // ingress on tap
+
+ MACAddress targetMAC;
+ MACAddress sourceMAC;
+ MACAddress destinationMAC;
+ boolean isIngress = false;
+ boolean isRequest = false;
+ short arpOpCode = arpPayload.getOpCode();
+ if (arpOpCode == ARP.OP_REQUEST) {
+ log.info("ARP packet is a request");
+ destinationMAC = BCAST_MAC;
+ isRequest = true;
+ } else if (arpOpCode == ARP.OP_REPLY) {
+ log.info("ARP packet is a reply");
+ } else {
+ log.info("ARP packet was neither request nor reply");
+ return Command.CONTINUE;
+ }
+ if (sw.getStringId() == TAP_DPID) {
+ if (outPort == 1 || outPort == 65534 || outPort == -1) {
+ targetMAC = TAP_MAC;
+ sourceMAC = null;
+ isIngress = true;
+ } else {
+ targetMAC = null;
+ sourceMAC = TAP_MAC;
+ }
+ } else if (sw.getStringId() == IFACE1_DPID) {
+ if (outPort == 1 || outPort == 65534 || outPort == -1) {
+ targetMAC = null;
+ sourceMAC = IFACE1_MAC;
+ } else {
+ targetMAC = TAP_MAC;
+ sourceMAC = null;
+ isIngress = true;
+ }
+ } else if (sw.getStringId() == IFACE2_DPID) {
+ if (outPort == 1 || outPort == 65534 || outPort == -1) {
+ targetMAC = null;
+ sourceMAC = IFACE2_MAC;
+ } else {
+ targetMAC = TAP_MAC;
+ sourceMAC = null;
+ isIngress = true;
+ }
+ } else if (sw.getStringId() == IFACE3_DPID) {
+ if (outPort == 1 || outPort == 65534 || outPort == -1) {
+ targetMAC = null;
+ sourceMAC = IFACE3_MAC;
+ } else {
+ targetMAC = TAP_MAC;
+ sourceMAC = null;
+ isIngress = true;
+ }
+ } else if (sw.getStringId() == IFACE4_DPID) {
+ if (outPort == 1 || outPort == 65534 || outPort == -1) {
+ targetMAC = null;
+ sourceMAC = IFACE4_MAC;
+ } else {
+ targetMAC = TAP_MAC;
+ sourceMAC = null;
+ isIngress = true;
+ }
+ } else {
+ sourceMAC = null;
+ targetMAC = null;
+ log.debug("Did find a matching DPID");
+ }
+
+ // 4 Cases: Only rewrite on non-TAP switch. The tap switch will have 4 flows for 0x800 and 0x806.
+ // All rewrites source and destination will occur on the OVS switch at the physical interface.
+ // (1) Ingress Packet, ARP Request -- rewrite nothing (need to find MAC aka request)
+ // (2) Ingress Packet, ARP Reply -- rewrite destination MAC to tap
+ // (3) Outbound Packet, ARP Request -- rewrite source MAC to physical (need to be able to respond and send on IFACE)
+ // (4) Outbound Packet, ARP Reply -- rewrite source MAC to physical (need to be able to send on IFACE)
+ if (isRequest && sw.getStringId() == TAP_DPID && isIngress) {
+ log.debug("Sending request out with SRC " + sourceMAC.toString() + " DST " + MACAddress.valueOf(arpPayload.getTargetHardwareAddress())
+ + " from port " + inPort + " to port " + outPort);
+ destinationMAC = BCAST_MAC;
+ sendARP(sw, pi, cntx, inPort, (short)65534, arpOpCode,
+ arpPayload.getSenderHardwareAddress(), arpPayload.getTargetHardwareAddress(), destinationMAC.toBytes());
+ } else if (!isRequest && sw.getStringId() == TAP_DPID && isIngress) {
+ log.debug("Sending reply out with SRC " + sourceMAC.toString() + " DST " + MACAddress.valueOf(arpPayload.getTargetHardwareAddress())
+ + " from port " + inPort + " to port " + outPort);
+ destinationMAC = targetMAC;
+ sendARP(sw, pi, cntx, inPort, (short)65534, arpOpCode,
+ arpPayload.getSenderHardwareAddress(), targetMAC.toBytes(), destinationMAC.toBytes());
+ } else if (isRequest && sw.getStringId() != TAP_DPID && !isIngress) {
+ log.debug("Sending request out with SRC " + sourceMAC.toString() + " DST " + MACAddress.valueOf(arpPayload.getTargetHardwareAddress())
+ + " from port " + inPort + " to port " + outPort);
+ destinationMAC = BCAST_MAC;
+ // removed (-) from outPort for testing
+ sendARP(sw, pi, cntx, inPort, (short)-outPort, arpOpCode,
+ sourceMAC.toBytes(), arpPayload.getTargetHardwareAddress(), destinationMAC.toBytes());
+ } else if (!isRequest && sw.getStringId() != TAP_DPID && !isIngress) {
+ log.debug("Sending reply out with SRC " + sourceMAC.toString() + " DST " + MACAddress.valueOf(arpPayload.getTargetHardwareAddress())
+ + " from port " + inPort + " to port " + outPort);
+ destinationMAC = targetMAC;
+ sendARP(sw, pi, cntx, inPort, (short)-outPort, arpOpCode,
+ sourceMAC.toBytes(), arpPayload.getTargetHardwareAddress(), destinationMAC.toBytes());
+ } else {
+ log.debug("Determining how to rewrite ARP packet failed!");
+ }
+ } else {
+ // Do nothing
+ }
+
+ return Command.CONTINUE;
+ }
+
+ protected void sendARP(IOFSwitch sw, OFPacketIn pi, FloodlightContext cntx, short inPort, short outPort,
+ short arpOpCode , byte[] sourceMACAddress, byte[] targetMACAddress, byte[] destinationMACAddress) {
+
+ Ethernet eth = IFloodlightProviderService.bcStore.get(cntx, IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
+ // retrieve original ARP
+ ARP arpPayload = (ARP) eth.getPayload();
+ log.debug("ARP to " + IPv4.fromIPv4Address(IPv4.toIPv4Address(arpPayload.getTargetProtocolAddress())));
+
+ // Modify original ARP packet
+ IPacket newARPPacket = new Ethernet()
+ .setSourceMACAddress(sourceMACAddress)
+ .setDestinationMACAddress(destinationMACAddress)
+ .setEtherType(Ethernet.TYPE_ARP)
+ .setVlanID(eth.getVlanID())
+ .setPriorityCode(eth.getPriorityCode())
+ .setPayload(
+ new ARP()
+ .setHardwareType(ARP.HW_TYPE_ETHERNET)
+ .setProtocolType(ARP.PROTO_TYPE_IP)
+ .setHardwareAddressLength((byte) 6)
+ .setProtocolAddressLength((byte) 4)
+ .setOpCode(arpOpCode)
+ .setSenderHardwareAddress(sourceMACAddress)
+ .setSenderProtocolAddress(
+ arpPayload.getSenderProtocolAddress())
+ .setTargetHardwareAddress(
+ targetMACAddress)
+ .setTargetProtocolAddress(
+ arpPayload.getTargetProtocolAddress()));
+
+ // push ARP out
+ pushPacket(newARPPacket, sw, OFPacketOut.BUFFER_ID_NONE, inPort, outPort, cntx, true);
+ log.debug("ARP packet pushed out PORT " + outPort + " on SWITCH " + sw.getStringId() + " with SRC " + MACAddress.valueOf(sourceMACAddress)
+ + " and TGT " + MACAddress.valueOf(targetMACAddress) + " and DST " + MACAddress.valueOf(destinationMACAddress));
+ return;
+ }
+
+ @Override
+ public Collection> getModuleServices() {
+ return null;
+ }
+
+}
diff --git a/client-level/fl-ho-cl/src/main/java/net/floodlightcontroller/handover/Handover.java b/client-level/fl-ho-cl/src/main/java/net/floodlightcontroller/handover/Handover.java
index d523d4d..8824dbf 100644
--- a/client-level/fl-ho-cl/src/main/java/net/floodlightcontroller/handover/Handover.java
+++ b/client-level/fl-ho-cl/src/main/java/net/floodlightcontroller/handover/Handover.java
@@ -130,7 +130,7 @@ public class Handover implements IFloodlightModule {
private static ArrayList ACTIVE_FLOWS;
private static final String OFFLINE = "offline";
private static String ACTIVE_NETWORK_TYPE = OFFLINE;
-
+
@Override
public Collection> getModuleServices() {
return null;
@@ -258,6 +258,7 @@ public void handleDevice(DeviceObject device) {
log.debug("GPSD: Updated DEVICE");
}
});
+
GPSD_CONN.start();
log.debug("Version: " + GPSD_CONN.version().toString());
@@ -590,7 +591,7 @@ private String askGRC() {
obj.put("operator", netType.equals("Wifi")? "" :"Clemson");
netTypeObjs.add(obj);
}
-
+
//create a JSON array containing all of our JSON objects, and include it in our request
log.debug("Latitude: " + Double.toString(GPSD_LATITUDE) + ", Longitude: " + Double.toString(GPSD_LONGITUDE));
JSONArray jNetTypesArray = new JSONArray(netTypeObjs);
@@ -602,7 +603,7 @@ private String askGRC() {
httpPost.setEntity(new UrlEncodedFormEntity(nvps));
HttpResponse response = httpclient.execute(httpPost);
int status = response.getStatusLine().getStatusCode();
-
+
//retreive JSON response
String body;
if(status >= 200 && status < 300){
@@ -611,7 +612,7 @@ private String askGRC() {
} else {
body = "ERROR";
}
-
+
//parse JSON response
JSONObject responseObj = new JSONObject(body);
String responseNet = responseObj.getString("network");
@@ -637,4 +638,4 @@ public void run() {
return;
}
} // END GRCProbe Class
-} // END Handover Module
\ No newline at end of file
+} // END Handover Module
diff --git a/client-level/fl-ho-cl/src/main/resources/floodlightdefault.properties b/client-level/fl-ho-cl/src/main/resources/floodlightdefault.properties
index 7f30ab2..dbd2ecb 100644
--- a/client-level/fl-ho-cl/src/main/resources/floodlightdefault.properties
+++ b/client-level/fl-ho-cl/src/main/resources/floodlightdefault.properties
@@ -62,4 +62,4 @@ net.floodlightcontroller.handover.Handover.ovs-wifi0-iface-port = 0
net.floodlightcontroller.handover.Handover.ovs-wifi1-iface-port = 0
net.floodlightcontroller.handover.Handover.ovs-wimax0-iface-port = 0
net.floodlightcontroller.handover.Handover.ovs-wimax1-iface-port = 0
-net.floodlightcontroller.handover.Handover.ovs-ethernet-iface-port = 0
\ No newline at end of file
+net.floodlightcontroller.handover.Handover.ovs-ethernet-iface-port = 0