| | 1 | [wiki:WikiStart Orbit] > [wiki:OtherApps Other Applications] > Iperf Scripts |
| | 2 | |
| | 3 | = Application Definition Schema = |
| | 4 | The application definition schema for the Iperf application is as follows |
| | 5 | {{{ |
| | 6 | <?xml version="1.0" encoding="UTF-8"?> |
| | 7 | <orbit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> |
| | 8 | <application id="orbit_winlab_iperf"> |
| | 9 | <name>iperf</name> |
| | 10 | <id>iperf</id> |
| | 11 | <version major="0" minor="1" revision="0"/> |
| | 12 | <organization> |
| | 13 | <name>WINLAB, Rutgers University</name> |
| | 14 | <url>http://www.winlab.rutgers.edu/</url> |
| | 15 | </organization> |
| | 16 | <shortDescription>Traffic Generator</shortDescription> |
| | 17 | <description>Receive network traffic on the specified interface |
| | 18 | </description> |
| | 19 | <url>http://apps.orbit-lab.org/otr</url> |
| | 20 | <measurement-points> |
| | 21 | <measurement-point id="receiverport"> |
| | 22 | <metric id="flow_no" type="int"> |
| | 23 | <description>id of the flow</description> |
| | 24 | </metric> |
| | 25 | <metric id="throughput" type="float"> |
| | 26 | <description> Flow Throughput</description> |
| | 27 | </metric> |
| | 28 | <metric id="jitter" type="float"> |
| | 29 | <description>Flow jitter</description> |
| | 30 | </metric> |
| | 31 | <metric id="packet_loss" type="float"/> |
| | 32 | <description>Flow Packet loss</description> |
| | 33 | </measurement-point> |
| | 34 | </measurement-points> |
| | 35 | <issueTrackingUrl>http://apps.orbit-lab.org/issues/winlab/iperf |
| | 36 | </issueTrackingUrl> |
| | 37 | <repository> |
| | 38 | <development>scm:cvs:pserver:anoncvs@cvs.orbit-lab.org:/trafficgenerator/iperf</development> |
| | 39 | <binary>apt:repository.orbit-lab.org/orbit/binary:???</binary> |
| | 40 | </repository> |
| | 41 | <mailingLists/> |
| | 42 | <developers> |
| | 43 | <developer> |
| | 44 | <name>John Doe</name> |
| | 45 | <id>jdoe</id> |
| | 46 | <email>jdoe@winlab.rutgers.edu</email> |
| | 47 | <organization> |
| | 48 | <name>WINLAB, Rutgers University</name> |
| | 49 | </organization> |
| | 50 | </developer> |
| | 51 | </developers> |
| | 52 | <dependencies> |
| | 53 | <dependency> |
| | 54 | <id>libmac</id> |
| | 55 | <version>>= 0.4</version> |
| | 56 | <url>apt:repository.orbit-lab.org/debian/binary:libmac |
| | 57 | </url> |
| | 58 | </dependency> |
| | 59 | </dependencies> |
| | 60 | </application> |
| | 61 | </orbit> |
| | 62 | |
| | 63 | }}} |
| | 64 | |
| | 65 | = Application definition script for Iperf sender and Receiver = |
| | 66 | |
| | 67 | == Iperf Sender == |
| | 68 | {{{ |
| | 69 | # |
| | 70 | # Create an application representation from scratch |
| | 71 | # |
| | 72 | require 'appDefinition' |
| | 73 | |
| | 74 | a = AppDefinition.create('test:app:iperfs') |
| | 75 | a.name = "iperfs" |
| | 76 | a.version(0, 0, 1) |
| | 77 | a.shortDescription = "Iperf traffic generator" |
| | 78 | a.description = <<TEXT |
| | 79 | Iperf is a traffic generator for TCP and UDP traffic. It contains generators |
| | 80 | producing various forms of packet streams and port for sending |
| | 81 | these packets via various transports, such as TCP and UDP. |
| | 82 | TEXT |
| | 83 | |
| | 84 | # addProperty(name, description, mnemonic, type, isDynamic = false, constraints = nil) |
| | 85 | a.addProperty('udp', 'Use UDP, otherwise TCP by default', nil, String, false) |
| | 86 | a.addProperty('client', 'Run as client', nil, String, false) |
| | 87 | a.addProperty('port', 'Sender port number', nil, Integer, false) |
| | 88 | a.addProperty('window', 'TCP Send Window Size', nil, Integer, false) |
| | 89 | a.addProperty('len', "Payload length (bytes)", nil, Integer, false) |
| | 90 | a.addProperty('bandwidth', "Offered load for UDP", nil, Integer, false) |
| | 91 | a.addProperty('time', "Duration of traffic generation(secs)", nil, Integer, false) |
| | 92 | a.addProperty('parallel', "Number of parallel flows", nil, Integer, false) |
| | 93 | |
| | 94 | a.addMeasurement("senderport", nil, [ |
| | 95 | ['stream_no', 'int'], |
| | 96 | ['pkt_seqno', 'long'], |
| | 97 | ['pkt_size', 'long'], |
| | 98 | ['gen_timestamp', 'long'], |
| | 99 | ['tx_timestamp', 'long'] |
| | 100 | ]) |
| | 101 | |
| | 102 | a.path = "/usr/local/bin/iperf" |
| | 103 | |
| | 104 | if $0 == __FILE__ |
| | 105 | require 'stringio' |
| | 106 | require 'rexml/document' |
| | 107 | include REXML |
| | 108 | |
| | 109 | sio = StringIO.new() |
| | 110 | a.to_xml.write(sio, 2) |
| | 111 | sio.rewind |
| | 112 | puts sio.read |
| | 113 | |
| | 114 | sio.rewind |
| | 115 | doc = Document.new(sio) |
| | 116 | t = AppDefinition.from_xml(doc.root) |
| | 117 | |
| | 118 | puts |
| | 119 | puts "-------------------------" |
| | 120 | puts |
| | 121 | t.to_xml.write($stdout, 2) |
| | 122 | |
| | 123 | end |
| | 124 | |
| | 125 | }}} |
| | 126 | == Iperf Receiver == |
| | 127 | {{{ |
| | 128 | # |
| | 129 | # Create an application representation from scratch |
| | 130 | # |
| | 131 | require 'appDefinition' |
| | 132 | |
| | 133 | a = AppDefinition.create('test:app:iperfr') |
| | 134 | a.name = "iperfr" |
| | 135 | a.version(0, 0, 1) |
| | 136 | a.shortDescription = "Iperf traffic generator" |
| | 137 | a.description = <<TEXT |
| | 138 | Iperf is a traffic generator for TCP and UDP traffic. It contains generators |
| | 139 | producing various forms of packet streams and port for sending |
| | 140 | these packets via various transports, such as TCP and UDP. |
| | 141 | TEXT |
| | 142 | |
| | 143 | # addProperty(name, description, mnemonic, type, isDynamic = false, constraints = nil) |
| | 144 | a.addProperty('udp', 'Use UDP, otherwise TCP by default', nil, String, false) |
| | 145 | a.addProperty('server', 'Client/Server', nil, String, false) |
| | 146 | a.addProperty('port', 'Receiver port number', nil, Integer, false) |
| | 147 | a.addProperty('window', 'TCP Receiver Window Size', nil, Integer, false) |
| | 148 | a.addProperty('time', "Duration for traffic generation(seconds)", nil, Integer, false) |
| | 149 | a.addProperty('len', "Payload Length(bytes)", nil, Integer, false) |
| | 150 | a.addProperty('interval', "Interval between reports (sec)", nil, Integer, false) |
| | 151 | |
| | 152 | a.addMeasurement("receiverport", nil, [ |
| | 153 | ['flow_no', 'int', 'id of the flow'], |
| | 154 | ['throughput', Float, 'Flow Throughput'], |
| | 155 | ['jitter', Float,'Average Jitter'], |
| | 156 | ['packet_loss',Float,'Packet loss'] |
| | 157 | ]) |
| | 158 | a.path = "/usr/local/bin/iperf" |
| | 159 | |
| | 160 | if $0 == __FILE__ |
| | 161 | require 'stringio' |
| | 162 | require 'rexml/document' |
| | 163 | include REXML |
| | 164 | |
| | 165 | sio = StringIO.new() |
| | 166 | a.to_xml.write(sio, 2) |
| | 167 | sio.rewind |
| | 168 | puts sio.read |
| | 169 | |
| | 170 | sio.rewind |
| | 171 | doc = Document.new(sio) |
| | 172 | t = AppDefinition.from_xml(doc.root) |
| | 173 | |
| | 174 | puts |
| | 175 | puts "-------------------------" |
| | 176 | puts |
| | 177 | t.to_xml.write($stdout, 2) |
| | 178 | |
| | 179 | end |
| | 180 | |
| | 181 | }}} |
| | 182 | = Sample prototype definitions script for Iperf UDP and TCP (sender and Receiver) = |
| | 183 | |
| | 184 | == Iperf UDP Sender == |
| | 185 | {{{ |
| | 186 | # |
| | 187 | # Define a prototype |
| | 188 | # |
| | 189 | require 'prototype' |
| | 190 | require 'filter' |
| | 191 | require 'appDefinition' |
| | 192 | |
| | 193 | p = Prototype.create("test:proto:iperfudpsender") |
| | 194 | p.name = "Iperf UDP Sender" |
| | 195 | p.description = "Nodes which send a stream of packets" |
| | 196 | p.defProperty('use_udp', 'Protocol to use') |
| | 197 | p.defProperty('client', 'Host to send packets to') |
| | 198 | p.defProperty('sender_rate', 'Number of bits per second', 100000) |
| | 199 | p.defProperty('len', 'Size of packets') |
| | 200 | p.defProperty('time', 'Experiment duration (sec)', 10) |
| | 201 | |
| | 202 | iperfs = p.addApplication(:iperfs, "test:app:iperfs") |
| | 203 | iperfs.bindProperty('udp','use_udp') |
| | 204 | iperfs.bindProperty('client') |
| | 205 | iperfs.bindProperty('bandwidth','sender_rate') |
| | 206 | iperfs.bindProperty('len') |
| | 207 | iperfs.bindProperty('time') |
| | 208 | |
| | 209 | iperfs.addMeasurement('senderport', Filter::TIME, |
| | 210 | {Filter::SAMPLE_SIZE => 1}, |
| | 211 | [ |
| | 212 | ['stream_no'], |
| | 213 | ['pkt_seqno'], |
| | 214 | ['pkt_size', Filter::SUM], |
| | 215 | ['gen_timestamp'], |
| | 216 | ['tx_timestamp'] |
| | 217 | ] |
| | 218 | ) |
| | 219 | if $0 == __FILE__ |
| | 220 | p.to_xml.write($stdout, 2) |
| | 221 | puts |
| | 222 | end |
| | 223 | |
| | 224 | }}} |
| | 225 | == Iperf UDP Receiver == |
| | 226 | {{{ |
| | 227 | # |
| | 228 | # Define a prototype |
| | 229 | # |
| | 230 | |
| | 231 | require 'prototype' |
| | 232 | require 'filter' |
| | 233 | require 'appDefinition' |
| | 234 | |
| | 235 | p = Prototype.create("test:proto:iperfudpreceiver") |
| | 236 | p.name = "Iperf UDP Receiver" |
| | 237 | p.description = "Nodes which receive packets" |
| | 238 | p.defProperty('use_udp', 'Protocol to use') |
| | 239 | p.defProperty('server', 'Client/Server') |
| | 240 | p.defProperty('time', 'Duration of experiment (seconds)', 10) |
| | 241 | p.defProperty('len', 'Payload length', 512) |
| | 242 | p.defProperty('report_interval', 'Interval between bandwidth reports', 1) |
| | 243 | |
| | 244 | iperfr = p.addApplication('iperfr', "test:app:iperfr") |
| | 245 | iperfr.bindProperty('udp') |
| | 246 | iperfr.bindProperty('server') |
| | 247 | iperfr.bindProperty('time') |
| | 248 | iperfr.bindProperty('len') |
| | 249 | iperfr.bindProperty('interval','report_interval') |
| | 250 | |
| | 251 | iperfr.addMeasurement('receiverport', Filter::TIME, |
| | 252 | {Filter::SAMPLE_SIZE => 1}, |
| | 253 | [ |
| | 254 | ['flow_no'], |
| | 255 | ['throughput'], |
| | 256 | ['jitter'], |
| | 257 | ['packet_loss'] |
| | 258 | ] |
| | 259 | ) |
| | 260 | if $0 == __FILE__ |
| | 261 | p.to_xml.write($stdout, 2) |
| | 262 | puts |
| | 263 | end |
| | 264 | |
| | 265 | }}} |
| | 266 | == Iperf TCP Sender == |
| | 267 | {{{ |
| | 268 | # |
| | 269 | # Define a prototype |
| | 270 | # |
| | 271 | require 'prototype' |
| | 272 | require 'filter' |
| | 273 | require 'appDefinition' |
| | 274 | |
| | 275 | p = Prototype.create("test:proto:iperftcpsender") |
| | 276 | p.name = "Iperf TCP Sender" |
| | 277 | p.description = "Nodes which send a stream of packets" |
| | 278 | p.defProperty('client', 'Host to send packets to') |
| | 279 | #p.defProperty('port', 'Port to send packets to') |
| | 280 | p.defProperty('len', 'Size of packets') |
| | 281 | p.defProperty('window', 'TCP window Size (bytes)', 64000) |
| | 282 | p.defProperty('time', 'Experiment duration (sec)', 10) |
| | 283 | |
| | 284 | iperfs = p.addApplication(:iperfs, "test:app:iperfs") |
| | 285 | iperfs.bindProperty('client') |
| | 286 | iperfs.bindProperty('len') |
| | 287 | iperfs.bindProperty('time') |
| | 288 | iperfs.bindProperty('window') |
| | 289 | |
| | 290 | iperfs.addMeasurement('senderport', Filter::TIME, |
| | 291 | {Filter::SAMPLE_SIZE => 1}, |
| | 292 | [ |
| | 293 | ['stream_no'], |
| | 294 | ['pkt_seqno'], |
| | 295 | ['pkt_size', Filter::SUM], |
| | 296 | ['gen_timestamp'], |
| | 297 | ['tx_timestamp'] |
| | 298 | ] |
| | 299 | ) |
| | 300 | # |
| | 301 | if $0 == __FILE__ |
| | 302 | p.to_xml.write($stdout, 2) |
| | 303 | puts |
| | 304 | end |
| | 305 | |
| | 306 | }}} |
| | 307 | == Iperf TCP Receiver == |
| | 308 | {{{ |
| | 309 | # |
| | 310 | # Define a prototype |
| | 311 | # |
| | 312 | |
| | 313 | require 'prototype' |
| | 314 | require 'filter' |
| | 315 | require 'appDefinition' |
| | 316 | |
| | 317 | p = Prototype.create("test:proto:iperftcpreceiver") |
| | 318 | p.name = "Iperf TCP Receiver" |
| | 319 | p.description = "Nodes which receive packets" |
| | 320 | p.defProperty('server', 'Client/Server') |
| | 321 | p.defProperty('time', 'Duration of experiment (seconds)', 10) |
| | 322 | p.defProperty('window', 'Receiver Window Size', 64000) |
| | 323 | p.defProperty('report_interval', 'Interval beween reports', 1) |
| | 324 | |
| | 325 | |
| | 326 | iperfr = p.addApplication('iperfr', "test:app:iperfr") |
| | 327 | iperfr.bindProperty('server') |
| | 328 | iperfr.bindProperty('time') |
| | 329 | iperfr.bindProperty('window') |
| | 330 | iperfr.bindProperty('interval', 'report_interval') |
| | 331 | |
| | 332 | iperfr.addMeasurement('receiverport', Filter::TIME, |
| | 333 | {Filter::SAMPLE_SIZE => 1}, |
| | 334 | [ |
| | 335 | ['flow_no'], |
| | 336 | ['throughput'], |
| | 337 | ] ) |
| | 338 | |
| | 339 | if $0 == __FILE__ |
| | 340 | p.to_xml.write($stdout, 2) |
| | 341 | puts |
| | 342 | end |
| | 343 | |
| | 344 | }}} |
| | 345 | |
| | 346 | = Experiment script for Iperf = |
| | 347 | {{{ |
| | 348 | ############# Tutorial1 ################################## |
| | 349 | # This script defines the experiment |
| | 350 | # that has one sender and one receiver using Iperf |
| | 351 | # Sender, Receiver - 802.11a channel 36 |
| | 352 | # UDP flow at 1 Mbps |
| | 353 | # Receiver reports throughput, packet loss and jitter |
| | 354 | ############################################################ |
| | 355 | |
| | 356 | require 'net/http' |
| | 357 | require 'uri' |
| | 358 | |
| | 359 | Experiment.name = "tutorial-iperf" |
| | 360 | Experiment.project = "orbit:tutorial" |
| | 361 | |
| | 362 | ########################################### |
| | 363 | # Sender definition and configuration |
| | 364 | ########################################### |
| | 365 | defNodes('sender',[1,1]) {|node| |
| | 366 | node.image = nil # assume the right image to be on disk |
| | 367 | # use prototype "iperfudpsender" |
| | 368 | # and set it's property "destinationHost" to |
| | 369 | # the receiver node |
| | 370 | # and bind the remaining properties to the |
| | 371 | # experiment property space |
| | 372 | node.prototype("test:proto:iperfudpsender", { |
| | 373 | 'client' => '192.168.1.2', |
| | 374 | 'use_udp' => nil, #UDP client - nil argument means use UDP, For TCP, we dont use this option |
| | 375 | 'time' => 60, #Duration of traffic gen |
| | 376 | 'sender_rate' => 1000000, #Sender rate = 1 Mbps |
| | 377 | 'len' => 1024 #Payload length (bytes) |
| | 378 | }) |
| | 379 | node.net.w0.ip = "%192.168.%x.%y" |
| | 380 | node.net.w0.mode = "master" |
| | 381 | node.net.w0.type = 'a' |
| | 382 | node.net.w0.essid = "helloworld" |
| | 383 | } |
| | 384 | ########################################### |
| | 385 | # Receiver definition and configuration |
| | 386 | ########################################### |
| | 387 | defNodes('receiver', [1,2]) {|node| |
| | 388 | node.image = nil # assume the right image to be on disk |
| | 389 | node.prototype("test:proto:iperfudpreceiver" , { |
| | 390 | 'server' => nil, # Server |
| | 391 | 'use_udp' => nil, # Use UDP nil means no argument required |
| | 392 | 'len' => 1024, # Payload length (bytes) |
| | 393 | 'time' => 60, # Duration = 60 seconds |
| | 394 | 'report_interval' => 1 # Report interval = 1 sec |
| | 395 | }) |
| | 396 | node.net.w0.ip = "%192.168.%x.%y" |
| | 397 | node.net.w0.mode = "managed" |
| | 398 | node.net.w0.type = 'a' |
| | 399 | node.net.w0.essid = "helloworld" |
| | 400 | } |
| | 401 | ########################################### |
| | 402 | # When nodeAgents have reported "OK" to |
| | 403 | # the nodeHandler start the application |
| | 404 | ########################################### |
| | 405 | whenAllInstalled {|node| |
| | 406 | NodeSet['receiver'].startApplications |
| | 407 | NodeSet['sender'].startApplications |
| | 408 | |
| | 409 | ########################################### |
| | 410 | # Run for 60 seconds |
| | 411 | ########################################### |
| | 412 | wait 60 |
| | 413 | |
| | 414 | ########################################### |
| | 415 | # Shutdown nodes |
| | 416 | ########################################### |
| | 417 | Experiment.done |
| | 418 | } |
| | 419 | |
| | 420 | }}} |