在mininet下设计网络拓扑、性能评价以及Linux内核修改、编译


https://blog.csdn.net/qq_45880533/article/details/112230039
https://blog.csdn.net/asddasads/article/details/110678627
https://blog.csdn.net/asddasads/article/details/110678705
https://blog.csdn.net/u010643777/article/details/81352481

前言

在网络领域,大多数情况下做的实验都是基于ns2、ns3等仿真软件。这些软件是在应用层上模拟了一套网络协议,算是在应用层实现的,而mininet使用的网络协议是基于内核的,更关注网络拓扑本身,要想修改协议进行网络测试,直接到内核级别进行更改,更有现实意义


一、mininet简单使用

在Linux平台上安装好mininet之后,可以通过终端使用,官方也支持python API,更方便的进行编码。

使用mininet创建一个拓扑结构

# 创建一个简单拓扑,h1--s1--h2
sudo mn --topo=minimal
# 测试网络性能
# h1开启iperf,-s:服务端,-p 端口号 -i
# 令主机h1为服务器,使用端口为5566,并且每隔一秒监视一次,在后台运行
h1 iperf -s -p 5566 -i 1 &
# 令主机h2为客户端,使用端口5566,并且每隔一秒监视一次,共持续15s,我们可以看见每隔一秒钟,会报告一次当前的网络状况,同时会在最后统计15秒内的网络情况
h2 iperf -c 10.0.0.1 -p 5566 -t 15 -i 1

二、关于系统变量控制的相关命令

# 设置系统控制变量(sysctl): -w 临时改变
sysctl -w net.mptcp.[name of the wariable]=[value]

# 当前内核可以使用的tcp拥塞控制算法
sysctl net.ipv4.tcp_available_congestion_control
# 当前内核正在使用的tcp拥塞控制算法
sysctl net.ipv4.tcp_congestion_control
# 更改tcp拥塞控制算法(更改为reno)
sysctl net.ipv4.tcp_congestion_control=reno
# 检查是否内核有没有开启mptcp协议
sudo sysctl -a | grep mptcp
# 确认mptcp内核版本号
dmesg | grep MPTCP

三、基于mininet的实验

1、小试牛刀——使用mininal拓扑

关闭mptcp选项,测试tcp协议的一些性能参数

sudo sysctl -a | grep mptcp

图1

sudo sysctl net.mptcp.mptcp_enabled=0

图2
查看当前tcp拥塞控制协议

sudo sysctl net.ipv4.tcp_congestion_control

图3

⬆️当前tcp协议的拥塞控制算法为balia
使用mininet创建minimal网络拓扑,并测试(依次输入以下命令)

sudo mn --topo=minimal
h1 iperf -s -p 5566 -i 1 &
h2 iperf -c 10.0.0.1 -p 5566 -t 15 -i 1

图4

⬆️由上图课件,当前校园网下网络拓扑为minimal,拥塞控制协议为balia,15s传输了74.4GBytes的数据。
更换拥塞控制协议,继续测量。
查看当前系统可以使用的tcp拥塞控制算法

sysctl net.ipv4.tcp_available_congestion_control

图5
⬆️reno bbr cubic lia olia wvegas balia mctcpdesync
更改拥塞控制算法为cubic,测量方式如上
图6

⬆️由上图可见,当前校园网下网络拓扑为minimal,拥塞控制协议为cubic,15s传输了77.3GBytes的数据。
一次测量数据具有偶然性,可以测量多次取平均值。(我实际测量,相同算法每次测量结果基本一致)
按照上述方法,可以设置拥塞控制算法,设计拓扑图,测量数据传输的效果。

2、自定义拓扑

拓扑1

mininet除了使用terminal进行控制之外,还支持python API,对于相对复杂的拓扑结构,我们使用python编程设计,然后执行更方便。
MPTCP协议在mininet中的性能测试
拓扑结构如下:
网络拓扑图

编写拓补脚本,mptcp-example1.py,启动iperf软件,可以测量节点间的带宽。(以下代码是python2的代码)

#!/usr/bin/env python
from mininet.net import Mininet
from mininet.cli import CLI
from mininet.link import Link, TCLink,Intf
from subprocess import Popen, PIPE
from mininet.log import setLogLevel
 
