📄 beet-2.6.23.patch
字号:
diff -urN linux-2.6.23/net/ipv4/esp4.c linux-2.6.23-beet/net/ipv4/esp4.c--- linux-2.6.23/net/ipv4/esp4.c 2007-10-09 23:31:38.000000000 +0300+++ linux-2.6.23-beet/net/ipv4/esp4.c 2007-10-11 19:39:30.000000000 +0300@@ -293,8 +293,6 @@ mtu += min_t(u32, blksize - 4, rem); break; case XFRM_MODE_BEET:- /* The worst case. */- mtu += min_t(u32, IPV4_BEET_PHMAXLEN, rem); break; } @@ -408,8 +406,11 @@ x->props.header_len = sizeof(struct ip_esp_hdr) + esp->conf.ivlen; 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;+ else if (x->props.mode == XFRM_MODE_BEET) {+ if (x->sel.family == AF_INET) {+ x->props.header_len += IPV4_BEET_PHMAXLEN;+ }+ } if (x->encap) { struct xfrm_encap_tmpl *encap = x->encap; diff -urN linux-2.6.23/net/ipv4/ip_options.c linux-2.6.23-beet/net/ipv4/ip_options.c--- linux-2.6.23/net/ipv4/ip_options.c 2007-10-09 23:31:38.000000000 +0300+++ linux-2.6.23-beet/net/ipv4/ip_options.c 2007-10-11 19:39:30.000000000 +0300@@ -656,3 +656,5 @@ } return 0; }++EXPORT_SYMBOL(ip_options_compile);diff -urN linux-2.6.23/net/ipv4/xfrm4_input.c linux-2.6.23-beet/net/ipv4/xfrm4_input.c--- linux-2.6.23/net/ipv4/xfrm4_input.c 2007-10-09 23:31:38.000000000 +0300+++ linux-2.6.23-beet/net/ipv4/xfrm4_input.c 2007-10-11 19:39:36.000000000 +0300@@ -101,7 +101,9 @@ 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 &&+ x->sel.family != AF_INET)) { decaps = 1; break; }diff -urN linux-2.6.23/net/ipv4/xfrm4_mode_beet.c linux-2.6.23-beet/net/ipv4/xfrm4_mode_beet.c--- linux-2.6.23/net/ipv4/xfrm4_mode_beet.c 2007-10-09 23:31:38.000000000 +0300+++ linux-2.6.23-beet/net/ipv4/xfrm4_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>@@ -16,6 +17,7 @@ #include <net/dst.h> #include <net/ip.h> #include <net/xfrm.h>+#include <net/inet_ecn.h> /* Add encapsulation header. *@@ -24,92 +26,177 @@ * 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.+ * On exit, skb->transport_header will be set to the start of the+ * payload to be processed by x->type->output and skb->network_header+ * will be set to the top IP header. */ static int xfrm4_beet_output(struct xfrm_state *x, struct sk_buff *skb) {- struct iphdr *iph, *top_iph;- int hdrlen, optlen;-- iph = ip_hdr(skb);- skb->transport_header = skb->network_header;-- hdrlen = 0;- optlen = iph->ihl * 4 - sizeof(*iph);- if (unlikely(optlen))- hdrlen += IPV4_BEET_PHMAXLEN - (optlen & 4);-- skb_push(skb, x->props.header_len - IPV4_BEET_PHMAXLEN + hdrlen);- skb_reset_network_header(skb);- top_iph = ip_hdr(skb);- skb->transport_header += sizeof(*iph) - hdrlen;-- memmove(top_iph, iph, sizeof(*iph));- 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 = top_iph->protocol;- if (ph->padlen)- memset(ph + 1, IPOPT_NOP, ph->padlen);-- top_iph->protocol = IPPROTO_BEETPH;- top_iph->ihl = sizeof(struct iphdr) / 4;+ struct dst_entry *dst = skb->dst;+ struct iphdr *iphv4, *top_iphv4;+ int hdrlen;++ if (ip_hdr(skb)->version == 4) {+ int optlen;++ /* 4-4 */+ iphv4 = ip_hdr(skb);+ skb->transport_header = skb->network_header;++ hdrlen = 0;+ optlen = iphv4->ihl * 4 - sizeof(*iphv4);+ if (unlikely(optlen))+ hdrlen += IPV4_BEET_PHMAXLEN - (optlen & 4);++ skb_push(skb, x->props.header_len - IPV4_BEET_PHMAXLEN + hdrlen);+ skb_reset_network_header(skb);+ top_iphv4 = ip_hdr(skb);+ skb->transport_header += sizeof(*iphv4) - hdrlen;++ memmove(top_iphv4, iphv4, sizeof(*iphv4));+ 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);++ top_iphv4->protocol = IPPROTO_BEETPH;+ top_iphv4->ihl = 5;+ }++ top_iphv4->saddr = x->props.saddr.a4;+ top_iphv4->daddr = x->id.daddr.a4;+#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)+ } else if (ip_hdr(skb)->version == 6) {+ int delta = sizeof(struct ipv6hdr) - sizeof(struct iphdr);+ u8 protocol = ipv6_hdr(skb)->nexthdr;++ skb_set_transport_header(skb, sizeof(struct ipv6hdr));++ /* Inner = 6, Outer = 4 : changing the external IP hdr+ * to the outer addresses+ */+ hdrlen = x->props.header_len;++ skb_pull(skb, delta);+ skb_push(skb, hdrlen);++ skb_reset_network_header(skb);+ top_iphv4 = ip_hdr(skb);+ top_iphv4->ihl = 5;+ top_iphv4->version = 4;+ top_iphv4->id = 0;+ top_iphv4->frag_off = htons(IP_DF);+ top_iphv4->ttl = dst_metric(dst->child, RTAX_HOPLIMIT);+ top_iphv4->protocol = protocol;++ top_iphv4->saddr = x->props.saddr.a4;+ top_iphv4->daddr = x->id.daddr.a4;+ IPCB(skb)->flags = 0;+#endif } - top_iph->saddr = x->props.saddr.a4;- top_iph->daddr = x->id.daddr.a4;-+ skb->protocol = htons(ETH_P_IP);+ memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options)); return 0; } static int xfrm4_beet_input(struct xfrm_state *x, struct sk_buff *skb) { struct iphdr *iph = ip_hdr(skb);+ int hops = iph->ttl; int phlen = 0; int optlen = 0;- u8 ph_nexthdr = 0;+ __u8 protocol = 0; int err = -EINVAL; - if (unlikely(iph->protocol == IPPROTO_BEETPH)) {- struct ip_beet_phdr *ph;+ protocol = iph->protocol;+ if (x->sel.family == AF_INET) {+ if (unlikely(protocol == IPPROTO_BEETPH)) {+ struct ip_beet_phdr *ph;++ if (!pskb_may_pull(skb, sizeof(*ph)))+ goto out;++ ph = (struct ip_beet_phdr *)(ipip_hdr(skb) + 1);++ 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;++ protocol = ph->nexthdr;+ }++ skb_push(skb, sizeof(*iph) - phlen);+ skb_reset_network_header(skb);+ memmove(skb_network_header(skb), iph, sizeof(*iph));++ iph = ip_hdr(skb);+ iph->ihl = (sizeof(*iph) + optlen) / 4;+ iph->tot_len = htons(skb->len);+ iph->daddr = x->sel.daddr.a4;+ iph->saddr = x->sel.saddr.a4;+ iph->protocol = protocol; - if (!pskb_may_pull(skb, sizeof(*ph)))+ ip_send_check(iph);+ if (ip_options_compile(NULL, skb)) goto out;- ph = (struct ip_beet_phdr *)(ipip_hdr(skb) + 1); - 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;- skb->len -= phlen + optlen;+ dst_release(skb->dst);+ skb->dst = NULL; - ph_nexthdr = ph->nexthdr;+ pskb_pull(skb, sizeof(*iph) + optlen);+ skb_reset_transport_header(skb);+ err = 0;+#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)+ } else if (x->sel.family == AF_INET6) {+ int delta = sizeof(struct ipv6hdr) + skb->mac_len;+ struct ipv6hdr *ip6h;+ const unsigned char *old_mac;++ /* Here, the inner family is 6, therefore I have to+ * substitute the IPhdr by enlarging it.+ */+ if (skb_headroom(skb) < delta) {+ if (pskb_expand_head(skb, delta, 0, GFP_ATOMIC))+ goto out;+ }++ skb_push(skb, sizeof(*ip6h));++ /* mac might have references to ipv4. 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);++ skb_reset_network_header(skb);+ skb_reset_transport_header(skb);++ ip6h = ipv6_hdr(skb);+ memset(ip6h->flow_lbl, 0, sizeof(ip6h->flow_lbl));+ ip6h->version = 6;+ ip6h->priority = 0;+ ip6h->nexthdr = protocol;+ ip6h->hop_limit = hops;+ ip6h->payload_len = htons(skb->len - sizeof(*ip6h));+ 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);+ err = 0;+#endif }-- skb_set_network_header(skb, phlen - sizeof(*iph));- memmove(skb_network_header(skb), iph, sizeof(*iph));- skb_set_transport_header(skb, phlen + optlen);- skb->data = skb_transport_header(skb);-- iph = ip_hdr(skb);- iph->ihl = (sizeof(*iph) + optlen) / 4;- iph->tot_len = htons(skb->len + iph->ihl * 4);- iph->daddr = x->sel.daddr.a4;- iph->saddr = x->sel.saddr.a4;- if (ph_nexthdr)- iph->protocol = ph_nexthdr;- iph->check = 0;- iph->check = ip_fast_csum(skb_network_header(skb), iph->ihl);- err = 0; out: return err; }diff -urN linux-2.6.23/net/ipv4/xfrm4_output.c linux-2.6.23-beet/net/ipv4/xfrm4_output.c--- linux-2.6.23/net/ipv4/xfrm4_output.c 2007-10-09 23:31:38.000000000 +0300+++ linux-2.6.23-beet/net/ipv4/xfrm4_output.c 2007-10-11 19:39:38.000000000 +0300@@ -14,6 +14,9 @@ #include <linux/skbuff.h> #include <linux/spinlock.h> #include <linux/netfilter_ipv4.h>+#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)+#include <linux/netfilter_ipv6.h>+#endif #include <net/ip.h> #include <net/xfrm.h> #include <net/icmp.h>@@ -84,7 +87,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)); IPCB(skb)->flags |= IPSKB_XFRM_TRANSFORMED; err = 0;@@ -166,7 +170,15 @@ int xfrm4_output(struct sk_buff *skb) {- return NF_HOOK_COND(PF_INET, NF_IP_POST_ROUTING, skb, NULL, skb->dst->dev,- xfrm4_output_finish,- !(IPCB(skb)->flags & IPSKB_REROUTED));+#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)+ if (ip_hdr(skb)->version == 6) {+ return NF_HOOK(PF_INET6, NF_IP6_POST_ROUTING, skb, NULL, skb->dst->dev,+ xfrm4_output_finish);+ } else+#endif+ {+ return NF_HOOK_COND(PF_INET, NF_IP_POST_ROUTING, skb, NULL, skb->dst->dev,+ xfrm4_output_finish,+ !(IPCB(skb)->flags & IPSKB_REROUTED));+ } }diff -urN linux-2.6.23/net/ipv4/xfrm4_policy.c linux-2.6.23-beet/net/ipv4/xfrm4_policy.c--- linux-2.6.23/net/ipv4/xfrm4_policy.c 2007-10-09 23:31:38.000000000 +0300+++ linux-2.6.23-beet/net/ipv4/xfrm4_policy.c 2007-10-11 19:39:38.000000000 +0300@@ -72,6 +72,7 @@ struct dst_entry *dst, *dst_prev; struct rtable *rt0 = (struct rtable*)(*dst_p); struct rtable *rt = rt0;+ unsigned short encap_family = AF_INET; struct flowi fl_tunnel = { .nl_u = { .ip4_u = {@@ -117,8 +118,9 @@ header_len += xfrm[i]->props.header_len; trailer_len += xfrm[i]->props.trailer_len; - if (xfrm[i]->props.mode == XFRM_MODE_TUNNEL) {- unsigned short encap_family = xfrm[i]->props.family;+ if (xfrm[i]->props.mode == XFRM_MODE_TUNNEL ||+ xfrm[i]->props.mode == XFRM_MODE_BEET) {+ encap_family = xfrm[i]->props.family; switch (encap_family) { case AF_INET: fl_tunnel.fl4_dst = xfrm[i]->id.daddr.a4;@@ -180,16 +182,19 @@ } dst_prev->output = afinfo->output; xfrm_state_put_afinfo(afinfo);- if (dst_prev->xfrm->props.family == AF_INET && rt->peer)- atomic_inc(&rt->peer->refcnt);- x->u.rt.peer = rt->peer;++ if (encap_family == AF_INET) {+ if (dst_prev->xfrm->props.family == AF_INET && rt->peer)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -