From: Vitaliy Makkoveev Subject: Re: in_pcbselsrc() and in6_pcbselsrc() const sockaddr parameter To: Alexander Bluhm Cc: tech@openbsd.org Date: Tue, 20 May 2025 12:26:41 +0000 On Tue, May 20, 2025 at 01:27:52PM +0900, Alexander Bluhm wrote: > Hi, > > Functions in_pcbselsrc() and in6_pcbselsrc() use the destination > sockaddr to determine a suitable source address. As the destination > is only used for lookup, it should never be modified. Use const > to let the compiler verify that. On the way down on the callstack, > also convert the parameter a bunch of other lookup functions to > const. > > ok? > ok mvs > bluhm > > Index: netinet/in_pcb.c > =================================================================== > RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/in_pcb.c,v > diff -u -p -r1.313 in_pcb.c > --- netinet/in_pcb.c 4 May 2025 23:05:17 -0000 1.313 > +++ netinet/in_pcb.c 20 May 2025 03:46:14 -0000 > @@ -986,12 +986,13 @@ in_pcbrtentry(struct inpcb *inp) > * an entry to the caller for later use. > */ > int > -in_pcbselsrc(struct in_addr *insrc, struct sockaddr_in *sin, > +in_pcbselsrc(struct in_addr *insrc, const struct sockaddr_in *dstsock, > struct inpcb *inp) > { > - struct ip_moptions *mopts = inp->inp_moptions; > - struct rtentry *rt; > + const struct in_addr *dst = &dstsock->sin_addr; > const struct in_addr *laddr = &inp->inp_laddr; > + struct rtentry *rt; > + struct ip_moptions *mopts = inp->inp_moptions; > u_int rtableid = inp->inp_rtableid; > struct sockaddr *ip4_source = NULL; > struct in_ifaddr *ia = NULL; > @@ -1012,8 +1013,8 @@ in_pcbselsrc(struct in_addr *insrc, stru > * been set as a multicast option, use the address of that > * interface as our source address. > */ > - if ((IN_MULTICAST(sin->sin_addr.s_addr) || > - sin->sin_addr.s_addr == INADDR_BROADCAST) && mopts != NULL) { > + if ((IN_MULTICAST(dst->s_addr) || dst->s_addr == INADDR_BROADCAST) && > + mopts != NULL) { > struct ifnet *ifp; > > ifp = if_get(mopts->imo_ifidx); > @@ -1035,7 +1036,7 @@ in_pcbselsrc(struct in_addr *insrc, stru > * If route is known or can be allocated now, > * our src addr is taken from the i/f, else punt. > */ > - rt = route_mpath(&inp->inp_route, &sin->sin_addr, NULL, rtableid); > + rt = route_mpath(&inp->inp_route, dst, NULL, rtableid); > > /* > * If we found a route, use the address > Index: netinet/in_pcb.h > =================================================================== > RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/in_pcb.h,v > diff -u -p -r1.167 in_pcb.h > --- netinet/in_pcb.h 4 May 2025 23:05:17 -0000 1.167 > +++ netinet/in_pcb.h 20 May 2025 03:19:29 -0000 > @@ -361,7 +361,8 @@ int in_sockaddr(struct socket *, struct > int in_peeraddr(struct socket *, struct mbuf *); > int in_baddynamic(u_int16_t, u_int16_t); > int in_rootonly(u_int16_t, u_int16_t); > -int in_pcbselsrc(struct in_addr *, struct sockaddr_in *, struct inpcb *); > +int in_pcbselsrc(struct in_addr *, const struct sockaddr_in *, > + struct inpcb *); > struct rtentry * > in_pcbrtentry(struct inpcb *); > > Index: netinet6/in6.c > =================================================================== > RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/in6.c,v > diff -u -p -r1.269 in6.c > --- netinet6/in6.c 19 May 2025 06:36:48 -0000 1.269 > +++ netinet6/in6.c 20 May 2025 03:38:24 -0000 > @@ -1194,7 +1194,7 @@ in6ifa_ifpwithaddr(struct ifnet *ifp, st > * Get a scope of the address. Node-local, link-local, site-local or global. > */ > int > -in6_addrscope(struct in6_addr *addr) > +in6_addrscope(const struct in6_addr *addr) > { > int scope; > > @@ -1249,7 +1249,7 @@ in6_addrscope(struct in6_addr *addr) > } > > int > -in6_addr2scopeid(unsigned int ifidx, struct in6_addr *addr) > +in6_addr2scopeid(unsigned int ifidx, const struct in6_addr *addr) > { > int scope = in6_addrscope(addr); > > @@ -1272,7 +1272,7 @@ in6_addr2scopeid(unsigned int ifidx, str > * hard coding... > */ > int > -in6_matchlen(struct in6_addr *src, struct in6_addr *dst) > +in6_matchlen(const struct in6_addr *src, const struct in6_addr *dst) > { > int match = 0; > u_char *s = (u_char *)src, *d = (u_char *)dst; > @@ -1317,7 +1317,7 @@ in6_prefixlen2mask(struct in6_addr *mask > * return the best address out of the same scope > */ > struct in6_ifaddr * > -in6_ifawithscope(struct ifnet *oifp, struct in6_addr *dst, u_int rdomain, > +in6_ifawithscope(struct ifnet *oifp, const struct in6_addr *dst, u_int rdomain, > struct rtentry *rt) > { > int dst_scope = in6_addrscope(dst), src_scope, best_scope = 0; > Index: netinet6/in6.h > =================================================================== > RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/in6.h,v > diff -u -p -r1.120 in6.h > --- netinet6/in6.h 2 Mar 2025 21:28:32 -0000 1.120 > +++ netinet6/in6.h 20 May 2025 03:37:00 -0000 > @@ -413,9 +413,9 @@ struct mbuf * > > int in6_cksum(struct mbuf *, uint8_t, uint32_t, uint32_t); > void in6_proto_cksum_out(struct mbuf *, struct ifnet *); > -int in6_addrscope(struct in6_addr *); > -struct in6_ifaddr *in6_ifawithscope(struct ifnet *, struct in6_addr *, u_int, > - struct rtentry *); > +int in6_addrscope(const struct in6_addr *); > +struct in6_ifaddr *in6_ifawithscope(struct ifnet *, const struct in6_addr *, > + u_int, struct rtentry *); > 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 **); > Index: netinet6/in6_src.c > =================================================================== > RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/in6_src.c,v > diff -u -p -r1.100 in6_src.c > --- netinet6/in6_src.c 1 Jan 2025 13:44:22 -0000 1.100 > +++ netinet6/in6_src.c 20 May 2025 03:46:11 -0000 > @@ -91,22 +91,21 @@ int in6_selectif(const struct in6_addr * > * the values set at pcb level can be overridden via cmsg. > */ > int > -in6_pcbselsrc(const struct in6_addr **in6src, struct sockaddr_in6 *dstsock, > - struct inpcb *inp, struct ip6_pktopts *opts) > +in6_pcbselsrc(const struct in6_addr **in6src, > + const struct sockaddr_in6 *dstsock, struct inpcb *inp, > + struct ip6_pktopts *opts) > { > - struct ip6_moptions *mopts = inp->inp_moptions6; > - struct rtentry *rt; > + const struct in6_addr *dst = &dstsock->sin6_addr; > const struct in6_addr *laddr = &inp->inp_laddr6; > + struct rtentry *rt; > + struct ip6_moptions *mopts = inp->inp_moptions6; > u_int rtableid = inp->inp_rtableid; > struct ifnet *ifp = NULL; > struct sockaddr *ip6_source = NULL; > - struct in6_addr *dst; > struct in6_ifaddr *ia6 = NULL; > struct in6_pktinfo *pi = NULL; > int error; > > - dst = &dstsock->sin6_addr; > - > /* > * If the source address is explicitly specified by the caller, > * check if the requested source address is indeed a unicast address > @@ -232,14 +231,13 @@ in6_pcbselsrc(const struct in6_addr **in > * an entry to the caller for later use. > */ > int > -in6_selectsrc(const struct in6_addr **in6src, struct sockaddr_in6 *dstsock, > +in6_selectsrc(const struct in6_addr **in6src, > + const struct sockaddr_in6 *dstsock, > struct ip6_moptions *mopts, unsigned int rtableid) > { > + const struct in6_addr *dst = &dstsock->sin6_addr; > struct ifnet *ifp = NULL; > - struct in6_addr *dst; > struct in6_ifaddr *ia6 = NULL; > - > - dst = &dstsock->sin6_addr; > > /* > * If the destination address is a link-local unicast address or > Index: netinet6/in6_var.h > =================================================================== > RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/in6_var.h,v > diff -u -p -r1.80 in6_var.h > --- netinet6/in6_var.h 13 May 2024 01:15:53 -0000 1.80 > +++ netinet6/in6_var.h 20 May 2025 03:38:12 -0000 > @@ -364,8 +364,8 @@ void in6_purgeaddr(struct ifaddr *); > int in6if_do_dad(struct ifnet *); > struct in6_ifaddr *in6ifa_ifpforlinklocal(struct ifnet *, int); > struct in6_ifaddr *in6ifa_ifpwithaddr(struct ifnet *, struct in6_addr *); > -int in6_addr2scopeid(unsigned int, struct in6_addr *); > -int in6_matchlen(struct in6_addr *, struct in6_addr *); > +int in6_addr2scopeid(unsigned int, const struct in6_addr *); > +int in6_matchlen(const struct in6_addr *, const struct in6_addr *); > void in6_prefixlen2mask(struct in6_addr *, int); > #endif /* _KERNEL */ > > Index: netinet6/ip6_var.h > =================================================================== > RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/ip6_var.h,v > diff -u -p -r1.123 ip6_var.h > --- netinet6/ip6_var.h 2 Mar 2025 21:28:32 -0000 1.123 > +++ netinet6/ip6_var.h 20 May 2025 03:33:40 -0000 > @@ -366,9 +366,9 @@ int rip6_sysctl(int *, u_int, void *, si > > int dest6_input(struct mbuf **, int *, int, int, struct netstack *); > > -int in6_pcbselsrc(const struct in6_addr **, struct sockaddr_in6 *, > +int in6_pcbselsrc(const struct in6_addr **, const struct sockaddr_in6 *, > struct inpcb *, struct ip6_pktopts *); > -int in6_selectsrc(const struct in6_addr **, struct sockaddr_in6 *, > +int in6_selectsrc(const struct in6_addr **, const struct sockaddr_in6 *, > struct ip6_moptions *, unsigned int); > struct rtentry *in6_selectroute(const struct in6_addr *, struct ip6_pktopts *, > struct route *, unsigned int rtableid); >