我决定玩veth:创建一个veth对和
从一端向另一端发送ping.
从一端向另一端发送ping.
$ip link add type veth $ip addr add 192.168.99.1 dev veth4 $ip addr add 192.168.99.2 dev veth5 $ip link dev veth4 set up $ip link dev veth5 set up
让我们检查.
$ip a 18: veth4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 6a:dc:02:5b:f0:f3 brd ff:ff:ff:ff:ff:ff inet 192.168.99.1/24 scope global veth4 valid_lft forever preferred_lft forever 19: veth5: <BROADCAST,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 22:ec:d5:e8:7c:3e brd ff:ff:ff:ff:ff:ff inet 192.168.99.2/24 scope global veth5 valid_lft forever preferred_lft forever
一切似乎都没问题.现在尝试ping.
$ping -I veth4 192.168.99.2 PING 192.168.99.2 (192.168.99.2) from 192.168.99.1 veth4: 56(84) bytes of data. From 192.168.99.1 icmp_seq=1 Destination Host Unreachable From 192.168.99.1 icmp_seq=2 Destination Host Unreachable From 192.168.99.1 icmp_seq=3 Destination Host Unreachable $sudo tshark -i veth5 Capturing on 'veth5' l 1 0.000000 6a:dc:02:5b:f0:f3 -> Broadcast ARP 42 Who has 192.168.99.2? Tell 192.168.99.1 1 2 1.003206 6a:dc:02:5b:f0:f3 -> Broadcast ARP 42 Who has 192.168.99.2? Tell 192.168.99.1
所以veth5接受了arp请求,但没有费心回答.怎么了?
解决方法
这是一个非常复杂,非常古老的问题,涉及几个不同的领域,特别是VETH,网络命名空间,ARP,路由表和NAT ……
我正在为这个问题添加答案,不仅仅是针对OP,而是针对其他人,希望能从灰头发中拯救别人,这给了我…
可以说,经过大量的研究和测试 – veth对可以完全以这种方式使用,因为它们实际上是两个单独的虚拟接口.但是,因为它们是虚拟的 – 你会遇到一些关于ARP表/条目的奇怪问题.经过几周的处理这个确切的场景(工作所需),我已经弄清楚如何做到这一点,并且在这个过程中已经学到了比我想要的更多关于ARP,NAT和路由的方法.
为了完全满足您的需求,请键入以下内容(在我的示例中为Ubuntu 16.04).请注意,一旦进入测试命名空间,就必须退出bash离开,因为从那一点开始的所有内容(路由表,iptables等)与主机上的不同.我通常会打开两个终端,一个停留在主机中 – 另一个停留在来宾名称空间中.
前言
# Tell the system we want to support IPv4 forwarding add/verify that the following is in `/etc/sysctl.conf` `net.ipv4.ip_forward = 1` # if it wasn't there,reparse syscrtl + restart networking sysctl -p; /etc/init.d/networking restart;
主机设置
# create a veth pair ip link add name vHOST type veth peer name vGUEST # choose a private MAC address and private IP address ifconfig vHOST hw ether 02:1d:8d:dd:0c:61 ifconfig vHOST 10.11.0.1/24 up # have to setup routes FROM HOST -> GUEST ip route add 10.111.0.0/24 via 10.11.0.1 dev vHOST # gateway # have to explicitly assign what the MAC is for the vGUEST in the vHOST interface ARP table arp -i vHOST -s 10.111.0.1 02:1d:8d:dd:0c:60 # vGUEST ip + mac address # We must tell vHOST-vGUEST "tunnel",vHOST side that it's not a REAL bridge,so any ARP requests must be answered by vHOST echo 1 > /proc/sys/net/ipv4/conf/vHOST/proxy_arp # setup forwarding + NAT (so packets can come back) iptables -A FORWARD -s 10.111.0.0/24 -o vHOST -j ACCEPT iptables -t nat -A POSTROUTING -s 10.111.0.1 -j SNAT --to 192.168.42.124
客人设置
# create the "test" namespace,so we can verfiy settings ip netns add test # add vGUEST "interface" to the "test" namespace ip link set vGUEST netns test # enter the "test" namespace with a bash shell ip netns exec test bash # choose a private MAC address and private IP address ifconfig vGUEST hw ether 02:1d:8d:dd:0c:60 ifconfig vGUEST 10.111.0.1/24 up # have to setup routes FROM GUEST -> HOST ip route add default via 10.111.0.1 dev vGUEST # gateway # have to explicitly assign what the MAC is for the vHOST in the vGUEST interface ARP table arp -i vGUEST -s 10.11.0.1 02:1d:8d:dd:0c:61 # vHOST ip + mac address
现在,GUEST / HOST可以互相ping,vGUEST可以在机器外ping
特别值得注意的是,multimac也可以采用与veth完全相同的方式,因为multimac支持多对一关系,其中veth是一对一的关系.