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

📄 beet-interfamily-and-sleep-loopback-2.6.19.7.patch

📁 HIP:Host Identity Protocol
💻 PATCH
📖 第 1 页 / 共 4 页
字号:
-		printk(KERN_INFO "ipip init: can't add xfrm handler\n");++	if (xfrm4_tunnel_register(&xfrm_tunnel_handler, AF_INET)) {+		printk(KERN_INFO "ipip init: can't add xfrm handler for AF_INET\n");+		xfrm_unregister_type(&ipip_type, AF_INET);+		return -EAGAIN;+	}+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)+	if (xfrm4_tunnel_register(&xfrm64_tunnel_handler, AF_INET6)) {+		printk(KERN_INFO "ipip init: can't add xfrm handler for AF_INET6\n");+		xfrm4_tunnel_deregister(&xfrm_tunnel_handler, AF_INET); 		xfrm_unregister_type(&ipip_type, AF_INET); 		return -EAGAIN; 	}+#endif 	return 0; }  static void __exit ipip_fini(void) {-	if (xfrm4_tunnel_deregister(&xfrm_tunnel_handler))-		printk(KERN_INFO "ipip close: can't remove xfrm handler\n");+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)+	if (xfrm4_tunnel_deregister(&xfrm64_tunnel_handler, AF_INET6))+		printk(KERN_INFO "ipip close: can't remove xfrm handler for AF_INET6\n");+#endif+	if (xfrm4_tunnel_deregister(&xfrm_tunnel_handler, AF_INET))+		printk(KERN_INFO "ipip close: can't remove xfrm handler for AF_INET\n"); 	if (xfrm_unregister_type(&ipip_type, AF_INET) < 0) 		printk(KERN_INFO "ipip close: can't remove xfrm type\n"); }diff -urN  a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c--- a/net/ipv4/tcp_ipv4.c 2007-05-25 14:44:51.000000000 +0300+++ b/net/ipv4/tcp_ipv4.c 2007-05-25 14:44:51.000000000 +0300@@ -179,7 +179,7 @@ 	tmp = ip_route_connect(&rt, nexthop, inet->saddr, 			       RT_CONN_FLAGS(sk), sk->sk_bound_dev_if, 			       IPPROTO_TCP,-			       inet->sport, usin->sin_port, sk);+			       inet->sport, usin->sin_port, sk, 1); 	if (tmp < 0) 		return tmp; diff -urN  a/net/ipv4/udp.c b/net/ipv4/udp.c--- a/net/ipv4/udp.c 2007-05-25 14:44:51.000000000 +0300+++ b/net/ipv4/udp.c 2007-05-25 14:44:51.000000000 +0300@@ -630,7 +630,7 @@ 					       { .sport = inet->sport, 						 .dport = dport } } }; 		security_sk_classify_flow(sk, &fl);-		err = ip_route_output_flow(&rt, &fl, sk, !(msg->msg_flags&MSG_DONTWAIT));+		err = ip_route_output_flow(&rt, &fl, sk, 1); 		if (err) 			goto out; diff -urN  a/net/ipv4/route.c b/net/ipv4/route.c--- a/net/ipv4/route.c 2007-05-25 14:44:51.000000000 +0300+++ b/net/ipv4/route.c 2007-05-25 14:44:51.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)))diff -urN  a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c--- a/net/ipv4/af_inet.c 2007-05-25 14:44:51.000000000 +0300+++ b/net/ipv4/af_inet.c 2007-05-25 14:44:51.000000000 +0300@@ -1006,7 +1006,7 @@ 			       RT_CONN_FLAGS(sk), 			       sk->sk_bound_dev_if, 			       sk->sk_protocol,-			       inet->sport, inet->dport, sk);+			       inet->sport, inet->dport, sk, 0); 	if (err) 		return err; diff -urN  a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c--- a/net/ipv4/xfrm4_input.c 2007-05-25 14:44:52.000000000 +0300+++ b/net/ipv4/xfrm4_input.c 2007-05-25 14:44:52.000000000 +0300@@ -106,7 +106,7 @@ 		if (x->mode->input(x, skb)) 			goto drop; -		if (x->props.mode == XFRM_MODE_TUNNEL) {+		if (x->props.mode == XFRM_MODE_TUNNEL || x->props.mode == XFRM_MODE_BEET) { 			decaps = 1; 			break; 		}@@ -136,10 +136,8 @@ 	nf_reset(skb);  	if (decaps) {-		if (!(skb->dev->flags&IFF_LOOPBACK)) {-			dst_release(skb->dst);-			skb->dst = NULL;-		}+                dst_release(skb->dst);+                skb->dst = NULL; 		netif_rx(skb); 		return 0; 	} else {diff -urN  a/net/ipv4/raw.c b/net/ipv4/raw.c--- a/net/ipv4/raw.c 2007-05-25 14:44:52.000000000 +0300+++ b/net/ipv4/raw.c 2007-05-25 14:44:52.000000000 +0300@@ -489,7 +489,7 @@ 		}  		security_sk_classify_flow(sk, &fl);-		err = ip_route_output_flow(&rt, &fl, sk, !(msg->msg_flags&MSG_DONTWAIT));+		err = ip_route_output_flow(&rt, &fl, sk, 1); 	} 	if (err) 		goto done;diff -urN  a/net/ipv4/tunnel4.c b/net/ipv4/tunnel4.c--- a/net/ipv4/tunnel4.c 2007-05-25 14:44:52.000000000 +0300+++ b/net/ipv4/tunnel4.c 2007-05-25 14:44:52.000000000 +0300@@ -14,9 +14,10 @@ #include <net/xfrm.h>  static struct xfrm_tunnel *tunnel4_handlers;+static struct xfrm_tunnel *tunnel64_handlers; static DEFINE_MUTEX(tunnel4_mutex); -int xfrm4_tunnel_register(struct xfrm_tunnel *handler)+int xfrm4_tunnel_register(struct xfrm_tunnel *handler, unsigned short family) { 	struct xfrm_tunnel **pprev; 	int ret = -EEXIST;@@ -24,7 +25,8 @@  	mutex_lock(&tunnel4_mutex); -	for (pprev = &tunnel4_handlers; *pprev; pprev = &(*pprev)->next) {+	for (pprev = (family == AF_INET) ? &tunnel4_handlers : &tunnel64_handlers;+	     *pprev; pprev = &(*pprev)->next) { 		if ((*pprev)->priority > priority) 			break; 		if ((*pprev)->priority == priority)@@ -44,14 +46,15 @@  EXPORT_SYMBOL(xfrm4_tunnel_register); -int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler)+int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler, unsigned short family) { 	struct xfrm_tunnel **pprev; 	int ret = -ENOENT;  	mutex_lock(&tunnel4_mutex); -	for (pprev = &tunnel4_handlers; *pprev; pprev = &(*pprev)->next) {+	for (pprev = (family == AF_INET) ? &tunnel4_handlers : &tunnel64_handlers;+	     *pprev; pprev = &(*pprev)->next) { 		if (*pprev == handler) { 			*pprev = handler->next; 			ret = 0;@@ -86,6 +89,26 @@ 	return 0; } +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)+static int tunnel64_rcv(struct sk_buff *skb)+{+	struct xfrm_tunnel *handler;++	if (!pskb_may_pull(skb, sizeof(struct iphdr)))+		goto drop;++	for (handler = tunnel64_handlers; handler; handler = handler->next)+		if (!handler->handler(skb))+			return 0;++	icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);++drop:+	kfree_skb(skb);+	return 0;+}+#endif+ static void tunnel4_err(struct sk_buff *skb, u32 info) { 	struct xfrm_tunnel *handler;@@ -101,17 +124,36 @@ 	.no_policy	=	1, }; +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)+static struct net_protocol tunnel64_protocol = {+	.handler	=	tunnel64_rcv,+	.err_handler	=	tunnel4_err,+	.no_policy	=	1,+};+#endif+ static int __init tunnel4_init(void) { 	if (inet_add_protocol(&tunnel4_protocol, IPPROTO_IPIP)) { 		printk(KERN_ERR "tunnel4 init: can't add protocol\n"); 		return -EAGAIN; 	}+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)+	if (inet_add_protocol(&tunnel64_protocol, IPPROTO_IPV6)) {+		printk(KERN_ERR "tunnel64 init: can't add protocol\n");+		inet_del_protocol(&tunnel4_protocol, IPPROTO_IPIP);+		return -EAGAIN;+	}+#endif 	return 0; }  static void __exit tunnel4_fini(void) {+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)+	if (inet_del_protocol(&tunnel64_protocol, IPPROTO_IPV6))+		printk(KERN_ERR "tunnel64 close: can't remove protocol\n");+#endif 	if (inet_del_protocol(&tunnel4_protocol, IPPROTO_IPIP)) 		printk(KERN_ERR "tunnel4 close: can't remove protocol\n"); }diff -urN  a/net/ipv4/datagram.c b/net/ipv4/datagram.c--- a/net/ipv4/datagram.c 2007-05-25 14:44:52.000000000 +0300+++ b/net/ipv4/datagram.c 2007-05-25 14:44:52.000000000 +0300@@ -49,7 +49,7 @@ 	err = ip_route_connect(&rt, usin->sin_addr.s_addr, saddr, 			       RT_CONN_FLAGS(sk), oif, 			       sk->sk_protocol,-			       inet->sport, usin->sin_port, sk);+			       inet->sport, usin->sin_port, sk, 1); 	if (err) 		return err; 	if ((rt->rt_flags & RTCF_BROADCAST) && !sock_flag(sk, SOCK_BROADCAST)) {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 14:44:52.000000000 +0300+++ b/net/ipv4/xfrm4_mode_tunnel.c 2007-05-25 14:44:52.000000000 +0300@@ -66,6 +66,8 @@ 	top_iph->daddr = x->id.daddr.a4; 	top_iph->protocol = IPPROTO_IPIP; +        skb->protocol = htons(ETH_P_IP);+ 	memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options)); 	return 0; }diff -urN  a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c--- a/net/ipv6/xfrm6_policy.c 2007-05-25 14:44:52.000000000 +0300+++ b/net/ipv6/xfrm6_policy.c 2007-05-25 14:44:52.000000000 +0300@@ -24,6 +24,7 @@  static struct dst_ops xfrm6_dst_ops; static struct xfrm_policy_afinfo xfrm6_policy_afinfo;+static void xfrm6_update_pmtu(struct dst_entry *dst, u32 mtu);  static int xfrm6_dst_lookup(struct xfrm_dst **xdst, struct flowi *fl) {@@ -89,7 +90,7 @@ static inline struct in6_addr* __xfrm6_bundle_addr_remote(struct xfrm_state *x, struct in6_addr *addr) {-	return (x->type->remote_addr) ?+	return (x->type && x->type->remote_addr) ? 		(struct in6_addr*)x->type->remote_addr(x, (xfrm_address_t *)addr) : 		(struct in6_addr*)&x->id.daddr; }@@ -97,7 +98,7 @@ static inline struct in6_addr* __xfrm6_bundle_addr_local(struct xfrm_state *x, struct in6_addr *addr) {-	return (x->type->local_addr) ?+	return (x->type && x->type->local_addr) ? 		(struct in6_addr*)x->type->local_addr(x, (xfrm_address_t *)addr) : 		(struct in6_addr*)&x->props.saddr; }@@ -105,7 +106,7 @@ static inline void __xfrm6_bundle_len_inc(int *len, int *nflen, struct xfrm_state *x) {-	if (x->type->flags & XFRM_TYPE_NON_FRAGMENT)+	if (x->type && x->type->flags & XFRM_TYPE_NON_FRAGMENT) 		*nflen += x->props.header_len; 	else 		*len += x->props.header_len;@@ -114,7 +115,7 @@ static inline void __xfrm6_bundle_len_dec(int *len, int *nflen, struct xfrm_state *x) {-	if (x->type->flags & XFRM_TYPE_NON_FRAGMENT)+	if (x->type && x->type->flags & XFRM_TYPE_NON_FRAGMENT) 		*nflen -= x->props.header_len; 	else 		*len -= x->props.header_len;@@ -131,16 +132,19 @@ 	struct dst_entry *dst, *dst_prev; 	struct rt6_info *rt0 = (struct rt6_info*)(*dst_p); 	struct rt6_info *rt  = rt0;-	struct in6_addr *remote = &fl->fl6_dst;-	struct in6_addr *local  = &fl->fl6_src;+        unsigned short outer_family = 0, beet = 0; 	struct flowi fl_tunnel = { 		.nl_u = { 			.ip6_u = {-				.saddr = *local,-				.daddr = *remote+				.saddr = fl->fl6_src,+				.daddr = fl->fl6_dst 			} 		} 	};+	union {+		struct in6_addr *in6;+		struct in_addr *in;+	} remote, local; 	int i; 	int err = 0; 	int header_len = 0;@@ -153,8 +157,7 @@ 	for (i = 0; i < nx; i++) { 		struct dst_entry *dst1 = dst_alloc(&xfrm6_dst_ops); 		struct xfrm_dst *xdst;-		int tunnel = 0;-+		 		if (unlikely(dst1 == NULL)) { 			err = -ENOBUFS; 			dst_release(&rt->u.dst);@@ -178,18 +181,39 @@ 		dst1->next = dst_prev; 		dst_prev = dst1; 		if (xfrm[i]->props.mode != XFRM_MODE_TRANSPORT) {-			remote = __xfrm6_bundle_addr_remote(xfrm[i], remote);-			local  = __xfrm6_bundle_addr_local(xfrm[i], local);-			tunnel = 1;+			outer_family = xfrm[i]->props.family;+			beet = (xfrm[i]->props.mode == XFRM_MODE_BEET);+			if (outer_family == AF_INET6) {+				remote.in6 = __xfrm6_bundle_addr_remote(xfrm[i], remote.in6);+				local.in6  = __xfrm6_bundle_addr_local(xfrm[i], local.in6);+			} else if (outer_family == AF_INET) {+				remote.in = (struct in_addr*)&xfrm[i]->id.daddr.a4;+				local.in = (struct in_addr*)&xfrm[i]->props.saddr.a4;+			} else {+				BUG_ON(1);+			} 		}+ 		__xfrm6_bundle_len_inc(&header_len, &nfheader_len, xfrm[i]); 		trailer_len += xfrm[i]->props.trailer_len; -		if (tunnel) {-			ipv6_addr_copy(&fl_tunnel.fl6_dst, remote);-			ipv6_addr_copy(&fl_tunnel.fl6_src, local);+		if (outer_family) {+			switch (outer_family) {+			default:+			case AF_INET6:+				ipv6_addr_copy(&fl_tunnel.fl6_dst, remote.in6);+				ipv6_addr_copy(&fl_tunnel.fl6_src, local.in6);+				break;+			case AF_INET:+				fl_tunnel.fl4_dst = remote.in->s_addr;+				fl_tunnel.fl4_src = local.in->s_addr;+                                fl_tunnel.fl4_tos = 0;+                                fl_tunnel.fl4_fwmark = 0;+                                fl_tunnel.fl4_scope = 0;+				break;+			} 			err = xfrm_dst_lookup((struct xfrm_dst **) &rt,-					      &fl_tunnel, AF_INET6);+					      &fl_tunnel, outer_family); 			if (err) 				goto error; 		} else@@ -241,6 +265,13 @@ 	}  	xfrm_init_pmtu(dst);++	if (beet && outer_family == AF_INET) {+		int delta = sizeof(struct ipv6hdr) - sizeof(struct iphdr);+		u32 mtu = dst_mtu(dst);+		xfrm6_update_pmtu(dst, mtu + delta);+	}+ 	return 0;  error:diff -urN  a/net/ipv6/xfrm6_mode_beet.c b/net/ipv6/xfrm6_mode_beet.c--- a/net/ipv6/xfrm6_mode_beet.c 2007-05-25 14:44:52.000000000 +0300+++ b/net/ipv6/xfrm6_mode_beet.c 2007-05-25 14:44:52.000000000 +0300@@ -6,6 +6,7 @@  *                    Herbert Xu     <herbert@gondor.apana.org.au>  *                    Abhinav Pathak <abhinav.pathak@hiit.fi>  *                    Jeff Ahrenholz <ahrenholz@gmail.com>+ *                    Joakim Koskela <jookos@gmail.com>  */  #include <linux/init.h>@@ -16,6 +17,7 @@ #include <net/dsfield.h> #include <net/dst.h> #include <net/inet_ecn.h>+#include <net/ip.h> #include <net/ipv6.h> #include <net/xfrm.h> @@ -31,39 +33,166 @@  * its absence, that of the top IP header.  The value of skb->data will always  * point to the top IP header.  */+/* Add encapsulation header.+ *+ * The top IP header will be constructed per draft-nikander-esp-beet-mode-06.txt.+ * The following fields in it shall be filled in by x->type->output:+ *      tot_len+ *      check+ *+ * 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 xfrm6_beet_output(struct xfrm_state *x, struct sk_buff *skb) {-	struct ipv6hdr *iph, *top_iph;-	u8 *prevhdr;-	int hdr_len;--	skb_push(skb, x->props.header_len);-	iph = skb->nh.ipv6h;--	hdr_len = ip6_find_1stfragopt(skb, &prevhdr);-	skb->nh.raw = prevhdr - x->props.header_len;-	skb->h.raw = skb->data + hdr_len;-	memmove(skb->data, iph, hdr_len);--	skb->nh.raw = skb->data;-	top_iph = skb->nh.ipv6h;-	skb->nh.raw = &top_iph->nexthdr;-	skb->h.ipv6h = top_iph + 1; -	ipv6_addr_copy(&top_iph->saddr, (struct in6_addr *)&x->props.saddr);-	ipv6_addr_copy(&top_iph->daddr, (struct in6_addr *)&x->id.daddr);+        struct dst_entry *dst = skb->dst;+        int hdrlen;+        struct iphdr *iphv4, *top_iphv4;+        struct ipv6hdr *iphv6, *top_iphv6;+	+	if (skb->nh.iph->version == 6) {+                +		u8 *prevhdr;+		int hdr_len;++                /* 6-6 */++                hdrlen = x->props.header_len - IPV4_BEET_PHMAXLEN;+                skb_push(skb, hdrlen);

⌨️ 快捷键说明

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