Index | Thread | Search

From:
"Nitsche, Elia" <elia.nitsche@tuwien.ac.at>
Subject:
Re: IPv4 route with IPv6 gateway
To:
"tech@openbsd.org" <tech@openbsd.org>
Cc:
"cjeker@diehard.n-r-g.com" <cjeker@diehard.n-r-g.com>, "openbsd@ledeuns.net" <openbsd@ledeuns.net>
Date:
Sun, 2 Aug 2026 21:34:29 +0000

Download raw body.

Thread
Here another go at a diff.

This one uses rt->rt_dst directly (with fallback to dst)

(because prob. we always want to send a v4 packet to a v4 target address)

So no need to change the function header.


I tested deleting the arp and ndp caches while pinging or downloading and

it seems fine.

This also sets the ip source address of icmp messages to 192.0.0.8, if no
valid ip was found on the interface.

elia



Index: net/if.c
===================================================================
RCS file: /cvs/src/sys/net/if.c,v
diff -u -p -r1.763 if.c
--- net/if.c    22 Mar 2026 23:14:00 -0000    1.763
+++ net/if.c    2 Aug 2026 15:30:46 -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,10 @@ if_output_tso(struct ifnet *ifp, struct
         return error;

     if ((*mp)->m_pkthdr.len <= mtu) {
+        /*
         switch (dst->sa_family) {
+        */
+        switch (af) {    //dev
         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 -r1.308 if_ethersubr.c
--- net/if_ethersubr.c    19 Dec 2025 02:04:13 -0000    1.308
+++ net/if_ethersubr.c    2 Aug 2026 15:30:46 -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);

@@ -236,13 +242,25 @@ ether_resolve(struct ifnet *ifp, struct
             ifp->if_rdomain, rtable_l2(m->m_pkthdr.ph_rtableid));
     }
 #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 -r1.149 in.h
--- netinet/in.h    2 Mar 2025 21:28:32 -0000    1.149
+++ netinet/in.h    2 Aug 2026 21:19:18 -0000
@@ -237,6 +237,7 @@ struct in_addr {
 #endif    /* _KERNEL */

 #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
Index: netinet/ip_output.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_output.c,v
diff -u -p -r1.419 ip_output.c
--- netinet/ip_output.c    17 Jul 2026 18:51:29 -0000    1.419
+++ netinet/ip_output.c    2 Aug 2026 21:19:19 -0000
@@ -218,6 +218,10 @@ 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) {    //dev
+            ip->ip_src.s_addr = INADDR_DUMMY;
+        }
     }

 #ifdef IPSEC