Meter mod wasn't working as the module was querying the wrong meter ID : Fixed!

Graph plot was showing wrong scales, corrected the calculation made from
bwm-ng output : Fixed!
Bandwidth usage still kind of broken : Revisit!
parent f4ff889c
......@@ -2,7 +2,7 @@
csv_input=$1
declare -a arr=("s1-eth1" "s2-eth1" "s2-eth2" "s3-eth2")
declare -a arr=("s1-eth1" "s1-eth2" "s2-eth1" "s2-eth2" "s2-eth3" "s3-eth2")
start_timestamp=`head -1 $csv_input | cut -d',' -f1`
export start_timestamp
......@@ -14,8 +14,8 @@ do
output_filename="$i.pdf"
export output_filename
export input_filename
#filed :1 timestamp, 6:bytes_in, 7:bytes_out
grep $i $csv_input | cut -d',' -f1,6,7 > $input_filename
#filed :1 timestamp, 3:bytes_out, 4:bytes_in, 8:total_packets, 9:errors_out, 10:errors_in
grep $i $csv_input | cut -d',' -f1,3,4,9,10 | sort -u -g --output=$input_filename
./gnu_deidtect_bw.scr
rm $input_filename
done
#!/opt/local/bin/gnuplot
#!/usr/bin/gnuplot
input_filename="`echo $input_filename`"
output_filename="`echo $output_filename`"
start_timestamp="`echo $start_timestamp`"
......@@ -11,18 +11,21 @@ set output output_filename
set style arrow 1 ls 5 lw 2
set style func linespoints
LW=2
set style line 1 lw 1
set style line 2 lw 1
set style line 3 lw 1
set style line 4 lw 1
set style line 1 lt 2 lc rgb "black" lw 3
set style line 2 lt 2 lc rgb "blue" lw 3
set style line 3 lt 2 lc rgb "yellow" lw 2
set style line 4 lt 2 lc rgb "orange" lw 2
set timefmt '%s'
set xlabel "Time Series"
set ylabel "MB"
set yrange [0:5]
set ytics 0.26
set ylabel "Mbps"
set yrange [0:10]
set ytics 0.5
#set xdata time
set datafile separator ","
plot input_filename using ($1-start_timestamp):($2/(1024*1024)) title 'in' with lines ls 1 , \
input_filename using ($1-start_timestamp):($3/(1024*1024)) title 'out' with lines ls 4
plot input_filename using ($1-start_timestamp):(($2*8)/(1024*1024)) title 'out' with lines ls 1 , \
input_filename using ($1-start_timestamp):(($3*8)/(1024*1024)) title 'in' with lines ls 2 , \
input_filename using ($1-start_timestamp):(($4*8)/(1024*1024)) title 'error-out' with lines ls 3 , \
input_filename using ($1-start_timestamp):(($5*8)/(1024*1024)) title 'error-in' with lines ls 4
......@@ -5,3 +5,7 @@ build/*
cscope*
*.pyc
ryu.egg-info/*
.nfs*
ryu.out
result/*
*.csv
#!/usr/bin/python
"""
Run deidtect to study the bandwdith sharing behaviour between
service traffic and tap traffic going through a common port.
Praveen Kumar Shanmugam
"""
import sys
sys.path = ['../'] + sys.path
import os
import random
import json
from time import sleep
from optparse import OptionParser
from subprocess import Popen, PIPE
import multiprocessing
from mininet.net import Mininet
from mininet.node import Controller, RemoteController, UserSwitch, CPULimitedHost
from mininet.link import TCLink
from mininet.cli import CLI
from mininet.log import setLogLevel, info, warn, error, debug
from mininet.util import custom, quietRun, run
#Parse command line options and dump results
def parseOptions():
"Parse command line options"
parser = OptionParser()
parser.add_option( '-i', '--infile', dest='infile',
default=None, help='traffic gen input file' )
parser.add_option( '-r', '--runs', dest='runs',
type='int', default=1, help='specify number of runs of each test' )
parser.add_option( '-b', '--bw', dest='bw',
type='int', default=0, help='use bandwidth limiting' )
parser.add_option( '-c', '--cip', dest='cip',
type='string', default="localhost", help='controller IP' )
parser.add_option( '-p', '--cpu', dest='cpu',
type='float', default=-1, help='cpu fraction to allocate to each host' )
parser.add_option( '-s', '--static', dest='static',
default=False, action='store_true',
help='statically allocate CPU to each host' )
parser.add_option( '-t', '--time', dest='time',
type='int', default=30, help='duration for which to run the experiment' )
parser.add_option( '-q', '--queue', dest='queue',
type='int', default=100, help='set switch buffer sizes' )
( options, args ) = parser.parse_args()
return options, args
opts, args = parseOptions()
def clean():
'''Clean any running instance of mininet and ryu'''
p = Popen("ps aux | grep 'ryu' | awk '{print $2}'",
stdout=PIPE, shell=True)
p.wait()
procs = (p.communicate()[0]).split('\n')
for pid in procs:
try:
pid = int(pid)
Popen('kill %d' % pid, shell=True).wait()
except:
pass
os.system('sudo mn -c')
#Creat a topology with 10 Mbs links except the one with the src host
#connected to the network, configure that with bw
def bandwidthTopo(bw, controllerip):
net = Mininet(controller=RemoteController, switch=UserSwitch)
c0 = net.addController('c0', ip=controllerip, port=6633 )
srcLink = custom(TCLink, bw=bw)
otherLink = custom(TCLink, bw=10)
"Create custom topo."
attacker = net.addHost( 'h1', mac='00:00:00:00:00:21')
brosys = net.addHost( 'h2', mac='00:00:00:00:00:22')
brosys2 = net.addHost( 'h3', mac='00:00:00:00:00:23')
brosys3 = net.addHost( 'h4', mac='00:00:00:00:00:24')
topSwitch = net.addSwitch( 's1' )
bottomSwitch = net.addSwitch( 's2' )
lvl2Switch = net.addSwitch( 's3' )
# Add links
srcLink( attacker, topSwitch )
otherLink( topSwitch, brosys )
otherLink( topSwitch, bottomSwitch)
otherLink( bottomSwitch, brosys2 )
otherLink( bottomSwitch, lvl2Switch )
otherLink( lvl2Switch , brosys3 )
net.build()
c0.start()
topSwitch.start([c0])
bottomSwitch.start([c0])
lvl2Switch.start([c0])
ryu_c = Popen("./ryu_init.sh %s %d 1> ryu.out 2> ryu.out" % (controllerip, 3), shell=True)
print "wait 5 sec for controller to connect"
sleep(5)
return net, ryu_c
def hostArray( net ):
"Return array[1..N] of net.hosts"
try:
host_array = sorted(net.hosts, key=lambda x: int(x.name))
except:
host_array = sorted(net.hosts, key=lambda x: x.name)
return host_array
def monitor_devs_ifstat(fname="rate.csv"):
if_cmd = 'ifstat -a -t > %s &' % (fname)
print if_cmd
Popen(if_cmd, shell=True).wait()
def monitor_devs_ng(fname="txrate.csv" , interval_sec=0.01):
"""Uses bwm-ng tool to collect iface tx rate stats. Very reliable."""
cmd = ("sleep 1; bwm-ng -t %s -o csv "
"-u bytes -T rate -C ',' > %s" %
(interval_sec * 1000, fname))
Popen(cmd, shell=True).wait()
def monitorInterfacesInit(net, outfile):
monitors = []
#monitors.append(multiprocessing.Process(target=monitor_devs_ifstat,
# args=("rate.csv",)))
os.system("rm -f %s" % outfile)
monitors.append(multiprocessing.Process(target=monitor_devs_ng,
args=(outfile, 1,)))
return monitors
def bandwidthTest(bw=5, controllerip="localhost"):
print bw
print controllerip
net, ryu_c = bandwidthTopo(bw,controllerip)
hosts = hostArray(net)
#for h in hosts:
# print "Host : %s\n" % (h.name)
h1 = net.getNodeByName('h1')
print h1.name
h2 = net.getNodeByName('h1')
print h2.name
h3 = net.getNodeByName('h3')
print h3.name
s1 = net.getNodeByName('s1')
print s1.name
#populate l3 routes
net.pingAll();
#bandwidth = net.iperf( [ h1, h3], udpBw='%sM' % bw, seconds=5 )
#print bandwidth
outfile="txrate%s.csv" % bw
monitors = monitorInterfacesInit(net,outfile);
for m in monitors:
m.start();
#CLI(net)
#start the traffic generation wait for 5 seconds (H1->H3)
h1_tg_cmd = 'mz h1-eth0 -c 0 -t udp sp=49 -A 10.0.0.1 -B 10.0.0.3 -P \"Hello World\" &'
#start the traffic generation wait for 5 seconds (H2->H4)
h2_tg_cmd = 'mz h2-eth0 -c 0 -t udp sp=51 -A 10.0.0.2 -B 10.0.0.4 -P \"Hello World\" &'
print "Traffic generation from H1 started"
h1.cmd(h1_tg_cmd)
sleep_time = 20
print "Sleeping for %d seconds before h2 sends traffic" % sleep_time
sleep(sleep_time)
#create the tap for s2-port(3)
#wait for 2 minutes for the rate-limiter to grow
h2.cmd(h2_tg_cmd)
print "Wait for %d seconds for h2 to send traffic" % sleep_time
sleep(sleep_time)
sleep_time = 120
i = 10;
while ( i < sleep_time):
print "Sleeping for %d seconds for rate-limiters to grow" % i
sleep(i)
sleep_time=sleep_time - i;
#for installing meter-mod
#CLI(net)
#stop the traffic generation
h1.cmd('killall mz')
h2.cmd('killall mz')
print "Stopped traffic generation"
#generate the graph
for m in monitors:
m.terminate();
net.stop();
return
def drawGraph(directory, infile):
Popen(("mkdir -p base-result/bw/%s" % directory), shell=True).wait() ;
Popen(("cp -v ../graphScripts/drawBwGraph.sh drawBwGraph.sh"),
shell=True).wait();
Popen(("cp -v ../graphScripts/gnu_deidtect_bw.scr gnu_deidtect_bw.scr"),
shell=True).wait();
Popen(("./drawBwGraph.sh %s" % infile), shell=True).wait();
Popen(("mv -v *.pdf base-result/bw/%s/" % directory), shell=True).wait();
Popen(("rm -v drawBwGraph.sh gnu_deidtect_bw.scr"), shell=True).wait();
print "Graph Generated for BW = %d " % directory
def DEIDtectBWTest(opts):
bw = opts.bw
controllerip=opts.cip
print "Rollback to known state"
clean();
bandwidthTest(bw=bw,controllerip=controllerip)
print "Cleanup the process"
clean();
infile="txrate%s.csv" % bw
drawGraph(bw, infile);
if __name__ == '__main__':
#global opts
DEIDtectBWTest(opts);
......@@ -122,17 +122,17 @@ def monitor_devs_ifstat(fname="rate.csv"):
def monitor_devs_ng(fname="txrate.csv" , interval_sec=0.01):
"""Uses bwm-ng tool to collect iface tx rate stats. Very reliable."""
cmd = ("sleep 1; bwm-ng -t %s -o csv "
"-u bits -T rate -C ',' > %s" %
"-u bytes -T rate -C ',' > %s" %
(interval_sec * 1000, fname))
Popen(cmd, shell=True).wait()
def monitorInterfacesInit(net):
def monitorInterfacesInit(net, outfile):
monitors = []
#monitors.append(multiprocessing.Process(target=monitor_devs_ifstat,
# args=("rate.csv",)))
os.system('rm txrate.csv')
os.system("rm -f %s" % outfile)
monitors.append(multiprocessing.Process(target=monitor_devs_ng,
args=('txrate.csv', 1,)))
args=(outfile, 1,)))
return monitors
......@@ -147,18 +147,22 @@ def bandwidthTest(bw=5, controllerip="localhost"):
#for h in hosts:
# print "Host : %s\n" % (h.name)
monitoringHosts = []
h1 = net.getNodeByName('h1')
print h1.name
monitoringHosts.append(h1)
h3 = net.getNodeByName('h3')
monitoringHosts.append(h3)
print h3.name
s1 = net.getNodeByName('s1')
print s1.name
#populate l3 routes
net.pingAll();
#bandwidth = net.iperf( [ h1, h3], udpBw='%sM' % bw, seconds=5 )
#print bandwidth
outfile="txrate%s.csv" % bw
monitors = monitorInterfacesInit(net);
monitors = monitorInterfacesInit(net,outfile);
for m in monitors:
m.start();
......@@ -166,7 +170,7 @@ def bandwidthTest(bw=5, controllerip="localhost"):
#CLI(net)
#start the traffic generation wait for 5 seconds (H1->H3)
tg_cmd = 'mz h1-eth0 -c 0 -t ip -A 10.0.0.1 -B 10.0.0.3 -P \"Hello World\" &'
tg_cmd = 'mz h1-eth0 -c 0 -t udp sp=49 -A 10.0.0.1 -B 10.0.0.3 -P \"Hello World\" &'
print "Traffic generation from H1 started"
h1.cmd(tg_cmd)
......@@ -179,8 +183,13 @@ def bandwidthTest(bw=5, controllerip="localhost"):
p = Popen("./bwTestTapFlow.sh", shell=True)
sleep_time = 120
print "Sleeping for %d seconds for rate-limiters to grow" % sleep_time
sleep(sleep_time)
i = 10;
while ( i < sleep_time):
print s1.cmd('dpctl unix:/tmp/s1 meter-config')
print "Sleeping for %d seconds for rate-limiters to grow" % i
sleep(i)
sleep_time=sleep_time - i;
#for installing meter-mod
#CLI(net)
#stop the traffic generation
......@@ -195,13 +204,13 @@ def bandwidthTest(bw=5, controllerip="localhost"):
return
def drawGraph(directory):
def drawGraph(directory, infile):
Popen(("mkdir -p result/bw/%s" % directory), shell=True).wait() ;
Popen(("cp -v ../graphScripts/drawBwGraph.sh drawBwGraph.sh"),
shell=True).wait();
Popen(("cp -v ../graphScripts/gnu_deidtect_bw.scr gnu_deidtect_bw.scr"),
shell=True).wait();
Popen(("./drawBwGraph.sh txrate.csv"), shell=True).wait();
Popen(("./drawBwGraph.sh %s" % infile), shell=True).wait();
Popen(("mv -v *.pdf result/bw/%s/" % directory), shell=True).wait();
Popen(("rm -v drawBwGraph.sh gnu_deidtect_bw.scr"), shell=True).wait();
print "Graph Generated for BW = %d " % directory
......@@ -218,7 +227,8 @@ def DEIDtectBWTest(opts):
print "Cleanup the process"
clean();
drawGraph(bw);
infile="txrate%s.csv" % bw
drawGraph(bw, infile);
if __name__ == '__main__':
#global opts
......
#!/bin/bash -x
declare -a arr=(5 6 7 8 9 10)
for i in "${arr[@]}"
do
echo "Running BW Test with source link setto $i MB"
python bw-test.py -b $i -c localhost
done
......@@ -33,7 +33,7 @@ from ryu.lib import tapDB
from ryu.lib import objectTapDB as oDB
LOG = logging.getLogger('ryu.app.cnac_rest')
LOG.setLevel(logging.WARNING)
LOG.setLevel(logging.DEBUG)
CMD_PATTERN = r'[a-f]|all'
global tapDb
tapDb = {}
......@@ -234,10 +234,12 @@ class TapPolicyController(ControllerBase):
LOG.debug("tap_port: %d", tap_port)
LOG.debug("vlan_id : %d", vlan_id)
rate = 10
tapDbEntry= {
'dpid': dpid_pd, 'monitorPort':tap_port, 'bandwidth':10,
'trafficType':'all', 'tunnelVlan':int(vlan_id),
'destinationVlan':int(vlan_id), 'ratelimit':10000
'destinationVlan':int(vlan_id), 'ratelimit':rate
}
......@@ -271,7 +273,8 @@ class TapPolicyController(ControllerBase):
src, ids_port)
#vlan_id = graph.edge[src][dst]['vlan']
in_vlan_id = vlan_id
iresponse = self.installSafeTapStart(tap_id, dpid_pd, tap_port, ids_port, vlan_id)
iresponse = self.installSafeTapStart(tap_id, dpid_pd,
tap_port, ids_port, vlan_id, rate)
LOG.debug("iresponse: %s", str(iresponse))
else:
LOG.debug("We have an intermediary switch as src :%s push to port:%d" , src,ids_port)
......@@ -516,7 +519,8 @@ class TapPolicyController(ControllerBase):
self.mod_flow(dp, command=of.OFPFC_ADD, match=match, inst=inst)
return True
def installSafeTapStart(self, tap_id, dpid_pd, tap_port, ids_port, vlan_id):
def installSafeTapStart(self, tap_id, dpid_pd, tap_port, ids_port,
vlan_id, rate):
dpid = hex_to_int(dpid_pd)
dp = self.dpset.get(dpid)
......@@ -542,12 +546,15 @@ class TapPolicyController(ControllerBase):
#create a meter_drop_band for the monitoring path
bands = []
rate = 10000
burst_size = 0
bands.append(ofp.OFPMeterBandDrop(rate, burst_size))
meter_mod = ofp.OFPMeterMod(
dp, of.OFPMC_ADD, of.OFPMF_KBPS, int(tap_id), bands)
dp.send_msg(meter_mod)
rate = 2 * rate ;
meter_mod = ofp.OFPMeterMod(
dp, of.OFPMC_MODIFY, of.OFPMF_KBPS, int(tap_id), bands)
dp.send_msg(meter_mod)
for i in flows[str(dpid)]:
for j in i['actions']:
......
......@@ -9,6 +9,7 @@ from ryu.lib.dpid import str_to_dpid,dpid_to_str
from ryu.lib import hub
from ryu.lib import tapDB
from ryu.lib import bwDB
from subprocess import Popen
#get all the tap points from the tap DB.
# for eac of the metering check the bandwidth associated with it.
......@@ -45,10 +46,10 @@ class dynamicRateLimiter(simple_switch_13.SimpleSwitch13):
def _reconfigure_metering(self, tap):
bwList = bwDB.getBWEntry(tap)
for bw in bwList:
#print bw
print bw
dpid = str_to_dpid(tap.get('dpid'))
datapath = self.datapaths[dpid]
'''
for dp in self.datapaths.values():
print dpid_str
......@@ -62,11 +63,12 @@ class dynamicRateLimiter(simple_switch_13.SimpleSwitch13):
bandwidth = bw.get('bandwidth')
usedbw = bw.get('usedbw')
pktError = bw.get('pktError')
limit = tap.get('limit')
tapid = tap.get('tapID')
ratelimit = int(tap.get('limit'))
tapid = int(tap.get('tapID'))
meterid = tapid +1
max_rate_limit = (bandwidth / 2) #max limit = 50%
increment = (bandwidth / 20 ) # 5% increment
increment = (bandwidth / (1024 * 100)) # 1% increment [bandwidth is in bytes]
if (pktError > 0):
print "Reduce the rate limiting in multiples of increment"
......@@ -77,9 +79,10 @@ class dynamicRateLimiter(simple_switch_13.SimpleSwitch13):
burst_size = 0
bands = []
bands.append(ofp.OFPMeterBandDrop(new_limit, burst_size))
meter_mod = ofp.OFPMeterMod(
datapath, of.OFPMC_MODIFY, of.OFPMF_KBPS, int(tapid), bands)
meter_mod = ofp.OFPMeterMod(datapath, of.OFPMC_MODIFY,
of.OFPMF_KBPS, meterid, bands)
datapath.send_msg(meter_mod)
rateEntry = {
'ratelimit' : new_limit,
'tapID' : tapid
......@@ -87,13 +90,13 @@ class dynamicRateLimiter(simple_switch_13.SimpleSwitch13):
tapDB.udpateRateLimit(rateEntry)
return ;
if limit == max_rate_limit:
print "Already at maximum time limit"
if ratelimit == max_rate_limit:
print "Already at maximum time ratelimit"
return ;
if (usedbw < 50): #less than 50%
print "Increase the rate for tunnel traffic"
new_limit = limit + increment;
new_limit = ratelimit + increment;
if new_limit > max_rate_limit:
new_limit = max_rate_limit;
of = datapath.ofproto
......@@ -101,9 +104,10 @@ class dynamicRateLimiter(simple_switch_13.SimpleSwitch13):
burst_size = 0
bands = []
bands.append(ofp.OFPMeterBandDrop(new_limit, burst_size))
meter_mod = ofp.OFPMeterMod(
datapath, of.OFPMC_MODIFY, of.OFPMF_KBPS, int(tapid), bands)
meter_mod = ofp.OFPMeterMod(datapath, of.OFPMC_MODIFY,
of.OFPMF_KBPS, meterid, bands)
datapath.send_msg(meter_mod)
rateEntry = {
'ratelimit' : new_limit,
'tapID' : tapid
......
......@@ -72,18 +72,18 @@ def checkDuplicateEntry(bwDBEntry):
def getBWEntry(bwDBEntry):
print "getBWEntry query for flowTable"
#print bwDBEntry
print bwDBEntry
conn = sql.connect(bwdb)
cursor = conn.cursor()
cursor.execute("""select uniqID,bandwidth, usedbw, rxBytes, txBytes,
txDrops, pktError, timeStamp from bwTable where dpid=:dpid and
txDrops, pktError, timeStamp, ratelimit from bwTable where dpid=:dpid and
port=:port """,bwDBEntry);
bwList = []
for row in cursor.fetchall():
#print row;
print row;
rowDict = {};
rowDict = { 'uniqID' : row[0],
'bandwidth':row[1],
......@@ -94,7 +94,7 @@ def getBWEntry(bwDBEntry):
'pktError':row[6],
'timeStamp':row[7]
}
#print rowDict
print rowDict
bwList.append(rowDict)
cursor.close();
......@@ -197,7 +197,8 @@ def updateBWDict(bwDBEntry):
print "zero timestamp; set rate to 0"
rate = 0;
utilization = (rate * 100 / bandwidth) #in percentage
utilization = (bandwidth* 100/rate) #in percentage
#utilization = (rate * 100 / bandwidth) #in percentage
#print "calculated bytes, time and rate"
#print newBytes;
#print sec;
......
......@@ -384,7 +384,7 @@ def getAllTapMeters():
'port':row[2],
'limit':row[3]
}
#print rowDict;
print rowDict;
tapList.append(rowDict);
except sql.error as e:
print "an error occured ",e.args[0];
......
......@@ -5,7 +5,7 @@ SWITCH_COUNT=$2
#./bin/ryu-manager --verbose --app-lists ryu/app/rest,ryu/app/rest_topology,ryu/topology/dumper,ryu/app/ofctl_rest,ryu/app/cnac_rest
#./bin/ryu-manager --verbose --observe-links --wsapi-host=$WSAPI_HOST --app-lists ryu.topology.switches,ryu.app.rest,ryu.app.rest_topology,ryu.app.ofctl_rest,ryu/app/cnac_rest,ryu/app/rest_net_topology,ryu.app.simple_switch_lacp
./bin/ryu-manager --wsapi-host=$WSAPI_HOST --app-lists ryu/app/rest,ryu/app/rest_topology,ryu/topology/dumper,ryu/app/ofctl_rest,ryu/app/cnac_rest,ryu/app/rest_net_topology,ryu/app/simple_switch_13,ryu/app/simple_monitor #,ryu/app/dump_pkt
./bin/ryu-manager --wsapi-host=$WSAPI_HOST --app-lists ryu/app/rest,ryu/app/rest_topology,ryu/topology/dumper,ryu/app/ofctl_rest,ryu/app/cnac_rest,ryu/app/rest_net_topology,ryu/app/simple_switch_13,ryu/app/simple_monitor,ryu/app/dynamic_rate_limiter #,ryu/app/dump_pkt
#./bin/ryu-manager --verbose --wsapi-host=$WSAPI_HOST --app-lists ryu.topology.switches,ryu.app.rest,ryu.app.rest_topology,ryu.app.ofctl_rest,ryu/app/cnac_rest,ryu/app/rest_net_topology,ryu/app/dump_pkt
#./bin/ryu-manager --verbose --wsapi-host=$WSAPI_HOST --app-lists ryu.topology.switches,ryu.app.rest,ryu.app.rest_topology,ryu.app.ofctl_rest,ryu/app/cnac_rest,ryu/app/rest_net_topology,ryu/app/simple_switch_13,ryu/app/simple_monitor,ryu/app/dynamic_rate_limiter,ryu/app/dump_pkt
#./bin/ryu-manager --verbose --observe-links --app-lists ryu.topology.switches,ryu.app.rest,ryu.app.rest_topology,ryu.app.ofctl_rest,ryu/app/cnac_rest,ryu/app/rest_net_topology
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment