summaryrefslogtreecommitdiffstats
path: root/sys/netinet6/ipsec.c
diff options
context:
space:
mode:
authorume <ume@FreeBSD.org>2001-10-17 13:03:37 +0000
committerume <ume@FreeBSD.org>2001-10-17 13:03:37 +0000
commit737d8ec1500304779377273b905a619d16e0b6ae (patch)
tree11a7590290049346bb42b6178d7cb755b66b2a69 /sys/netinet6/ipsec.c
parentb44023b126535b8854d9ccdc4d6969ed312fb1f8 (diff)
downloadFreeBSD-src-737d8ec1500304779377273b905a619d16e0b6ae.zip
FreeBSD-src-737d8ec1500304779377273b905a619d16e0b6ae.tar.gz
Fixed to process a IPv6 packet when ah transport after esp tunnel
should be applied. the SA of AH transport could not be selected from the SAD because of this bug. Obtained from: KAME MFC after: 1 week
Diffstat (limited to 'sys/netinet6/ipsec.c')
-rw-r--r--sys/netinet6/ipsec.c45
1 files changed, 42 insertions, 3 deletions
diff --git a/sys/netinet6/ipsec.c b/sys/netinet6/ipsec.c
index 3cb835d..6f4bd7d 100644
--- a/sys/netinet6/ipsec.c
+++ b/sys/netinet6/ipsec.c
@@ -2902,9 +2902,48 @@ ipsec6_output_tunnel(state, sp, flags)
break;
}
- for (/*already initialized*/; isr; isr = isr->next) {
- /* When tunnel mode, SA peers must be specified. */
- bcopy(&isr->saidx, &saidx, sizeof(saidx));
+ for (/* already initialized */; isr; isr = isr->next) {
+ if (isr->saidx.mode == IPSEC_MODE_TUNNEL) {
+ /* When tunnel mode, SA peers must be specified. */
+ bcopy(&isr->saidx, &saidx, sizeof(saidx));
+ } else {
+ /* make SA index to look for a proper SA */
+ struct sockaddr_in6 *sin6;
+
+ bzero(&saidx, sizeof(saidx));
+ saidx.proto = isr->saidx.proto;
+ saidx.mode = isr->saidx.mode;
+ saidx.reqid = isr->saidx.reqid;
+
+ ip6 = mtod(state->m, struct ip6_hdr *);
+ sin6 = (struct sockaddr_in6 *)&saidx.src;
+ if (sin6->sin6_len == 0) {
+ sin6->sin6_len = sizeof(*sin6);
+ sin6->sin6_family = AF_INET6;
+ sin6->sin6_port = IPSEC_PORT_ANY;
+ bcopy(&ip6->ip6_src, &sin6->sin6_addr,
+ sizeof(ip6->ip6_src));
+ if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src)) {
+ /* fix scope id for comparing SPD */
+ sin6->sin6_addr.s6_addr16[1] = 0;
+ sin6->sin6_scope_id = ntohs(ip6->ip6_src.s6_addr16[1]);
+ }
+ }
+ sin6 = (struct sockaddr_in6 *)&saidx.dst;
+ if (sin6->sin6_len == 0) {
+ sin6->sin6_len = sizeof(*sin6);
+ sin6->sin6_family = AF_INET6;
+ sin6->sin6_port = IPSEC_PORT_ANY;
+ bcopy(&ip6->ip6_dst, &sin6->sin6_addr,
+ sizeof(ip6->ip6_dst));
+ if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst)) {
+ /* fix scope id for comparing SPD */
+ sin6->sin6_addr.s6_addr16[1] = 0;
+ sin6->sin6_scope_id = ntohs(ip6->ip6_dst.s6_addr16[1]);
+ }
+ }
+ }
+
if (key_checkrequest(isr, &saidx) == ENOENT) {
/*
* IPsec processing is required, but no SA found.
OpenPOWER on IntegriCloud