Index | Thread | Search

From:
Denis Fondras <openbsd@ledeuns.net>
Subject:
Re: IPv4 route with IPv6 gateway
To:
"Nitsche, Elia" <elia.nitsche@tuwien.ac.at>
Cc:
"tech@openbsd.org" <tech@openbsd.org>, "cjeker@diehard.n-r-g.com" <cjeker@diehard.n-r-g.com>
Date:
Thu, 13 Aug 2026 09:15:00 +0200

Download raw body.

Thread
Le Sun, Aug 02, 2026 at 09:34:29PM +0000, Nitsche, Elia a écrit :
> 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.
> 

Yes, it works fine for the general "Internet" usage.
However I cannot get NFS to work but I guess this has more to do with NFS than
this diff :D

Thank you for your work on this.

> 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