Index | Thread | Search

From:
Alexander Bluhm <bluhm@openbsd.org>
Subject:
Re: Unlock IPV6CTL_DEFMCASTHLIM case of ip6_sysctl()
To:
Vitaliy Makkoveev <mvs@openbsd.org>
Cc:
tech@openbsd.org
Date:
Thu, 24 Jul 2025 21:36:18 +0200

Download raw body.

Thread
On Thu, Jul 24, 2025 at 09:42:32PM +0300, Vitaliy Makkoveev wrote:
> Only ip6_setmoptions() needs to use cached value. Nothing critical if
> the destination interface was changed and ip6_output() will load
> `ip6_defmcasthlim' once again to re-initialize `ip6' header.

OK bluhm@

> Index: sys/netinet6/in6_proto.c
> ===================================================================
> RCS file: /cvs/src/sys/netinet6/in6_proto.c,v
> retrieving revision 1.141
> diff -u -p -r1.141 in6_proto.c
> --- sys/netinet6/in6_proto.c	24 Jul 2025 18:02:19 -0000	1.141
> +++ sys/netinet6/in6_proto.c	24 Jul 2025 18:31:27 -0000
> @@ -352,9 +352,9 @@ int	ip6_forwarding = 0;	/* [a] no forwar
>  int	ip6_mforwarding = 0;	/* no multicast forwarding unless ... */
>  int	ip6_multipath = 0;	/* [a] no using multipath routes unless ... */
>  int	ip6_sendredirects = 1;	/* [a] */
> -int	ip6_defhlim = IPV6_DEFHLIM;	/* [a] */
> -int	ip6_defmcasthlim = IPV6_DEFAULT_MULTICAST_HOPS;
> -int	ip6_maxfragpackets = 200;	/* [a] */
> +int	ip6_defhlim = IPV6_DEFHLIM;			/* [a] */
> +int	ip6_defmcasthlim = IPV6_DEFAULT_MULTICAST_HOPS; /* [a] */
> +int	ip6_maxfragpackets = 200;			/* [a] */
>  int	ip6_maxfrags = 200;
>  int	ip6_log_interval = 5;	/* [a] */
>  int	ip6_hdrnestlimit = 10;	/* [a] appropriate? */
> Index: sys/netinet6/ip6_input.c
> ===================================================================
> RCS file: /cvs/src/sys/netinet6/ip6_input.c,v
> retrieving revision 1.285
> diff -u -p -r1.285 ip6_input.c
> --- sys/netinet6/ip6_input.c	24 Jul 2025 18:02:19 -0000	1.285
> +++ sys/netinet6/ip6_input.c	24 Jul 2025 18:31:27 -0000
> @@ -1452,10 +1452,10 @@ const struct sysctl_bounded_args ipv6ctl
>  	{ IPV6CTL_HDRNESTLIMIT, &ip6_hdrnestlimit, 0, 100 },
>  	{ IPV6CTL_DAD_COUNT, &ip6_dad_count, 0, 10 },
>  	{ IPV6CTL_AUTO_FLOWLABEL, &ip6_auto_flowlabel, 0, 1 },
> +	{ IPV6CTL_DEFMCASTHLIM, &ip6_defmcasthlim, 0, 255 },
>  };
>  
>  const struct sysctl_bounded_args ipv6ctl_vars[] = {
> -	{ IPV6CTL_DEFMCASTHLIM, &ip6_defmcasthlim, 0, 255 },
>  	{ IPV6CTL_USE_DEPRECATED, &ip6_use_deprecated, 0, 1 },
>  	{ IPV6CTL_MAXFRAGS, &ip6_maxfrags, 0, 1000 },
>  	{ IPV6CTL_MFORWARDING, &ip6_mforwarding, 0, 1 },
> @@ -1575,6 +1575,7 @@ ip6_sysctl(int *name, u_int namelen, voi
>  	case IPV6CTL_HDRNESTLIMIT:
>  	case IPV6CTL_DAD_COUNT:
>  	case IPV6CTL_AUTO_FLOWLABEL:
> +	case IPV6CTL_DEFMCASTHLIM:
>  		return (sysctl_bounded_arr(
>  		    ipv6ctl_vars_unlocked, nitems(ipv6ctl_vars_unlocked),
>  		    name, namelen, oldp, oldlenp, newp, newlen));
> Index: sys/netinet6/ip6_output.c
> ===================================================================
> RCS file: /cvs/src/sys/netinet6/ip6_output.c,v
> retrieving revision 1.301
> diff -u -p -r1.301 ip6_output.c
> --- sys/netinet6/ip6_output.c	8 Jul 2025 00:47:41 -0000	1.301
> +++ sys/netinet6/ip6_output.c	24 Jul 2025 18:31:27 -0000
> @@ -420,7 +420,7 @@ reroute:
>  		if (im6o != NULL)
>  			ip6->ip6_hlim = im6o->im6o_hlim;
>  		else
> -			ip6->ip6_hlim = ip6_defmcasthlim;
> +			ip6->ip6_hlim = atomic_load_int(&ip6_defmcasthlim);
>  	}
>  
>  #ifdef IPSEC
> @@ -1879,6 +1879,7 @@ ip6_setmoptions(int optname, struct ip6_
>  	struct ip6_moptions *im6o = *im6op;
>  	struct in6_multi_mship *imm;
>  	struct proc *p = curproc;	/* XXX */
> +	int ip6_defmcasthlim_local = atomic_load_int(&ip6_defmcasthlim);
>  
>  	if (im6o == NULL) {
>  		/*
> @@ -1890,7 +1891,7 @@ ip6_setmoptions(int optname, struct ip6_
>  			return (ENOBUFS);
>  		*im6op = im6o;
>  		im6o->im6o_ifidx = 0;
> -		im6o->im6o_hlim = ip6_defmcasthlim;
> +		im6o->im6o_hlim = ip6_defmcasthlim_local;
>  		im6o->im6o_loop = IPV6_DEFAULT_MULTICAST_LOOP;
>  		LIST_INIT(&im6o->im6o_memberships);
>  	}
> @@ -1937,7 +1938,7 @@ ip6_setmoptions(int optname, struct ip6_
>  		if (optval < -1 || optval >= 256)
>  			error = EINVAL;
>  		else if (optval == -1)
> -			im6o->im6o_hlim = ip6_defmcasthlim;
> +			im6o->im6o_hlim = ip6_defmcasthlim_local;
>  		else
>  			im6o->im6o_hlim = optval;
>  		break;
> @@ -2137,7 +2138,7 @@ ip6_setmoptions(int optname, struct ip6_
>  	 * structure.
>  	 */
>  	if (im6o->im6o_ifidx == 0 &&
> -	    im6o->im6o_hlim == ip6_defmcasthlim &&
> +	    im6o->im6o_hlim == ip6_defmcasthlim_local &&
>  	    im6o->im6o_loop == IPV6_DEFAULT_MULTICAST_LOOP &&
>  	    LIST_EMPTY(&im6o->im6o_memberships)) {
>  		free(*im6op, M_IPMOPTS, sizeof(**im6op));
> @@ -2169,7 +2170,7 @@ ip6_getmoptions(int optname, struct ip6_
>  		hlim = mtod(m, u_int *);
>  		m->m_len = sizeof(u_int);
>  		if (im6o == NULL)
> -			*hlim = ip6_defmcasthlim;
> +			*hlim = atomic_load_int(&ip6_defmcasthlim);
>  		else
>  			*hlim = im6o->im6o_hlim;
>  		return (0);
> @@ -2178,7 +2179,7 @@ ip6_getmoptions(int optname, struct ip6_
>  		loop = mtod(m, u_int *);
>  		m->m_len = sizeof(u_int);
>  		if (im6o == NULL)
> -			*loop = ip6_defmcasthlim;
> +			*loop = atomic_load_int(&ip6_defmcasthlim);
>  		else
>  			*loop = im6o->im6o_loop;
>  		return (0);