diff options
author | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2024-03-31 15:53:13 +0000 |
---|---|---|
committer | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2024-03-31 15:53:13 +0000 |
commit | 8ce5a2ffafee07d085e8a59f02b1ddb1ab50aece (patch) | |
tree | 0cf561f16fca534e589af0a228d095e043ac7e74 /sys/net | |
parent | 36216e9a9641b39c6716095e1f00c9f523b6c959 (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.c | 34 | ||||
-rw-r--r-- | sys/net/route.h | 6 |
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 *); |