Eu tenho o Ubuntu 16.04 LTS com o kernel hwe 4.13.0-39-generic. Eu configuro o par veth no namespace de rede padrão da seguinte forma:
$ sudo ip link add h1-eth0 type veth peer name h2-eth0
$ sudo ip link set dev h1-eth0 up
$ sudo ip link set dev h2-eth0 up
$ sudo ip addr add 10.0.0.1/24 dev h1-eth0
$ sudo ip addr add 10.0.0.2/24 dev h2-eth0
Aqui estão as configurações que recebo após a configuração acima:
$ ifconfig
...
h1-eth0 Link encap:Ethernet HWaddr ea:ee:1e:bb:66:55
inet addr:10.0.0.1 Bcast:0.0.0.0 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
...
h2-eth0 Link encap:Ethernet HWaddr ba:aa:99:77:ff:78
inet addr:10.0.0.2 Bcast:0.0.0.0 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
...
$ ip route show
10.0.0.0/24 dev h1-eth0 proto kernel scope link src 10.0.0.1
10.0.0.0/24 dev h2-eth0 proto kernel scope link src 10.0.0.2
...
Agora eu posso pingar uma interface de outra da seguinte forma:
$ ping -I 10.0.0.1 -c1 10.0.0.2
PING 10.0.0.2 (10.0.0.2) from 10.0.0.1 : 56(84) bytes of data.
64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=0.046 ms
--- 10.0.0.2 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.046/0.046/0.046/0.000 ms
Mas o primeiro problema é que o ping falha quando tento pingar usando o nome da interface, em vez do endereço IP:
$ ping -I h1-eth0 -c1 10.0.0.2
PING 10.0.0.2 (10.0.0.2) from 10.0.0.1 h1-eth0: 56(84) bytes of data.
From 10.0.0.1 icmp_seq=1 Destination Host Unreachable
--- 10.0.0.2 ping statistics ---
1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms
Como isso pode ser um problema se h1-eth0 tiver o endereço IP 10.0.0.1?
O segundo problema, creio eu, está relacionado. Eu configuro as interfaces da seguinte forma:
$ sudo tc qdisc add dev h1-eth0 root netem delay 60ms
$ sudo tc qdisc add dev h2-eth0 root netem delay 60ms
$ tc qdisc show
qdisc netem 8006: dev h2-eth0 root refcnt 2 limit 1000 delay 60.0ms
qdisc netem 8005: dev h1-eth0 root refcnt 2 limit 1000 delay 60.0ms
Agora eu pingo novamente com o atraso:
$ ping -I 10.0.0.1 -c4 10.0.0.2
PING 10.0.0.2 (10.0.0.2) from 10.0.0.1 : 56(84) bytes of data.
64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=0.033 ms
64 bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=0.034 ms
64 bytes from 10.0.0.2: icmp_seq=3 ttl=64 time=0.059 ms
64 bytes from 10.0.0.2: icmp_seq=4 ttl=64 time=0.027 ms
--- 10.0.0.2 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3063ms
rtt min/avg/max/mdev = 0.027/0.038/0.059/0.013 ms
E pode-se ver que o rtt não é esperado 60ms*2=120ms. Então parece que tc qdisc netem não funciona para minhas interfaces.
Então, no geral, vejo que minha configuração está de alguma forma quebrada.
Eu respondo minha própria pergunta abaixo.
A evasão mais simples (minha abordagem): colocar um do veth par em outro namespace de rede. Vamos chamá-lo
test
.Agora verificamos:
Outras abordagens
Descobri que minha pergunta já foi feita, mas também não foi respondida: https://serverfault.com/questions/585246/network-level-of-veth-doesnt-respond-to-arp . A partir daí vemos que o problema está no ARP.
Uma pergunta relacionada a este problema com ARP foi feita aqui O Linux não responde às mensagens de solicitação ARP se o endereço IP solicitado estiver associado a outra interface (desativada) e o iniciador do tópico recebeu alguma explicação, mas o problema ainda não foi resolvido.
O problema é que os endereços 10.0.0.1 e 10.0.0.2 estão presentes não apenas na tabela de rotas principal, mas também na tabela de rotas local e a tabela de rotas local tem maior prioridade que a tabela de rotas principal. Abaixo estão essas tabelas para a configuração inicial da minha pergunta, ou seja, SEM colocar uma extremidade do par veth em outro namespace de rede
test
:Ao ter uma das extremidades do par veth em outro namespace de rede, não temos uma situação em que dois dos endereços sejam colocados na tabela de rotas local ao mesmo tempo. Então, provavelmente, é por isso que não temos esse problema. Tentei excluir os endereços da tabela de rotas local (apenas um deles ou ambos - em combinações diferentes), mas não ajudou. No geral, eu não entendo completamente a situação, então vou apenas definir as extremidades do par veth em diferentes namespaces de rede. Ainda mais, é assim que um par de veth é usado principalmente, até onde eu sei.