diff options
author | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2024-06-20 19:25:43 +0000 |
---|---|---|
committer | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2024-06-20 19:25:43 +0000 |
commit | 8fb789f4ab1f9e44048fb77339edaab6b7c5541a (patch) | |
tree | c542bff5e0b356c8db9e47f979e94d5656bc1ff8 /sys/netinet6 | |
parent | 2b6bba564dfa2cabcc572f444847374f35e15658 (diff) |
Read IPv6 forwarding value only once while processing a packet.
IPv4 uses IP_FORWARDING to pass down a consistent value of
net.inet.ip.forwarding down the stack. This is needed for unlocking
sysctl. Do the same for IPv6.
Read ip6_forwarding once in ip6_input_if() and pass down IPV6_FORWARDING
as flags to ip6_ours(), ip6_hbhchcheck(), ip6_forward(). Replace
the srcrt value with IPV6_REDIRECT flag for consistency with IPv4.
To have common syntax with IPv4, use ip6_forwarding == 0 checks
instead of !ip6_forwarding. This will also make it easier to
implement net.inet6.ip6.forwarding=2 for IPsec only forwarding
later.
In nd6_ns_input() and nd6_na_input() read ip6_forwarding once and
store it in i_am_router. The variable name has been chosen to avoid
confusion with is_router, which indicates router flag of the packet.
Reading of ip6_forwarding is done independently from ip6_input_if(),
consistency does not really matter. One is for ND router behavior
the other for forwarding. Again use the ip6_forwarding != 0 check,
so when ip6_forwarding IPsec only value 2 gets implemented, it will
behave like a router.
OK deraadt@ sashan@ florian@ claudio@
Diffstat (limited to 'sys/netinet6')
-rw-r--r-- | sys/netinet6/icmp6.c | 8 | ||||
-rw-r--r-- | sys/netinet6/ip6_forward.c | 10 | ||||
-rw-r--r-- | sys/netinet6/ip6_input.c | 45 | ||||
-rw-r--r-- | sys/netinet6/ip6_var.h | 11 | ||||
-rw-r--r-- | sys/netinet6/nd6.c | 4 | ||||
-rw-r--r-- | sys/netinet6/nd6_nbr.c | 15 |
6 files changed, 51 insertions, 42 deletions
diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c index 058800bc5cf..2a8950d0a66 100644 --- a/sys/netinet6/icmp6.c +++ b/sys/netinet6/icmp6.c @@ -1,4 +1,4 @@ -/* $OpenBSD: icmp6.c,v 1.252 2024/04/21 17:32:10 florian Exp $ */ +/* $OpenBSD: icmp6.c,v 1.253 2024/06/20 19:25:42 bluhm Exp $ */ /* $KAME: icmp6.c,v 1.217 2001/06/20 15:03:29 jinmei Exp $ */ /* @@ -1240,8 +1240,8 @@ icmp6_redirect_input(struct mbuf *m, int off) if (ifp == NULL) return; - /* XXX if we are router, we don't update route by icmp6 redirect */ - if (ip6_forwarding) + /* if we are router, we don't update route by icmp6 redirect */ + if (ip6_forwarding != 0) goto freeit; if (!(ifp->if_xflags & IFXF_AUTOCONF6)) goto freeit; @@ -1442,7 +1442,7 @@ icmp6_redirect_output(struct mbuf *m0, struct rtentry *rt) icmp6_errcount(ND_REDIRECT, 0); /* if we are not router, we don't send icmp6 redirect */ - if (!ip6_forwarding) + if (ip6_forwarding == 0) goto fail; /* sanity check */ diff --git a/sys/netinet6/ip6_forward.c b/sys/netinet6/ip6_forward.c index 13e60375492..9daf51f92b6 100644 --- a/sys/netinet6/ip6_forward.c +++ b/sys/netinet6/ip6_forward.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip6_forward.c,v 1.118 2024/06/07 18:24:16 bluhm Exp $ */ +/* $OpenBSD: ip6_forward.c,v 1.119 2024/06/20 19:25:42 bluhm Exp $ */ /* $KAME: ip6_forward.c,v 1.75 2001/06/29 12:42:13 jinmei Exp $ */ /* @@ -82,7 +82,7 @@ */ void -ip6_forward(struct mbuf *m, struct route *ro, int srcrt) +ip6_forward(struct mbuf *m, struct route *ro, int flags) { struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); struct route iproute; @@ -248,8 +248,8 @@ reroute: m_freem(m); goto freecopy; } - if (rt->rt_ifidx == m->m_pkthdr.ph_ifidx && !srcrt && - ip6_sendredirects && + if (rt->rt_ifidx == m->m_pkthdr.ph_ifidx && + ip6_sendredirects && !ISSET(flags, IPV6_REDIRECT) && (rt->rt_flags & (RTF_DYNAMIC|RTF_MODIFIED)) == 0) { if ((ifp->if_flags & IFF_POINTOPOINT) && nd6_is_addr_neighbor(&ro->ro_dstsin6, ifp)) { @@ -305,7 +305,7 @@ reroute: } else if (m->m_pkthdr.pf.flags & PF_TAG_REROUTE) { /* tag as generated to skip over pf_test on rerun */ m->m_pkthdr.pf.flags |= PF_TAG_GENERATED; - srcrt = 1; + SET(flags, IPV6_REDIRECT); if (ro == &iproute) rtfree(ro->ro_rt); ro = NULL; diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c index 276a35d6816..de9468ecc3f 100644 --- a/sys/netinet6/ip6_input.c +++ b/sys/netinet6/ip6_input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip6_input.c,v 1.262 2024/05/08 13:01:30 bluhm Exp $ */ +/* $OpenBSD: ip6_input.c,v 1.263 2024/06/20 19:25:42 bluhm Exp $ */ /* $KAME: ip6_input.c,v 1.188 2001/03/29 05:34:31 itojun Exp $ */ /* @@ -119,9 +119,9 @@ struct cpumem *ip6counters; uint8_t ip6_soiikey[IP6_SOIIKEY_LEN]; -int ip6_ours(struct mbuf **, int *, int, int); +int ip6_ours(struct mbuf **, int *, int, int, int); int ip6_check_rh0hdr(struct mbuf *, int *); -int ip6_hbhchcheck(struct mbuf **, int *, int *); +int ip6_hbhchcheck(struct mbuf **, int *, int *, int); int ip6_hopopts_input(struct mbuf **, int *, u_int32_t *, u_int32_t *); struct mbuf *ip6_pullexthdr(struct mbuf *, size_t, int); int ip6_sysctl_soiikey(void *, size_t *, void *, size_t); @@ -172,11 +172,11 @@ ip6_init(void) * NET_LOCK_SHARED() and the transport layer needing it exclusively. */ int -ip6_ours(struct mbuf **mp, int *offp, int nxt, int af) +ip6_ours(struct mbuf **mp, int *offp, int nxt, int af, int flags) { /* ip6_hbhchcheck() may be run before, then off and nxt are set */ if (*offp == 0) { - nxt = ip6_hbhchcheck(mp, offp, NULL); + nxt = ip6_hbhchcheck(mp, offp, NULL, flags); if (nxt == IPPROTO_DONE) return IPPROTO_DONE; } @@ -365,7 +365,7 @@ ip6_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp) #if NPF > 0 struct in6_addr odst; #endif - int pfrdr = 0; + int flags = 0; KASSERT(*offp == 0); @@ -412,9 +412,13 @@ ip6_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp) goto bad; ip6 = mtod(m, struct ip6_hdr *); - pfrdr = !IN6_ARE_ADDR_EQUAL(&odst, &ip6->ip6_dst); + if (!IN6_ARE_ADDR_EQUAL(&odst, &ip6->ip6_dst)) + SET(flags, IPV6_REDIRECT); #endif + if (ip6_forwarding != 0) + SET(flags, IPV6_FORWARDING); + /* * Without embedded scope ID we cannot find link-local * addresses in the routing table. @@ -445,7 +449,7 @@ ip6_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp) #if NPF > 0 if (pf_ouraddr(m) == 1) { - nxt = ip6_ours(mp, offp, nxt, af); + nxt = ip6_ours(mp, offp, nxt, af, flags); goto out; } #endif @@ -472,7 +476,7 @@ ip6_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp) if (ip6_mforwarding && ip6_mrouter[ifp->if_rdomain]) { int error; - nxt = ip6_hbhchcheck(&m, offp, &ours); + nxt = ip6_hbhchcheck(&m, offp, &ours, flags); if (nxt == IPPROTO_DONE) goto out; @@ -496,7 +500,8 @@ ip6_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp) if (ours) { if (af == AF_UNSPEC) - nxt = ip6_ours(mp, offp, nxt, af); + nxt = ip6_ours(mp, offp, nxt, af, + flags); goto out; } goto bad; @@ -508,7 +513,7 @@ ip6_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp) ip6stat_inc(ip6s_cantforward); goto bad; } - nxt = ip6_ours(mp, offp, nxt, af); + nxt = ip6_ours(mp, offp, nxt, af, flags); goto out; } @@ -526,7 +531,8 @@ ip6_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp) if (rt != NULL && ISSET(rt->rt_flags, RTF_LOCAL)) { struct in6_ifaddr *ia6 = ifatoia6(rt->rt_ifa); - if (ip6_forwarding == 0 && rt->rt_ifidx != ifp->if_index && + if (!ISSET(flags, IPV6_FORWARDING) && + rt->rt_ifidx != ifp->if_index && !((ifp->if_flags & IFF_LOOPBACK) || (ifp->if_type == IFT_ENC) || (m->m_pkthdr.pf.flags & PF_TAG_TRANSLATE_LOCALHOST))) { @@ -567,7 +573,7 @@ ip6_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp) goto bad; } else { - nxt = ip6_ours(mp, offp, nxt, af); + nxt = ip6_ours(mp, offp, nxt, af, flags); goto out; } } @@ -582,18 +588,18 @@ ip6_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp) * Now there is no reason to process the packet if it's not our own * and we're not a router. */ - if (!ip6_forwarding) { + if (!ISSET(flags, IPV6_FORWARDING)) { ip6stat_inc(ip6s_cantforward); goto bad; } - nxt = ip6_hbhchcheck(&m, offp, &ours); + nxt = ip6_hbhchcheck(&m, offp, &ours, flags); if (nxt == IPPROTO_DONE) goto out; if (ours) { if (af == AF_UNSPEC) - nxt = ip6_ours(mp, offp, nxt, af); + nxt = ip6_ours(mp, offp, nxt, af, flags); goto out; } @@ -613,7 +619,7 @@ ip6_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp) } #endif /* IPSEC */ - ip6_forward(m, &ro, pfrdr); + ip6_forward(m, &ro, flags); *mp = NULL; rtfree(ro.ro_rt); return IPPROTO_DONE; @@ -627,7 +633,7 @@ ip6_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp) /* On error free mbuf and return IPPROTO_DONE. */ int -ip6_hbhchcheck(struct mbuf **mp, int *offp, int *oursp) +ip6_hbhchcheck(struct mbuf **mp, int *offp, int *oursp, int flags) { struct ip6_hdr *ip6; u_int32_t plen, rtalert = ~0; @@ -680,7 +686,8 @@ ip6_hbhchcheck(struct mbuf **mp, int *offp, int *oursp) * accept the packet if a router alert option is included * and we act as an IPv6 router. */ - if (rtalert != ~0 && ip6_forwarding && oursp != NULL) + if (rtalert != ~0 && ISSET(flags, IPV6_FORWARDING) && + oursp != NULL) *oursp = 1; } else nxt = ip6->ip6_nxt; diff --git a/sys/netinet6/ip6_var.h b/sys/netinet6/ip6_var.h index 5987653010d..47fca707dda 100644 --- a/sys/netinet6/ip6_var.h +++ b/sys/netinet6/ip6_var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ip6_var.h,v 1.117 2024/05/13 01:15:53 jsg Exp $ */ +/* $OpenBSD: ip6_var.h,v 1.118 2024/06/20 19:25:42 bluhm Exp $ */ /* $KAME: ip6_var.h,v 1.33 2000/06/11 14:59:20 jinmei Exp $ */ /* @@ -265,10 +265,11 @@ ip6stat_add(enum ip6stat_counters c, uint64_t v) counters_add(ip6counters, c, v); } -/* flags passed to ip6_output as last parameter */ -#define IPV6_UNSPECSRC 0x01 /* allow :: as the source address */ -#define IPV6_FORWARDING 0x02 /* most of IPv6 header exists */ -#define IPV6_MINMTU 0x04 /* use minimum MTU (IPV6_USE_MIN_MTU) */ +/* flags passed to ip6_output or ip6_forward as last parameter */ +#define IPV6_UNSPECSRC 0x01 /* allow :: as the source address */ +#define IPV6_FORWARDING 0x02 /* most of IPv6 header exists */ +#define IPV6_MINMTU 0x04 /* use minimum MTU (IPV6_USE_MIN_MTU) */ +#define IPV6_REDIRECT 0x08 /* redirected by pf */ extern int ip6_mtudisc_timeout; /* mtu discovery */ extern struct rttimer_queue icmp6_mtudisc_timeout_q; diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c index 8ddde1536a4..28bc1b91d50 100644 --- a/sys/netinet6/nd6.c +++ b/sys/netinet6/nd6.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nd6.c,v 1.280 2023/05/13 16:27:59 bluhm Exp $ */ +/* $OpenBSD: nd6.c,v 1.281 2024/06/20 19:25:42 bluhm Exp $ */ /* $KAME: nd6.c,v 1.280 2002/06/08 19:52:07 itojun Exp $ */ /* @@ -671,7 +671,7 @@ nd6_free(struct rtentry *rt) ifp = if_get(rt->rt_ifidx); - if (!ip6_forwarding) { + if (ip6_forwarding == 0) { if (ln->ln_router) { /* * rt6_flush must be called whether or not the neighbor diff --git a/sys/netinet6/nd6_nbr.c b/sys/netinet6/nd6_nbr.c index e2fccc45c31..b6747312d5b 100644 --- a/sys/netinet6/nd6_nbr.c +++ b/sys/netinet6/nd6_nbr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nd6_nbr.c,v 1.151 2023/07/30 12:52:03 krw Exp $ */ +/* $OpenBSD: nd6_nbr.c,v 1.152 2024/06/20 19:25:42 bluhm Exp $ */ /* $KAME: nd6_nbr.c,v 1.61 2001/02/10 16:06:14 jinmei Exp $ */ /* @@ -108,7 +108,7 @@ nd6_ns_input(struct mbuf *m, int off, int icmp6len) struct ifaddr *ifa = NULL; int lladdrlen = 0; int anycast = 0, proxy = 0, tentative = 0; - int router = ip6_forwarding; + int i_am_router = (ip6_forwarding != 0); int tlladdr; struct nd_opts ndopts; struct sockaddr_dl *proxydl = NULL; @@ -244,7 +244,7 @@ nd6_ns_input(struct mbuf *m, int off, int icmp6len) if (ifa) { proxy = 1; proxydl = satosdl(rt->rt_gateway); - router = 0; /* XXX */ + i_am_router = 0; /* XXX */ } } if (rt) @@ -317,7 +317,7 @@ nd6_ns_input(struct mbuf *m, int off, int icmp6len) saddr6.s6_addr16[1] = htons(ifp->if_index); nd6_na_output(ifp, &saddr6, &taddr6, ((anycast || proxy || !tlladdr) ? 0 : ND_NA_FLAG_OVERRIDE) | - (router ? ND_NA_FLAG_ROUTER : 0), + (i_am_router ? ND_NA_FLAG_ROUTER : 0), tlladdr, sdltosa(proxydl)); goto freeit; } @@ -327,7 +327,7 @@ nd6_ns_input(struct mbuf *m, int off, int icmp6len) nd6_na_output(ifp, &saddr6, &taddr6, ((anycast || proxy || !tlladdr) ? 0 : ND_NA_FLAG_OVERRIDE) | - (router ? ND_NA_FLAG_ROUTER : 0) | ND_NA_FLAG_SOLICITED, + (i_am_router ? ND_NA_FLAG_ROUTER : 0) | ND_NA_FLAG_SOLICITED, tlladdr, sdltosa(proxydl)); freeit: m_freem(m); @@ -559,6 +559,7 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len) int is_override; char *lladdr = NULL; int lladdrlen = 0; + int i_am_router = (ip6_forwarding != 0); struct ifaddr *ifa; struct in6_ifaddr *ifa6; struct llinfo_nd6 *ln; @@ -684,7 +685,7 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len) * If we are a router, we may create new stale cache entries upon * receiving Unsolicited Neighbor Advertisements. */ - if (rt == NULL && ip6_forwarding == 1) { + if (rt == NULL && i_am_router) { rt = nd6_lookup(&taddr6, 1, ifp, ifp->if_rdomain); if (rt == NULL || lladdr == NULL || ((sdl = satosdl(rt->rt_gateway)) == NULL)) @@ -837,7 +838,7 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len) } if (ln->ln_router && !is_router) { - if (!ip6_forwarding) { + if (!i_am_router) { /* * The neighbor may be used * as a next hop for some destinations |