<div dir="ltr">> There's not really such a thing as an "inet interface" or an "inet6 <br>> interface" an interface, represented by an index, can have multiple <br><div>> addresses, both IPv4 and IPv6.</div><div><br></div><div>You're right. That was imprecise mental shortcut.</div><div><br></div><div>> What I would expect to see here is that the interface had both IPv4 <br>> addresses and IPv6 addresses when it was added to the daemon->interfaces <br>> list, so this check will find at least one entry on that list which came <br>> from the arrival interface and has the correct address family.</div><div><br></div><div>The thing is it only has the IPv6 address. This is how Calico (or the OS</div><div>- I'm not entirely sure) configures it.</div><div><br></div><div>> Your description implies that the TCP connection is over IPv4. Does the <br>> interface is arrives on have an IP4 address?</div><div><br></div><div>Destination is a regular eth0 iface on the server with IPv4 address only.</div><div>The connection originates from a Pod that is connected through veth pair.</div><div>That veth pair has only IPv6 address in the system.</div><div><br></div><div>> As usual, the most useful resource here is the simplest configuration <br>> which demonstrates this problem on the most vanilla kernel network <br>> configuration.</div><div><br></div><div>I'm not sure if that's the most vanilla way out there, but I believe that</div><div>Calico does something along following. I'm not sure if the proxy_arp</div><div>thing is necessary. With following I was able to reproduce the problem.</div><div><br></div><div># ip netns add fakepod</div><div># ip link add host-veth type veth peer name pod-veth</div><div># ip link set pod-veth netns fakepod</div><div># ip link set host-veth up</div><div># echo 1 | sudo tee /proc/sys/net/ipv4/conf/host-veth/proxy_arp</div><div># ip netns exec fakepod bash</div><div># ip link <span class="gmail-hljs-built_in">set</span> lo up</div><div># ip link set pod-veth up</div><div># ip addr add <a href="http://10.44.0.51/32">10.44.0.51/32</a> dev pod-veth</div><div># ip route add default dev pod-veth</div><div># ip route add <a href="http://169.254.1.1/32">169.254.1.1/32</a> dev pod-veth</div><div># exit</div><div># ip route add <a href="http://10.44.0.51/32">10.44.0.51/32</a> dev host-veth<br><br></div><div>Now, start dnsmasq on the host:</div><div># sudo ./src/dnsmasq -d --log-debug 2>&1 | tee /tmp/dnsmasq.log</div><div><br></div><div>And trigger the behavior:</div><div># ip netns exec fakepod dig <a href="http://duckduckgo.com">duckduckgo.com</a>. A +tcp @[REDACTED: server eth0 physical IPv4 address]<br>;; communications error to [REDACTED: server eth0 physical IPv4 address]#53: end of file<br><br>;; communications error to [REDACTED: server eth0 physical IPv4 address]#53: end of file</div><div><br></div><div>This is, by the way, how the iface shows up in the system:</div><div>266: host-veth@if265: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000<br>    link/ether d6:35:97:b9:51:f0 brd ff:ff:ff:ff:ff:ff link-netns fakepod<br>    inet6 fe80::d435:97ff:feb9:51f0/64 scope link<br>       valid_lft forever preferred_lft forever</div><div><br></div><div>And dnsmasq will recognize it as IPv6. I added some debug prints</div><div>to verify that it happens. Incoming TCP addr sa_family is 0x2, iface</div><div>sa_family is 0xA.</div><div><br></div><div>I think the IPv6 address that is attached to the veth host end is added</div><div>by the OS.</div><div><br></div><div>Hopefully all of the above is helpful.</div><div><br></div></div><br><div class="gmail_quote gmail_quote_container"><div dir="ltr" class="gmail_attr">On Wed, Dec 3, 2025 at 10:34 PM Simon Kelley <<a href="mailto:simon@thekelleys.org.uk">simon@thekelleys.org.uk</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><br>
<br>
On 12/3/25 12:39, Sławomir Zborowski wrote:<br>
> Hello,<br>
> <br>
> In the source code (commit eb601683820723df89858cfa695aa131012f1a63),<br>
> in function `do_tcp_connection` client connections are checked. At least <br>
> when options like<br>
> OPT_NOWILD are not enabled.<br>
> <br>
> The code seems to go through all interfaces reported by the OS and find <br>
> matching one<br>
> before allowing query to proceed further.<br>
> <br>
> Following piece of code seems to be responsible for finding matching iface:<br>
> <br>
>       for (iface = daemon->interfaces; iface; iface = iface->next)<br>
>         if (iface->index == if_index && iface->addr.sa.sa_family == <br>
> tcp_addr.sa.sa_family)<br>
>           break;<br>
> <br>
> However, in some Kubernetes setups, at least in these which use Calico for<br>
> networking, the network interfaces show up as IPv6, so iface- <br>
>  >adrrs.sa.sa_family<br>
> is AF_INET6, but the traffic that goes through is IPv4, so <br>
> tcp_addr.sa.sa_family<br>
> is AF_INET.<br>
> <br>
> Unfortunately I'm not well-educated w.r.t. IPv6, so I don't understand <br>
> how it's<br>
> all realized, but due to that mismatch, TCP connections are abruptly <br>
> closed and entire<br>
> downstream fails. In our case it's CoreDNS that considers dnsmasq <br>
> unhealthy and<br>
> bombards it with health checks NS <Root>.<br>
> <br>
> Now, this can be fixed by using bind-interfaces/-z, but that seems to be <br>
> bad choice,<br>
> as per the manual, which reads:<br>
> <br>
>  > About the only time when this is useful is when running another <br>
> nameserver<br>
>  > (or another instance of dnsmasq) on the same machine.<br>
> <br>
> My question is whether the AF_INET/AF_INET6 mismatch is handled correctly?<br>
> Shouldn't dnsmasq allow ipv4 queries originating from inet6 ifaces?<br>
<br>
There's not really such a thing as an "inet interface" or an "inet6 <br>
interface" an interface, represented by an index, can have multiple <br>
addresses, both IPv4 and IPv6.<br>
<br>
What I would expect to see here is that the interface had both IPv4 <br>
addresses and IPv6 addresses when it was added to the daemon->interfaces <br>
list, so this check will find at least one entry on that list which came <br>
from the arrival interface and has the correct address family.<br>
<br>
<br>
Your description implies that the TCP connection is over IPv4. Does the <br>
interface is arrives on have an IP4 address?<br>
<br>
If it does, did it have an IPv4 address when dnsmasq was started? There <br>
may be problems with dnsmasq tracking changes to network configuration.<br>
<br>
If it doesn't, that's very odd and needs more investigation.<br>
<br>
As usual, the most useful resource here is the simplest configuration <br>
which demonstrates this problem on the most vanilla kernel network <br>
configuration.<br>
<br>
<br>
Cheers,<br>
<br>
Simon.<br>
<br>
> <br>
> An if not, I assume that workaround should be placed elsewhere?<br>
> <br>
> -- <br>
> Best Regards, Sławomir Zborowski<br>
> <br>
> _______________________________________________<br>
> Dnsmasq-discuss mailing list<br>
> <a href="mailto:Dnsmasq-discuss@lists.thekelleys.org.uk" target="_blank">Dnsmasq-discuss@lists.thekelleys.org.uk</a><br>
> <a href="https://lists.thekelleys.org.uk/cgi-bin/mailman/listinfo/dnsmasq-discuss" rel="noreferrer" target="_blank">https://lists.thekelleys.org.uk/cgi-bin/mailman/listinfo/dnsmasq-discuss</a><br>
<br>
<br>
_______________________________________________<br>
Dnsmasq-discuss mailing list<br>
<a href="mailto:Dnsmasq-discuss@lists.thekelleys.org.uk" target="_blank">Dnsmasq-discuss@lists.thekelleys.org.uk</a><br>
<a href="https://lists.thekelleys.org.uk/cgi-bin/mailman/listinfo/dnsmasq-discuss" rel="noreferrer" target="_blank">https://lists.thekelleys.org.uk/cgi-bin/mailman/listinfo/dnsmasq-discuss</a><br>
</blockquote></div>