-/* $OpenBSD: nd6_nbr.c,v 1.109 2016/08/22 10:33:22 mpi Exp $ */
+/* $OpenBSD: nd6_nbr.c,v 1.110 2016/08/23 11:03:10 mpi Exp $ */
/* $KAME: nd6_nbr.c,v 1.61 2001/02/10 16:06:14 jinmei Exp $ */
/*
int icmp6len;
int maxlen;
caddr_t mac;
- struct route_in6 ro;
-
- bzero(&ro, sizeof(ro));
- ro.ro_tableid = ifp->if_rdomain;
if (IN6_IS_ADDR_MULTICAST(taddr6))
return;
if (saddr6 && in6ifa_ifpwithaddr(ifp, saddr6))
src_sa.sin6_addr = *saddr6;
else {
- struct in6_addr *src0;
- int error;
+ struct rtentry *rt;
- bcopy(&dst_sa, &ro.ro_dst, sizeof(dst_sa));
- error = in6_selectsrc(&src0, &dst_sa, NULL, &ro,
+ rt = rtalloc(sin6tosa(&dst_sa), RT_RESOLVE,
m->m_pkthdr.ph_rtableid);
- if (error) {
+ if (!rtisvalid(rt)) {
char addr[INET6_ADDRSTRLEN];
nd6log((LOG_DEBUG,
- "nd6_ns_output: source can't be "
- "determined: dst=%s, error=%d\n",
- inet_ntop(AF_INET6, &dst_sa.sin6_addr,
- addr, sizeof(addr)),
- error));
+ "%s: source can't be determined: dst=%s\n",
+ __func__, inet_ntop(AF_INET6,
+ &dst_sa.sin6_addr, addr, sizeof(addr))));
+ rtfree(rt);
goto bad;
}
- src_sa.sin6_addr = *src0;
+ src_sa.sin6_addr =
+ ifatoia6(rt->rt_ifa)->ia_addr.sin6_addr;
+ rtfree(rt);
}
} else {
/*
nd_ns->nd_ns_cksum = 0;
m->m_pkthdr.csum_flags |= M_ICMP_CSUM_OUT;
- ip6_output(m, NULL, &ro, dad ? IPV6_UNSPECSRC : 0, &im6o, NULL);
+ ip6_output(m, NULL, NULL, dad ? IPV6_UNSPECSRC : 0, &im6o, NULL);
icmp6stat.icp6s_outhist[ND_NEIGHBOR_SOLICIT]++;
-
- if (ro.ro_rt) { /* we don't cache this route. */
- rtfree(ro.ro_rt);
- }
return;
bad:
- if (ro.ro_rt) {
- rtfree(ro.ro_rt);
- }
m_freem(m);
- return;
}
/*
struct sockaddr *sdl0)
{
struct mbuf *m;
+ struct rtentry *rt = NULL;
struct ip6_hdr *ip6;
struct nd_neighbor_advert *nd_na;
struct ip6_moptions im6o;
- struct sockaddr_in6 src_sa, dst_sa;
- struct in6_addr *src0;
- int icmp6len, maxlen, error;
- caddr_t mac;
- struct route_in6 ro;
-
- mac = NULL;
- bzero(&ro, sizeof(ro));
- ro.ro_tableid = ifp->if_rdomain;
+ struct sockaddr_in6 dst_sa;
+ int icmp6len, maxlen;
+ caddr_t mac = NULL;
/* estimate the size of message */
maxlen = sizeof(*ip6) + sizeof(*nd_na);
ip6->ip6_vfc |= IPV6_VERSION;
ip6->ip6_nxt = IPPROTO_ICMPV6;
ip6->ip6_hlim = 255;
- bzero(&src_sa, sizeof(src_sa));
bzero(&dst_sa, sizeof(dst_sa));
- src_sa.sin6_len = dst_sa.sin6_len = sizeof(struct sockaddr_in6);
- src_sa.sin6_family = dst_sa.sin6_family = AF_INET6;
+ dst_sa.sin6_len = sizeof(struct sockaddr_in6);
+ dst_sa.sin6_family = AF_INET6;
dst_sa.sin6_addr = *daddr6;
if (IN6_IS_ADDR_UNSPECIFIED(daddr6)) {
/* reply to DAD */
/*
* Select a source whose scope is the same as that of the dest.
*/
- bcopy(&dst_sa, &ro.ro_dst, sizeof(dst_sa));
- error = in6_selectsrc(&src0, &dst_sa, NULL, &ro,
- m->m_pkthdr.ph_rtableid);
- if (error) {
+ rt = rtalloc(sin6tosa(&dst_sa), RT_RESOLVE, ifp->if_rdomain);
+ if (!rtisvalid(rt)) {
char addr[INET6_ADDRSTRLEN];
- nd6log((LOG_DEBUG, "nd6_na_output: source can't be "
- "determined: dst=%s, error=%d\n",
- inet_ntop(AF_INET6, &dst_sa.sin6_addr, addr, sizeof(addr)),
- error));
+ nd6log((LOG_DEBUG, "%s: source can't be determined: dst=%s\n",
+ __func__, inet_ntop(AF_INET6, &dst_sa.sin6_addr, addr,
+ sizeof(addr))));
+ rtfree(rt);
goto bad;
}
- src_sa.sin6_addr = *src0;
- ip6->ip6_src = src_sa.sin6_addr;
+ ip6->ip6_src = ifatoia6(rt->rt_ifa)->ia_addr.sin6_addr;
+ rtfree(rt);
nd_na = (struct nd_neighbor_advert *)(ip6 + 1);
nd_na->nd_na_type = ND_NEIGHBOR_ADVERT;
nd_na->nd_na_code = 0;
nd_na->nd_na_cksum = 0;
m->m_pkthdr.csum_flags |= M_ICMP_CSUM_OUT;
- ip6_output(m, NULL, &ro, 0, &im6o, NULL);
+ ip6_output(m, NULL, NULL, 0, &im6o, NULL);
icmp6stat.icp6s_outhist[ND_NEIGHBOR_ADVERT]++;
-
- if (ro.ro_rt) { /* we don't cache this route. */
- rtfree(ro.ro_rt);
- }
return;
bad:
- if (ro.ro_rt) {
- rtfree(ro.ro_rt);
- }
m_freem(m);
- return;
}
caddr_t