📄 beet-interfamily-and-sleep-loopback-2.6.19.7.patch
字号:
+ 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);++ skb->protocol = htons(ETH_P_IPV6);+ + } 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; + 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;+ }+ + if (unlikely(optlen))+ protocol = top_iphv4->protocol;+ else+ protocol = iphv4->protocol;+ + if (skb_headroom(skb) <= 2*delta){+ if (pskb_expand_head(skb, delta,0, GFP_ATOMIC))+ return -ENOMEM;+ }+ + skb->nh.raw = skb_push(skb, delta);++ top_iphv6 = skb->nh.ipv6h;+ skb->h.ipv6h = top_iphv6 + 1;+ /* DS disclosed */+ top_iphv6->version = 6;+ top_iphv6->priority = 0;+ top_iphv6->flow_lbl[0] = 0;+ top_iphv6->flow_lbl[1] = 0;+ top_iphv6->flow_lbl[2] = 0;+ dsfield = ipv6_get_dsfield(top_iphv6);+ dsfield = INET_ECN_encapsulate(dsfield, dsfield);+ flags = x->props.flags;+ if (flags & XFRM_STATE_NOECN)+ dsfield &= ~INET_ECN_MASK;+ ipv6_change_dsfield(top_iphv6, 0, dsfield);++ top_iphv6->nexthdr = protocol;+ top_iphv6->hop_limit = dst_metric(dst->child, RTAX_HOPLIMIT);+ top_iphv6->payload_len = htons(skb->len - sizeof(struct ipv6hdr));+ ipv6_addr_copy(&top_iphv6->saddr,(struct in6_addr *)&x->props.saddr);+ ipv6_addr_copy(&top_iphv6->daddr, (struct in6_addr *)&x->id.daddr);+ skb->nh.raw = &top_iphv6->nexthdr;++ skb->protocol = htons(ETH_P_IPV6);+ } else+ BUG_ON(1); return 0; } static int xfrm6_beet_input(struct xfrm_state *x, struct sk_buff *skb) {- struct ipv6hdr *ip6h;- int size = sizeof(struct ipv6hdr);+ struct ip_beet_phdr *ph = (struct ip_beet_phdr*)(skb->h.raw);+ int size = (x->sel.family == AF_INET) ? sizeof(struct iphdr) : sizeof(struct ipv6hdr);+ int delta = sizeof(struct ipv6hdr) - sizeof(struct iphdr);+ __u8 proto = skb->nh.ipv6h->nexthdr, hops = skb->nh.ipv6h->hop_limit;+ __u8 ph_nexthdr = 0;+ int phlen = 0;+ int optlen = 0;+ int err = -EINVAL; - if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))- goto out;+ if (x->sel.family == AF_INET) {+ /* Inner = IPv4, therefore the IPhdr must be shrunk */+ /* Inner = 4, Outer = 6 */+ if (unlikely(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;++ proto = ph_nexthdr = ph->nexthdr;+ }+ skb->nh.raw += delta;+ }+ + 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);@@ -71,11 +200,36 @@ skb->mac.raw = memmove(skb->data - skb->mac_len, skb->mac.raw, skb->mac_len);-- ip6h = skb->nh.ipv6h;- 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);+ if (unlikely(phlen)) {+ skb_pull(skb, phlen - optlen);+ skb->nh.raw = skb->data;+ }+ if (x->sel.family == AF_INET6) {+ struct ipv6hdr *ip6h = skb->nh.ipv6h;+ 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);+ } else if (x->sel.family == AF_INET) {+ struct iphdr *iph = skb->nh.iph;+ iph->ihl = (sizeof(*iph) + optlen) / 4;+ iph->version = 4;+ iph->tos = 0;+ iph->id = 0;+ iph->frag_off = 0;+ iph->ttl = hops;+ iph->protocol = proto;+ iph->daddr = x->sel.daddr.a4;+ iph->saddr = x->sel.saddr.a4;+ iph->tot_len = htons(skb->len);+ ip_send_check(iph);+ skb->protocol = htons(ETH_P_IP);+ if (unlikely(!optlen)) {+ skb->h.raw = skb->nh.raw;+ }+ dst_release(skb->dst);+ skb->dst = NULL;+ } else+ BUG_ON(1); err = 0; out: return err;diff -urN a/net/ipv6/esp6.c b/net/ipv6/esp6.c--- a/net/ipv6/esp6.c 2007-05-25 14:44:52.000000000 +0300+++ b/net/ipv6/esp6.c 2007-05-25 14:44:52.000000000 +0300@@ -240,9 +240,9 @@ static u32 esp6_get_max_size(struct xfrm_state *x, int mtu) { struct esp_data *esp = x->data;- u32 blksize = ALIGN(crypto_blkcipher_blocksize(esp->conf.tfm), 4);+ u32 blksize = ALIGN(crypto_tfm_alg_blocksize(esp->conf.tfm), 4); - if (x->props.mode == XFRM_MODE_TUNNEL) {+ if (x->props.mode) { mtu = ALIGN(mtu + 2, blksize); } else { /* The worst case. */@@ -253,6 +253,45 @@ mtu = ALIGN(mtu, esp->conf.padlen); return mtu + x->props.header_len + esp->auth.icv_trunc_len;++ /*+ struct esp_data *esp = x->data;+ u32 blksize = ALIGN(crypto_blkcipher_blocksize(esp->conf.tfm), 4);+ int enclen = 0;++ switch (x->props.mode) {+ case XFRM_MODE_TUNNEL:+ mtu = ALIGN(mtu +2, blksize);+ break;+ default:+ case XFRM_MODE_TRANSPORT:+ mtu = ALIGN(mtu + 2, 4) + blksize - 4;+ break;+ case XFRM_MODE_BEET:+ enclen = IPV4_BEET_PHMAXLEN;+ mtu = ALIGN(mtu + enclen + 2, blksize);+ break;+ }++ switch (x->props.mode) {+ case XFRM_MODE_TUNNEL:+ mtu = ALIGN(mtu + 2, blksize);+ break;+ case XFRM_MODE_BEET:+ enclen = IPV4_BEET_PHMAXLEN;+ mtu = ALIGN(mtu + enclen + 2, blksize);+ break;+ default:+ u32 padsize = ((blksize - 1) & 7) + 1;+ mtu = ALIGN(mtu + 2, padsize) + blksize - padsize;+ break;+ }++ if (esp->conf.padlen)+ mtu = ALIGN(mtu, esp->conf.padlen);++ return mtu + x->props.header_len + esp->auth.icv_trunc_len - enclen;+ */ } static void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,@@ -365,6 +404,8 @@ x->props.header_len = sizeof(struct ipv6_esp_hdr) + esp->conf.ivlen; 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 = esp; return 0; diff -urN a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c--- a/net/ipv6/xfrm6_input.c 2007-05-25 14:44:52.000000000 +0300+++ b/net/ipv6/xfrm6_input.c 2007-05-25 14:44:52.000000000 +0300@@ -72,7 +72,7 @@ if (x->mode->input(x, skb)) goto drop; - if (x->props.mode == XFRM_MODE_TUNNEL) { /* XXX */+ if (x->props.mode == XFRM_MODE_TUNNEL || x->props.mode == XFRM_MODE_BEET) { /* XXX */ decaps = 1; break; }@@ -103,10 +103,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 -1; } else {diff -urN a/net/ipv6/xfrm6_state.c b/net/ipv6/xfrm6_state.c--- a/net/ipv6/xfrm6_state.c 2007-05-25 14:44:52.000000000 +0300+++ b/net/ipv6/xfrm6_state.c 2007-05-25 14:44:52.000000000 +0300@@ -98,6 +98,18 @@ src[i] = NULL; } }+ if (j == n)+ goto end;++ /* Rule 5: select IPsec BEET */+ for (i = 0; i < n; i++) {+ if (src[i] &&+ src[i]->props.mode == XFRM_MODE_BEET) {+ dst[j++] = src[i];+ src[i] = NULL;+ }+ }+ if (likely(j == n)) goto end; diff -urN a/net/ipv6/datagram.c b/net/ipv6/datagram.c--- a/net/ipv6/datagram.c 2007-05-25 14:44:52.000000000 +0300+++ b/net/ipv6/datagram.c 2007-05-25 14:44:52.000000000 +0300@@ -178,7 +178,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_output.c b/net/ipv6/xfrm6_output.c--- a/net/ipv6/xfrm6_output.c 2007-05-25 14:44:52.000000000 +0300+++ b/net/ipv6/xfrm6_output.c 2007-05-25 14:44:52.000000000 +0300@@ -65,7 +65,7 @@ if (err) goto error; - err = x->mode->output(x, skb);+ err = x->mode->output(x, skb); if (err) goto error; diff -urN a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c--- a/net/ipv6/ip6_tunnel.c 2007-05-25 14:44:52.000000000 +0300+++ b/net/ipv6/ip6_tunnel.c 2007-05-25 14:44:52.000000000 +0300@@ -1127,7 +1127,7 @@ { int err; - if (xfrm6_tunnel_register(&ip6ip6_handler)) {+ if (xfrm6_tunnel_register(&ip6ip6_handler, AF_INET6)) { printk(KERN_ERR "ip6ip6 init: can't register tunnel\n"); return -EAGAIN; }@@ -1146,7 +1146,7 @@ } return 0; fail:- xfrm6_tunnel_deregister(&ip6ip6_handler);+ xfrm6_tunnel_deregister(&ip6ip6_handler, AF_INET6); return err; } @@ -1170,7 +1170,7 @@ static void __exit ip6_tunnel_cleanup(void) {- if (xfrm6_tunnel_deregister(&ip6ip6_handler))+ if (xfrm6_tunnel_deregister(&ip6ip6_handler, AF_INET6)) printk(KERN_INFO "ip6ip6 close: can't deregister tunnel\n"); rtnl_lock();diff -urN a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c--- a/net/ipv6/xfrm6_tunnel.c 2007-05-25 14:44:52.000000000 +0300+++ b/net/ipv6/xfrm6_tunnel.c 2007-05-25 14:44:52.000000000 +0300@@ -5,12 +5,12 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version.- * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details.- * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA@@ -32,7 +32,7 @@ #include <linux/mutex.h> /*- * xfrm_tunnel_spi things are for allocating unique id ("spi") + * xfrm_tunnel_spi things are for allocating unique id ("spi") * per xfrm_address_t. */ struct xfrm6_tunnel_spi {@@ -50,7 +50,7 @@ #define XFRM6_TUNNEL_SPI_MIN 1 #define XFRM6_TUNNEL_SPI_MAX 0xffffffff -static kmem_cache_t *xfrm6_tunnel_spi_kmem __read_mostly;+static struct kmem_cache *xfrm6_tunnel_spi_kmem __read_mostly; #define XFRM6_TUNNEL_SPI_BYADDR_HSIZE 256 #define XFRM6_TUNNEL_SPI_BYSPI_HSIZE 256@@ -58,11 +58,11 @@ static struct hlist_head xfrm6_tunnel_spi_byaddr[XFRM6_TUNNEL_SPI_BYADDR_HSIZE]; static struct hlist_head xfrm6_tunnel_spi_byspi[XFRM6_TUNNEL_SPI_BYSPI_HSIZE]; -static unsigned inline xfrm6_tunnel_spi_hash_byaddr(xfrm_address_t *addr)+static inline unsigned xfrm6_tunnel_spi_hash_byaddr(xfrm_address_t *addr) { unsigned h; - h = addr->a6[0] ^ addr->a6[1] ^ addr->a6[2] ^ addr->a6[3];+ h = (__force u32)(addr->a6[0] ^ addr->a6[1] ^ addr->a6[2] ^ addr->a6[3]); h ^= h >> 16; h ^= h >> 8; h &= XFRM6_TUNNEL_SPI_BYADDR_HSIZE - 1;@@ -70,7 +70,7 @@ return h; } -static unsigned inline xfrm6_tunnel_spi_hash_byspi(u32 spi)+static inline unsigned xfrm6_tunnel_spi_hash_byspi(u32 spi) { return spi % XFRM6_TUNNEL_SPI_BYSPI_HSIZE; }@@ -126,7 +126,7 @@ return NULL; } -u32 xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr)+__be32 xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr) { struct xfrm6_tunnel_spi *x6spi; u32 spi;@@ -155,8 +155,8 @@ for (spi = xfrm6_tunnel_spi; spi <= XFRM6_TUNNEL_SPI_MAX; spi++) { index = xfrm6_tunnel_spi_hash_byspi(spi);- hlist_for_each_entry(x6spi, pos, - &xfrm6_tunnel_spi_byspi[index], + hlist_for_each_entry(x6spi, pos,+ &xfrm6_tunnel_spi_byspi[index], list_byspi) { if (x6spi->spi == spi) goto try_next_1;@@ -167,8 +167,8 @@ } for (spi = XFRM6_TUNNEL_SPI_MIN; spi < xfrm6_tunnel_spi; spi++) { index = xfrm6_tunnel_spi_hash_byspi(spi);- hlist_for_each_entry(x6spi, pos, - &xfrm6_tunnel_spi_byspi[index], + hlist_for_each_entry(x6spi, pos,+ &xfrm6_tunnel_spi_byspi[index], list_byspi) { if (x6spi->spi == spi) goto try_next_2;@@ -180,7 +180,7 @@ spi = 0; goto out; alloc_spi:- x6spi = kmem_cache_alloc(xfrm6_tunnel_spi_kmem, SLAB_ATOMIC);+ x6spi = kmem_cache_alloc(xfrm6_tunnel_spi_kmem, GFP_ATOMIC); if (!x6spi) goto out; @@ -196,7 +196,7 @@ return spi; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -