Index: sys/arch/amd64/conf/GENERIC.MP =================================================================== RCS file: /mount/openbsd/cvs/src/sys/arch/amd64/conf/GENERIC.MP,v diff -u -p -u -p -r1.16 GENERIC.MP --- sys/arch/amd64/conf/GENERIC.MP 9 Feb 2021 14:06:19 -0000 1.16 +++ sys/arch/amd64/conf/GENERIC.MP 15 Feb 2024 00:17:33 -0000 @@ -4,6 +4,6 @@ include "arch/amd64/conf/GENERIC" option MULTIPROCESSOR #option MP_LOCKDEBUG -#option WITNESS +option WITNESS cpu* at mainbus? Index: sys/arch/arm64/conf/GENERIC.MP =================================================================== RCS file: /mount/openbsd/cvs/src/sys/arch/arm64/conf/GENERIC.MP,v diff -u -p -u -p -r1.5 GENERIC.MP --- sys/arch/arm64/conf/GENERIC.MP 1 Jul 2018 21:05:07 -0000 1.5 +++ sys/arch/arm64/conf/GENERIC.MP 15 Feb 2024 00:17:33 -0000 @@ -4,6 +4,6 @@ include "arch/arm64/conf/GENERIC" option MULTIPROCESSOR #option MP_LOCKDEBUG -#option WITNESS +option WITNESS cpu* at mainbus? Index: sys/arch/i386/conf/GENERIC.MP =================================================================== RCS file: /mount/openbsd/cvs/src/sys/arch/i386/conf/GENERIC.MP,v diff -u -p -u -p -r1.11 GENERIC.MP --- sys/arch/i386/conf/GENERIC.MP 3 Jun 2018 05:18:33 -0000 1.11 +++ sys/arch/i386/conf/GENERIC.MP 15 Feb 2024 00:17:33 -0000 @@ -7,6 +7,6 @@ include "arch/i386/conf/GENERIC" option MULTIPROCESSOR # Multiple processor support #option MP_LOCKDEBUG -#option WITNESS +option WITNESS cpu* at mainbus? Index: sys/arch/macppc/conf/GENERIC.MP =================================================================== RCS file: /mount/openbsd/cvs/src/sys/arch/macppc/conf/GENERIC.MP,v diff -u -p -u -p -r1.2 GENERIC.MP --- sys/arch/macppc/conf/GENERIC.MP 15 Apr 2020 08:09:33 -0000 1.2 +++ sys/arch/macppc/conf/GENERIC.MP 15 Feb 2024 00:17:33 -0000 @@ -4,6 +4,6 @@ include "arch/macppc/conf/GENERIC" option MULTIPROCESSOR #option MP_LOCKDEBUG -#option WITNESS +option WITNESS cpu* at mainbus? Index: sys/arch/powerpc64/conf/GENERIC.MP =================================================================== RCS file: /mount/openbsd/cvs/src/sys/arch/powerpc64/conf/GENERIC.MP,v diff -u -p -u -p -r1.1 GENERIC.MP --- sys/arch/powerpc64/conf/GENERIC.MP 21 Jul 2020 21:38:31 -0000 1.1 +++ sys/arch/powerpc64/conf/GENERIC.MP 15 Feb 2024 00:17:33 -0000 @@ -4,6 +4,6 @@ include "arch/powerpc64/conf/GENERIC" option MULTIPROCESSOR #option MP_LOCKDEBUG -#option WITNESS +option WITNESS cpu* at mainbus? Index: sys/arch/riscv64/conf/GENERIC.MP =================================================================== RCS file: /mount/openbsd/cvs/src/sys/arch/riscv64/conf/GENERIC.MP,v diff -u -p -u -p -r1.1 GENERIC.MP --- sys/arch/riscv64/conf/GENERIC.MP 29 Jun 2021 21:27:52 -0000 1.1 +++ sys/arch/riscv64/conf/GENERIC.MP 15 Feb 2024 00:17:33 -0000 @@ -4,6 +4,6 @@ include "arch/riscv64/conf/GENERIC" option MULTIPROCESSOR #option MP_LOCKDEBUG -#option WITNESS +option WITNESS cpu* at mainbus? Index: sys/net/route.c =================================================================== RCS file: /mount/openbsd/cvs/src/sys/net/route.c,v diff -u -p -u -p -r1.432 route.c --- sys/net/route.c 13 Feb 2024 12:22:09 -0000 1.432 +++ sys/net/route.c 15 Feb 2024 00:17:25 -0000 @@ -202,7 +202,8 @@ route_init(void) } int -route_cache(struct route *ro, struct in_addr addr, u_int rtableid) +route_cache(struct route *ro, struct in_addr dst, const struct in_addr *src, + u_int rtableid) { u_long gen; @@ -213,28 +214,37 @@ route_cache(struct route *ro, struct in_ ro->ro_generation == gen && ro->ro_tableid == rtableid && ro->ro_dstsa.sa_family == AF_INET && - ro->ro_dstsin.sin_addr.s_addr == addr.s_addr) { - ipstat_inc(ips_rtcachehit); - return (0); + ro->ro_dstsin.sin_addr.s_addr == dst.s_addr) { + if (src == NULL || + !ISSET(ro->ro_rt->rt_flags, RTF_MPATH) || + (ISSET(ro->ro_flags, RTF_MPATH) && + ro->ro_srcin.s_addr == src->s_addr)) { + ipstat_inc(ips_rtcachehit); + return (0); + } } ipstat_inc(ips_rtcachemiss); rtfree(ro->ro_rt); - ro->ro_rt = NULL; + memset(ro, 0, sizeof(*ro)); ro->ro_generation = gen; ro->ro_tableid = rtableid; - memset(&ro->ro_dst, 0, sizeof(ro->ro_dst)); ro->ro_dstsin.sin_family = AF_INET; ro->ro_dstsin.sin_len = sizeof(struct sockaddr_in); - ro->ro_dstsin.sin_addr = addr; + ro->ro_dstsin.sin_addr = dst; + if (src != NULL) { + ro->ro_srcin = *src; + SET(ro->ro_flags, RTF_MPATH); + } return (ESRCH); } #ifdef INET6 int -route6_cache(struct route *ro, const struct in6_addr *addr, u_int rtableid) +route6_cache(struct route *ro, const struct in6_addr *dst, + const struct in6_addr *src, u_int rtableid) { u_long gen; @@ -245,21 +255,29 @@ route6_cache(struct route *ro, const str ro->ro_generation == gen && ro->ro_tableid == rtableid && ro->ro_dstsa.sa_family == AF_INET6 && - IN6_ARE_ADDR_EQUAL(&ro->ro_dstsin6.sin6_addr, addr)) { - ip6stat_inc(ip6s_rtcachehit); - return (0); + IN6_ARE_ADDR_EQUAL(&ro->ro_dstsin6.sin6_addr, dst)) { + if (src == NULL || + !ISSET(ro->ro_rt->rt_flags, RTF_MPATH) || + (ISSET(ro->ro_flags, RTF_MPATH) && + IN6_ARE_ADDR_EQUAL(&ro->ro_srcin6, src))) { + ip6stat_inc(ip6s_rtcachehit); + return (0); + } } ip6stat_inc(ip6s_rtcachemiss); rtfree(ro->ro_rt); - ro->ro_rt = NULL; + memset(ro, 0, sizeof(*ro)); ro->ro_generation = gen; ro->ro_tableid = rtableid; - memset(&ro->ro_dst, 0, sizeof(ro->ro_dst)); ro->ro_dstsin6.sin6_family = AF_INET6; ro->ro_dstsin6.sin6_len = sizeof(struct sockaddr_in6); - ro->ro_dstsin6.sin6_addr = *addr; + ro->ro_dstsin6.sin6_addr = *dst; + if (src != NULL) { + ro->ro_srcin6 = *src; + SET(ro->ro_flags, RTF_MPATH); + } return (ESRCH); } Index: sys/net/route.h =================================================================== RCS file: /mount/openbsd/cvs/src/sys/net/route.h,v diff -u -p -u -p -r1.206 route.h --- sys/net/route.h 13 Feb 2024 12:22:09 -0000 1.206 +++ sys/net/route.h 15 Feb 2024 00:17:25 -0000 @@ -400,6 +400,13 @@ struct route { #define ro_dstsa ro_dst.rod_sa #define ro_dstsin ro_dst.rod_sin #define ro_dstsin6 ro_dst.rod_sin6 + union { + struct in_addr ros_in; + struct in6_addr ros_in6; + } ro_src; +#define ro_srcin ro_src.ros_in +#define ro_srcin6 ro_src.ros_in6 + u_int ro_flags; }; #endif /* __BSD_VISIBLE */ @@ -462,8 +469,10 @@ struct if_ieee80211_data; struct bfd_config; void route_init(void); -int route_cache(struct route *, struct in_addr, u_int); -int route6_cache(struct route *, const struct in6_addr *, u_int); +int route_cache(struct route *, struct in_addr, const struct in_addr *, + u_int); +int route6_cache(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 *); Index: sys/netinet/in_pcb.c =================================================================== RCS file: /mount/openbsd/cvs/src/sys/netinet/in_pcb.c,v diff -u -p -u -p -r1.293 in_pcb.c --- sys/netinet/in_pcb.c 13 Feb 2024 12:22:09 -0000 1.293 +++ sys/netinet/in_pcb.c 15 Feb 2024 00:17:25 -0000 @@ -919,7 +919,8 @@ in_pcbrtentry(struct inpcb *inp) if (inp->inp_faddr.s_addr == INADDR_ANY) return (NULL); - if (route_cache(ro, inp->inp_faddr, inp->inp_rtableid)) { + if (route_cache(ro, inp->inp_faddr, &inp->inp_laddr, + inp->inp_rtableid)) { ro->ro_rt = rtalloc_mpath(&ro->ro_dstsa, &inp->inp_laddr.s_addr, ro->ro_tableid); } @@ -982,7 +983,7 @@ in_pcbselsrc(struct in_addr *insrc, stru * If route is known or can be allocated now, * our src addr is taken from the i/f, else punt. */ - if (route_cache(ro, sin->sin_addr, rtableid)) { + if (route_cache(ro, sin->sin_addr, NULL, rtableid)) { /* No route yet, so try to acquire one */ ro->ro_rt = rtalloc_mpath(&ro->ro_dstsa, NULL, ro->ro_tableid); } Index: sys/netinet/ip_input.c =================================================================== RCS file: /mount/openbsd/cvs/src/sys/netinet/ip_input.c,v diff -u -p -u -p -r1.389 ip_input.c --- sys/netinet/ip_input.c 13 Feb 2024 12:22:09 -0000 1.389 +++ sys/netinet/ip_input.c 15 Feb 2024 00:17:25 -0000 @@ -1491,7 +1491,7 @@ ip_forward(struct mbuf *m, struct ifnet } ro.ro_rt = NULL; - route_cache(&ro, ip->ip_dst, m->m_pkthdr.ph_rtableid); + route_cache(&ro, ip->ip_dst, &ip->ip_src, m->m_pkthdr.ph_rtableid); if (!rtisvalid(rt)) { rtfree(rt); rt = rtalloc_mpath(&ro.ro_dstsa, &ip->ip_src.s_addr, Index: sys/netinet/ip_output.c =================================================================== RCS file: /mount/openbsd/cvs/src/sys/netinet/ip_output.c,v diff -u -p -u -p -r1.395 ip_output.c --- sys/netinet/ip_output.c 13 Feb 2024 12:22:09 -0000 1.395 +++ sys/netinet/ip_output.c 15 Feb 2024 00:17:25 -0000 @@ -166,7 +166,7 @@ reroute: * If there is a cached route, check that it is to the same * destination and is still up. If not, free it and try again. */ - route_cache(ro, ip->ip_dst, m->m_pkthdr.ph_rtableid); + route_cache(ro, ip->ip_dst, &ip->ip_src, m->m_pkthdr.ph_rtableid); dst = &ro->ro_dstsin; if ((IN_MULTICAST(ip->ip_dst.s_addr) || Index: sys/netinet6/in6_pcb.c =================================================================== RCS file: /mount/openbsd/cvs/src/sys/netinet6/in6_pcb.c,v diff -u -p -u -p -r1.138 in6_pcb.c --- sys/netinet6/in6_pcb.c 13 Feb 2024 12:22:09 -0000 1.138 +++ sys/netinet6/in6_pcb.c 15 Feb 2024 00:17:25 -0000 @@ -565,7 +565,8 @@ in6_pcbrtentry(struct inpcb *inp) if (IN6_IS_ADDR_UNSPECIFIED(&inp->inp_faddr6)) return (NULL); - if (route6_cache(ro, &inp->inp_faddr6, inp->inp_rtableid)) { + if (route6_cache(ro, &inp->inp_faddr6, &inp->inp_laddr6, + inp->inp_rtableid)) { ro->ro_rt = rtalloc_mpath(&ro->ro_dstsa, &inp->inp_laddr6.s6_addr32[0], ro->ro_tableid); } Index: sys/netinet6/in6_src.c =================================================================== RCS file: /mount/openbsd/cvs/src/sys/netinet6/in6_src.c,v diff -u -p -u -p -r1.94 in6_src.c --- sys/netinet6/in6_src.c 13 Feb 2024 12:22:09 -0000 1.94 +++ sys/netinet6/in6_src.c 15 Feb 2024 00:17:25 -0000 @@ -179,8 +179,8 @@ in6_pcbselsrc(const struct in6_addr **in * If route is known or can be allocated now, * our src addr is taken from the i/f, else punt. */ - if (route6_cache(ro, dst, rtableid)) { - ro->ro_rt = rtalloc(&ro->ro_dstsa, RT_RESOLVE, ro->ro_tableid); + if (route6_cache(ro, dst, NULL, rtableid)) { + ro->ro_rt = rtalloc_mpath(&ro->ro_dstsa, NULL, ro->ro_tableid); } /* @@ -304,7 +304,7 @@ in6_selectroute(const struct in6_addr *d * a new one. */ if (ro) { - if (route6_cache(ro, dst, rtableid)) { + if (route6_cache(ro, dst, NULL, rtableid)) { /* No route yet, so try to acquire one */ ro->ro_rt = rtalloc_mpath(&ro->ro_dstsa, NULL, ro->ro_tableid); Index: sys/netinet6/ip6_forward.c =================================================================== RCS file: /mount/openbsd/cvs/src/sys/netinet6/ip6_forward.c,v diff -u -p -u -p -r1.114 ip6_forward.c --- sys/netinet6/ip6_forward.c 13 Feb 2024 12:22:09 -0000 1.114 +++ sys/netinet6/ip6_forward.c 15 Feb 2024 00:17:25 -0000 @@ -166,7 +166,8 @@ reroute: #endif /* IPSEC */ ro.ro_rt = NULL; - route6_cache(&ro, &ip6->ip6_dst, m->m_pkthdr.ph_rtableid); + route6_cache(&ro, &ip6->ip6_dst, &ip6->ip6_src, + m->m_pkthdr.ph_rtableid); dst = &ro.ro_dstsa; if (!rtisvalid(rt)) { rtfree(rt); Index: sys/netinet6/ip6_output.c =================================================================== RCS file: /mount/openbsd/cvs/src/sys/netinet6/ip6_output.c,v diff -u -p -u -p -r1.286 ip6_output.c --- sys/netinet6/ip6_output.c 13 Feb 2024 12:22:09 -0000 1.286 +++ sys/netinet6/ip6_output.c 15 Feb 2024 00:17:25 -0000 @@ -480,7 +480,7 @@ reroute: goto bad; } } else { - route6_cache(ro, &ip6->ip6_dst, m->m_pkthdr.ph_rtableid); + route6_cache(ro, &ip6->ip6_dst, NULL, m->m_pkthdr.ph_rtableid); } if (rt && (rt->rt_flags & RTF_GATEWAY) &&