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
This seems to be a quirk of flannel. Using weave-net the correct broadcast is returned.