为了以受控的方式测试网络应用程序,我想在一台可以控制延迟的机器上创建某种虚拟网络。(我正在运行 Ubuntu 14.04 x64)。我进行了一些研究,得出了以下结论:
使用 tap 接口:vde_switch 创建虚拟交换机,如下所示:
sudo vde_switch -tap tap0 -tap tap1
sudo ip addr add 10.0.0.100 dev tap0
sudo ip addr add 10.0.0.101 dev tap1
我尝试过的创建点击界面的另一种方法是:
sudo ip tuntap add dev tap0 mode tap
sudo ip link set dev tap0 up
sudo ip addr add 10.0.0.100 dev tap0
[repeat for tap1 and any further interfaces]
到目前为止一切顺利。现在我的问题是在这些 tap 接口中引入了人为延迟。我设法使用以下方法对 lo 和 eth0 等实际接口执行此操作:
sudo tc qdisc add dev eth0 root netem delay 15ms
但是,上述命令似乎不适用于 tap 接口。在我为其中一个 tap 接口执行该命令后,似乎没有任何变化。该命令没有提供任何输出,因此似乎可以找到接口并成功完成。但是,ping 10.0.0.100 等时,延迟没有变化。
我是否遗漏了什么明显的内容?(或者我完全以错误的方式处理这个问题?)谢谢!
答案1
我最终找到了一个解决方法。它在我的环境中运行良好,但需要使用虚拟机;可能还有更优雅的解决方案。请注意。
此方法使用 VMware Workstation(请注意,Player 不够用)。我分别使用 Ubuntu Desktop 和 Ubuntu Server 作为主机和客户机操作系统。
Workstation 有一个“虚拟网络编辑器”(Workstation 附带的单独应用程序)。使用它,您可以创建额外的虚拟网络接口,并且可以独立地为这些接口分配虚拟延迟。根据需要创建额外的 vmnetX 接口(我的接口类型为仅主机),您可以向 VM 添加新的网络适配器,手动指定相应的网络接口。如果您使用的是 Linux,您可能还需要将新适配器添加到客户操作系统中的 /etc/network/interfaces。
现在您应该有多个不同的接口/网络可供主机和客户机共享。使用类似下面的命令为这些接口引入延迟(谷歌此命令了解更多详细信息,这只是一个例子):
sudo tc qdisc add dev vmnet1 root netem delay 20ms
我最终在客户操作系统(使用 eth0、eth1 等接口)而不是主机中引入了延迟,如上例所示。不过,我认为这不会带来太大的差别。
请注意,这只是我如何让它工作的快速而粗略的描述,而不是非常通用的描述。如果你想做类似的事情,你可能需要更改一些细节。
答案2
虽然不漂亮,但是可以工作:
#!/bin/bash
TAP0="tap0"
TAP1="tap1"
# use different subnets
IP0="10.0.31.1"
IP1="10.0.32.1"
# some fake ips in yet different subnets
FAKE0="10.1.31.1"
FAKE1="10.1.32.1"
ip tuntap add dev $TAP0 mode tap;
ip tuntap add dev $TAP1 mode tap;
ip addr add $IP0 dev $TAP0;
ip addr add $IP1 dev $TAP1;
ifconfig $TAP0 inet $IP0 netmask 255.255.255.0 up;
ifconfig $TAP1 inet $IP1 netmask 255.255.255.0 up;
ifconfig -a;
vde_switch -d -tap $TAP0 -tap $TAP1;
iptables -t nat -A POSTROUTING -s $IP0 -d $FAKE1 -j SNAT --to-source $FAKE0;
iptables -t nat -A PREROUTING -d $FAKE0 -j DNAT --to-destination $IP0;
iptables -t nat -A POSTROUTING -s $IP1 -d $FAKE0 -j SNAT --to-source $FAKE1;
iptables -t nat -A PREROUTING -d $FAKE1 -j DNAT --to-destination $IP1;
ip route add $FAKE1 dev $TAP0;
arp -i $TAP0 -s $FAKE1 $(ifconfig -a|grep $TAP1|awk '{print $5}');
ip route add $FAKE0 dev $TAP1;
arp -i $TAP1 -s $FAKE0 $(ifconfig -a|grep $TAP0|awk '{print $5}');
tc qdisc add dev $TAP0 root handle 1:0 netem delay 80ms 20ms 25% loss 5% duplicate 5%;
tc qdisc add dev $TAP1 root handle 1:0 netem delay 80ms 20ms 25% loss 5% duplicate 5%;
虽然这可能非常丑陋并且可能完全错误 - 但它可以按我需要的方式工作。请注意,这仅在 tap0 和 tap1 之间有效,而不是从 tap0 循环到 tap0 左右。请参阅测试 ping:
$ ping -qi 0.2 10.0.31.1 -I tap1
PING 10.0.31.1 (10.0.31.1) from 10.0.32.1 tap1: 56(84) bytes of data.
^C
--- 10.0.31.1 ping statistics ---
313 packets transmitted, 301 received, +13 duplicates, 3% packet loss, time 62650ms
rtt min/avg/max/mdev = 60.013/81.053/99.951/11.661 ms