veth 的网络层不响应 arp

veth 的网络层不响应 arp

我决定玩一下 veth:创建一个 veth 对并从一端向另一端发送 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,MULTICAST,UP,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 请求,但却懒得应答。这是怎么回事?

答案1

这是一个非常复杂、非常古老的问题,涉及几个不同的领域,具体来说是 VETH、网络命名空间、ARP、路由表和 NAT……

我添加这个问题的答案不仅仅是为了 OP,也是为了其他人,希望能拯救其他人免于因为我而导致的白发......

经过大量的研究和测试,可以说——veth 对可以这样使用, 像他们那样字面上地两个独立的虚拟的接口。但是,由于它们虚拟的——您将遇到一些与 ARP 表/条目有关的非常奇怪的问题。经过几周的解决这个确切场景(工作所需),我已经弄清楚了如何做到这一点,并且在此过程中学到了比我想要的更多的有关 ARP、NAT 和路由的知识。

为了准确完成您的要求,请输入以下内容(在我的情况下为 Ubuntu 16.04)。请注意一旦进入test命名空间,就必须退出 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 通机器外部

特别值得注意的是,多麦基也可以做与 veth 完全相同的事情,但方式略有不同,因为 multimac 支持多对一关系,而 veth 是一对一关系。

为了支持这一点没有命名空间,你必须使用策略路由(比网络命名空间稍微复杂一些)

答案2

Veth 对不是这样使用的。Veth 对实际上是一个设备管道,数据包从管道的一端传出到另一端。

我能提供的最简单的同义词是想象成对的一半是以太网设备,而另一端是设备插入的交换机端口。您不应将这对设备视为两个独立的设备,而应将其视为具有两个可推/拉的“端点”的设备。

答案3

尝试设置这些:

echo 1 > /proc/sys/net/ipv4/conf/all/accept_local
echo 1 > /proc/sys/net/ipv4/conf/default/accept_local
echo 1 > /proc/sys/net/ipv4/conf/veth4/accept_local
echo 1 > /proc/sys/net/ipv4/conf/veth5/accept_local
echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter
echo 0 > /proc/sys/net/ipv4/conf/default/rp_filter
echo 0 > /proc/sys/net/ipv4/conf/veth4/rp_filter
echo 0 > /proc/sys/net/ipv4/conf/veth5/rp_filter

答案4

对于 veth 接口,您需要位更改 ip 规则:无 arp、无 ping 应答等。

# ip rule
0:  from all lookup local
1000:   from all lookup [l3mdev-table]
32766:  from all lookup main
32767:  from all lookup default

移动查找本地后 l3mdev veth 工作正常

# ip rule
1000:   from all lookup [l3mdev-table]
32000:  from all lookup local
32766:  from all lookup main
32767:  from all lookup default

你可以通过关闭 ARP 来关闭,ip link set arp off dev <veth>但是通过引导查找本地,同一个网络中的远程 veth 无论如何都不会响应自己的流量......

相关内容