On 12/3/25 23:55, Sławomir Zborowski wrote:
> There's not really such a thing as an "inet interface" or an "inet6
> interface" an interface, represented by an index, can have multiple
> addresses, both IPv4 and IPv6.
You're right. That was imprecise mental shortcut.
> What I would expect to see here is that the interface had both IPv4
> addresses and IPv6 addresses when it was added to the daemon->interfaces
> list, so this check will find at least one entry on that list which came
> from the arrival interface and has the correct address family.
The thing is it only has the IPv6 address. This is how Calico (or the OS
- I'm not entirely sure) configures it.
> Your description implies that the TCP connection is over IPv4. Does the
> interface is arrives on have an IP4 address?
Destination is a regular eth0 iface on the server with IPv4 address only.
The connection originates from a Pod that is connected through veth pair.
That veth pair has only IPv6 address in the system.
> As usual, the most useful resource here is the simplest configuration
> which demonstrates this problem on the most vanilla kernel network
> configuration.
I'm not sure if that's the most vanilla way out there, but I believe that
Calico does something along following. I'm not sure if the proxy_arp
thing is necessary. With following I was able to reproduce the problem.
# ip netns add fakepod
# ip link add host-veth type veth peer name pod-veth
# ip link set pod-veth netns fakepod
# ip link set host-veth up
# echo 1 | sudo tee /proc/sys/net/ipv4/conf/host-veth/proxy_arp
# ip netns exec fakepod bash
# ip link set lo up
# ip link set pod-veth up
# ip addr add 10.44.0.51/32 <http://10.44.0.51/32> dev pod-veth
# ip route add default dev pod-veth
# ip route add 169.254.1.1/32 <http://169.254.1.1/32> dev pod-veth
# exit
# ip route add 10.44.0.51/32 <http://10.44.0.51/32> dev host-veth
Now, start dnsmasq on the host:
# sudo ./src/dnsmasq -d --log-debug 2>&1 | tee /tmp/dnsmasq.log
And trigger the behavior:
# ip netns exec fakepod dig duckduckgo.com <http://duckduckgo.com>. A +tcp
@[REDACTED: server eth0 physical IPv4 address]
;; communications error to [REDACTED: server eth0 physical IPv4 address]#53: end
of file
;; communications error to [REDACTED: server eth0 physical IPv4 address]#53: end
of file
This is, by the way, how the iface shows up in the system:
266: host-veth@if265: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue
state UP group default qlen 1000
link/ether d6:35:97:b9:51:f0 brd ff:ff:ff:ff:ff:ff link-netns fakepod
inet6 fe80::d435:97ff:feb9:51f0/64 scope link
valid_lft forever preferred_lft forever
And dnsmasq will recognize it as IPv6. I added some debug prints
to verify that it happens. Incoming TCP addr sa_family is 0x2, iface
sa_family is 0xA.
I think the IPv6 address that is attached to the veth host end is added
by the OS.
Hopefully all of the above is helpful.
So basically, dnsmasq receives a TCP connection from 10.44.0.51 to [redacted]
through the host-veth interface, but the host-veth interface only have a ipv6
link-local and no ipv4. [redacted] is actually configured on eth0.
It is quite difficult for a TCP server to know from which an interface a request
comes from. Finding the interface where the destination address was configured
only works on systems with a strong host model, but linux uses a weak host model
and your setup rely on it.
A weak host model system will accept packets from 10.44.0.51 to [redacted]
regardless of the interface the packet came from. And replies are sent to
whatever interface the FIB says should be used and the interface may change over
time.
A workaround would be to use RTM_GETROUTE on the source address and consider
that as the interface the request came from, but that could cause other problems.
_______________________________________________
Dnsmasq-discuss mailing list
[email protected]
https://lists.thekelleys.org.uk/cgi-bin/mailman/listinfo/dnsmasq-discuss