netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Mitsuru KANDA / 神田 充" <mk@linux-ipv6.org>
To: "David S. Miller" <davem@redhat.com>
Cc: jmorris@intercode.com.au, kuznet@ms2.inr.ac.ru,
	netdev@oss.sgi.com, usagi@linux-ipv6.org
Subject: [PATCH] xfrm ip6ip6 (revised)
Date: Sat, 14 Jun 2003 01:03:50 +0900	[thread overview]
Message-ID: <87smqerml5.wl@karaba.org> (raw)
In-Reply-To: <20030601.013040.116362760.davem@redhat.com>

Hello,

I recreated a xfrm ip6ip6 patch.
The changes to the previous patch are:
	- to allocate unique spi values in xfrm6_tunnel.c  
	  by using just simple open addressing hash, 
	- to introduce device-like ip6ip6 handling, and
	- to fix some bugs.

This patch is against CS1.1304.

Chould you check this?

Regards,
-mk

At Sun, 01 Jun 2003 01:30:40 -0700 (PDT),
"David S. Miller" <davem@redhat.com> wrote:
(snipped)
> I would suggest following implementation:
> 
> 1) Implement something similar to xfrm_alloc_spi(t, 1, ~(u32)0)
> 
>    It just needs to allocate unique SPI numbers local to
>    xfrm6_tunnel.c   We mark "SPI" value zero as reserved and
>    to indicate failed lookup.
> 
> 2) Create hash table, it is keyed by ipv6 address and hash table
>    entries give SPI values.
> 
> So on input you would say something like:
> 
> 	u32 spi;
> 
> 	spi = spihash_lookup(&iph->saddr);
> 	if (!spi)
> 		goto drop;
> 	x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, spi,
> 			      IPPROTO_IPV6, AF_INET6);
(snipped)


Index: linux25-XFRM6_TUNNEL-20030612/include/net/xfrm.h
===================================================================
RCS file: /cvsroot/usagi/usagi-backport/linux25/include/net/xfrm.h,v
retrieving revision 1.1.1.25
retrieving revision 1.1.1.25.2.1
diff -u -r1.1.1.25 -r1.1.1.25.2.1
--- linux25-XFRM6_TUNNEL-20030612/include/net/xfrm.h	10 Jun 2003 13:21:39 -0000	1.1.1.25
+++ linux25-XFRM6_TUNNEL-20030612/include/net/xfrm.h	12 Jun 2003 15:30:16 -0000	1.1.1.25.2.1
@@ -494,10 +494,6 @@
 	return 0;
 }
 
-/* placeholder until xfrm6_tunnel.c is written */
-static inline int xfrm6_tunnel_check_size(struct sk_buff *skb)
-{ return 0; }
-
 /* A struct encoding bundle of transformations to apply to some set of flow.
  *
  * dst->child points to the next element of bundle.
@@ -748,6 +744,12 @@
 	void (*err_handler)(struct sk_buff *skb, void *info);
 };
 
+struct xfrm6_tunnel {
+	int (*handler)(struct sk_buff **pskb, unsigned int *nhoffp);
+	void (*err_handler)(struct sk_buff *skb, struct inet6_skb_parm *opt,
+			    int type, int code, int offset, __u32 info);
+};
+
 extern void xfrm_init(void);
 extern void xfrm4_init(void);
 extern void xfrm4_fini(void);
@@ -781,6 +783,11 @@
 extern int xfrm4_tunnel_register(struct xfrm_tunnel *handler);
 extern int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler);
 extern int xfrm4_tunnel_check_size(struct sk_buff *skb);
+extern int xfrm6_tunnel_register(struct xfrm6_tunnel *handler);
+extern int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler);
+extern int xfrm6_tunnel_check_size(struct sk_buff *skb);
+extern u32 xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr);
+extern u32 xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr);
 extern int xfrm6_rcv(struct sk_buff **pskb, unsigned int *nhoffp);
 extern int xfrm6_clear_mutable_options(struct sk_buff *skb, u16 *nh_offset, int dir);
 extern int xfrm_user_policy(struct sock *sk, int optname, u8 *optval, int optlen);
Index: linux25-XFRM6_TUNNEL-20030612/net/ipv6/Makefile
===================================================================
RCS file: /cvsroot/usagi/usagi-backport/linux25/net/ipv6/Makefile,v
retrieving revision 1.1.1.13
retrieving revision 1.1.1.13.2.1
diff -u -r1.1.1.13 -r1.1.1.13.2.1
--- linux25-XFRM6_TUNNEL-20030612/net/ipv6/Makefile	10 Jun 2003 13:21:55 -0000	1.1.1.13
+++ linux25-XFRM6_TUNNEL-20030612/net/ipv6/Makefile	12 Jun 2003 15:29:53 -0000	1.1.1.13.2.1
@@ -9,7 +9,7 @@
 		protocol.o icmp.o mcast.o reassembly.o tcp_ipv6.o \
 		exthdrs.o sysctl_net_ipv6.o datagram.o proc.o \
 		ip6_flowlabel.o ipv6_syms.o \
-		xfrm6_policy.o xfrm6_state.o xfrm6_input.o
+		xfrm6_policy.o xfrm6_state.o xfrm6_input.o xfrm6_tunnel.o
 
 obj-$(CONFIG_INET6_AH) += ah6.o
 obj-$(CONFIG_INET6_ESP) += esp6.o
Index: linux25-XFRM6_TUNNEL-20030612/net/ipv6/ip6_tunnel.c
===================================================================
RCS file: /cvsroot/usagi/usagi-backport/linux25/net/ipv6/ip6_tunnel.c,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.2.1
diff -u -r1.1.1.1 -r1.1.1.1.2.1
--- linux25-XFRM6_TUNNEL-20030612/net/ipv6/ip6_tunnel.c	10 Jun 2003 13:21:55 -0000	1.1.1.1
+++ linux25-XFRM6_TUNNEL-20030612/net/ipv6/ip6_tunnel.c	12 Jun 2003 15:29:53 -0000	1.1.1.1.2.1
@@ -48,6 +48,7 @@
 #include <net/ip6_route.h>
 #include <net/addrconf.h>
 #include <net/ip6_tunnel.h>
+#include <net/xfrm.h>
 
 MODULE_AUTHOR("Ville Nuorvala");
 MODULE_DESCRIPTION("IPv6-in-IPv6 tunnel");
@@ -1174,10 +1175,9 @@
 	return 0;
 }
 
-static struct inet6_protocol ip6ip6_protocol = {
+static struct xfrm_tunnel ip6ip6_handler = {
 	.handler = ip6ip6_rcv,
 	.err_handler = ip6ip6_err,
-	.flags = INET6_PROTO_FINAL
 };
 
 /**
@@ -1192,6 +1192,11 @@
 	struct sock *sk;
 	struct ipv6_pinfo *np;
 
+	if (xfrm6_tunnel_register(&ip6ip6_handler) < 0) {
+		printk(KERN_INFO "ip6ip6 init: can't register tunnel\n");
+		return -EAGAIN;
+	}
+
 	ip6ip6_fb_tnl_dev.priv = (void *) &ip6ip6_fb_tnl;
 
 	for (i = 0; i < NR_CPUS; i++) {
@@ -1216,10 +1221,6 @@
 
 		sk->sk_prot->unhash(sk);
 	}
-	if ((err = inet6_add_protocol(&ip6ip6_protocol, IPPROTO_IPV6)) < 0) {
-		printk(KERN_ERR "Failed to register IPv6 protocol\n");
-		goto fail;
-	}
 
 	SET_MODULE_OWNER(&ip6ip6_fb_tnl_dev);
 	register_netdev(&ip6ip6_fb_tnl_dev);
@@ -1243,9 +1244,10 @@
 {
 	int i;
 
-	unregister_netdev(&ip6ip6_fb_tnl_dev);
+	if (xfrm6_tunnel_deregister(&ip6ip6_handler) < 0)
+		printk(KERN_INFO "ip6ip6 close: can't deregister tunnel\n");
 
-	inet6_del_protocol(&ip6ip6_protocol, IPPROTO_IPV6);
+	unregister_netdev(&ip6ip6_fb_tnl_dev);
 
 	for (i = 0; i < NR_CPUS; i++) {
 		if (!cpu_possible(i))
Index: linux25-XFRM6_TUNNEL-20030612/net/ipv6/ipcomp6.c
===================================================================
RCS file: /cvsroot/usagi/usagi-backport/linux25/net/ipv6/ipcomp6.c,v
retrieving revision 1.1.1.3
diff -u -r1.1.1.3 ipcomp6.c
--- linux25-XFRM6_TUNNEL-20030612/net/ipv6/ipcomp6.c	10 Jun 2003 13:21:54 -0000	1.1.1.3
+++ linux25-XFRM6_TUNNEL-20030612/net/ipv6/ipcomp6.c	13 Jun 2003 09:44:59 -0000
@@ -254,6 +254,66 @@
 	xfrm_state_put(x);
 }
 
+static struct xfrm_state *ipcomp6_tunnel_create(struct xfrm_state *x)
+{
+	struct xfrm_state *t = NULL;
+
+	t = xfrm_state_alloc();
+	if (!t)
+		goto out;
+
+	t->id.proto = IPPROTO_IPV6;
+	t->id.spi = xfrm6_tunnel_alloc_spi((xfrm_address_t *)&x->props.saddr);
+	memcpy(t->id.daddr.a6, x->id.daddr.a6, sizeof(struct in6_addr));
+	memcpy(&t->sel, &x->sel, sizeof(t->sel));
+	t->props.family = AF_INET6;
+	t->props.mode = 1;
+	memcpy(t->props.saddr.a6, x->props.saddr.a6, sizeof(struct in6_addr));
+
+	t->type = xfrm_get_type(IPPROTO_IPV6, t->props.family);
+	if (t->type == NULL)
+		goto error;
+
+	if (t->type->init_state(t, NULL))
+		goto error;
+
+	t->km.state = XFRM_STATE_VALID;
+	atomic_set(&t->tunnel_users, 1);
+
+out:
+	return t;
+
+error:
+	xfrm_state_put(t);
+	goto out;
+}
+
+static int ipcomp6_tunnel_attach(struct xfrm_state *x)
+{
+	int err = 0;
+	struct xfrm_state *t = NULL;
+	u32 spi;
+
+	spi = xfrm6_tunnel_spi_lookup((xfrm_address_t *)&x->props.saddr);
+	if (spi)
+		t = xfrm_state_lookup((xfrm_address_t *)&x->id.daddr,
+					      spi, IPPROTO_IPV6, AF_INET6);
+	if (!t) {
+		t = ipcomp6_tunnel_create(x);
+		if (!t) {
+			err = -EINVAL;
+			goto out;
+		}
+		xfrm_state_insert(t);
+		xfrm_state_hold(t);
+	}
+	x->tunnel = t;
+	atomic_inc(&t->tunnel_users);
+
+out:
+	return err;
+}
+
 static void ipcomp6_free_data(struct ipcomp_data *ipcd)
 {
 	if (ipcd->tfm)
@@ -292,6 +352,12 @@
 	ipcd->tfm = crypto_alloc_tfm(x->calg->alg_name, 0);
 	if (!ipcd->tfm)
 		goto error;
+
+	if (x->props.mode) {
+		err = ipcomp6_tunnel_attach(x);
+		if (err)
+			goto error;
+	}
 
 	calg_desc = xfrm_calg_get_byname(x->calg->alg_name);
 	BUG_ON(!calg_desc);
Index: linux25-XFRM6_TUNNEL-20030612/net/ipv6/ipv6_syms.c
===================================================================
RCS file: /cvsroot/usagi/usagi-backport/linux25/net/ipv6/ipv6_syms.c,v
retrieving revision 1.1.1.13
retrieving revision 1.1.1.13.2.1
diff -u -r1.1.1.13 -r1.1.1.13.2.1
--- linux25-XFRM6_TUNNEL-20030612/net/ipv6/ipv6_syms.c	10 Jun 2003 13:21:55 -0000	1.1.1.13
+++ linux25-XFRM6_TUNNEL-20030612/net/ipv6/ipv6_syms.c	12 Jun 2003 15:29:53 -0000	1.1.1.13.2.1
@@ -38,6 +38,11 @@
 EXPORT_SYMBOL(ip6_find_1stfragopt);
 EXPORT_SYMBOL(xfrm6_rcv);
 EXPORT_SYMBOL(xfrm6_clear_mutable_options);
+EXPORT_SYMBOL(xfrm6_tunnel_register);
+EXPORT_SYMBOL(xfrm6_tunnel_deregister);
+EXPORT_SYMBOL(xfrm6_tunnel_check_size);
+EXPORT_SYMBOL(xfrm6_tunnel_alloc_spi);
+EXPORT_SYMBOL(xfrm6_tunnel_spi_lookup);
 EXPORT_SYMBOL(rt6_lookup);
 EXPORT_SYMBOL(fl6_sock_lookup);
 EXPORT_SYMBOL(ipv6_ext_hdr);
Index: linux25-XFRM6_TUNNEL-20030612/net/ipv6/xfrm6_tunnel.c
===================================================================
RCS file: linux25-XFRM6_TUNNEL-20030612/net/ipv6/xfrm6_tunnel.c
diff -N linux25-XFRM6_TUNNEL-20030612/net/ipv6/xfrm6_tunnel.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ linux25-XFRM6_TUNNEL-20030612/net/ipv6/xfrm6_tunnel.c	13 Jun 2003 09:44:59 -0000
@@ -0,0 +1,380 @@
+/*
+ * Copyright (C)2003 USAGI/WIDE Project
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author	Mitsuru KANDA  <mk@linux-ipv6.org>
+ *
+ * Based on xfrm4_tunnel
+ *
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/xfrm.h>
+#include <net/ip.h>
+#include <net/xfrm.h>
+#include <net/icmp.h>
+#include <net/ipv6.h>
+#include <linux/ipv6.h>
+#include <linux/icmpv6.h>
+
+#define XFRM6_TUNNEL_HSIZE 1024
+/* note: we assume index of xfrm_tunnel_table[] == spi */
+static xfrm_address_t *xfrm6_tunnel_table[XFRM6_TUNNEL_HSIZE];
+
+static spinlock_t xfrm6_tunnel_lock = SPIN_LOCK_UNLOCKED;
+
+static unsigned xfrm6_addr_hash(xfrm_address_t *addr)
+{
+	unsigned h;
+	h = ntohl(addr->a6[0]^addr->a6[1]^addr->a6[2]^addr->a6[3]);
+	h = (h ^ (h>>16)) % XFRM6_TUNNEL_HSIZE;
+	return h;
+}
+
+static void xfrm6_tunnel_htable_init(void)
+{
+	int i;
+	for (i=0; i<XFRM6_TUNNEL_HSIZE; i++)
+		xfrm6_tunnel_table[i] = NULL;
+}
+
+u32 xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr)
+{
+	u32 spi = 0;
+	u32 index = xfrm6_addr_hash(saddr);
+	xfrm_address_t *index_addr;
+	int i;
+
+	spin_lock(&xfrm6_tunnel_lock);
+	for (i = index; i < XFRM6_TUNNEL_HSIZE; i++) {
+		index_addr = xfrm6_tunnel_table[i];
+		if (index_addr == NULL)
+			continue;
+		if (!memcmp(index_addr, saddr, sizeof(xfrm_address_t))) {
+			spi = htonl(i);
+			goto out;
+		}
+	}
+out:
+	spin_unlock(&xfrm6_tunnel_lock);
+	return spi;
+}
+
+u32 xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr)
+{
+	u32 spi = 0;
+	u32 index = xfrm6_addr_hash(saddr);
+	xfrm_address_t *index_addr;
+	int i;
+
+	spin_lock(&xfrm6_tunnel_lock);
+	for (i = index; i < XFRM6_TUNNEL_HSIZE; i++) {
+		if (xfrm6_tunnel_table[i] == NULL) {
+			index_addr = kmalloc(sizeof(xfrm_address_t), GFP_ATOMIC);
+			memcpy(index_addr, saddr, sizeof(xfrm_address_t));
+			xfrm6_tunnel_table[i] = index_addr;
+			spi = htonl(i);
+			goto out;
+		}
+	}
+
+out:
+	spin_unlock(&xfrm6_tunnel_lock);
+	return spi;
+}
+
+static void xfrm6_tunnel_free_spi(xfrm_address_t *saddr){
+	u32 index = ntohl(xfrm6_tunnel_spi_lookup(saddr));
+
+	if (index) {
+		spin_lock(&xfrm6_tunnel_lock);
+		kfree(xfrm6_tunnel_table[index]);
+		xfrm6_tunnel_table[index] = NULL;
+		spin_unlock(&xfrm6_tunnel_lock);
+	}
+}
+
+
+int xfrm6_tunnel_check_size(struct sk_buff *skb)
+{
+	int mtu, ret = 0;
+	struct dst_entry *dst = skb->dst;
+
+	mtu = dst_pmtu(dst) - sizeof(struct ipv6hdr);
+	if (mtu < IPV6_MIN_MTU)
+		mtu = IPV6_MIN_MTU;
+
+	if (skb->len > mtu) {
+		icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev);
+		ret = -EMSGSIZE;
+	}
+
+	return ret;
+}
+
+static int ip6ip6_output(struct sk_buff *skb)
+{
+	struct dst_entry *dst = skb->dst;
+	struct xfrm_state *x = dst->xfrm;
+	struct ipv6hdr *iph, *top_iph;
+	int err;
+
+	if ((err = xfrm6_tunnel_check_size(skb)) != 0)
+		goto error_nolock;
+
+	iph = skb->nh.ipv6h;
+
+	top_iph = (struct ipv6hdr *)skb_push(skb, x->props.header_len);
+	top_iph->version = 6;
+	top_iph->priority = iph->priority;
+	top_iph->flow_lbl[0] = iph->flow_lbl[0];
+	top_iph->flow_lbl[1] = iph->flow_lbl[1];
+	top_iph->flow_lbl[2] = iph->flow_lbl[2];
+	top_iph->nexthdr = IPPROTO_IPV6; 
+	top_iph->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
+	top_iph->hop_limit = iph->hop_limit;
+	ipv6_addr_copy(&top_iph->saddr, (struct in6_addr *)&x->props.saddr);
+	ipv6_addr_copy(&top_iph->daddr, (struct in6_addr *)&x->id.daddr);
+	skb->nh.raw = skb->data;
+	skb->h.raw = skb->nh.raw + sizeof(struct ipv6hdr);
+
+	x->curlft.bytes += skb->len;
+	x->curlft.packets++;
+
+	spin_unlock_bh(&x->lock);
+
+	if ((skb->dst = dst_pop(dst)) == NULL) { 
+		kfree_skb(skb);
+		err = -EHOSTUNREACH;
+		goto error_nolock;
+	}
+
+	return NET_XMIT_BYPASS;
+
+error_nolock:
+	kfree_skb(skb);
+	return err;
+}
+
+static int ip6ip6_xfrm_rcv(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_buff *skb)
+{
+	if (!pskb_may_pull(skb, sizeof(struct ipv6hdr))) 
+		return -EINVAL;
+
+	skb->mac.raw = skb->nh.raw;
+	skb->nh.raw = skb->data;
+	dst_release(skb->dst);
+	skb->dst = NULL;
+	skb->protocol = htons(ETH_P_IPV6);
+	skb->pkt_type = PACKET_HOST;
+	netif_rx(skb);
+
+	return 0;
+}
+
+static struct xfrm6_tunnel *ip6ip6_handler;
+static DECLARE_MUTEX(xfrm6_tunnel_sem);
+
+int xfrm6_tunnel_register(struct xfrm6_tunnel *handler)
+{
+	int ret;
+
+	down(&xfrm6_tunnel_sem);
+	ret = 0;
+	if (ip6ip6_handler != NULL)
+		ret = -EINVAL;
+	if (!ret)
+		ip6ip6_handler = handler;
+	up(&xfrm6_tunnel_sem);
+
+	return ret;
+}
+
+int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler)
+{
+	int ret;
+
+	down(&xfrm6_tunnel_sem);
+	ret = 0;
+	if (ip6ip6_handler != handler)
+	ret = -EINVAL;
+	if (!ret)
+		ip6ip6_handler = NULL;
+	up(&xfrm6_tunnel_sem);
+
+	synchronize_net();
+
+	return ret;
+}
+
+static int ip6ip6_rcv(struct sk_buff **pskb, unsigned int *nhoffp)
+{
+	struct sk_buff *skb = *pskb;
+	struct xfrm6_tunnel *handler = ip6ip6_handler;
+	struct xfrm_state *x = NULL;
+	struct ipv6hdr *iph = skb->nh.ipv6h;
+	int err = 0;
+	u32 spi;
+
+	/* device-like_ip6ip6_handler() */
+	if (handler) {
+		err = handler->handler(pskb, nhoffp);
+		if (!err)
+			goto out;
+	}
+
+	spi = xfrm6_tunnel_spi_lookup((xfrm_address_t *)&iph->saddr);
+	x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, 
+			spi,
+			IPPROTO_IPV6, AF_INET6);
+
+	if (!x)
+		goto drop;
+
+	spin_lock(&x->lock);
+
+	if (unlikely(x->km.state != XFRM_STATE_VALID))
+		goto drop_unlock;
+
+	err = ip6ip6_xfrm_rcv(x, NULL, skb);
+	if (err)
+		goto drop_unlock;
+
+	x->curlft.bytes += skb->len;
+	x->curlft.packets++; 
+	spin_unlock(&x->lock); 
+	xfrm_state_put(x); 
+
+out:
+	return 0;
+
+drop_unlock:
+	spin_unlock(&x->lock);
+	xfrm_state_put(x);
+drop:
+	kfree_skb(skb);
+
+	return -1;
+}
+
+static void ip6ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
+			int type, int code, int offset, __u32 info)
+{
+	struct xfrm6_tunnel *handler = ip6ip6_handler;
+
+	/* call here first for device-like ip6ip6 err handling */
+	if (handler) {
+		handler->err_handler(skb, opt, type, code, offset, info);
+		return;
+	}
+
+	/* xfrm ip6ip6 native err handling */
+	switch (type) {
+	case ICMPV6_DEST_UNREACH: 
+		switch (code) {
+		case ICMPV6_NOROUTE: 
+		case ICMPV6_ADM_PROHIBITED:
+		case ICMPV6_NOT_NEIGHBOUR:
+		case ICMPV6_ADDR_UNREACH:
+		case ICMPV6_PORT_UNREACH:
+		default:
+			printk(KERN_ERR "xfrm ip6ip6: Destination Unreach.\n");
+			break;
+		}
+		break;
+	case ICMPV6_PKT_TOOBIG:
+			printk(KERN_ERR "xfrm ip6ip6: Packet Too Big.\n");
+		break;
+	case ICMPV6_TIME_EXCEED:
+		switch (code) {
+		case ICMPV6_EXC_HOPLIMIT:
+			printk(KERN_ERR "xfrm ip6ip6: Too small Hoplimit.\n");
+			break;
+		case ICMPV6_EXC_FRAGTIME:
+		default: 
+			break;
+		}
+		break;
+	case ICMPV6_PARAMPROB:
+		switch (code) {
+		case ICMPV6_HDR_FIELD: break;
+		case ICMPV6_UNK_NEXTHDR: break;
+		case ICMPV6_UNK_OPTION: break;
+		}
+		break;
+	default:
+		break;
+	}
+	return;
+}
+
+static int ip6ip6_init_state(struct xfrm_state *x, void *args)
+{
+	if (!x->props.mode)
+		return -EINVAL;
+
+	x->props.header_len = sizeof(struct ipv6hdr);
+
+	return 0;
+}
+
+static void ip6ip6_destroy(struct xfrm_state *x)
+{
+	xfrm6_tunnel_free_spi((xfrm_address_t *)&x->props.saddr);
+}
+
+static struct xfrm_type ip6ip6_type = {
+	.description	= "IP6IP6",
+	.owner          = THIS_MODULE,
+	.proto		= IPPROTO_IPV6,
+	.init_state	= ip6ip6_init_state,
+	.destructor	= ip6ip6_destroy,
+	.input		= ip6ip6_xfrm_rcv,
+	.output		= ip6ip6_output,
+};
+
+static struct inet6_protocol ip6ip6_protocol = {
+	.handler	= ip6ip6_rcv,
+	.err_handler	= ip6ip6_err, 
+	.flags          = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
+};
+
+static int __init ip6ip6_init(void)
+{
+	if (xfrm_register_type(&ip6ip6_type, AF_INET6) < 0) {
+		printk(KERN_INFO "ip6ip6  init: can't add xfrm type\n");
+		return -EAGAIN;
+	}
+	if (inet6_add_protocol(&ip6ip6_protocol, IPPROTO_IPV6) < 0) {
+		printk(KERN_INFO "ip6ip6 init: can't add protocol\n");
+		xfrm_unregister_type(&ip6ip6_type, AF_INET6);
+		return -EAGAIN;
+	}
+	xfrm6_tunnel_htable_init();
+	return 0;
+}
+
+static void __exit ip6ip6_fini(void)
+{
+	if (inet6_del_protocol(&ip6ip6_protocol, IPPROTO_IPV6) < 0)
+		printk(KERN_INFO "ip6ip6 close: can't remove protocol\n");
+	if (xfrm_unregister_type(&ip6ip6_type, AF_INET6) < 0)
+		printk(KERN_INFO "ip6ip6 close: can't remove xfrm type\n");
+}
+
+module_init(ip6ip6_init);
+module_exit(ip6ip6_fini);
+MODULE_LICENSE("GPL");
Index: linux25-XFRM6_TUNNEL-20030612/net/xfrm/xfrm_output.c
===================================================================
RCS file: /cvsroot/usagi/usagi-backport/linux25/net/xfrm/xfrm_output.c,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.24.1
diff -u -r1.1.1.1 -r1.1.1.1.24.1
--- linux25-XFRM6_TUNNEL-20030612/net/xfrm/xfrm_output.c	6 May 2003 12:43:55 -0000	1.1.1.1
+++ linux25-XFRM6_TUNNEL-20030612/net/xfrm/xfrm_output.c	12 Jun 2003 15:29:06 -0000	1.1.1.1.24.1
@@ -27,11 +27,11 @@
 		case AF_INET:
 			err = xfrm4_tunnel_check_size(skb);
 			break;
-			
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)			
 		case AF_INET6:
 			err = xfrm6_tunnel_check_size(skb);
 			break;
-			
+#endif	
 		default:
 			err = -EINVAL;
 		}

  reply	other threads:[~2003-06-13 16:03 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-05-31 15:20 [PATCH] xfrm ip6ip6 Mitsuru KANDA / 神田 充
2003-05-31 16:01 ` James Morris
2003-06-01  8:34   ` David S. Miller
2003-05-31 16:06 ` James Morris
2003-06-01  8:30 ` David S. Miller
2003-06-13 16:03   ` Mitsuru KANDA / 神田 充 [this message]
2003-06-13 16:11     ` [PATCH] xfrm ip6ip6 (revised) YOSHIFUJI Hideaki / 吉藤英明
2003-06-13 16:13       ` YOSHIFUJI Hideaki / 吉藤英明
2003-06-13 18:08         ` Ville Nuorvala
2003-06-13 19:07     ` David S. Miller
2003-06-13 19:19       ` David S. Miller

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87smqerml5.wl@karaba.org \
    --to=mk@linux-ipv6.org \
    --cc=davem@redhat.com \
    --cc=jmorris@intercode.com.au \
    --cc=kuznet@ms2.inr.ac.ru \
    --cc=netdev@oss.sgi.com \
    --cc=usagi@linux-ipv6.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).