diff --git a/regress/sys/kern/nanosleep/nanosleep.c b/regress/sys/kern/nanosleep/nanosleep.c index 5ccc08262..790707ae0 100644 --- a/regress/sys/kern/nanosleep/nanosleep.c +++ b/regress/sys/kern/nanosleep/nanosleep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nanosleep.c,v 1.7 2018/05/22 18:33:41 cheloha Exp $ */ +/* $OpenBSD: nanosleep.c,v 1.8 2024/02/29 18:17:41 bluhm Exp $ */ /* * Written by Artur Grabowski 2002 Public Domain. */ @@ -137,13 +137,13 @@ int time_elapsed(void) { struct timespec ts; - struct timeval stv, etv; + struct timespec stv, etv; ts.tv_sec = 0; ts.tv_nsec = 500000000; - if (gettimeofday(&stv, NULL) < 0) { - warn("gettimeofday"); + if (clock_gettime(CLOCK_MONOTONIC, &stv) < 0) { + warn("clock_gettime"); return 1; } @@ -152,14 +152,14 @@ time_elapsed(void) return 1; } - if (gettimeofday(&etv, NULL) < 0) { - warn("gettimeofday"); + if (clock_gettime(CLOCK_MONOTONIC, &etv) < 0) { + warn("clock_gettime"); return 1; } - timersub(&etv, &stv, &stv); + timespecsub(&etv, &stv, &stv); - if (stv.tv_sec == 0 && stv.tv_usec < 500000) { + if (stv.tv_sec == 0 && stv.tv_nsec < 500000000) { warnx("slept less than 0.5 sec"); return 1; } @@ -171,7 +171,7 @@ int time_elapsed_with_signal(void) { struct timespec ts, rts; - struct timeval stv, etv; + struct timespec stv, etv; pid_t pid; int status; @@ -195,8 +195,8 @@ time_elapsed_with_signal(void) rts.tv_sec = 0; rts.tv_nsec = 0; - if (gettimeofday(&stv, NULL) < 0) { - warn("gettimeofday"); + if (clock_gettime(CLOCK_MONOTONIC, &stv) < 0) { + warn("clock_gettime"); return 1; } @@ -205,17 +205,17 @@ time_elapsed_with_signal(void) return 1; } - if (gettimeofday(&etv, NULL) < 0) { - warn("gettimeofday"); + if (clock_gettime(CLOCK_MONOTONIC, &etv) < 0) { + warn("clock_gettime"); return 1; } - timersub(&etv, &stv, &stv); + timespecsub(&etv, &stv, &stv); etv.tv_sec = rts.tv_sec; - etv.tv_usec = rts.tv_nsec / 1000 + 1; /* the '+ 1' is a "roundup" */ + etv.tv_nsec = rts.tv_nsec; - timeradd(&etv, &stv, &stv); + timespecadd(&etv, &stv, &stv); if (stv.tv_sec < 10) { warnx("slept time + leftover time < 10 sec"); diff --git a/regress/sys/net/vxlan/vxlan_2.sh b/regress/sys/net/vxlan/vxlan_2.sh index 6b9806061..c7c600f80 100644 --- a/regress/sys/net/vxlan/vxlan_2.sh +++ b/regress/sys/net/vxlan/vxlan_2.sh @@ -1,5 +1,5 @@ #!/bin/ksh -# $Id: vxlan_2.sh,v 1.4 2023/10/19 18:36:41 anton Exp $ +# $Id: vxlan_2.sh,v 1.5 2024/02/29 06:54:29 anton Exp $ CAPFILE=$(mktemp -t regress_vxlan.XXXXXXX) @@ -104,10 +104,12 @@ vstack_add() { . ${CURDIR}/vxlan_subr -VNETID=0 +# Use the first rdomain as the vnetid. +VNETID="$(set -- $RDOMAINS; echo $1)" +RDOMAINS="$(set -- $RDOMAINS; shift 1; echo $@)" + for rdom in $RDOMAINS; do rdomain_is_used $rdom || abort_test "rdomain $rdom already in use" - [[ $rdom -ge $VNETID ]] && VNETID=$(( rdom + 1 )) done rdomain_is_used $VNETID || abort_test "rdomain $rdom already in use" diff --git a/sys/arch/amd64/amd64/vmm_machdep.c b/sys/arch/amd64/amd64/vmm_machdep.c index 943797dde..e3abe2f72 100644 --- a/sys/arch/amd64/amd64/vmm_machdep.c +++ b/sys/arch/amd64/amd64/vmm_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vmm_machdep.c,v 1.19 2024/02/25 22:33:09 guenther Exp $ */ +/* $OpenBSD: vmm_machdep.c,v 1.20 2024/02/29 16:10:52 guenther Exp $ */ /* * Copyright (c) 2014 Mike Larkin * @@ -3958,9 +3958,8 @@ vcpu_run_vmx(struct vcpu *vcpu, struct vm_run_params *vrp) struct schedstate_percpu *spc; struct vmx_invvpid_descriptor vid; uint64_t eii, procbased, int_st; - uint16_t irq, ldt_sel; + uint16_t irq; u_long s; - struct region_descriptor idtr; rw_assert_wrlock(&vcpu->vc_lock); @@ -4180,9 +4179,6 @@ vcpu_run_vmx(struct vcpu *vcpu, struct vm_run_params *vrp) break; } - sidt(&idtr); - sldt(&ldt_sel); - TRACEPOINT(vmm, guest_enter, vcpu, vrp); /* @@ -4210,8 +4206,14 @@ vcpu_run_vmx(struct vcpu *vcpu, struct vm_run_params *vrp) wrpkru(0, PGK_VALUE); } - lidt(&idtr); - lldt(ldt_sel); + /* + * VM exit restores the GDT and IDT bases, but gives + * them high limits. Reload with the correct limits here. + * 'gdt' is set above first time through and reset there + * whenever this thread switches CPU. + */ + bare_lgdt(&gdt); + cpu_init_idt(); /* * On exit, interrupts are disabled, and we are running with diff --git a/sys/conf/newvers.sh b/sys/conf/newvers.sh index 61ce300b3..1c112c112 100644 --- a/sys/conf/newvers.sh +++ b/sys/conf/newvers.sh @@ -1,6 +1,6 @@ #!/bin/sh - # -# $OpenBSD: newvers.sh,v 1.201 2024/02/17 16:13:24 deraadt Exp $ +# $OpenBSD: newvers.sh,v 1.202 2024/02/29 17:05:10 deraadt Exp $ # $NetBSD: newvers.sh,v 1.17.2.1 1995/10/12 05:17:11 jtc Exp $ # # Copyright (c) 1984, 1986, 1990, 1993 @@ -71,9 +71,9 @@ ost="SecBSD" osr="1.5" cat >vers.c < @@ -477,6 +477,7 @@ dt_ioctl_get_stats(struct dt_softc *sc, struct dtioc_stat *dtst) int dt_ioctl_record_start(struct dt_softc *sc) { + uint64_t now; struct dt_pcb *dp; if (sc->ds_recording) @@ -487,6 +488,7 @@ dt_ioctl_record_start(struct dt_softc *sc) return ENOENT; rw_enter_write(&dt_lock); + now = nsecuptime(); TAILQ_FOREACH(dp, &sc->ds_pcbs, dp_snext) { struct dt_probe *dtp = dp->dp_dtp; @@ -497,7 +499,8 @@ dt_ioctl_record_start(struct dt_softc *sc) if (dp->dp_nsecs != 0) { clockintr_bind(&dp->dp_clockintr, dp->dp_cpu, dt_clock, dp); - clockintr_advance(&dp->dp_clockintr, dp->dp_nsecs); + clockintr_schedule(&dp->dp_clockintr, + now + dp->dp_nsecs); } } rw_exit_write(&dt_lock); diff --git a/sys/dev/ic/qwx.c b/sys/dev/ic/qwx.c index 9c4450034..ab426012d 100644 --- a/sys/dev/ic/qwx.c +++ b/sys/dev/ic/qwx.c @@ -1,4 +1,4 @@ -/* $OpenBSD: qwx.c,v 1.52 2024/02/24 15:21:39 cheloha Exp $ */ +/* $OpenBSD: qwx.c,v 1.54 2024/02/29 11:45:47 stsp Exp $ */ /* * Copyright 2023 Stefan Sperling @@ -12793,6 +12793,7 @@ qwx_mgmt_rx_event(struct qwx_softc *sc, struct mbuf *m) } #endif ieee80211_input(ifp, m, ni, &rxi); + ieee80211_release_node(ic, ni); exit: #ifdef notyet rcu_read_unlock(); @@ -21332,7 +21333,7 @@ qwx_ce_rx_post_buf(struct qwx_softc *sc) pipe = &sc->ce.ce_pipe[i]; ret = qwx_ce_rx_post_pipe(pipe); if (ret) { - if (ret == ENOBUFS) + if (ret == ENOSPC) continue; printf("%s: failed to post rx buf to pipe: %d err: %d\n", @@ -21436,7 +21437,7 @@ qwx_ce_recv_process_cb(struct qwx_ce_pipe *pipe) } err = qwx_ce_rx_post_pipe(pipe); - if (err && err != ENOBUFS) { + if (err && err != ENOSPC) { printf("%s: failed to post rx buf to pipe: %d err: %d\n", __func__, pipe->pipe_num, err); #ifdef notyet diff --git a/sys/dev/pci/drm/i915/i915_devlist.h b/sys/dev/pci/drm/i915/i915_devlist.h index 565048901..7987b538a 100644 --- a/sys/dev/pci/drm/i915/i915_devlist.h +++ b/sys/dev/pci/drm/i915/i915_devlist.h @@ -301,6 +301,8 @@ static const struct pci_matchid i915_devices[] = { { 0x8086, 0x46d0 }, { 0x8086, 0x46d1 }, { 0x8086, 0x46d2 }, + { 0x8086, 0x46d3 }, + { 0x8086, 0x46d4 }, { 0x8086, 0xa780 }, { 0x8086, 0xa781 }, { 0x8086, 0xa782 }, diff --git a/sys/dev/pci/drm/include/drm/i915_pciids.h b/sys/dev/pci/drm/include/drm/i915_pciids.h index 21faa73db..9199e2e12 100644 --- a/sys/dev/pci/drm/include/drm/i915_pciids.h +++ b/sys/dev/pci/drm/include/drm/i915_pciids.h @@ -672,7 +672,9 @@ #define INTEL_ADLN_IDS(info) \ INTEL_VGA_DEVICE(0x46D0, info), \ INTEL_VGA_DEVICE(0x46D1, info), \ - INTEL_VGA_DEVICE(0x46D2, info) + INTEL_VGA_DEVICE(0x46D2, info), \ + INTEL_VGA_DEVICE(0x46D3, info), \ + INTEL_VGA_DEVICE(0x46D4, info) /* RPL-S */ #define INTEL_RPLS_IDS(info) \ diff --git a/sys/dev/pci/pcidevs b/sys/dev/pci/pcidevs index ef314b78f..caf04f461 100644 --- a/sys/dev/pci/pcidevs +++ b/sys/dev/pci/pcidevs @@ -1,4 +1,4 @@ -$OpenBSD: pcidevs,v 1.2063 2024/02/19 05:36:17 jsg Exp $ +$OpenBSD: pcidevs,v 1.2064 2024/02/29 10:09:54 jsg Exp $ /* $NetBSD: pcidevs,v 1.30 1997/06/24 06:20:24 thorpej Exp $ */ /* @@ -5739,6 +5739,8 @@ product INTEL ADL_P_GT2_18 0x46c3 Graphics product INTEL ADL_N_GT_1 0x46d0 Graphics product INTEL ADL_N_GT_2 0x46d1 Graphics product INTEL ADL_N_GT_3 0x46d2 Graphics +product INTEL ADL_N_GT_4 0x46d3 Graphics +product INTEL ADL_N_GT_5 0x46d4 Graphics product INTEL DG1_1 0x4905 Iris Xe MAX product INTEL DG1_2 0x4906 Graphics product INTEL DG1_3 0x4907 SG-18M diff --git a/sys/dev/pci/pcidevs.h b/sys/dev/pci/pcidevs.h index cdd316615..fdaff6d74 100644 --- a/sys/dev/pci/pcidevs.h +++ b/sys/dev/pci/pcidevs.h @@ -2,7 +2,7 @@ * THIS FILE AUTOMATICALLY GENERATED. DO NOT EDIT. * * generated from: - * OpenBSD: pcidevs,v 1.2063 2024/02/19 05:36:17 jsg Exp + * OpenBSD: pcidevs,v 1.2064 2024/02/29 10:09:54 jsg Exp */ /* $NetBSD: pcidevs,v 1.30 1997/06/24 06:20:24 thorpej Exp $ */ @@ -5744,6 +5744,8 @@ #define PCI_PRODUCT_INTEL_ADL_N_GT_1 0x46d0 /* Graphics */ #define PCI_PRODUCT_INTEL_ADL_N_GT_2 0x46d1 /* Graphics */ #define PCI_PRODUCT_INTEL_ADL_N_GT_3 0x46d2 /* Graphics */ +#define PCI_PRODUCT_INTEL_ADL_N_GT_4 0x46d3 /* Graphics */ +#define PCI_PRODUCT_INTEL_ADL_N_GT_5 0x46d4 /* Graphics */ #define PCI_PRODUCT_INTEL_DG1_1 0x4905 /* Iris Xe MAX */ #define PCI_PRODUCT_INTEL_DG1_2 0x4906 /* Graphics */ #define PCI_PRODUCT_INTEL_DG1_3 0x4907 /* SG-18M */ diff --git a/sys/dev/pci/pcidevs_data.h b/sys/dev/pci/pcidevs_data.h index ea91d4d18..d4a8b9153 100644 --- a/sys/dev/pci/pcidevs_data.h +++ b/sys/dev/pci/pcidevs_data.h @@ -2,7 +2,7 @@ * THIS FILE AUTOMATICALLY GENERATED. DO NOT EDIT. * * generated from: - * OpenBSD: pcidevs,v 1.2063 2024/02/19 05:36:17 jsg Exp + * OpenBSD: pcidevs,v 1.2064 2024/02/29 10:09:54 jsg Exp */ /* $NetBSD: pcidevs,v 1.30 1997/06/24 06:20:24 thorpej Exp $ */ @@ -20315,6 +20315,14 @@ static const struct pci_known_product pci_known_products[] = { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_ADL_N_GT_3, "Graphics", }, + { + PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_ADL_N_GT_4, + "Graphics", + }, + { + PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_ADL_N_GT_5, + "Graphics", + }, { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_DG1_1, "Iris Xe MAX", diff --git a/sys/net/route.c b/sys/net/route.c index ffc87f6e9..9dadb5aa5 100644 --- a/sys/net/route.c +++ b/sys/net/route.c @@ -1,4 +1,4 @@ -/* $OpenBSD: route.c,v 1.434 2024/02/27 12:37:49 bluhm Exp $ */ +/* $OpenBSD: route.c,v 1.435 2024/02/29 12:01:59 naddy Exp $ */ /* $NetBSD: route.c,v 1.14 1996/02/13 22:00:46 christos Exp $ */ /* @@ -239,28 +239,6 @@ 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); - if (!rtisvalid(ro->ro_rt)) { - rtfree(ro->ro_rt); - ro->ro_rt = NULL; - } - } - return (ro->ro_rt); -} - #ifdef INET6 int route6_cache(struct route *ro, const struct in6_addr *dst, @@ -299,24 +277,6 @@ 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); - if (!rtisvalid(ro->ro_rt)) { - rtfree(ro->ro_rt); - ro->ro_rt = NULL; - } - } - return (ro->ro_rt); -} #endif /* diff --git a/sys/net/route.h b/sys/net/route.h index 6a7ee94e6..c05a70d06 100644 --- a/sys/net/route.h +++ b/sys/net/route.h @@ -1,4 +1,4 @@ -/* $OpenBSD: route.h,v 1.208 2024/02/27 12:37:49 bluhm Exp $ */ +/* $OpenBSD: route.h,v 1.209 2024/02/29 12:01:59 naddy Exp $ */ /* $NetBSD: route.h,v 1.9 1996/02/13 22:00:49 christos Exp $ */ /* @@ -465,12 +465,8 @@ 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 *); diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c index 8135144c9..610b91d11 100644 --- a/sys/netinet/in_pcb.c +++ b/sys/netinet/in_pcb.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in_pcb.c,v 1.295 2024/02/27 12:37:49 bluhm Exp $ */ +/* $OpenBSD: in_pcb.c,v 1.296 2024/02/29 12:01:59 naddy Exp $ */ /* $NetBSD: in_pcb.c,v 1.25 1996/02/13 23:41:53 christos Exp $ */ /* @@ -908,15 +908,23 @@ in_pcblookup_local_lock(struct inpcbtable *table, const void *laddrp, struct rtentry * in_pcbrtentry(struct inpcb *inp) { + struct route *ro; + #ifdef INET6 if (ISSET(inp->inp_flags, INP_IPV6)) return in6_pcbrtentry(inp); #endif + ro = &inp->inp_route; + if (inp->inp_faddr.s_addr == INADDR_ANY) return (NULL); - return (route_mpath(&inp->inp_route, &inp->inp_faddr, &inp->inp_laddr, - 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); + } + return (ro->ro_rt); } /* @@ -930,7 +938,7 @@ in_pcbselsrc(struct in_addr *insrc, struct sockaddr_in *sin, struct inpcb *inp) { struct ip_moptions *mopts = inp->inp_moptions; - struct rtentry *rt; + struct route *ro = &inp->inp_route; const struct in_addr *laddr = &inp->inp_laddr; u_int rtableid = inp->inp_rtableid; struct sockaddr *ip4_source = NULL; @@ -975,14 +983,17 @@ in_pcbselsrc(struct in_addr *insrc, struct sockaddr_in *sin, * If route is known or can be allocated now, * our src addr is taken from the i/f, else punt. */ - rt = route_mpath(&inp->inp_route, &sin->sin_addr, NULL, 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); + } /* * If we found a route, use the address * corresponding to the outgoing interface. */ - if (rt != NULL) - ia = ifatoia(rt->rt_ifa); + if (ro->ro_rt != NULL) + ia = ifatoia(ro->ro_rt->rt_ifa); /* * Use preferred source address if : @@ -990,7 +1001,8 @@ in_pcbselsrc(struct in_addr *insrc, struct sockaddr_in *sin, * - preferred source address is set * - output interface is UP */ - if (rt && !(rt->rt_flags & RTF_LLINFO) && !(rt->rt_flags & RTF_HOST)) { + if (ro->ro_rt && !(ro->ro_rt->rt_flags & RTF_LLINFO) && + !(ro->ro_rt->rt_flags & RTF_HOST)) { ip4_source = rtable_getsource(rtableid, AF_INET); if (ip4_source != NULL) { struct ifaddr *ifa; diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c index c678bbf56..ac10047a6 100644 --- a/sys/netinet6/in6_pcb.c +++ b/sys/netinet6/in6_pcb.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in6_pcb.c,v 1.140 2024/02/27 12:37:49 bluhm Exp $ */ +/* $OpenBSD: in6_pcb.c,v 1.141 2024/02/29 12:01:59 naddy Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -561,10 +561,16 @@ in6_pcbnotify(struct inpcbtable *table, const struct sockaddr_in6 *dst, struct rtentry * in6_pcbrtentry(struct inpcb *inp) { + struct route *ro = &inp->inp_route; + if (IN6_IS_ADDR_UNSPECIFIED(&inp->inp_faddr6)) return (NULL); - return (route6_mpath(&inp->inp_route, &inp->inp_faddr6, - &inp->inp_laddr6, 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); + } + return (ro->ro_rt); } struct inpcb * diff --git a/sys/netinet6/in6_src.c b/sys/netinet6/in6_src.c index 145a1c11a..2ebfdb9d4 100644 --- a/sys/netinet6/in6_src.c +++ b/sys/netinet6/in6_src.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in6_src.c,v 1.96 2024/02/27 12:37:49 bluhm Exp $ */ +/* $OpenBSD: in6_src.c,v 1.97 2024/02/29 12:01:59 naddy Exp $ */ /* $KAME: in6_src.c,v 1.36 2001/02/06 04:08:17 itojun Exp $ */ /* @@ -95,7 +95,7 @@ in6_pcbselsrc(const struct in6_addr **in6src, struct sockaddr_in6 *dstsock, struct inpcb *inp, struct ip6_pktopts *opts) { struct ip6_moptions *mopts = inp->inp_moptions6; - struct rtentry *rt; + struct route *ro = &inp->inp_route; const struct in6_addr *laddr = &inp->inp_laddr6; u_int rtableid = inp->inp_rtableid; struct ifnet *ifp = NULL; @@ -118,8 +118,7 @@ in6_pcbselsrc(const struct in6_addr **in6src, struct sockaddr_in6 *dstsock, struct sockaddr_in6 sa6; /* get the outgoing interface */ - error = in6_selectif(dst, opts, mopts, &inp->inp_route, &ifp, - rtableid); + error = in6_selectif(dst, opts, mopts, ro, &ifp, rtableid); if (error) return (error); @@ -180,7 +179,9 @@ in6_pcbselsrc(const struct in6_addr **in6src, struct sockaddr_in6 *dstsock, * If route is known or can be allocated now, * our src addr is taken from the i/f, else punt. */ - rt = route6_mpath(&inp->inp_route, dst, NULL, rtableid); + if (route6_cache(ro, dst, NULL, rtableid)) { + ro->ro_rt = rtalloc_mpath(&ro->ro_dstsa, NULL, ro->ro_tableid); + } /* * in_pcbconnect() checks out IFF_LOOPBACK to skip using @@ -189,14 +190,14 @@ in6_pcbselsrc(const struct in6_addr **in6src, struct sockaddr_in6 *dstsock, * so doesn't check out IFF_LOOPBACK. */ - if (rt != NULL) { - ifp = if_get(rt->rt_ifidx); + if (ro->ro_rt) { + ifp = if_get(ro->ro_rt->rt_ifidx); if (ifp != NULL) { ia6 = in6_ifawithscope(ifp, dst, rtableid); if_put(ifp); } if (ia6 == NULL) /* xxx scope error ?*/ - ia6 = ifatoia6(rt->rt_ifa); + ia6 = ifatoia6(ro->ro_rt->rt_ifa); } /* @@ -205,7 +206,8 @@ in6_pcbselsrc(const struct in6_addr **in6src, struct sockaddr_in6 *dstsock, * - preferred source address is set * - output interface is UP */ - if (rt && !(rt->rt_flags & RTF_LLINFO) && !(rt->rt_flags & RTF_HOST)) { + if (ro->ro_rt && !(ro->ro_rt->rt_flags & RTF_LLINFO) && + !(ro->ro_rt->rt_flags & RTF_HOST)) { ip6_source = rtable_getsource(rtableid, AF_INET6); if (ip6_source != NULL) { struct ifaddr *ifa; @@ -302,9 +304,11 @@ in6_selectroute(const struct in6_addr *dst, struct ip6_pktopts *opts, * a new one. */ if (ro) { - struct rtentry *rt; - - rt = route6_mpath(ro, dst, NULL, 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); + } /* * Check if the outgoing interface conflicts with @@ -315,13 +319,15 @@ in6_selectroute(const struct in6_addr *dst, struct ip6_pktopts *opts, */ if (opts && opts->ip6po_pktinfo && opts->ip6po_pktinfo->ipi6_ifindex) { - if (rt != NULL && !ISSET(rt->rt_flags, RTF_LOCAL) && - rt->rt_ifidx != opts->ip6po_pktinfo->ipi6_ifindex) { + if (ro->ro_rt != NULL && + !ISSET(ro->ro_rt->rt_flags, RTF_LOCAL) && + ro->ro_rt->rt_ifidx != + opts->ip6po_pktinfo->ipi6_ifindex) { return (NULL); } } - return (rt); + return (ro->ro_rt); } return (NULL); @@ -332,7 +338,7 @@ in6_selectif(const struct in6_addr *dst, struct ip6_pktopts *opts, struct ip6_moptions *mopts, struct route *ro, struct ifnet **retifp, u_int rtableid) { - struct rtentry *rt; + struct rtentry *rt = NULL; struct in6_pktinfo *pi = NULL; /* If the caller specify the outgoing interface explicitly, use it. */ @@ -371,10 +377,11 @@ in6_selectif(const struct in6_addr *dst, struct ip6_pktopts *opts, * Although this may not be very harmful, it should still be confusing. * We thus reject the case here. */ - if (ISSET(rt->rt_flags, RTF_REJECT | RTF_BLACKHOLE)) + if (rt && (rt->rt_flags & (RTF_REJECT | RTF_BLACKHOLE))) return (rt->rt_flags & RTF_HOST ? EHOSTUNREACH : ENETUNREACH); - *retifp = if_get(rt->rt_ifidx); + if (rt != NULL) + *retifp = if_get(rt->rt_ifidx); return (0); }