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>>
_______________________________________________
pld-cvs-commit mailing list
[email protected]
http://lists.pld-linux.org/mailman/listinfo/pld-cvs-commit

Reply via email to