summaryrefslogtreecommitdiffstats
path: root/sys/netipsec/key.c
diff options
context:
space:
mode:
authorLuiz Otavio O Souza <luiz@netgate.com>2015-09-15 15:22:37 -0500
committerLuiz Otavio O Souza <luiz@netgate.com>2015-10-20 12:01:14 -0500
commit16636d7a65a723c72f597d46931c31fdd4993205 (patch)
tree85eba7a9c22d8fa1366d1720a5d3cf434d36ac60 /sys/netipsec/key.c
parentc3560c4520f486ebf25e8ca725a7f77c559cb589 (diff)
downloadFreeBSD-src-16636d7a65a723c72f597d46931c31fdd4993205.zip
FreeBSD-src-16636d7a65a723c72f597d46931c31fdd4993205.tar.gz
MFC r281693:
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 TAG: IPSEC-HEAD Issue: #4841
Diffstat (limited to 'sys/netipsec/key.c')
-rw-r--r--sys/netipsec/key.c43
1 files changed, 7 insertions, 36 deletions
diff --git a/sys/netipsec/key.c b/sys/netipsec/key.c
index c19dd47..6ab3f64 100644
--- a/sys/netipsec/key.c
+++ b/sys/netipsec/key.c
@@ -3854,48 +3854,19 @@ key_ismyaddr(struct sockaddr *sa)
* compare my own address for IPv6.
* 1: ours
* 0: other
- * NOTE: derived ip6_input() in KAME. This is necessary to modify more.
*/
-#include <netinet6/in6_var.h>
-
static int
key_ismyaddr6(struct sockaddr_in6 *sin6)
{
- struct in6_ifaddr *ia;
-#if 0
- struct in6_multi *in6m;
-#endif
+ struct in6_addr in6;
- IN6_IFADDR_RLOCK();
- TAILQ_FOREACH(ia, &V_in6_ifaddrhead, ia_link) {
- if (key_sockaddrcmp((struct sockaddr *)sin6,
- (struct sockaddr *)&ia->ia_addr, 0) == 0) {
- IN6_IFADDR_RUNLOCK();
- return 1;
- }
+ if (!IN6_IS_SCOPE_LINKLOCAL(&sin6->sin6_addr))
+ return (in6_localip(&sin6->sin6_addr));
-#if 0
- /*
- * XXX Multicast
- * XXX why do we care about multlicast here while we don't care
- * about IPv4 multicast??
- * XXX scope
- */
- in6m = NULL;
- IN6_LOOKUP_MULTI(sin6->sin6_addr, ia->ia_ifp, in6m);
- if (in6m) {
- IN6_IFADDR_RUNLOCK();
- return 1;
- }
-#endif
- }
- IN6_IFADDR_RUNLOCK();
-
- /* loopback, just for safety */
- if (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr))
- return 1;
-
- return 0;
+ /* Convert address into kernel-internal form */
+ in6 = sin6->sin6_addr;
+ in6.s6_addr16[1] = htons(sin6->sin6_scope_id & 0xffff);
+ return (in6_localip(&in6));
}
#endif /*INET6*/
OpenPOWER on IntegriCloud