linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Re: [PATH] IPv6 IPsec support
       [not found] <20030305233025.784feb00.kazunori@miyazawa.org>
@ 2003-03-05 15:21 ` David S. Miller
  2003-03-05 15:48   ` (usagi-core 12294) Re: [PATCH] " YOSHIFUJI Hideaki / 吉藤英明
  2003-03-05 23:25 ` [PATH] " David S. Miller
  1 sibling, 1 reply; 10+ messages in thread
From: David S. Miller @ 2003-03-05 15:21 UTC (permalink / raw)
  To: kazunori; +Cc: kuznet, linux-kernel, netdev, usagi-core

   From: Kazunori Miyazawa <kazunori@miyazawa.org>
   Date: Wed, 5 Mar 2003 23:30:25 +0900

Hello Miyazawa-san,

   I submit the patch to let the kernel support ipv6 ipsec again.
   It is able to comple ipv6 as module.
   
   This patch incldes a couple of clean-up and
   changes of function name.

Excellent work.

I have comments, but they are very minor and can wait.
I will apply your patch after basic build testing.

The next large task will be to abstract out more common
pieces of code.  There is still quite a bit of code duplication
between v4 and v6 xfrm methods,

Thank you!

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: (usagi-core 12294) Re: [PATCH] IPv6 IPsec support
  2003-03-05 15:21 ` [PATH] IPv6 IPsec support David S. Miller
@ 2003-03-05 15:48   ` YOSHIFUJI Hideaki / 吉藤英明
  2003-03-05 23:41     ` David S. Miller
  0 siblings, 1 reply; 10+ messages in thread
From: YOSHIFUJI Hideaki / 吉藤英明 @ 2003-03-05 15:48 UTC (permalink / raw)
  To: davem; +Cc: kazunori, kuznet, linux-kernel, netdev, usagi

In article <20030305.072149.121185037.davem@redhat.com> (at Wed, 05 Mar 2003 07:21:49 -0800 (PST)), "David S. Miller" <davem@redhat.com> says:

> I will apply your patch after basic build testing.

Thank you.

> The next large task will be to abstract out more common
> pieces of code.  There is still quite a bit of code duplication
> between v4 and v6 xfrm methods,

Yes, we will do that.  That patch is first step for reducing 
duplicate codes between IPv4 and IPv6.

--yoshfuji

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATH] IPv6 IPsec support
       [not found] <20030305233025.784feb00.kazunori@miyazawa.org>
  2003-03-05 15:21 ` [PATH] IPv6 IPsec support David S. Miller
@ 2003-03-05 23:25 ` David S. Miller
  2003-03-06  0:32   ` Kazunori Miyazawa
  1 sibling, 1 reply; 10+ messages in thread
From: David S. Miller @ 2003-03-05 23:25 UTC (permalink / raw)
  To: kazunori; +Cc: kuznet, linux-kernel, netdev, usagi-core

   From: Kazunori Miyazawa <kazunori@miyazawa.org>
   Date: Wed, 5 Mar 2003 23:30:25 +0900

Hello Miyazawa-san,

   I submit the patch to let the kernel support ipv6 ipsec again.
   It is able to comple ipv6 as module.

As promised I applied the patch.  I will push it to Linus later
this evening, or tomorrow.

In this initial checkin I made only 2 minor fixes, they
are attached below:

--- ./include/net/ip6_route.h.~1~	Wed Mar  5 15:32:41 2003
+++ ./include/net/ip6_route.h	Wed Mar  5 15:40:42 2003
@@ -38,7 +38,6 @@
 extern int			ipv6_route_ioctl(unsigned int cmd, void *arg);
 
 extern int			ip6_route_add(struct in6_rtmsg *rtmsg);
-extern int			ip6_route_del(struct in6_rtmsg *rtmsg);
 extern int			ip6_del_rt(struct rt6_info *);
 
 extern int			ip6_rt_addr_add(struct in6_addr *addr,
--- ./net/ipv6/Kconfig.~1~	Wed Mar  5 15:32:41 2003
+++ ./net/ipv6/Kconfig	Wed Mar  5 15:35:27 2003
@@ -19,6 +19,7 @@
 
 config INET6_AH
 	tristate "IPv6: AH transformation"
+	depends on IPV6
 	---help---
 	  Support for IPsec AH.
 
@@ -26,6 +27,7 @@
 
 config INET6_ESP
 	tristate "IPv6: ESP transformation"
+	depends on IPV6
 	---help---
 	  Support for IPsec ESP.
 

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: (usagi-core 12294) Re: [PATCH] IPv6 IPsec support
  2003-03-05 15:48   ` (usagi-core 12294) Re: [PATCH] " YOSHIFUJI Hideaki / 吉藤英明
@ 2003-03-05 23:41     ` David S. Miller
  2003-03-06 21:32       ` Chris Wedgwood
  0 siblings, 1 reply; 10+ messages in thread
From: David S. Miller @ 2003-03-05 23:41 UTC (permalink / raw)
  To: yoshfuji; +Cc: kazunori, kuznet, linux-kernel, netdev, usagi

   From: YOSHIFUJI Hideaki / 吉藤英明 <yoshfuji@linux-ipv6.org>
   Date: Thu, 06 Mar 2003 00:48:20 +0900 (JST)
   
   > The next large task will be to abstract out more common
   > pieces of code.  There is still quite a bit of code duplication
   > between v4 and v6 xfrm methods,
   
   Yes, we will do that.  That patch is first step for reducing 
   duplicate codes between IPv4 and IPv6.

Great.  I believe it should be possible, in the end, to make the XFRM
engine %100 address-family (v4, v6 etc.) and protocol (ah, esp)
independant.  If that goal is achieved, we may move generic parts from
net/ipv4/xfrm_*.c to net/xfrm_*.c

Note that this coincides with the idea to eventually have
an address-family independant flow cache.

Most of the address-family specific areas are:

1) DST lookup (xfrm_dst_lookup_t)

2) selector key comparisons and state lookup
   (xfrm$(AF)_selector_match, xfrm$(AF)_state_find)

3) receive processing (xfrm${AF}_rcv)

#1 is made for ipv6 by Miyazawa-san's patch.  This could logically
be extended to handle issues #2 and #3 above.

All protocol specific (ESP, AH) and address-family specific references
should go away from places like include/net/xfrm.h

I think you understand all of this, and therefore I cannot wait for the
next ipsec cleanup patch from you :)

Finally, note that eventually we will need some reference counting scheme
for to allow xfrm address-family modules to be unloaded safely.

Currently, ipv4 cannot be a module and ipv6 as a module is not able
to unload :-)  So the module unload problem does not exist right
at this moment.  So ignore this issue for now.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATH] IPv6 IPsec support
  2003-03-05 23:25 ` [PATH] " David S. Miller
@ 2003-03-06  0:32   ` Kazunori Miyazawa
  2003-03-06  4:43     ` David S. Miller
  0 siblings, 1 reply; 10+ messages in thread
From: Kazunori Miyazawa @ 2003-03-06  0:32 UTC (permalink / raw)
  To: David S. Miller; +Cc: kuznet, linux-kernel, netdev, usagi-core

Hello David,

On Wed, 05 Mar 2003 15:25:30 -0800 (PST)
"David S. Miller" <davem@redhat.com> wrote:

>    From: Kazunori Miyazawa <kazunori@miyazawa.org>
>    Date: Wed, 5 Mar 2003 23:30:25 +0900
> 
> Hello Miyazawa-san,
> 
>    I submit the patch to let the kernel support ipv6 ipsec again.
>    It is able to comple ipv6 as module.
> 
> As promised I applied the patch.  I will push it to Linus later
> this evening, or tomorrow.
> 
> In this initial checkin I made only 2 minor fixes, they
> are attached below:
> 

Thank you very much.

My patch is the first step.
 I think there are these TODOs around IPv6 IPsec as far as I remember.

- Extension Header Processing on inbound:
  As a result of IPv6 IPsec support, Extension Header processing is devided
  into ipv6_parse_exthdrs and ipproto->handler. I think it is better to merge
  other Extension Header handling into ipproto->handler.

- Fragmentation support on outbound:
  We should change ipv6_build_xmit like ip_append_data style to support
  fragmentation with IPsec.

- Removing duplicate codes, clean up and improveing performance.

- Considering relation of IPv6 IPsec and Mobile IPv6. This is future stuff.

Best regards,

--Kazunori Miyazawa (Yokogawa Electric Corporation)


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATH] IPv6 IPsec support
  2003-03-06  0:32   ` Kazunori Miyazawa
@ 2003-03-06  4:43     ` David S. Miller
  2003-03-18 18:32       ` [PATCH] IPv6 Extension headers (Re: [PATCH] IPv6 IPsec support) Mitsuru KANDA / 神田 充
  0 siblings, 1 reply; 10+ messages in thread
From: David S. Miller @ 2003-03-06  4:43 UTC (permalink / raw)
  To: kazunori; +Cc: kuznet, linux-kernel, netdev, usagi-core

   From: Kazunori Miyazawa <kazunori@miyazawa.org>
   Date: Thu, 6 Mar 2003 09:32:19 +0900

   - Extension Header Processing on inbound:
     As a result of IPv6 IPsec support, Extension Header processing is devided
     into ipv6_parse_exthdrs and ipproto->handler. I think it is better to merge
     other Extension Header handling into ipproto->handler.
   
Ok.

   - Fragmentation support on outbound:
     We should change ipv6_build_xmit like ip_append_data style to support
     fragmentation with IPsec.
   
Please work together with Alexey on this.  There are known
major problems on ipv4 side, and it must be resolved before
ipv6 side may be done.

For example, right now a non-TCP packet can do the following.  If it
is just slightly smaller than MTU, and when encapsulated in ESP/AH it
becomes larger than MTU, we will not fragment it and too-large frame
will be sent to device.

In my last round of talks with Alexey I believe we were very close to
a possible solution to this problem.  The idea was to have a "local
dont-fragment" flag, and at the very last stage of IP output we check
this and either 1) clear DF and fragment or 2) drop packet and send
ICMP message back.

Alexey, what is the current state?

   - Removing duplicate codes, clean up and improveing performance.
   
   - Considering relation of IPv6 IPsec and Mobile IPv6. This is future stuff.
   
Ok.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: (usagi-core 12294) Re: [PATCH] IPv6 IPsec support
  2003-03-05 23:41     ` David S. Miller
@ 2003-03-06 21:32       ` Chris Wedgwood
  2003-03-06 23:27         ` David S. Miller
  0 siblings, 1 reply; 10+ messages in thread
From: Chris Wedgwood @ 2003-03-06 21:32 UTC (permalink / raw)
  To: David S. Miller; +Cc: yoshfuji, kazunori, kuznet, linux-kernel, netdev, usagi

On Wed, Mar 05, 2003 at 03:41:00PM -0800, David S. Miller wrote:

> Note that this coincides with the idea to eventually have an
> address-family independant flow cache.

Actually... at that point being able to monitor updates to the
flow-cache would be useful for various statistical purposes and
applications, especially if the flow cache was able to periodically
export utilization counters...


  --cw

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: (usagi-core 12294) Re: [PATCH] IPv6 IPsec support
  2003-03-06 21:32       ` Chris Wedgwood
@ 2003-03-06 23:27         ` David S. Miller
  0 siblings, 0 replies; 10+ messages in thread
From: David S. Miller @ 2003-03-06 23:27 UTC (permalink / raw)
  To: cw; +Cc: yoshfuji, kazunori, kuznet, linux-kernel, netdev, usagi

   From: Chris Wedgwood <cw@f00f.org>
   Date: Thu, 6 Mar 2003 13:32:17 -0800
   
   Actually... at that point being able to monitor updates to the
   flow-cache would be useful for various statistical purposes and
   applications, especially if the flow cache was able to periodically
   export utilization counters...
   
It will keep statistics, just like the route cache keeps
them now.
   

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH] IPv6 Extension headers (Re: [PATCH] IPv6 IPsec support)
  2003-03-06  4:43     ` David S. Miller
@ 2003-03-18 18:32       ` Mitsuru KANDA / 神田 充
  2003-03-24  5:29         ` [PATCH] IPv6 Extension headers David S. Miller
  0 siblings, 1 reply; 10+ messages in thread
From: Mitsuru KANDA / 神田 充 @ 2003-03-18 18:32 UTC (permalink / raw)
  To: davem, kuznet; +Cc: linux-kernel, netdev, usagi-core


Hello,

At Wed, 05 Mar 2003 20:43:48 -0800 (PST),
"David S. Miller" <davem@redhat.com> wrote:
> 
>    From: Kazunori Miyazawa <kazunori@miyazawa.org>
>    Date: Thu, 6 Mar 2003 09:32:19 +0900
> 
>    - Extension Header Processing on inbound:
>      As a result of IPv6 IPsec support, Extension Header processing is devided
>      into ipv6_parse_exthdrs and ipproto->handler. I think it is better to merge
>      other Extension Header handling into ipproto->handler.
>    
> Ok.

This patch merges inbound IPv6 extension header processing parts into 
inet6_protocols{} like a IPv6 AH/ESP headers.
As a result of this patch, I removed destopt parsing part in xfrm6_rcv()
and removed ipv6_parse_exthdrs().

Could you check this patch?
(This patch is against 2.5.65.)

Best Regards,
-mk

Index: include/net/ipv6.h
===================================================================
RCS file: /cvsroot/usagi/usagi-backport/linux25/include/net/ipv6.h,v
retrieving revision 1.1.1.4
diff -u -r1.1.1.4 ipv6.h
--- include/net/ipv6.h	9 Jan 2003 11:14:19 -0000	1.1.1.4
+++ include/net/ipv6.h	18 Mar 2003 05:11:39 -0000
@@ -203,11 +203,7 @@
 
 extern int			ip6_call_ra_chain(struct sk_buff *skb, int sel);
 
-extern int			ipv6_reassembly(struct sk_buff **skb, int);
-
 extern int			ipv6_parse_hopopts(struct sk_buff *skb, int);
-
-extern int			ipv6_parse_exthdrs(struct sk_buff **skb, int);
 
 extern struct ipv6_txoptions *  ipv6_dup_options(struct sock *sk, struct ipv6_txoptions *opt);
 
Index: include/net/protocol.h
===================================================================
RCS file: /cvsroot/usagi/usagi-backport/linux25/include/net/protocol.h,v
retrieving revision 1.1.1.3
diff -u -r1.1.1.3 protocol.h
--- include/net/protocol.h	11 Nov 2002 04:08:20 -0000	1.1.1.3
+++ include/net/protocol.h	18 Mar 2003 05:11:39 -0000
@@ -44,7 +44,7 @@
 #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
 struct inet6_protocol 
 {
-	int	(*handler)(struct sk_buff *skb);
+	int	(*handler)(struct sk_buff **skbp);
 
 	void	(*err_handler)(struct sk_buff *skb,
 			       struct inet6_skb_parm *opt,
Index: include/net/transp_v6.h
===================================================================
RCS file: /cvsroot/usagi/usagi-backport/linux25/include/net/transp_v6.h,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 transp_v6.h
--- include/net/transp_v6.h	7 Oct 2002 10:22:46 -0000	1.1.1.1
+++ include/net/transp_v6.h	18 Mar 2003 05:11:39 -0000
@@ -15,6 +15,14 @@
 
 struct flowi;
 
+/* extention headers */
+extern void				ipv6_hopopts_init(void);
+extern void				ipv6_rthdr_init(void);
+extern void				ipv6_frag_init(void);
+extern void				ipv6_nodata_init(void);
+extern void				ipv6_destopt_init(void);
+
+/* transport protocols */
 extern void				rawv6_init(void);
 extern void				udpv6_init(void);
 extern void				tcpv6_init(void);
Index: include/net/xfrm.h
===================================================================
RCS file: /cvsroot/usagi/usagi-backport/linux25/include/net/xfrm.h,v
retrieving revision 1.1.1.8
diff -u -r1.1.1.8 xfrm.h
--- include/net/xfrm.h	13 Mar 2003 17:29:53 -0000	1.1.1.8
+++ include/net/xfrm.h	18 Mar 2003 05:11:39 -0000
@@ -415,7 +415,7 @@
 extern void xfrm_replay_advance(struct xfrm_state *x, u32 seq);
 extern int xfrm_check_selectors(struct xfrm_state **x, int n, struct flowi *fl);
 extern int xfrm4_rcv(struct sk_buff *skb);
-extern int xfrm6_rcv(struct sk_buff *skb);
+extern int xfrm6_rcv(struct sk_buff **pskb);
 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: net/ipv4/xfrm_input.c
===================================================================
RCS file: /cvsroot/usagi/usagi-backport/linux25/net/ipv4/xfrm_input.c,v
retrieving revision 1.1.1.4
diff -u -r1.1.1.4 xfrm_input.c
--- net/ipv4/xfrm_input.c	13 Mar 2003 17:29:03 -0000	1.1.1.4
+++ net/ipv4/xfrm_input.c	18 Mar 2003 05:11:39 -0000
@@ -311,8 +311,9 @@
 	return nexthdr;
 }
 
-int xfrm6_rcv(struct sk_buff *skb)
+int xfrm6_rcv(struct sk_buff **pskb)
 {
+	struct sk_buff *skb = *pskb;
 	int err;
 	u32 spi, seq;
 	struct xfrm_state *xfrm_vec[XFRM_MAX_DEPTH];
@@ -325,12 +326,8 @@
 	u16 nh_offset = 0;
 	u8 nexthdr = 0;
 
-	if (hdr->nexthdr == IPPROTO_AH || hdr->nexthdr == IPPROTO_ESP) {
-		nh_offset = ((unsigned char*)&skb->nh.ipv6h->nexthdr) - skb->nh.raw;
-		hdr_len = sizeof(struct ipv6hdr);
-	} else {
-		hdr_len = skb->h.raw - skb->nh.raw;
-	}
+	nh_offset = ((unsigned char*)&skb->nh.ipv6h->nexthdr) - skb->nh.raw;
+	hdr_len = sizeof(struct ipv6hdr);
 
 	tmp_hdr = kmalloc(hdr_len, GFP_ATOMIC);
 	if (!tmp_hdr)
@@ -378,18 +375,6 @@
 		xfrm_vec[xfrm_nr++] = x;
 
 		iph = skb->nh.ipv6h; /* ??? */ 
-
-		if (nexthdr == NEXTHDR_DEST) {
-			if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+8) ||
-		    	!pskb_may_pull(skb, (skb->h.raw-skb->data)+((skb->h.raw[1]+1)<<3))) {
-				err = -EINVAL;
-				goto drop;
-			}
-			nexthdr = skb->h.raw[0];
-			nh_offset = skb->h.raw - skb->nh.raw;
-			skb_pull(skb, (skb->h.raw[1]+1)<<3);
-			skb->h.raw = skb->data;
-		}
 
 		if (x->props.mode) { /* XXX */
 			if (iph->nexthdr != IPPROTO_IPV6)
Index: net/ipv6/af_inet6.c
===================================================================
RCS file: /cvsroot/usagi/usagi-backport/linux25/net/ipv6/af_inet6.c,v
retrieving revision 1.1.1.7
diff -u -r1.1.1.7 af_inet6.c
--- net/ipv6/af_inet6.c	25 Feb 2003 05:33:26 -0000	1.1.1.7
+++ net/ipv6/af_inet6.c	18 Mar 2003 05:11:40 -0000
@@ -793,6 +793,13 @@
 	addrconf_init();
 	sit_init();
 
+	/* Init v6 extention headers. */
+	ipv6_hopopts_init();
+	ipv6_rthdr_init();
+	ipv6_frag_init();
+	ipv6_nodata_init();
+	ipv6_destopt_init();
+
 	/* Init v6 transport protocols. */
 	udpv6_init();
 	tcpv6_init();
Index: net/ipv6/exthdrs.c
===================================================================
RCS file: /cvsroot/usagi/usagi-backport/linux25/net/ipv6/exthdrs.c,v
retrieving revision 1.1.1.3
diff -u -r1.1.1.3 exthdrs.c
--- net/ipv6/exthdrs.c	20 Feb 2003 08:34:32 -0000	1.1.1.3
+++ net/ipv6/exthdrs.c	18 Mar 2003 05:11:40 -0000
@@ -18,6 +18,9 @@
 /* Changes:
  *	yoshfuji		: ensure not to overrun while parsing 
  *				  tlv options.
+ *	Mitsuru KANDA @USAGI	: Remove ipv6_parse_exthdrs().
+ *				: Register inbound extention header
+ *				: handlers as inet6_protocol{}.
  */
 
 #include <linux/errno.h>
@@ -44,20 +47,6 @@
 #include <asm/uaccess.h>
 
 /*
- *	Parsing inbound headers.
- *
- *	Parsing function "func" returns offset wrt skb->nh of the place,
- *	where next nexthdr value is stored or NULL, if parsing
- *	failed. It should also update skb->h tp point at the next header.
- */
-
-struct hdrtype_proc
-{
-	int	type;
-	int	(*func) (struct sk_buff **, int offset);
-};
-
-/*
  *	Parsing tlv encoded headers.
  *
  *	Parsing function "func" returns 1, if parsing succeed
@@ -164,49 +153,77 @@
 	{-1,			NULL}
 };
 
-static int ipv6_dest_opt(struct sk_buff **skb_ptr, int nhoff)
+int ipv6_destopt_rcv(struct sk_buff **skbp) 
 {
-	struct sk_buff *skb=*skb_ptr;
+	struct sk_buff *skb = *skbp;
 	struct inet6_skb_parm *opt = (struct inet6_skb_parm *)skb->cb;
+	u8 nexthdr = 0;
 
 	if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+8) ||
 	    !pskb_may_pull(skb, (skb->h.raw-skb->data)+((skb->h.raw[1]+1)<<3))) {
 		kfree_skb(skb);
-		return -1;
+		return 0;
 	}
 
+	nexthdr = ((struct ipv6_destopt_hdr *)skb->h.raw)->nexthdr;
+	
 	opt->dst1 = skb->h.raw - skb->nh.raw;
 
 	if (ip6_parse_tlv(tlvprocdestopt_lst, skb)) {
 		skb->h.raw += ((skb->h.raw[1]+1)<<3);
-		return opt->dst1;
+		return -nexthdr;
 	}
+						
+	return 0;
+}
 
-	return -1;
+static struct inet6_protocol destopt_protocol =
+{
+	.handler 	= 	ipv6_destopt_rcv,
+};
+
+void __init ipv6_destopt_init(void)
+{
+	if (inet6_add_protocol(&destopt_protocol, IPPROTO_DSTOPTS) < 0) 
+		printk(KERN_ERR "ipv6_destopt_init: Could not register protocol\n");
 }
 
 /********************************
   NONE header. No data in packet.
  ********************************/
 
-static int ipv6_nodata(struct sk_buff **skb_ptr, int nhoff)
+int ipv6_nodata_rcv(struct sk_buff **skbp)
 {
-	kfree_skb(*skb_ptr);
-	return -1;
+	struct sk_buff *skb = *skbp;
+
+	kfree_skb(skb);
+	return 0;
+}
+
+static struct inet6_protocol nodata_protocol =
+{
+	.handler	=	ipv6_nodata_rcv,
+};
+
+void __init ipv6_nodata_init(void)
+{
+	if (inet6_add_protocol(&nodata_protocol, IPPROTO_NONE) < 0)
+		printk(KERN_ERR "ipv6_nodata_init: Could not register protocol\n");
 }
 
 /********************************
   Routing header.
  ********************************/
 
-static int ipv6_routing_header(struct sk_buff **skb_ptr, int nhoff)
+int ipv6_rthdr_rcv(struct sk_buff **skbp)
 {
-	struct sk_buff *skb = *skb_ptr;
+	struct sk_buff *skb = *skbp;
 	struct inet6_skb_parm *opt = (struct inet6_skb_parm *)skb->cb;
 	struct in6_addr *addr;
 	struct in6_addr daddr;
 	int addr_type;
 	int n, i;
+	u8 nexthdr = 0;
 
 	struct ipv6_rt_hdr *hdr;
 	struct rt0_hdr *rthdr;
@@ -215,15 +232,16 @@
 	    !pskb_may_pull(skb, (skb->h.raw-skb->data)+((skb->h.raw[1]+1)<<3))) {
 		IP6_INC_STATS_BH(Ip6InHdrErrors);
 		kfree_skb(skb);
-		return -1;
+		return 0;
 	}
 
 	hdr = (struct ipv6_rt_hdr *) skb->h.raw;
+	nexthdr = hdr->nexthdr;
 
 	if ((ipv6_addr_type(&skb->nh.ipv6h->daddr)&IPV6_ADDR_MULTICAST) ||
 	    skb->pkt_type != PACKET_HOST) {
 		kfree_skb(skb);
-		return -1;
+		return 0;
 	}
 
 looped_back:
@@ -232,24 +250,24 @@
 		skb->h.raw += (hdr->hdrlen + 1) << 3;
 		opt->dst0 = opt->dst1;
 		opt->dst1 = 0;
-		return (&hdr->nexthdr) - skb->nh.raw;
+		return -nexthdr;
 	}
 
 	if (hdr->type != IPV6_SRCRT_TYPE_0 || (hdr->hdrlen & 0x01)) {
 		icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, hdr->type != IPV6_SRCRT_TYPE_0 ? 2 : 1);
-		return -1;
+		return 0;
 	}
 
 	/*
 	 *	This is the routing header forwarding algorithm from
-	 *	RFC 1883, page 17.
+	 *	RFC 2460, page 16.
 	 */
 
 	n = hdr->hdrlen >> 1;
 
 	if (hdr->segments_left > n) {
 		icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->segments_left) - skb->nh.raw);
-		return -1;
+		return 0;
 	}
 
 	/* We are about to mangle packet header. Be careful!
@@ -259,8 +277,8 @@
 		struct sk_buff *skb2 = skb_copy(skb, GFP_ATOMIC);
 		kfree_skb(skb);
 		if (skb2 == NULL)
-			return -1;
-		*skb_ptr = skb = skb2;
+			return 0;
+		*skbp = skb = skb2;
 		opt = (struct inet6_skb_parm *)skb2->cb;
 		hdr = (struct ipv6_rt_hdr *) skb2->h.raw;
 	}
@@ -278,7 +296,7 @@
 
 	if (addr_type&IPV6_ADDR_MULTICAST) {
 		kfree_skb(skb);
-		return -1;
+		return 0;
 	}
 
 	ipv6_addr_copy(&daddr, addr);
@@ -289,23 +307,34 @@
 	ip6_route_input(skb);
 	if (skb->dst->error) {
 		dst_input(skb);
-		return -1;
+		return 0;
 	}
 	if (skb->dst->dev->flags&IFF_LOOPBACK) {
 		if (skb->nh.ipv6h->hop_limit <= 1) {
 			icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT,
 				    0, skb->dev);
 			kfree_skb(skb);
-			return -1;
+			return 0;
 		}
 		skb->nh.ipv6h->hop_limit--;
 		goto looped_back;
 	}
 
 	dst_input(skb);
-	return -1;
+	return 0;
 }
 
+static struct inet6_protocol rthdr_protocol =
+{
+	.handler	=	ipv6_rthdr_rcv,
+};
+
+void __init ipv6_rthdr_init(void)
+{
+	if (inet6_add_protocol(&rthdr_protocol, IPPROTO_ROUTING) < 0)
+		printk(KERN_ERR "ipv6_rthdr_init: Could not register protocol\n");
+};
+
 /*
    This function inverts received rthdr.
    NOTE: specs allow to make it automatically only if
@@ -371,97 +400,6 @@
 	return opt;
 }
 
-/********************************
-  AUTH header.
- ********************************/
-
-/*
-   rfc1826 said, that if a host does not implement AUTH header
-   it MAY ignore it. We use this hole 8)
-
-   Actually, now we can implement OSPFv6 without kernel IPsec.
-   Authentication for poors may be done in user space with the same success.
-
-   Yes, it means, that we allow application to send/receive
-   raw authentication header. Apparently, we suppose, that it knows
-   what it does and calculates authentication data correctly.
-   Certainly, it is possible only for udp and raw sockets, but not for tcp.
-
-   AUTH header has 4byte granular length, which kills all the idea
-   behind AUTOMATIC 64bit alignment of IPv6. Now we will lose
-   cpu ticks, checking that sender did not something stupid
-   and opt->hdrlen is even. Shit!		--ANK (980730)
- */
-
-static int ipv6_auth_hdr(struct sk_buff **skb_ptr, int nhoff)
-{
-	struct sk_buff *skb=*skb_ptr;
-	struct inet6_skb_parm *opt = (struct inet6_skb_parm *)skb->cb;
-	int len;
-
-	if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+8))
-		goto fail;
-
-	/*
-	 * RFC2402 2.2 Payload Length
-	 * The 8-bit field specifies the length of AH in 32-bit words 
-	 * (4-byte units), minus "2".
-	 * -- Noriaki Takamiya @USAGI Project
-	 */
-	len = (skb->h.raw[1]+2)<<2;
-
-	if (len&7)
-		goto fail;
-
-	if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+len))
-		goto fail;
-
-	opt->auth = skb->h.raw - skb->nh.raw;
-	skb->h.raw += len;
-	return opt->auth;
-
-fail:
-	kfree_skb(skb);
-	return -1;
-}
-
-/* This list MUST NOT contain entry for NEXTHDR_HOP.
-   It is parsed immediately after packet received
-   and if it occurs somewhere in another place we must
-   generate error.
- */
-
-static struct hdrtype_proc hdrproc_lst[] = {
-	{NEXTHDR_FRAGMENT,	ipv6_reassembly},
-	{NEXTHDR_ROUTING,	ipv6_routing_header},
-	{NEXTHDR_DEST,		ipv6_dest_opt},
-	{NEXTHDR_NONE,		ipv6_nodata},
-	{NEXTHDR_AUTH,		ipv6_auth_hdr},
-   /*
-	{NEXTHDR_ESP,		ipv6_esp_hdr},
-    */
-	{-1,			NULL}
-};
-
-int ipv6_parse_exthdrs(struct sk_buff **skb_in, int nhoff)
-{
-	struct hdrtype_proc *hdrt;
-	u8 nexthdr = (*skb_in)->nh.raw[nhoff];
-
-restart:
-	for (hdrt=hdrproc_lst; hdrt->type >= 0; hdrt++) {
-		if (hdrt->type == nexthdr) {
-			if ((nhoff = hdrt->func(skb_in, nhoff)) >= 0) {
-				nexthdr = (*skb_in)->nh.raw[nhoff];
-				goto restart;
-			}
-			return -1;
-		}
-	}
-	return nhoff;
-}
-
-
 /**********************************
   Hop-by-hop options.
  **********************************/
@@ -530,6 +468,34 @@
 	if (ip6_parse_tlv(tlvprochopopt_lst, skb))
 		return sizeof(struct ipv6hdr);
 	return -1;
+}
+
+/* This is fake. We have already parsed hopopts in ipv6_rcv(). -mk */
+int ipv6_hopopts_rcv(struct sk_buff **skbp)
+{
+	struct sk_buff *skb = *skbp;
+	u8 nexthdr = 0;
+
+	if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+8) ||
+	    !pskb_may_pull(skb, (skb->h.raw-skb->data)+((skb->h.raw[1]+1)<<3))) {
+		kfree_skb(skb);
+		return 0;
+	}
+	nexthdr = ((struct ipv6_hopopt_hdr *)skb->h.raw)->nexthdr;
+	skb->h.raw += (skb->h.raw[1]+1)<<3;
+
+       return -nexthdr;
+}
+
+static struct inet6_protocol hopopts_protocol =
+{
+	.handler	=	ipv6_hopopts_rcv,
+};
+
+void __init ipv6_hopopts_init(void)
+{
+	if (inet6_add_protocol(&hopopts_protocol, IPPROTO_HOPOPTS) < 0)
+		printk(KERN_ERR "ipv6_hopopts_init: Could not register protocol\n");
 }
 
 /*
Index: net/ipv6/icmp.c
===================================================================
RCS file: /cvsroot/usagi/usagi-backport/linux25/net/ipv6/icmp.c,v
retrieving revision 1.1.1.7
diff -u -r1.1.1.7 icmp.c
--- net/ipv6/icmp.c	13 Mar 2003 17:29:06 -0000	1.1.1.7
+++ net/ipv6/icmp.c	18 Mar 2003 05:11:40 -0000
@@ -74,7 +74,7 @@
 static struct socket *__icmpv6_socket[NR_CPUS];
 #define icmpv6_socket	__icmpv6_socket[smp_processor_id()]
 
-static int icmpv6_rcv(struct sk_buff *skb);
+static int icmpv6_rcv(struct sk_buff **pskb);
 
 static struct inet6_protocol icmpv6_protocol = {
 	.handler	=	icmpv6_rcv,
@@ -458,8 +458,9 @@
  *	Handle icmp messages
  */
 
-static int icmpv6_rcv(struct sk_buff *skb)
+static int icmpv6_rcv(struct sk_buff **pskb)
 {
+	struct sk_buff *skb = *pskb;
 	struct net_device *dev = skb->dev;
 	struct in6_addr *saddr, *daddr;
 	struct ipv6hdr *orig_hdr;
Index: net/ipv6/ip6_input.c
===================================================================
RCS file: /cvsroot/usagi/usagi-backport/linux25/net/ipv6/ip6_input.c,v
retrieving revision 1.1.1.6
diff -u -r1.1.1.6 ip6_input.c
--- net/ipv6/ip6_input.c	13 Mar 2003 17:29:06 -0000	1.1.1.6
+++ net/ipv6/ip6_input.c	18 Mar 2003 05:11:40 -0000
@@ -15,6 +15,10 @@
  *      as published by the Free Software Foundation; either version
  *      2 of the License, or (at your option) any later version.
  */
+/* Changes
+ *
+ * 	Mitsuru KANDA @USAGI	: Remove ipv6_parse_exthdrs().
+ */
 
 #include <linux/errno.h>
 #include <linux/types.h>
@@ -127,38 +131,11 @@
 	struct inet6_protocol *ipprot;
 	struct sock *raw_sk;
 	int nhoff;
-	int nexthdr;
+	int nexthdr = hdr->nexthdr;
 	u8 hash;
 
 	skb->h.raw = skb->nh.raw + sizeof(struct ipv6hdr);
 
-	/*
-	 *	Parse extension headers
-	 */
-
-	nexthdr = hdr->nexthdr;
-	nhoff = offsetof(struct ipv6hdr, nexthdr);
-
-	/* Skip  hop-by-hop options, they are already parsed. */
-	if (nexthdr == NEXTHDR_HOP) {
-		nhoff = sizeof(struct ipv6hdr);
-		nexthdr = skb->h.raw[0];
-		skb->h.raw += (skb->h.raw[1]+1)<<3;
-	}
-
-	/* This check is sort of optimization.
-	   It would be stupid to detect for optional headers,
-	   which are missing with probability of 200%
-	 */
-	if (nexthdr != IPPROTO_TCP && nexthdr != IPPROTO_UDP &&
-	    nexthdr != NEXTHDR_AUTH && nexthdr != NEXTHDR_ESP) {
-		nhoff = ipv6_parse_exthdrs(&skb, nhoff);
-		if (nhoff < 0)
-			return 0;
-		nexthdr = skb->nh.raw[nhoff];
-		hdr = skb->nh.ipv6h;
-	}
-
 	if (!pskb_pull(skb, skb->h.raw - skb->data))
 		goto discard;
 
@@ -173,7 +150,7 @@
 
 	hash = nexthdr & (MAX_INET_PROTOS - 1);
 	if ((ipprot = inet6_protos[hash]) != NULL) {
-		int ret = ipprot->handler(skb);
+		int ret = ipprot->handler(&skb);
 		if (ret < 0) {
 			nexthdr = -ret;
 			goto resubmit;
@@ -182,6 +159,7 @@
 	} else {
 		if (!raw_sk) {
 			IP6_INC_STATS_BH(Ip6InUnknownProtos);
+			nhoff = offsetof(struct ipv6hdr, nexthdr);
 			icmpv6_param_prob(skb, ICMPV6_UNK_NEXTHDR, nhoff);
 		} else {
 			IP6_INC_STATS_BH(Ip6InDelivers);
Index: net/ipv6/reassembly.c
===================================================================
RCS file: /cvsroot/usagi/usagi-backport/linux25/net/ipv6/reassembly.c,v
retrieving revision 1.1.1.4
diff -u -r1.1.1.4 reassembly.c
--- net/ipv6/reassembly.c	20 Feb 2003 08:34:32 -0000	1.1.1.4
+++ net/ipv6/reassembly.c	18 Mar 2003 05:11:40 -0000
@@ -23,6 +23,7 @@
  *      Horst von Brand Add missing #include <linux/string.h>
  *	Alexey Kuznetsov	SMP races, threading, cleanup.
  *	Patrick McHardy		LRU queue of frag heads for evictor.
+ *	Mitsuru KANDA @USAGI	Register inet6_protocol{}.
  */
 #include <linux/config.h>
 #include <linux/errno.h>
@@ -525,6 +526,7 @@
 	int    remove_fraghdr = 0;
 	int    payload_len;
 	int    nhoff;
+	u8     nexthdr = 0;
 
 	fq_kill(fq);
 
@@ -535,6 +537,8 @@
 	payload_len = (head->data - head->nh.raw) - sizeof(struct ipv6hdr) + fq->len;
 	nhoff = head->h.raw - head->nh.raw;
 
+	nexthdr = ((struct frag_hdr*)head->h.raw)->nexthdr;
+
 	if (payload_len > 65535) {
 		payload_len -= 8;
 		if (payload_len > 65535)
@@ -609,9 +613,13 @@
 	if (head->ip_summed == CHECKSUM_HW)
 		head->csum = csum_partial(head->nh.raw, head->h.raw-head->nh.raw, head->csum);
 
+	if (!pskb_pull(head, head->h.raw - head->data)) {
+		goto out_fail;
+	}
+
 	IP6_INC_STATS_BH(Ip6ReasmOKs);
 	fq->fragments = NULL;
-	return nhoff;
+	return nexthdr;
 
 out_oversize:
 	if (net_ratelimit())
@@ -622,16 +630,18 @@
 		printk(KERN_DEBUG "ip6_frag_reasm: no memory for reassembly\n");
 out_fail:
 	IP6_INC_STATS_BH(Ip6ReasmFails);
-	return -1;
+	return 0;
 }
 
-int ipv6_reassembly(struct sk_buff **skbp, int nhoff)
+int ipv6_frag_rcv(struct sk_buff **skbp)
 {
 	struct sk_buff *skb = *skbp; 
 	struct net_device *dev = skb->dev;
 	struct frag_hdr *fhdr;
 	struct frag_queue *fq;
 	struct ipv6hdr *hdr;
+	int nhoff = skb->h.raw - skb->nh.raw;
+	u8 nexthdr = 0;
 
 	hdr = skb->nh.ipv6h;
 
@@ -640,15 +650,16 @@
 	/* Jumbo payload inhibits frag. header */
 	if (hdr->payload_len==0) {
 		icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, skb->h.raw-skb->nh.raw);
-		return -1;
+		goto discard;
 	}
 	if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+sizeof(struct frag_hdr))) {
 		icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, skb->h.raw-skb->nh.raw);
-		return -1;
+		goto discard;
 	}
 
 	hdr = skb->nh.ipv6h;
 	fhdr = (struct frag_hdr *)skb->h.raw;
+	nexthdr = fhdr->nexthdr;
 
 	if (!(fhdr->frag_off & htons(0xFFF9))) {
 		/* It is not a fragmented frame */
@@ -674,10 +685,22 @@
 
 		spin_unlock(&fq->lock);
 		fq_put(fq);
-		return ret;
+		return -ret;
 	}
 
+discard:
 	IP6_INC_STATS_BH(Ip6ReasmFails);
 	kfree_skb(skb);
-	return -1;
+	return 0;
+}
+
+static struct inet6_protocol frag_protocol =
+{
+	.handler	=	ipv6_frag_rcv,
+};
+
+void __init ipv6_frag_init(void)
+{
+	if (inet6_add_protocol(&frag_protocol, IPPROTO_FRAGMENT) < 0)
+		printk(KERN_ERR "ipv6_frag_init: Could not register protocol\n");
 }
Index: net/ipv6/tcp_ipv6.c
===================================================================
RCS file: /cvsroot/usagi/usagi-backport/linux25/net/ipv6/tcp_ipv6.c,v
retrieving revision 1.1.1.8
diff -u -r1.1.1.8 tcp_ipv6.c
--- net/ipv6/tcp_ipv6.c	13 Mar 2003 17:29:06 -0000	1.1.1.8
+++ net/ipv6/tcp_ipv6.c	18 Mar 2003 05:11:40 -0000
@@ -1591,8 +1591,9 @@
 	return 0;
 }
 
-static int tcp_v6_rcv(struct sk_buff *skb)
+static int tcp_v6_rcv(struct sk_buff **pskb)
 {
+	struct sk_buff *skb = *pskb;
 	struct tcphdr *th;	
 	struct sock *sk;
 	int ret;
Index: net/ipv6/udp.c
===================================================================
RCS file: /cvsroot/usagi/usagi-backport/linux25/net/ipv6/udp.c,v
retrieving revision 1.1.1.7
diff -u -r1.1.1.7 udp.c
--- net/ipv6/udp.c	13 Mar 2003 17:29:06 -0000	1.1.1.7
+++ net/ipv6/udp.c	18 Mar 2003 05:11:40 -0000
@@ -641,8 +641,9 @@
 	read_unlock(&udp_hash_lock);
 }
 
-static int udpv6_rcv(struct sk_buff *skb)
+static int udpv6_rcv(struct sk_buff **pskb)
 {
+	struct sk_buff *skb = *pskb;
 	struct sock *sk;
   	struct udphdr *uh;
 	struct net_device *dev = skb->dev;


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] IPv6 Extension headers
  2003-03-18 18:32       ` [PATCH] IPv6 Extension headers (Re: [PATCH] IPv6 IPsec support) Mitsuru KANDA / 神田 充
@ 2003-03-24  5:29         ` David S. Miller
  0 siblings, 0 replies; 10+ messages in thread
From: David S. Miller @ 2003-03-24  5:29 UTC (permalink / raw)
  To: mk; +Cc: kuznet, linux-kernel, netdev, usagi-core

   From: Mitsuru KANDA / 神田 充 <mk@linux-ipv6.org>
   Date: Tue, 18 Mar 2003 10:32:27 -0800
   
   Could you check this patch?
   (This patch is against 2.5.65.)

I applied this patch with some minor changes.

First, many functions in net/ipv6/exthdrs.c and net/ipv6/reassembly.c
can be marked static now.

Second, some local variables (for example, "nhoff" in ip6_input()) can
be eliminated entirely because they compute a value in one place and
use it in the very next line and nowhere else is it referenced.

Thank you.

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2003-03-24  5:21 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <20030305233025.784feb00.kazunori@miyazawa.org>
2003-03-05 15:21 ` [PATH] IPv6 IPsec support David S. Miller
2003-03-05 15:48   ` (usagi-core 12294) Re: [PATCH] " YOSHIFUJI Hideaki / 吉藤英明
2003-03-05 23:41     ` David S. Miller
2003-03-06 21:32       ` Chris Wedgwood
2003-03-06 23:27         ` David S. Miller
2003-03-05 23:25 ` [PATH] " David S. Miller
2003-03-06  0:32   ` Kazunori Miyazawa
2003-03-06  4:43     ` David S. Miller
2003-03-18 18:32       ` [PATCH] IPv6 Extension headers (Re: [PATCH] IPv6 IPsec support) Mitsuru KANDA / 神田 充
2003-03-24  5:29         ` [PATCH] IPv6 Extension headers David S. Miller

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).