summaryrefslogtreecommitdiff
path: root/sys/net
diff options
context:
space:
mode:
authorAlexander Bluhm <bluhm@cvs.openbsd.org>2024-03-31 15:53:13 +0000
committerAlexander Bluhm <bluhm@cvs.openbsd.org>2024-03-31 15:53:13 +0000
commit8ce5a2ffafee07d085e8a59f02b1ddb1ab50aece (patch)
tree0cf561f16fca534e589af0a228d095e043ac7e74 /sys/net
parent36216e9a9641b39c6716095e1f00c9f523b6c959 (diff)
Combine route_cache() and rtalloc_mpath() in new route_mpath().
Fill and check the cache and call rtalloc_mpath() together. Then the caller of route_mpath() does not have to care about the uint32_t *src pointer and just pass struct in_addr. All the conversions are done inside the functions. A previous version of this diff was backed out. There was an additional rtisvalid() in rtalloc_mpath() that prevented packet output via interfaces that were not up. Now the route in the cache has to be valid, but after new lookup, rtalloc_mpath() may return invalid routes. This generates less errors in userland an preserves existing behavior. OK sashan@
Diffstat (limited to 'sys/net')
-rw-r--r--sys/net/route.c34
-rw-r--r--sys/net/route.h6
2 files changed, 38 insertions, 2 deletions
diff --git a/sys/net/route.c b/sys/net/route.c
index 9dadb5aa5eb..028199bd4c0 100644
--- a/sys/net/route.c
+++ b/sys/net/route.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: route.c,v 1.435 2024/02/29 12:01:59 naddy Exp $ */
+/* $OpenBSD: route.c,v 1.436 2024/03/31 15:53:12 bluhm Exp $ */
/* $NetBSD: route.c,v 1.14 1996/02/13 22:00:46 christos Exp $ */
/*
@@ -239,6 +239,24 @@ route_cache(struct route *ro, const struct in_addr *dst,
return (ESRCH);
}
+/*
+ * Check cache for route, else allocate a new one, potentially using multipath
+ * to select the peer. Update cache and return valid route or NULL.
+ */
+struct rtentry *
+route_mpath(struct route *ro, const struct in_addr *dst,
+ const struct in_addr *src, u_int rtableid)
+{
+ if (route_cache(ro, dst, src, rtableid)) {
+ uint32_t *s = NULL;
+
+ if (ro->ro_srcin.s_addr != INADDR_ANY)
+ s = &ro->ro_srcin.s_addr;
+ ro->ro_rt = rtalloc_mpath(&ro->ro_dstsa, s, ro->ro_tableid);
+ }
+ return (ro->ro_rt);
+}
+
#ifdef INET6
int
route6_cache(struct route *ro, const struct in6_addr *dst,
@@ -277,6 +295,20 @@ route6_cache(struct route *ro, const struct in6_addr *dst,
return (ESRCH);
}
+
+struct rtentry *
+route6_mpath(struct route *ro, const struct in6_addr *dst,
+ const struct in6_addr *src, u_int rtableid)
+{
+ if (route6_cache(ro, dst, src, rtableid)) {
+ uint32_t *s = NULL;
+
+ if (!IN6_IS_ADDR_UNSPECIFIED(&ro->ro_srcin6))
+ s = &ro->ro_srcin6.s6_addr32[0];
+ ro->ro_rt = rtalloc_mpath(&ro->ro_dstsa, s, ro->ro_tableid);
+ }
+ return (ro->ro_rt);
+}
#endif
/*
diff --git a/sys/net/route.h b/sys/net/route.h
index c05a70d0636..a301193e79a 100644
--- a/sys/net/route.h
+++ b/sys/net/route.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: route.h,v 1.209 2024/02/29 12:01:59 naddy Exp $ */
+/* $OpenBSD: route.h,v 1.210 2024/03/31 15:53:12 bluhm Exp $ */
/* $NetBSD: route.h,v 1.9 1996/02/13 22:00:49 christos Exp $ */
/*
@@ -465,8 +465,12 @@ struct bfd_config;
void route_init(void);
int route_cache(struct route *, const struct in_addr *,
const struct in_addr *, u_int);
+struct rtentry *route_mpath(struct route *, const struct in_addr *,
+ const struct in_addr *, u_int);
int route6_cache(struct route *, const struct in6_addr *,
const struct in6_addr *, u_int);
+struct rtentry *route6_mpath(struct route *, const struct in6_addr *,
+ const struct in6_addr *, u_int);
void rtm_ifchg(struct ifnet *);
void rtm_ifannounce(struct ifnet *, int);
void rtm_bfd(struct bfd_config *);