Score:1

Why is traffic routed between different veth devices?

ua flag

I have a problem: there is unexpected route path between virtual network devices.

Let's create two independent veth-peer device pairs:

$ sudo ip link add veth0 type veth peer name peer0
$ sudo ip link add veth1 type veth peer name peer1

Assign addresses to peerX devices:

$ sudo ip addr add ab:: dev peer0
$ sudo ip addr add cd:: dev peer1

Set all devices up:

$ sudo ip link set dev veth0 up
$ sudo ip link set dev veth1 up
$ sudo ip link set dev peer1 up
$ sudo ip link set dev peer0 up

Check devices:

$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 02:82:b2:df:b0:58 brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.15/24 brd 10.0.2.255 scope global dynamic enp0s3
       valid_lft 84429sec preferred_lft 84429sec
    inet6 fe80::82:b2ff:fedf:b058/64 scope link
       valid_lft forever preferred_lft forever
3: peer0@veth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 6e:8d:c0:7c:02:9c brd ff:ff:ff:ff:ff:ff
    inet6 ab::/128 scope global
       valid_lft forever preferred_lft forever
    inet6 fe80::6c8d:c0ff:fe7c:29c/64 scope link
       valid_lft forever preferred_lft forever
4: veth0@peer0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 4e:43:26:75:10:11 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::4c43:26ff:fe75:1011/64 scope link
       valid_lft forever preferred_lft forever
5: peer1@veth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether ea:8c:82:e6:2e:a9 brd ff:ff:ff:ff:ff:ff
    inet6 cd::/128 scope global
       valid_lft forever preferred_lft forever
    inet6 fe80::e88c:82ff:fee6:2ea9/64 scope link
       valid_lft forever preferred_lft forever
6: veth1@peer1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether da:5a:68:b1:e8:43 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::d85a:68ff:feb1:e843/64 scope link
       valid_lft forever preferred_lft forever

and routes:

$ ip r
default via 10.0.2.2 dev enp0s3 proto dhcp src 10.0.2.15 metric 100
10.0.2.0/24 dev enp0s3 proto kernel scope link src 10.0.2.15
10.0.2.2 dev enp0s3 proto dhcp scope link src 10.0.2.15 metric 100

Now listen peer0 on UDP port 2000:

$ nc -u -6 -l ab:: 2000

And send packet though peer1:

$ echo -n abc nc -u -6 -s cd:: ab:: 2000

And listening nc prints abc! But why? peer0 and peer1 aren't connected in any way. If I understand correctly, listening nc should bind to peer0 and sending nc should bind to peer1.

Score:1
cl flag
A.B

peer0 and peer1 aren't connected in any way.

They are all interfaces belonging to the system so they are connected to the system. Routing happens on the system. The system will communicate among addresses belonging to itself directly, without routing packets outside, ie without sending packets through the veth interfaces but by using its loopback interface (dev lo below):

# ip route get from cd:: to ab::
local ab:: from cd:: dev lo table local proto kernel src ab:: metric 0 pref medium

Also, not that it helps much here, but when displaying routes without any IPv6 value to hint IPv6, -6 has to be given, or it defaults to IPv4.

# ip -6 route
ab:: dev peer0 proto kernel metric 256 pref medium
cd:: dev peer1 proto kernel metric 256 pref medium
fe80::/64 dev peer1 proto kernel metric 256 pref medium
fe80::/64 dev veth1 proto kernel metric 256 pref medium
fe80::/64 dev peer0 proto kernel metric 256 pref medium
fe80::/64 dev veth0 proto kernel metric 256 pref medium
# ip -6 route show table local
local ::1 dev lo proto kernel metric 0 pref medium
local fe80::4c43:26ff:fe75:1011 dev veth0 proto kernel metric 0 pref medium
local fe80::6c8d:c0ff:fe7c:29c dev peer0 proto kernel metric 0 pref medium
local fe80::d85a:68ff:feb1:e843 dev veth1 proto kernel metric 0 pref medium
local fe80::e88c:82ff:fee6:2ea9 dev peer1 proto kernel metric 0 pref medium
multicast ff00::/8 dev veth1 proto kernel metric 256 pref medium
multicast ff00::/8 dev peer1 proto kernel metric 256 pref medium
multicast ff00::/8 dev veth0 proto kernel metric 256 pref medium
multicast ff00::/8 dev peer0 proto kernel metric 256 pref medium
ua flag
Thank. So in order to isolate them I have to use separate network namespaces?
A.B avatar
cl flag
A.B
I don't know exactly what you intend to do and why there are two pairs of veth interfaces rather than just one pair, but yes the main use of veth interfaces is across network namespaces (there are other less common uses in the same namespace when using a bridge too).
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.