Назад | Перейти на главную страницу

сетевой уровень veth не отвечает на arp

Решил поиграться с veth: создать пару veth и отправить пинг с одного конца на другой.

$ 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 -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). пожалуйста, обратите внимание что как только вы окажетесь в 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 могут пинговать друг друга, а vGUEST может пинговать за пределами машины

Особо следует отметить, мультимак может также делать то же самое, что и veth, но немного по-другому, поскольку multimac поддерживает отношения «многие к одному», где veth - это отношения «один к одному».

Чтобы поддержать это на без пространств имен, вы должны использовать политика маршрутизации (что немного сложнее, чем сетевые пространства имен)

Пары Veth так не используются. Пара veth - это буквально труба устройства, из одного конца трубы выходят пакеты с другого конца.

Самый простой синоним, который я могу предложить, - это представить себе, что одна половина пары - это устройство Ethernet, а другой конец - это порт коммутатора, к которому устройство подключено. Вы не должны относиться к паре как к двум отдельным устройствам, а как к одному устройству, у которого есть два «конца», с которых можно толкать / тянуть.

попробуйте установить их:

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