Run sysctl net.inet.ip.forwarding without net lock.
authorbluhm <bluhm@openbsd.org>
Fri, 12 Jul 2024 09:25:27 +0000 (09:25 +0000)
committerbluhm <bluhm@openbsd.org>
Fri, 12 Jul 2024 09:25:27 +0000 (09:25 +0000)
The places in packet processing where ip_forwarding is evaluated
have been consolidated.  The remaining pieces in pf test, ip input,
and icmp input do not need consistent information.  If the integer
value is changed by another CPU, it is harmless.
The sysctl syscall sets the value atomically, so add atomic read
in network processing and remove the net lock in sysctl IPCTL_FORWARDING.

OK claudio@ mvs@

sys/net/pf.c
sys/netinet/ip_icmp.c
sys/netinet/ip_input.c

index f22c319..fb278db 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: pf.c,v 1.1201 2024/07/04 12:50:08 bluhm Exp $ */
+/*     $OpenBSD: pf.c,v 1.1202 2024/07/12 09:25:27 bluhm Exp $ */
 
 /*
  * Copyright (c) 2001 Daniel Hartmeier
@@ -7966,7 +7966,7 @@ done:
                        if (pd.dir == PF_IN) {
                                int flags = IP_REDIRECT;
 
-                               switch (ip_forwarding) {
+                               switch (atomic_load_int(&ip_forwarding)) {
                                case 2:
                                        SET(flags, IP_FORWARDING_IPSEC);
                                        /* FALLTHROUGH */
index a283bc2..baaa9a2 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ip_icmp.c,v 1.194 2024/06/20 19:25:04 bluhm Exp $     */
+/*     $OpenBSD: ip_icmp.c,v 1.195 2024/07/12 09:25:27 bluhm Exp $     */
 /*     $NetBSD: ip_icmp.c,v 1.19 1996/02/13 23:42:22 christos Exp $    */
 
 /*
@@ -589,7 +589,8 @@ reflect:
                struct sockaddr_in ssrc;
                struct rtentry *newrt = NULL;
 
-               if (icmp_rediraccept == 0 || ip_forwarding != 0)
+               if (icmp_rediraccept == 0 ||
+                   atomic_load_int(&ip_forwarding) != 0)
                        goto freeit;
                if (code > 3)
                        goto badcode;
index 21221c1..8797a26 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ip_input.c,v 1.397 2024/07/02 18:33:47 bluhm Exp $    */
+/*     $OpenBSD: ip_input.c,v 1.398 2024/07/12 09:25:27 bluhm Exp $    */
 /*     $NetBSD: ip_input.c,v 1.30 1996/03/16 23:53:58 christos Exp $   */
 
 /*
 #include <netinet/ip_carp.h>
 #endif
 
+/*
+ * Locks used to protect global variables in this file:
+ *     I       immutable after creation
+ *     a       atomic operations
+ *     N       net lock
+ */
+
 /* values controllable via sysctl */
-int    ip_forwarding = 0;
+int    ip_forwarding = 0;                      /* [a] */
 int    ipmforwarding = 0;
 int    ipmultipath = 0;
 int    ip_sendredirects = 1;
@@ -108,7 +115,6 @@ const struct sysctl_bounded_args ipctl_vars[] = {
 #ifdef MROUTING
        { IPCTL_MRTPROTO, &ip_mrtproto, SYSCTL_INT_READONLY },
 #endif
-       { IPCTL_FORWARDING, &ip_forwarding, 0, 2 },
        { IPCTL_SENDREDIRECTS, &ip_sendredirects, 0, 1 },
        { IPCTL_DEFTTL, &ip_defttl, 0, 255 },
        { IPCTL_DIRECTEDBCAST, &ip_directedbcast, 0, 1 },
@@ -465,7 +471,7 @@ ip_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp)
                SET(flags, IP_REDIRECT);
 #endif
 
-       switch (ip_forwarding) {
+       switch (atomic_load_int(&ip_forwarding)) {
        case 2:
                SET(flags, IP_FORWARDING_IPSEC);
                /* FALLTHROUGH */
@@ -1792,6 +1798,9 @@ ip_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
                        atomic_inc_long(&rtgeneration);
                NET_UNLOCK();
                return (error);
+       case IPCTL_FORWARDING:
+               return (sysctl_int_bounded(oldp, oldlenp, newp, newlen,
+                   &ip_forwarding, 0, 2));
        default:
                NET_LOCK();
                error = sysctl_bounded_arr(ipctl_vars, nitems(ipctl_vars),