Index | Thread | Search

From:
Alexander Bluhm <bluhm@openbsd.org>
Subject:
Re: sysctl(2): unlock etherip_sysctl()
To:
Vitaliy Makkoveev <mvs@openbsd.org>
Cc:
tech@openbsd.org
Date:
Mon, 19 Aug 2024 13:23:34 +0200

Download raw body.

Thread
On Fri, Aug 16, 2024 at 05:42:44PM +0300, Vitaliy Makkoveev wrote:
> - ETHERIPCTL_ALLOW - atomically accessed integer;
> - ETHERIPCTL_STATS - per-CPU counters
> 
> ok?

OK bluhm@

> Index: sys/net/if_etherip.c
> ===================================================================
> RCS file: /cvs/src/sys/net/if_etherip.c,v
> diff -u -p -r1.55 if_etherip.c
> --- sys/net/if_etherip.c	13 Feb 2024 12:22:09 -0000	1.55
> +++ sys/net/if_etherip.c	16 Aug 2024 14:38:30 -0000
> @@ -55,6 +55,11 @@
>  
>  #include <net/if_etherip.h>
>  
> +/*
> + * Locks used to protect data:
> + *	a	atomic
> + */
> + 
>  union etherip_addr {
>  	struct in_addr	in4;
>  	struct in6_addr	in6;
> @@ -97,7 +102,7 @@ struct etherip_softc {
>   * We can control the acceptance of EtherIP packets by altering the sysctl
>   * net.inet.etherip.allow value. Zero means drop them, all else is acceptance.
>   */
> -int etherip_allow = 0;
> +int etherip_allow = 0;	/* [a] */
>  
>  struct cpumem *etheripcounters;
>  
> @@ -628,7 +633,8 @@ etherip_input(struct etherip_tunnel *key
>  	struct etherip_header *eip;
>  	int rxprio;
>  
> -	if (!etherip_allow && (m->m_flags & (M_AUTH|M_CONF)) == 0) {
> +	if (atomic_load_int(&etherip_allow) == 0 &&
> +	    (m->m_flags & (M_AUTH|M_CONF)) == 0) {
>  		etheripstat_inc(etherips_pdrops);
>  		goto drop;
>  	}
> @@ -799,19 +805,14 @@ int
>  etherip_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
>      void *newp, size_t newlen)
>  {
> -	int error;
> -
>  	/* All sysctl names at this level are terminal. */
>  	if (namelen != 1)
>  		return ENOTDIR;
>  
>  	switch (name[0]) {
>  	case ETHERIPCTL_ALLOW:
> -		NET_LOCK();
> -		error = sysctl_int_bounded(oldp, oldlenp, newp, newlen,
> -		    &etherip_allow, 0, 1);
> -		NET_UNLOCK();
> -		return (error);
> +		return (sysctl_int_bounded(oldp, oldlenp, newp, newlen,
> +		    &etherip_allow, 0, 1));
>  	case ETHERIPCTL_STATS:
>  		return (etherip_sysctl_etheripstat(oldp, oldlenp, newp));
>  	default:
> Index: sys/netinet/in_proto.c
> ===================================================================
> RCS file: /cvs/src/sys/netinet/in_proto.c,v
> diff -u -p -r1.108 in_proto.c
> --- sys/netinet/in_proto.c	16 Aug 2024 09:20:35 -0000	1.108
> +++ sys/netinet/in_proto.c	16 Aug 2024 14:38:30 -0000
> @@ -366,7 +366,7 @@ const struct protosw inetsw[] = {
>    .pr_type	= SOCK_RAW,
>    .pr_domain	= &inetdomain,
>    .pr_protocol	= IPPROTO_ETHERIP,
> -  .pr_flags	= PR_ATOMIC|PR_ADDR|PR_MPSOCKET,
> +  .pr_flags	= PR_ATOMIC|PR_ADDR|PR_MPSOCKET|PR_MPSYSCTL,
>    .pr_input	= ip_etherip_input,
>    .pr_ctloutput	= rip_ctloutput,
>    .pr_usrreqs	= &rip_usrreqs,