?? beet-and-sleep-patch-2.6.17.14.patch
字號:
+ 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);+ }+ decaps = 1;+ break; } if ((err = xfrm_parse_spi(skb, skb->nh.iph->protocol, &spi, &seq)) < 0)diff -urN a/net/ipv4/raw.c b/net/ipv4/raw.c--- a/net/ipv4/raw.c 2007-05-18 15:21:38.000000000 +0300+++ b/net/ipv4/raw.c 2007-05-18 15:21:38.000000000 +0300@@ -484,7 +484,7 @@ if (!inet->hdrincl) raw_probe_proto_opt(&fl, msg); - 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/ah4.c b/net/ipv4/ah4.c--- a/net/ipv4/ah4.c 2007-05-18 15:21:38.000000000 +0300+++ b/net/ipv4/ah4.c 2007-05-18 15:21:38.000000000 +0300@@ -257,8 +257,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-18 15:21:38.000000000 +0300+++ b/net/ipv4/xfrm4_policy.c 2007-05-18 15:21:38.000000000 +0300@@ -19,6 +19,8 @@ static struct xfrm_type_map xfrm4_type_map = { .lock = RW_LOCK_UNLOCKED }; +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);@@ -56,17 +58,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;@@ -78,7 +83,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;@@ -99,21 +103,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); }@@ -163,6 +191,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/datagram.c b/net/ipv4/datagram.c--- a/net/ipv4/datagram.c 2007-05-18 15:21:38.000000000 +0300+++ b/net/ipv4/datagram.c 2007-05-18 15:21:38.000000000 +0300@@ -50,7 +50,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/esp4.c b/net/ipv4/esp4.c--- a/net/ipv4/esp4.c 2007-05-18 15:21:38.000000000 +0300+++ b/net/ipv4/esp4.c 2007-05-18 15:21:38.000000000 +0300@@ -240,7 +240,8 @@ * as per draft-ietf-ipsec-udp-encaps-06, * section 3.1.2 */- if (!x->props.mode)+ if (x->props.mode == XFRM_MODE_TRANSPORT ||+ x->props.mode == XFRM_MODE_BEET) skb->ip_summed = CHECKSUM_UNNECESSARY; } @@ -262,17 +263,27 @@ { struct esp_data *esp = x->data; u32 blksize = ALIGN(crypto_tfm_alg_blocksize(esp->conf.tfm), 4);+ int enclen = 0; - if (x->props.mode) {- mtu = ALIGN(mtu + 2, blksize);- } else {- /* The worst case. */+ switch (x->props.mode) {+ default:+ case XFRM_MODE_TUNNEL:+ mtu = ALIGN(mtu +2, blksize);+ break;+ case XFRM_MODE_TRANSPORT:+ /* The worst case */ mtu = ALIGN(mtu + 2, 4) + blksize - 4;+ break;+ case XFRM_MODE_BEET:+ /* The worst case. */+ enclen = IPV4_BEET_PHMAXLEN;+ mtu = ALIGN(mtu + enclen + 2, blksize);+ break; } if (esp->conf.padlen) mtu = ALIGN(mtu, esp->conf.padlen); - return mtu + x->props.header_len + esp->auth.icv_trunc_len;+ return mtu + x->props.header_len + esp->auth.icv_trunc_len - enclen; } static void esp4_err(struct sk_buff *skb, u32 info)@@ -377,8 +388,10 @@ if (crypto_cipher_setkey(esp->conf.tfm, esp->conf.key, esp->conf.key_len)) goto error; x->props.header_len = sizeof(struct ip_esp_hdr) + esp->conf.ivlen;- 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; if (x->encap) { struct xfrm_encap_tmpl *encap = x->encap; diff -urN a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c--- a/net/ipv4/ipcomp.c 2007-05-18 15:21:38.000000000 +0300+++ b/net/ipv4/ipcomp.c 2007-05-18 15:21:38.000000000 +0300@@ -194,7 +194,7 @@ return 0; out_ok:- if (x->props.mode)+ if (x->props.mode == XFRM_MODE_TUNNEL) ip_send_check(iph); return 0; }@@ -234,7 +234,7 @@ t->id.daddr.a4 = x->id.daddr.a4; memcpy(&t->sel, &x->sel, sizeof(t->sel)); t->props.family = AF_INET;- t->props.mode = 1;+ t->props.mode = x->props.mode; t->props.saddr.a4 = x->props.saddr.a4; t->props.flags = x->props.flags; @@ -434,8 +434,10 @@ memset(ipcd, 0, sizeof(*ipcd)); x->props.header_len = 0;- 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; mutex_lock(&ipcomp_resource_mutex); if (!ipcomp_alloc_scratches())@@ -446,7 +448,7 @@ goto error; mutex_unlock(&ipcomp_resource_mutex); - if (x->props.mode) {+ if (x->props.mode == XFRM_MODE_TUNNEL) { err = ipcomp_tunnel_attach(x); if (err) goto error_tunnel;diff -urN a/net/ipv6/ah6.c b/net/ipv6/ah6.c--- a/net/ipv6/ah6.c 2007-05-18 15:21:38.000000000 +0300+++ b/net/ipv6/ah6.c 2007-05-18 15:21:38.000000000 +0300@@ -392,8 +392,10 @@ goto error; x->props.header_len = XFRM_ALIGN8(sizeof(struct ipv6_auth_hdr) + ahp->icv_trunc_len);- if (x->props.mode)+ if (x->props.mode == XFRM_MODE_TUNNEL) x->props.header_len += sizeof(struct ipv6hdr);+ else if (x->props.mode == XFRM_MODE_BEET)+ x->props.header_len += IPV4_BEET_PHMAXLEN; x->data = ahp; return 0;diff -urN a/net/ipv6/datagram.c b/net/ipv6/datagram.c--- a/net/ipv6/datagram.c 2007-05-18 15:21:38.000000000 +0300+++ b/net/ipv6/datagram.c 2007-05-18 15:21:38.000000000 +0300@@ -176,7 +176,7 @@ if (final_p) ipv6_addr_copy(&fl.fl6_dst, final_p); - if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0)+ if ((err = xfrm_lookup(&dst, &fl, sk, 1)) < 0) goto out; /* source address lookup done in ip6_dst_lookup */diff -urN a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c--- a/net/ipv6/xfrm6_policy.c 2007-05-18 15:21:39.000000000 +0300+++ b/net/ipv6/xfrm6_policy.c 2007-05-18 15:21:39.000000000 +0300@@ -25,6 +25,8 @@ static struct xfrm_type_map xfrm6_type_map = { .lock = RW_LOCK_UNLOCKED }; +static void xfrm6_update_pmtu(struct dst_entry *dst, u32 mtu);+ static int xfrm6_dst_lookup(struct xfrm_dst **dst, struct flowi *fl) { int err = 0;@@ -73,16 +75,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; 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;+ unsigned short outer_family = 0, beet = 0; int i; int err = 0; int header_len = 0;@@ -94,7 +99,6 @@ 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;@@ -117,19 +121,38 @@ dst1->next = dst_prev; dst_prev = dst1;- if (xfrm[i]->props.mode) {- remote = (struct in6_addr*)&xfrm[i]->id.daddr;- local = (struct in6_addr*)&xfrm[i]->props.saddr;- 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;+ } } header_len += xfrm[i]->props.header_len; 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) {+ 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;+ 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_INET6);+ &fl_tunnel, outer_family); if (err) goto error; } else@@ -180,6 +203,11 @@ } 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_output.c b/net/ipv6/xfrm6_output.c--- a/net/ipv6/xfrm6_output.c 2007-05-18 15:21:39.000000000 +0300+++ b/net/ipv6/xfrm6_output.c 2007-05-18 15:21:39.000000000 +0300@@ -18,6 +18,7 @@ #include <net/inet_ecn.h> #include <net/ipv6.h> #include <net/xfrm.h>+#include <net/ip.h> /* Add encapsulation header. *@@ -40,40 +41,73 @@ struct xfrm_state *x = dst->xfrm; struct ipv6hdr *iph, *top_iph; int dsfield;+ int hdrlen;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -