Index | Thread | Search

From:
Alexander Bluhm <alexander.bluhm@gmx.net>
Subject:
struct route inet
To:
tech@openbsd.org
Cc:
Claudio Jeker <claudio@openbsd.org>
Date:
Fri, 2 Feb 2024 22:11:00 +0100

Download raw body.

Thread
Hi,

Claudio complained about generic struct route usage without enough
storage to hold IPv6 address.  This diff splits definitions in
struct route_in and route_in6 with correct types.

Is that what you want?

bluhm

Index: net/route.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/net/route.c,v
diff -u -p -r1.427 route.c
--- net/route.c	31 Jan 2024 14:56:42 -0000	1.427
+++ net/route.c	2 Feb 2024 20:41:04 -0000
@@ -202,7 +202,7 @@ route_init(void)
 }
 
 void
-route_cache(struct route *ro, struct in_addr addr, u_int rtableid)
+route_cache_in(struct route_in *ro, struct in_addr addr, u_int rtableid)
 {
 	u_long gen;
 
@@ -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_dst.sin_family == AF_INET &&
+	    ro->ro_dst.sin_addr.s_addr == addr.s_addr) {
 		return;
 	}
 
@@ -223,9 +223,9 @@ 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_dst.sin_family = AF_INET;
+	ro->ro_dst.sin_len = sizeof(struct sockaddr_in);
+	ro->ro_dst.sin_addr = addr;
 }
 
 /*
Index: net/route.h
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/net/route.h,v
diff -u -p -r1.204 route.h
--- net/route.h	31 Jan 2024 14:56:42 -0000	1.204
+++ net/route.h	2 Feb 2024 20:52:50 -0000
@@ -448,9 +448,10 @@ struct in_addr;
 struct sockaddr_in6;
 struct if_ieee80211_data;
 struct bfd_config;
+struct route_in;
 
 void	 route_init(void);
-void	 route_cache(struct route *, struct in_addr, u_int);
+void	 route_cache_in(struct route_in *, struct in_addr, u_int);
 void	 rtm_ifchg(struct ifnet *);
 void	 rtm_ifannounce(struct ifnet *, int);
 void	 rtm_bfd(struct bfd_config *);
Index: netinet/in.h
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/in.h,v
diff -u -p -r1.145 in.h
--- netinet/in.h	10 Nov 2023 20:05:22 -0000	1.145
+++ netinet/in.h	2 Feb 2024 20:48:14 -0000
@@ -322,6 +322,16 @@ struct ip_opts {
 
 #if __BSD_VISIBLE
 /*
+ * IPv4 route structure, keep fields in sync with struct route.
+ */
+struct route_in {
+	struct	rtentry *ro_rt;
+	u_long		 ro_generation;
+	u_long		 ro_tableid;	/* padded to long for alignment */
+	struct	sockaddr_in ro_dst;
+};
+
+/*
  * Security levels - IPsec, not IPSO
  */
 