if '__main__' == __name__:
  setLogLevel('info')
  net = Mininet(link=TCLink)
  key = "net.mptcp.mptcp_enabled"
  value = 1
  p = Popen("sysctl -w %s=%s" % (key, value), shell=True, stdout=PIPE, stderr=PIPE)
  stdout, stderr = p.communicate()
  print "stdout=",stdout,"stderr=", stderr
  h1 = net.addHost('h1')
  h2 = net.addHost('h2')
  r1 = net.addHost('r1')
  linkopt={'bw':10}
  net.addLink(r1,h1,cls=TCLink, **linkopt)
  net.addLink(r1,h1,cls=TCLink, **linkopt)
  net.addLink(r1,h2,cls=TCLink, **linkopt)
  net.addLink(r1,h2,cls=TCLink, **linkopt)
  net.build()
  r1.cmd("ifconfig r1-eth0 0")
  r1.cmd("ifconfig r1-eth1 0")
  r1.cmd("ifconfig r1-eth2 0")
  r1.cmd("ifconfig r1-eth3 0")
  h1.cmd("ifconfig h1-eth0 0")
  h1.cmd("ifconfig h1-eth1 0")
  h2.cmd("ifconfig h2-eth0 0")
  h2.cmd("ifconfig h2-eth1 0")
  r1.cmd("echo 1 > /proc/sys/net/ipv4/ip_forward")
  r1.cmd("ifconfig r1-eth0 10.0.0.1 netmask 255.255.255.0")
  r1.cmd("ifconfig r1-eth1 10.0.1.1 netmask 255.255.255.0")
  r1.cmd("ifconfig r1-eth2 10.0.2.1 netmask 255.255.255.0")
  r1.cmd("ifconfig r1-eth3 10.0.3.1 netmask 255.255.255.0")
  h1.cmd("ifconfig h1-eth0 10.0.0.2 netmask 255.255.255.0")
  h1.cmd("ifconfig h1-eth1 10.0.1.2 netmask 255.255.255.0")
  h2.cmd("ifconfig h2-eth0 10.0.2.2 netmask 255.255.255.0")
  h2.cmd("ifconfig h2-eth1 10.0.3.2 netmask 255.255.255.0")
  h1.cmd("ip rule add from 10.0.0.2 table 1")
  h1.cmd("ip rule add from 10.0.1.2 table 2")
  h1.cmd("ip route add 10.0.0.0/24 dev h1-eth0 scope link table 1")
  h1.cmd("ip route add default via 10.0.0.1 dev h1-eth0 table 1")
  h1.cmd("ip route add 10.0.1.0/24 dev h1-eth1 scope link table 2")
  h1.cmd("ip route add default via 10.0.1.1 dev h1-eth1 table 2")
  h1.cmd("ip route add default scope global nexthop via 10.0.0.1 dev h1-eth0")
  h2.cmd("ip rule add from 10.0.2.2 table 1")
  h2.cmd("ip rule add from 10.0.3.2 table 2")
  h2.cmd("ip route add 10.0.2.0/24 dev h2-eth0 scope link table 1")
  h2.cmd("ip route add default via 10.0.2.1 dev h2-eth0 table 1")
  h2.cmd("ip route add 10.0.3.0/24 dev h2-eth1 scope link table 2")
  h2.cmd("ip route add default via 10.0.3.1 dev h2-eth1 table 2")
  h2.cmd("ip route add default scope global nexthop via 10.0.2.1 dev h2-eth0")
  CLI(net)
  net.stop()

执行命令

sudo python mptcp-example1.py

启动h1,h2两个终端窗口

mininet>xterm h1 h2

首先在h2中输入:

iperf -s -i 1

接着在h1中输入:

iperf -c 10.0.2.2 -t 10 -i 1

代码中value的值控制mptcp的开启和关闭,1为开启,0为关闭。效果图如下:
图7
图8

拓扑2

拓扑2
python代码:

#!/usr/bin/env python
from mininet.net import Mininet
from mininet.cli import CLI
from mininet.link import Link, TCLink, Intf
from subprocess import Popen, PIPE
from mininet.log import setLogLevel
import sys

if '__main__' == __name__:
    # 处理命令行参数

    value = 1
    if len(sys.argv) > 2:
        value = int(sys.argv[1])

    setLogLevel('info')
    net = Mininet(link=TCLink)
    key = "net.mptcp.mptcp_enabled"
    p = Popen("sysctl -w %s=%s" % (key, value), shell=True, stdout=PIPE, stderr=PIPE)
    stdout, stderr = p.communicate()
    print("stdout=", stdout, "stderr=", stderr)

    h1 = net.addHost('h1')
    h2 = net.addHost('h2')
    h3 = net.addHost('h3')
    r1 = net.addHost('r1')
    r2 = net.addHost('r2')
    # 设置链路带宽
    linkopt = {'bw': 10}

    # 总共有五条链路
    #           r1
    #    h1              h2
    #           r2
    #
    #           h3
    net.addLink(r1, h1, cls=TCLink, **linkopt)
    net.addLink(r1, h2, cls=TCLink, **linkopt)
    net.addLink(r2, h1, cls=TCLink, **linkopt)
    net.addLink(r2, h2, cls=TCLink, **linkopt)
    net.addLink(r2, h3, cls=TCLink, **linkopt)

    net.build()
    # 配置路由器r1两个端口
    r1.cmd("ifconfig r1-eth0 0")
    r1.cmd("ifconfig r1-eth1 0")

    # 配置路由器r2三个端口
    r2.cmd("ifconfig r2-eth0 0")
    r2.cmd("ifconfig r2-eth1 0")
    r2.cmd("ifconfig r2-eth2 0")

    h1.cmd("ifconfig h1-eth0 0")
    h1.cmd("ifconfig h1-eth1 0")
    h2.cmd("ifconfig h2-eth0 0")
    h2.cmd("ifconfig h2-eth1 0")
    h3.cmd("ifconfig h3-eth0 0")

    r1.cmd("echo 1 > /proc/sys/net/ipv4/ip_forward")
    r2.cmd("echo 1 > /proc/sys/net/ipv4/ip_forward")
    r1.cmd("ifconfig r1-eth0 10.0.0.1 netmask 255.255.255.0")
    r1.cmd("ifconfig r1-eth1 10.0.1.1 netmask 255.255.255.0")
    r2.cmd("ifconfig r2-eth0 10.0.2.1 netmask 255.255.255.0")
    r2.cmd("ifconfig r2-eth1 10.0.3.1 netmask 255.255.255.0")
    r2.cmd("ifconfig r2-eth2 10.0.4.1 netmask 255.255.255.0")

    h1.cmd("ifconfig h1-eth0 10.0.0.2 netmask 255.255.255.0")
    h1.cmd("ifconfig h1-eth1 10.0.2.2 netmask 255.255.255.0")
    h2.cmd("ifconfig h2-eth0 10.0.1.2 netmask 255.255.255.0")
    h2.cmd("ifconfig h2-eth1 10.0.3.2 netmask 255.255.255.0")
    h3.cmd("ifconfig h3-eth0 10.0.4.2 netmask 255.255.255.0")

    h1.cmd("ip rule add from 10.0.0.2 table 1")
    h1.cmd("ip rule add from 10.0.2.2 table 2")
    h1.cmd("ip route add 10.0.0.0/24 dev h1-eth0 scope link table 1")
    h1.cmd("ip route add default via 10.0.0.1 dev h1-eth0 table 1")
    h1.cmd("ip route add 10.0.2.0/24 dev h1-eth1 scope link table 2")
    h1.cmd("ip route add default via 10.0.2.1 dev h1-eth1 table 2")
    h1.cmd("ip route add default scope global nexthop via 10.0.0.1 dev h1-eth0")

    h2.cmd("ip rule add from 10.0.1.2 table 1")
    h2.cmd("ip rule add from 10.0.3.2 table 2")
    h2.cmd("ip route add 10.0.1.0/24 dev h2-eth0 scope link table 1")
    h2.cmd("ip route add default via 10.0.2.1 dev h2-eth0 table 1")
    h2.cmd("ip route add 10.0.3.0/24 dev h2-eth1 scope link table 2")
    h2.cmd("ip route add default via 10.0.3.1 dev h2-eth1 table 2")
    h2.cmd("ip route add default scope global nexthop via 10.0.1.1 dev h2-eth0")

    h3.cmd("ip rule add from 10.0.4.2 table 1")
    h3.cmd("ip route add 10.0.4.0/24 dev h3-eth0 scope link table 1")
    h3.cmd("ip route add default via 10.0.4.1 dev h3-eth0 table 1")
    h3.cmd("ip route add default scope global nexthop via 10.0.4.1 dev h3-eth0")
    CLI(net)
    net.stop()

测试的话,自己随便尝试吧!

四、自定义内核

以上我们使用系统中的内核进行了tcp性能的简单测试,我们可以做的不止这些,可以设计一个tcp拥塞控制算法,然后编译到内核里面,运行并测量效果。

1、设计源代码

