📄 beet-2.6.23.patch
字号:
+ atomic_inc(&rt->peer->refcnt);+ x->u.rt.peer = rt->peer;+ x->u.rt.rt_type = rt->rt_type;+ x->u.rt.rt_gateway = rt->rt_gateway;+ } /* Sheit... I remember I did this right. Apparently, * it was magically lost, so this code needs audit */ x->u.rt.rt_flags = rt0->rt_flags&(RTCF_BROADCAST|RTCF_MULTICAST|RTCF_LOCAL);- x->u.rt.rt_type = rt->rt_type; x->u.rt.rt_src = rt0->rt_src; x->u.rt.rt_dst = rt0->rt_dst;- x->u.rt.rt_gateway = rt->rt_gateway; x->u.rt.rt_spec_dst = rt0->rt_spec_dst; x->u.rt.idev = rt0->idev; in_dev_hold(rt0->idev);diff -urN linux-2.6.23/net/ipv6/esp6.c linux-2.6.23-beet/net/ipv6/esp6.c--- linux-2.6.23/net/ipv6/esp6.c 2007-10-09 23:31:38.000000000 +0300+++ linux-2.6.23-beet/net/ipv6/esp6.c 2007-10-11 19:39:38.000000000 +0300@@ -246,7 +246,8 @@ rem = mtu & (align - 1); mtu &= ~(align - 1); - if (x->props.mode != XFRM_MODE_TUNNEL) {+ if (x->props.mode != XFRM_MODE_TUNNEL ||+ x->props.mode != XFRM_MODE_BEET) { u32 padsize = ((blksize - 1) & 7) + 1; mtu -= blksize - padsize; mtu += min_t(u32, blksize - padsize, rem);@@ -365,6 +366,12 @@ 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) {+ if (x->sel.family == AF_INET) {+ x->props.header_len += IPV4_BEET_PHMAXLEN ++ (sizeof(struct ipv6hdr) - sizeof(struct iphdr));+ }+ } x->data = esp; return 0; diff -urN linux-2.6.23/net/ipv6/xfrm6_input.c linux-2.6.23-beet/net/ipv6/xfrm6_input.c--- linux-2.6.23/net/ipv6/xfrm6_input.c 2007-10-09 23:31:38.000000000 +0300+++ linux-2.6.23-beet/net/ipv6/xfrm6_input.c 2007-10-11 19:39:38.000000000 +0300@@ -73,7 +73,9 @@ 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 &&+ x->sel.family != AF_INET6)) { decaps = 1; break; }diff -urN linux-2.6.23/net/ipv6/xfrm6_mode_beet.c linux-2.6.23-beet/net/ipv6/xfrm6_mode_beet.c--- linux-2.6.23/net/ipv6/xfrm6_mode_beet.c 2007-10-09 23:31:38.000000000 +0300+++ linux-2.6.23-beet/net/ipv6/xfrm6_mode_beet.c 2007-10-11 19:39:38.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>@@ -17,6 +18,7 @@ #include <net/dst.h> #include <net/inet_ecn.h> #include <net/ipv6.h>+#include <net/ip.h> #include <net/xfrm.h> /* Add encapsulation header.@@ -33,54 +35,167 @@ */ static int xfrm6_beet_output(struct xfrm_state *x, struct sk_buff *skb) {- struct ipv6hdr *iph, *top_iph;- u8 *prevhdr;+ struct dst_entry *dst = skb->dst;+ struct iphdr *iphv4;+ struct ipv6hdr *iphv6, *top_iphv6; int hdr_len; - skb_push(skb, x->props.header_len);- iph = ipv6_hdr(skb);+ if (ip_hdr(skb)->version == 6) {+ u8 *prevhdr; - hdr_len = ip6_find_1stfragopt(skb, &prevhdr);- skb_set_network_header(skb,- (prevhdr - x->props.header_len) - skb->data);- skb_set_transport_header(skb, hdr_len);- memmove(skb->data, iph, hdr_len);-- skb_reset_network_header(skb);- top_iph = ipv6_hdr(skb);- skb->transport_header = skb->network_header + sizeof(struct ipv6hdr);- skb->network_header += offsetof(struct ipv6hdr, nexthdr);+ skb_push(skb, x->props.header_len);+ iphv6 = ipv6_hdr(skb); - ipv6_addr_copy(&top_iph->saddr, (struct in6_addr *)&x->props.saddr);- ipv6_addr_copy(&top_iph->daddr, (struct in6_addr *)&x->id.daddr);+ hdr_len = ip6_find_1stfragopt(skb, &prevhdr);+ skb_reset_network_header(skb); + top_iphv6 = ipv6_hdr(skb);+ memmove(top_iphv6, iphv6, hdr_len);+ 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->transport_header = skb->network_header + sizeof(struct ipv6hdr);+ skb->network_header += offsetof(struct ipv6hdr, nexthdr);+ } else if (ip_hdr(skb)->version == 4) {+ int flags, optlen, dsfield;+ u8 protocol;++ iphv4 = ip_hdr(skb);+ skb->transport_header = skb->network_header;++ hdr_len = 0;+ optlen = iphv4->ihl * 4 - sizeof(*iphv4);+ if (unlikely(optlen))+ hdr_len += IPV4_BEET_PHMAXLEN - (optlen & 4);++ skb_push(skb, x->props.header_len - IPV4_BEET_PHMAXLEN + hdr_len);+ skb->transport_header += sizeof(*iphv4) - hdr_len;+ if (unlikely(optlen)) {+ struct ip_beet_phdr *ph;++ BUG_ON(optlen < 0);++ ph = (struct ip_beet_phdr *)skb_transport_header(skb);+ ph->padlen = 4 - (optlen & 4);+ ph->hdrlen = optlen / 8;+ ph->nexthdr = iphv4->protocol;+ if (ph->padlen)+ memset(ph + 1, IPOPT_NOP, ph->padlen);++ protocol = IPPROTO_BEETPH;+ } else+ protocol = iphv4->protocol;++ skb_reset_network_header(skb);+ top_iphv6 = ipv6_hdr(skb);++ /* 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->transport_header = skb->network_header + sizeof(struct ipv6hdr);+ skb->network_header += offsetof(struct ipv6hdr, nexthdr);+ }++ skb->protocol = htons(ETH_P_IPV6); return 0; } + static int xfrm6_beet_input(struct xfrm_state *x, struct sk_buff *skb) { struct ipv6hdr *ip6h; const unsigned char *old_mac;- int size = sizeof(struct ipv6hdr);+ int size = ((x->sel.family == AF_INET) ?+ sizeof(struct iphdr) :+ sizeof(struct ipv6hdr)); int err = -EINVAL; - if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))- goto out;-- skb_push(skb, size);- memmove(skb->data, skb_network_header(skb), size);- skb_reset_network_header(skb);-- old_mac = skb_mac_header(skb);- skb_set_mac_header(skb, -skb->mac_len);- memmove(skb_mac_header(skb), old_mac, skb->mac_len);-- ip6h = ipv6_hdr(skb);- 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);- err = 0;-out:+ if (x->sel.family == AF_INET6) {+ if (skb_cloned(skb) &&+ pskb_expand_head(skb, 0, 0, GFP_ATOMIC))+ goto out;++ ip6h = ipv6_hdr(skb);+ skb_set_network_header(skb, -size);+ memmove(skb_network_header(skb), ip6h, size);++ ip6h = ipv6_hdr(skb);+ ipv6_addr_copy(&ip6h->daddr, (struct in6_addr *) &x->sel.daddr.a6);+ ipv6_addr_copy(&ip6h->saddr, (struct in6_addr *) &x->sel.saddr.a6);++ ip6h->payload_len = htons(skb->len);+ skb_reset_transport_header(skb);+ skb->protocol = htons(ETH_P_IPV6);+ err = 0;+ } else {+ __u8 proto = ipv6_hdr(skb)->nexthdr;+ __u8 hops = ipv6_hdr(skb)->hop_limit;+ int phlen = 0;+ int optlen = 0;+ struct iphdr *iph;++ /* Inner = IPv4, therefore the IPhdr must be shrunk */+ /* Inner = 4, Outer = 6 */+ if (unlikely(proto == IPPROTO_BEETPH)) {+ struct ip_beet_phdr *ph = (struct ip_beet_phdr *)+ (struct ip_beet_phdr *)skb->data;++ if (!pskb_may_pull(skb, sizeof(*ph)))+ goto out;++ phlen = sizeof(*ph) + ph->padlen;+ optlen = ph->hdrlen * 8 + (IPV4_BEET_PHMAXLEN - phlen);+ if (optlen < 0 || optlen & 3 || optlen > 250)+ goto out;++ if (!pskb_may_pull(skb, phlen + optlen))+ goto out;+ proto = ph->nexthdr;+ }++ if (skb_cloned(skb) &&+ pskb_expand_head(skb, 0, 0, GFP_ATOMIC))+ goto out;++ skb_push(skb, size - phlen);+ skb_reset_network_header(skb);+ skb_reset_transport_header(skb);++ /* mac might have references to ipv6. shouldn't matter */+ old_mac = skb_mac_header(skb);+ skb_set_mac_header(skb, -skb->mac_len);+ memmove(skb_mac_header(skb), old_mac, skb->mac_len);++ iph = ip_hdr(skb);+ 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);+ err = 0;+ }+ out: return err; } diff -urN linux-2.6.23/net/ipv6/xfrm6_output.c linux-2.6.23-beet/net/ipv6/xfrm6_output.c--- linux-2.6.23/net/ipv6/xfrm6_output.c 2007-10-09 23:31:38.000000000 +0300+++ linux-2.6.23-beet/net/ipv6/xfrm6_output.c 2007-10-11 19:39:38.000000000 +0300@@ -14,8 +14,10 @@ #include <linux/spinlock.h> #include <linux/icmpv6.h> #include <linux/netfilter_ipv6.h>+#include <linux/netfilter_ipv4.h> #include <net/ipv6.h> #include <net/xfrm.h>+#include <net/ip.h> int xfrm6_find_1stfragopt(struct xfrm_state *x, struct sk_buff *skb, u8 **prevhdr)@@ -90,7 +92,8 @@ } dst = skb->dst; x = dst->xfrm;- } while (x && (x->props.mode != XFRM_MODE_TUNNEL));+ } while (x && (x->props.mode != XFRM_MODE_TUNNEL) &&+ (x->props.mode != XFRM_MODE_BEET)); IP6CB(skb)->flags |= IP6SKB_XFRM_TRANSFORMED; err = 0;@@ -165,6 +168,12 @@ int xfrm6_output(struct sk_buff *skb) {- return NF_HOOK(PF_INET6, NF_IP6_POST_ROUTING, skb, NULL, skb->dst->dev,- xfrm6_output_finish);+ if (ip_hdr(skb)->version == 4) {+ return NF_HOOK_COND(PF_INET, NF_IP_POST_ROUTING, skb, NULL, skb->dst->dev,+ xfrm6_output_finish,+ !(IPCB(skb)->flags & IPSKB_REROUTED));+ } else {+ return NF_HOOK(PF_INET6, NF_IP6_POST_ROUTING, skb, NULL, skb->dst->dev,+ xfrm6_output_finish);+ } }diff -urN linux-2.6.23/net/ipv6/xfrm6_policy.c linux-2.6.23-beet/net/ipv6/xfrm6_policy.c--- linux-2.6.23/net/ipv6/xfrm6_policy.c 2007-10-09 23:31:38.000000000 +0300+++ linux-2.6.23-beet/net/ipv6/xfrm6_policy.c 2007-10-11 19:39:38.000000000 +0300@@ -131,6 +131,7 @@ struct dst_entry *dst, *dst_prev; struct rt6_info *rt0 = (struct rt6_info*)(*dst_p); struct rt6_info *rt = rt0;+ unsigned short encap_family = AF_INET6; struct flowi fl_tunnel = { .nl_u = { .ip6_u = {@@ -179,12 +180,15 @@ trailer_len += xfrm[i]->props.trailer_len; if (xfrm[i]->props.mode == XFRM_MODE_TUNNEL ||+ xfrm[i]->props.mode == XFRM_MODE_BEET || xfrm[i]->props.mode == XFRM_MODE_ROUTEOPTIMIZATION) {- unsigned short encap_family = xfrm[i]->props.family;+ encap_family = xfrm[i]->props.family; switch(encap_family) { case AF_INET: fl_tunnel.fl4_dst = xfrm[i]->id.daddr.a4; fl_tunnel.fl4_src = xfrm[i]->props.saddr.a4;+ fl_tunnel.fl4_tos = 0;+ fl_tunnel.fl4_scope = 0; break; case AF_INET6: ipv6_addr_copy(&fl_tunnel.fl6_dst, __xfrm6_bundle_addr_remote(xfrm[i], &fl->fl6_dst));@@ -205,7 +209,7 @@ dst_prev->child = &rt->u.dst; dst->path = &rt->u.dst;- if (rt->rt6i_node)+ if (encap_family == AF_INET6 && rt->rt6i_node) ((struct xfrm_dst *)dst)->path_cookie = rt->rt6i_node->fn_sernum; *dst_p = dst;diff -urN linux-2.6.23/net/ipv6/xfrm6_state.c linux-2.6.23-beet/net/ipv6/xfrm6_state.c--- linux-2.6.23/net/ipv6/xfrm6_state.c 2007-10-09 23:31:38.000000000 +0300+++ linux-2.6.23-beet/net/ipv6/xfrm6_state.c 2007-10-11 19:39:38.000000000 +0300@@ -98,6 +98,17 @@ 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 linux-2.6.23/net/key/af_key.c linux-2.6.23-beet/net/key/af_key.c--- linux-2.6.23/net/key/af_key.c 2007-10-09 23:31:38.000000000 +0300+++ linux-2.6.23-beet/net/key/af_key.c 2007-10-11 19:40:06.000000000 +0300@@ -1205,6 +1205,9 @@ x->sel.family = pfkey_sadb_addr2xfrm_addr(addr, &x->sel.saddr); x->sel.prefixlen_s = addr->sadb_address_prefixlen; }+ + if (!x->sel.family)+ x->sel.family = x->props.family; if (!x->sel.family) x->sel.family = x->props.family;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -