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