Skip to content

Commit

Permalink
merged commits
Browse files Browse the repository at this point in the history
  • Loading branch information
ajhodges committed May 19, 2014
2 parents 217ce6d + 333585c commit 1a9f35f
Show file tree
Hide file tree
Showing 5 changed files with 320 additions and 8 deletions.
2 changes: 1 addition & 1 deletion client-level/fl-ho-cl/.classpath
Expand Up @@ -24,13 +24,13 @@
<classpathentry exported="true" kind="lib" path="lib/simple-4.1.21.jar"/>
<classpathentry exported="true" kind="lib" path="lib/slf4j-api-1.6.4.jar"/>
<classpathentry exported="true" kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="lib" path="lib/java-json.jar"/>
<classpathentry kind="lib" path="lib/httpcomponents-client-4.3.3/lib/commons-codec-1.6.jar"/>
<classpathentry kind="lib" path="lib/httpcomponents-client-4.3.3/lib/commons-logging-1.1.3.jar"/>
<classpathentry kind="lib" path="lib/httpcomponents-client-4.3.3/lib/fluent-hc-4.3.3.jar"/>
<classpathentry kind="lib" path="lib/httpcomponents-client-4.3.3/lib/httpclient-4.3.3.jar"/>
<classpathentry kind="lib" path="lib/httpcomponents-client-4.3.3/lib/httpclient-cache-4.3.3.jar"/>
<classpathentry kind="lib" path="lib/httpcomponents-client-4.3.3/lib/httpcore-4.3.2.jar"/>
<classpathentry kind="lib" path="lib/httpcomponents-client-4.3.3/lib/httpmime-4.3.3.jar"/>
<classpathentry kind="lib" path="lib/java-json.jar"/>
<classpathentry kind="output" path="target/bin"/>
</classpath>
Submodule ARPRewrite deleted from 06e5cf
@@ -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<Class<? extends IFloodlightService>> getModuleDependencies() {
Collection<Class<? extends IFloodlightService>> l =
new ArrayList<Class<? extends IFloodlightService>>();
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<String, String> 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<String, OFFlowMod> 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<OFFlowMod> 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<Class<? extends IFloodlightService>> getModuleServices() {
return null;
}

}
Expand Up @@ -130,7 +130,7 @@ public class Handover implements IFloodlightModule {
private static ArrayList<String> ACTIVE_FLOWS;
private static final String OFFLINE = "offline";
private static String ACTIVE_NETWORK_TYPE = OFFLINE;

@Override
public Collection<Class<? extends IFloodlightService>> getModuleServices() {
return null;
Expand Down Expand Up @@ -258,6 +258,7 @@ public void handleDevice(DeviceObject device) {
log.debug("GPSD: Updated DEVICE");
}
});

GPSD_CONN.start();

log.debug("Version: " + GPSD_CONN.version().toString());
Expand Down Expand Up @@ -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);
Expand All @@ -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){
Expand All @@ -611,7 +612,7 @@ private String askGRC() {
} else {
body = "ERROR";
}

//parse JSON response
JSONObject responseObj = new JSONObject(body);
String responseNet = responseObj.getString("network");
Expand All @@ -637,4 +638,4 @@ public void run() {
return;
}
} // END GRCProbe Class
} // END Handover Module
} // END Handover Module
Expand Up @@ -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
net.floodlightcontroller.handover.Handover.ovs-ethernet-iface-port = 0

0 comments on commit 1a9f35f

Please sign in to comment.