Index: netinet/in_pcb.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/in_pcb.c,v
diff -u -p -r1.289 in_pcb.c
--- netinet/in_pcb.c	2 Feb 2024 15:39:23 -0000	1.289
+++ netinet/in_pcb.c	2 Feb 2024 20:54:19 -0000
@@ -907,7 +907,7 @@ in_pcblookup_local_lock(struct inpcbtabl
 struct rtentry *
 in_pcbrtentry(struct inpcb *inp)
 {
-	struct route *ro;
+	struct route_in *ro;
 
 #ifdef INET6
 	if (ISSET(inp->inp_flags, INP_IPV6))
@@ -926,15 +926,15 @@ in_pcbrtentry(struct inpcb *inp)
 	 * No route yet, so try to acquire one.
 	 */
 	if (ro->ro_rt == NULL) {
-		memset(ro, 0, sizeof(struct route));
+		memset(ro, 0, sizeof(struct route_in));
 
 		if (inp->inp_faddr.s_addr == INADDR_ANY)
 			return (NULL);
-		ro->ro_dst.sa_family = AF_INET;
-		ro->ro_dst.sa_len = sizeof(struct sockaddr_in);
-		satosin(&ro->ro_dst)->sin_addr = inp->inp_faddr;
+		ro->ro_dst.sin_family = AF_INET;
+		ro->ro_dst.sin_len = sizeof(struct sockaddr_in);
+		ro->ro_dst.sin_addr = inp->inp_faddr;
 		ro->ro_tableid = inp->inp_rtableid;
-		ro->ro_rt = rtalloc_mpath(&ro->ro_dst,
+		ro->ro_rt = rtalloc_mpath(sintosa(&ro->ro_dst),
 		    &inp->inp_laddr.s_addr, ro->ro_tableid);
 	}
 	return (ro->ro_rt);
@@ -951,7 +951,7 @@ in_pcbselsrc(struct in_addr *insrc, stru
     struct inpcb *inp)
 {
 	struct ip_moptions *mopts = inp->inp_moptions;
-	struct route *ro = &inp->inp_route;
+	struct route_in *ro = &inp->inp_route;
 	const struct in_addr *laddr = &inp->inp_laddr;
 	u_int rtableid = inp->inp_rtableid;
 	struct sockaddr	*ip4_source = NULL;
@@ -999,23 +999,24 @@ in_pcbselsrc(struct in_addr *insrc, stru
 	 * our src addr is taken from the i/f, else punt.
 	 */
 	if (!rtisvalid(ro->ro_rt) || (ro->ro_tableid != rtableid) ||
-	    (satosin(&ro->ro_dst)->sin_addr.s_addr != sin->sin_addr.s_addr)) {
+	    (ro->ro_dst.sin_addr.s_addr != sin->sin_addr.s_addr)) {
 		rtfree(ro->ro_rt);
 		ro->ro_rt = NULL;
 	}
 	if (ro->ro_rt == NULL) {
 		/* No route yet, so try to acquire one */
-		ro->ro_dst.sa_family = AF_INET;
-		ro->ro_dst.sa_len = sizeof(struct sockaddr_in);
-		satosin(&ro->ro_dst)->sin_addr = sin->sin_addr;
+		ro->ro_dst.sin_family = AF_INET;
+		ro->ro_dst.sin_len = sizeof(struct sockaddr_in);
+		ro->ro_dst.sin_addr = sin->sin_addr;
 		ro->ro_tableid = rtableid;
-		ro->ro_rt = rtalloc_mpath(&ro->ro_dst, NULL, ro->ro_tableid);
+		ro->ro_rt = rtalloc_mpath(sintosa(&ro->ro_dst), NULL,
+		    ro->ro_tableid);
 
 		/*
 		 * It is important to zero out the rest of the
 		 * struct sockaddr_in when mixing v6 & v4!
 		 */
-		sin2 = satosin(&ro->ro_dst);
+		sin2 = &ro->ro_dst;
 		memset(sin2->sin_zero, 0, sizeof(sin2->sin_zero));
 	}
 
Index: netinet/in_pcb.h
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/in_pcb.h,v
diff -u -p -r1.150 in_pcb.h
--- netinet/in_pcb.h	31 Jan 2024 12:27:57 -0000	1.150
+++ netinet/in_pcb.h	2 Feb 2024 20:27:59 -0000
@@ -152,11 +152,11 @@ struct inpcb {
 	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;
+		struct route_in iru_route;
+		struct route_in6 iru_route6;
 	} inp_ru;
-#define	inp_route	inp_ru.ru_route
-#define	inp_route6	inp_ru.ru_route6
+#define inp_route	inp_ru.iru_route
+#define inp_route6	inp_ru.iru_route6
 	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: 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
--- netinet/ip_input.c	31 Jan 2024 14:56:42 -0000	1.388
+++ netinet/ip_input.c	2 Feb 2024 20:41:57 -0000
@@ -1475,7 +1475,7 @@ ip_forward(struct mbuf *m, struct ifnet 
 {
 	struct mbuf mfake, *mcopy = NULL;
 	struct ip *ip = mtod(m, struct ip *);
-	struct route ro;
+	struct route_in ro;
 	int error = 0, type = 0, code = 0, destmtu = 0, fake = 0, len;
 	u_int32_t dest;
 
@@ -1491,10 +1491,10 @@ ip_forward(struct mbuf *m, struct ifnet 
 	}
 
 	ro.ro_rt = NULL;
-	route_cache(&ro, ip->ip_dst, m->m_pkthdr.ph_rtableid);
+	route_cache_in(&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(sintosa(&ro.ro_dst), &ip->ip_src.s_addr,
 		    m->m_pkthdr.ph_rtableid);
 		if (rt == NULL) {
 			ipstat_inc(ips_noroute);
Index: 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
--- netinet/ip_output.c	31 Jan 2024 14:56:43 -0000	1.394
+++ netinet/ip_output.c	2 Feb 2024 20:43:22 -0000
@@ -86,9 +86,9 @@ void in_delayed_cksum(struct mbuf *);
 
 int ip_output_ipsec_lookup(struct mbuf *m, int hlen, const u_char seclevel[],
     struct tdb **, int ipsecflowinfo);
-void ip_output_ipsec_pmtu_update(struct tdb *, struct route *, struct in_addr,
-    int, int);
-int ip_output_ipsec_send(struct tdb *, struct mbuf *, struct route *, int);
+void ip_output_ipsec_pmtu_update(struct tdb *, struct route_in *,
+    struct in_addr, int, int);
+int ip_output_ipsec_send(struct tdb *, struct mbuf *, struct route_in *, int);
 
 /*
  * IP output.  The packet in mbuf chain m contains a skeletal IP
@@ -97,7 +97,7 @@ int ip_output_ipsec_send(struct tdb *, s
  * The mbuf opt, if present, will not be freed.
  */
 int
-ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags,
+ip_output(struct mbuf *m, struct mbuf *opt, struct route_in *ro, int flags,
     struct ip_moptions *imo, const u_char seclevel[], u_int32_t ipsecflowinfo)
 {
 	struct ip *ip;
@@ -105,7 +105,7 @@ ip_output(struct mbuf *m, struct mbuf *o
 	struct mbuf_list ml;
 	int hlen = sizeof (struct ip);
 	int error = 0;
-	struct route iproute;
+	struct route_in iproute;
 	struct sockaddr_in *dst;
 	struct tdb *tdb = NULL;
 	u_long mtu;
@@ -166,8 +166,8 @@ reroute:
 	 * If there is a cached route, check that it is to the same
 	 * 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);
+	route_cache_in(ro, ip->ip_dst, m->m_pkthdr.ph_rtableid);
+	dst = &ro->ro_dst;
 
 	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(sintosa(&ro->ro_dst),
 			    &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_dst;
 
 		/*
 		 * See if the caller provided any multicast options
@@ -454,8 +454,8 @@ sendit:
 		if (ro->ro_tableid != orig_rtableid) {
 			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_rt = icmp_mtudisc_clone(ro->ro_dst.sin_addr,
+			    ro->ro_tableid, 0);
 		}
 #endif
 		/*
@@ -536,7 +536,7 @@ ip_output_ipsec_lookup(struct mbuf *m, i
 }
 
 void
-ip_output_ipsec_pmtu_update(struct tdb *tdb, struct route *ro,
+ip_output_ipsec_pmtu_update(struct tdb *tdb, struct route_in *ro,
     struct in_addr dst, int rtableid, int transportmode)
 {
 	struct rtentry *rt = NULL;
@@ -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(sintosa(&ro->ro_dst),
+			    RT_RESOLVE, rtableid);
 		}
 		if (rt_mtucloned)
 			rtfree(rt);
@@ -566,7 +567,8 @@ ip_output_ipsec_pmtu_update(struct tdb *
 }
 
 int
-ip_output_ipsec_send(struct tdb *tdb, struct mbuf *m, struct route *ro, int fwd)
+ip_output_ipsec_send(struct tdb *tdb, struct mbuf *m, struct route_in *ro,
+    int fwd)
 {
 	struct mbuf_list ml;
 	struct ifnet *encif = NULL;
Index: netinet/ip_var.h
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/ip_var.h,v
diff -u -p -r1.110 ip_var.h
--- netinet/ip_var.h	26 Nov 2023 22:08:10 -0000	1.110
+++ netinet/ip_var.h	2 Feb 2024 20:40:13 -0000
@@ -223,7 +223,7 @@ extern const struct pr_usrreqs rip_usrre
 
 extern struct rttimer_queue ip_mtudisc_timeout_q;
 extern struct pool ipqent_pool;
-struct route;
+struct route_in;
 struct inpcb;
 
 int	 ip_ctloutput(int, struct socket *, int, int, struct mbuf *);
@@ -235,7 +235,7 @@ struct mbuf*
 	 ip_insertoptions(struct mbuf *, struct mbuf *, int *);
 int	 ip_mforward(struct mbuf *, struct ifnet *);
 int	 ip_optcopy(struct ip *, struct ip *);
-int	 ip_output(struct mbuf *, struct mbuf *, struct route *, int,
+int	 ip_output(struct mbuf *, struct mbuf *, struct route_in *, int,
 	    struct ip_moptions *, const u_char[], u_int32_t);
 u_int16_t
 	 ip_randomid(void);
Index: netinet/tcp_input.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/tcp_input.c,v
diff -u -p -r1.399 tcp_input.c
--- netinet/tcp_input.c	27 Jan 2024 21:13:46 -0000	1.399
+++ netinet/tcp_input.c	2 Feb 2024 20:59:38 -0000
@@ -3165,7 +3165,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,12 +3578,12 @@ 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 */
+		inp->inp_route = sc->sc_route;		/* struct assignment */
 #ifdef INET6
 	else
 		inp->inp_route6 = sc->sc_route6;
 #endif
-	sc->sc_route4.ro_rt = NULL;
+	sc->sc_route.ro_rt = NULL;
 
 	am = m_get(M_DONTWAIT, MT_SONAME);	/* XXX */
 	if (am == NULL)
@@ -4151,7 +4151,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;
Index: 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
--- netinet/tcp_var.h	27 Jan 2024 21:13:46 -0000	1.175
+++ netinet/tcp_var.h	2 Feb 2024 20:45:17 -0000
@@ -248,15 +248,11 @@ struct syn_cache {
 	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_in sru_route;
+		struct route_in6 sru_route6;
+	} sc_ru;
+#define sc_route	sc_ru.sru_route		/* [N] */
+#define sc_route6	sc_ru.sru_route6	/* [N] */
 	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: netinet6/in6.h
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/in6.h,v
diff -u -p -r1.113 in6.h
--- netinet6/in6.h	31 Jan 2024 14:56:43 -0000	1.113
+++ netinet6/in6.h	2 Feb 2024 20:23:09 -0000
@@ -145,7 +145,7 @@ extern const struct in6_addr in6addr_lin
 
 #if __BSD_VISIBLE
 /*
- * IPv6 route structure, keep fields in sync with struct route
+ * IPv6 route structure, keep fields in sync with struct route.
  */
 struct route_in6 {
 	struct	rtentry *ro_rt;
Index: netinet6/in6_pcb.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/in6_pcb.c,v
diff -u -p -r1.134 in6_pcb.c
--- netinet6/in6_pcb.c	31 Jan 2024 12:27:57 -0000	1.134
+++ netinet6/in6_pcb.c	2 Feb 2024 20:53:48 -0000
@@ -519,7 +519,7 @@ in6_pcbnotify(struct inpcbtable *table, 
 		    !(inp->inp_route.ro_rt->rt_flags & RTF_HOST)) {
 			struct sockaddr_in6 *dst6;
 
-			dst6 = satosin6(&inp->inp_route.ro_dst);
+			dst6 = &inp->inp_route6.ro_dst;
 			if (IN6_ARE_ADDR_EQUAL(&dst6->sin6_addr,
 			    &dst->sin6_addr))
 				goto do_notify;