Mon Jun 6 16:48:35 2011 UTC ()
remove a limitation that inner and outer IP version must be equal
for an ESP tunnel, and add some fixes which make v4-in-v6 work
(v6 as inner protocol isn't ready, even v6-in-v6 can never have worked)

being here, fix a statistics counter and kill an unused variable


(drochner)
diff -r1.32 -r1.33 src/sys/netipsec/ipsec_output.c
diff -r1.71 -r1.72 src/sys/netipsec/key.c
diff -r1.26 -r1.27 src/sys/netipsec/xform_ipip.c

cvs diff -r1.32 -r1.33 src/sys/netipsec/ipsec_output.c (expand / switch to unified diff)

--- src/sys/netipsec/ipsec_output.c 2011/02/18 16:12:26 1.32
+++ src/sys/netipsec/ipsec_output.c 2011/06/06 16:48:35 1.33
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: ipsec_output.c,v 1.32 2011/02/18 16:12:26 drochner Exp $ */ 1/* $NetBSD: ipsec_output.c,v 1.33 2011/06/06 16:48:35 drochner Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2002, 2003 Sam Leffler, Errno Consulting 4 * Copyright (c) 2002, 2003 Sam Leffler, Errno Consulting
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -19,27 +19,27 @@ @@ -19,27 +19,27 @@
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE. 26 * SUCH DAMAGE.
27 * 27 *
28 * $FreeBSD: /repoman/r/ncvs/src/sys/netipsec/ipsec_output.c,v 1.3.2.2 2003/03/28 20:32:53 sam Exp $ 28 * $FreeBSD: /repoman/r/ncvs/src/sys/netipsec/ipsec_output.c,v 1.3.2.2 2003/03/28 20:32:53 sam Exp $
29 */ 29 */
30 30
31#include <sys/cdefs.h> 31#include <sys/cdefs.h>
32__KERNEL_RCSID(0, "$NetBSD: ipsec_output.c,v 1.32 2011/02/18 16:12:26 drochner Exp $"); 32__KERNEL_RCSID(0, "$NetBSD: ipsec_output.c,v 1.33 2011/06/06 16:48:35 drochner Exp $");
33 33
34/* 34/*
35 * IPsec output processing. 35 * IPsec output processing.
36 */ 36 */
37#include "opt_inet.h" 37#include "opt_inet.h"
38#ifdef __FreeBSD__ 38#ifdef __FreeBSD__
39#include "opt_inet6.h" 39#include "opt_inet6.h"
40#endif 40#endif
41#include "opt_ipsec.h" 41#include "opt_ipsec.h"
42 42
43#include <sys/param.h> 43#include <sys/param.h>
44#include <sys/systm.h> 44#include <sys/systm.h>
45#include <sys/mbuf.h> 45#include <sys/mbuf.h>
@@ -598,29 +598,35 @@ ipsec4_process_packet( @@ -598,29 +598,35 @@ ipsec4_process_packet(
598 } 598 }
599 599
600 /* 600 /*
601 * Dispatch to the appropriate IPsec transform logic. The 601 * Dispatch to the appropriate IPsec transform logic. The
602 * packet will be returned for transmission after crypto 602 * packet will be returned for transmission after crypto
603 * processing, etc. are completed. For encapsulation we 603 * processing, etc. are completed. For encapsulation we
604 * bypass this call because of the explicit call done above 604 * bypass this call because of the explicit call done above
605 * (necessary to deal with IP_DF handling for IPv4). 605 * (necessary to deal with IP_DF handling for IPv4).
606 * 606 *
607 * NB: m & sav are ``passed to caller'' who's reponsible for 607 * NB: m & sav are ``passed to caller'' who's reponsible for
608 * for reclaiming their resources. 608 * for reclaiming their resources.
609 */ 609 */
610 if (sav->tdb_xform->xf_type != XF_IP4) { 610 if (sav->tdb_xform->xf_type != XF_IP4) {
611 ip = mtod(m, struct ip *); 611 union sockaddr_union *dst = &sav->sah->saidx.dst;
612 i = ip->ip_hl << 2; 612 if (dst->sa.sa_family == AF_INET) {
613 off = offsetof(struct ip, ip_p); 613 ip = mtod(m, struct ip *);
 614 i = ip->ip_hl << 2;
 615 off = offsetof(struct ip, ip_p);
 616 } else {
 617 i = sizeof(struct ip6_hdr);
 618 off = offsetof(struct ip6_hdr, ip6_nxt);
 619 }
614 error = (*sav->tdb_xform->xf_output)(m, isr, NULL, i, off); 620 error = (*sav->tdb_xform->xf_output)(m, isr, NULL, i, off);
615 } else { 621 } else {
616 error = ipsec_process_done(m, isr); 622 error = ipsec_process_done(m, isr);
617 } 623 }
618 splx(s); 624 splx(s);
619 return error; 625 return error;
620bad: 626bad:
621 splx(s); 627 splx(s);
622 if (m) 628 if (m)
623 m_freem(m); 629 m_freem(m);
624 return error; 630 return error;
625} 631}
626#endif 632#endif

cvs diff -r1.71 -r1.72 src/sys/netipsec/key.c (expand / switch to unified diff)

--- src/sys/netipsec/key.c 2011/05/23 15:17:25 1.71
+++ src/sys/netipsec/key.c 2011/06/06 16:48:35 1.72
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: key.c,v 1.71 2011/05/23 15:17:25 drochner Exp $ */ 1/* $NetBSD: key.c,v 1.72 2011/06/06 16:48:35 drochner Exp $ */
2/* $FreeBSD: src/sys/netipsec/key.c,v 1.3.2.3 2004/02/14 22:23:23 bms Exp $ */ 2/* $FreeBSD: src/sys/netipsec/key.c,v 1.3.2.3 2004/02/14 22:23:23 bms Exp $ */
3/* $KAME: key.c,v 1.191 2001/06/27 10:46:49 sakane Exp $ */ 3/* $KAME: key.c,v 1.191 2001/06/27 10:46:49 sakane Exp $ */
4  4
5/* 5/*
6 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 6 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
7 * All rights reserved. 7 * All rights reserved.
8 * 8 *
9 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
11 * are met: 11 * are met:
12 * 1. Redistributions of source code must retain the above copyright 12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer. 13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
@@ -22,27 +22,27 @@ @@ -22,27 +22,27 @@
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE. 31 * SUCH DAMAGE.
32 */ 32 */
33 33
34#include <sys/cdefs.h> 34#include <sys/cdefs.h>
35__KERNEL_RCSID(0, "$NetBSD: key.c,v 1.71 2011/05/23 15:17:25 drochner Exp $"); 35__KERNEL_RCSID(0, "$NetBSD: key.c,v 1.72 2011/06/06 16:48:35 drochner Exp $");
36 36
37/* 37/*
38 * This code is referd to RFC 2367 38 * This code is referd to RFC 2367
39 */ 39 */
40 40
41#include "opt_inet.h" 41#include "opt_inet.h"
42#ifdef __FreeBSD__ 42#ifdef __FreeBSD__
43#include "opt_inet6.h" 43#include "opt_inet6.h"
44#endif 44#endif
45#include "opt_ipsec.h" 45#include "opt_ipsec.h"
46#ifdef __NetBSD__ 46#ifdef __NetBSD__
47#include "opt_gateway.h" 47#include "opt_gateway.h"
48#endif 48#endif
@@ -1932,44 +1932,26 @@ key_spdadd(struct socket *so, struct mbu @@ -1932,44 +1932,26 @@ key_spdadd(struct socket *so, struct mbu
1932 &newsp->spidx); 1932 &newsp->spidx);
1933 1933
1934 /* sanity check on addr pair */ 1934 /* sanity check on addr pair */
1935 if (((struct sockaddr *)(src0 + 1))->sa_family != 1935 if (((struct sockaddr *)(src0 + 1))->sa_family !=
1936 ((struct sockaddr *)(dst0+ 1))->sa_family) { 1936 ((struct sockaddr *)(dst0+ 1))->sa_family) {
1937 KFREE(newsp); 1937 KFREE(newsp);
1938 return key_senderror(so, m, EINVAL); 1938 return key_senderror(so, m, EINVAL);
1939 } 1939 }
1940 if (((struct sockaddr *)(src0 + 1))->sa_len != 1940 if (((struct sockaddr *)(src0 + 1))->sa_len !=
1941 ((struct sockaddr *)(dst0+ 1))->sa_len) { 1941 ((struct sockaddr *)(dst0+ 1))->sa_len) {
1942 KFREE(newsp); 1942 KFREE(newsp);
1943 return key_senderror(so, m, EINVAL); 1943 return key_senderror(so, m, EINVAL);
1944 } 1944 }
1945#if 1 
1946 if (newsp->req && newsp->req->saidx.src.sa.sa_family) { 
1947 struct sockaddr *sa; 
1948 sa = (struct sockaddr *)(src0 + 1); 
1949 if (sa->sa_family != newsp->req->saidx.src.sa.sa_family) { 
1950 KFREE(newsp); 
1951 return key_senderror(so, m, EINVAL); 
1952 } 
1953 } 
1954 if (newsp->req && newsp->req->saidx.dst.sa.sa_family) { 
1955 struct sockaddr *sa; 
1956 sa = (struct sockaddr *)(dst0 + 1); 
1957 if (sa->sa_family != newsp->req->saidx.dst.sa.sa_family) { 
1958 KFREE(newsp); 
1959 return key_senderror(so, m, EINVAL); 
1960 } 
1961 } 
1962#endif 
1963 1945
1964 newsp->created = time_uptime; 1946 newsp->created = time_uptime;
1965 newsp->lastused = newsp->created; 1947 newsp->lastused = newsp->created;
1966 newsp->lifetime = lft ? lft->sadb_lifetime_addtime : 0; 1948 newsp->lifetime = lft ? lft->sadb_lifetime_addtime : 0;
1967 newsp->validtime = lft ? lft->sadb_lifetime_usetime : 0; 1949 newsp->validtime = lft ? lft->sadb_lifetime_usetime : 0;
1968 1950
1969 newsp->refcnt = 1; /* do not reclaim until I say I do */ 1951 newsp->refcnt = 1; /* do not reclaim until I say I do */
1970 newsp->state = IPSEC_SPSTATE_ALIVE; 1952 newsp->state = IPSEC_SPSTATE_ALIVE;
1971 LIST_INSERT_TAIL(&sptree[newsp->spidx.dir], newsp, secpolicy, chain); 1953 LIST_INSERT_TAIL(&sptree[newsp->spidx.dir], newsp, secpolicy, chain);
1972 1954
1973 /* delete the entry in spacqtree */ 1955 /* delete the entry in spacqtree */
1974 if (mhp->msg->sadb_msg_type == SADB_X_SPDUPDATE) { 1956 if (mhp->msg->sadb_msg_type == SADB_X_SPDUPDATE) {
1975 struct secspacq *spacq; 1957 struct secspacq *spacq;

cvs diff -r1.26 -r1.27 src/sys/netipsec/xform_ipip.c (expand / switch to unified diff)

--- src/sys/netipsec/xform_ipip.c 2011/02/18 20:40:58 1.26
+++ src/sys/netipsec/xform_ipip.c 2011/06/06 16:48:35 1.27
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: xform_ipip.c,v 1.26 2011/02/18 20:40:58 drochner Exp $ */ 1/* $NetBSD: xform_ipip.c,v 1.27 2011/06/06 16:48:35 drochner Exp $ */
2/* $FreeBSD: src/sys/netipsec/xform_ipip.c,v 1.3.2.1 2003/01/24 05:11:36 sam Exp $ */ 2/* $FreeBSD: src/sys/netipsec/xform_ipip.c,v 1.3.2.1 2003/01/24 05:11:36 sam Exp $ */
3/* $OpenBSD: ip_ipip.c,v 1.25 2002/06/10 18:04:55 itojun Exp $ */ 3/* $OpenBSD: ip_ipip.c,v 1.25 2002/06/10 18:04:55 itojun Exp $ */
4 4
5/* 5/*
6 * The authors of this code are John Ioannidis (ji@tla.org), 6 * The authors of this code are John Ioannidis (ji@tla.org),
7 * Angelos D. Keromytis (kermit@csd.uch.gr) and 7 * Angelos D. Keromytis (kermit@csd.uch.gr) and
8 * Niels Provos (provos@physnet.uni-hamburg.de). 8 * Niels Provos (provos@physnet.uni-hamburg.de).
9 * 9 *
10 * The original version of this code was written by John Ioannidis 10 * The original version of this code was written by John Ioannidis
11 * for BSD/OS in Athens, Greece, in November 1995. 11 * for BSD/OS in Athens, Greece, in November 1995.
12 * 12 *
13 * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996, 13 * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
14 * by Angelos D. Keromytis. 14 * by Angelos D. Keromytis.
@@ -29,27 +29,27 @@ @@ -29,27 +29,27 @@
29 * You may use this code under the GNU public license if you so wish. Please 29 * You may use this code under the GNU public license if you so wish. Please
30 * contribute changes back to the authors under this freer than GPL license 30 * contribute changes back to the authors under this freer than GPL license
31 * so that we may further the use of strong encryption without limitations to 31 * so that we may further the use of strong encryption without limitations to
32 * all. 32 * all.
33 * 33 *
34 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR 34 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
35 * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY 35 * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
36 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE 36 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
37 * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR 37 * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
38 * PURPOSE. 38 * PURPOSE.
39 */ 39 */
40 40
41#include <sys/cdefs.h> 41#include <sys/cdefs.h>
42__KERNEL_RCSID(0, "$NetBSD: xform_ipip.c,v 1.26 2011/02/18 20:40:58 drochner Exp $"); 42__KERNEL_RCSID(0, "$NetBSD: xform_ipip.c,v 1.27 2011/06/06 16:48:35 drochner Exp $");
43 43
44/* 44/*
45 * IP-inside-IP processing 45 * IP-inside-IP processing
46 */ 46 */
47#include "opt_inet.h" 47#include "opt_inet.h"
48#ifdef __FreeBSD__ 48#ifdef __FreeBSD__
49#include "opt_inet6.h" 49#include "opt_inet6.h"
50#include "opt_random_ip_id.h" 50#include "opt_random_ip_id.h"
51#endif /* __FreeBSD__ */ 51#endif /* __FreeBSD__ */
52 52
53 53
54#include <sys/param.h> 54#include <sys/param.h>
55#include <sys/systm.h> 55#include <sys/systm.h>
@@ -193,27 +193,26 @@ ip4_input(struct mbuf *m, ...) @@ -193,27 +193,26 @@ ip4_input(struct mbuf *m, ...)
193static void 193static void
194_ipip_input(struct mbuf *m, int iphlen, struct ifnet *gifp) 194_ipip_input(struct mbuf *m, int iphlen, struct ifnet *gifp)
195{ 195{
196 register struct sockaddr_in *sin; 196 register struct sockaddr_in *sin;
197 register struct ifnet *ifp; 197 register struct ifnet *ifp;
198 register struct ifaddr *ifa; 198 register struct ifaddr *ifa;
199 struct ifqueue *ifq = NULL; 199 struct ifqueue *ifq = NULL;
200 struct ip *ipo; 200 struct ip *ipo;
201#ifdef INET6 201#ifdef INET6
202 register struct sockaddr_in6 *sin6; 202 register struct sockaddr_in6 *sin6;
203 struct ip6_hdr *ip6 = NULL; 203 struct ip6_hdr *ip6 = NULL;
204 u_int8_t itos; 204 u_int8_t itos;
205#endif 205#endif
206 u_int8_t nxt; 
207 int isr; 206 int isr;
208 u_int8_t otos; 207 u_int8_t otos;
209 u_int8_t v; 208 u_int8_t v;
210 int hlen; 209 int hlen;
211 210
212 IPIP_STATINC(IPIP_STAT_IPACKETS); 211 IPIP_STATINC(IPIP_STAT_IPACKETS);
213 212
214 m_copydata(m, 0, 1, &v); 213 m_copydata(m, 0, 1, &v);
215 214
216 switch (v >> 4) { 215 switch (v >> 4) {
217#ifdef INET 216#ifdef INET
218 case 4: 217 case 4:
219 hlen = sizeof(struct ip); 218 hlen = sizeof(struct ip);
@@ -312,34 +311,32 @@ _ipip_input(struct mbuf *m, int iphlen,  @@ -312,34 +311,32 @@ _ipip_input(struct mbuf *m, int iphlen,
312 } 311 }
313 312
314 /* 313 /*
315 * RFC 1853 specifies that the inner TTL should not be touched on 314 * RFC 1853 specifies that the inner TTL should not be touched on
316 * decapsulation. There's no reason this comment should be here, but 315 * decapsulation. There's no reason this comment should be here, but
317 * this is as good as any a position. 316 * this is as good as any a position.
318 */ 317 */
319 318
320 /* Some sanity checks in the inner IP header */ 319 /* Some sanity checks in the inner IP header */
321 switch (v >> 4) { 320 switch (v >> 4) {
322#ifdef INET 321#ifdef INET
323 case 4: 322 case 4:
324 ipo = mtod(m, struct ip *); 323 ipo = mtod(m, struct ip *);
325 nxt = ipo->ip_p; 
326 ip_ecn_egress(ip4_ipsec_ecn, &otos, &ipo->ip_tos); 324 ip_ecn_egress(ip4_ipsec_ecn, &otos, &ipo->ip_tos);
327 break; 325 break;
328#endif /* INET */ 326#endif /* INET */
329#ifdef INET6 327#ifdef INET6
330 case 6: 328 case 6:
331 ip6 = (struct ip6_hdr *) ipo; 329 ip6 = (struct ip6_hdr *) ipo;
332 nxt = ip6->ip6_nxt; 
333 itos = (ntohl(ip6->ip6_flow) >> 20) & 0xff; 330 itos = (ntohl(ip6->ip6_flow) >> 20) & 0xff;
334 ip_ecn_egress(ip6_ipsec_ecn, &otos, &itos); 331 ip_ecn_egress(ip6_ipsec_ecn, &otos, &itos);
335 ip6->ip6_flow &= ~htonl(0xff << 20); 332 ip6->ip6_flow &= ~htonl(0xff << 20);
336 ip6->ip6_flow |= htonl((u_int32_t) itos << 20); 333 ip6->ip6_flow |= htonl((u_int32_t) itos << 20);
337 break; 334 break;
338#endif 335#endif
339 default: 336 default:
340 panic("ipip_input: unknown ip version %u (inner)", v>>4); 337 panic("ipip_input: unknown ip version %u (inner)", v>>4);
341 } 338 }
342 339
343 /* Check for local address spoofing. */ 340 /* Check for local address spoofing. */
344 if ((m->m_pkthdr.rcvif == NULL || 341 if ((m->m_pkthdr.rcvif == NULL ||
345 !(m->m_pkthdr.rcvif->if_flags & IFF_LOOPBACK)) && 342 !(m->m_pkthdr.rcvif->if_flags & IFF_LOOPBACK)) &&
@@ -539,50 +536,56 @@ ipip_output( @@ -539,50 +536,56 @@ ipip_output(
539 case AF_INET6: 536 case AF_INET6:
540 if (IN6_IS_ADDR_UNSPECIFIED(&saidx->dst.sin6.sin6_addr) || 537 if (IN6_IS_ADDR_UNSPECIFIED(&saidx->dst.sin6.sin6_addr) ||
541 saidx->src.sa.sa_family != AF_INET6 || 538 saidx->src.sa.sa_family != AF_INET6 ||
542 IN6_IS_ADDR_UNSPECIFIED(&saidx->src.sin6.sin6_addr)) { 539 IN6_IS_ADDR_UNSPECIFIED(&saidx->src.sin6.sin6_addr)) {
543 DPRINTF(("ipip_output: unspecified tunnel endpoint " 540 DPRINTF(("ipip_output: unspecified tunnel endpoint "
544 "address in SA %s/%08lx\n", 541 "address in SA %s/%08lx\n",
545 ipsec_address(&saidx->dst), 542 ipsec_address(&saidx->dst),
546 (u_long) ntohl(sav->spi))); 543 (u_long) ntohl(sav->spi)));
547 IPIP_STATINC(IPIP_STAT_UNSPEC); 544 IPIP_STATINC(IPIP_STAT_UNSPEC);
548 error = ENOBUFS; 545 error = ENOBUFS;
549 goto bad; 546 goto bad;
550 } 547 }
551 548
552 /* scoped address handling */ 549 if (tp == (IPV6_VERSION >> 4)) {
553 ip6 = mtod(m, struct ip6_hdr *); 550 /* scoped address handling */
554 if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src)) 551 ip6 = mtod(m, struct ip6_hdr *);
555 ip6->ip6_src.s6_addr16[1] = 0; 552 if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src))
556 if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst)) 553 ip6->ip6_src.s6_addr16[1] = 0;
557 ip6->ip6_dst.s6_addr16[1] = 0; 554 if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst))
 555 ip6->ip6_dst.s6_addr16[1] = 0;
 556 }
558 557
559 M_PREPEND(m, sizeof(struct ip6_hdr), M_DONTWAIT); 558 M_PREPEND(m, sizeof(struct ip6_hdr), M_DONTWAIT);
560 if (m == 0) { 559 if (m == 0) {
561 DPRINTF(("ipip_output: M_PREPEND failed\n")); 560 DPRINTF(("ipip_output: M_PREPEND failed\n"));
562 IPIP_STATINC(IPIP_STAT_HDROPS); 561 IPIP_STATINC(IPIP_STAT_HDROPS);
563 error = ENOBUFS; 562 error = ENOBUFS;
564 goto bad; 563 goto bad;
565 } 564 }
566 565
567 /* Initialize IPv6 header */ 566 /* Initialize IPv6 header */
568 ip6o = mtod(m, struct ip6_hdr *); 567 ip6o = mtod(m, struct ip6_hdr *);
569 ip6o->ip6_flow = 0; 568 ip6o->ip6_flow = 0;
570 ip6o->ip6_vfc &= ~IPV6_VERSION_MASK; 569 ip6o->ip6_vfc &= ~IPV6_VERSION_MASK;
571 ip6o->ip6_vfc |= IPV6_VERSION; 570 ip6o->ip6_vfc |= IPV6_VERSION;
572 ip6o->ip6_plen = htons(m->m_pkthdr.len); 571 ip6o->ip6_plen = htons(m->m_pkthdr.len);
573 ip6o->ip6_hlim = ip_defttl; 572 ip6o->ip6_hlim = ip_defttl;
574 ip6o->ip6_dst = saidx->dst.sin6.sin6_addr; 573 ip6o->ip6_dst = saidx->dst.sin6.sin6_addr;
575 ip6o->ip6_src = saidx->src.sin6.sin6_addr; 574 ip6o->ip6_src = saidx->src.sin6.sin6_addr;
 575 if (IN6_IS_SCOPE_LINKLOCAL(&ip6o->ip6_dst))
 576 ip6o->ip6_dst.s6_addr16[1] = htons(saidx->dst.sin6.sin6_scope_id);
 577 if (IN6_IS_SCOPE_LINKLOCAL(&ip6o->ip6_src))
 578 ip6o->ip6_src.s6_addr16[1] = htons(saidx->src.sin6.sin6_scope_id);
576 579
577#ifdef INET 580#ifdef INET
578 if (tp == IPVERSION) { 581 if (tp == IPVERSION) {
579 /* Save ECN notification */ 582 /* Save ECN notification */
580 m_copydata(m, sizeof(struct ip6_hdr) + 583 m_copydata(m, sizeof(struct ip6_hdr) +
581 offsetof(struct ip, ip_tos), sizeof(u_int8_t), 584 offsetof(struct ip, ip_tos), sizeof(u_int8_t),
582 &itos); 585 &itos);
583 586
584 /* This is really IPVERSION. */ 587 /* This is really IPVERSION. */
585 ip6o->ip6_nxt = IPPROTO_IPIP; 588 ip6o->ip6_nxt = IPPROTO_IPIP;
586 } else 589 } else
587#endif /* INET */ 590#endif /* INET */
588 if (tp == (IPV6_VERSION >> 4)) { 591 if (tp == (IPV6_VERSION >> 4)) {
@@ -626,27 +629,27 @@ nofamily: @@ -626,27 +629,27 @@ nofamily:
626#endif 629#endif
627 IPIP_STATADD(IPIP_STAT_OBYTES, 630 IPIP_STATADD(IPIP_STAT_OBYTES,
628 m->m_pkthdr.len - sizeof(struct ip)); 631 m->m_pkthdr.len - sizeof(struct ip));
629 } 632 }
630#endif /* INET */ 633#endif /* INET */
631 634
632#ifdef INET6 635#ifdef INET6
633 if (saidx->dst.sa.sa_family == AF_INET6) { 636 if (saidx->dst.sa.sa_family == AF_INET6) {
634#if 0 637#if 0
635 if (sav->tdb_xform->xf_type == XF_IP4) 638 if (sav->tdb_xform->xf_type == XF_IP4)
636 tdb->tdb_cur_bytes += 639 tdb->tdb_cur_bytes +=
637 m->m_pkthdr.len - sizeof(struct ip6_hdr); 640 m->m_pkthdr.len - sizeof(struct ip6_hdr);
638#endif 641#endif
639 IPIP_STATADD(IPIP_STAT_IBYTES, 642 IPIP_STATADD(IPIP_STAT_OBYTES,
640 m->m_pkthdr.len - sizeof(struct ip6_hdr)); 643 m->m_pkthdr.len - sizeof(struct ip6_hdr));
641 } 644 }
642#endif /* INET6 */ 645#endif /* INET6 */
643 646
644 return 0; 647 return 0;
645bad: 648bad:
646 if (m) 649 if (m)
647 m_freem(m); 650 m_freem(m);
648 *mp = NULL; 651 *mp = NULL;
649 return (error); 652 return (error);
650} 653}
651 654
652#ifdef FAST_IPSEC 655#ifdef FAST_IPSEC