summaryrefslogtreecommitdiff
path: root/sys/netinet6
diff options
context:
space:
mode:
authorAlexander Bluhm <bluhm@cvs.openbsd.org>2024-06-20 19:25:43 +0000
committerAlexander Bluhm <bluhm@cvs.openbsd.org>2024-06-20 19:25:43 +0000
commit8fb789f4ab1f9e44048fb77339edaab6b7c5541a (patch)
treec542bff5e0b356c8db9e47f979e94d5656bc1ff8 /sys/netinet6
parent2b6bba564dfa2cabcc572f444847374f35e15658 (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.c8
-rw-r--r--sys/netinet6/ip6_forward.c10
-rw-r--r--sys/netinet6/ip6_input.c45
-rw-r--r--sys/netinet6/ip6_var.h11
-rw-r--r--sys/netinet6/nd6.c4
-rw-r--r--sys/netinet6/nd6_nbr.c15
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