Figure 1: Hybrid Programmable Forwarding Planes |
The Integrated hybrid model is much more interesting since it can be used to combine the best attributes of OpenFlow and existing distributed routing protocols to deliver robust solutions. The OpenFlow 1.3.1 specification includes supports for the integrated hybrid model by defining the NORMAL action:
Optional: NORMAL: Represents the traditional non-OpenFlow pipeline of the switch (see 5.1). Can be used only as an output port and processes the packet using the normal pipeline. If the switch cannot forward packets from the OpenFlow pipeline to the normal pipeline, it must indicate that it does not support this action.Hybrid solutions leverage the full capabilities of vendor and merchant silicon which efficiently support distributed forwarding protocols. In addition, most switch and merchant silicon vendors embed support for the sFlow standard, allowing the fabric controller to rapidly detect large flows and apply OpenFlow forwarding rules to control these flows.
Existing switching silicon is often criticized for the limited size of the hardware forwarding tables, supporting too few general match OpenFlow forwarding rules to be useful in production settings. However, consider that SDN and large flows defines a large flow as a flow that consumes 10% of a link's bandwidth. Using this definition, a 48 port switch would require a maximum of 480 general match rules in order to steer all large flows, well within the capabilities of current hardware (see OpenFlow Switching Performance: Not All TCAM Is Created Equal).
This article will use the Mininet testbed described in Controlling large flows with OpenFlow to experiment with using integrated hybrid forwarding to selectively control large flows, leaving the remaining flows to the switch's NORMAL forwarding pipeline.
Figure 2: MiniNet as an SDN test platform |
$ sudo mn --topo single,3 --controller=remote,ip=127.0.0.1The next command enables sFlow on the switch:
sudo ovs-vsctl -- --id=@sflow create sflow agent=eth0 target=\"127.0.0.1:6343\" sampling=10 polling=20 -- -- set bridge s1 sflow=@sflowFloodlight's Static Flow Pusher API will be used to insert OpenFlow rules in the switch. The default Floodlight configuration implements packet forwarding, disabling the forwarding module requires configuration changes:
- Copy the default properties file target/bin/floodlightdefault.properties to static.properties
- Edit the file to remove the line net.floodlightcontroller.forwarding.Forwarding,\
- Copy the floodlight.sh script to floodlight_static.sh
- Modify the last line of the script to invoke the properties, java ${JVM_OPTS} -Dlogback.configurationFile=${FL_LOGBACK} -jar ${FL_JAR} -cf static.properties
Update 22 December, 2013 Thanks to Jason Parraga, the following modules are the minimum set needed to support the Static Flow Pusher functionality in the Floodlight properties file:Start Floodlight with the forwarding module disabled:
floodlight.modules=\
net.floodlightcontroller.counter.CounterStore,\
net.floodlightcontroller.storage.memory.MemoryStorageSource,\
net.floodlightcontroller.core.internal.FloodlightProvider,\
net.floodlightcontroller.staticflowentry.StaticFlowEntryPusher,\
net.floodlightcontroller.perfmon.PktInProcessingTime,\
net.floodlightcontroller.ui.web.StaticWebRoutable
cd floodlight $ ./floodlight_static.shThe following sFlow-RT script is based on the DDoS script described in Embedded SDN applications:
include('extras/json2.js'); var flowkeys = 'ipsource'; var value = 'frames'; var filter = 'outputifindex!=discard&direction=ingress&sourcegroup=external'; var threshold = 1000; var groups = {'external':['0.0.0.0/0'],'internal':['10.0.0.2/32']}; var metricName = 'ddos'; var controls = {}; var enabled = true; var blockSeconds = 20; var flowpusher = 'http://localhost:8080/wm/staticflowentrypusher/json'; function clearOpenFlow() { http('http://localhost:8080/wm/staticflowentrypusher/clear/all/json'); } function setOpenFlow(spec) { http(flowpusher, 'post','application/json',JSON.stringify(spec)); } function deleteOpenFlow(spec) { http(flowpusher, 'delete','application/json',JSON.stringify(spec)); } function block(address) { if(!controls[address]) { setOpenFlow({name:'block-' + address, switch:'00:00:00:00:00:01', cookie:'0', priority:'11', active: true, 'ether-type':'0x0800', 'src-ip': address, actions:""}); controls[address] = { action:'block', time: (new Date()).getTime() }; } } function allow(address) { if(controls[address]) { deleteOpenFlow({name:'block-' + address}); delete controls[address]; } } setEventHandler(function(evt) { if(!enabled) return; var addr = evt.flowKey; block(addr); },[metricName]); setIntervalHandler(function() { // remove stale controls var stale = []; var now = (new Date()).getTime(); var threshMs = 1000 * blockSeconds; for(var addr in controls) { if((now - controls[addr].time) > threshMs) stale.push(addr); } for(var i = 0; i < stale.length; i++) allow(stale[i]); },10); setHttpHandler(function(request) { var result = {}; try { var action = '' + request.query.action; switch(action) { case 'block': var address = request.query.address[0]; if(address) block(address); break; case 'allow': var address = request.query.address[0]; if(address) allow(address); break; case 'enable': enabled = true; break; case 'disable': enabled = false; break; } } catch(e) { result.error = e.message } result.controls = controls; result.enabled = enabled; return JSON.stringify(result); }); setGroups(groups); setFlow(metricName,{keys:flowkeys,value:value,filter:filter}); setThreshold(metricName,{metric:metricName,value:threshold,byFlow:true,timeout:5}); clearOpenFlow(); setOpenFlow({name:'normal',switch:"00:00:00:00:00:01",cookie:"0", priority:"10",active:true,actions:"output=normal"});The following command line argument loads the script on startup:
-Dscript.file=normal.jsSome notes on the script:
- The intervalHandler() function is used to automatically release controls after 20 seconds
- The clearOpenFlow() function is used to remove any existing flow entries at startup
- The last line in the script defined the NORMAL forwarding action for all packets on the switch using a priority of 10
- Blocking rules are added for specific addresses using a higher priority of 11
- disable the controller
- perform a simulated DoS attack (using a flood ping)
- enable the controller
- simulate a second DoS attack
Figure 3: DDoS attack traffic with and without controller |
DDoS mitigation is only one use case large flow control, others described on this blog include: ECMP / LAG load balancing, traffic marking and packet capture. This script can be modified to address these different use cases. The Mininet test bed provides a useful way to test hybrid OpenFlow control schemes before moving them into production using physical switches that support integrated hybrid OpenFlow.
No comments:
Post a Comment