This issue is reproducible but is due to choosing a name which interferes with the default choice made by the kernel.
When not specifying a name for the peer interface, the lowest possible interger is appended to veth
to build the peer name first. This happens first, before the main interface itself is created. This can be seen when one specifies a name that can't clash:
# ip link add name myveth type veth
# ip link show type veth
17: veth0@myveth: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether 2a:93:f8:8e:bc:b6 brd ff:ff:ff:ff:ff:ff
18: myveth@veth0: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether 8a:c3:1d:82:93:a6 brd ff:ff:ff:ff:ff:ff
the peer name is chosen following the usual way: create an interface with the type and next available integer appended to it: veth
+0
: veth0
. The lower index (here 17 versus 18) means it's created first.
Now if one specifies the very same name that the kernel automatically creates first, a clash happens, the specified interface isn't created and the peer interface thus gets deleted. No trace except for a RTNETLINK answers: File exists
. This can clearly be seen when running in a separate shell ip link monitor
:
shell 1:
$ ip link monitor
shell 2:
# ip link add name veth0 type veth
RTNETLINK answers: File exists
shell 1 again:
23: veth0@NONE: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default
link/ether 72:2d:b8:9f:90:6c brd ff:ff:ff:ff:ff:ff
Deleted 23: veth0@NONE: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default
link/ether 72:2d:b8:9f:90:6c brd ff:ff:ff:ff:ff:ff
Here @NONE
means there's no peer link index associated... yet. A veth
interface does have a peer link index: the other side of the virtual Ethernet wire. It should have resolved the peer link index to the next interface just created with index 24, but then this interface couldn't be created with the name veth0
because it already existed (even if that's because of its own creation). This triggers the cancellation of the whole operation and the deletion of the ephemeral veth0
as well as the error message sent back as File exists
, else leaving no trace of the issue.
Conclusion: to avoid any clash,
don't specify any name and let the kernel pick them:
ip link add type veth
getting:
24: veth0@veth1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default
link/ether 2a:93:f8:8e:bc:b6 brd ff:ff:ff:ff:ff:ff
25: veth1@veth0: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default
link/ether 86:70:54:05:0f:75 brd ff:ff:ff:ff:ff:ff
specify a name not following the default naming scheme
ip link add name myveth type veth
or specify both names, even if they're not the default order they would be created by the kernel in its default naming scheme (peer as veth0
and main as veth1
):
ip link add name veth0 type veth peer name veth1
don't forget veth
interfaces are most of the time (but not always) useless outside of network namespace environments. The peer interface can get added directly elsewhere if needed:
ip netns add othernamespace
ip link add name veth0 type veth peer netns othernamespace
where the peer will also be created as veth0
without any clash.
# ip link show type veth
27: veth0@if2: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether 2a:93:f8:8e:bc:b6 brd ff:ff:ff:ff:ff:ff link-netns othernamespace
# ip -n othernamespace link show type veth
2: veth0@if27: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether fa:cb:bf:23:fc:a6 brd ff:ff:ff:ff:ff:ff link-netnsid 0
ip link show dev veth0
. If there's one that means it was created. Whatever happened before or after the reboot, something creates or recreates it. This something might have done this automatically when you created it first or not, but there is not enough information provided in the question to guess what.