From: "Nitsche, Elia" Subject: Re: IPv4 route with IPv6 gateway To: "tech@openbsd.org" Date: Mon, 14 Sep 2026 09:23:07 +0000 Hello, what would make this diff merge able? elia Index: net/if.c =================================================================== RCS file: /cvs/src/sys/net/if.c,v diff -u -p -u -r1.763 if.c --- net/if.c 22 Mar 2026 23:14:00 -0000 1.763 +++ net/if.c 15 Aug 2026 12:38:48 -0000 @@ -928,8 +928,13 @@ if_output_tso(struct ifnet *ifp, struct { uint32_t ifcap; int error; + sa_family_t af; + if (rt != NULL) + af = rt_key(rt)->sa_family; + else + af = dst->sa_family; - switch (dst->sa_family) { + switch (af) { case AF_INET: ifcap = IFCAP_TSOv4; break; @@ -953,7 +958,7 @@ if_output_tso(struct ifnet *ifp, struct return error; if ((*mp)->m_pkthdr.len <= mtu) { - switch (dst->sa_family) { + switch (af) { case AF_INET: in_hdr_cksum_out(*mp, ifp); in_proto_cksum_out(*mp, ifp); Index: net/if_ethersubr.c =================================================================== RCS file: /cvs/src/sys/net/if_ethersubr.c,v diff -u -p -u -r1.308 if_ethersubr.c --- net/if_ethersubr.c 19 Dec 2025 02:04:13 -0000 1.308 +++ net/if_ethersubr.c 15 Aug 2026 12:38:48 -0000 @@ -220,9 +220,15 @@ ether_resolve(struct ifnet *ifp, struct struct rtentry *rt, struct ether_header *eh) { struct arpcom *ac = (struct arpcom *)ifp; - sa_family_t af = dst->sa_family; int error = 0; + sa_family_t af; + if (rt != NULL) + af = rt_key(rt)->sa_family; + else + // fallback + af = dst->sa_family; + if (!ISSET(ifp->if_flags, IFF_RUNNING)) senderr(ENETDOWN); @@ -237,12 +243,24 @@ ether_resolve(struct ifnet *ifp, struct } #endif + /* packet type depends on af of rt->rt_dst (this might get overwritten later) */ switch (af) { case AF_INET: + eh->ether_type = htons(ETHERTYPE_IP); + break; +#ifdef INET6 + case AF_INET6: + eh->ether_type = htons(ETHERTYPE_IPV6); + break; +#endif + } + + /* resolve LL depending on the af of dst */ + switch (dst->sa_family) { + case AF_INET: error = arpresolve(ifp, rt, m, dst, eh->ether_dhost); if (error) return (error); - eh->ether_type = htons(ETHERTYPE_IP); /* * If broadcasting on a simplex interface, loopback a copy. @@ -265,7 +283,6 @@ ether_resolve(struct ifnet *ifp, struct error = nd6_resolve(ifp, rt, m, dst, eh->ether_dhost); if (error) return (error); - eh->ether_type = htons(ETHERTYPE_IPV6); break; #endif #ifdef MPLS Index: netinet/in.h =================================================================== RCS file: /cvs/src/sys/netinet/in.h,v diff -u -p -u -r1.149 in.h --- netinet/in.h 2 Mar 2025 21:28:32 -0000 1.149 +++ netinet/in.h 15 Aug 2026 12:38:48 -0000 @@ -238,6 +238,7 @@ struct in_addr { #define INADDR_ANY __IPADDR(0x00000000) #define INADDR_LOOPBACK __IPADDR(0x7f000001) +#define INADDR_DUMMY __IPADDR(0xc0000008) /* 192.0.0.8 (RFC 7600) */ #define INADDR_BROADCAST __IPADDR(0xffffffff) /* must be masked */ #ifndef _KERNEL #define INADDR_NONE __IPADDR(0xffffffff) /* -1 return */ Index: netinet/ip_output.c =================================================================== RCS file: /cvs/src/sys/netinet/ip_output.c,v diff -u -p -u -r1.419 ip_output.c --- netinet/ip_output.c 17 Jul 2026 18:51:29 -0000 1.419 +++ netinet/ip_output.c 15 Aug 2026 12:38:48 -0000 @@ -218,6 +218,9 @@ reroute: /* Set the source IP address */ if (ip->ip_src.s_addr == INADDR_ANY && ia) ip->ip_src = ia->ia_addr.sin_addr; + /* if ia has not set an address */ + if (ip->ip_src.s_addr == INADDR_ANY) + ip->ip_src.s_addr = INADDR_DUMMY; } #ifdef IPSEC