我的内核的名字为mptcp,一般情况下Linux内核源代码的名字叫linux5.10.60-9.al8.x86_64这样的名字。
进入内核源码文件夹

cd /usr/src/mptcp

进入tcp协议中拥塞控制算法源码的目录(/net/ipv4)

:/usr/src/mptcp
cd net/ipv4
:/usr/src/mptcp/net/ipv4

图9
我想在cubic的基础上修改实现一个我自己的拥塞控制算法,取名叫tcp_bupt,就是我们学校的名字,哈哈哈!
可以找到tcp cubic算法的源文件为tcp_cubic.c
可以打开查看一下:

gedit tcp_cubic.c

图10
文件内部有简单介绍该算法。
在文件中搜索.name,可以找到如下信息,“cubic”
图11

复制tcp_cubic.c为tcp_bupt.c

sudo cp tcp_cubic.c tcp_bupt.c

(需要注意的是,如果拥塞控制算法不止在一个c文件中实现,注意要复制所有的文件,判断的方式为
a. 文件名前缀相同
b. 看c文件中是否包含双引号的头文件
更改一下里面的内容:
图12

更改的一行为

delta = (cube_rtt_scale * offs * offs * offs) >> (10+3*BICTCP_HZ)
⬇️
delta = (cube_rtt_scale * offs * offs * offs) >> (20+4*BICTCP_HZ)

更改文件最后的.name中的"cubic"为"bupt"
图13

2、编译信息配置

Linux模块文件如何编译到内核和独立编译成模块?
修改Makefile

sudo vim Makefile

比葫芦画葫芦
c文件经过编译生成o文件
增加一行内容:

obj_$(CONFIG_TCP_CONG_BUPT) += tcp_bupt.o

图14

修改Kconfig

sudo gedit Kconfig

还是比葫芦画葫芦,需要注意的一点是有一行内容为

default m
default y
default n

m,y,n分别代表的意思为编译为模块、编译进内核、不编译。
我选择y
图15

下面的choice也要将信息添加进来
图16

回退到目录/usr/src/mptcp

cd ..
cd ..

执行命令

sudo make menuconfig

出现如下配置界面
图17
依次进入

>Networking support>Networking options>TCP: advanced congestion control

界面内容为:
图18
可以发现,最后一行TCP Bupt ( NEW ),前面的<*>表示编译到内核。因此不需要任何配置,直接退出吧!

3、编译

执行make命令,注意在Linux源文件目录下执行该命令

:/usr/src/mptcp$  sudo make

图19
让我们选择编译TCP Bupt的选项,Y是大写表示默认,可以直接回车,也可以输入y,这里我输入y
编译中,请耐心等待,喝杯咖啡放松一下!!!!
编译完成后。
可能还需要执行(如果编译的是模块的话,需要install,直接编译到内核不需要这一行代码)
其实执行一下也无所谓,这总是稳妥的。

sudo make install

重新启动Linux
查看拥塞控制算法

sudo sysctl net.ipv4.tcp_avaliable_congestion_control

图20

可以发现已经有了bupt这样一个算法,这个名字是.name控制的,tcp_bupt.c里面的.name是什么,你的算法就叫什么名字。

4、测试新的拥塞控制算法bupt

终于到了测试的环节了,因为bupt是经过cubic改良过来的(改了一行代码),所以我将这两个拥塞控制算法的性能进行比较。

# 关闭mptcp
sudo sysctl net.mptcp_enabled=0

1、cubic

sudo sysctl net.ipv4.tcp_congestion_control=cubic

在mininet下使用minimal拓扑测试

sudo mn --topo=minimal
h1 iperf -s -p 5566 -i 1 &
h2 iperf -c 10.0.0.1 -p 5566 -t 15 -i 1

图21

2、bupt

sudo sysctl net.ipv4.tcp_congestion_control=bupt
sudo mn --topo=minimal
h1 iperf -s -p 5566 -i 1 &
h2 iperf -c 10.0.0.1 -p 5566 -t 15 -i 1

图22

从两个实验的对比,发现好像差距不大,毕竟我只改了一行代码,如果想获得更加明显的对比(随意修改的算法参数,一般情况都会性能下降),需要更多的更改才行。
你可以尝试一下!

总结

通过上述内容,你可以了解mininet的简单实用,系统变量的查看与控制,已经修改内核编译内核,真的是收获满满了。对于想从事网络研究的人来说,相信一定对你有很大的帮助!

  • 6
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值