Unlock sysctl net.inet.ip.redirect and net.inet6.ip6.redirect.
authorbluhm <bluhm@openbsd.org>
Fri, 19 Jul 2024 16:58:31 +0000 (16:58 +0000)
committerbluhm <bluhm@openbsd.org>
Fri, 19 Jul 2024 16:58:31 +0000 (16:58 +0000)
Variable ip and ip6 sendredirects is only read once during packet
processing.  Use atomic_load_int() to access the value in exactly
one read instruction.  No memory barriers needed as there is no
correlation with other values.
Sort the ip and ip6 checks, so the difference is easier to see.
Move access to global variable to the end.

OK mvs@

sys/netinet/ip_input.c
sys/netinet6/in6_proto.c
sys/netinet6/ip6_forward.c
sys/netinet6/ip6_input.c

index 1d68e0f..46e3526 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ip_input.c,v 1.399 2024/07/14 18:53:39 bluhm Exp $    */
+/*     $OpenBSD: ip_input.c,v 1.400 2024/07/19 16:58:31 bluhm Exp $    */
 /*     $NetBSD: ip_input.c,v 1.30 1996/03/16 23:53:58 christos Exp $   */
 
 /*
@@ -94,7 +94,7 @@
 int    ip_forwarding = 0;                      /* [a] */
 int    ipmforwarding = 0;
 int    ipmultipath = 0;
-int    ip_sendredirects = 1;
+int    ip_sendredirects = 1;                   /* [a] */
 int    ip_dosourceroute = 0;
 int    ip_defttl = IPDEFTTL;
 int    ip_mtudisc = 1;
@@ -113,13 +113,13 @@ int       ip_frags = 0;
 
 const struct sysctl_bounded_args ipctl_vars_unlocked[] = {
        { IPCTL_FORWARDING, &ip_forwarding, 0, 2 },
+       { IPCTL_SENDREDIRECTS, &ip_sendredirects, 0, 1 },
 };
 
 const struct sysctl_bounded_args ipctl_vars[] = {
 #ifdef MROUTING
        { IPCTL_MRTPROTO, &ip_mrtproto, SYSCTL_INT_READONLY },
 #endif
-       { IPCTL_SENDREDIRECTS, &ip_sendredirects, 0, 1 },
        { IPCTL_DEFTTL, &ip_defttl, 0, 255 },
        { IPCTL_DIRECTEDBCAST, &ip_directedbcast, 0, 1 },
        { IPCTL_IPPORT_FIRSTAUTO, &ipport_firstauto, 0, 65535 },
@@ -1605,10 +1605,11 @@ ip_forward(struct mbuf *m, struct ifnet *ifp, struct route *ro, int flags)
         * Don't send redirect if we advertise destination's arp address
         * as ours (proxy arp).
         */
-       if ((rt->rt_ifidx == ifp->if_index) &&
-           (rt->rt_flags & (RTF_DYNAMIC|RTF_MODIFIED)) == 0 &&
-           satosin(rt_key(rt))->sin_addr.s_addr != 0 &&
-           ip_sendredirects && !ISSET(flags, IP_REDIRECT) &&
+       if (rt->rt_ifidx == ifp->if_index &&
+           !ISSET(rt->rt_flags, RTF_DYNAMIC|RTF_MODIFIED) &&
+           satosin(rt_key(rt))->sin_addr.s_addr != INADDR_ANY &&
+           !ISSET(flags, IP_REDIRECT) &&
+           atomic_load_int(&ip_sendredirects) &&
            !arpproxy(satosin(rt_key(rt))->sin_addr, rtableid)) {
                if ((ip->ip_src.s_addr & ifatoia(rt->rt_ifa)->ia_netmask) ==
                    ifatoia(rt->rt_ifa)->ia_net) {
@@ -1803,6 +1804,7 @@ ip_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
                NET_UNLOCK();
                return (error);
        case IPCTL_FORWARDING:
+       case IPCTL_SENDREDIRECTS:
                return (sysctl_bounded_arr(
                    ipctl_vars_unlocked, nitems(ipctl_vars_unlocked),
                    name, namelen, oldp, oldlenp, newp, newlen));
index a737e99..ac9f884 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: in6_proto.c,v 1.115 2024/07/12 19:50:35 bluhm Exp $   */
+/*     $OpenBSD: in6_proto.c,v 1.116 2024/07/19 16:58:32 bluhm Exp $   */
 /*     $KAME: in6_proto.c,v 1.66 2000/10/10 15:35:47 itojun Exp $      */
 
 /*
@@ -343,10 +343,10 @@ const struct domain inet6domain = {
 /*
  * Internet configuration info
  */
-int    ip6_forwarding = 0;     /* no forwarding unless sysctl'd to enable */
+int    ip6_forwarding = 0;     /* [a] no forwarding unless sysctl to enable */
 int    ip6_mforwarding = 0;    /* no multicast forwarding unless ... */
 int    ip6_multipath = 0;      /* no using multipath routes unless ... */
-int    ip6_sendredirects = 1;
+int    ip6_sendredirects = 1;  /* [a] */
 int    ip6_defhlim = IPV6_DEFHLIM;
 int    ip6_defmcasthlim = IPV6_DEFAULT_MULTICAST_HOPS;
 int    ip6_maxfragpackets = 200;
index 5d2cf55..c405478 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ip6_forward.c,v 1.123 2024/07/13 10:09:40 bluhm Exp $ */
+/*     $OpenBSD: ip6_forward.c,v 1.124 2024/07/19 16:58:32 bluhm Exp $ */
 /*     $KAME: ip6_forward.c,v 1.75 2001/06/29 12:42:13 jinmei Exp $    */
 
 /*
@@ -280,8 +280,9 @@ reroute:
                goto freecopy;
        }
        if (rt->rt_ifidx == ifidx &&
-           ip6_sendredirects && !ISSET(flags, IPV6_REDIRECT) &&
-           (rt->rt_flags & (RTF_DYNAMIC|RTF_MODIFIED)) == 0) {
+           !ISSET(rt->rt_flags, RTF_DYNAMIC|RTF_MODIFIED) &&
+           !ISSET(flags, IPV6_REDIRECT) &&
+           atomic_load_int(&ip6_sendredirects)) {
                if ((ifp->if_flags & IFF_POINTOPOINT) &&
                    nd6_is_addr_neighbor(&ro->ro_dstsin6, ifp)) {
                        /*
index 4ab7d8c..79ba290 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ip6_input.c,v 1.265 2024/07/14 18:53:39 bluhm Exp $   */
+/*     $OpenBSD: ip6_input.c,v 1.266 2024/07/19 16:58:32 bluhm Exp $   */
 /*     $KAME: ip6_input.c,v 1.188 2001/03/29 05:34:31 itojun Exp $     */
 
 /*
@@ -1445,6 +1445,7 @@ extern int ip6_mrtproto;
 
 const struct sysctl_bounded_args ipv6ctl_vars_unlocked[] = {
        { IPV6CTL_FORWARDING, &ip6_forwarding, 0, 2 },
+       { IPV6CTL_SENDREDIRECTS, &ip6_sendredirects, 0, 1 },
 };
 
 const struct sysctl_bounded_args ipv6ctl_vars[] = {
@@ -1452,7 +1453,6 @@ const struct sysctl_bounded_args ipv6ctl_vars[] = {
 #ifdef MROUTING
        { IPV6CTL_MRTPROTO, &ip6_mrtproto, SYSCTL_INT_READONLY },
 #endif
-       { IPV6CTL_SENDREDIRECTS, &ip6_sendredirects, 0, 1 },
        { IPV6CTL_DEFHLIM, &ip6_defhlim, 0, 255 },
        { IPV6CTL_MAXFRAGPACKETS, &ip6_maxfragpackets, 0, 1000 },
        { IPV6CTL_LOG_INTERVAL, &ip6_log_interval, 0, INT_MAX },
@@ -1572,6 +1572,7 @@ ip6_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
                NET_UNLOCK();
                return (error);
        case IPV6CTL_FORWARDING:
+       case IPV6CTL_SENDREDIRECTS:
                return (sysctl_bounded_arr(
                    ipv6ctl_vars_unlocked, nitems(ipv6ctl_vars_unlocked),
                    name, namelen, oldp, oldlenp, newp, newlen));