diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c index a7bbac05ab03..54d7e1eb6513 100644 --- a/sys/netinet6/icmp6.c +++ b/sys/netinet6/icmp6.c @@ -2184,7 +2184,6 @@ icmp6_reflect(struct mbuf *m, size_t off) if (srcp == NULL) { int e; struct sockaddr_in6 sin6; - struct route_in6 ro; /* * This case matches to multicasts, our anycast, or unicasts @@ -2196,10 +2195,7 @@ icmp6_reflect(struct mbuf *m, size_t off) sin6.sin6_len = sizeof(sin6); sin6.sin6_addr = ip6->ip6_dst; /* zone ID should be embedded */ - bzero(&ro, sizeof(ro)); - e = in6_selectsrc(&sin6, NULL, NULL, &ro, NULL, &outif, &src); - if (ro.ro_rt) - RTFREE(ro.ro_rt); /* XXX: we could use this */ + e = in6_selectsrc(&sin6, NULL, NULL, NULL, &outif, &src); if (e) { char ip6buf[INET6_ADDRSTRLEN]; nd6log((LOG_DEBUG, diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c index 9f876a4cbb92..67ecb8ca0b69 100644 --- a/sys/netinet6/in6_pcb.c +++ b/sys/netinet6/in6_pcb.c @@ -359,7 +359,7 @@ in6_pcbladdr(register struct inpcb *inp, struct sockaddr *nam, return (error); error = in6_selectsrc(sin6, inp->in6p_outputopts, - inp, NULL, inp->inp_cred, &ifp, &in6a); + inp, inp->inp_cred, &ifp, &in6a); if (error) return (error); diff --git a/sys/netinet6/in6_src.c b/sys/netinet6/in6_src.c index c2e26f8fd2e2..fb362e25013a 100644 --- a/sys/netinet6/in6_src.c +++ b/sys/netinet6/in6_src.c @@ -134,7 +134,7 @@ static int selectroute(struct sockaddr_in6 *, struct ip6_pktopts *, struct ip6_moptions *, struct route_in6 *, struct ifnet **, struct rtentry **, int, u_int); static int in6_selectif(struct sockaddr_in6 *, struct ip6_pktopts *, - struct ip6_moptions *, struct route_in6 *ro, struct ifnet **, + struct ip6_moptions *, struct ifnet **, struct ifnet *, u_int); static struct in6_addrpolicy *lookup_addrsel_policy(struct sockaddr_in6 *); @@ -177,7 +177,7 @@ static struct in6_addrpolicy *match_addrsel_policy(struct sockaddr_in6 *); int in6_selectsrc(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts, - struct inpcb *inp, struct route_in6 *ro, struct ucred *cred, + struct inpcb *inp, struct ucred *cred, struct ifnet **ifpp, struct in6_addr *srcp) { struct rm_priotracker in6_ifa_tracker; @@ -227,7 +227,7 @@ in6_selectsrc(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts, struct in6_ifaddr *ia6; /* get the outgoing interface */ - if ((error = in6_selectif(dstsock, opts, mopts, ro, &ifp, oifp, + if ((error = in6_selectif(dstsock, opts, mopts, &ifp, oifp, (inp != NULL) ? inp->inp_inc.inc_fibnum : RT_DEFAULT_FIB)) != 0) return (error); @@ -293,7 +293,7 @@ in6_selectsrc(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts, * the outgoing interface and the destination address. */ /* get the outgoing interface */ - if ((error = in6_selectif(dstsock, opts, mopts, ro, &ifp, oifp, + if ((error = in6_selectif(dstsock, opts, mopts, &ifp, oifp, (inp != NULL) ? inp->inp_inc.inc_fibnum : RT_DEFAULT_FIB)) != 0) return (error); @@ -761,24 +761,27 @@ selectroute(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts, static int in6_selectif(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts, - struct ip6_moptions *mopts, struct route_in6 *ro, struct ifnet **retifp, + struct ip6_moptions *mopts, struct ifnet **retifp, struct ifnet *oifp, u_int fibnum) { int error; struct route_in6 sro; struct rtentry *rt = NULL; + int rt_flags; KASSERT(retifp != NULL, ("%s: retifp is NULL", __func__)); - if (ro == NULL) { - bzero(&sro, sizeof(sro)); - ro = &sro; - } + bzero(&sro, sizeof(sro)); + rt_flags = 0; - if ((error = selectroute(dstsock, opts, mopts, ro, retifp, - &rt, 1, fibnum)) != 0) { - if (ro == &sro && rt && rt == sro.ro_rt) - RTFREE(rt); + error = selectroute(dstsock, opts, mopts, &sro, retifp, &rt, 1, fibnum); + + if (rt) + rt_flags = rt->rt_flags; + if (rt && rt == sro.ro_rt) + RTFREE(rt); + + if (error != 0) { /* Help ND. See oifp comment in in6_selectsrc(). */ if (oifp != NULL && fibnum == RT_DEFAULT_FIB) { *retifp = oifp; @@ -804,16 +807,12 @@ in6_selectif(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts, * Although this may not be very harmful, it should still be confusing. * We thus reject the case here. */ - if (rt && (rt->rt_flags & (RTF_REJECT | RTF_BLACKHOLE))) { - int flags = (rt->rt_flags & RTF_HOST ? EHOSTUNREACH : ENETUNREACH); - if (ro == &sro && rt && rt == sro.ro_rt) - RTFREE(rt); - return (flags); + if (rt_flags & (RTF_REJECT | RTF_BLACKHOLE)) { + error = (rt_flags & RTF_HOST ? EHOSTUNREACH : ENETUNREACH); + return (error); } - if (ro == &sro && rt && rt == sro.ro_rt) - RTFREE(rt); return (0); } diff --git a/sys/netinet6/ip6_var.h b/sys/netinet6/ip6_var.h index 2159f29536e7..f43a28c199b1 100644 --- a/sys/netinet6/ip6_var.h +++ b/sys/netinet6/ip6_var.h @@ -419,7 +419,7 @@ int dest6_input(struct mbuf **, int *, int); int none_input(struct mbuf **, int *, int); int in6_selectsrc(struct sockaddr_in6 *, struct ip6_pktopts *, - struct inpcb *inp, struct route_in6 *, struct ucred *cred, + struct inpcb *inp, struct ucred *cred, struct ifnet **, struct in6_addr *); int in6_selectroute(struct sockaddr_in6 *, struct ip6_pktopts *, struct ip6_moptions *, struct route_in6 *, struct ifnet **, diff --git a/sys/netinet6/nd6_nbr.c b/sys/netinet6/nd6_nbr.c index 80a5cd3ee972..407c6e51b40b 100644 --- a/sys/netinet6/nd6_nbr.c +++ b/sys/netinet6/nd6_nbr.c @@ -408,7 +408,6 @@ nd6_ns_output_fib(struct ifnet *ifp, const struct in6_addr *saddr6, int icmp6len; int maxlen; caddr_t mac; - struct route_in6 ro; if (IN6_IS_ADDR_MULTICAST(taddr6)) return; @@ -428,8 +427,6 @@ nd6_ns_output_fib(struct ifnet *ifp, const struct in6_addr *saddr6, return; M_SETFIB(m, fibnum); - bzero(&ro, sizeof(ro)); - if (daddr6 == NULL || IN6_IS_ADDR_MULTICAST(daddr6)) { m->m_flags |= M_MCAST; im6o.im6o_multicast_ifp = ifp; @@ -497,7 +494,7 @@ nd6_ns_output_fib(struct ifnet *ifp, const struct in6_addr *saddr6, oifp = ifp; error = in6_selectsrc(&dst_sa, NULL, - NULL, &ro, NULL, &oifp, &src_in); + NULL, NULL, &oifp, &src_in); if (error) { char ip6buf[INET6_ADDRSTRLEN]; nd6log((LOG_DEBUG, "%s: source can't be " @@ -585,21 +582,15 @@ nd6_ns_output_fib(struct ifnet *ifp, const struct in6_addr *saddr6, m_tag_prepend(m, mtag); } - ip6_output(m, NULL, &ro, (nonce != NULL) ? IPV6_UNSPECSRC : 0, + ip6_output(m, NULL, NULL, (nonce != NULL) ? IPV6_UNSPECSRC : 0, &im6o, NULL, NULL); icmp6_ifstat_inc(ifp, ifs6_out_msg); icmp6_ifstat_inc(ifp, ifs6_out_neighborsolicit); ICMP6STAT_INC(icp6s_outhist[ND_NEIGHBOR_SOLICIT]); - /* We don't cache this route. */ - RO_RTFREE(&ro); - return; bad: - if (ro.ro_rt) { - RTFREE(ro.ro_rt); - } m_freem(m); return; } @@ -960,9 +951,6 @@ nd6_na_output_fib(struct ifnet *ifp, const struct in6_addr *daddr6_0, struct sockaddr_in6 dst_sa; int icmp6len, maxlen, error; caddr_t mac = NULL; - struct route_in6 ro; - - bzero(&ro, sizeof(ro)); daddr6 = *daddr6_0; /* make a local copy for modification */ @@ -1020,9 +1008,8 @@ nd6_na_output_fib(struct ifnet *ifp, const struct in6_addr *daddr6_0, /* * Select a source whose scope is the same as that of the dest. */ - bcopy(&dst_sa, &ro.ro_dst, sizeof(dst_sa)); oifp = ifp; - error = in6_selectsrc(&dst_sa, NULL, NULL, &ro, NULL, &oifp, &src); + error = in6_selectsrc(&dst_sa, NULL, NULL, NULL, &oifp, &src); if (error) { char ip6buf[INET6_ADDRSTRLEN]; nd6log((LOG_DEBUG, "nd6_na_output: source can't be " @@ -1093,20 +1080,14 @@ nd6_na_output_fib(struct ifnet *ifp, const struct in6_addr *daddr6_0, m_tag_prepend(m, mtag); } - ip6_output(m, NULL, &ro, 0, &im6o, NULL, NULL); + ip6_output(m, NULL, NULL, 0, &im6o, NULL, NULL); icmp6_ifstat_inc(ifp, ifs6_out_msg); icmp6_ifstat_inc(ifp, ifs6_out_neighboradvert); ICMP6STAT_INC(icp6s_outhist[ND_NEIGHBOR_ADVERT]); - /* We don't cache this route. */ - RO_RTFREE(&ro); - return; bad: - if (ro.ro_rt) { - RTFREE(ro.ro_rt); - } m_freem(m); return; } diff --git a/sys/netinet6/raw_ip6.c b/sys/netinet6/raw_ip6.c index 390194459441..0725842cbe7e 100644 --- a/sys/netinet6/raw_ip6.c +++ b/sys/netinet6/raw_ip6.c @@ -460,7 +460,7 @@ rip6_output(struct mbuf *m, struct socket *so, ...) /* * Source address selection. */ - error = in6_selectsrc(dstsock, optp, in6p, NULL, so->so_cred, + error = in6_selectsrc(dstsock, optp, in6p, so->so_cred, &oifp, &in6a); if (error) goto bad; @@ -814,7 +814,7 @@ rip6_connect(struct socket *so, struct sockaddr *nam, struct thread *td) INP_WLOCK(inp); /* Source address selection. XXX: need pcblookup? */ error = in6_selectsrc(addr, inp->in6p_outputopts, - inp, NULL, so->so_cred, &ifp, &in6a); + inp, so->so_cred, &ifp, &in6a); if (error) { INP_WUNLOCK(inp); INP_INFO_WUNLOCK(&V_ripcbinfo); diff --git a/sys/netinet6/udp6_usrreq.c b/sys/netinet6/udp6_usrreq.c index 375c00d0a3e2..353b260d33ca 100644 --- a/sys/netinet6/udp6_usrreq.c +++ b/sys/netinet6/udp6_usrreq.c @@ -731,7 +731,7 @@ udp6_output(struct inpcb *inp, struct mbuf *m, struct sockaddr *addr6, } if (!IN6_IS_ADDR_V4MAPPED(faddr)) { - error = in6_selectsrc(sin6, optp, inp, NULL, + error = in6_selectsrc(sin6, optp, inp, td->td_ucred, &oifp, &in6a); if (error) goto release;