diff options
author | melifaro <melifaro@FreeBSD.org> | 2016-01-10 13:40:29 +0000 |
---|---|---|
committer | melifaro <melifaro@FreeBSD.org> | 2016-01-10 13:40:29 +0000 |
commit | 21632a9bd96fd68b505602bfdd4850ab1e18574a (patch) | |
tree | 97b6bca373452e47001d3052c19a801b844cc5c5 /sys/netinet6/icmp6.c | |
parent | 62e557108e3812d8e8b16b2a263c2b82ea2538e5 (diff) | |
download | FreeBSD-src-21632a9bd96fd68b505602bfdd4850ab1e18574a.zip FreeBSD-src-21632a9bd96fd68b505602bfdd4850ab1e18574a.tar.gz |
Split in6_selectsrc() into in6_selectsrc_addr() and in6_selectsrc_socket().
in6_selectsrc() has 2 class of users: socket-based one (raw/udp/pcb/etc) and
socket-less (ND code). The main reason for that change is inability to
specify non-default FIB for callers w/o socket since (internally) inpcb
is used to determine fib.
As as result, add 2 wrappers for in6_selectsrc() (making in6_selectsrc()
static):
1) in6_selectsrc_socket() for the former class. Embed scope_ambiguous check
along with returning hop limit when needed.
2) in6_selectsrc_addr() for the latter case. Add 'fibnum' argument and
pass IPv6 address w/ explicitly specified scope as separate argument.
Reviewed by: ae (previous version)
Diffstat (limited to 'sys/netinet6/icmp6.c')
-rw-r--r-- | sys/netinet6/icmp6.c | 22 |
1 files changed, 9 insertions, 13 deletions
diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c index 2007a18..dd77527 100644 --- a/sys/netinet6/icmp6.c +++ b/sys/netinet6/icmp6.c @@ -2194,26 +2194,25 @@ icmp6_reflect(struct mbuf *m, size_t off) } if (srcp == NULL) { - int e; - struct sockaddr_in6 sin6; + int error; + struct in6_addr dst6; + uint32_t scopeid; /* * This case matches to multicasts, our anycast, or unicasts * that we do not own. Select a source address based on the * source address of the erroneous packet. */ - bzero(&sin6, sizeof(sin6)); - sin6.sin6_family = AF_INET6; - sin6.sin6_len = sizeof(sin6); - sin6.sin6_addr = ip6->ip6_dst; /* zone ID should be embedded */ + in6_splitscope(&ip6->ip6_dst, &dst6, &scopeid); + error = in6_selectsrc_addr(RT_DEFAULT_FIB, &dst6, + scopeid, NULL, &src6, &hlim); - e = in6_selectsrc(&sin6, NULL, NULL, NULL, &outif, &src6); - if (e) { + if (error) { char ip6buf[INET6_ADDRSTRLEN]; nd6log((LOG_DEBUG, "icmp6_reflect: source can't be determined: " "dst=%s, error=%d\n", - ip6_sprintf(ip6buf, &ip6->ip6_dst), e)); + ip6_sprintf(ip6buf, &ip6->ip6_dst), error)); goto bad; } srcp = &src6; @@ -2228,10 +2227,7 @@ icmp6_reflect(struct mbuf *m, size_t off) ip6->ip6_vfc &= ~IPV6_VERSION_MASK; ip6->ip6_vfc |= IPV6_VERSION; ip6->ip6_nxt = IPPROTO_ICMPV6; - if (outif) - ip6->ip6_hlim = ND_IFINFO(outif)->chlim; - else - ip6->ip6_hlim = hlim; + ip6->ip6_hlim = hlim; icmp6->icmp6_cksum = 0; icmp6->icmp6_cksum = in6_cksum(m, IPPROTO_ICMPV6, |