Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
M
mininet
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Requirements
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Locked files
Deploy
Releases
Package registry
Model registry
Operate
Terraform modules
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Olaf Bergmann
mininet
Commits
40580731
Commit
40580731
authored
15 years ago
by
Bob Lantz
Browse files
Options
Downloads
Patches
Plain Diff
Added simple all-to-all UDP bandwidth test.
parent
9bb15c76
No related branches found
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
examples/udpbwtest.c
+200
-0
200 additions, 0 deletions
examples/udpbwtest.c
examples/udpbwtest.py
+101
-0
101 additions, 0 deletions
examples/udpbwtest.py
with
301 additions
and
0 deletions
examples/udpbwtest.c
0 → 100644
+
200
−
0
View file @
40580731
/* udpbwtest: a simple bandwidth test
*
* To test all-to-all communication, we simply open up a
* UDP socket and repeat the following:
*
* 1. Send a packet to a random host if possible
* 2. Receive a packet if possible
* 3. Periodically report our I/O bandwidth
*
*/
#include
<stdio.h>
#include
<stdlib.h>
#include
<stdint.h>
#include
<strings.h>
#include
<sys/socket.h>
#include
<netinet/in.h>
#include
<arpa/inet.h>
#include
<assert.h>
#include
<sys/time.h>
#include
<poll.h>
#include
<signal.h>
enum
{
Port
=
12345
};
/* Handy utility functions */
int
bindAddr
(
int
fd
,
long
addr
,
u_short
port
)
{
/* Easy interface to bind */
struct
sockaddr_in
sa
;
bzero
(
&
sa
,
sizeof
(
sa
)
);
sa
.
sin_family
=
AF_INET
;
sa
.
sin_addr
.
s_addr
=
htonl
(
addr
);
sa
.
sin_port
=
htons
(
port
);
return
bind
(
fd
,
(
struct
sockaddr
*
)
&
sa
,
sizeof
(
sa
)
);
}
int
udpSocket
(
u_short
port
)
{
/* Easy interface to making a UDP socket */
int
fd
=
socket
(
AF_INET
,
SOCK_DGRAM
,
0
);
if
(
fd
<
0
)
{
return
fd
;
}
int
err
=
bindAddr
(
fd
,
INADDR_ANY
,
port
);
if
(
err
<
0
)
{
return
err
;
}
return
fd
;
}
ssize_t
sendBytes
(
int
sock
,
char
*
outbuf
,
size_t
bufsize
,
struct
in_addr
*
addr
,
u_short
port
)
{
/* Simpler sendto */
struct
sockaddr_in
sa
;
int
err
;
bzero
(
&
sa
,
sizeof
(
sa
)
);
sa
.
sin_family
=
AF_INET
;
sa
.
sin_addr
=
*
addr
;
sa
.
sin_port
=
htons
(
port
);
err
=
sendto
(
sock
,
outbuf
,
bufsize
,
0
,
(
const
struct
sockaddr
*
)
&
sa
,
sizeof
(
sa
)
);
if
(
err
<
0
)
{
perror
(
"sendto:"
);
}
return
err
;
}
ssize_t
recvBytes
(
int
sock
,
char
*
inbuf
,
size_t
bufsize
,
struct
in_addr
*
addr
)
{
/* Simpler recvfrom */
struct
sockaddr_in
sa
;
socklen_t
saLen
=
sizeof
(
sa
);
ssize_t
len
;
len
=
recvfrom
(
sock
,
inbuf
,
bufsize
,
0
,
(
struct
sockaddr
*
)
&
sa
,
&
saLen
);
if
(
len
>=
0
)
{
assert
(
saLen
==
sizeof
(
sa
)
);
*
addr
=
sa
.
sin_addr
;
}
else
{
perror
(
"recvfrom:"
);
}
return
len
;
}
int
readable
(
int
fd
)
{
/* Poll a single file descriptor for reading */
struct
pollfd
fds
=
{
fd
,
POLLIN
,
POLLIN
};
int
result
=
poll
(
&
fds
,
1
,
0
);
/* True if there is one readable descriptor */
return
(
result
==
1
);
}
int
writable
(
int
fd
)
{
/* Poll a single file descriptor for writing */
struct
pollfd
fds
=
{
fd
,
POLLOUT
,
POLLOUT
};
int
result
=
poll
(
&
fds
,
1
,
0
);
/* True if there is one writable descriptor */
return
(
result
==
1
);
}
int
poll1
(
int
fd
,
int
flags
,
int
ms
)
{
/* Call poll on a single descriptor */
struct
pollfd
fds
[]
=
{
{
fd
,
flags
,
0
}
};
return
poll
(
fds
,
1
,
ms
);
}
int
waitReadable
(
int
fd
,
int
ms
)
{
return
poll1
(
fd
,
POLLIN
,
ms
);
}
int
waitWritable
(
int
fd
,
int
ms
)
{
return
poll1
(
fd
,
POLLIN
,
ms
);
}
int
waitReadableOrWritable
(
int
fd
,
int
ms
)
{
return
poll1
(
fd
,
POLLIN
|
POLLOUT
,
ms
);
}
/* Timer support */
int
alarm
=
0
;
void
handleAlarm
(
int
sig
)
{
alarm
=
1
;
}
void
startTimer
(
int
seconds
)
{
struct
itimerval
v
;
v
.
it_interval
.
tv_sec
=
seconds
;
v
.
it_interval
.
tv_usec
=
0
;
v
.
it_value
=
v
.
it_interval
;
signal
(
SIGALRM
,
handleAlarm
);
setitimer
(
ITIMER_REAL
,
&
v
,
0
);
}
void
startOneSecondTimer
()
{
startTimer
(
1
);
}
void
stopTimer
()
{
struct
itimerval
v
;
bzero
(
&
v
,
sizeof
v
);
setitimer
(
ITIMER_REAL
,
&
v
,
0
);
}
/* Actual program */
void
bwtest
(
int
sock
,
struct
in_addr
*
hosts
,
int
hostCount
)
{
/* Test our bandwidth, by receiving whatever we get, and sending
* randomly to a set of hosts */
char
outbuf
[
1024
];
char
inbuf
[
1024
];
time_t
seconds
=
time
(
0
);
uint64_t
b
,
bytes
;
uint64_t
inbytes
=
0
,
outbytes
=
0
;
int
i
;
for
(
i
=
0
;
i
<
sizeof
(
outbuf
);
i
++
)
{
outbuf
[
i
]
=
i
%
255
;
}
while
(
1
)
{
size_t
addr_len
;
struct
in_addr
addr
=
hosts
[
random
()
%
hostCount
];
/* Wait until we have something to do. */
waitReadableOrWritable
(
sock
,
0
);
/* Receive some bytes */
for
(
b
=
0
;
b
<
10
&&
readable
(
sock
);
b
+=
1
)
{
bytes
=
recvBytes
(
sock
,
inbuf
,
sizeof
(
inbuf
),
&
addr
);
inbytes
+=
bytes
;
}
/* Send some bytes */
for
(
b
=
0
;
b
<
10
&&
writable
(
sock
);
b
+=
1
)
{
bytes
=
sendBytes
(
sock
,
outbuf
,
sizeof
(
outbuf
),
&
addr
,
Port
);
outbytes
+=
bytes
;
}
/* Periodically report bandwidth */
if
(
alarm
)
{
alarm
=
0
;
seconds
++
;
printf
(
"%d s: in %.2f Mbps, out %.2f Mbps
\n
"
,
seconds
,
8
.
0
*
inbytes
/
1e6
,
8
.
0
*
outbytes
/
1e6
);
fflush
(
stdout
);
inbytes
=
outbytes
=
0
;
}
}
}
int
main
(
int
argc
,
char
*
argv
[]
)
{
struct
in_addr
start
,
*
hosts
,
addr
;
int
count
,
sock
,
i
;
if
(
argc
<
2
)
{
fprintf
(
stderr
,
"usage: %s host...
\n
"
,
argv
[
0
]
);
exit
(
1
);
}
count
=
argc
-
1
;
hosts
=
(
struct
in_addr
*
)
malloc
(
count
*
sizeof
(
struct
in_addr
)
);
if
(
hosts
==
NULL
)
{
perror
(
"malloc:"
);
exit
(
1
);
}
for
(
i
=
0
;
i
<
count
;
i
++
)
inet_aton
(
argv
[
i
+
1
],
&
hosts
[
i
]
);
sock
=
udpSocket
(
Port
);
if
(
sock
<
0
)
{
perror
(
"udpSocket:"
);
exit
(
1
);
}
startOneSecondTimer
();
bwtest
(
sock
,
hosts
,
count
);
/* Never returns for now... */
stopTimer
();
}
This diff is collapsed.
Click to expand it.
examples/udpbwtest.py
0 → 100755
+
101
−
0
View file @
40580731
#!/usr/bin/python
"""
Create a tree network and run udpbwtest.c on it, attempting to
saturate global bandwidth by sending constant all-to-all
udp traffic. This should be something of a stress test.
We should also make a tcp version. :D
"""
import
select
,
sys
,
time
,
re
from
mininet
import
init
,
TreeNet
,
Cli
,
flush
,
quietRun
# Some useful stuff: buffered readline and host monitoring
def
readline
(
host
,
buffer
):
"
Read a line from a host, buffering with buffer.
"
buffer
+=
host
.
read
(
1024
)
if
'
\n
'
not
in
buffer
:
return
None
,
buffer
pos
=
buffer
.
find
(
'
\n
'
)
line
=
buffer
[
0
:
pos
]
rest
=
buffer
[
pos
+
1
:]
return
line
,
rest
def
monitor
(
hosts
,
seconds
):
"
Monitor a set of hosts and yield their output.
"
poller
=
select
.
poll
()
Node
=
hosts
[
0
]
# so we can call class method
buffers
=
{}
for
host
in
hosts
:
poller
.
register
(
host
.
stdout
)
buffers
[
host
]
=
''
quitTime
=
time
.
time
()
+
seconds
while
time
.
time
()
<
quitTime
:
ready
=
poller
.
poll
()
for
fd
,
event
in
ready
:
host
=
Node
.
fdToNode
(
fd
)
line
,
buffers
[
host
]
=
readline
(
host
,
buffers
[
host
]
)
if
line
:
yield
host
,
line
yield
None
,
''
# bwtest support
def
parsebwtest
(
line
,
r
=
re
.
compile
(
r
'
(\d+) s: in ([\d\.]+) Mbps, out ([\d\.]+) Mbps
'
)
):
match
=
r
.
match
(
line
)
return
match
.
group
(
1
,
2
,
3
)
if
match
else
(
None
,
None
,
None
)
def
printTotalHeader
():
print
print
"
time(s)
\t
hosts
\t
total in/out (Mbps)
\t
avg in/out (Mbps)
"
def
printTotal
(
time
=
None
,
result
=
None
):
intotal
=
outtotal
=
0.0
count
=
len
(
result
)
for
host
,
inbw
,
outbw
in
result
:
intotal
+=
inbw
outtotal
+=
outbw
inavg
=
intotal
/
count
if
count
>
0
else
0
outavg
=
outtotal
/
count
if
count
>
0
else
0
print
'
%d
\t
%d
\t
%.2f/%.2f
\t\t
%.2f/%.2f
'
%
(
time
,
count
,
intotal
,
outtotal
,
inavg
,
outavg
)
def
udpbwtest
(
controllers
,
switches
,
hosts
,
seconds
):
"
Start up and monitor udpbwtest on each of our hosts.
"
hostCount
=
len
(
hosts
)
print
"
*** Starting udpbwtest on hosts
"
for
host
in
hosts
:
ips
=
[
h
.
IP
()
for
h
in
hosts
if
h
!=
host
]
print
host
.
name
,
;
flush
()
host
.
cmd
(
'
./udpbwtest
'
+
'
'
.
join
(
ips
)
+
'
&
'
)
print
results
=
{}
print
"
*** Monitoring hosts
"
output
=
monitor
(
hosts
,
seconds
)
while
True
:
host
,
line
=
output
.
next
()
if
host
is
None
:
break
time
,
inbw
,
outbw
=
parsebwtest
(
line
)
if
time
is
not
None
:
time
,
inbw
,
outbw
=
int
(
time
),
float
(
inbw
),
float
(
outbw
)
result
=
results
.
get
(
time
,
[]
)
+
[
(
host
,
inbw
,
outbw
)
]
if
len
(
result
)
==
hostCount
:
printTotal
(
time
,
result
)
results
[
time
]
=
result
print
"
*** Stopping udpbwtest processes
"
# We *really* don't want these things hanging around!
quietRun
(
'
killall -9 udpbwtest
'
)
print
print
"
*** Results:
"
printTotalHeader
()
times
=
sorted
(
results
.
keys
()
)
for
time
in
times
:
printTotal
(
time
-
times
[
0
]
,
results
[
time
]
)
print
if
__name__
==
'
__main__
'
:
init
()
network
=
TreeNet
(
depth
=
2
,
fanout
=
8
,
kernel
=
True
)
def
test
(
c
,
s
,
h
):
return
udpbwtest
(
c
,
s
,
h
,
seconds
=
10
)
network
.
run
(
test
)
\ No newline at end of file
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment