summaryrefslogtreecommitdiffstats
path: root/sys/netinet6/icmp6.c
diff options
context:
space:
mode:
authormelifaro <melifaro@FreeBSD.org>2016-01-10 13:40:29 +0000
committermelifaro <melifaro@FreeBSD.org>2016-01-10 13:40:29 +0000
commit21632a9bd96fd68b505602bfdd4850ab1e18574a (patch)
tree97b6bca373452e47001d3052c19a801b844cc5c5 /sys/netinet6/icmp6.c
parent62e557108e3812d8e8b16b2a263c2b82ea2538e5 (diff)
downloadFreeBSD-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.c22
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,
OpenPOWER on IntegriCloud