IPv6 IPsec support
Subsystems (6)
Hello,
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.
Sorry, this patch is for linux-2.5.63.
Best Regards,
--Kazunori Miyazawa (Yokogawa Electric Corporation)
Patch-Name: IPsec
Patch-Id: IPSEC_2_5_63_ALL-20030304
Patch-Author: Kazunori Miyazawa <[email protected]>
Credit: Kazunori Miyazawa <[email protected]>,
Mitsuru Kanda <[email protected]>, YOSHIFUJI Hideaki <[email protected]>, Kunihiro Ishiguro
This patch make the kernel process IPv6 packet with IPsec.
- We've introduced a function pointer (xfrm_dst_lookup) for looking up routing table of each address family to comple ipv6 as module.
- We moved some common functions among protocols such as skb_icv_walk() in net/ipv4/{ah.c,esp.c} to net/ipv4/xfrm_algo.c. This is for compling ah / esp and ah6 / esp6 as modules.
- We renamed some IPv4 specific xfrm_XXX() functions to xfrm4_XXX().
include/linux/ipv6.h +15 -0
@@ -74,6 +74,21 @@#define rt0_type rt_hdr.type; }; +struct ipv6_auth_hdr { +__u8 nexthdr; +__u8 hdrlen;/* This one is measured in 32 bit units! */ +__u16 reserved; +__u32 spi; +__u32 seq_no;/* Sequence number */ +__u8 auth_data[4 ];/* Length variable but >=4. Mind the 64 bit alignment! */ +}; + +struct ipv6_esp_hdr { +__u32 spi; +__u32 seq_no;/* Sequence number */ +__u8 enc_data[8 ];/* Length variable but >=8. Mind the 64 bit alignment! */ +}; +/* * IPv6 fixed header *
include/net/dst.h +3 -0
@@ -247,7 +247,10 @@struct flowi ;extern int xfrm_lookup (struct dst_entry **dst_p,struct flowi *fl,struct sock *sk,int flags); +extern int xfrm6_lookup (struct dst_entry **dst_p,struct flowi *fl, +struct sock *sk,int flags);extern void xfrm_init (void ); +extern void xfrm6_init (void );#endif
include/net/ip6_route.h +3 -0
@@ -38,6 +38,7 @@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,
@@ -57,6 +58,8 @@struct in6_addr *saddr, int oif, int flags); +extern struct rt6_info *ndisc_get_dummy_rt (void ); +/* * support functions for ND *
include/net/xfrm.h +151 -19
241 lines not on this page · raw message
net/ipv4/ah.c +2 -105
126 lines not on this page · raw message
net/ipv4/esp.c +2 -306
321 lines not on this page · raw message
net/ipv4/route.c +9 -0
@@ -96,6 +96,7 @@#include <net/arp.h> #include <net/tcp.h> #include <net/icmp.h> +#include <net/xfrm.h> #ifdef CONFIG_SYSCTL #include <linux/sysctl.h> #endif
@@ -2599,6 +2600,13 @@#endif /* CONFIG_PROC_FS */ #endif /* CONFIG_NET_CLS_ROUTE */ +int xfrm_dst_lookup (struct xfrm_dst **dst,struct flowi *fl) +{ +int err =0 ; + err =__ip_route_output_key ((struct rtable **)dst, fl); +return err; +} +int __init ip_rt_init (void ) {int i, order, goal, rc =0 ;
@@ -2680,6 +2688,7 @@ ip_rt_gc_interval;add_timer (&rt_periodic_timer); +xfrm_dst_lookup_register (xfrm_dst_lookup,AF_INET );#ifdef CONFIG_PROC_FS if (rt_cache_proc_init ()) goto out_enomem;
net/ipv4/xfrm_algo.c +332 -0
344 lines not on this page · raw message
net/ipv4/xfrm_input.c +296 -1
310 lines not on this page · raw message
net/ipv4/xfrm_policy.c +528 -51
829 lines not on this page · raw message
net/ipv4/xfrm_state.c +260 -129
470 lines not on this page · raw message
net/ipv4/xfrm_user.c +4 -4
@@ -234,8 +234,8 @@switch (x->props.family) {case AF_INET : - x1 =xfrm_state_lookup (x->props.saddr.xfrm4_addr, - x->id.spi, x->id.proto); + x1 =xfrm4_state_lookup (x->props.saddr.xfrm4_addr, + x->id.spi, x->id.proto);break ;#if defined(CONFIG_IPV6 ) || defined(CONFIG_IPV6_MODULE )case AF_INET6 :
@@ -265,7 +265,7 @@switch (p->family) {case AF_INET : - x =xfrm_state_lookup (p->saddr.xfrm4_addr, p->spi, p->proto); + x =xfrm4_state_lookup (p->saddr.xfrm4_addr, p->spi, p->proto);break ;#if defined(CONFIG_IPV6 ) || defined(CONFIG_IPV6_MODULE )case AF_INET6 :
@@ -395,7 +395,7 @@switch (p->family) {case AF_INET : - x =xfrm_state_lookup (p->saddr.xfrm4_addr, p->spi, p->proto); + x =xfrm4_state_lookup (p->saddr.xfrm4_addr, p->spi, p->proto);break ;#if defined(CONFIG_IPV6 ) || defined(CONFIG_IPV6_MODULE )case AF_INET6 :
net/ipv6/Kconfig +14 -1
@@ -17,5 +17,18 @@ See <file:Documentation/networking/ip-sysctl.txt> for details. -source "net/ipv6/netfilter/Kconfig" +config INET6_AH + tristate "IPv6: AH transformation" + ---help--- + Support for IPsec AH. + + If unsure, say Y. + +config INET6_ESP + tristate "IPv6: ESP transformation" + ---help--- + Support for IPsec ESP. + If unsure, say Y. + +source "net/ipv6/netfilter/Kconfig"
net/ipv6/Makefile +2 -0
@@ -10,4 +10,6 @@ exthdrs.o sysctl_net_ipv6.o datagram.o proc.o \ ip6_flowlabel.o ipv6_syms.o +obj-$(CONFIG_INET6_AH) += ah6.o +obj-$(CONFIG_INET6_ESP) += esp6.o obj-$(CONFIG_NETFILTER) += netfilter/
net/ipv6/ah6.c +361 -0
235 lines not on this page · raw message
net/ipv6/esp6.c +526 -0
526 lines not on this page · raw message
net/ipv6/ndisc.c +133 -36
169 lines not on this page · raw message
The rest of this diff is not shown. View the raw message.
Part of the diff is not shown here. View the raw message.
From: Kazunori Miyazawa <[email protected]>
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!
Re: (usagi-core 12294) Re: [PATCH] IPv6 IPsec support
In article <[email protected]> (at Wed, 05 Mar 2003 07:21:49 -0800 (PST)), "David S. Miller" <[email protected]> says:
Quoted 1 line
I will apply your patch after basic build testing.
Thank you.
Quoted 3 lines
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
Re: (usagi-core 12294) Re: [PATCH] IPv6 IPsec support
From: YOSHIFUJI Hideaki / 吉藤英明 <[email protected]>
Date: Thu, 06 Mar 2003 00:48:20 +0900 (JST)
Quoted 3 lines
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.
Re: (usagi-core 12294) Re: [PATCH] IPv6 IPsec support
Quoted 2 lines · David S. Miller
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
Re: (usagi-core 12294) Re: [PATCH] IPv6 IPsec support
From: Chris Wedgwood <[email protected]>
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.
From: Kazunori Miyazawa <[email protected]>
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 renamed from include/net/ip6_route.h.~1~ +0 -1
@@ -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 renamed from net/ipv6/Kconfig.~1~ +2 -0
@@ -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.
Hello David,
Quoted 5 lines · On Wed, 05 Mar 2003 15:25:30 -0800 (PST) "David S. Miller" <[email protected]>…
From: Kazunori Miyazawa <[email protected]>
Date: Wed, 5 Mar 2003 23:30:25 +0900Hello Miyazawa-san,
Quoted 9 lines
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)
From: Kazunori Miyazawa <[email protected]>
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.
PATCH 1/1 IPv6 Extension headers (Re: [PATCH] IPv6 IPsec support)
Hello,
At Wed, 05 Mar 2003 20:43:48 -0800 (PST),
Quoted 10 lines · David S. Miller
From: Kazunori Miyazawa <[email protected]>
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
net/ipv6.h +0 -4
@@ -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
net/protocol.h +1 -1
@@ -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
net/transp_v6.h +8 -0
@@ -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
net/xfrm.h +1 -1
@@ -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
ipv4/xfrm_input.c +4 -19
@@ -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
ipv6/af_inet6.c +7 -0
@@ -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
ipv6/exthdrs.c +93 -127
348 lines not on this page · raw message
Index: net/ipv6/icmp.c
===================================================================
RCS file: /cvsroot/usagi/usagi-backport/linux25/net/ipv6/icmp.c,v retrieving revision 1.1.1.7
ipv6/icmp.c +3 -2
@@ -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
ipv6/ip6_input.c +7 -29
@@ -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
ipv6/reassembly.c +30 -7
@@ -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
ipv6/tcp_ipv6.c +2 -1
@@ -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
ipv6/udp.c +2 -1
@@ -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;
Re: [PATCH] IPv6 Extension headers
From: Mitsuru KANDA / 神田 充 <[email protected]>
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.