SOURCES: linux-2.6.20.2-hip.patch (NEW) - updated patch from http:...

gotar gotar at pld-linux.org
Tue Mar 13 18:16:59 CET 2007


Author: gotar                        Date: Tue Mar 13 17:16:59 2007 GMT
Module: SOURCES                       Tag: HEAD
---- Log message:
- updated patch from http://downloads.sourceforge.net/openhip/linux-2.6.13.5-hip.patch

---- Files affected:
SOURCES:
   linux-2.6.20.2-hip.patch (NONE -> 1.1)  (NEW)

---- Diffs:

================================================================
Index: SOURCES/linux-2.6.20.2-hip.patch
diff -u /dev/null SOURCES/linux-2.6.20.2-hip.patch:1.1
--- /dev/null	Tue Mar 13 18:16:59 2007
+++ SOURCES/linux-2.6.20.2-hip.patch	Tue Mar 13 18:16:54 2007
@@ -0,0 +1,969 @@
+--- linux-2.6.13.5/Makefile	2005-12-15 10:38:27.000000000 -0800
++++ linux-2.6.13.5-hip/Makefile	2006-05-04 16:52:27.000000000 -0700
+@@ -1,7 +1,7 @@
+ VERSION = 2
+ PATCHLEVEL = 6
+ SUBLEVEL = 20
+-EXTRAVERSION = .2
++EXTRAVERSION = .2-hip
+ NAME=Homicidal Dwarf Hamster
+ 
+ # *DOCUMENTATION*
+--- linux-2.6.13.5/net/xfrm/xfrm_user.c	2005-12-15 10:38:27.000000000 -0800
++++ linux-2.6.13.5-hip/net/xfrm/xfrm_user.c	2006-05-04 16:49:03.000000000 -0700
+@@ -653,6 +653,9 @@
+ 	xp->action = p->action;
+ 	xp->flags = p->flags;
+ 	xp->family = p->sel.family;
++#ifdef CONFIG_HIP
++	xp->xfrm_hipType = 1;
++#endif
+ 	/* XXX xp->share = p->share; */
+ }
+ 
+--- linux-2.6.13.5/net/xfrm/xfrm_policy.c	2005-12-15 10:38:27.000000000 -0800
++++ linux-2.6.13.5-hip/net/xfrm/xfrm_policy.c	2006-05-04 16:49:03.000000000 -0700
+@@ -602,6 +602,9 @@
+ 		newp->xfrm_nr = old->xfrm_nr;
+ 		newp->index = old->index;
+ 		newp->type = old->type;
++#ifdef CONFIG_HIP
++		newp->xfrm_hipType =  old->xfrm_hipType;
++#endif 
+ 		memcpy(newp->xfrm_vec, old->xfrm_vec,
+ 		       newp->xfrm_nr*sizeof(struct xfrm_tmpl));
+ 		write_lock_bh(&xfrm_policy_lock);
+@@ -935,6 +938,16 @@
+ {
+ 	struct flowi fl;
+ 
++
++#ifdef CONFIG_HIP
++/* 
++   jeffm: bypass policy enforcement on HIP sockets
++*/
++	if (sk && (sk->sk_protocol == IPPROTO_HIP)) {   
++		//printk("__xfrm_policy_check: allowing HIP socket bypass\n");
++		return 1;
++	}
++#endif
+ 	if (xfrm_decode_session(skb, &fl, family) < 0)
+ 		return 0;
+ 
+--- linux-2.6.13.5/net/key/af_key.c	2005-12-15 10:38:27.000000000 -0800
++++ linux-2.6.13.5-hip/net/key/af_key.c	2006-05-04 16:49:03.000000000 -0700
+@@ -29,6 +29,12 @@
+ #include <net/xfrm.h>
+ 
+ #include <net/sock.h>
++#ifdef CONFIG_HIP
++#include <net/protocol.h>
++#include <net/tcp.h>
++#include <net/udp.h>
++#include <net/raw.h>
++#endif
+ 
+ #define _X2KEY(x) ((x) == XFRM_INF ? 0 : (x))
+ #define _KEY2X(x) ((x) == 0 ? XFRM_INF : (x))
+@@ -320,6 +326,9 @@
+ 	[SADB_EXT_ADDRESS_SRC]		= (u8) sizeof(struct sadb_address),
+ 	[SADB_EXT_ADDRESS_DST]		= (u8) sizeof(struct sadb_address),
+ 	[SADB_EXT_ADDRESS_PROXY]	= (u8) sizeof(struct sadb_address),
++#ifdef CONFIG_HIP
++	[SADB_EXT_HIT]			= (u8) sizeof(struct sadb_hit),
++#endif
+ 	[SADB_EXT_KEY_AUTH]		= (u8) sizeof(struct sadb_key),
+ 	[SADB_EXT_KEY_ENCRYPT]		= (u8) sizeof(struct sadb_key),
+ 	[SADB_EXT_IDENTITY_SRC]		= (u8) sizeof(struct sadb_ident),
+@@ -911,6 +920,9 @@
+ 	struct sadb_key *key;
+ 	uint16_t proto;
+ 	int err;
++#ifdef CONFIG_HIP
++	struct sadb_hit *magic;
++#endif
+ 	
+ 
+ 	sa = (struct sadb_sa *) ext_hdrs[SADB_EXT_SA-1];
+@@ -993,6 +1005,18 @@
+ 			goto out;
+ 	}
+ 
++
++#ifdef CONFIG_HIP
++	magic = (struct sadb_hit *) ext_hdrs[SADB_EXT_HIT-1];
++	if(magic) {
++		x->hitMagic = magic->sadb_hit;
++		x->xfrm_hipType = 1;
++	}	
++	else {
++		x->xfrm_hipType = 0;
++		x->hitMagic = 0;
++	}
++#endif
+ 	key = (struct sadb_key*) ext_hdrs[SADB_EXT_KEY_AUTH-1];
+ 	if (sa->sadb_sa_auth) {
+ 		int keysize = 0;
+@@ -1656,6 +1680,16 @@
+ 	if (rq->sadb_x_ipsecrequest_mode == 0)
+ 		return -EINVAL;
+ 
++#ifdef CONFIG_HIP
++	if(rq->sadb_x_ipsecrequest_proto == IPPROTO_HIP) {
++//		printk("parse_ipsecrequest(), transforming HIP ipsecrequest\n");
++          	rq->sadb_x_ipsecrequest_proto = IPPROTO_ESP;
++		xp->xfrm_hipType = 1;
++	}
++	else {
++		xp->xfrm_hipType = 0;
++	} 
++#endif
+ 	t->id.proto = rq->sadb_x_ipsecrequest_proto; /* XXX check proto */
+ 	t->mode = rq->sadb_x_ipsecrequest_mode-1;
+ 	if (rq->sadb_x_ipsecrequest_level == IPSEC_LEVEL_USE)
+@@ -2023,6 +2057,17 @@
+ 	 */
+ 	xp->selector.proto = pfkey_proto_to_xfrm(sa->sadb_address_proto);
+ 
++#ifdef CONFIG_HIP
++	if(xp->selector.proto == IPPROTO_HIP) {
++
++//		printk("pfkey_spdadd(), handling HIP spd rule\n");
++          	xp->selector.proto = IPPROTO_ESP;
++		xp->xfrm_hipType = 1;
++	}
++	else {
++		xp->xfrm_hipType = 0;
++	} 
++#endif
+ 	xp->selector.dport = ((struct sockaddr_in *)(sa+1))->sin_port;
+ 	if (xp->selector.dport)
+ 		xp->selector.dport_mask = ~0;
+@@ -2044,6 +2089,19 @@
+ 		xp->lft.soft_use_expires_seconds = lifetime->sadb_lifetime_usetime;
+ 	}
+ 	xp->xfrm_nr = 0;
++/*
++
++ jeffm jeffm jeffm jeffm
++ pol is a chain of sadb_x_ipsec_request structs.  
++ if one of the chain is for IPPROTO_HIP, change
++ it to HIP and mark the spd entry as xfrm_hipType
++
++ what happens when a chain of sadb_x_ipsec_request
++ structs contains HIP and non-HIP transforms?  is
++ this even possible?
++
++
++*/
+ 	if (pol->sadb_x_policy_type == IPSEC_POLICY_IPSEC &&
+ 	    (err = parse_ipsecrequests(xp, pol)) < 0)
+ 		goto out;
+@@ -2243,6 +2301,318 @@
+ 
+ 	return 0;
+ }
++#ifdef CONFIG_HIP
++
++#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
++/* these macros sucked in from <netinet/in.h> */
++#define IN6_IS_ADDR_V4MAPPED(a) \
++        ((((__const uint32_t *) (a))[0] == 0)                                 \
++         && (((__const uint32_t *) (a))[1] == 0)                              \
++         && (((__const uint32_t *) (a))[2] == htonl (0xffff)))
++                                                                                
++#define IN6_IS_ADDR_V4COMPAT(a) \
++        ((((__const uint32_t *) (a))[0] == 0)                                 \
++         && (((__const uint32_t *) (a))[1] == 0)                              \
++         && (((__const uint32_t *) (a))[2] == 0)                              \
++         && (ntohl (((__const uint32_t *) (a))[3]) > 1))
++
++/* 
++ * Update a v4-in-v6 address 
++ */
++int hip_change_v6v4(struct in6_addr *addr6, __u32 ip_old, __u32 ip_new)
++{
++	if (IN6_IS_ADDR_V4MAPPED(addr6) || IN6_IS_ADDR_V4COMPAT(addr6)) {
++		/*printk("XXX Found v4 mapped: ");
++		printk("%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x", NIP6(*addr6));
++		printk(" comp %u.%u.%u.%u\n", NIPQUAD(ip_old));*/
++		if (ip_old == addr6->s6_addr32[3]) {
++			addr6->s6_addr32[3] = ip_new;
++			return(1);
++		}
++	}
++	return(0);	
++}
++#endif
++
++/*
++ * Given a sock, replace all occurrences of addr_old with addr_new 
++ * for both IPv4/v6, and return the number of replacements made.
++ */
++int hip_change_address(struct sock *sk, struct sockaddr *addr_old, struct sockaddr *addr_new) 
++{
++	struct inet_sock *inet;
++	__u32 ip_old=-1, ip_new=-1;
++#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
++	struct ipv6_pinfo *inet6;
++	struct in6_addr *ip6_old, *ip6_new;
++#endif
++	int ret=0;
++
++	if (!addr_old || !addr_new)
++		return(0);
++
++#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
++	/* replace IPv4-in-IPv6 addresses */
++	if ((sk->sk_family == AF_INET6) && 
++	    (addr_old->sa_family == AF_INET)) {
++		ip_old = ((struct sockaddr_in *)addr_old)->sin_addr.s_addr;
++		ip_new = ((struct sockaddr_in *)addr_new)->sin_addr.s_addr;
++		inet6 = inet6_sk(sk);
++
++		if (hip_change_v6v4(&inet6->daddr, ip_old, ip_new)) {
++			/* update the destination cache */
++			sk_dst_reset(sk);
++			ret++;
++		}
++		if (hip_change_v6v4(&inet6->rcv_saddr, ip_old, ip_new))
++			ret++;
++		if (hip_change_v6v4(&inet6->saddr, ip_old, ip_new))
++			ret++;
++		return(ret);
++		
++	/* replace IPv6 addresses */
++	} else if ((sk->sk_family == AF_INET6) && 
++	    (addr_old->sa_family == AF_INET6)) {
++		ip6_old = &((struct sockaddr_in6 *)addr_old)->sin6_addr;
++		ip6_new = &((struct sockaddr_in6 *)addr_new)->sin6_addr;
++		inet6 = inet6_sk(sk);
++		
++		if (!ipv6_addr_cmp(&inet6->daddr, ip6_old)) {
++			ipv6_addr_copy(&inet6->daddr, ip6_new);
++			/* update the destination cache */
++			sk_dst_reset(sk);
++			ret++;
++		}
++		if (!ipv6_addr_cmp(&inet6->rcv_saddr, ip6_old)) {
++			ipv6_addr_copy(&inet6->rcv_saddr, ip6_new);
++			ret++;
++		}
++		if (!ipv6_addr_cmp(&inet6->saddr, ip6_old)) {
++			ipv6_addr_copy(&inet6->saddr, ip6_new);
++			ret++;
++		}
++
++		return(ret);
++
++	}
++#endif
++	/* replace IPv4 address */
++	if (sk->sk_family == addr_old->sa_family) {
++		ip_old = ((struct sockaddr_in *)addr_old)->sin_addr.s_addr;
++		ip_new = ((struct sockaddr_in *)addr_new)->sin_addr.s_addr;
++		inet = inet_sk(sk);
++		if (ip_old == inet->daddr) {
++			inet->daddr = ip_new;
++			/* update the destination cache */
++			sk_dst_reset(sk);
++			ret++;
++		}
++		if (ip_old == inet->rcv_saddr) {
++			inet->rcv_saddr = ip_new;
++			ret++;
++		}
++		if (ip_old == inet->saddr) {
++			inet->saddr = ip_new;
++			ret++;
++		}
++	}
++	return(ret);
++}
++
++
++/* 
++ * Perform HIP readdressing tasks for TCPv4/v6 sockets
++ */
++int hip_readdress_tcp_sockets(struct sockaddr *old, struct sockaddr *new)
++{
++	int i;
++	struct hlist_head *list;
++	struct sock *sk_tmp;
++	__u32 ip_old=-1, ip_new=-1;
++	struct hlist_node *node, *t;
++#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
++	struct in6_addr *ip6_old=0, *ip6_new=0;
++
++	if (old->sa_family == AF_INET6) {
++		ip6_old = &((struct sockaddr_in6*)old)->sin6_addr;
++		ip6_new = &((struct sockaddr_in6*)new)->sin6_addr;
++	}
++#endif
++	if (old->sa_family == AF_INET) {
++		ip_old = ((struct sockaddr_in *)old)->sin_addr.s_addr;
++		ip_new = ((struct sockaddr_in *)new)->sin_addr.s_addr;
++	}
++
++	/* listening TCP sockets */
++	tcp_listen_lock();
++	for (i = 0; i < TCP_LHTABLE_SIZE; i++) {
++		list = &tcp_listening_hash[i];
++		sk_for_each_safe(sk_tmp, node, t, list) {
++			if (hip_change_address(sk_tmp, old, new) > 0) {
++				tcp_listen_unlock();
++				sk_tmp->sk_prot->unhash(sk_tmp);
++				sk_tmp->sk_prot->hash(sk_tmp);
++				tcp_listen_lock();
++			}
++		}
++	}
++	tcp_listen_unlock();
++
++	/* established TCP sockets */
++	for (i = 0; i < tcp_ehash_size; i++) {
++		struct tcp_ehash_bucket *head = &tcp_ehash[i];
++		struct tcp_tw_bucket *tw;
++	        
++		read_lock(&head->lock);
++		/* process every socket in this chain */
++		sk_for_each_safe(sk_tmp, node, t, &head->chain) {
++			if (hip_change_address(sk_tmp, old, new) > 0) {
++				read_unlock(&head->lock);
++				sk_tmp->sk_prot->unhash(sk_tmp);
++				sk_tmp->sk_prot->hash(sk_tmp);
++				read_lock(&head->lock);
++			}
++		}
++		/* go through each time wait bucket */
++		sk_for_each(sk_tmp, node, &(head + tcp_ehash_size)->chain) {
++			tw = (struct tcp_tw_bucket *)sk_tmp;
++			if (tw->tw_family == AF_INET) {
++				if (ip_old == tw->tw_daddr)
++					tw->tw_daddr = ip_new;
++				if (ip_old == tw->tw_rcv_saddr)
++					tw->tw_daddr = ip_new;
++			}
++#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
++			else if (tw->tw_family == AF_INET6) {
++				/* look for v6-mapped v4 addresses */
++				if (old->sa_family == AF_INET) {
++					hip_change_v6v4(&tw->tw_v6_daddr,
++							ip_old, ip_new);
++					hip_change_v6v4(&tw->tw_v6_rcv_saddr,
++							ip_old, ip_new);
++					sk_for_each_continue(sk_tmp, node);
++				}
++				/* compare as normal IPv6 address */
++				if (old->sa_family != AF_INET6)
++					sk_for_each_continue(sk_tmp, node);
++				if (!(ipv6_addr_cmp(&tw->tw_v6_daddr, ip6_old)))
++				    ipv6_addr_copy(&tw->tw_v6_daddr,ip6_new);
++				if (!(ipv6_addr_cmp(&tw->tw_v6_rcv_saddr,
++						    ip6_old)))
++				    ipv6_addr_copy(&tw->tw_v6_rcv_saddr,
++						   ip6_new);
++			}
++#endif
++		}
++	        read_unlock(&head->lock);
++	}
++
++	return(0);
++}
++
++/* 
++ * Perform HIP readdressing tasks for UDPv4/v6 sockets 
++ */
++int hip_readdress_udp_sockets(struct sockaddr *old, struct sockaddr *new)
++{
++	int i;
++	struct hlist_head *list;
++	struct sock *sk_tmp;
++	struct hlist_node *node;
++	
++	/* update UDP sockets */
++	write_lock_bh(&udp_hash_lock);
++	for (i = 0; i < UDP_HTABLE_SIZE; i++) {
++		list = &udp_hash[i];
++		sk_for_each(sk_tmp, node, list) {
++			hip_change_address(sk_tmp, old, new);
++		}
++	}
++	write_unlock_bh(&udp_hash_lock);
++
++	return(0);
++}
++
++/* 
++ * Perform HIP readdressing tasks for RAWv4/v6 sockets 
++ */
++int hip_readdress_raw_sockets(struct sockaddr *old, struct sockaddr *new)
++{
++	int i;
++	struct hlist_head *list;
++	struct sock *sk_tmp;
++	struct hlist_node *node;
++	
++	/* update RAW IPv4 sockets */
++	write_lock_bh(&raw_v4_lock);
++	for (i = 0; i < RAWV4_HTABLE_SIZE; i++) {
++		list = &raw_v4_htable[i];
++		sk_for_each(sk_tmp, node, list) {
++			hip_change_address(sk_tmp, old, new);
++		}
++	}
++	write_unlock_bh(&raw_v4_lock);
++	
++	return(0);
++}
++
++/*
++ * Handle the SADB_READDRESS message, where SRC is the old address and DST
++ * is the new address, and dispatch various readdressing tasks.
++ */
++static int pfkey_readdress(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs)
++{
++	struct sadb_address *pfk_addr_old, *pfk_addr_new;
++	struct sadb_sa *sa_in;
++	struct sk_buff *out_skb;
++	struct sadb_msg *out_hdr;
++	int size, sockaddr_size;
++	struct sockaddr *addr_old, *addr_new;
++
++	/*
++	 * handle a readdress message
++	 * here src = old address, dst = new address
++	 */
++	if (!present_and_same_family(ext_hdrs[SADB_EXT_ADDRESS_SRC-1],
++				     ext_hdrs[SADB_EXT_ADDRESS_DST-1]))
++		return(-EINVAL);
++	sa_in = ext_hdrs[SADB_EXT_SA-1];
++	pfk_addr_old = ext_hdrs[SADB_EXT_ADDRESS_SRC-1];
++	pfk_addr_new = ext_hdrs[SADB_EXT_ADDRESS_DST-1];
++	addr_old = (struct sockaddr *)(pfk_addr_old + 1);
++	addr_new = (struct sockaddr *)(pfk_addr_new + 1);
++
++	/* 
++	 * perform readdress in all kernel sockets
++	 */	
++	local_bh_disable(); /* disable soft interrupts on local CPU */
++	hip_readdress_tcp_sockets(addr_old, addr_new);
++	hip_readdress_udp_sockets(addr_old, addr_new);
++	hip_readdress_raw_sockets(addr_old, addr_new);
++	local_bh_enable(); /* re-enable soft interrupts on local CPU */
++
++	/*
++	 * send back a SADB_READDRESS response (header only)
++	 */
++	sockaddr_size = pfkey_sockaddr_size(addr_old->sa_family);
++	size = sizeof(struct sadb_msg);
++	out_skb =  alloc_skb(size + 16, GFP_ATOMIC);
++	if (out_skb == NULL)
++		return(-ENOBUFS);
++	out_hdr = (struct sadb_msg *) skb_put(out_skb, sizeof(struct sadb_msg));
++	memset(out_hdr, 0, size);
++	hdr->sadb_msg_len = size / sizeof(uint64_t);
++	out_hdr->sadb_msg_version = hdr->sadb_msg_version;
++	out_hdr->sadb_msg_type = SADB_READDRESS;
++	out_hdr->sadb_msg_satype = 0;
++	out_hdr->sadb_msg_errno = 0;
++	out_hdr->sadb_msg_seq = hdr->sadb_msg_seq;
++	out_hdr->sadb_msg_pid = hdr->sadb_msg_pid;
++	pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ALL, sk);
++
++	return(0);
++}
++#endif
+ 
+ typedef int (*pfkey_handler)(struct sock *sk, struct sk_buff *skb,
+ 			     struct sadb_msg *hdr, void **ext_hdrs);
+@@ -2269,6 +2639,9 @@
+ 	[SADB_X_SPDFLUSH]	= pfkey_spdflush,
+ 	[SADB_X_SPDSETIDX]	= pfkey_spdadd,
+ 	[SADB_X_SPDDELETE2]	= pfkey_spdget,
++#ifdef CONFIG_HIP
++	[SADB_READDRESS]	= pfkey_readdress,
++#endif
+ };
+ 
+ static int pfkey_process(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr)
+@@ -2558,6 +2931,12 @@
+ 	hdr = (struct sadb_msg *) skb_put(skb, sizeof(struct sadb_msg));
+ 	hdr->sadb_msg_version = PF_KEY_V2;
+ 	hdr->sadb_msg_type = SADB_ACQUIRE;
++#ifdef CONFIG_HIP
++	if(xp->xfrm_hipType) {
++//		printk("munging message to SADB_HIP_ACQUIRE\n");
++		hdr->sadb_msg_type = SADB_HIP_ACQUIRE;
++	}
++#endif
+ 	hdr->sadb_msg_satype = pfkey_proto2satype(x->id.proto);
+ 	hdr->sadb_msg_len = size / sizeof(uint64_t);
+ 	hdr->sadb_msg_errno = 0;
+--- linux-2.6.13.5/net/ipv4/route.c	2005-12-15 10:38:27.000000000 -0800
++++ linux-2.6.13.5-hip/net/ipv4/route.c	2006-05-04 16:49:03.000000000 -0700
+@@ -2607,6 +2607,12 @@
+ 	if ((err = __ip_route_output_key(rp, flp)) != 0)
+ 		return err;
+ 
++#ifdef CONFIG_HIP
++	/* use xfrm policy #0 for hip protocol packets */	
++	if((sk) && ( sk->sk_protocol == IPPROTO_HIP)) {
++		return 0;
++	}
++#endif
+ 	if (flp->proto) {
+ 		if (!flp->fl4_src)
+ 			flp->fl4_src = (*rp)->rt_src;
+--- linux-2.6.13.5/net/ipv4/esp4.c	2005-12-15 10:38:27.000000000 -0800
++++ linux-2.6.13.5-hip/net/ipv4/esp4.c	2006-05-04 16:49:03.000000000 -0700
+@@ -3,6 +3,9 @@
+ #include <net/ip.h>
+ #include <net/xfrm.h>
+ #include <net/esp.h>
++#ifdef CONFIG_HIP
++#include <net/checksum.h>
++#endif
+ #include <asm/scatterlist.h>
+ #include <linux/crypto.h>
+ #include <linux/pfkeyv2.h>
+@@ -30,6 +33,28 @@
+ 	int alen;
+ 	int nfrags;
+ 
++#ifdef CONFIG_HIP  /* replace TCP or UDP checksum with HIP csum */
++	if((x) && (x->xfrm_hipType)) {
++		struct iphdr *iph=NULL;
++		struct tcphdr *th=NULL;
++		struct udphdr *uh=NULL;
++                
++		iph = skb->nh.iph;
++		if(iph->protocol == IPPROTO_TCP) {
++			th = skb->h.th;
++			if (th) {
++				th->check =csum_tcpudp_hip_nofold(iph->saddr,
++				    iph->daddr, th->check, x->hitMagic);
++			}
++		} else if(iph->protocol==IPPROTO_UDP) {
++			uh = skb->h.uh;
++			if (uh) {
++				uh->check =csum_tcpudp_hip_nofold(iph->saddr,
++				    iph->daddr, uh->check, x->hitMagic);
++			}
++		}
++	}
++#endif
+ 	/* Strip IP+ESP header. */
+ 	__skb_pull(skb, skb->h.raw - skb->data);
+ 	/* Now skb is pure payload to encrypt */
+@@ -238,6 +263,32 @@
+ 		skb->nh.iph->tot_len = htons(skb->len);
+ 	}
+ 
++#ifdef CONFIG_HIP  /* replace TCP or UDP checksum with HIP csum */
++	if((x) && (x->xfrm_hipType)) {
++		struct iphdr *iph=NULL;
++		struct tcphdr *th=NULL;
++		struct udphdr *uh=NULL;
++		unsigned short csum=0;
++               
++		iph = skb->nh.iph;
++		if(iph->protocol == IPPROTO_TCP) {
++    			th = skb->h.th;
++			if (th) {
++        			th->check = csum_hip_revert(iph->saddr,
++				    iph->daddr, th->check, x->hitMagic);
++				csum = th->check;
++			}	
++    		} else if(iph->protocol==IPPROTO_UDP) {
++    			uh = skb->h.uh;
++			if (uh) {
++        			uh->check = csum_hip_revert(iph->saddr,
++				    iph->daddr, uh->check, x->hitMagic);
++				csum = uh->check;
++			}
++		}
++	}
++#endif
++	/* Strip IP header in transport mode. Save it. */
+ 	return 0;
+ 
<<Diff was trimmed, longer than 597 lines>>


More information about the pld-cvs-commit mailing list