⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hipmod-sleep-beet-and-interfamily-all-in-one.patch

📁 HIP:Host Identity Protocol
💻 PATCH
📖 第 1 页 / 共 3 页
字号:
diff -urN  a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c--- a/net/ipv4/xfrm4_input.c 2007-05-25 12:21:11.000000000 +0300+++ b/net/ipv4/xfrm4_input.c 2007-05-25 12:21:11.000000000 +0300@@ -13,6 +13,7 @@ #include <linux/string.h> #include <linux/netfilter.h> #include <linux/netfilter_ipv4.h>+#include <net/inet_ecn.h> #include <net/ip.h> #include <net/xfrm.h> @@ -23,6 +24,15 @@  EXPORT_SYMBOL(xfrm4_rcv); +static inline void ipip_ecn_decapsulate(struct sk_buff *skb)+{+	struct iphdr *outer_iph = skb->nh.iph;+	struct iphdr *inner_iph = skb->h.ipiph;++	if (INET_ECN_is_ce(outer_iph->tos))+		IP_ECN_set_ce(inner_iph);+}+ static int xfrm4_parse_spi(struct sk_buff *skb, u8 nexthdr, u32 *spi, u32 *seq) { 	switch (nexthdr) {@@ -103,11 +113,11 @@  		xfrm_vec[xfrm_nr++] = x; -		if (x->mode->input(x, skb))+                if (x->mode->input(x, skb)) 			goto drop;-+		 		if (x->props.mode) {-			decaps = 1;+		        decaps = 1; 			break; 		} diff -urN  a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c--- a/net/ipv4/xfrm4_output.c 2007-05-25 12:21:11.000000000 +0300+++ b/net/ipv4/xfrm4_output.c 2007-05-25 12:21:11.000000000 +0300@@ -14,10 +14,12 @@ #include <linux/skbuff.h> #include <linux/spinlock.h> #include <linux/netfilter_ipv4.h>+#include <net/inet_ecn.h> #include <net/ip.h> #include <net/xfrm.h> #include <net/icmp.h> + static int xfrm4_tunnel_check_size(struct sk_buff *skb) { 	int mtu, ret = 0;@@ -54,7 +56,7 @@ 			goto error_nolock; 	} -	if (x->props.mode) {+	if (x->props.mode == XFRM_MODE_TUNNEL) { 		err = xfrm4_tunnel_check_size(skb); 		if (err) 			goto error_nolock;@@ -66,7 +68,7 @@ 		if (err) 			goto error; -		err = x->mode->output(skb);+                err = x->mode->output(skb); 		if (err) 			goto error; @@ -85,6 +87,7 @@ 		} 		dst = skb->dst; 		x = dst->xfrm;+ 	} while (x && !x->props.mode);  	IPCB(skb)->flags |= IPSKB_XFRM_TRANSFORMED;diff -urN  a/net/ipv4/xfrm4_tunnel.c b/net/ipv4/xfrm4_tunnel.c--- a/net/ipv4/xfrm4_tunnel.c 2007-05-25 12:21:11.000000000 +0300+++ b/net/ipv4/xfrm4_tunnel.c 2007-05-25 12:21:11.000000000 +0300@@ -28,13 +28,20 @@  static int ipip_init_state(struct xfrm_state *x) {-	if (!x->props.mode)-		return -EINVAL;- 	if (x->encap) 		return -EINVAL; -	x->props.header_len = sizeof(struct iphdr);+	switch (x->props.mode) {+	case XFRM_MODE_TRANSPORT:+		return -EINVAL;+	default:+	case XFRM_MODE_TUNNEL:+		x->props.header_len = sizeof(struct iphdr);+		break;+	case XFRM_MODE_BEET:+		x->props.header_len += IPV4_BEET_PHMAXLEN;+		break;+	}  	return 0; }diff -urN  a/net/ipv4/route.c b/net/ipv4/route.c--- a/net/ipv4/route.c 2007-05-25 12:21:11.000000000 +0300+++ b/net/ipv4/route.c 2007-05-25 12:21:11.000000000 +0300@@ -108,6 +108,7 @@ #ifdef CONFIG_SYSCTL #include <linux/sysctl.h> #endif+#include <linux/xfrm.h>  #define RT_FL_TOS(oldflp) \     ((u32)(oldflp->fl4_tos & (IPTOS_RT_MASK | RTO_ONLINK)))@@ -2631,7 +2632,7 @@  int ip_route_output_key(struct rtable **rp, struct flowi *flp) {-	return ip_route_output_flow(rp, flp, NULL, 0);+	return ip_route_output_flow(rp, flp, NULL, XFRM_LOOKUP_SLEEP); }  static int rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event,diff -urN  a/net/ipv4/ah4.c b/net/ipv4/ah4.c--- a/net/ipv4/ah4.c 2007-05-25 12:21:11.000000000 +0300+++ b/net/ipv4/ah4.c 2007-05-25 12:21:11.000000000 +0300@@ -253,8 +253,10 @@ 		goto error; 	 	x->props.header_len = XFRM_ALIGN8(sizeof(struct ip_auth_hdr) + ahp->icv_trunc_len);-	if (x->props.mode)+	if (x->props.mode == XFRM_MODE_TUNNEL) 		x->props.header_len += sizeof(struct iphdr);+	else if (x->props.mode == XFRM_MODE_BEET)+		x->props.header_len += IPV4_BEET_PHMAXLEN; 	x->data = ahp;  	return 0;diff -urN  a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c--- a/net/ipv4/xfrm4_policy.c 2007-05-25 12:21:11.000000000 +0300+++ b/net/ipv4/xfrm4_policy.c 2007-05-25 12:21:11.000000000 +0300@@ -16,6 +16,8 @@ static struct dst_ops xfrm4_dst_ops; static struct xfrm_policy_afinfo xfrm4_policy_afinfo; +static void xfrm4_update_pmtu(struct dst_entry *dst, u32 mtu);+ static int xfrm4_dst_lookup(struct xfrm_dst **dst, struct flowi *fl) { 	return __ip_route_output_key((struct rtable**)dst, fl);@@ -53,17 +55,20 @@ 	struct dst_entry *dst, *dst_prev; 	struct rtable *rt0 = (struct rtable*)(*dst_p); 	struct rtable *rt = rt0;-	u32 remote = fl->fl4_dst;-	u32 local  = fl->fl4_src; 	struct flowi fl_tunnel = { 		.nl_u = { 			.ip4_u = {-				.saddr = local,-				.daddr = remote,+				.saddr = fl->fl4_dst,+				.daddr = fl->fl4_src, 				.tos = fl->fl4_tos 			} 		} 	};+	union {+		struct in6_addr *in6;+		struct in_addr *in;+	} remote, local;+	unsigned short outer_family = 0, beet = 0; 	int i; 	int err; 	int header_len = 0;@@ -75,7 +80,6 @@ 	for (i = 0; i < nx; i++) { 		struct dst_entry *dst1 = dst_alloc(&xfrm4_dst_ops); 		struct xfrm_dst *xdst;-		int tunnel = 0;  		if (unlikely(dst1 == NULL)) { 			err = -ENOBUFS;@@ -96,21 +100,45 @@  		dst1->next = dst_prev; 		dst_prev = dst1;-		if (xfrm[i]->props.mode) {-			remote = xfrm[i]->id.daddr.a4;-			local  = xfrm[i]->props.saddr.a4;-			tunnel = 1;++		if (xfrm[i]->props.mode == XFRM_MODE_TUNNEL || xfrm[i]->props.mode == XFRM_MODE_BEET) {+			outer_family = xfrm[i]->props.family;+			beet = (xfrm[i]->props.mode == XFRM_MODE_BEET);++			if(outer_family == AF_INET6){+				remote.in6 = (struct in6_addr*)&xfrm[i]->id.daddr;+				local.in6 = (struct in6_addr*)&xfrm[i]->props.saddr;+			} else if(outer_family == AF_INET){+				remote.in = (struct in_addr*)&xfrm[i]->id.daddr;+				local.in = (struct in_addr*)&xfrm[i]->props.saddr;+			} else+				BUG_ON(1); 		} 		header_len += xfrm[i]->props.header_len; 		trailer_len += xfrm[i]->props.trailer_len; -		if (tunnel) {-			fl_tunnel.fl4_src = local;-			fl_tunnel.fl4_dst = remote;+		if (outer_family) {+			switch(outer_family) {+			case AF_INET:+				fl_tunnel.fl4_dst = remote.in->s_addr;+				fl_tunnel.fl4_src = local.in->s_addr;+				break;+			case AF_INET6:+				ipv6_addr_copy(&fl_tunnel.fl6_dst, remote.in6);+				ipv6_addr_copy(&fl_tunnel.fl6_src, local.in6);+				break;+			default:+				BUG_ON(1);+			} 			err = xfrm_dst_lookup((struct xfrm_dst **)&rt,-					      &fl_tunnel, AF_INET);+					      &fl_tunnel, outer_family); 			if (err) 				goto error;+			/* Without this, the atomic inc below segfaults */+			if (outer_family == AF_INET6) {+				rt->peer = NULL;+				rt_bind_peer(rt,1);+			} 		} else 			dst_hold(&rt->u.dst); 	}@@ -160,6 +188,11 @@ 	}  	xfrm_init_pmtu(dst);+	if (beet && outer_family == AF_INET6) {+		int delta = sizeof(struct ipv6hdr) - sizeof(struct iphdr);+		u32 mtu = dst_mtu(dst);+		xfrm4_update_pmtu(dst, mtu - delta);+	} 	return 0;  error:diff -urN  a/net/ipv4/xfrm4_mode_tunnel.c b/net/ipv4/xfrm4_mode_tunnel.c--- a/net/ipv4/xfrm4_mode_tunnel.c 2007-05-25 12:21:11.000000000 +0300+++ b/net/ipv4/xfrm4_mode_tunnel.c 2007-05-25 12:21:11.000000000 +0300@@ -33,7 +33,7 @@  * On exit, skb->h will be set to the start of the payload to be processed  * by x->type->output and skb->nh will be set to the top IP header.  */-static int xfrm4_tunnel_output(struct sk_buff *skb)+ static int xfrm4_tunnel_output(struct sk_buff *skb) { 	struct dst_entry *dst = skb->dst; 	struct xfrm_state *x = dst->xfrm;@@ -98,6 +98,182 @@ 	return err; } +/* jk: this should be moved to the beet module! */+static int xfrm4_beet_output(struct sk_buff *skb)+{+        struct dst_entry *dst = skb->dst;+        struct xfrm_state *x = dst->xfrm;+        int hdrlen;+        struct iphdr *iphv4, *top_iphv4;+        struct ipv6hdr *iphv6, *top_iphv6;++        if (skb->nh.iph->version == 4) {+                +                int optlen;++                /* 4-4 */++                iphv4 = skb->nh.iph;+                skb->h.ipiph = iphv4;+                +                hdrlen = x->props.header_len;+                +                optlen = iphv4->ihl * 4 - sizeof(*iphv4);+                if (!optlen) {+                        hdrlen -= IPV4_BEET_PHMAXLEN;+                } else {+                        skb->h.raw -= (IPV4_BEET_PHMAXLEN - (optlen & 4));+                        hdrlen -= optlen & 4;+                }+                +                skb->nh.raw = skb_push(skb, hdrlen);+                top_iphv4 = skb->nh.iph;+                +                hdrlen = iphv4->ihl * 4 - optlen;+                skb->h.raw += hdrlen;+                memmove(top_iphv4, iphv4, hdrlen);+                +                if (unlikely(optlen)) {+                        struct ip_beet_phdr *ph;+                        +                        BUG_ON(optlen < 0);+                        +                        ph = (struct ip_beet_phdr *)skb->h.raw;+                        ph->padlen = 4 - (optlen & 4);+                        ph->hdrlen = (optlen + ph->padlen + sizeof(*ph)) / 8;+                        ph->nexthdr = iphv4->protocol;+                        top_iphv4->protocol = IPPROTO_BEETPH;+                        top_iphv4->ihl = sizeof(struct iphdr) / 4;+                }+                +                top_iphv4->saddr = x->props.saddr.a4;+                top_iphv4->daddr = x->id.daddr.a4;+                +	} else if (skb->nh.iph->version == 6) {+                +                u8 protocol;+                int delta = sizeof(struct ipv6hdr) - sizeof(struct iphdr);++                /* Inner = 6, Outer = 4 : changing the external IP hdr+                 * to the outer addresses+                 */++                hdrlen = x->props.header_len - IPV4_BEET_PHMAXLEN;+                skb_push(skb, hdrlen);+                iphv6 = skb->nh.ipv6h;+                +                skb->nh.raw = skb->data;+                top_iphv6 = skb->nh.ipv6h;++                protocol = iphv6->nexthdr;+                skb->nh.raw = skb_pull(skb, delta);+                top_iphv4 = skb->nh.iph;+                skb->h.raw = skb->data + hdrlen;+                top_iphv4->ihl = (sizeof(struct iphdr) >> 2);+                top_iphv4->version = 4;+                top_iphv4->id = 0;+                top_iphv4->frag_off = htons(IP_DF);+                top_iphv4->ttl = dst_metric(dst->child, RTAX_HOPLIMIT);+                top_iphv4->saddr = x->props.saddr.a4;+                top_iphv4->daddr = x->id.daddr.a4;+                skb->h.raw += top_iphv4->ihl*4;+                top_iphv4->protocol = protocol;+         +        } else +                BUG_ON(1);+        +	return 0;+}+++/* jk: this should be moved to the beet module! */+static int xfrm4_beet_input(struct xfrm_state *x, struct sk_buff *skb)+{+        int err = -EINVAL;+        int phlen = 0;+        int optlen = 0;+        __u8 ph_nexthdr = 0;+        int size = (x->sel.family == AF_INET) ? sizeof(struct iphdr) : sizeof(struct ipv6hdr);+        int proto = skb->nh.iph->protocol;+        int hops = skb->nh.iph->ttl;+        int delta = sizeof(struct ipv6hdr) - sizeof(struct iphdr);+      +        if (x->sel.family == AF_INET6) {+                /* Here, the inner family is 6, therefore I have to+                 * substitute the IPhdr by enlarging it */+                if (skb_tailroom(skb) <  delta){+                        if (pskb_expand_head(skb, 0, delta, GFP_ATOMIC))+                                goto out;		//Just returning from here.+                }++                skb->nh.raw -= delta;+        } else if (x->sel.family == AF_INET) {+                // We need to extract the PH+                struct ip_beet_phdr *ph = (struct ip_beet_phdr*)(skb->nh.iph + 1);++                if (proto == IPPROTO_BEETPH) {+                        if (!pskb_may_pull(skb, sizeof(*ph)))+                                goto out;+                        phlen = ph->hdrlen * 8;+                        optlen = phlen - ph->padlen - sizeof(*ph);++                        if (optlen < 0 || optlen & 3 || optlen > 250)+                                goto out;+                        if (!pskb_may_pull(skb, phlen))+                                goto out;++                        ph_nexthdr = ph->nexthdr;+                }+        } else+                BUG_ON(1);++        if (skb_cloned(skb) &&+            pskb_expand_head(skb, 0, 0, GFP_ATOMIC))+                goto out;+  +        skb_push(skb, size);+        memmove(skb->data, skb->nh.raw, size);+        skb->nh.raw = skb->data;++        if (x->sel.family == AF_INET) {+                struct iphdr *iph = skb->nh.iph;++                if (unlikely(phlen)) {+                        skb_pull(skb, phlen - optlen);+                        memmove(skb->data, skb->nh.raw, sizeof(*iph));+                        skb->nh.raw = skb->data;+                        iph = skb->nh.iph;+                }++                iph->ihl = (sizeof(*iph) + optlen) / 4;+                iph->tot_len = htons(skb->len);+                iph->daddr = x->sel.daddr.a4;+                iph->saddr = x->sel.saddr.a4;+                if (ph_nexthdr)+                        iph->protocol = ph_nexthdr;+                else+                        iph->protocol = proto;+                ip_send_check(iph);+        } else if (x->sel.family == AF_INET6) {+                struct ipv6hdr *ip6h = skb->nh.ipv6h;++                memset(ip6h->flow_lbl, 0, sizeof(ip6h->flow_lbl));+                ip6h->version = 6;+                ip6h->priority = 0;+                ip6h->nexthdr = proto;+                ip6h->hop_limit = hops;+                ip6h->payload_len = htons(skb->len - size);+                ipv6_addr_copy(&ip6h->daddr, (struct in6_addr *)&x->sel.daddr.a6);+                ipv6_addr_copy(&ip6h->saddr, (struct in6_addr *)&x->sel.saddr.a6);+                skb->protocol = htons(ETH_P_IPV6);+        }++        err = 0;+ out:++        return err;+}+ static struct xfrm_mode xfrm4_tunnel_mode = { 	.input = xfrm4_tunnel_input, 	.output = xfrm4_tunnel_output,@@ -105,8 +281,19 @@ 	.encap = XFRM_MODE_TUNNEL, }; +/* jk: this should be moved to the beet module! */+static struct xfrm_mode xfrm4_beet_mode = {+	.input = xfrm4_beet_input,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -