On Mon, Mar 03, 2025 at 11:41:48AM -0500, Jon Maloy wrote:On 2025-03-03 07:07, 7ppKb5bW wrote:[snip]In fact, I think the point our mystery person is making here is subtly different from the v4 vs v6 thing I raised earlier in the discussion. I was talking about possible future cases where we might be using a different IP version on the host than we're using for the guest (e.g. CLAT). For that we'd need to pick our generated ICMP version based on the addresses in the flow - and rather more complicated we'd need to be prepared to do translation between ICMPv4 and ICMPv6 errors. The point that 7ppKb5bW is raising here, is that a dual-stack socket (mostly) counts as an IPv6 socket and will show the cmsg_level accordingly, even though it can also receive ICMPv4 errors. I don't think it's urgent to fix this before merging the series, because we're only handling errors on reply sockets for now, and we don't use dual-stack sockets for those. We should fix it as a follow up, though, which I believe we can do fairly easily by looking at ee_origin, instead of cmsg_level. -- David Gibson (he or they) | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you, not the other way | around. http://www.ozlabs.org/~dgibsonYes, this was mentioned at some point during our discussions, and we should eventually handle it, but it is really outside the scope of the current series.- udp_send_conn_fail_icmp4(c, ee, toside, data, rc); + size_t dlen = rc; + + if (hdr->cmsg_level == IPPROTO_IP) { + dlen = MIN(dlen, ICMP4_MAX_DLEN); + udp_send_conn_fail_icmp4(c, ee, toside, data, dlen); + } else if (hdr->cmsg_level == IPPROTO_IPV6) { + udp_send_conn_fail_icmp6(c, ee, toside, data, + dlen, sidx.flowi); + } } else { trace("Ignoring received IP_RECVERR cmsg on listener socket"); }If the socket is dual-stack, cmsg_level may not match cmsg_data. ``` #dual-stack-test.py from socket import * import time IP_RECVERR=0xb with socket(AF_INET6,SOCK_DGRAM,IPPROTO_UDP) as sock: sock.setsockopt(IPPROTO_IP,IP_RECVERR,1) sock.setsockopt(IPPROTO_IP,IP_TTL,1) packet=bytes(8) sock.sendto(packet,("::ffff:151.101.1.6",443)) time.sleep(0.1) print(sock.recvmsg(1472,1024,MSG_ERRQUEUE)) ```