From 1ae800e7a6eccc8f85cd4f3219433db0770e18ac Mon Sep 17 00:00:00 2001 From: "Andrey V. Elsukov" Date: Sat, 18 Apr 2015 16:46:31 +0000 Subject: Fix handling of scoped IPv6 addresses in IPSec code. * in ipsec_encap() embed scope zone ids into link-local addresses in the new IPv6 header, this helps ip6_output() disambiguate the scope; * teach key_ismyaddr6() use in6_localip(). in6_localip() is less strict than key_sockaddrcmp(). It doesn't compare all fileds of struct sockaddr_in6, but it is faster and it should be safe, because all SA's data was checked for correctness. Also, since IPv6 link-local addresses in the &V_in6_ifaddrhead are stored in kernel-internal form, we need to embed scope zone id from SA into the address before calling in6_localip. * in ipsec_common_input() take scope zone id embedded in the address and use it to initialize sin6_scope_id, then use this sockaddr structure to lookup SA, because we keep addresses in the SADB without embedded scope zone id. Differential Revision: https://reviews.freebsd.org/D2304 Reviewed by: gnn Sponsored by: Yandex LLC --- sys/netipsec/ipsec_output.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'sys/netipsec/ipsec_output.c') diff --git a/sys/netipsec/ipsec_output.c b/sys/netipsec/ipsec_output.c index 2c06c8666e53..691e6845b199 100644 --- a/sys/netipsec/ipsec_output.c +++ b/sys/netipsec/ipsec_output.c @@ -503,7 +503,14 @@ ipsec_encap(struct mbuf **mp, struct secasindex *saidx) ip6->ip6_hlim = V_ip6_defhlim; ip6->ip6_nxt = proto; ip6->ip6_dst = saidx->dst.sin6.sin6_addr; + /* For link-local address embed scope zone id */ + if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst)) + ip6->ip6_dst.s6_addr16[1] = + htons(saidx->dst.sin6.sin6_scope_id & 0xffff); ip6->ip6_src = saidx->src.sin6.sin6_addr; + if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src)) + ip6->ip6_src.s6_addr16[1] = + htons(saidx->src.sin6.sin6_scope_id & 0xffff); ip6->ip6_plen = htons((*mp)->m_pkthdr.len - sizeof(*ip6)); ip_ecn_ingress(V_ip6_ipsec_ecn, &proto, &itos); ip6->ip6_flow |= htonl((uint32_t)proto << 20); -- cgit v1.2.3