TCP incast

This article will show you how to reproduce TCP incast using a virtual network at an end host.

1. Topology

topology.jpg
  • VM1, VM2 and VM3 are clients (sender) and VM5 is a server (receiver). VM4 play the role of switch and you can realize your NF at it.
  • start up the topology
#createVnet.sh
sudo ovs-vsctl add-br mgmt
echo "create mgmt"
sudo ovs-vsctl add-br exp_1
echo "create exp_1"
sudo ovs-vsctl add-br exp_2
echo "create exp_2"

#clear NAT
#sudo ifconfig docker0 down
sudo iptables -F
sudo iptables -P INPUT ACCEPT
sudo iptables -P FORWARD ACCEPT

sudo ifconfig mgmt 100.0.0.1/24 up
#sudo ifconfig exp_1 up
#sudo ifconfig exp_2 up

echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A POSTROUTING -s 100.0.0.0/24 ! -d 100.0.0.0/24 -j MASQUERADE
#iptables -nvL

#sudo virsh create /etc/libvirt/qemu/vm0.xml
#sudo virsh create /etc/libvirt/qemu/vm1.xml
#sudo virsh create /etc/libvirt/qemu/vm2.xml

sudo virsh start vm1
sudo virsh start vm2
sudo virsh start vm3
sudo virsh start vm4
sudo virsh start vm5

#ovs-dpctl show
#sudo ovs-ofctl add-flow exp in_port=1,action=output:2
#sudo ovs-ofctl add-flow exp in_port=3,action=output:4
#sudo ovs-ofctl add-flow exp in_port=4,action=output:1

echo "finished!"

  • destroy the virtual network
#destroyVnet.sh
sudo virsh destroy vm1
sudo virsh destroy vm2
sudo virsh destroy vm3
sudo virsh destroy vm4
sudo virsh destroy vm5

sudo ovs-vsctl del-br mgmt
echo "delete mgmt"
sudo ovs-vsctl del-br exp_1
echo "delete exp_1"
sudo ovs-vsctl del-br exp_2
echo "delete exp_2"

2. Incast

#!/bin/bash

protocol=("reno")
ip_arr=(10 20 30)
flow_arr=(1 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30)
#flow_arr=(1 2 4)


ssh_func()
{
    # ${1}: protocol  ${2}: ip  ${3}: flow number

    sshpass -p 1234 ssh [email protected].${2} > /dev/null 2>&1 << eeooff
    #sudo sysctl -w net.ipv4.tcp_ecn=1
    #sudo sysctl -w net.ipv4.tcp_congestion_control=${1}
    iperf -c 10.0.0.50 -n 64K -P ${3} > /home/ubuntu/Desktop/iperf_${1}_${3}.txt
    #iperf -c 10.0.0.50 -i 1 -t 5 > /home/ubuntu/Desktop/iperf_${1}_${3}.txt
    exit
eeooff
}

ssh_server()
{
    sshpass -p 1234 ssh [email protected] > /dev/null 2>&1 << eeooff
    #sudo sysctl -w net.ipv4.tcp_ecn=1
    #sudo sysctl -w net.ipv4.tcp_congestion_control=${1}
    timeout -s SIGINT 3 iperf -s > /home/ubuntu/Desktop/iperf_${1}_${3}.txt 
    exit 
eeooff
}

for proto in ${protocol[@]}
do
    for flow in ${flow_arr[@]}
    do 
        echo "protocol : "${proto}    "    flow number : "${flow}
        #ssh_server ${proto} ${ip} ${flow} &      # 3 seconds   
        #sleep 1
        for ip in ${ip_arr[@]}
        do 
            #echo ${proto} 10.0.0.${ip} ${flow}
            ssh_func ${proto} ${ip} ${flow} &        # 64K 10Gbps
        done 
        echo ""
        sleep 4
    done
    echo ""
done

echo "done!!!"
exit 0

3. Results

#!/usr/bin/python3
# -*- coding: UTF-8 -*-

import re
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
from matplotlib.backends.backend_pdf import PdfPages
from pylab import *
import matplotlib.gridspec as gridspec

def read_iperf(path):
    with open(path,'r') as iperf:
        for line in iperf.readlines():
            matchobj = re.search(r'\[.*\]',line,re.M|re.I)
            if matchobj:
                if re.search(r'SUM',line,re.M|re.I):
                    temp_1 = re.search(r'Bytes .* Mbits/sec',line,re.M|re.I)
                    temp_2 = re.search(r'Bytes .* Gbits/sec',line,re.M|re.I)
                    if temp_1:
                        aList = re.split(r'\s+',temp_1.group())
                        return float(aList[1])/1000
                    elif temp_2:
                        aList = re.split(r'\s+',temp_2.group())
                        return float(aList[1])

def path_gen():
    dir_path = "/Users/yche/Desktop/results/"
    folders  = ["client_10","client_20","client_30"]
    flow_num = [2*i + 2 for i in range(15)]
    protos   = ["dctcp","cubic","reno","reno_ecn_off"]

    tput_list= []

    for p in protos:
        put_temp = []
        for flow in flow_num:
            good_put = 0
            for folder in folders:
                path = dir_path + folder + "/iperf_" + p + "_" + str(flow) + ".txt"
                good_put = good_put + read_iperf(path)
                #print (path)
            put_temp.append(good_put)
        tput_list.append(put_temp)

    for item in tput_list:
        print(item)

    return tput_list

def plot(good_put):
    patterns = ['b*-','g+-','cx-',"md-"]
    legends  = ["DCTCP","CUBIC","RENO","RENO (NO ECN)"]

    dctcp        = good_put[0]
    cubic        = good_put[1]
    reno         = good_put[2]
    reno_ecn_off = good_put[3]

    plt.figure(figsize=(6,3))
    ax = plt.subplot(1,1,1)

    x_data = [2*i+2 for i in range(len(dctcp))]
    #print(x_data)

    ax.plot(x_data,dctcp,patterns[0],label=legends[0])
    ax.plot(x_data,cubic,patterns[1],label=legends[1])
    ax.plot(x_data,reno,patterns[2],label=legends[2])
    ax.plot(x_data,reno_ecn_off,patterns[3],label=legends[3])
    
    ax.set_xlim(-1,31)
    ax.set_ylim(0,10)
    ax.set_xlabel("Number of senders in parallel")
    ax.set_ylabel("goodput (Gbps)")
    ax.yaxis.grid(True)

    plt.legend(loc=0,prop={'size': 10})

    plt.tight_layout()
    pp = PdfPages("/Users/yche/Desktop/results/incast.pdf")
    pp.savefig()
    pp.close()

if __name__ == '__main__':
    good_put = path_gen()
    plot(good_put)
incast.jpg

你可能感兴趣的:(TCP incast)