Re: IPv4 route with IPv6 gateway

"Nitsche, Elia" <[email protected]> Sun, 2 Aug 2026 21:34:29 +0000
Newsgroups gmane.os.openbsd.tech
Message-ID <[email protected]>
--_000_fcf302c9477646eaaaceb978636d403dtuwienacat_
Content-Type: text/plain; charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

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
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
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 !=3D NULL)
+        af =3D rt_key(rt)->sa_family;
+    else
+        af =3D dst->sa_family;

-    switch (dst->sa_family) {
+    switch (af) {
     case AF_INET:
         ifcap =3D IFCAP_TSOv4;
         break;
@@ -953,7 +958,10 @@ if_output_tso(struct ifnet *ifp, struct
         return error;

     if ((*mp)->m_pkthdr.len <=3D 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
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
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 =3D (struct arpcom *)ifp;
-    sa_family_t af =3D dst->sa_family;
     int error =3D 0;

+    sa_family_t af;
+    if (rt !=3D NULL)
+        af =3D rt_key(rt)->sa_family;
+    else
+        // fallback
+        af =3D 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 =3D htons(ETHERTYPE_IP);
+        break;
+#ifdef INET6
+    case AF_INET6:
+        eh->ether_type =3D htons(ETHERTYPE_IPV6);
+        break;
+#endif
+    }
+
+    /* resolve LL depending on the af of dst */
+    switch (dst->sa_family) {
+    case AF_INET:
         error =3D arpresolve(ifp, rt, m, dst, eh->ether_dhost);
         if (error)
             return (error);
-        eh->ether_type =3D htons(ETHERTYPE_IP);

         /*
          * If broadcasting on a simplex interface, loopback a copy.
@@ -265,7 +283,6 @@ ether_resolve(struct ifnet *ifp, struct
         error =3D nd6_resolve(ifp, rt, m, dst, eh->ether_dhost);
         if (error)
             return (error);
-        eh->ether_type =3D htons(ETHERTYPE_IPV6);
         break;
 #endif
 #ifdef MPLS
Index: netinet/in.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
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 7=
600) */
 #define    INADDR_BROADCAST    __IPADDR(0xffffffff)    /* must be masked *=
/
 #ifndef _KERNEL
Index: netinet/ip_output.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
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 =3D=3D INADDR_ANY && ia)
             ip->ip_src =3D ia->ia_addr.sin_addr;
+        /* if ia has not set an address */
+        if (ip->ip_src.s_addr =3D=3D INADDR_ANY) {    //dev
+            ip->ip_src.s_addr =3D INADDR_DUMMY;
+        }
     }

 #ifdef IPSEC

--_000_fcf302c9477646eaaaceb978636d403dtuwienacat_
Content-Type: text/html; charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

<html>
<head>
<meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3Diso-8859-=
1">
<style type=3D"text/css" style=3D"display:none;"><!-- P {margin-top:0;margi=
n-bottom:0;} --></style>
</head>
<body dir=3D"ltr">
<div id=3D"divtagdefaultwrapper" style=3D"font-size: 12pt; color: rgb(0, 0,=
 0); font-family: Calibri, Helvetica, sans-serif, &quot;EmojiFont&quot;, &q=
uot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, NotoColorEmoji, &q=
uot;Segoe UI Symbol&quot;, &quot;Android Emoji&quot;, EmojiSymbols;" dir=3D=
"ltr">
<p>Here <span>another</span>&nbsp;go at a diff.</p>
<p><br>
This one uses rt-&gt;rt_dst directly (with fallback to dst)</p>
<p>(because prob. we always want to send a v4 packet to a v4 target&nbsp;ad=
dress)</p>
<p>So no need to change the function header.</p>
<p><br>
</p>
<p>I tested deleting the arp and ndp caches while pinging or downloading an=
d</p>
<p>it seems fine.</p>
<div style=3D"color: rgb(0, 0, 0);"><br>
</div>
<div style=3D"color: rgb(0, 0, 0);">This also sets the ip source address of=
 icmp messages to 192.0.0.8, if no&nbsp;</div>
<div style=3D"color: rgb(0, 0, 0);">valid ip was found on the interface.</d=
iv>
<div style=3D"color: rgb(0, 0, 0);"><br>
elia</div>
<div style=3D"color: rgb(0, 0, 0);"><br>
</div>
<div style=3D"color: rgb(0, 0, 0);"><br>
</div>
<div style=3D"color: rgb(0, 0, 0);"><br>
</div>
<div style=3D"color: rgb(0, 0, 0);">
<div>Index: net/if.c<br>
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D<br>
RCS file: /cvs/src/sys/net/if.c,v<br>
diff -u -p -r1.763 if.c<br>
--- net/if.c&nbsp; &nbsp; 22 Mar 2026 23:14:00 -0000&nbsp; &nbsp; 1.763<br>
&#43;&#43;&#43; net/if.c&nbsp; &nbsp; 2 Aug 2026 15:30:46 -0000<br>
@@ -928,8 &#43;928,13 @@ if_output_tso(struct ifnet *ifp, struct<br>
&nbsp;{<br>
&nbsp; &nbsp; &nbsp;uint32_t ifcap;<br>
&nbsp; &nbsp; &nbsp;int error;<br>
&#43;&nbsp; &nbsp; sa_family_t af;<br>
&#43;&nbsp; &nbsp; if (rt !=3D NULL)<br>
&#43;&nbsp; &nbsp; &nbsp; &nbsp; af =3D rt_key(rt)-&gt;sa_family;<br>
&#43;&nbsp; &nbsp; else<br>
&#43;&nbsp; &nbsp; &nbsp; &nbsp; af =3D dst-&gt;sa_family;<br>
<br>
-&nbsp; &nbsp; switch (dst-&gt;sa_family) {<br>
&#43;&nbsp; &nbsp; switch (af) {<br>
&nbsp; &nbsp; &nbsp;case AF_INET:<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ifcap =3D IFCAP_TSOv4;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;break;<br>
@@ -953,7 &#43;958,10 @@ if_output_tso(struct ifnet *ifp, struct<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return error;<br>
<br>
&nbsp; &nbsp; &nbsp;if ((*mp)-&gt;m_pkthdr.len &lt;=3D mtu) {<br>
&#43;&nbsp; &nbsp; &nbsp; &nbsp; /*<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;switch (dst-&gt;sa_family) {<br>
&#43;&nbsp; &nbsp; &nbsp; &nbsp; */<br>
&#43;&nbsp; &nbsp; &nbsp; &nbsp; switch (af) {&nbsp; &nbsp; //dev<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;case AF_INET:<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;in_hdr_cksum_out(*mp, ifp);=
<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;in_proto_cksum_out(*mp, ifp=
);<br>
Index: net/if_ethersubr.c<br>
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D<br>
RCS file: /cvs/src/sys/net/if_ethersubr.c,v<br>
diff -u -p -r1.308 if_ethersubr.c<br>
--- net/if_ethersubr.c&nbsp; &nbsp; 19 Dec 2025 02:04:13 -0000&nbsp; &nbsp;=
 1.308<br>
&#43;&#43;&#43; net/if_ethersubr.c&nbsp; &nbsp; 2 Aug 2026 15:30:46 -0000<b=
r>
@@ -220,9 &#43;220,15 @@ ether_resolve(struct ifnet *ifp, struct<br>
&nbsp; &nbsp; &nbsp;struct rtentry *rt, struct ether_header *eh)<br>
&nbsp;{<br>
&nbsp; &nbsp; &nbsp;struct arpcom *ac =3D (struct arpcom *)ifp;<br>
-&nbsp; &nbsp; sa_family_t af =3D dst-&gt;sa_family;<br>
&nbsp; &nbsp; &nbsp;int error =3D 0;<br>
<br>
&#43;&nbsp; &nbsp; sa_family_t af;<br>
&#43;&nbsp; &nbsp; if (rt !=3D NULL)<br>
&#43;&nbsp; &nbsp; &nbsp; &nbsp; af =3D rt_key(rt)-&gt;sa_family;<br>
&#43;&nbsp; &nbsp; else<br>
&#43;&nbsp; &nbsp; &nbsp; &nbsp; // fallback<br>
&#43;&nbsp; &nbsp; &nbsp; &nbsp; af =3D dst-&gt;sa_family;<br>
&#43;<br>
&nbsp; &nbsp; &nbsp;if (!ISSET(ifp-&gt;if_flags, IFF_RUNNING))<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;senderr(ENETDOWN);<br>
<br>
@@ -236,13 &#43;242,25 @@ ether_resolve(struct ifnet *ifp, struct<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ifp-&gt;if_rdomain, rtable_=
l2(m-&gt;m_pkthdr.ph_rtableid));<br>
&nbsp; &nbsp; &nbsp;}<br>
&nbsp;#endif<br>
-<br>
&#43;&nbsp; &nbsp;&nbsp;<br>
&#43;&nbsp; &nbsp; /* packet type depends on af of rt-&gt;rt_dst (this migh=
t get overwritten later) */<br>
&nbsp; &nbsp; &nbsp;switch (af) {<br>
&nbsp; &nbsp; &nbsp;case AF_INET:<br>
&#43;&nbsp; &nbsp; &nbsp; &nbsp; eh-&gt;ether_type =3D htons(ETHERTYPE_IP);=
<br>
&#43;&nbsp; &nbsp; &nbsp; &nbsp; break;<br>
&#43;#ifdef INET6<br>
&#43;&nbsp; &nbsp; case AF_INET6:<br>
&#43;&nbsp; &nbsp; &nbsp; &nbsp; eh-&gt;ether_type =3D htons(ETHERTYPE_IPV6=
);<br>
&#43;&nbsp; &nbsp; &nbsp; &nbsp; break;<br>
&#43;#endif<br>
&#43;&nbsp; &nbsp; }<br>
&#43;<br>
&#43;&nbsp; &nbsp; /* resolve LL depending on the af of dst */<br>
&#43;&nbsp; &nbsp; switch (dst-&gt;sa_family) {<br>
&#43;&nbsp; &nbsp; case AF_INET:<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;error =3D arpresolve(ifp, rt, m, dst, eh-=
&gt;ether_dhost);<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (error)<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return (error);<br>
-&nbsp; &nbsp; &nbsp; &nbsp; eh-&gt;ether_type =3D htons(ETHERTYPE_IP);<br>
<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;/*<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; * If broadcasting on a simplex interface=
, loopback a copy.<br>
@@ -265,7 &#43;283,6 @@ ether_resolve(struct ifnet *ifp, struct<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;error =3D nd6_resolve(ifp, rt, m, dst, eh=
-&gt;ether_dhost);<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (error)<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return (error);<br>
-&nbsp; &nbsp; &nbsp; &nbsp; eh-&gt;ether_type =3D htons(ETHERTYPE_IPV6);<b=
r>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;break;<br>
&nbsp;#endif<br>
&nbsp;#ifdef MPLS</div>
<div>
<div>Index: netinet/in.h<br>
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D<br>
RCS file: /cvs/src/sys/netinet/in.h,v<br>
diff -u -p -r1.149 in.h<br>
--- netinet/in.h&nbsp; &nbsp; 2 Mar 2025 21:28:32 -0000&nbsp; &nbsp; 1.149<=
br>
&#43;&#43;&#43; netinet/in.h&nbsp; &nbsp; 2 Aug 2026 21:19:18 -0000<br>
@@ -237,6 &#43;237,7 @@ struct in_addr {<br>
&nbsp;#endif&nbsp; &nbsp; /* _KERNEL */<br>
<br>
&nbsp;#define&nbsp; &nbsp; INADDR_ANY&nbsp; &nbsp; &nbsp; &nbsp; __IPADDR(0=
x00000000)<br>
&nbsp;#define&nbsp; &nbsp; INADDR_LOOPBACK&nbsp; &nbsp; &nbsp; &nbsp; __IPA=
DDR(0x7f000001)</div>
<div><span id=3D"ms-rterangepaste-start"></span><span>&#43;#define&nbsp; &n=
bsp; INADDR_DUMMY&nbsp; &nbsp; &nbsp; &nbsp; __IPADDR(0xc0000008)&nbsp; &nb=
sp; /* 192.0.0.8 (RFC 7600) */</span><span id=3D"ms-rterangepaste-end"></sp=
an><br>
&nbsp;#define&nbsp; &nbsp; INADDR_BROADCAST&nbsp; &nbsp; __IPADDR(0xfffffff=
f)&nbsp; &nbsp; /* must be masked */<br>
&nbsp;#ifndef _KERNEL<br>
Index: netinet/ip_output.c<br>
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D<br>
RCS file: /cvs/src/sys/netinet/ip_output.c,v<br>
diff -u -p -r1.419 ip_output.c<br>
--- netinet/ip_output.c&nbsp; &nbsp; 17 Jul 2026 18:51:29 -0000&nbsp; &nbsp=
; 1.419<br>
&#43;&#43;&#43; netinet/ip_output.c&nbsp; &nbsp; 2 Aug 2026 21:19:19 -0000<=
br>
@@ -218,6 &#43;218,10 @@ reroute:<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;/* Set the source IP address */<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (ip-&gt;ip_src.s_addr =3D=3D INADDR_AN=
Y &amp;&amp; ia)<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ip-&gt;ip_src =3D ia-&gt;ia=
_addr.sin_addr;<br>
&#43;&nbsp; &nbsp; &nbsp; &nbsp; /* if ia has not set an address */<br>
&#43;&nbsp; &nbsp; &nbsp; &nbsp; if (ip-&gt;ip_src.s_addr =3D=3D INADDR_ANY=
) {&nbsp; &nbsp; //dev<br>
&#43;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ip-&gt;ip_src.s_addr =3D INA=
DDR_DUMMY;<br>
&#43;&nbsp; &nbsp; &nbsp; &nbsp; }<br>
&nbsp; &nbsp; &nbsp;}<br>
<br>
&nbsp;#ifdef IPSEC</div>
</div>
</div>
</div>
</body>
</html>

--_000_fcf302c9477646eaaaceb978636d403dtuwienacat_--