Index | Thread | Search

From:
Vitaliy Makkoveev <mvs@openbsd.org>
Subject:
Re: in_pcbselsrc() and in6_pcbselsrc() const sockaddr parameter
To:
Alexander Bluhm <bluhm@openbsd.org>
Cc:
tech@openbsd.org
Date:
Tue, 20 May 2025 12:26:41 +0000

Download raw body.

Thread
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);
>