Index | Thread | Search

From:
Alexander Bluhm <alexander.bluhm@gmx.net>
Subject:
Re: struct route inet
To:
tech@openbsd.org
Date:
Mon, 12 Feb 2024 22:53:05 +0100

Download raw body.

Thread
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.

> 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.

> >  #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?

Diff below passed regress and make release.

ok?

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';