diff options
author | ae <ae@FreeBSD.org> | 2015-07-03 19:01:38 +0000 |
---|---|---|
committer | ae <ae@FreeBSD.org> | 2015-07-03 19:01:38 +0000 |
commit | cce394167652b07f62c963698e3990608ed9ea02 (patch) | |
tree | 6376d167ba0675f6013f407f8756b069b98a01ed /sys/netinet6/ip6_output.c | |
parent | 1aded648f26c980c95b0112b0e6ced7ac386480d (diff) | |
download | FreeBSD-src-cce394167652b07f62c963698e3990608ed9ea02.zip FreeBSD-src-cce394167652b07f62c963698e3990608ed9ea02.tar.gz |
Keep IPv6 address specified by IPV6_PKTINFO socket option in kernel
internal form to be able handle link-local IPv6 addresses.
Reported by: kp
Tested by: kp
Diffstat (limited to 'sys/netinet6/ip6_output.c')
-rw-r--r-- | sys/netinet6/ip6_output.c | 11 |
1 files changed, 7 insertions, 4 deletions
diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c index d667903..d671951 100644 --- a/sys/netinet6/ip6_output.c +++ b/sys/netinet6/ip6_output.c @@ -2189,12 +2189,14 @@ ip6_getpcbopt(struct ip6_pktopts *pktopt, int optname, struct sockopt *sopt) switch (optname) { case IPV6_PKTINFO: - if (pktopt && pktopt->ip6po_pktinfo) - optdata = (void *)pktopt->ip6po_pktinfo; - else { + optdata = (void *)&null_pktinfo; + if (pktopt && pktopt->ip6po_pktinfo) { + bcopy(pktopt->ip6po_pktinfo, &null_pktinfo, + sizeof(null_pktinfo)); + in6_clearscope(&null_pktinfo.ipi6_addr); + } else { /* XXX: we don't have to do this every time... */ bzero(&null_pktinfo, sizeof(null_pktinfo)); - optdata = (void *)&null_pktinfo; } optdatalen = sizeof(struct in6_pktinfo); break; @@ -2566,6 +2568,7 @@ ip6_setpktopt(int optname, u_char *buf, int len, struct ip6_pktopts *opt, !IN6_IS_ADDR_UNSPECIFIED(&pktinfo->ipi6_addr)) { struct in6_ifaddr *ia; + in6_setscope(&pktinfo->ipi6_addr, ifp, NULL); ia = in6ifa_ifpwithaddr(ifp, &pktinfo->ipi6_addr); if (ia == NULL) return (EADDRNOTAVAIL); |