summaryrefslogtreecommitdiff
path: root/sys/netinet6
diff options
context:
space:
mode:
authorAlexander Bluhm <bluhm@cvs.openbsd.org>2024-04-16 12:56:40 +0000
committerAlexander Bluhm <bluhm@cvs.openbsd.org>2024-04-16 12:56:40 +0000
commitb747340ebe114457e3dd703702b909354bbdb303 (patch)
tree6e78f5a7aab7efebbf4db61ea499ebd22826be06 /sys/netinet6
parent989891d6ea337764b983eb195f21039b0e3ae440 (diff)
Use route cache function in IP input.
Instaed of passing a struct rtentry from ip_input() to ip_forward() and then embed it into a struct route for ip_output(), start with struct route and pass it along. Then the route cache is used consistently. Also the route cache hit and missed counters should reflect reality after this commit. There is a small difference in the code. in_ouraddr() checks for NULL and not rtisvalid(). Previous discussion showed that the route RTF_UP flag should only be considered for multipath routing. Otherwise it does not mean anything. Especially the local and broadcast check in in_ouraddr() should not be affected by interface link status. When doing cache lookups, route must be valid, but after rtalloc_mpath() lookup, use any route that route_mpath() returns. OK claudio@
Diffstat (limited to 'sys/netinet6')
-rw-r--r--sys/netinet6/ip6_forward.c50
-rw-r--r--sys/netinet6/ip6_input.c20
-rw-r--r--sys/netinet6/ip6_output.c4
-rw-r--r--sys/netinet6/ip6_var.h4
4 files changed, 37 insertions, 41 deletions
diff --git a/sys/netinet6/ip6_forward.c b/sys/netinet6/ip6_forward.c
index 84c872a192f..913fb64304c 100644
--- a/sys/netinet6/ip6_forward.c
+++ b/sys/netinet6/ip6_forward.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip6_forward.c,v 1.116 2024/02/28 10:57:20 bluhm Exp $ */
+/* $OpenBSD: ip6_forward.c,v 1.117 2024/04/16 12:56:39 bluhm Exp $ */
/* $KAME: ip6_forward.c,v 1.75 2001/06/29 12:42:13 jinmei Exp $ */
/*
@@ -82,11 +82,12 @@
*/
void
-ip6_forward(struct mbuf *m, struct rtentry *rt, int srcrt)
+ip6_forward(struct mbuf *m, struct route *ro, int srcrt)
{
struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
+ struct route iproute;
+ struct rtentry *rt;
struct sockaddr *dst;
- struct route ro;
struct ifnet *ifp = NULL;
int error = 0, type = 0, code = 0, destmtu = 0;
struct mbuf *mcopy;
@@ -165,25 +166,22 @@ reroute:
}
#endif /* IPSEC */
- ro.ro_rt = NULL;
- route6_cache(&ro, &ip6->ip6_dst, &ip6->ip6_src,
+ if (ro == NULL) {
+ ro = &iproute;
+ ro->ro_rt = NULL;
+ }
+ rt = route6_mpath(ro, &ip6->ip6_dst, &ip6->ip6_src,
m->m_pkthdr.ph_rtableid);
- dst = &ro.ro_dstsa;
- if (!rtisvalid(rt)) {
- rtfree(rt);
- rt = rtalloc_mpath(dst, &ip6->ip6_src.s6_addr32[0],
- m->m_pkthdr.ph_rtableid);
- if (rt == NULL) {
- ip6stat_inc(ip6s_noroute);
- if (mcopy != NULL) {
- icmp6_error(mcopy, ICMP6_DST_UNREACH,
- ICMP6_DST_UNREACH_NOROUTE, 0);
- }
- m_freem(m);
- goto done;
+ if (rt == NULL) {
+ ip6stat_inc(ip6s_noroute);
+ if (mcopy != NULL) {
+ icmp6_error(mcopy, ICMP6_DST_UNREACH,
+ ICMP6_DST_UNREACH_NOROUTE, 0);
}
+ m_freem(m);
+ goto done;
}
- ro.ro_rt = rt;
+ dst = &ro->ro_dstsa;
/*
* Scope check: if a packet can't be delivered to its destination
@@ -225,8 +223,8 @@ reroute:
*/
if (tdb != NULL) {
/* Callee frees mbuf */
- error = ip6_output_ipsec_send(tdb, m, &ro, 0, 1);
- rt = ro.ro_rt;
+ error = ip6_output_ipsec_send(tdb, m, ro, 0, 1);
+ rt = ro->ro_rt;
if (error)
goto senderr;
goto freecopy;
@@ -254,7 +252,7 @@ reroute:
ip6_sendredirects &&
(rt->rt_flags & (RTF_DYNAMIC|RTF_MODIFIED)) == 0) {
if ((ifp->if_flags & IFF_POINTOPOINT) &&
- nd6_is_addr_neighbor(&ro.ro_dstsin6, ifp)) {
+ nd6_is_addr_neighbor(&ro->ro_dstsin6, ifp)) {
/*
* If the incoming interface is equal to the outgoing
* one, the link attached to the interface is
@@ -308,8 +306,9 @@ reroute:
/* tag as generated to skip over pf_test on rerun */
m->m_pkthdr.pf.flags |= PF_TAG_GENERATED;
srcrt = 1;
- rtfree(rt);
- rt = NULL;
+ if (ro == &iproute)
+ rtfree(ro->ro_rt);
+ ro = NULL;
if_put(ifp);
ifp = NULL;
goto reroute;
@@ -388,7 +387,8 @@ senderr:
freecopy:
m_freem(mcopy);
done:
- rtfree(rt);
+ if (ro == &iproute)
+ rtfree(ro->ro_rt);
if_put(ifp);
#ifdef IPSEC
tdb_unref(tdb);
diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c
index 5f4e991e0f8..e389bc0aa35 100644
--- a/sys/netinet6/ip6_input.c
+++ b/sys/netinet6/ip6_input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip6_input.c,v 1.260 2024/04/14 20:46:27 bluhm Exp $ */
+/* $OpenBSD: ip6_input.c,v 1.261 2024/04/16 12:56:39 bluhm Exp $ */
/* $KAME: ip6_input.c,v 1.188 2001/03/29 05:34:31 itojun Exp $ */
/*
@@ -356,10 +356,10 @@ bad:
int
ip6_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp)
{
+ struct route ro;
struct mbuf *m;
struct ip6_hdr *ip6;
- struct sockaddr_in6 sin6;
- struct rtentry *rt = NULL;
+ struct rtentry *rt;
int ours = 0;
u_int16_t src_scope, dst_scope;
#if NPF > 0
@@ -369,8 +369,8 @@ ip6_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp)
KASSERT(*offp == 0);
+ ro.ro_rt = NULL;
ip6stat_inc(ip6s_total);
-
m = *mp = ipv6_check(ifp, *mp);
if (m == NULL)
goto bad;
@@ -516,18 +516,14 @@ ip6_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp)
/*
* Unicast check
*/
- memset(&sin6, 0, sizeof(struct sockaddr_in6));
- sin6.sin6_len = sizeof(struct sockaddr_in6);
- sin6.sin6_family = AF_INET6;
- sin6.sin6_addr = ip6->ip6_dst;
- rt = rtalloc_mpath(sin6tosa(&sin6), &ip6->ip6_src.s6_addr32[0],
+ rt = route6_mpath(&ro, &ip6->ip6_dst, &ip6->ip6_src,
m->m_pkthdr.ph_rtableid);
/*
* Accept the packet if the route to the destination is marked
* as local.
*/
- if (rtisvalid(rt) && ISSET(rt->rt_flags, RTF_LOCAL)) {
+ 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 &&
@@ -617,14 +613,14 @@ ip6_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp)
}
#endif /* IPSEC */
- ip6_forward(m, rt, pfrdr);
+ ip6_forward(m, &ro, pfrdr);
*mp = NULL;
return IPPROTO_DONE;
bad:
nxt = IPPROTO_DONE;
m_freemp(mp);
out:
- rtfree(rt);
+ rtfree(ro.ro_rt);
return nxt;
}
diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c
index a2ba550fa5a..99d494df528 100644
--- a/sys/netinet6/ip6_output.c
+++ b/sys/netinet6/ip6_output.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip6_output.c,v 1.289 2024/04/09 11:05:05 bluhm Exp $ */
+/* $OpenBSD: ip6_output.c,v 1.290 2024/04/16 12:56:39 bluhm Exp $ */
/* $KAME: ip6_output.c,v 1.172 2001/03/25 09:55:56 itojun Exp $ */
/*
@@ -391,7 +391,7 @@ reroute:
/* initialize cached route */
if (ro == NULL) {
ro = &iproute;
- bzero((caddr_t)ro, sizeof(*ro));
+ ro->ro_rt = NULL;
}
ro_pmtu = ro;
if (opt && opt->ip6po_rthdr)
diff --git a/sys/netinet6/ip6_var.h b/sys/netinet6/ip6_var.h
index c1249f7974f..1b9ae82c482 100644
--- a/sys/netinet6/ip6_var.h
+++ b/sys/netinet6/ip6_var.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip6_var.h,v 1.114 2024/02/14 13:18:21 claudio Exp $ */
+/* $OpenBSD: ip6_var.h,v 1.115 2024/04/16 12:56:39 bluhm Exp $ */
/* $KAME: ip6_var.h,v 1.33 2000/06/11 14:59:20 jinmei Exp $ */
/*
@@ -320,7 +320,7 @@ int ip6_process_hopopts(struct mbuf **, u_int8_t *, int, u_int32_t *,
void ip6_savecontrol(struct inpcb *, struct mbuf *, struct mbuf **);
int ip6_sysctl(int *, u_int, void *, size_t *, void *, size_t);
-void ip6_forward(struct mbuf *, struct rtentry *, int);
+void ip6_forward(struct mbuf *, struct route *, int);
void ip6_mloopback(struct ifnet *, struct mbuf *, struct sockaddr_in6 *);
int ip6_output(struct mbuf *, struct ip6_pktopts *, struct route *, int,