Search code examples
linuxkuberneteslinux-device-driverkubeadmflannel

Why does Kubernetes return odd results for ioctl


I have a legacy application that I'm running inside a pod on Kubernetes deployed with kubeadm. The CNI is flannel. The code calls ioctl with SIOCGIFBRDADDR to get the broadcast address of the container interface. In vanilla Docker the correct broadcast request is returned. In Kubernetes it incorrectly returns 0.0.0.0. An strace shows the call from the Kubernetes pod below:

ioctl(4, SIOCGIFBRDADDR, {ifr_name="eth0", ifr_broadaddr={AF_INET, inet_addr("0.0.0.0")}}) = 0

I was expecting the broadcast calculated from the /24 assigned to pods running on the worker node, i.e. 10.244.2.255 for a pod IP address of 10.244.2.70/24

The interface address does seem to be returned correctly by SIOCGIFCONF:

ioctl(4, SIOCGIFCONF, {100 * sizeof(struct ifreq) => 2 * sizeof(struct ifreq), [{ifr_name="lo", ifr_addr={AF_INET, inet_addr("127.0.0.1")}}, {ifr_name="eth0", ifr_addr={AF_INET, inet_addr("10.244.2.70")}}]}) = 0

Is there a reason why the broadcast address get doesn't work?

Update: As a testcase I compiled the code described here, which just calls ioctl as described above. https://gist.github.com/loderunner/ec7d4725daca39283606#file-getbroadaddr-c

When running the binary in my pod centos:7 it gives the result:

sh-4.2$ ./getaddrs
Listing all interfaces:
lo
eth0
sh-4.2$ ./getaddrs eth0
eth0                    0.0.0.0
sh-4.2$ ip a s
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue 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
3: eth0@if43: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 8950 qdisc noqueue
    link/ether 3e:b4:05:db:cf:41 brd ff:ff:ff:ff:ff:ff
    inet 10.244.4.7/24 scope global eth0
        valid_lft forever preferred_lft forever
    inet6 fe80::3cb4:5ff:fedb:cf41/64 scope link
        valid_lft forever preferred_lft forever

This illustrates the issue. The result from ./getaddr eth0 should be 10.244.4.255, not 0.0.0.0


Solution

  • This seems to be a quirk of flannel. Using weave-net the correct broadcast is returned.