Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys add patch from Arnaud Degroote to handle IPv6 extended o...
details: https://anonhg.NetBSD.org/src/rev/799c34573206
branches: trunk
changeset: 772654:799c34573206
user: drochner <drochner%NetBSD.org@localhost>
date: Tue Jan 10 20:01:56 2012 +0000
description:
add patch from Arnaud Degroote to handle IPv6 extended options with
(FAST_)IPSEC, tested lightly with a DSTOPTS header consisting
of PAD1
diffstat:
sys/netinet6/ip6_input.c | 11 +++---
sys/netinet6/ip6_output.c | 30 ++++-------------
sys/netinet6/ip6_var.h | 5 +-
sys/netipsec/ipsec_output.c | 75 ++++++++++++++++++++++++++++++++++++++++++--
sys/netipsec/xform_ah.c | 70 ++++++++++++++++++++++++++++++++---------
5 files changed, 141 insertions(+), 50 deletions(-)
diffs (truncated from 366 to 300 lines):
diff -r 12f3c3fc5158 -r 799c34573206 sys/netinet6/ip6_input.c
--- a/sys/netinet6/ip6_input.c Tue Jan 10 18:55:37 2012 +0000
+++ b/sys/netinet6/ip6_input.c Tue Jan 10 20:01:56 2012 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ip6_input.c,v 1.135 2011/12/31 20:41:59 christos Exp $ */
+/* $NetBSD: ip6_input.c,v 1.136 2012/01/10 20:01:56 drochner Exp $ */
/* $KAME: ip6_input.c,v 1.188 2001/03/29 05:34:31 itojun Exp $ */
/*
@@ -62,7 +62,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip6_input.c,v 1.135 2011/12/31 20:41:59 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip6_input.c,v 1.136 2012/01/10 20:01:56 drochner Exp $");
#include "opt_gateway.h"
#include "opt_inet.h"
@@ -161,7 +161,8 @@
static void ip6_init2(void *);
static struct m_tag *ip6_setdstifaddr(struct mbuf *, const struct in6_ifaddr *);
-static int ip6_hopopts_input(u_int32_t *, u_int32_t *, struct mbuf **, int *);
+static int ip6_process_hopopts(struct mbuf *, u_int8_t *, int, u_int32_t *,
+ u_int32_t *);
static struct mbuf *ip6_pullexthdr(struct mbuf *, size_t, int);
static void sysctl_net_inet6_ip6_setup(struct sysctllog **);
@@ -882,7 +883,7 @@
*
* rtalertp - XXX: should be stored more smart way
*/
-static int
+int
ip6_hopopts_input(u_int32_t *plenp, u_int32_t *rtalertp,
struct mbuf **mp, int *offp)
{
@@ -927,7 +928,7 @@
* (RFC2460 p7), opthead is pointer into data content in m, and opthead to
* opthead + hbhlen is located in continuous memory region.
*/
-int
+static int
ip6_process_hopopts(struct mbuf *m, u_int8_t *opthead, int hbhlen,
u_int32_t *rtalertp, u_int32_t *plenp)
{
diff -r 12f3c3fc5158 -r 799c34573206 sys/netinet6/ip6_output.c
--- a/sys/netinet6/ip6_output.c Tue Jan 10 18:55:37 2012 +0000
+++ b/sys/netinet6/ip6_output.c Tue Jan 10 20:01:56 2012 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ip6_output.c,v 1.142 2011/12/31 20:41:59 christos Exp $ */
+/* $NetBSD: ip6_output.c,v 1.143 2012/01/10 20:01:56 drochner Exp $ */
/* $KAME: ip6_output.c,v 1.172 2001/03/25 09:55:56 itojun Exp $ */
/*
@@ -62,7 +62,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip6_output.c,v 1.142 2011/12/31 20:41:59 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip6_output.c,v 1.143 2012/01/10 20:01:56 drochner Exp $");
#include "opt_inet.h"
#include "opt_inet6.h"
@@ -317,10 +317,6 @@
#ifdef FAST_IPSEC
/* Check the security policy (SP) for the packet */
- /* XXX For moment, we doesn't support packet with extented action */
- if (optlen !=0)
- goto freehdrs;
-
sp = ipsec6_check_policy(m,so,flags,&needipsec,&error);
if (error != 0) {
/*
@@ -858,28 +854,18 @@
* it must be examined and processed even by the source node.
* (RFC 2460, section 4.)
*/
- if (exthdrs.ip6e_hbh) {
- struct ip6_hbh *hbh = mtod(exthdrs.ip6e_hbh, struct ip6_hbh *);
+ if (ip6->ip6_nxt == IPV6_HOPOPTS) {
u_int32_t dummy1; /* XXX unused */
u_int32_t dummy2; /* XXX unused */
-
- /*
- * XXX: if we have to send an ICMPv6 error to the sender,
- * we need the M_LOOP flag since icmp6_error() expects
- * the IPv6 and the hop-by-hop options header are
- * continuous unless the flag is set.
- */
- m->m_flags |= M_LOOP;
- m->m_pkthdr.rcvif = ifp;
- if (ip6_process_hopopts(m, (u_int8_t *)(hbh + 1),
- ((hbh->ip6h_len + 1) << 3) - sizeof(struct ip6_hbh),
- &dummy1, &dummy2) < 0) {
+ int hoff = sizeof(struct ip6_hdr);
+
+ if (ip6_hopopts_input(&dummy1, &dummy2, &m, &hoff)) {
/* m was already freed at this point */
error = EINVAL;/* better error? */
goto done;
}
- m->m_flags &= ~M_LOOP; /* XXX */
- m->m_pkthdr.rcvif = NULL;
+
+ ip6 = mtod(m, struct ip6_hdr *);
}
#ifdef PFIL_HOOKS
diff -r 12f3c3fc5158 -r 799c34573206 sys/netinet6/ip6_var.h
--- a/sys/netinet6/ip6_var.h Tue Jan 10 18:55:37 2012 +0000
+++ b/sys/netinet6/ip6_var.h Tue Jan 10 20:01:56 2012 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ip6_var.h,v 1.56 2011/11/04 00:22:33 zoltan Exp $ */
+/* $NetBSD: ip6_var.h,v 1.57 2012/01/10 20:01:56 drochner Exp $ */
/* $KAME: ip6_var.h,v 1.33 2000/06/11 14:59:20 jinmei Exp $ */
/*
@@ -327,8 +327,7 @@
void ip6_delaux(struct mbuf *);
int ip6_mforward(struct ip6_hdr *, struct ifnet *, struct mbuf *);
-int ip6_process_hopopts(struct mbuf *, u_int8_t *, int, u_int32_t *,
- u_int32_t *);
+int ip6_hopopts_input(u_int32_t *, u_int32_t *, struct mbuf **, int *);
void ip6_savecontrol(struct in6pcb *, struct mbuf **, struct ip6_hdr *,
struct mbuf *);
void ip6_notify_pmtu(struct in6pcb *, const struct sockaddr_in6 *,
diff -r 12f3c3fc5158 -r 799c34573206 sys/netipsec/ipsec_output.c
--- a/sys/netipsec/ipsec_output.c Tue Jan 10 18:55:37 2012 +0000
+++ b/sys/netipsec/ipsec_output.c Tue Jan 10 20:01:56 2012 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ipsec_output.c,v 1.37 2011/08/31 18:31:03 plunky Exp $ */
+/* $NetBSD: ipsec_output.c,v 1.38 2012/01/10 20:01:57 drochner Exp $ */
/*-
* Copyright (c) 2002, 2003 Sam Leffler, Errno Consulting
@@ -29,7 +29,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ipsec_output.c,v 1.37 2011/08/31 18:31:03 plunky Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ipsec_output.c,v 1.38 2012/01/10 20:01:57 drochner Exp $");
/*
* IPsec output processing.
@@ -632,6 +632,74 @@
#endif
#ifdef INET6
+static void
+compute_ipsec_pos(struct mbuf *m, int *i, int *off)
+{
+ int nxt;
+ struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr*);
+ struct ip6_ext ip6e;
+ int dstopt = 0;
+
+ *i = sizeof(struct ip6_hdr);
+ *off = offsetof(struct ip6_hdr, ip6_nxt);
+ nxt = ip6->ip6_nxt;
+
+ /*
+ * chase mbuf chain to find the appropriate place to
+ * put AH/ESP/IPcomp header.
+ * IPv6 hbh dest1 rthdr ah* [esp* dest2 payload]
+ */
+ do {
+ switch (nxt) {
+ case IPPROTO_AH:
+ case IPPROTO_ESP:
+ case IPPROTO_IPCOMP:
+ /*
+ * we should not skip security header added
+ * beforehand.
+ */
+ return;
+
+ case IPPROTO_HOPOPTS:
+ case IPPROTO_DSTOPTS:
+ case IPPROTO_ROUTING:
+ /*
+ * if we see 2nd destination option header,
+ * we should stop there.
+ */
+ if (nxt == IPPROTO_DSTOPTS && dstopt)
+ return;
+
+ if (nxt == IPPROTO_DSTOPTS) {
+ /*
+ * seen 1st or 2nd destination option.
+ * next time we see one, it must be 2nd.
+ */
+ dstopt = 1;
+ } else if (nxt == IPPROTO_ROUTING) {
+ /*
+ * if we see destionation option next
+ * time, it must be dest2.
+ */
+ dstopt = 2;
+ }
+
+ /* skip this header */
+ m_copydata(m, *i, sizeof(ip6e), &ip6e);
+ nxt = ip6e.ip6e_nxt;
+ *off = *i + offsetof(struct ip6_ext, ip6e_nxt);
+ /*
+ * we will never see nxt == IPPROTO_AH
+ * so it is safe to omit AH case.
+ */
+ *i += (ip6e.ip6e_len + 1) << 3;
+ break;
+ default:
+ return;
+ }
+ } while (*i < m->m_pkthdr.len);
+}
+
static int
in6_sa_equal_addrwithscope(const struct sockaddr_in6 *sa, const struct in6_addr *ia)
{
@@ -731,8 +799,7 @@
i = ip->ip_hl << 2;
off = offsetof(struct ip, ip_p);
} else {
- i = sizeof(struct ip6_hdr);
- off = offsetof(struct ip6_hdr, ip6_nxt);
+ compute_ipsec_pos(m, &i, &off);
}
error = (*sav->tdb_xform->xf_output)(m, isr, NULL, i, off);
splx(s);
diff -r 12f3c3fc5158 -r 799c34573206 sys/netipsec/xform_ah.c
--- a/sys/netipsec/xform_ah.c Tue Jan 10 18:55:37 2012 +0000
+++ b/sys/netipsec/xform_ah.c Tue Jan 10 20:01:56 2012 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: xform_ah.c,v 1.33 2011/05/24 19:10:08 drochner Exp $ */
+/* $NetBSD: xform_ah.c,v 1.34 2012/01/10 20:01:57 drochner Exp $ */
/* $FreeBSD: src/sys/netipsec/xform_ah.c,v 1.1.4.1 2003/01/24 05:11:36 sam Exp $ */
/* $OpenBSD: ip_ah.c,v 1.63 2001/06/26 06:18:58 angelos Exp $ */
/*
@@ -39,7 +39,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xform_ah.c,v 1.33 2011/05/24 19:10:08 drochner Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xform_ah.c,v 1.34 2012/01/10 20:01:57 drochner Exp $");
#include "opt_inet.h"
#ifdef __FreeBSD__
@@ -72,6 +72,7 @@
#ifdef INET6
#include <netinet6/ip6_var.h>
+#include <netinet6/scope6_var.h>
#include <netipsec/ipsec6.h>
# ifdef __FreeBSD__
# include <netinet6/ip6_ecn.h>
@@ -279,7 +280,7 @@
#ifdef INET6
struct ip6_ext *ip6e;
struct ip6_hdr ip6;
- int alloc, len, ad;
+ int alloc, ad, nxt;
#endif /* INET6 */
switch (proto) {
@@ -501,28 +502,28 @@
} else
break;
- off = ip6.ip6_nxt & 0xff; /* Next header type. */
+ nxt = ip6.ip6_nxt & 0xff; /* Next header type. */
- for (len = 0; len < skip - sizeof(struct ip6_hdr);)
- switch (off) {
+ for (off = 0; off < skip - sizeof(struct ip6_hdr);)
+ switch (nxt) {
case IPPROTO_HOPOPTS:
case IPPROTO_DSTOPTS:
- ip6e = (struct ip6_ext *) (ptr + len);
+ ip6e = (struct ip6_ext *) (ptr + off);
/*
* Process the mutable/immutable
* options -- borrows heavily from the
* KAME code.
*/
- for (count = len + sizeof(struct ip6_ext);
- count < len + ((ip6e->ip6e_len + 1) << 3);) {
+ for (count = off + sizeof(struct ip6_ext);
+ count < off + ((ip6e->ip6e_len + 1) << 3);) {
if (ptr[count] == IP6OPT_PAD1) {
count++;
continue; /* Skip padding. */
}
/* Sanity check. */
- if (count > len +
+ if (count > off +
Home |
Main Index |
Thread Index |
Old Index