📄 hipmod-sleep-beet-and-interfamily-all-in-one.patch
字号:
+ .output = xfrm4_beet_output,+ .owner = THIS_MODULE,+ .encap = XFRM_MODE_BEET,+};+ static int __init xfrm4_tunnel_init(void) {+ int err;+ /* jk: this should be moved to the beet module! */+ err = xfrm_register_mode(&xfrm4_beet_mode, AF_INET); return xfrm_register_mode(&xfrm4_tunnel_mode, AF_INET); } @@ -114,6 +301,9 @@ { int err; + /* jk: this should be moved to the beet module! */+ err = xfrm_unregister_mode(&xfrm4_beet_mode, AF_INET);+ BUG_ON(err); err = xfrm_unregister_mode(&xfrm4_tunnel_mode, AF_INET); BUG_ON(err); }diff -urN a/net/ipv4/esp4.c b/net/ipv4/esp4.c--- a/net/ipv4/esp4.c 2007-05-25 12:21:11.000000000 +0300+++ b/net/ipv4/esp4.c 2007-05-25 12:21:11.000000000 +0300@@ -237,7 +237,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; } @@ -255,17 +256,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)@@ -368,8 +379,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-25 12:21:11.000000000 +0300+++ b/net/ipv4/ipcomp.c 2007-05-25 12:21:11.000000000 +0300@@ -176,7 +176,7 @@ return 0; out_ok:- if (x->props.mode)+ if (x->props.mode == XFRM_MODE_TUNNEL) ip_send_check(iph); return 0; }@@ -216,7 +216,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; @@ -415,8 +415,10 @@ goto out; 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())@@ -427,7 +429,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/xfrm6_input.c b/net/ipv6/xfrm6_input.c--- a/net/ipv6/xfrm6_input.c 2007-05-25 12:21:11.000000000 +0300+++ b/net/ipv6/xfrm6_input.c 2007-05-25 12:21:11.000000000 +0300@@ -13,9 +13,21 @@ #include <linux/string.h> #include <linux/netfilter.h> #include <linux/netfilter_ipv6.h>+#include <net/dsfield.h>+#include <net/inet_ecn.h>+#include <net/ip.h> #include <net/ipv6.h> #include <net/xfrm.h> +static inline void ipip6_ecn_decapsulate(struct sk_buff *skb)+{+ struct ipv6hdr *outer_iph = skb->nh.ipv6h;+ struct ipv6hdr *inner_iph = skb->h.ipv6h;++ if (INET_ECN_is_ce(ipv6_get_dsfield(outer_iph)))+ IP6_ECN_set_ce(inner_iph);+}+ int xfrm6_rcv_spi(struct sk_buff *skb, u32 spi) { int err;@@ -33,7 +45,6 @@ seq = 0; if (!spi && (err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) != 0) goto drop;- do { struct ipv6hdr *iph = skb->nh.ipv6h; @@ -44,6 +55,7 @@ if (x == NULL) goto drop; spin_lock(&x->lock);+ if (unlikely(x->km.state != XFRM_STATE_VALID)) goto drop_unlock; @@ -69,16 +81,17 @@ xfrm_vec[xfrm_nr++] = x; - if (x->mode->input(x, skb))+ if (x->mode->input(x, skb)) goto drop;-- if (x->props.mode) { /* XXX */- decaps = 1;- break;+ + if (x->props.mode) {+ decaps = 1;+ break; } if ((err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) < 0) goto drop;+ } while (!err); /* Allocate new secpath or COW existing one. */@@ -110,6 +123,7 @@ netif_rx(skb); return -1; } else {+ #ifdef CONFIG_NETFILTER skb->nh.ipv6h->payload_len = htons(skb->len); __skb_push(skb, skb->data - skb->nh.raw);diff -urN a/net/ipv6/ah6.c b/net/ipv6/ah6.c--- a/net/ipv6/ah6.c 2007-05-25 12:21:11.000000000 +0300+++ b/net/ipv6/ah6.c 2007-05-25 12:21:11.000000000 +0300@@ -387,8 +387,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/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c--- a/net/ipv6/xfrm6_policy.c 2007-05-25 12:21:11.000000000 +0300+++ b/net/ipv6/xfrm6_policy.c 2007-05-25 12:21:11.000000000 +0300@@ -22,6 +22,8 @@ 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 **dst, struct flowi *fl) { int err = 0;@@ -70,16 +72,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;@@ -91,7 +96,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;@@ -114,19 +118,39 @@ 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@@ -177,6 +201,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-25 12:21:11.000000000 +0300+++ b/net/ipv6/xfrm6_output.c 2007-05-25 12:21:11.000000000 +0300@@ -14,8 +14,11 @@ #include <linux/spinlock.h> #include <linux/icmpv6.h> #include <linux/netfilter_ipv6.h>+#include <net/dsfield.h>+#include <net/inet_ecn.h> #include <net/ipv6.h> #include <net/xfrm.h>+#include <net/ip.h> static int xfrm6_tunnel_check_size(struct sk_buff *skb) {@@ -47,7 +50,7 @@ goto error_nolock; } - if (x->props.mode) {+ if (x->props.mode == XFRM_MODE_TUNNEL) { err = xfrm6_tunnel_check_size(skb); if (err) goto error_nolock;@@ -59,7 +62,7 @@ if (err) goto error; - err = x->mode->output(skb);+ err = x->mode->output(skb); if (err) goto error; diff -urN a/net/ipv6/udp.c b/net/ipv6/udp.c--- a/net/ipv6/udp.c 2007-05-25 12:21:11.000000000 +0300+++ b/net/ipv6/udp.c 2007-05-25 12:21:11.000000000 +0300@@ -788,7 +788,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, XFRM_LOOKUP_SLEEP)) < 0) goto out; if (hlimit < 0) {diff -urN a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c--- a/net/ipv6/tcp_ipv6.c 2007-05-25 12:21:11.000000000 +0300+++ b/net/ipv6/tcp_ipv6.c 2007-05-25 12:21:11.000000000 +0300@@ -257,7 +257,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, XFRM_LOOKUP_SLEEP)) < 0) goto failure; if (saddr == NULL) {diff -urN a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c--- a/net/ipv6/af_inet6.c 2007-05-25 12:21:11.000000000 +0300+++ b/net/ipv6/af_inet6.c 2007-05-25 12:21:11.000000000 +0300@@ -939,4 +939,8 @@ } module_exit(inet6_exit); +EXPORT_SYMBOL(inet6_create);+EXPORT_SYMBOL(inet6_stream_ops);+EXPORT_SYMBOL(inet6_dgram_ops);+ MODULE_ALIAS_NETPROTO(PF_INET6);diff -urN a/net/ipv6/xfrm6_mode_tunnel.c b/net/ipv6/xfrm6_mode_tunnel.c--- a/net/ipv6/xfrm6_mode_tunnel.c 2007-05-25 12:21:11.000000000 +0300+++ b/net/ipv6/xfrm6_mode_tunnel.c 2007-05-25 12:21:11.000000000 +0300@@ -15,6 +15,7 @@ #include <net/inet_ecn.h> #include <net/ipv6.h> #include <net/xfrm.h>+#include <net/ip.h> static inline void ipip6_ecn_decapsulate(struct sk_buff *skb) {@@ -95,6 +96,209 @@ return err; } ++/* jk: move this to beet module! */+static int xfrm6_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 == 6) {+ + u8 *prevhdr;+ int hdr_len;++ /* 6-6 */++ hdrlen = x->props.header_len - IPV4_BEET_PHMAXLEN;+ skb_push(skb, hdrlen);+ iphv6 = skb->nh.ipv6h;++ hdr_len = ip6_find_1stfragopt(skb, &prevhdr);+ skb->nh.raw = prevhdr - hdrlen;+ skb->h.raw = skb->data + hdr_len;+ memmove(skb->data, iphv6, hdr_len);+ + skb->nh.raw = skb->data;+ top_iphv6 = skb->nh.ipv6h;+ skb->nh.raw = &top_iphv6->nexthdr;+ skb->h.ipv6h = top_iphv6 + 1;+ ipv6_addr_copy(&top_iphv6->saddr, (struct in6_addr *)&x->props.saddr);+ ipv6_addr_copy(&top_iphv6->daddr, (struct in6_addr *)&x->id.daddr);++ } else if (skb->nh.iph->version == 4) {++ int flags;+ int optlen;+ int dsfield;+ u8 protocol;+ int delta = sizeof(struct ipv6hdr) - sizeof(struct iphdr);++ /* Inner = 4, Outer = 6*/++ 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;+
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -