Download raw body.
sysctl ip6 forwarding unlock
Hi,
Personally I prefer ‘_local’ postfix like we already used for
unlocked sysctls like kern.somaxconn, kern.sominconn or
net.pipex.enable
solisten(struct socket *so, int backlog)
{
int somaxconn_local = READ_ONCE(somaxconn);
int sominconn_local = READ_ONCE(sominconn);
pppx_if_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
struct rtentry *rt)
{
struct pppx_if *pxi = (struct pppx_if *)ifp->if_softc;
struct pppx_hdr *th;
int error = 0;
int pipex_enable_local, proto;
pipex_enable_local = atomic_load_int(&pipex_enable);
The rest of the diff is good for me.
> On 14 Jul 2024, at 18:13, Alexander Bluhm <bluhm@openbsd.org> wrote:
>
> Hi,
>
> Like already done for IPv4, also unlock ip6_forwarding from net
> lock.
>
> To make clear where actually the router property is needed, I added
> the i_am_router variable. It already existed in nd6_nbr. Move
> i_am_router setting up the call stack until all users seem to be
> independent.
>
> The forwarding decisions in pf_test, pf_refragment6, ip6_input do
> also not interfere.
>
> Use a new array ipv6ctl_vars_unlocked to make transition of all the
> integer sysctls easier. Adapt IPv4 to the new style.
>
> ok?
>
> bluhm
>
> Index: net/if.c
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/net/if.c,v
> diff -u -p -r1.719 if.c
> --- net/if.c 20 Jun 2024 19:25:42 -0000 1.719
> +++ net/if.c 14 Jul 2024 08:52:35 -0000
> @@ -3353,6 +3353,7 @@ ifnewlladdr(struct ifnet *ifp)
> {
> #ifdef INET6
> struct ifaddr *ifa;
> + int i_am_router = (atomic_load_int(&ip6_forwarding) != 0);
> #endif
> struct ifreq ifrq;
> short up;
> @@ -3378,7 +3379,7 @@ ifnewlladdr(struct ifnet *ifp)
> * Update the link-local address. Don't do it if we're
> * a router to avoid confusing hosts on the network.
> */
> - if (ip6_forwarding == 0) {
> + if (!i_am_router) {
> ifa = &in6ifa_ifpforlinklocal(ifp, 0)->ia_ifa;
> if (ifa) {
> in6_purgeaddr(ifa);
> Index: net/pf.c
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/net/pf.c,v
> diff -u -p -r1.1202 pf.c
> --- net/pf.c 12 Jul 2024 09:25:27 -0000 1.1202
> +++ net/pf.c 14 Jul 2024 08:52:35 -0000
> @@ -7988,7 +7988,7 @@ done:
> if (pd.dir == PF_IN) {
> int flags = IPV6_REDIRECT;
>
> - switch (ip6_forwarding) {
> + switch (atomic_load_int(&ip6_forwarding)) {
> case 2:
> SET(flags, IPV6_FORWARDING_IPSEC);
> /* FALLTHROUGH */
> Index: net/pf_norm.c
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/net/pf_norm.c,v
> diff -u -p -r1.232 pf_norm.c
> --- net/pf_norm.c 4 Jul 2024 12:50:08 -0000 1.232
> +++ net/pf_norm.c 14 Jul 2024 08:52:35 -0000
> @@ -1013,7 +1013,7 @@ pf_refragment6(struct mbuf **m0, struct
> if (ifp == NULL) {
> int flags = 0;
>
> - switch (ip6_forwarding) {
> + switch (atomic_load_int(&ip6_forwarding)) {
> case 2:
> SET(flags, IPV6_FORWARDING_IPSEC);
> /* FALLTHROUGH */
> Index: netinet/ip_carp.c
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/ip_carp.c,v
> diff -u -p -r1.362 ip_carp.c
> --- netinet/ip_carp.c 20 Jun 2024 19:25:42 -0000 1.362
> +++ netinet/ip_carp.c 14 Jul 2024 08:52:35 -0000
> @@ -1287,9 +1287,10 @@ carp_send_na(struct carp_softc *sc)
> struct ifaddr *ifa;
> struct in6_addr *in6;
> static struct in6_addr mcast = IN6ADDR_LINKLOCAL_ALLNODES_INIT;
> + int i_am_router = (atomic_load_int(&ip6_forwarding) != 0);
> int flags = ND_NA_FLAG_OVERRIDE;
>
> - if (ip6_forwarding != 0)
> + if (i_am_router)
> flags |= ND_NA_FLAG_ROUTER;
>
> TAILQ_FOREACH(ifa, &sc->sc_if.if_addrlist, ifa_list) {
> Index: netinet/ip_icmp.c
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/ip_icmp.c,v
> diff -u -p -r1.195 ip_icmp.c
> --- netinet/ip_icmp.c 12 Jul 2024 09:25:27 -0000 1.195
> +++ netinet/ip_icmp.c 14 Jul 2024 14:54:13 -0000
> @@ -588,9 +588,9 @@ reflect:
> struct sockaddr_in sgw;
> struct sockaddr_in ssrc;
> struct rtentry *newrt = NULL;
> + int i_am_router = (atomic_load_int(&ip_forwarding) != 0);
>
> - if (icmp_rediraccept == 0 ||
> - atomic_load_int(&ip_forwarding) != 0)
> + if (icmp_rediraccept == 0 || i_am_router)
> goto freeit;
> if (code > 3)
> goto badcode;
> Index: netinet/ip_input.c
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/ip_input.c,v
> diff -u -p -r1.398 ip_input.c
> --- netinet/ip_input.c 12 Jul 2024 09:25:27 -0000 1.398
> +++ netinet/ip_input.c 14 Jul 2024 09:01:22 -0000
> @@ -111,6 +111,10 @@ LIST_HEAD(, ipq) ipq;
> int ip_maxqueue = 300;
> int ip_frags = 0;
>
> +const struct sysctl_bounded_args ipctl_vars_unlocked[] = {
> + { IPCTL_FORWARDING, &ip_forwarding, 0, 2 },
> +};
> +
> const struct sysctl_bounded_args ipctl_vars[] = {
> #ifdef MROUTING
> { IPCTL_MRTPROTO, &ip_mrtproto, SYSCTL_INT_READONLY },
> @@ -1799,8 +1803,9 @@ ip_sysctl(int *name, u_int namelen, void
> NET_UNLOCK();
> return (error);
> case IPCTL_FORWARDING:
> - return (sysctl_int_bounded(oldp, oldlenp, newp, newlen,
> - &ip_forwarding, 0, 2));
> + return (sysctl_bounded_arr(
> + ipctl_vars_unlocked, nitems(ipctl_vars_unlocked),
> + name, namelen, oldp, oldlenp, newp, newlen));
> default:
> NET_LOCK();
> error = sysctl_bounded_arr(ipctl_vars, nitems(ipctl_vars),
> Index: netinet6/icmp6.c
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/icmp6.c,v
> diff -u -p -r1.253 icmp6.c
> --- netinet6/icmp6.c 20 Jun 2024 19:25:42 -0000 1.253
> +++ netinet6/icmp6.c 14 Jul 2024 14:44:30 -0000
> @@ -1228,6 +1228,7 @@ icmp6_redirect_input(struct mbuf *m, int
> char *lladdr = NULL;
> int lladdrlen = 0;
> struct rtentry *rt = NULL;
> + int i_am_router = (atomic_load_int(&ip6_forwarding) != 0);
> int is_router;
> int is_onlink;
> struct in6_addr src6 = ip6->ip6_src;
> @@ -1241,7 +1242,7 @@ icmp6_redirect_input(struct mbuf *m, int
> return;
>
> /* if we are router, we don't update route by icmp6 redirect */
> - if (ip6_forwarding != 0)
> + if (i_am_router)
> goto freeit;
> if (!(ifp->if_xflags & IFXF_AUTOCONF6))
> goto freeit;
> @@ -1366,7 +1367,7 @@ icmp6_redirect_input(struct mbuf *m, int
>
> /* RFC 2461 8.3 */
> nd6_cache_lladdr(ifp, &redtgt6, lladdr, lladdrlen, ND_REDIRECT,
> - is_onlink ? ND_REDIRECT_ONLINK : ND_REDIRECT_ROUTER);
> + is_onlink ? ND_REDIRECT_ONLINK : ND_REDIRECT_ROUTER, i_am_router);
>
> if (!is_onlink) { /* better router case. perform rtredirect. */
> /* perform rtredirect */
> @@ -1438,11 +1439,12 @@ icmp6_redirect_output(struct mbuf *m0, s
> size_t maxlen;
> u_char *p;
> struct sockaddr_in6 src_sa;
> + int i_am_router = (atomic_load_int(&ip6_forwarding) != 0);
>
> icmp6_errcount(ND_REDIRECT, 0);
>
> /* if we are not router, we don't send icmp6 redirect */
> - if (ip6_forwarding == 0)
> + if (!i_am_router)
> goto fail;
>
> /* sanity check */
> Index: netinet6/ip6_input.c
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/ip6_input.c,v
> diff -u -p -r1.264 ip6_input.c
> --- netinet6/ip6_input.c 4 Jul 2024 12:50:08 -0000 1.264
> +++ netinet6/ip6_input.c 14 Jul 2024 09:03:09 -0000
> @@ -416,7 +416,7 @@ ip6_input_if(struct mbuf **mp, int *offp
> SET(flags, IPV6_REDIRECT);
> #endif
>
> - switch (ip6_forwarding) {
> + switch (atomic_load_int(&ip6_forwarding)) {
> case 2:
> SET(flags, IPV6_FORWARDING_IPSEC);
> /* FALLTHROUGH */
> @@ -1443,12 +1443,15 @@ const u_char inet6ctlerrmap[PRC_NCMDS] =
> extern int ip6_mrtproto;
> #endif
>
> +const struct sysctl_bounded_args ipv6ctl_vars_unlocked[] = {
> + { IPV6CTL_FORWARDING, &ip6_forwarding, 0, 2 },
> +};
> +
> const struct sysctl_bounded_args ipv6ctl_vars[] = {
> { IPV6CTL_DAD_PENDING, &ip6_dad_pending, SYSCTL_INT_READONLY },
> #ifdef MROUTING
> { IPV6CTL_MRTPROTO, &ip6_mrtproto, SYSCTL_INT_READONLY },
> #endif
> - { IPV6CTL_FORWARDING, &ip6_forwarding, 0, 2 },
> { IPV6CTL_SENDREDIRECTS, &ip6_sendredirects, 0, 1 },
> { IPV6CTL_DEFHLIM, &ip6_defhlim, 0, 255 },
> { IPV6CTL_MAXFRAGPACKETS, &ip6_maxfragpackets, 0, 1000 },
> @@ -1568,6 +1571,10 @@ ip6_sysctl(int *name, u_int namelen, voi
> atomic_inc_long(&rtgeneration);
> NET_UNLOCK();
> return (error);
> + case IPV6CTL_FORWARDING:
> + return (sysctl_bounded_arr(
> + ipv6ctl_vars_unlocked, nitems(ipv6ctl_vars_unlocked),
> + name, namelen, oldp, oldlenp, newp, newlen));
> default:
> NET_LOCK();
> error = sysctl_bounded_arr(ipv6ctl_vars, nitems(ipv6ctl_vars),
> Index: netinet6/nd6.c
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/nd6.c,v
> diff -u -p -r1.281 nd6.c
> --- netinet6/nd6.c 20 Jun 2024 19:25:42 -0000 1.281
> +++ netinet6/nd6.c 14 Jul 2024 14:44:51 -0000
> @@ -107,8 +107,8 @@ void nd6_slowtimo(void *);
> void nd6_expire(void *);
> void nd6_expire_timer(void *);
> void nd6_invalidate(struct rtentry *);
> -void nd6_free(struct rtentry *);
> -int nd6_llinfo_timer(struct rtentry *);
> +void nd6_free(struct rtentry *, int);
> +int nd6_llinfo_timer(struct rtentry *, int);
>
> struct timeout nd6_timer_to;
> struct timeout nd6_slowtimo_ch;
> @@ -264,6 +264,7 @@ nd6_timer(void *unused)
> {
> struct llinfo_nd6 *ln, *nln;
> time_t uptime, expire;
> + int i_am_router = (atomic_load_int(&ip6_forwarding) != 0);
> int secs;
>
> NET_LOCK();
> @@ -276,7 +277,7 @@ nd6_timer(void *unused)
> struct rtentry *rt = ln->ln_rt;
>
> if (rt->rt_expire && rt->rt_expire <= uptime)
> - if (nd6_llinfo_timer(rt))
> + if (nd6_llinfo_timer(rt, i_am_router))
> continue;
>
> if (rt->rt_expire && rt->rt_expire < expire)
> @@ -300,7 +301,7 @@ nd6_timer(void *unused)
> * Returns 1 if `rt' should no longer be used, 0 otherwise.
> */
> int
> -nd6_llinfo_timer(struct rtentry *rt)
> +nd6_llinfo_timer(struct rtentry *rt, int i_am_router)
> {
> struct llinfo_nd6 *ln = (struct llinfo_nd6 *)rt->rt_llinfo;
> struct sockaddr_in6 *dst = satosin6(rt_key(rt));
> @@ -346,7 +347,7 @@ nd6_llinfo_timer(struct rtentry *rt)
> } else
> atomic_sub_int(&ln_hold_total, len);
>
> - nd6_free(rt);
> + nd6_free(rt, i_am_router);
> ln = NULL;
> }
> break;
> @@ -362,7 +363,7 @@ nd6_llinfo_timer(struct rtentry *rt)
> case ND6_LLINFO_PURGE:
> /* Garbage Collection(RFC 2461 5.3) */
> if (!ND6_LLINFO_PERMANENT(ln)) {
> - nd6_free(rt);
> + nd6_free(rt, i_am_router);
> ln = NULL;
> }
> break;
> @@ -383,7 +384,7 @@ nd6_llinfo_timer(struct rtentry *rt)
> nd6_ns_output(ifp, &dst->sin6_addr, &dst->sin6_addr,
> &ln->ln_saddr6, 0);
> } else {
> - nd6_free(rt);
> + nd6_free(rt, i_am_router);
> ln = NULL;
> }
> break;
> @@ -477,6 +478,7 @@ void
> nd6_purge(struct ifnet *ifp)
> {
> struct llinfo_nd6 *ln, *nln;
> + int i_am_router = (atomic_load_int(&ip6_forwarding) != 0);
>
> NET_ASSERT_LOCKED_EXCLUSIVE();
>
> @@ -492,7 +494,7 @@ nd6_purge(struct ifnet *ifp)
> rt->rt_gateway->sa_family == AF_LINK) {
> sdl = satosdl(rt->rt_gateway);
> if (sdl->sdl_index == ifp->if_index)
> - nd6_free(rt);
> + nd6_free(rt, i_am_router);
> }
> }
> }
> @@ -661,7 +663,7 @@ nd6_invalidate(struct rtentry *rt)
> * Free an nd6 llinfo entry.
> */
> void
> -nd6_free(struct rtentry *rt)
> +nd6_free(struct rtentry *rt, int i_am_router)
> {
> struct llinfo_nd6 *ln = (struct llinfo_nd6 *)rt->rt_llinfo;
> struct in6_addr in6 = satosin6(rt_key(rt))->sin6_addr;
> @@ -671,7 +673,7 @@ nd6_free(struct rtentry *rt)
>
> ifp = if_get(rt->rt_ifidx);
>
> - if (ip6_forwarding == 0) {
> + if (!i_am_router) {
> if (ln->ln_router) {
> /*
> * rt6_flush must be called whether or not the neighbor
> @@ -1031,7 +1033,7 @@ nd6_ioctl(u_long cmd, caddr_t data, stru
> */
> void
> nd6_cache_lladdr(struct ifnet *ifp, const struct in6_addr *from, char *lladdr,
> - int lladdrlen, int type, int code)
> + int lladdrlen, int type, int code, int i_am_router)
> {
> struct rtentry *rt;
> struct llinfo_nd6 *ln;
> @@ -1080,7 +1082,7 @@ nd6_cache_lladdr(struct ifnet *ifp, cons
> return;
> if ((rt->rt_flags & (RTF_GATEWAY | RTF_LLINFO)) != RTF_LLINFO) {
> fail:
> - nd6_free(rt);
> + nd6_free(rt, i_am_router);
> rtfree(rt);
> return;
> }
> Index: netinet6/nd6.h
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/nd6.h,v
> diff -u -p -r1.99 nd6.h
> --- netinet6/nd6.h 4 May 2023 06:56:56 -0000 1.99
> +++ netinet6/nd6.h 14 Jul 2024 14:38:25 -0000
> @@ -134,7 +134,7 @@ void nd6_nud_hint(struct rtentry *);
> void nd6_rtrequest(struct ifnet *, int, struct rtentry *);
> int nd6_ioctl(u_long, caddr_t, struct ifnet *);
> void nd6_cache_lladdr(struct ifnet *, const struct in6_addr *, char *,
> - int, int, int);
> + int, int, int, int);
> int nd6_resolve(struct ifnet *, struct rtentry *, struct mbuf *,
> struct sockaddr *, u_char *);
> int nd6_need_cache(struct ifnet *);
> Index: netinet6/nd6_nbr.c
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/nd6_nbr.c,v
> diff -u -p -r1.152 nd6_nbr.c
> --- netinet6/nd6_nbr.c 20 Jun 2024 19:25:42 -0000 1.152
> +++ netinet6/nd6_nbr.c 14 Jul 2024 14:39:34 -0000
> @@ -108,7 +108,7 @@ nd6_ns_input(struct mbuf *m, int off, in
> struct ifaddr *ifa = NULL;
> int lladdrlen = 0;
> int anycast = 0, proxy = 0, tentative = 0;
> - int i_am_router = (ip6_forwarding != 0);
> + int i_am_router = (atomic_load_int(&ip6_forwarding) != 0);
> int tlladdr;
> struct nd_opts ndopts;
> struct sockaddr_dl *proxydl = NULL;
> @@ -323,7 +323,7 @@ nd6_ns_input(struct mbuf *m, int off, in
> }
>
> nd6_cache_lladdr(ifp, &saddr6, lladdr, lladdrlen, ND_NEIGHBOR_SOLICIT,
> - 0);
> + 0, i_am_router);
>
> nd6_na_output(ifp, &saddr6, &taddr6,
> ((anycast || proxy || !tlladdr) ? 0 : ND_NA_FLAG_OVERRIDE) |
> @@ -559,7 +559,7 @@ nd6_na_input(struct mbuf *m, int off, in
> int is_override;
> char *lladdr = NULL;
> int lladdrlen = 0;
> - int i_am_router = (ip6_forwarding != 0);
> + int i_am_router = (atomic_load_int(&ip6_forwarding) != 0);
> struct ifaddr *ifa;
> struct in6_ifaddr *ifa6;
> struct llinfo_nd6 *ln;
> Index: netinet6/nd6_rtr.c
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/nd6_rtr.c,v
> diff -u -p -r1.170 nd6_rtr.c
> --- netinet6/nd6_rtr.c 31 Mar 2023 19:43:33 -0000 1.170
> +++ netinet6/nd6_rtr.c 14 Jul 2024 14:42:55 -0000
> @@ -73,6 +73,7 @@ nd6_rtr_cache(struct mbuf *m, int off, i
> struct in6_addr saddr6 = ip6->ip6_src;
> char *lladdr = NULL;
> int lladdrlen = 0;
> + int i_am_router = (atomic_load_int(&ip6_forwarding) != 0);
> struct nd_opts ndopts;
> char src[INET6_ADDRSTRLEN], dst[INET6_ADDRSTRLEN];
>
> @@ -157,7 +158,8 @@ nd6_rtr_cache(struct mbuf *m, int off, i
> goto bad;
> }
>
> - nd6_cache_lladdr(ifp, &saddr6, lladdr, lladdrlen, icmp6_type, 0);
> + nd6_cache_lladdr(ifp, &saddr6, lladdr, lladdrlen, icmp6_type, 0,
> + i_am_router);
> if_put(ifp);
>
> freeit:
>
sysctl ip6 forwarding unlock