📄 beet-and-sleep-patch-2.6.17.14.patch
字号:
diff -urN a/include/net/xfrm.h b/include/net/xfrm.h--- a/include/net/xfrm.h 2007-05-18 15:21:38.000000000 +0300+++ b/include/net/xfrm.h 2007-05-18 15:21:38.000000000 +0300@@ -287,6 +287,10 @@ /* Source address of tunnel. Ignored, if it is not a tunnel. */ xfrm_address_t saddr; +/* family of the outer addresses. The family may differ from+ the one in selector */+ unsigned short outer_family;+ __u32 reqid; /* Mode: transport/tunnel */diff -urN a/include/net/route.h b/include/net/route.h--- a/include/net/route.h 2007-05-18 15:21:38.000000000 +0300+++ b/include/net/route.h 2007-05-18 15:21:38.000000000 +0300@@ -146,7 +146,8 @@ static inline int ip_route_connect(struct rtable **rp, u32 dst, u32 src, u32 tos, int oif, u8 protocol,- u16 sport, u16 dport, struct sock *sk)+ u16 sport, u16 dport, struct sock *sk,+ int flags) { struct flowi fl = { .oif = oif, .nl_u = { .ip4_u = { .daddr = dst,@@ -167,7 +168,7 @@ ip_rt_put(*rp); *rp = NULL; }- return ip_route_output_flow(rp, &fl, sk, 0);+ return ip_route_output_flow(rp, &fl, sk, flags); } static inline int ip_route_newports(struct rtable **rp, u8 protocol,diff -urN a/include/linux/xfrm.h b/include/linux/xfrm.h--- a/include/linux/xfrm.h 2007-05-18 15:21:38.000000000 +0300+++ b/include/linux/xfrm.h 2007-05-18 15:21:38.000000000 +0300@@ -118,6 +118,13 @@ XFRM_SHARE_UNIQUE /* Use once */ }; +enum+{+ XFRM_MODE_TRANSPORT = 0,+ XFRM_MODE_TUNNEL,+ XFRM_MODE_BEET+};+ /* Netlink configuration messages. */ enum { XFRM_MSG_BASE = 0x10,diff -urN a/include/linux/ipsec.h b/include/linux/ipsec.h--- a/include/linux/ipsec.h 2007-05-18 15:21:38.000000000 +0300+++ b/include/linux/ipsec.h 2007-05-18 15:21:38.000000000 +0300@@ -12,7 +12,8 @@ enum { IPSEC_MODE_ANY = 0, /* We do not support this for SA */ IPSEC_MODE_TRANSPORT = 1,- IPSEC_MODE_TUNNEL = 2+ IPSEC_MODE_TUNNEL = 2,+ IPSEC_MODE_BEET = 3 }; enum {diff -urN a/include/linux/in.h b/include/linux/in.h--- a/include/linux/in.h 2007-05-18 15:21:38.000000000 +0300+++ b/include/linux/in.h 2007-05-18 15:21:38.000000000 +0300@@ -40,6 +40,7 @@ IPPROTO_ESP = 50, /* Encapsulation Security Payload protocol */ IPPROTO_AH = 51, /* Authentication Header protocol */+ IPPROTO_BEETPH = 94, /* IP option pseudo header for BEET */ IPPROTO_PIM = 103, /* Protocol Independent Multicast */ IPPROTO_COMP = 108, /* Compression Header protocol */diff -urN a/include/linux/ip.h b/include/linux/ip.h--- a/include/linux/ip.h 2007-05-18 15:21:38.000000000 +0300+++ b/include/linux/ip.h 2007-05-18 15:21:38.000000000 +0300@@ -79,6 +79,8 @@ #define IPOPT_TS_TSANDADDR 1 /* timestamps and addresses */ #define IPOPT_TS_PRESPEC 3 /* specified modules only */ +#define IPV4_BEET_PHMAXLEN 8+ struct iphdr { #if defined(__LITTLE_ENDIAN_BITFIELD) __u8 ihl:4,@@ -122,4 +124,11 @@ __u16 cpi; }; +struct ip_beet_phdr {+ __u8 nexthdr;+ __u8 hdrlen;+ __u8 padlen;+ __u8 reserved;+};+ #endif /* _LINUX_IP_H */diff -urN a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c--- a/net/ipv4/xfrm4_output.c 2007-05-18 15:21:38.000000000 +0300+++ b/net/ipv4/xfrm4_output.c 2007-05-18 15:21:38.000000000 +0300@@ -32,45 +32,131 @@ */ static void xfrm4_encap(struct sk_buff *skb) {- struct dst_entry *dst = skb->dst;- struct xfrm_state *x = dst->xfrm;- struct iphdr *iph, *top_iph;- int flags;-- iph = skb->nh.iph;- skb->h.ipiph = iph;-- skb->nh.raw = skb_push(skb, x->props.header_len);- top_iph = skb->nh.iph;-- if (!x->props.mode) {- skb->h.raw += iph->ihl*4;- memmove(top_iph, iph, iph->ihl*4);- return;- }-- top_iph->ihl = 5;- top_iph->version = 4;-- /* DS disclosed */- top_iph->tos = INET_ECN_encapsulate(iph->tos, iph->tos);-- flags = x->props.flags;- if (flags & XFRM_STATE_NOECN)- IP_ECN_clear(top_iph);-- top_iph->frag_off = (flags & XFRM_STATE_NOPMTUDISC) ?- 0 : (iph->frag_off & htons(IP_DF));- if (!top_iph->frag_off)- __ip_select_ident(top_iph, dst->child, 0);-- top_iph->ttl = dst_metric(dst->child, RTAX_HOPLIMIT);-- top_iph->saddr = x->props.saddr.a4;- top_iph->daddr = x->id.daddr.a4;- top_iph->protocol = IPPROTO_IPIP;-- memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));+ struct dst_entry *dst = skb->dst;+ struct xfrm_state *x = dst->xfrm;+ struct iphdr *iph, *top_iph;+ int flags;+ int hdrlen, optlen;++ iph = skb->nh.iph;+ skb->h.ipiph = iph;++ hdrlen = x->props.header_len;+ optlen = iph->ihl * 4 - sizeof(*iph);+ if (x->props.mode == XFRM_MODE_BEET) {+ 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_iph = skb->nh.iph;++ hdrlen = iph->ihl * 4 - optlen;+ switch (x->props.mode) {+ case XFRM_MODE_TRANSPORT:+ skb->h.raw += hdrlen;+ memmove(top_iph, iph, hdrlen);+ return;+ case XFRM_MODE_BEET:+ skb->h.raw += hdrlen;+ if (x->props.family == AF_INET) {+ memmove(top_iph, iph, 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 = iph->protocol;+ top_iph->protocol = IPPROTO_BEETPH;+ top_iph->ihl = sizeof(struct iphdr) / 4;+ }++ break;+ default:+ case XFRM_MODE_TUNNEL:+ if (x->props.family == AF_INET) {+ top_iph->ihl = 5;+ top_iph->version = 4;++ /* DS disclosed */+ top_iph->tos = INET_ECN_encapsulate(iph->tos, iph->tos);+ flags = x->props.flags;+ if (flags & XFRM_STATE_NOECN)+ IP_ECN_clear(top_iph);++ top_iph->frag_off = (flags & XFRM_STATE_NOPMTUDISC) ?+ 0 : (iph->frag_off & htons(IP_DF));+ if (!top_iph->frag_off)+ __ip_select_ident(top_iph, dst, 0);++ top_iph->ttl = dst_metric(dst->child, RTAX_HOPLIMIT);++ top_iph->protocol = IPPROTO_IPIP;+ memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options)); }+ break;+ }++ if (x->props.family == AF_INET) {+ top_iph->saddr = x->props.saddr.a4;+ top_iph->daddr = x->id.daddr.a4;+ } else if (x->props.family == AF_INET6) {+ /* Inner = 4, Outer = 6*/+ struct ipv6hdr *top_iph6;+ int dsfield;+ u8 protocol = top_iph->protocol;++ if (unlikely(optlen))+ protocol = top_iph->protocol;+ else+ protocol = iph->protocol;+ if (x->props.mode == XFRM_MODE_BEET) {+ int delta = sizeof(struct ipv6hdr) - sizeof(struct iphdr);++ if (skb_headroom(skb) <= 2*delta){+ if (pskb_expand_head(skb, delta,0, GFP_ATOMIC))+ return;+ }++ skb->nh.raw = skb_push(skb, delta);+ }++ top_iph6 = skb->nh.ipv6h;+ skb->h.ipv6h = top_iph6 + 1;+ /* DS disclosed */+ top_iph6->version = 6;+ top_iph6->priority = 0;+ top_iph6->flow_lbl[0] = 0;+ top_iph6->flow_lbl[1] = 0;+ top_iph6->flow_lbl[2] = 0;+ dsfield = ipv6_get_dsfield(top_iph6);+ dsfield = INET_ECN_encapsulate(dsfield, dsfield);+ flags = x->props.flags;+ if (flags & XFRM_STATE_NOECN)+ dsfield &= ~INET_ECN_MASK;+ ipv6_change_dsfield(top_iph6, 0, dsfield);++ if (x->props.mode == XFRM_MODE_TUNNEL)+ top_iph6->nexthdr = IPPROTO_IPIP;+ else+ top_iph6->nexthdr = protocol;+ top_iph6->hop_limit = dst_metric(dst->child, RTAX_HOPLIMIT);+ top_iph6->payload_len = htons(skb->len - sizeof(struct ipv6hdr));+ ipv6_addr_copy(&top_iph6->saddr,(struct in6_addr *)&x->props.saddr);+ ipv6_addr_copy(&top_iph6->daddr, (struct in6_addr *)&x->id.daddr);+ skb->nh.raw = &top_iph6->nexthdr;+ //skb->nh.raw = &skb->nh.ipv6h->nexthdr;+ } else+ BUG_ON(1); } static int xfrm4_tunnel_check_size(struct sk_buff *skb)@@ -109,7 +195,7 @@ goto error_nolock; } - if (x->props.mode) {+ if (x->props.mode == XFRM_MODE_TUNNEL) { err = xfrm4_tunnel_check_size(skb); if (err) goto error_nolock;diff -urN a/net/ipv4/xfrm4_tunnel.c b/net/ipv4/xfrm4_tunnel.c--- a/net/ipv4/xfrm4_tunnel.c 2007-05-18 15:21:38.000000000 +0300+++ b/net/ipv4/xfrm4_tunnel.c 2007-05-18 15:21:38.000000000 +0300@@ -28,13 +28,20 @@ static int ipip_init_state(struct xfrm_state *x) {- if (!x->props.mode)- return -EINVAL;- if (x->encap) return -EINVAL; - x->props.header_len = sizeof(struct iphdr);+ switch (x->props.mode) {+ case XFRM_MODE_TRANSPORT:+ return -EINVAL;+ default:+ case XFRM_MODE_TUNNEL:+ x->props.header_len = sizeof(struct iphdr);+ break;+ case XFRM_MODE_BEET:+ x->props.header_len += IPV4_BEET_PHMAXLEN;+ break;+ } return 0; }diff -urN a/net/ipv4/udp.c b/net/ipv4/udp.c--- a/net/ipv4/udp.c 2007-05-18 15:21:38.000000000 +0300+++ b/net/ipv4/udp.c 2007-05-18 15:21:38.000000000 +0300@@ -604,7 +604,7 @@ .uli_u = { .ports = { .sport = inet->sport, .dport = dport } } };- 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 out; diff -urN a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c--- a/net/ipv4/tcp_ipv4.c 2007-05-18 15:21:38.000000000 +0300+++ b/net/ipv4/tcp_ipv4.c 2007-05-18 15:21:38.000000000 +0300@@ -179,7 +179,7 @@ tmp = ip_route_connect(&rt, nexthop, inet->saddr, RT_CONN_FLAGS(sk), sk->sk_bound_dev_if, IPPROTO_TCP,- inet->sport, usin->sin_port, sk);+ inet->sport, usin->sin_port, sk, 1); if (tmp < 0) return tmp; diff -urN a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c--- a/net/ipv4/af_inet.c 2007-05-18 15:21:38.000000000 +0300+++ b/net/ipv4/af_inet.c 2007-05-18 15:21:38.000000000 +0300@@ -1006,7 +1006,7 @@ RT_CONN_FLAGS(sk), sk->sk_bound_dev_if, sk->sk_protocol,- inet->sport, inet->dport, sk);+ inet->sport, inet->dport, sk, 0); if (err) return err; diff -urN a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c--- a/net/ipv4/xfrm4_input.c 2007-05-18 15:21:38.000000000 +0300+++ b/net/ipv4/xfrm4_input.c 2007-05-18 15:21:38.000000000 +0300@@ -115,16 +115,29 @@ iph = skb->nh.iph; - if (x->props.mode) {- if (iph->protocol != IPPROTO_IPIP)- goto drop;- if (!pskb_may_pull(skb, sizeof(struct iphdr)))- goto drop;- if (skb_cloned(skb) &&- pskb_expand_head(skb, 0, 0, GFP_ATOMIC))- goto drop;- if (x->props.flags & XFRM_STATE_DECAP_DSCP)- ipv4_copy_dscp(iph, skb->h.ipiph);+ if (x->props.mode == XFRM_MODE_TUNNEL) {+ if (x->sel.family == AF_INET) {+ if (iph->protocol != IPPROTO_IPIP)+ goto drop;+ if (!pskb_may_pull(skb, sizeof(struct iphdr)))+ goto drop;+ if (skb_cloned(skb) &&+ pskb_expand_head(skb, 0, 0, GFP_ATOMIC))+ goto drop;+ if (x->props.flags & XFRM_STATE_DECAP_DSCP)+ ipv4_copy_dscp(iph, skb->h.ipiph);+ } else if (x->sel.family == AF_INET6) {+ /* Inner = 6, Outer = 4 */+ if (skb->nh.iph->protocol != IPPROTO_IPV6)+ goto drop;++ if (skb_cloned(skb) &&+ pskb_expand_head(skb, 0, 0, GFP_ATOMIC))+ goto drop;+ skb->protocol = htons(ETH_P_IPV6);+ } else+ BUG_ON(1);+ if (!(x->props.flags & XFRM_STATE_NOECN)) ipip_ecn_decapsulate(skb); skb->mac.raw = memmove(skb->data - skb->mac_len,@@ -133,6 +146,84 @@ memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options)); decaps = 1; break;+ } else if (x->props.mode == XFRM_MODE_BEET) {+ int phlen = 0;+ int optlen = 0;+ __u8 ph_nexthdr = 0;+ int size = (x->sel.family == AF_INET) ? sizeof(struct iphdr) : sizeof(struct ipv6hdr);+ int proto = skb->nh.iph->protocol;+ int hops = skb->nh.iph->ttl;+ int delta = sizeof(struct ipv6hdr) - sizeof(struct iphdr);+ if (x->sel.family == AF_INET6) {+ /* Here, the inner family is 6, therefore I have to+ * substitute the IPhdr by enlarging it */+ if (skb_tailroom(skb) < delta){+ if (pskb_expand_head(skb, 0, delta, GFP_ATOMIC))+ return -EINVAL; //Just returning from here.+ }+ skb->nh.raw -= delta;+ } else if (x->sel.family == AF_INET) {+ // We need to extract the PH+ struct ip_beet_phdr *ph = (struct ip_beet_phdr*)(skb->nh.iph + 1);++ if (proto == IPPROTO_BEETPH) {+ if (!pskb_may_pull(skb, sizeof(*ph)))+ goto drop;+ phlen = ph->hdrlen * 8;+ optlen = phlen - ph->padlen - sizeof(*ph);++ if (optlen < 0 || optlen & 3 || optlen > 250)+ goto drop;+ if (!pskb_may_pull(skb, phlen))+ goto drop;++ ph_nexthdr = ph->nexthdr;+ }+ } else+ BUG_ON(1);+++ if (skb_cloned(skb) &&+ pskb_expand_head(skb, 0, 0, GFP_ATOMIC))+ goto drop;+
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -