NetStress: Difference between revisions

From RidgeRun Developer Wiki
No edit summary
 
(7 intermediate revisions by 2 users not shown)
Line 1: Line 1:
<seo title="NetStress | Command Line Utility | RidgeRun Developer" titlemode="replace" keywords="GStreamer, Linux SDK, Linux BSP,  Embedded Linux, Device Drivers, Nvidia, Xilinx, TI, NXP, Freescale, Embedded Linux driver development, Linux Software development, Embedded Linux SDK, Embedded Linux Application development, GStreamer Multimedia Framework."  description="Learn to test multimedia servers and client robustness with NetStress, a command line utility. Read more about network condition simulation now at RidgeRun."></seo>
==Overview==
==Overview==


Line 5: Line 7:
*Delay: Amount of milliseconds to delay samples.
*Delay: Amount of milliseconds to delay samples.
Both parameters apply in a bidirectional way, this is, for packets coming from the server and entering the client, and packets entering the server coming from the client.  
Both parameters apply in a bidirectional way, this is, for packets coming from the server and entering the client, and packets entering the server coming from the client.  




Line 15: Line 16:


  ~# netstress -h
  ~# netstress -h
  ~# netstress -a ip [-i interface] [-d delay] [-l loss] [-n | -o]
  ~# netstress -a ip [-i interface] [-d delay] [-l loss]  [-r rate] [-n | -o]  


===Arguments===
===Arguments===
Line 39: Line 40:
| -l
| -l
| Loss (%)
| Loss (%)
| Optional
|-
| -r
| Rate (bps)
| Optional
| Optional
|-
|-
Line 78: Line 83:


Copy this script into a file named netstress.sh and give it read and execution permissions
Copy this script into a file named netstress.sh and give it read and execution permissions
#!/bin/sh
 
<syntaxhighlight lang=bash lines=1>
LOSS=0%
#!/bin/sh
DELAY=0ms
 
INTERFACE=eth0
LOSS=0%
ADDRESS=0
DELAY=0ms
DIR="bi"
INTERFACE=eth0
ADDRESS=0
usage()
RATE=100Mbps
{
DIR="bi"
    cat <<EOF
 
This script simulates bad streaming conditions by dropping or delaying network packets streamed to a given port.
usage()
Root is the only user allowed to run this script
{
    cat <<EOF
Options:
This script simulates bad streaming conditions by dropping or delaying network packets streamed to a given port.
-h            : Prints this help
Root is the only user allowed to run this script
-i <interface> : Specifies the interface to be used on the simulation. Defaults to 'eth0'.  
 
-l <loss>      : Defines the percentage of packets to drop. Defaults to 0.
Options:
-d <delay>    : Defines the amount of miliseconds to delay packets. Defaults to 0.
-h            : Prints this help
-a <ipaddress> : Mandatory argument to specifies the ip address to apply the simulation to. The loss and delay will be applied to
-i <interface> : Specifies the interface to be used on the simulation. Defaults to 'eth0'.
                  the packets coming from and going to this address.
-l <loss>      : Defines the percentage of packets to drop. Defaults to 0.
-o            : Apply simulation to outgoing packets only. If neither -o or -i option is specified then simulation will be applied bidirectionaly.
-d <delay>    : Defines the amount of miliseconds to delay packets. Defaults to 0.
-n            : Apply simulation to incoming packets only. If neither -o or -i option is specified then simulation will be applied bidirectionaly.
-r <rate>      : Limits the bandwidth of the filter. Defaults to 100Mbps.
Examples:
-a <ipaddress> : Mandatory argument to specifies the ip address to apply the simulation to. The loss and delay will be applied to
                the packets coming from and going to this address.
Drop 1% of the packets received through a UDP stream at address 192.168.1.168 on both incoming and outgoing packets
-o            : Apply simulation to outgoing packets only. If neither -o or -i option is specified then simulation will be applied bidirectionaly.
  ~# netstress -l 1 -a 192.168.1.168
-n            : Apply simulation to incoming packets only. If neither -o or -i option is specified then simulation will be applied bidirectionaly.
Examples:
Drop 10% of the outgoing packets and apply a delay of 5ms of a RTSP stream from device 10.251.101.135 received using the eth1 interface.
 
  ~# netstress -l 10 -d 5 -i eth1 -a 10.251.101.135 -o
Drop 1% of the packets received through a UDP stream at address 192.168.1.168 on both incoming and outgoing packets
  ~# netstress -l 1 -a 192.168.1.168
Erase all the simulations applied to the interface 'eth1'
 
  ~# netstress -i eth1
Drop 10% of the outgoing packets and apply a delay of 5ms of a RTSP stream from device 10.251.101.135 received using the eth1 interface.
  ~# netstress -l 10 -d 5 -i eth1 -a 10.251.101.135 -o
Erase all the simulations applied to the default interface 'eth0'
 
  ~# netstress  
Erase all the simulations applied to the interface 'eth1'
  ~# netstress -i eth1
Copyright (c) RidgeRun 2013
 
Michael Gruner <michael.gruner@ridgerun.com>
Erase all the simulations applied to the default interface 'eth0'
EOF
  ~# netstress
}
 
Copyright (c) RidgeRun 2013
logerror()
Michael Gruner <michael.gruner@ridgerun.com>
{
EOF
    echo "NetStress: error: $1" 1>&2  
}
    exit 1
 
}
logerror()
{
parseop()
    echo "NetStress: error: $1" 1>&2
{
    exit 1
    while getopts "honi:l:d:a:" OP
}
    do
 
case $OP in
parseop()
    h)
{
usage
  while getopts "honi:l:d:a:r:" OP
exit 0
    do
;;
    case $OP in
   
        h)
    i)
        usage
INTERFACE=$OPTARG
        exit 0
;;
        ;;
   
 
    l)
        i)
LOSS="$OPTARG"%  
        INTERFACE=$OPTARG
;;
        ;;
   
 
    d)
        l)
DELAY="$OPTARG"ms
        LOSS="$OPTARG"%
;;
        ;;
    a)
 
ADDRESS=$OPTARG
        r)
;;
        RATE="$OPTARG"
    o)
        ;;
DIR="out"
 
;;
        d)
    n)
        DELAY="$OPTARG"ms
DIR="in"
        ;;
;;
        a)
        ADDRESS=$OPTARG
    *)
        ;;
usage
        o)
exit 1
        DIR="out"
;;
        ;;
esac
        n)
    done
        DIR="in"
}
        ;;
 
redirecttraffic()
        *)
{
        usage
    # Insert the module if not already
        exit 1
    modprobe ifb
        ;;
    ip link set dev ifb0 up
    esac
    done
    # Grab the incomming packets and redirect them to ifb0
}
    tc qdisc del dev $INTERFACE ingress 2>/dev/null || echo ""
 
    tc qdisc add dev $INTERFACE ingress
redirecttraffic()
{
    # Redirect to ifb0
    # Insert the module if not already
    tc filter add dev $INTERFACE parent ffff: \
    modprobe ifb
protocol ip u32 match u32 0 0 \
    ip link set dev ifb0 up
action mirred egress redirect dev ifb0  
 
}
    # Grab the incomming packets and redirect them to ifb0
    tc qdisc del dev $INTERFACE ingress 2>/dev/null || echo ""
createtree()
    tc qdisc add dev $INTERFACE ingress
{
 
    # Tree layout
    # Redirect to ifb0
    #
    tc filter add dev $INTERFACE parent ffff: \
    #        Ingress 1:0 (ifb0)        Egress 2:0 (eth0)
    protocol ip u32 match u32 0 0 \
    #                |                        |
    action mirred egress redirect dev ifb0
    #            Class 1:1                Class 2:1
}
    #                |                        |
 
    #        (Attach netem leaf)      (Attach netem leaf)  
createtree()
    #
{
   
    # Tree layout
    # Root of the tree for all the non-filtered input packets
    #
    tc qdisc add dev ifb0 root handle 1: htb
    #        Ingress 1:0 (ifb0)        Egress 2:0 (eth0)
    #                |                        |
    # Create a class to attach the filter. Netem leafs can attach to this class
    #            Class 1:1                Class 2:1
    tc class add dev ifb0 parent 1: classid 1:1 htb rate 100Mbps
    #                |                        |
    #        (Attach netem leaf)      (Attach netem leaf)
    # Root of the tree for all the non-filtered ouput packets
    #
    tc qdisc add dev $INTERFACE root handle 2: htb
 
    # Root of the tree for all the non-filtered input packets
    # Create a class to attach the filter. Netem leafs can attach to this class
    tc qdisc add dev ifb0 root handle 1: htb
    tc class add dev $INTERFACE parent 2: classid 2:1 htb rate 100Mbps
 
}
    # Create a class to attach the filter. Netem leafs can attach to this class
    tc class add dev ifb0 parent 1: classid 1:1 htb rate 100Mbps
applyrules()
 
{
    # Root of the tree for all the non-filtered ouput packets
    echo -n "Aplying rules..."
    tc qdisc add dev $INTERFACE root handle 2: htb
    # Input packets
 
    tc qdisc add dev ifb0 parent 1:1 handle 10: netem delay $DELAY loss $LOSS || \
    # Create a class to attach the filter. Netem leafs can attach to this class
logerror "Failed to apply rules"
    tc class add dev $INTERFACE parent 2: classid 2:1 htb rate 100Mbps
    # Output packets
}
    tc qdisc add dev $INTERFACE parent 2:1 handle 20: netem delay $DELAY loss $LOSS || \
 
logerror "Failed to apply rules"
applyrules()
    echo " done!"
{
}
    echo -n "Applying rules..."
    # Input packets
applyfilter()
    tc qdisc add dev ifb0 parent 1:1 handle 10: netem delay $DELAY rate $RATE || \
{
    logerror "Failed to apply rules"
    echo -n "Aplying filters..."
    # Output packets
    #Incoming packets
    tc qdisc add dev $INTERFACE parent 2:1 handle 20: netem delay $DELAY rate $RATE || \
    if [ $DIR != "out" ]; then
    logerror "Failed to apply rules"
tc filter add dev ifb0 protocol ip parent 1: prio 3 u32 match ip src $ADDRESS flowid 1:1
    echo " done!"
    fi
}
 
    #Outgoing packets
applyfilter()
    if [ $DIR != "in" ]; then
{
tc filter add dev $INTERFACE protocol ip parent 2: prio 3 u32 match ip dst $ADDRESS flowid 2:1
    echo -n "Applying filters..."
    fi
    #Incoming packets
    echo " done!"
    if [ $DIR != "out" ]; then
}
    tc filter add dev ifb0 protocol ip parent 1: prio 3 u32 match ip src $ADDRESS flowid 1:1
    fi
checkroot()
 
{
    #Outgoing packets
    if [ "root" != `whoami` ]; then
    if [ $DIR != "in" ]; then
logerror "Only root is allowed to run this script!"
    tc filter add dev $INTERFACE protocol ip parent 2: prio 3 u32 match ip dst $ADDRESS flowid 2:1
    fi
    fi
}
    echo " done!"
}
stopsimulation()
 
{
checkroot()
    echo -n "Stopping simulation at interface $INTERFACE..."
{
   
    if [ "root" != `whoami` ]; then
    # Avoid any problems if there was no simulation running  
    logerror "Only root is allowed to run this script!"
    tc qdisc del dev $INTERFACE ingress 2>/dev/null || echo -n ""
    fi
    tc qdisc del dev $INTERFACE root 2>/dev/null || echo -n ""
}
    tc qdisc del dev ifb0 root 2>/dev/null || echo -n ""
 
stopsimulation()
    echo " done!"
{
}
    echo -n "Stopping simulation at interface $INTERFACE..."
 
main()
    # Avoid any problems if there was no simulation running
{
    tc qdisc del dev $INTERFACE ingress 2>/dev/null || echo -n ""
    #Parse the options passed through the cmdline
    tc qdisc del dev $INTERFACE root 2>/dev/null || echo -n ""
    parseop $@
    tc qdisc del dev ifb0 root 2>/dev/null || echo -n ""
   
 
    #Check that the user is root
    echo " done!"
    checkroot
}
 
    stopsimulation
main()
{
    #Check if user wants to erase all rules  
    #Parse the options passed through the cmdline
    if [[ $LOSS ==  "0%" && $DELAY == "0ms" ]]; then
    parseop $@
exit 0
 
    fi
    #Check that the user is root
    checkroot
    #Ip is a mandatory argument
 
    if [[ $ADDRESS == "0" ]]; then
    stopsimulation
logerror "Ip address is a mandatory parameter"
 
    fi
    #Check if user wants to erase all rules
      
    if [ x$LOSS =  "x0%" ] && [ x$DELAY = "x0ms" ] && [ x$RATE = "x100Mbps" ]; then
    echo "Simulation configured to"
    exit 0
    echo -e "\tInterface: $INTERFACE"
    fi
    echo -e "\tLoss: $LOSS"
 
    echo -e "\tDelay: $DELAY"
    #Ip is a mandatory argument
    echo -e "\tAddress: $ADDRESS"
    if [ x$ADDRESS = "x0" ]; then
    logerror "Ip address is a mandatory parameter"
    fi
    redirecttraffic
 
    createtree
     echo "Simulation configured to"
    applyrules
    echo -e "\tInterface: $INTERFACE"
    applyfilter
    echo -e "\tLoss: $LOSS"
}
    echo -e "\tDelay: $DELAY"
    echo -e "\tAddress: $ADDRESS"
#Calling starting point
 
main $@
 
    redirecttraffic
    createtree
    applyrules
    applyfilter
}
 
#Calling starting point
main $@
</syntaxhighlight>


==Known Limitations==
==Known Limitations==
Line 293: Line 307:


==Support==
==Support==
Michael Gruner <michael.gruner@ridgerun.com>
If you have any questions please [http://www.ridgerun.com/contact/ '''contact us'''] or email to [mailto:support@ridgerun.com '''support@ridgerun.com'''].   
 




[[Category:HowTo]]
[[Category:HowTo]][[Category:Tools]]

Latest revision as of 16:50, 10 July 2019


Overview

NetStress is a command line utility that simulates bad network conditions for multiple kinds of streaming. It is meant for testing multimedia server and client robustness by stressing the transmission channel. To do so NetStress provides two different packet modeling:

  • Loss: Percentage in which the packets are randomly dropped. For a 1% loss: 1 of 100 packets is dropped randomly.
  • Delay: Amount of milliseconds to delay samples.

Both parameters apply in a bidirectional way, this is, for packets coming from the server and entering the client, and packets entering the server coming from the client.


Dependencies

NetStress is based on GNU/Linux traffic control (tc). This tool is distributed as part of the iproute package.

Basic Usage

~# netstress -h
~# netstress -a ip [-i interface] [-d delay] [-l loss]  [-r rate] [-n | -o] 

Arguments

Argument Purpose Nature
-h Help Optional
-a IP address Mandatory
-d Delay (ms) Optional
-l Loss (%) Optional
-r Rate (bps) Optional
-i interface (defaults to eth0) Optional
-n Apply to input packtets* Optional
-o Apply to output packets* Optional
  • If neither input (-n) or output (-o) are specified packets are filtered bidirectionally.

Adding packet delay

To add a 10ms delay to every packet sent and received from a RTSP stream produced by a device with IP address: 192.168.1.58

~# netstress -d 10 -a 192.168.1.58

Adding packet loss

To add a 5% loss to every packet sent and received from an UPD stream produced by a device with IP address: 10.251.101.66

~# netstress -l 5 -a 10.251.101.66

Adding packet delay and loss

To add a 1% loss and 20ms delay to every packet sent and received from a RTP stream produced by a device with IP address: 10.251.101.146

~# netstress -l 1 -d 20 -a 10.251.101.146

Clearing up simulation

To clear up any current configured simulation

~# netstress

Download

Copy this script into a file named netstress.sh and give it read and execution permissions

#!/bin/sh

LOSS=0%
DELAY=0ms
INTERFACE=eth0
ADDRESS=0
RATE=100Mbps
DIR="bi"

usage()
{
    cat <<EOF
This script simulates bad streaming conditions by dropping or delaying network packets streamed to a given port.
Root is the only user allowed to run this script

Options:
-h             : Prints this help
-i <interface> : Specifies the interface to be used on the simulation. Defaults to 'eth0'.
-l <loss>      : Defines the percentage of packets to drop. Defaults to 0.
-d <delay>     : Defines the amount of miliseconds to delay packets. Defaults to 0.
-r <rate>      : Limits the bandwidth of the filter. Defaults to 100Mbps.
-a <ipaddress> : Mandatory argument to specifies the ip address to apply the simulation to. The loss and delay will be applied to
                 the packets coming from and going to this address.
-o             : Apply simulation to outgoing packets only. If neither -o or -i option is specified then simulation will be applied bidirectionaly.
-n             : Apply simulation to incoming packets only. If neither -o or -i option is specified then simulation will be applied bidirectionaly.
Examples:

Drop 1% of the packets received through a UDP stream at address 192.168.1.168 on both incoming and outgoing packets
  ~# netstress -l 1 -a 192.168.1.168

Drop 10% of the outgoing packets and apply a delay of 5ms of a RTSP stream from device 10.251.101.135 received using the eth1 interface.
  ~# netstress -l 10 -d 5 -i eth1 -a 10.251.101.135 -o

Erase all the simulations applied to the interface 'eth1'
  ~# netstress -i eth1

Erase all the simulations applied to the default interface 'eth0'
  ~# netstress

Copyright (c) RidgeRun 2013
Michael Gruner <michael.gruner@ridgerun.com>
EOF
}

logerror()
{
    echo "NetStress: error: $1" 1>&2
    exit 1
}

parseop()
{
   while getopts "honi:l:d:a:r:" OP
    do
    case $OP in
        h)
        usage
        exit 0
        ;;

        i)
        INTERFACE=$OPTARG
        ;;

        l)
        LOSS="$OPTARG"%
        ;;

        r)
        RATE="$OPTARG"
        ;;

        d)
        DELAY="$OPTARG"ms
        ;;
        a)
        ADDRESS=$OPTARG
        ;;
        o)
        DIR="out"
        ;;
        n)
        DIR="in"
        ;;

        *)
        usage
        exit 1
        ;;
    esac
    done
}

redirecttraffic()
{
    # Insert the module if not already
    modprobe ifb
    ip link set dev ifb0 up

    # Grab the incomming packets and redirect them to ifb0
    tc qdisc del dev $INTERFACE ingress 2>/dev/null || echo ""
    tc qdisc add dev $INTERFACE ingress

    # Redirect to ifb0
    tc filter add dev $INTERFACE parent ffff: \
    protocol ip u32 match u32 0 0 \
    action mirred egress redirect dev ifb0
}

createtree()
{
    # Tree layout
    #
    #         Ingress 1:0 (ifb0)        Egress 2:0 (eth0)
    #                 |                        |
    #            Class 1:1                 Class 2:1
    #                 |                        |
    #         (Attach netem leaf)      (Attach netem leaf)
    #

    # Root of the tree for all the non-filtered input packets
    tc qdisc add dev ifb0 root handle 1: htb

    # Create a class to attach the filter. Netem leafs can attach to this class
    tc class add dev ifb0 parent 1: classid 1:1 htb rate 100Mbps

    # Root of the tree for all the non-filtered ouput packets
    tc qdisc add dev $INTERFACE root handle 2: htb

    # Create a class to attach the filter. Netem leafs can attach to this class
    tc class add dev $INTERFACE parent 2: classid 2:1 htb rate 100Mbps
}

applyrules()
{
    echo -n "Applying rules..."
    # Input packets
    tc qdisc add dev ifb0 parent 1:1 handle 10: netem delay $DELAY rate $RATE || \
    logerror "Failed to apply rules"
    # Output packets
    tc qdisc add dev $INTERFACE parent 2:1 handle 20: netem delay $DELAY rate $RATE || \
    logerror "Failed to apply rules"
    echo " done!"
}

applyfilter()
{
    echo -n "Applying filters..."
    #Incoming packets
    if [ $DIR != "out" ]; then
    tc filter add dev ifb0 protocol ip parent 1: prio 3 u32 match ip src $ADDRESS flowid 1:1
    fi

    #Outgoing packets
    if [ $DIR != "in" ]; then
    tc filter add dev $INTERFACE protocol ip parent 2: prio 3 u32 match ip dst $ADDRESS flowid 2:1
    fi
    echo " done!"
}

checkroot()
{
    if [ "root" != `whoami` ]; then
    logerror "Only root is allowed to run this script!"
    fi
}

stopsimulation()
{
    echo -n "Stopping simulation at interface $INTERFACE..."

    # Avoid any problems if there was no simulation running
    tc qdisc del dev $INTERFACE ingress 2>/dev/null || echo -n ""
    tc qdisc del dev $INTERFACE root 2>/dev/null || echo -n ""
    tc qdisc del dev ifb0 root 2>/dev/null || echo -n ""

    echo " done!"
}

main()
{
    #Parse the options passed through the cmdline
    parseop $@

    #Check that the user is root
    checkroot

    stopsimulation

    #Check if user wants to erase all rules
    if [ x$LOSS =  "x0%" ] && [ x$DELAY = "x0ms" ] && [ x$RATE = "x100Mbps" ]; then
    exit 0
    fi

    #Ip is a mandatory argument
    if [ x$ADDRESS = "x0" ]; then
    logerror "Ip address is a mandatory parameter"
    fi

    echo "Simulation configured to"
    echo -e "\tInterface: $INTERFACE"
    echo -e "\tLoss: $LOSS"
    echo -e "\tDelay: $DELAY"
    echo -e "\tAddress: $ADDRESS"


    redirecttraffic
    createtree
    applyrules
    applyfilter
}

#Calling starting point
main $@

Known Limitations

  • Only one IP address can be filtered at a time.
  • Port filtering is not supported yet


Support

If you have any questions please contact us or email to support@ridgerun.com.