Index | Thread | Search

From:
Claudio Jeker <cjeker@diehard.n-r-g.com>
Subject:
Re: struct route inet
To:
Alexander Bluhm <alexander.bluhm@gmx.net>
Cc:
tech@openbsd.org
Date:
Tue, 13 Feb 2024 08:43:35 +0100

Download raw body.

Thread
On Mon, Feb 12, 2024 at 10:53:05PM +0100, Alexander Bluhm wrote:
> On Thu, Feb 08, 2024 at 04:07:12PM +0100, Claudio Jeker wrote:
> > > Diff below.  Only compile tested.  But now we have to include the
> > > netinet and netinet6 stuff into route header.  At least I moved
> > > struct route into #ifdef _KERNEL.  Does any user land use struct
> > > route?
> > 
> > Nothing should use that outside of _KERNEL. Not super happy about the
> > reach around but no better idea.
> 
> netstat uses inp_route.  I had to put it in #ifdef __BSD_VISIBLE.
> #include <netinet/in.h> is also in #ifdef __BSD_VISIBLE.

Grrr. is that the kvm bits of netstat that dig into the inp?
 
> > Hmmm. A route cache in the forwarding path only makes sense if we make the
> > input queues sorted by flow so that same source packets are processed back
> > to back. Be careful with percpu caches, I think you want to cache per
> > network task.
> 
> Per CPU is good enough for now.  Pinning softnet thread to CPU is
> something for later.  Per CPU is easy as we have infrastructure
> now.  Due to network queue per CPU and hardware sorting stream this
> is already a huge gain.  But not in this diff.  We can discuss
> later.

The problem with per CPU is that on every rwlock the cpu may change.
So you must be very careful to not have a sleep point or you may end up
with a different cache object.

This is why I think it needs to be a per thread value.
 
> > >  #include <net/if_types.h>
> > > +#include <net/if_types.h>
> > 
> > Double include.
> 
> fixed
> 
> > You could use an anonimous union here and remove those defines.
> 
> I think we have compiler that do not support it.  Do we use anonimous
> union anywhere in the tree?

We do use them in a few places. struct ratelimit_entry in net/wg_cookie.h
is one place. There are probably more in userland -- rpki-client uses them
for example. This is C99 that even gcc3 with its gnu99 support manages.
 
> Diff below passed regress and make release.
> 
> ok?

OK claudio@ (we can further cleanup the c99 bits in tree).
 
> bluhm
> 
> Index: sys/net/if_bridge.c
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/net/if_bridge.c,v
> diff -u -p -r1.368 if_bridge.c
> --- sys/net/if_bridge.c	16 May 2023 14:32:54 -0000	1.368
> +++ sys/net/if_bridge.c	11 Feb 2024 19:52:56 -0000
> @@ -48,6 +48,7 @@
>  #include <net/if_types.h>
>  #include <net/if_llc.h>
>  #include <net/netisr.h>
> +#include <net/route.h>
>  
>  #include <netinet/in.h>
>  #include <netinet/ip.h>
> Index: sys/net/if_etherip.c
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/net/if_etherip.c,v
> diff -u -p -r1.54 if_etherip.c
> --- sys/net/if_etherip.c	23 Dec 2023 10:52:54 -0000	1.54
> +++ sys/net/if_etherip.c	11 Feb 2024 19:52:56 -0000
> @@ -31,6 +31,7 @@
>  #include <net/if_var.h>
>  #include <net/if_dl.h>
>  #include <net/if_media.h>
> +#include <net/route.h>
>  #include <net/rtable.h>
>  
>  #include <netinet/in.h>
> Index: sys/net/if_pfsync.c
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/net/if_pfsync.c,v
> diff -u -p -r1.324 if_pfsync.c
> --- sys/net/if_pfsync.c	23 Dec 2023 10:52:54 -0000	1.324
> +++ sys/net/if_pfsync.c	11 Feb 2024 19:52:56 -0000
> @@ -69,6 +69,7 @@
>  #include <net/if_types.h>
>  #include <net/bpf.h>
>  #include <net/netisr.h>
> +#include <net/route.h>
>  
>  #include <netinet/in.h>
>  #include <netinet/if_ether.h>
> Index: sys/net/if_veb.c
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/net/if_veb.c,v
> diff -u -p -r1.34 if_veb.c
> --- sys/net/if_veb.c	23 Dec 2023 10:52:54 -0000	1.34
> +++ sys/net/if_veb.c	11 Feb 2024 19:52:56 -0000
> @@ -46,7 +46,6 @@
>  #ifdef INET6
>  #include <netinet6/in6_var.h>
>  #include <netinet/ip6.h>
> -#include <netinet6/ip6_var.h>
>  #endif
>  
>  #if 0 && defined(IPSEC)
> Index: sys/net/route.c
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/net/route.c,v
> diff -u -p -r1.431 route.c
> --- sys/net/route.c	9 Feb 2024 14:02:11 -0000	1.431
> +++ sys/net/route.c	11 Feb 2024 19:52:56 -0000
> @@ -212,8 +212,8 @@ route_cache(struct route *ro, struct in_
>  	if (rtisvalid(ro->ro_rt) &&
>  	    ro->ro_generation == gen &&
>  	    ro->ro_tableid == rtableid &&
> -	    ro->ro_dst.sa_family == AF_INET &&
> -	    satosin(&ro->ro_dst)->sin_addr.s_addr == addr.s_addr) {
> +	    ro->ro_dstsa.sa_family == AF_INET &&
> +	    ro->ro_dstsin.sin_addr.s_addr == addr.s_addr) {
>  		ipstat_inc(ips_rtcachehit);
>  		return (0);
>  	}
> @@ -225,17 +225,16 @@ route_cache(struct route *ro, struct in_
>  	ro->ro_tableid = rtableid;
>  
>  	memset(&ro->ro_dst, 0, sizeof(ro->ro_dst));
> -	satosin(&ro->ro_dst)->sin_family = AF_INET;
> -	satosin(&ro->ro_dst)->sin_len = sizeof(struct sockaddr_in);
> -	satosin(&ro->ro_dst)->sin_addr = addr;
> +	ro->ro_dstsin.sin_family = AF_INET;
> +	ro->ro_dstsin.sin_len = sizeof(struct sockaddr_in);
> +	ro->ro_dstsin.sin_addr = addr;
>  
>  	return (ESRCH);
>  }
>  
>  #ifdef INET6
>  int
> -route6_cache(struct route_in6 *ro, const struct in6_addr *addr,
> -    u_int rtableid)
> +route6_cache(struct route *ro, const struct in6_addr *addr, u_int rtableid)
>  {
>  	u_long gen;
>  
> @@ -245,8 +244,8 @@ route6_cache(struct route_in6 *ro, const
>  	if (rtisvalid(ro->ro_rt) &&
>  	    ro->ro_generation == gen &&
>  	    ro->ro_tableid == rtableid &&
> -	    ro->ro_dst.sin6_family == AF_INET6 &&
> -	    IN6_ARE_ADDR_EQUAL(&ro->ro_dst.sin6_addr, addr)) {
> +	    ro->ro_dstsa.sa_family == AF_INET6 &&
> +	    IN6_ARE_ADDR_EQUAL(&ro->ro_dstsin6.sin6_addr, addr)) {
>  		ip6stat_inc(ip6s_rtcachehit);
>  		return (0);
>  	}
> @@ -258,9 +257,9 @@ route6_cache(struct route_in6 *ro, const
>  	ro->ro_tableid = rtableid;
>  
>  	memset(&ro->ro_dst, 0, sizeof(ro->ro_dst));
> -	ro->ro_dst.sin6_family = AF_INET6;
> -	ro->ro_dst.sin6_len = sizeof(struct sockaddr_in6);
> -	ro->ro_dst.sin6_addr = *addr;
> +	ro->ro_dstsin6.sin6_family = AF_INET6;
> +	ro->ro_dstsin6.sin6_len = sizeof(struct sockaddr_in6);
> +	ro->ro_dstsin6.sin6_addr = *addr;
>  
>  	return (ESRCH);
>  }
> Index: sys/net/route.h
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/net/route.h,v
> diff -u -p -r1.205 route.h
> --- sys/net/route.h	5 Feb 2024 12:52:11 -0000	1.205
> +++ sys/net/route.h	11 Feb 2024 19:52:56 -0000
> @@ -370,6 +370,19 @@ struct sockaddr_rtsearch {
>  	char		sr_search[RTSEARCH_LEN];
>  };
>  
> +struct rt_addrinfo {
> +	int	rti_addrs;
> +	const	struct sockaddr *rti_info[RTAX_MAX];
> +	int	rti_flags;
> +	struct	ifaddr *rti_ifa;
> +	struct	rt_msghdr *rti_rtm;
> +	u_char	rti_mpls;
> +};
> +
> +#ifdef __BSD_VISIBLE
> +
> +#include <netinet/in.h>
> +
>  /*
>   * A route consists of a destination address and a reference
>   * to a routing entry.  These are often held by protocols
> @@ -379,17 +392,17 @@ struct route {
>  	struct	rtentry *ro_rt;
>  	u_long		 ro_generation;
>  	u_long		 ro_tableid;	/* u_long because of alignment */
> -	struct	sockaddr ro_dst;
> +	union {
> +		struct	sockaddr	rod_sa;
> +		struct	sockaddr_in	rod_sin;
> +		struct	sockaddr_in6	rod_sin6;
> +	} ro_dst;
> +#define ro_dstsa	ro_dst.rod_sa
> +#define ro_dstsin	ro_dst.rod_sin
> +#define ro_dstsin6	ro_dst.rod_sin6
>  };
>  
> -struct rt_addrinfo {
> -	int	rti_addrs;
> -	const	struct sockaddr *rti_info[RTAX_MAX];
> -	int	rti_flags;
> -	struct	ifaddr *rti_ifa;
> -	struct	rt_msghdr *rti_rtm;
> -	u_char	rti_mpls;
> -};
> +#endif /* __BSD_VISIBLE */
>  
>  #ifdef _KERNEL
>  
> @@ -449,6 +462,8 @@ struct if_ieee80211_data;
>  struct bfd_config;
>  
>  void	 route_init(void);
> +int	 route_cache(struct route *, struct in_addr, u_int);
> +int	 route6_cache(struct route *, const struct in6_addr *, u_int);
>  void	 rtm_ifchg(struct ifnet *);
>  void	 rtm_ifannounce(struct ifnet *, int);
>  void	 rtm_bfd(struct bfd_config *);
> Index: sys/netinet/in.h
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/in.h,v
> diff -u -p -r1.147 in.h
> --- sys/netinet/in.h	9 Feb 2024 14:02:11 -0000	1.147
> +++ sys/netinet/in.h	11 Feb 2024 19:52:56 -0000
> @@ -789,8 +789,6 @@ void	   in_len2mask(struct in_addr *, in
>  int	   in_nam2sin(const struct mbuf *, struct sockaddr_in **);
>  int	   in_sa2sin(struct sockaddr *, struct sockaddr_in **);
>  
> -int	   route_cache(struct route *, struct in_addr, u_int);
> -
>  char	  *inet_ntoa(struct in_addr);
>  int	   inet_nat64(int, const void *, void *, const void *, u_int8_t);
>  int	   inet_nat46(int, const void *, void *, const void *, u_int8_t);
> Index: sys/netinet/in_pcb.c
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/in_pcb.c,v
> diff -u -p -r1.292 in_pcb.c
> --- sys/netinet/in_pcb.c	11 Feb 2024 01:27:45 -0000	1.292
> +++ sys/netinet/in_pcb.c	11 Feb 2024 19:52:56 -0000
> @@ -920,7 +920,7 @@ in_pcbrtentry(struct inpcb *inp)
>  	if (inp->inp_faddr.s_addr == INADDR_ANY)
>  		return (NULL);
>  	if (route_cache(ro, inp->inp_faddr, inp->inp_rtableid)) {
> -		ro->ro_rt = rtalloc_mpath(&ro->ro_dst,
> +		ro->ro_rt = rtalloc_mpath(&ro->ro_dstsa,
>  		    &inp->inp_laddr.s_addr, ro->ro_tableid);
>  	}
>  	return (ro->ro_rt);
> @@ -984,7 +984,7 @@ in_pcbselsrc(struct in_addr *insrc, stru
>  	 */
>  	if (route_cache(ro, sin->sin_addr, rtableid)) {
>  		/* No route yet, so try to acquire one */
> -		ro->ro_rt = rtalloc_mpath(&ro->ro_dst, NULL, ro->ro_tableid);
> +		ro->ro_rt = rtalloc_mpath(&ro->ro_dstsa, NULL, ro->ro_tableid);
>  	}
>  
>  	/*
> Index: sys/netinet/in_pcb.h
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/in_pcb.h,v
> diff -u -p -r1.151 in_pcb.h
> --- sys/netinet/in_pcb.h	11 Feb 2024 01:27:45 -0000	1.151
> +++ sys/netinet/in_pcb.h	11 Feb 2024 19:52:56 -0000
> @@ -150,12 +150,7 @@ struct inpcb {
>  	u_int16_t inp_lport;		/* [t] local port */
>  	struct	  socket *inp_socket;	/* [I] back pointer to socket */
>  	caddr_t	  inp_ppcb;		/* pointer to per-protocol pcb */
> -	union {				/* Route (notice increased size). */
> -		struct route ru_route;
> -		struct route_in6 ru_route6;
> -	} inp_ru;
> -#define	inp_route	inp_ru.ru_route
> -#define	inp_route6	inp_ru.ru_route6
> +	struct    route inp_route;	/* cached route */
>  	struct    refcnt inp_refcnt;	/* refcount PCB, delay memory free */
>  	struct	  mutex inp_mtx;	/* protect PCB and socket members */
>  	int	  inp_flags;		/* generic IP/datagram flags */
> Index: sys/netinet/ip_carp.c
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/ip_carp.c,v
> diff -u -p -r1.360 ip_carp.c
> --- sys/netinet/ip_carp.c	23 Dec 2023 10:52:54 -0000	1.360
> +++ sys/netinet/ip_carp.c	11 Feb 2024 19:52:56 -0000
> @@ -54,6 +54,7 @@
>  #include <net/if_var.h>
>  #include <net/if_types.h>
>  #include <net/netisr.h>
> +#include <net/route.h>
>  
>  #include <crypto/sha1.h>
>  
> Index: sys/netinet/ip_input.c
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/ip_input.c,v
> diff -u -p -r1.388 ip_input.c
> --- sys/netinet/ip_input.c	31 Jan 2024 14:56:42 -0000	1.388
> +++ sys/netinet/ip_input.c	11 Feb 2024 19:52:56 -0000
> @@ -1494,7 +1494,7 @@ ip_forward(struct mbuf *m, struct ifnet 
>  	route_cache(&ro, ip->ip_dst, m->m_pkthdr.ph_rtableid);
>  	if (!rtisvalid(rt)) {
>  		rtfree(rt);
> -		rt = rtalloc_mpath(&ro.ro_dst, &ip->ip_src.s_addr,
> +		rt = rtalloc_mpath(&ro.ro_dstsa, &ip->ip_src.s_addr,
>  		    m->m_pkthdr.ph_rtableid);
>  		if (rt == NULL) {
>  			ipstat_inc(ips_noroute);
> Index: sys/netinet/ip_output.c
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/ip_output.c,v
> diff -u -p -r1.394 ip_output.c
> --- sys/netinet/ip_output.c	31 Jan 2024 14:56:43 -0000	1.394
> +++ sys/netinet/ip_output.c	11 Feb 2024 19:52:56 -0000
> @@ -167,7 +167,7 @@ reroute:
>  	 * destination and is still up.  If not, free it and try again.
>  	 */
>  	route_cache(ro, ip->ip_dst, m->m_pkthdr.ph_rtableid);
> -	dst = satosin(&ro->ro_dst);
> +	dst = &ro->ro_dstsin;
>  
>  	if ((IN_MULTICAST(ip->ip_dst.s_addr) ||
>  	    (ip->ip_dst.s_addr == INADDR_BROADCAST)) &&
> @@ -185,7 +185,7 @@ reroute:
>  		struct in_ifaddr *ia;
>  
>  		if (ro->ro_rt == NULL)
> -			ro->ro_rt = rtalloc_mpath(&ro->ro_dst,
> +			ro->ro_rt = rtalloc_mpath(&ro->ro_dstsa,
>  			    &ip->ip_src.s_addr, ro->ro_tableid);
>  
>  		if (ro->ro_rt == NULL) {
> @@ -253,7 +253,7 @@ reroute:
>  		 * still points to the address in "ro".  (It may have been
>  		 * changed to point to a gateway address, above.)
>  		 */
> -		dst = satosin(&ro->ro_dst);
> +		dst = &ro->ro_dstsin;
>  
>  		/*
>  		 * See if the caller provided any multicast options
> @@ -455,7 +455,7 @@ sendit:
>  			rtfree(ro->ro_rt);
>  			ro->ro_tableid = orig_rtableid;
>  			ro->ro_rt = icmp_mtudisc_clone(
> -			    satosin(&ro->ro_dst)->sin_addr, ro->ro_tableid, 0);
> +			    ro->ro_dstsin.sin_addr, ro->ro_tableid, 0);
>  		}
>  #endif
>  		/*
> @@ -558,7 +558,8 @@ ip_output_ipsec_pmtu_update(struct tdb *
>  		rt->rt_mtu = tdb->tdb_mtu;
>  		if (ro != NULL && ro->ro_rt != NULL) {
>  			rtfree(ro->ro_rt);
> -			ro->ro_rt = rtalloc(&ro->ro_dst, RT_RESOLVE, rtableid);
> +			ro->ro_rt = rtalloc(&ro->ro_dstsa, RT_RESOLVE,
> +			    rtableid);
>  		}
>  		if (rt_mtucloned)
>  			rtfree(rt);
> Index: sys/netinet/ip_var.h
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/ip_var.h,v
> diff -u -p -r1.112 ip_var.h
> --- sys/netinet/ip_var.h	5 Feb 2024 23:16:39 -0000	1.112
> +++ sys/netinet/ip_var.h	11 Feb 2024 19:52:56 -0000
> @@ -227,6 +227,7 @@ extern const struct pr_usrreqs rip_usrre
>  
>  extern struct rttimer_queue ip_mtudisc_timeout_q;
>  extern struct pool ipqent_pool;
> +struct rtentry;
>  struct route;
>  struct inpcb;
>  
> Index: sys/netinet/tcp_input.c
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/tcp_input.c,v
> diff -u -p -r1.400 tcp_input.c
> --- sys/netinet/tcp_input.c	11 Feb 2024 01:27:45 -0000	1.400
> +++ sys/netinet/tcp_input.c	11 Feb 2024 19:52:56 -0000
> @@ -145,8 +145,8 @@ struct timeval tcp_ackdrop_ppslim_last;
>  #define ND6_HINT(tp) \
>  do { \
>  	if (tp && tp->t_inpcb && (tp->t_inpcb->inp_flags & INP_IPV6) &&	\
> -	    rtisvalid(tp->t_inpcb->inp_route6.ro_rt)) {			\
> -		nd6_nud_hint(tp->t_inpcb->inp_route6.ro_rt);		\
> +	    rtisvalid(tp->t_inpcb->inp_route.ro_rt)) {			\
> +		nd6_nud_hint(tp->t_inpcb->inp_route.ro_rt);		\
>  	} \
>  } while (0)
>  #else
> @@ -3166,7 +3166,7 @@ syn_cache_put(struct syn_cache *sc)
>  
>  	/* Dealing with last reference, no lock needed. */
>  	m_free(sc->sc_ipopts);
> -	rtfree(sc->sc_route4.ro_rt);
> +	rtfree(sc->sc_route.ro_rt);
>  
>  	pool_put(&syn_cache_pool, sc);
>  }
> @@ -3578,13 +3578,8 @@ syn_cache_get(struct sockaddr *src, stru
>  	/*
>  	 * Give the new socket our cached route reference.
>  	 */
> -	if (src->sa_family == AF_INET)
> -		inp->inp_route = sc->sc_route4;         /* struct assignment */
> -#ifdef INET6
> -	else
> -		inp->inp_route6 = sc->sc_route6;
> -#endif
> -	sc->sc_route4.ro_rt = NULL;
> +	inp->inp_route = sc->sc_route;		/* struct assignment */
> +	sc->sc_route.ro_rt = NULL;
>  
>  	am = m_get(M_DONTWAIT, MT_SONAME);	/* XXX */
>  	if (am == NULL)
> @@ -4152,7 +4147,7 @@ syn_cache_respond(struct syn_cache *sc, 
>  		if (inp != NULL)
>  			ip->ip_tos = inp->inp_ip.ip_tos;
>  
> -		error = ip_output(m, sc->sc_ipopts, &sc->sc_route4,
> +		error = ip_output(m, sc->sc_ipopts, &sc->sc_route,
>  		    (ip_mtudisc ? IP_MTUDISC : 0),  NULL,
>  		    inp ? inp->inp_seclevel : NULL, 0);
>  		break;
> @@ -4164,7 +4159,7 @@ syn_cache_respond(struct syn_cache *sc, 
>  		ip6->ip6_hlim = in6_selecthlim(inp);
>  		/* leave flowlabel = 0, it is legal and require no state mgmt */
>  
> -		error = ip6_output(m, NULL /*XXX*/, &sc->sc_route6, 0,
> +		error = ip6_output(m, NULL /*XXX*/, &sc->sc_route, 0,
>  		    NULL, inp ? inp->inp_seclevel : NULL);
>  		break;
>  #endif
> Index: sys/netinet/tcp_output.c
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/tcp_output.c,v
> diff -u -p -r1.142 tcp_output.c
> --- sys/netinet/tcp_output.c	11 Feb 2024 01:27:45 -0000	1.142
> +++ sys/netinet/tcp_output.c	11 Feb 2024 19:52:56 -0000
> @@ -1109,7 +1109,7 @@ send:
>  #endif
>  		}
>  		error = ip6_output(m, tp->t_inpcb->inp_outputopts6,
> -		    &tp->t_inpcb->inp_route6, 0, NULL,
> +		    &tp->t_inpcb->inp_route, 0, NULL,
>  		    tp->t_inpcb->inp_seclevel);
>  		break;
>  #endif /* INET6 */
> Index: sys/netinet/tcp_subr.c
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/tcp_subr.c,v
> diff -u -p -r1.198 tcp_subr.c
> --- sys/netinet/tcp_subr.c	11 Feb 2024 01:27:45 -0000	1.198
> +++ sys/netinet/tcp_subr.c	11 Feb 2024 19:52:56 -0000
> @@ -401,7 +401,7 @@ tcp_respond(struct tcpcb *tp, caddr_t te
>  		ip6->ip6_plen = tlen - sizeof(struct ip6_hdr);
>  		ip6->ip6_plen = htons(ip6->ip6_plen);
>  		ip6_output(m, tp ? tp->t_inpcb->inp_outputopts6 : NULL,
> -		    tp ? &tp->t_inpcb->inp_route6 : NULL,
> +		    tp ? &tp->t_inpcb->inp_route : NULL,
>  		    0, NULL,
>  		    tp ? tp->t_inpcb->inp_seclevel : NULL);
>  		break;
> Index: sys/netinet/tcp_var.h
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/tcp_var.h,v
> diff -u -p -r1.175 tcp_var.h
> --- sys/netinet/tcp_var.h	27 Jan 2024 21:13:46 -0000	1.175
> +++ sys/netinet/tcp_var.h	11 Feb 2024 19:52:56 -0000
> @@ -247,16 +247,7 @@ struct syn_cache {
>  	TAILQ_ENTRY(syn_cache) sc_bucketq;	/* [S] link on bucket list */
>  	struct refcnt sc_refcnt;		/* ref count list and timer */
>  	struct timeout sc_timer;		/* rexmt timer */
> -	union {					/* cached route */
> -		struct route route4;
> -#ifdef INET6
> -		struct route_in6 route6;
> -#endif
> -	} sc_route_u;
> -#define sc_route4	sc_route_u.route4	/* [N] */
> -#ifdef INET6
> -#define sc_route6	sc_route_u.route6	/* [N] */
> -#endif
> +	struct route sc_route;			/* [N] cached route */
>  	long sc_win;				/* [I] advertised window */
>  	struct syn_cache_head *sc_buckethead;	/* [S] our bucket index */
>  	struct syn_cache_set *sc_set;		/* [S] our syn cache set */
> Index: sys/netinet6/dest6.c
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/dest6.c,v
> diff -u -p -r1.19 dest6.c
> --- sys/netinet6/dest6.c	29 Jun 2022 22:45:24 -0000	1.19
> +++ sys/netinet6/dest6.c	11 Feb 2024 19:52:56 -0000
> @@ -38,6 +38,8 @@
>  #include <sys/time.h>
>  #include <sys/kernel.h>
>  
> +#include <net/route.h>
> +
>  #include <netinet/in.h>
>  #include <netinet/ip6.h>
>  #include <netinet6/ip6_var.h>
> Index: sys/netinet6/in6.h
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/in6.h,v
> diff -u -p -r1.115 in6.h
> --- sys/netinet6/in6.h	9 Feb 2024 14:02:12 -0000	1.115
> +++ sys/netinet6/in6.h	11 Feb 2024 19:52:56 -0000
> @@ -145,16 +145,6 @@ extern const struct in6_addr in6addr_lin
>  
>  #if __BSD_VISIBLE
>  /*
> - * IPv6 route structure, keep fields in sync with struct route
> - */
> -struct route_in6 {
> -	struct	rtentry *ro_rt;
> -	u_long		 ro_generation;
> -	u_long		 ro_tableid;	/* padded to long for alignment */
> -	struct	sockaddr_in6 ro_dst;
> -};
> -
> -/*
>   * Definition of some useful macros to handle IP6 addresses
>   */
>  #define IN6ADDR_ANY_INIT \
> @@ -427,8 +417,6 @@ struct	in6_ifaddr *in6_ifawithscope(stru
>  int	in6_mask2len(struct in6_addr *, u_char *);
>  int	in6_nam2sin6(const struct mbuf *, struct sockaddr_in6 **);
>  int	in6_sa2sin6(struct sockaddr *, struct sockaddr_in6 **);
> -
> -int	route6_cache(struct route_in6 *, const struct in6_addr *, u_int);
>  
>  struct ip6_pktopts;
>  struct ip6_moptions;
> Index: sys/netinet6/in6_pcb.c
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/in6_pcb.c,v
> diff -u -p -r1.137 in6_pcb.c
> --- sys/netinet6/in6_pcb.c	11 Feb 2024 01:27:45 -0000	1.137
> +++ sys/netinet6/in6_pcb.c	11 Feb 2024 19:52:56 -0000
> @@ -114,13 +114,12 @@
>  #include <net/pfvar.h>
>  
>  #include <netinet/in.h>
> +#include <netinet6/in6_var.h>
>  #include <netinet/ip.h>
>  #include <netinet/ip_var.h>
>  #include <netinet6/ip6_var.h>
>  #include <netinet/in_pcb.h>
>  
> -#include <netinet6/in6_var.h>
> -
>  #if NSTOEPLITZ > 0
>  #include <net/toeplitz.h>
>  #endif
> @@ -517,13 +516,10 @@ in6_pcbnotify(struct inpcbtable *table, 
>  		if ((PRC_IS_REDIRECT(cmd) || cmd == PRC_HOSTDEAD) &&
>  		    IN6_IS_ADDR_UNSPECIFIED(&inp->inp_laddr6) &&
>  		    inp->inp_route.ro_rt &&
> -		    !(inp->inp_route.ro_rt->rt_flags & RTF_HOST)) {
> -			struct sockaddr_in6 *dst6;
> -
> -			dst6 = satosin6(&inp->inp_route.ro_dst);
> -			if (IN6_ARE_ADDR_EQUAL(&dst6->sin6_addr,
> -			    &dst->sin6_addr))
> -				goto do_notify;
> +		    !(inp->inp_route.ro_rt->rt_flags & RTF_HOST) &&
> +		    IN6_ARE_ADDR_EQUAL(&inp->inp_route.ro_dstsin6.sin6_addr,
> +		    &dst->sin6_addr)) {
> +			goto do_notify;
>  		}
>  
>  		/*
> @@ -565,12 +561,12 @@ in6_pcbnotify(struct inpcbtable *table, 
>  struct rtentry *
>  in6_pcbrtentry(struct inpcb *inp)
>  {
> -	struct route_in6 *ro = &inp->inp_route6;
> +	struct route *ro = &inp->inp_route;
>  
>  	if (IN6_IS_ADDR_UNSPECIFIED(&inp->inp_faddr6))
>  		return (NULL);
>  	if (route6_cache(ro, &inp->inp_faddr6, inp->inp_rtableid)) {
> -		ro->ro_rt = rtalloc_mpath(sin6tosa(&ro->ro_dst),
> +		ro->ro_rt = rtalloc_mpath(&ro->ro_dstsa,
>  		    &inp->inp_laddr6.s6_addr32[0], ro->ro_tableid);
>  	}
>  	return (ro->ro_rt);
> Index: sys/netinet6/in6_src.c
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/in6_src.c,v
> diff -u -p -r1.93 in6_src.c
> --- sys/netinet6/in6_src.c	9 Feb 2024 14:02:12 -0000	1.93
> +++ sys/netinet6/in6_src.c	11 Feb 2024 19:52:56 -0000
> @@ -83,7 +83,7 @@
>  #include <netinet6/nd6.h>
>  
>  int in6_selectif(const struct in6_addr *, struct ip6_pktopts *,
> -    struct ip6_moptions *, struct route_in6 *, struct ifnet **, u_int);
> +    struct ip6_moptions *, struct route *, struct ifnet **, u_int);
>  
>  /*
>   * Return an IPv6 address, which is the most appropriate for a given
> @@ -95,7 +95,7 @@ in6_pcbselsrc(const struct in6_addr **in
>      struct inpcb *inp, struct ip6_pktopts *opts)
>  {
>  	struct ip6_moptions *mopts = inp->inp_moptions6;
> -	struct route_in6 *ro = &inp->inp_route6;
> +	struct route *ro = &inp->inp_route;
>  	const struct in6_addr *laddr = &inp->inp_laddr6;
>  	u_int rtableid = inp->inp_rtableid;
>  	struct ifnet *ifp = NULL;
> @@ -180,8 +180,7 @@ in6_pcbselsrc(const struct in6_addr **in
>  	 * our src addr is taken from the i/f, else punt.
>  	 */
>  	if (route6_cache(ro, dst, rtableid)) {
> -		ro->ro_rt = rtalloc(sin6tosa(&ro->ro_dst),
> -		    RT_RESOLVE, ro->ro_tableid);
> +		ro->ro_rt = rtalloc(&ro->ro_dstsa, RT_RESOLVE, ro->ro_tableid);
>  	}
>  
>  	/*
> @@ -298,7 +297,7 @@ in6_selectsrc(const struct in6_addr **in
>  
>  struct rtentry *
>  in6_selectroute(const struct in6_addr *dst, struct ip6_pktopts *opts,
> -    struct route_in6 *ro, unsigned int rtableid)
> +    struct route *ro, unsigned int rtableid)
>  {
>  	/*
>  	 * Use a cached route if it exists and is valid, else try to allocate
> @@ -307,8 +306,8 @@ in6_selectroute(const struct in6_addr *d
>  	if (ro) {
>  		if (route6_cache(ro, dst, rtableid)) {
>  			/* No route yet, so try to acquire one */
> -			ro->ro_rt = rtalloc_mpath(sin6tosa(&ro->ro_dst),
> -			    NULL, ro->ro_tableid);
> +			ro->ro_rt = rtalloc_mpath(&ro->ro_dstsa, NULL,
> +			    ro->ro_tableid);
>  		}
>  
>  		/*
> @@ -336,7 +335,7 @@ in6_selectroute(const struct in6_addr *d
>  
>  int
>  in6_selectif(const struct in6_addr *dst, struct ip6_pktopts *opts,
> -    struct ip6_moptions *mopts, struct route_in6 *ro, struct ifnet **retifp,
> +    struct ip6_moptions *mopts, struct route *ro, struct ifnet **retifp,
>      u_int rtableid)
>  {
>  	struct rtentry *rt = NULL;
> Index: sys/netinet6/ip6_divert.c
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/ip6_divert.c,v
> diff -u -p -r1.93 ip6_divert.c
> --- sys/netinet6/ip6_divert.c	11 Feb 2024 01:27:45 -0000	1.93
> +++ sys/netinet6/ip6_divert.c	11 Feb 2024 19:52:56 -0000
> @@ -30,13 +30,13 @@
>  #include <net/netisr.h>
>  
>  #include <netinet/in.h>
> +#include <netinet6/in6_var.h>
>  #include <netinet/ip.h>
>  #include <netinet/ip_var.h>
> -#include <netinet/in_pcb.h>
> -#include <netinet/ip_divert.h>
>  #include <netinet/ip6.h>
>  #include <netinet6/ip6_var.h>
> -#include <netinet6/in6_var.h>
> +#include <netinet/in_pcb.h>
> +#include <netinet/ip_divert.h>
>  #include <netinet6/ip6_divert.h>
>  #include <netinet/tcp.h>
>  #include <netinet/udp.h>
> @@ -180,7 +180,7 @@ divert6_output(struct inpcb *inp, struct
>  	} else {
>  		m->m_pkthdr.ph_rtableid = inp->inp_rtableid;
>  
> -		error = ip6_output(m, NULL, &inp->inp_route6,
> +		error = ip6_output(m, NULL, &inp->inp_route,
>  		    IP_ALLOWBROADCAST | IP_RAWOUTPUT, NULL, NULL);
>  	}
>  
> Index: sys/netinet6/ip6_forward.c
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/ip6_forward.c,v
> diff -u -p -r1.113 ip6_forward.c
> --- sys/netinet6/ip6_forward.c	7 Feb 2024 23:40:40 -0000	1.113
> +++ sys/netinet6/ip6_forward.c	11 Feb 2024 19:52:56 -0000
> @@ -86,7 +86,7 @@ ip6_forward(struct mbuf *m, struct rtent
>  {
>  	struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
>  	struct sockaddr *dst;
> -	struct route_in6 ro;
> +	struct route ro;
>  	struct ifnet *ifp = NULL;
>  	int error = 0, type = 0, code = 0, destmtu = 0;
>  	struct mbuf *mcopy = NULL;
> @@ -167,7 +167,7 @@ reroute:
>  
>  	ro.ro_rt = NULL;
>  	route6_cache(&ro, &ip6->ip6_dst, m->m_pkthdr.ph_rtableid);
> -	dst = sin6tosa(&ro.ro_dst);
> +	dst = &ro.ro_dstsa;
>  	if (!rtisvalid(rt)) {
>  		rtfree(rt);
>  		rt = rtalloc_mpath(dst, &ip6->ip6_src.s6_addr32[0],
> @@ -253,7 +253,7 @@ reroute:
>  	    ip6_sendredirects &&
>  	    (rt->rt_flags & (RTF_DYNAMIC|RTF_MODIFIED)) == 0) {
>  		if ((ifp->if_flags & IFF_POINTOPOINT) &&
> -		    nd6_is_addr_neighbor(&ro.ro_dst, ifp)) {
> +		    nd6_is_addr_neighbor(&ro.ro_dstsin6, ifp)) {
>  			/*
>  			 * If the incoming interface is equal to the outgoing
>  			 * one, the link attached to the interface is
> Index: sys/netinet6/ip6_id.c
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/ip6_id.c,v
> diff -u -p -r1.16 ip6_id.c
> --- sys/netinet6/ip6_id.c	10 Mar 2021 10:21:49 -0000	1.16
> +++ sys/netinet6/ip6_id.c	11 Feb 2024 19:52:56 -0000
> @@ -89,7 +89,6 @@
>  
>  #include <netinet/in.h>
>  #include <netinet/ip6.h>
> -#include <netinet6/ip6_var.h>
>  
>  struct randomtab {
>  	const int	ru_bits; /* resulting bits */
> Index: sys/netinet6/ip6_output.c
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/ip6_output.c,v
> diff -u -p -r1.285 ip6_output.c
> --- sys/netinet6/ip6_output.c	7 Feb 2024 23:40:40 -0000	1.285
> +++ sys/netinet6/ip6_output.c	11 Feb 2024 19:52:56 -0000
> @@ -143,7 +143,7 @@ static __inline u_int16_t __attribute__(
>      u_int32_t, u_int32_t);
>  void in6_delayed_cksum(struct mbuf *, u_int8_t);
>  
> -int ip6_output_ipsec_pmtu_update(struct tdb *, struct route_in6 *,
> +int ip6_output_ipsec_pmtu_update(struct tdb *, struct route *,
>      struct in6_addr *, int, int, int);
>  
>  /* Context for non-repeating IDs */
> @@ -160,14 +160,14 @@ struct idgen32_ctx ip6_id_ctx;
>   * We use u_long to hold largest one, * which is rt_mtu.
>   */
>  int
> -ip6_output(struct mbuf *m, struct ip6_pktopts *opt, struct route_in6 *ro,
> +ip6_output(struct mbuf *m, struct ip6_pktopts *opt, struct route *ro,
>      int flags, struct ip6_moptions *im6o, const u_char seclevel[])
>  {
>  	struct ip6_hdr *ip6;
>  	struct ifnet *ifp = NULL;
>  	struct mbuf_list ml;
>  	int hlen, tlen;
> -	struct route_in6 ip6route;
> +	struct route iproute;
>  	struct rtentry *rt = NULL;
>  	struct sockaddr_in6 *dst;
>  	int error = 0;
> @@ -177,7 +177,7 @@ ip6_output(struct mbuf *m, struct ip6_pk
>  	u_int32_t optlen = 0, plen = 0, unfragpartlen = 0;
>  	struct ip6_exthdrs exthdrs;
>  	struct in6_addr finaldst;
> -	struct route_in6 *ro_pmtu = NULL;
> +	struct route *ro_pmtu = NULL;
>  	int hdrsplit = 0;
>  	u_int8_t sproto = 0;
>  	u_char nextproto;
> @@ -390,13 +390,13 @@ reroute:
>  
>  	/* initialize cached route */
>  	if (ro == NULL) {
> -		ro = &ip6route;
> +		ro = &iproute;
>  		bzero((caddr_t)ro, sizeof(*ro));
>  	}
>  	ro_pmtu = ro;
>  	if (opt && opt->ip6po_rthdr)
>  		ro = &opt->ip6po_route;
> -	dst = &ro->ro_dst;
> +	dst = &ro->ro_dstsin6;
>  
>  	/*
>  	 * if specified, try to fill in the traffic class field.
> @@ -750,9 +750,9 @@ reroute:
>  	ip6stat_inc(ip6s_fragmented);
>  
>  done:
> -	if (ro == &ip6route && ro->ro_rt) {
> +	if (ro == &iproute && ro->ro_rt) {
>  		rtfree(ro->ro_rt);
> -	} else if (ro_pmtu == &ip6route && ro_pmtu->ro_rt) {
> +	} else if (ro_pmtu == &iproute && ro_pmtu->ro_rt) {
>  		rtfree(ro_pmtu->ro_rt);
>  	}
>  	if_put(ifp);
> @@ -2772,7 +2772,7 @@ ip6_output_ipsec_lookup(struct mbuf *m, 
>  }
>  
>  int
> -ip6_output_ipsec_pmtu_update(struct tdb *tdb, struct route_in6 *ro,
> +ip6_output_ipsec_pmtu_update(struct tdb *tdb, struct route *ro,
>      struct in6_addr *dst, int ifidx, int rtableid, int transportmode)
>  {
>  	struct rtentry *rt = NULL;
> @@ -2807,7 +2807,7 @@ ip6_output_ipsec_pmtu_update(struct tdb 
>  		rt->rt_mtu = tdb->tdb_mtu;
>  		if (ro != NULL && ro->ro_rt != NULL) {
>  			rtfree(ro->ro_rt);
> -			ro->ro_rt = rtalloc(sin6tosa(&ro->ro_dst), RT_RESOLVE,
> +			ro->ro_rt = rtalloc(&ro->ro_dstsa, RT_RESOLVE,
>  			    rtableid);
>  		}
>  		if (rt_mtucloned)
> @@ -2817,7 +2817,7 @@ ip6_output_ipsec_pmtu_update(struct tdb 
>  }
>  
>  int
> -ip6_output_ipsec_send(struct tdb *tdb, struct mbuf *m, struct route_in6 *ro,
> +ip6_output_ipsec_send(struct tdb *tdb, struct mbuf *m, struct route *ro,
>      int tunalready, int fwd)
>  {
>  	struct mbuf_list ml;
> Index: sys/netinet6/ip6_var.h
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/ip6_var.h,v
> diff -u -p -r1.112 ip6_var.h
> --- sys/netinet6/ip6_var.h	7 Feb 2024 23:40:40 -0000	1.112
> +++ sys/netinet6/ip6_var.h	11 Feb 2024 19:52:56 -0000
> @@ -103,7 +103,7 @@ struct	ip6_moptions {
>  /* Routing header related info */
>  struct	ip6po_rhinfo {
>  	struct	ip6_rthdr *ip6po_rhi_rthdr; /* Routing header */
> -	struct	route_in6 ip6po_rhi_route; /* Route to the 1st hop */
> +	struct	route ip6po_rhi_route; /* Route to the 1st hop */
>  };
>  #define ip6po_rthdr	ip6po_rhinfo.ip6po_rhi_rthdr
>  #define ip6po_route	ip6po_rhinfo.ip6po_rhi_route
> @@ -323,7 +323,7 @@ int	ip6_sysctl(int *, u_int, void *, siz
>  void	ip6_forward(struct mbuf *, struct rtentry *, int);
>  
>  void	ip6_mloopback(struct ifnet *, struct mbuf *, struct sockaddr_in6 *);
> -int	ip6_output(struct mbuf *, struct ip6_pktopts *, struct route_in6 *, int,
> +int	ip6_output(struct mbuf *, struct ip6_pktopts *, struct route *, int,
>  	    struct ip6_moptions *, const u_char[]);
>  int	ip6_fragment(struct mbuf *, struct mbuf_list *, int, u_char, u_long);
>  int	ip6_ctloutput(int, struct socket *, int, int, struct mbuf *);
> @@ -370,14 +370,14 @@ int	in6_pcbselsrc(const struct in6_addr 
>  int	in6_selectsrc(const struct in6_addr **, struct sockaddr_in6 *,
>  	    struct ip6_moptions *, unsigned int);
>  struct rtentry *in6_selectroute(const struct in6_addr *, struct ip6_pktopts *,
> -	    struct route_in6 *, unsigned int rtableid);
> +	    struct route *, unsigned int rtableid);
>  
>  u_int32_t ip6_randomflowlabel(void);
>  
>  #ifdef IPSEC
>  struct tdb;
>  int	ip6_output_ipsec_lookup(struct mbuf *, const u_char[], struct tdb **);
> -int	ip6_output_ipsec_send(struct tdb *, struct mbuf *, struct route_in6 *,
> +int	ip6_output_ipsec_send(struct tdb *, struct mbuf *, struct route *,
>  	    int, int);
>  #endif /* IPSEC */
>  
> Index: sys/netinet6/mld6.c
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/mld6.c,v
> diff -u -p -r1.61 mld6.c
> --- sys/netinet6/mld6.c	8 Sep 2022 10:22:07 -0000	1.61
> +++ sys/netinet6/mld6.c	11 Feb 2024 19:52:56 -0000
> @@ -74,6 +74,7 @@
>  
>  #include <net/if.h>
>  #include <net/if_var.h>
> +#include <net/route.h>
>  
>  #include <netinet/in.h>
>  #include <netinet6/in6_var.h>
> Index: sys/netinet6/raw_ip6.c
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/raw_ip6.c,v
> diff -u -p -r1.180 raw_ip6.c
> --- sys/netinet6/raw_ip6.c	3 Feb 2024 22:50:09 -0000	1.180
> +++ sys/netinet6/raw_ip6.c	11 Feb 2024 19:52:56 -0000
> @@ -512,7 +512,7 @@ rip6_output(struct mbuf *m, struct socke
>  		pf_mbuf_link_inpcb(m, inp);
>  #endif
>  
> -	error = ip6_output(m, optp, &inp->inp_route6, flags,
> +	error = ip6_output(m, optp, &inp->inp_route, flags,
>  	    inp->inp_moptions6, inp->inp_seclevel);
>  	if (so->so_proto->pr_protocol == IPPROTO_ICMPV6) {
>  		icmp6stat_inc(icp6s_outhist + type);
> Index: sys/netinet6/route6.c
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/route6.c,v
> diff -u -p -r1.21 route6.c
> --- sys/netinet6/route6.c	14 Apr 2017 20:46:31 -0000	1.21
> +++ sys/netinet6/route6.c	11 Feb 2024 19:52:56 -0000
> @@ -37,6 +37,7 @@
>  
>  #include <net/if.h>
>  #include <net/if_var.h>
> +#include <net/route.h>
>  
>  #include <netinet/in.h>
>  #include <netinet6/in6_var.h>
> Index: sys/netinet6/udp6_output.c
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/udp6_output.c,v
> diff -u -p -r1.63 udp6_output.c
> --- sys/netinet6/udp6_output.c	3 Dec 2023 20:36:24 -0000	1.63
> +++ sys/netinet6/udp6_output.c	11 Feb 2024 19:52:56 -0000
> @@ -232,7 +232,7 @@ udp6_output(struct inpcb *inp, struct mb
>  		pf_mbuf_link_inpcb(m, inp);
>  #endif
>  
> -	error = ip6_output(m, optp, &inp->inp_route6,
> +	error = ip6_output(m, optp, &inp->inp_route,
>  	    flags, inp->inp_moptions6, inp->inp_seclevel);
>  	goto releaseopt;
>  
> Index: usr.bin/netstat/inet.c
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/usr.bin/netstat/inet.c,v
> diff -u -p -r1.180 inet.c
> --- usr.bin/netstat/inet.c	5 Feb 2024 23:16:39 -0000	1.180
> +++ usr.bin/netstat/inet.c	11 Feb 2024 20:18:39 -0000
> @@ -1461,14 +1461,14 @@ inpcb_dump(u_long off, short protocol, i
>  	case AF_INET:
>  		inet_ntop(af, &inp.inp_faddr, faddr, sizeof(faddr));
>  		inet_ntop(af, &inp.inp_laddr, laddr, sizeof(laddr));
> -		inet_ntop(af, &((struct sockaddr_in *)
> -		    (&inp.inp_route.ro_dst))->sin_addr, raddr, sizeof(raddr));
> +		inet_ntop(af, &inp.inp_route.ro_dstsin.sin_addr, raddr,
> +		    sizeof(raddr));
>  		break;
>  	case AF_INET6:
>  		inet_ntop(af, &inp.inp_faddr6, faddr, sizeof(faddr));
>  		inet_ntop(af, &inp.inp_laddr6, laddr, sizeof(laddr));
> -		inet_ntop(af, &inp.inp_route6.ro_dst.sin6_addr,
> -		    raddr, sizeof(raddr));
> +		inet_ntop(af, &inp.inp_route.ro_dstsin6.sin6_addr, raddr,
> +		    sizeof(raddr));
>  		break;
>  	default:
>  		faddr[0] = laddr[0] = '\0';
> 

-- 
:wq Claudio