> Date: Thu, 5 May 2022 22:41:01 +0200
> From: Alexander Bluhm <alexander.bl...@gmx.net>
> 
> Hi,
> 
> The easiest way to make divert_packet() MP safe for now, is to
> protect sbappendaddr() with kernel lock.

All other invocations of sbappendaddr() run with the kernel lock held?
If so, maybe that should be asserted inside sbappendaddr()?

If not, I don't understand how this would help...

> ok?
> 
> bluhm
> 
> Index: netinet/ip_divert.c
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/ip_divert.c,v
> retrieving revision 1.67
> diff -u -p -r1.67 ip_divert.c
> --- netinet/ip_divert.c       5 May 2022 16:44:22 -0000       1.67
> +++ netinet/ip_divert.c       5 May 2022 20:36:23 -0000
> @@ -222,11 +222,18 @@ divert_packet(struct mbuf *m, int dir, u
>       }
>  
>       so = inp->inp_socket;
> +     /*
> +      * XXXSMP sbappendaddr() is not MP safe and this function is called
> +      * from pf with shared netlock.  To run only one sbappendaddr()
> +      * protect it with kernel lock.  Socket buffer access from system
> +      * call is protected with exclusive net lock.
> +      */
> +     KERNEL_LOCK();
>       if (sbappendaddr(so, &so->so_rcv, sintosa(&sin), m, NULL) == 0) {
> +             KERNEL_UNLOCK();
>               divstat_inc(divs_fullsock);
>               goto bad;
>       }
> -     KERNEL_LOCK();
>       sorwakeup(inp->inp_socket);
>       KERNEL_UNLOCK();
>  
> Index: netinet6/ip6_divert.c
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/ip6_divert.c,v
> retrieving revision 1.66
> diff -u -p -r1.66 ip6_divert.c
> --- netinet6/ip6_divert.c     5 May 2022 16:44:22 -0000       1.66
> +++ netinet6/ip6_divert.c     5 May 2022 20:36:23 -0000
> @@ -228,11 +228,18 @@ divert6_packet(struct mbuf *m, int dir, 
>       }
>  
>       so = inp->inp_socket;
> +     /*
> +      * XXXSMP sbappendaddr() is not MP safe and this function is called
> +      * from pf with shared netlock.  To run only one sbappendaddr()
> +      * protect it with kernel lock.  Socket buffer access from system
> +      * call is protected with exclusive net lock.
> +      */
> +     KERNEL_LOCK();
>       if (sbappendaddr(so, &so->so_rcv, sin6tosa(&sin6), m, NULL) == 0) {
> +             KERNEL_UNLOCK();
>               div6stat_inc(div6s_fullsock);
>               goto bad;
>       }
> -     KERNEL_LOCK();
>       sorwakeup(inp->inp_socket);
>       KERNEL_UNLOCK();
>  
> 
> 

Reply via email to