3

I run docker containers which are all connected to a bridge of my own (not the standard docker0 one). This is what it looks like from the host perspective (I left only information relevant to the virtual bridging and ethernet):

root@srv ~# ip link
(...)    
8: br-7b20560b3603: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default
    link/ether 02:42:7c:70:e1:47 brd ff:ff:ff:ff:ff:ff
9: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default
    link/ether 02:42:f1:70:4f:a6 brd ff:ff:ff:ff:ff:ff
11: veth1fb5957@if10: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-7b20560b3603 state UP mode DEFAULT group default
    link/ether 4e:38:69:b2:db:ef brd ff:ff:ff:ff:ff:ff link-netnsid 2
13: vethc225476@if12: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-7b20560b3603 state UP mode DEFAULT group default
    link/ether 56:1d:d5:96:68:ac brd ff:ff:ff:ff:ff:ff link-netnsid 1
377: veth7fcee93@if376: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-7b20560b3603 state UP mode DEFAULT group default
    link/ether 62:06:5d:c7:31:7b brd ff:ff:ff:ff:ff:ff link-netnsid 4
431: vethd0879bb@if430: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-7b20560b3603 state UP mode DEFAULT group default
    link/ether 0a:f8:aa:02:a9:f4 brd ff:ff:ff:ff:ff:ff link-netnsid 3
245: veth4a8ecb1@if244: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-7b20560b3603 state UP mode DEFAULT group default
    link/ether d6:86:f1:8b:73:ab brd ff:ff:ff:ff:ff:ff link-netnsid 0

When connecting to one of the containers, I see

root@vpnin ~# ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
12: eth0@if13: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default
    link/ether 02:42:0a:c8:00:03 brd ff:ff:ff:ff:ff:ff link-netnsid 0

The topology is such that, on the host, br-7b20560b3603 has several veth* as children, and each of them is connected to a container - this other side becomes the container's eth0.

How can I find out which veth* on the host corresponds to the eth0@<something> in the container?

I can see that the first column on the host has 13, which is similar to the eth0@if13 in the container. Reciprocally, eth0@if13 corresponds to the label 12 in the container, which is referenced as vethc225476@if12 on the host. I do not know if this is a coincidence - if not, to what do the first column labels in ip link correspond?

4

As you suspect, the @if13 does refer to the number in the first column, which is the ifindex number (at least, "ifindex" is the name of the variable exposed by libnl, used to talk netlink to the kernel to get this kind of info). When the number exists in the same namespace, the ip utility shows the name associated with the number instead of the number (e.g. myvlan@eth0).

You can also see the field 'link-netnsid' which is another integer, this one identifying the namespace holding the link (either the other end of a veth pair, as you have here, or otherwise handling the other end of the device, such as the namespace whose IP address is used for a tunnel device). You can list those with ip netns list-id (at least on recent versions of iproute2). If the namespace is mounted in the usual place, it will show the name of the network namespace next to the ID.

examples:

$ sudo ip link add name veth1 type veth peer name veth2
$ ip link show | grep veth
32: veth2@veth1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
33: veth1@veth2: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group

$ sudo ip netns add examplens
$ sudo ip link setns examplens dev veth2
$ ip link show | grep -a1 veth
33: veth1@if32: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default
link/ether e2:99:ce:05:64:a4 brd ff:ff:ff:ff:ff:ff link-netnsid 2

$ ip netns list-id
nsid 0 
nsid 1 
nsid 2 (iproute2 netns name: examplens)

$ sudo ip -n examplens link
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
32: veth2@if33: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 3a:89:30:01:4a:49 brd ff:ff:ff:ff:ff:ff link-netnsid 0

In the above, we create a veth pair and can see both end's show the name of the other end. We then create a netns named examplens and move veth2 into it. Now ip doesn't know the name of veth1's peer anymore, but still has the ifnumber, so it shows that instead (if32), which we can see is what it was before it was moved. We also see that the link is in netnsid (nsid) 2, which we see is named examplens.

Listing the links within examplens shows veth2, with its peer having ifnumber 33 in netnsid 0.

Unfortunately, the ip utility doesn't help you find where the nsid is when it is not bound to and entry in /var/run/netns (which is where the ip utility bind mounts its created netns to give them a name). Many (most? all?) other utilities don't seem to do this, including docker, so there isn't much help in finding the other end from the host, making users do a manual search for other network namespaces (e.g. by finding all unique entries in /proc/*/ns/net).

In short, this helps find the link on the host when you know the container's link list, but not so much finding the container when you have the host's link list.

A last note about the nsids: they are unique per netns. nsid 0 of the host is not the same namespace as nsid 0 in the examplens namespace in my example, for example.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.