From 9c4c1a6ff154df900c0b48496cb7a09e1d2a98b8 Mon Sep 17 00:00:00 2001 From: bluhm Date: Fri, 19 Jul 2024 16:58:31 +0000 Subject: [PATCH] Unlock sysctl net.inet.ip.redirect and net.inet6.ip6.redirect. 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 | 16 +++++++++------- sys/netinet6/in6_proto.c | 6 +++--- sys/netinet6/ip6_forward.c | 7 ++++--- sys/netinet6/ip6_input.c | 5 +++-- 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c index 1d68e0f6161..46e352610b7 100644 --- a/sys/netinet/ip_input.c +++ b/sys/netinet/ip_input.c @@ -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)); diff --git a/sys/netinet6/in6_proto.c b/sys/netinet6/in6_proto.c index a737e995c84..ac9f8848186 100644 --- a/sys/netinet6/in6_proto.c +++ b/sys/netinet6/in6_proto.c @@ -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; diff --git a/sys/netinet6/ip6_forward.c b/sys/netinet6/ip6_forward.c index 5d2cf55592a..c4054781c54 100644 --- a/sys/netinet6/ip6_forward.c +++ b/sys/netinet6/ip6_forward.c @@ -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)) { /* diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c index 4ab7d8c4578..79ba290503f 100644 --- a/sys/netinet6/ip6_input.c +++ b/sys/netinet6/ip6_input.c @@ -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)); -- 2.20.1