Hi,

The easiest way to make divert_packet() MP safe for now, is to
protect sbappendaddr() with kernel lock.

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