📄 beet-interfamily-and-sleep-loopback-2.6.19.7.patch
字号:
-u32 xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr)+__be32 xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr) { struct xfrm6_tunnel_spi *x6spi; u32 spi;@@ -222,7 +222,7 @@ write_lock_bh(&xfrm6_tunnel_spi_lock); - hlist_for_each_entry_safe(x6spi, pos, n, + hlist_for_each_entry_safe(x6spi, pos, n, &xfrm6_tunnel_spi_byaddr[xfrm6_tunnel_spi_hash_byaddr(saddr)], list_byaddr) {@@ -265,13 +265,13 @@ } static int xfrm6_tunnel_err(struct sk_buff *skb, struct inet6_skb_parm *opt,- int type, int code, int offset, __u32 info)+ int type, int code, int offset, __be32 info) { /* xfrm6_tunnel native err handling */ switch (type) {- case ICMPV6_DEST_UNREACH: + case ICMPV6_DEST_UNREACH: switch (code) {- case ICMPV6_NOROUTE: + case ICMPV6_NOROUTE: case ICMPV6_ADM_PROHIBITED: case ICMPV6_NOT_NEIGHBOUR: case ICMPV6_ADDR_UNREACH:@@ -287,7 +287,7 @@ case ICMPV6_EXC_HOPLIMIT: break; case ICMPV6_EXC_FRAGTIME:- default: + default: break; } break;@@ -307,7 +307,7 @@ static int xfrm6_tunnel_init_state(struct xfrm_state *x) {- if (x->props.mode != XFRM_MODE_TUNNEL)+ if (x->props.mode != XFRM_MODE_TUNNEL || x->props.mode != XFRM_MODE_BEET) return -EINVAL; if (x->encap)@@ -339,17 +339,29 @@ .priority = 2, }; +static struct xfrm6_tunnel xfrm46_tunnel_handler = {+ .handler = xfrm6_tunnel_rcv,+ .err_handler = xfrm6_tunnel_err,+ .priority = 2,+};+ static int __init xfrm6_tunnel_init(void) { if (xfrm_register_type(&xfrm6_tunnel_type, AF_INET6) < 0) return -EAGAIN; - if (xfrm6_tunnel_register(&xfrm6_tunnel_handler)) {+ if (xfrm6_tunnel_register(&xfrm6_tunnel_handler, AF_INET6)) {+ xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6);+ return -EAGAIN;+ }+ if (xfrm6_tunnel_register(&xfrm46_tunnel_handler, AF_INET)) {+ xfrm6_tunnel_deregister(&xfrm6_tunnel_handler, AF_INET6); xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6); return -EAGAIN; } if (xfrm6_tunnel_spi_init() < 0) {- xfrm6_tunnel_deregister(&xfrm6_tunnel_handler);+ xfrm6_tunnel_deregister(&xfrm46_tunnel_handler, AF_INET);+ xfrm6_tunnel_deregister(&xfrm6_tunnel_handler, AF_INET6); xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6); return -EAGAIN; }@@ -359,7 +371,8 @@ static void __exit xfrm6_tunnel_fini(void) { xfrm6_tunnel_spi_fini();- xfrm6_tunnel_deregister(&xfrm6_tunnel_handler);+ xfrm6_tunnel_deregister(&xfrm46_tunnel_handler, AF_INET);+ xfrm6_tunnel_deregister(&xfrm6_tunnel_handler, AF_INET6); xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6); } diff -urN a/net/ipv6/udp.c b/net/ipv6/udp.c--- a/net/ipv6/udp.c 2007-05-25 14:44:52.000000000 +0300+++ b/net/ipv6/udp.c 2007-05-25 14:44:52.000000000 +0300@@ -722,7 +722,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; 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 14:44:52.000000000 +0300+++ b/net/ipv6/tcp_ipv6.c 2007-05-25 14:44:52.000000000 +0300@@ -259,7 +259,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 failure; if (saddr == NULL) {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 14:44:52.000000000 +0300+++ b/net/ipv6/xfrm6_mode_tunnel.c 2007-05-25 14:44:52.000000000 +0300@@ -65,6 +65,8 @@ top_iph->hop_limit = dst_metric(dst->child, RTAX_HOPLIMIT); ipv6_addr_copy(&top_iph->saddr, (struct in6_addr *)&x->props.saddr); ipv6_addr_copy(&top_iph->daddr, (struct in6_addr *)&x->id.daddr);+ skb->protocol = htons(ETH_P_IPV6);+ return 0; } diff -urN a/net/ipv6/icmp.c b/net/ipv6/icmp.c--- a/net/ipv6/icmp.c 2007-05-25 14:44:52.000000000 +0300+++ b/net/ipv6/icmp.c 2007-05-25 14:44:52.000000000 +0300@@ -64,6 +64,7 @@ #include <net/ip6_route.h> #include <net/addrconf.h> #include <net/icmp.h>+#include <linux/xfrm.h> #include <asm/uaccess.h> #include <asm/system.h>diff -urN a/net/ipv6/raw.c b/net/ipv6/raw.c--- a/net/ipv6/raw.c 2007-05-25 14:44:52.000000000 +0300+++ b/net/ipv6/raw.c 2007-05-25 14:44:52.000000000 +0300@@ -816,7 +816,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; if (hlimit < 0) {diff -urN a/net/ipv6/tunnel6.c b/net/ipv6/tunnel6.c--- a/net/ipv6/tunnel6.c 2007-05-25 14:44:52.000000000 +0300+++ b/net/ipv6/tunnel6.c 2007-05-25 14:44:52.000000000 +0300@@ -30,9 +30,10 @@ #include <net/xfrm.h> static struct xfrm6_tunnel *tunnel6_handlers;+static struct xfrm6_tunnel *tunnel46_handlers; static DEFINE_MUTEX(tunnel6_mutex); -int xfrm6_tunnel_register(struct xfrm6_tunnel *handler)+int xfrm6_tunnel_register(struct xfrm6_tunnel *handler, unsigned short family) { struct xfrm6_tunnel **pprev; int ret = -EEXIST;@@ -40,7 +41,8 @@ mutex_lock(&tunnel6_mutex); - for (pprev = &tunnel6_handlers; *pprev; pprev = &(*pprev)->next) {+ for (pprev = (family == AF_INET6) ? &tunnel6_handlers : &tunnel46_handlers;+ *pprev; pprev = &(*pprev)->next) { if ((*pprev)->priority > priority) break; if ((*pprev)->priority == priority)@@ -60,14 +62,15 @@ EXPORT_SYMBOL(xfrm6_tunnel_register); -int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler)+int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler, unsigned short family) { struct xfrm6_tunnel **pprev; int ret = -ENOENT; mutex_lock(&tunnel6_mutex); - for (pprev = &tunnel6_handlers; *pprev; pprev = &(*pprev)->next) {+ for (pprev = (family == AF_INET6) ? &tunnel6_handlers : &tunnel46_handlers;+ *pprev; pprev = &(*pprev)->next) { if (*pprev == handler) { *pprev = handler->next; ret = 0;@@ -103,8 +106,27 @@ return 0; } +static int tunnel46_rcv(struct sk_buff **pskb)+{+ struct sk_buff *skb = *pskb;+ struct xfrm6_tunnel *handler;++ if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))+ goto drop;++ for (handler = tunnel46_handlers; handler; handler = handler->next)+ if (!handler->handler(skb))+ return 0;++ icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0, skb->dev);++drop:+ kfree_skb(skb);+ return 0;+}+ static void tunnel6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,- int type, int code, int offset, __u32 info)+ int type, int code, int offset, __be32 info) { struct xfrm6_tunnel *handler; @@ -119,17 +141,30 @@ .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL, }; +static struct inet6_protocol tunnel46_protocol = {+ .handler = tunnel46_rcv,+ .err_handler = tunnel6_err,+ .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,+};+ static int __init tunnel6_init(void) { if (inet6_add_protocol(&tunnel6_protocol, IPPROTO_IPV6)) { printk(KERN_ERR "tunnel6 init(): can't add protocol\n"); return -EAGAIN; }+ if (inet6_add_protocol(&tunnel46_protocol, IPPROTO_IPIP)) {+ printk(KERN_ERR "tunnel6 init(): can't add protocol\n");+ inet6_del_protocol(&tunnel6_protocol, IPPROTO_IPV6);+ return -EAGAIN;+ } return 0; } static void __exit tunnel6_fini(void) {+ if (inet6_del_protocol(&tunnel46_protocol, IPPROTO_IPIP))+ printk(KERN_ERR "tunnel6 close: can't remove protocol\n"); if (inet6_del_protocol(&tunnel6_protocol, IPPROTO_IPV6)) printk(KERN_ERR "tunnel6 close: can't remove protocol\n"); }diff -urN a/net/dccp/ipv4.c b/net/dccp/ipv4.c--- a/net/dccp/ipv4.c 2007-05-25 14:44:52.000000000 +0300+++ b/net/dccp/ipv4.c 2007-05-25 14:44:52.000000000 +0300@@ -72,7 +72,7 @@ tmp = ip_route_connect(&rt, nexthop, inet->saddr, RT_CONN_FLAGS(sk), sk->sk_bound_dev_if, IPPROTO_DCCP,- inet->sport, usin->sin_port, sk);+ inet->sport, usin->sin_port, sk, 1); if (tmp < 0) return tmp; diff -urN a/net/dccp/ipv6.c b/net/dccp/ipv6.c--- a/net/dccp/ipv6.c 2007-05-25 14:44:52.000000000 +0300+++ b/net/dccp/ipv6.c 2007-05-25 14:44:52.000000000 +0300@@ -218,7 +218,7 @@ if (final_p) ipv6_addr_copy(&fl.fl6_dst, final_p); - err = xfrm_lookup(&dst, &fl, sk, 0);+ err = xfrm_lookup(&dst, &fl, sk, 1); if (err < 0) goto failure; diff -urN a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c--- a/net/xfrm/xfrm_user.c 2007-05-25 14:44:52.000000000 +0300+++ b/net/xfrm/xfrm_user.c 2007-05-25 14:44:52.000000000 +0300@@ -875,6 +875,8 @@ t->aalgos = ut->aalgos; t->ealgos = ut->ealgos; t->calgos = ut->calgos;+ t->encap_family = ut->family;+ } } @@ -1028,7 +1030,7 @@ struct xfrm_tmpl *kp = &xp->xfrm_vec[i]; memcpy(&up->id, &kp->id, sizeof(up->id));- up->family = xp->family;+ up->family = kp->encap_family; memcpy(&up->saddr, &kp->saddr, sizeof(up->saddr)); up->reqid = kp->reqid; up->mode = kp->mode;diff -urN a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c--- a/net/xfrm/xfrm_policy.c 2007-05-25 14:44:52.000000000 +0300+++ b/net/xfrm/xfrm_policy.c 2007-05-25 14:44:52.000000000 +0300@@ -1168,9 +1168,10 @@ xfrm_address_t *local = saddr; struct xfrm_tmpl *tmpl = &policy->xfrm_vec[i]; - if (tmpl->mode == XFRM_MODE_TUNNEL) {+ if (tmpl->mode == XFRM_MODE_TUNNEL || tmpl->mode == XFRM_MODE_BEET) { remote = &tmpl->id.daddr; local = &tmpl->saddr;+ family = tmpl->encap_family; if (xfrm_addr_any(local, family)) { error = xfrm_get_saddr(&tmp, remote, family); if (error)@@ -1193,6 +1194,7 @@ xfrm_state_put(x); } + if (!tmpl->optional) goto fail; }@@ -1465,6 +1467,7 @@ err = -EHOSTUNREACH; goto error; }+ dst->next = policy->bundles; policy->bundles = dst; dst_hold(dst);@@ -1511,7 +1514,7 @@ unsigned short family) { if (xfrm_state_kern(x))- return tmpl->optional && !xfrm_state_addr_cmp(tmpl, x, family);+ return tmpl->optional && !xfrm_state_addr_cmp(tmpl, x, tmpl->encap_family); return x->id.proto == tmpl->id.proto && (x->id.spi == tmpl->id.spi || !tmpl->id.spi) && (x->props.reqid == tmpl->reqid || !tmpl->reqid) &&diff -urN a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c--- a/net/xfrm/xfrm_state.c 2007-05-25 14:44:52.000000000 +0300+++ b/net/xfrm/xfrm_state.c 2007-05-25 14:44:52.000000000 +0300@@ -549,7 +549,7 @@ selector. */ if (x->km.state == XFRM_STATE_VALID) {- if (!xfrm_selector_match(&x->sel, fl, family) ||+ if (!xfrm_selector_match(&x->sel, fl, x->sel.family) || !security_xfrm_state_pol_flow_match(x, pol, fl)) continue; if (!best ||@@ -561,9 +561,10 @@ acquire_in_progress = 1; } else if (x->km.state == XFRM_STATE_ERROR || x->km.state == XFRM_STATE_EXPIRED) {- if (xfrm_selector_match(&x->sel, fl, family) &&- security_xfrm_state_pol_flow_match(x, pol, fl))+ if (xfrm_selector_match(&x->sel, fl, x->sel.family) &&+ security_xfrm_state_pol_flow_match(x, pol, fl)) { error = -ESRCH;+ } } } }@@ -620,6 +621,7 @@ xfrm_state_hold(x); else *err = acquire_in_progress ? -EAGAIN : error;+ spin_unlock_bh(&xfrm_state_lock); return x; }diff -urN a/include/net/xfrm.h b/include/net/xfrm.h--- a/include/net/xfrm.h 2007-05-25 14:44:52.000000000 +0300+++ b/include/net/xfrm.h 2007-05-25 14:44:52.000000000 +0300@@ -237,7 +237,7 @@ extern int xfrm_policy_unregister_afinfo(struct xfrm_policy_afinfo *afinfo); extern void km_policy_notify(struct xfrm_policy *xp, int dir, struct km_event *c); extern void km_state_notify(struct xfrm_state *x, struct km_event *c);-#define XFRM_ACQ_EXPIRES 30+#define XFRM_ACQ_EXPIRES 3 struct xfrm_tmpl; extern int km_query(struct xfrm_state *x, struct xfrm_tmpl *t, struct xfrm_policy *pol);@@ -310,6 +310,8 @@ /* Source address of tunnel. Ignored, if it is not a tunnel. */ xfrm_address_t saddr; + unsigned short encap_family;+ __u32 reqid; /* Mode: transport, tunnel etc. */@@ -325,6 +327,7 @@ __u32 aalgos; __u32 ealgos; __u32 calgos;+ }; #define XFRM_MAX_DEPTH 6@@ -509,6 +512,7 @@ static inline int __xfrm4_selector_match(struct xfrm_selector *sel, struct flowi *fl) {+ return addr_match(&fl->fl4_dst, &sel->daddr, sel->prefixlen_d) && addr_match(&fl->fl4_src, &sel->saddr, sel->prefixlen_s) && !((xfrm_flowi_dport(fl) ^ sel->dport) & sel->dport_mask) &&@@ -943,14 +947,14 @@ extern int xfrm_init_state(struct xfrm_state *x); extern int xfrm4_rcv(struct sk_buff *skb); extern int xfrm4_output(struct sk_buff *skb);-extern int xfrm4_tunnel_register(struct xfrm_tunnel *handler);-extern int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler);+extern int xfrm4_tunnel_register(struct xfrm_tunnel *handler, unsigned short family);+extern int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler, unsigned short family); extern int xfrm6_rcv_spi(struct sk_buff *skb, __be32 spi); extern int xfrm6_rcv(struct sk_buff **pskb); extern int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr, xfrm_address_t *saddr, u8 proto);-extern int xfrm6_tunnel_register(struct xfrm6_tunnel *handler);-extern int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler);+extern int xfrm6_tunnel_register(struct xfrm6_tunnel *handler, unsigned short family);+extern int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler, unsigned short family); extern u32 xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr); extern void xfrm6_tunnel_free_spi(xfrm_address_t *saddr); extern u32 xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr);@@ -1064,5 +1068,4 @@ xfrm_replay_notify(x, XFRM_REPLAY_UPDATE); } - #endif /* _NET_XFRM_H */diff -urN a/include/net/route.h b/include/net/route.h--- a/include/net/route.h 2007-05-25 14:44:52.000000000 +0300+++ b/include/net/route.h 2007-05-25 14:44:52.000000000 +0300@@ -146,7 +146,8 @@ static inline int ip_route_connect(struct rtable **rp, __be32 dst, __be32 src, u32 tos, int oif, u8 protocol,- __be16 sport, __be16 dport, struct sock *sk)+ __be16 sport, __be16 dport, struct sock *sk,+ int flags) { struct flowi fl = { .oif = oif, .nl_u = { .ip4_u = { .daddr = dst,@@ -168,7 +169,7 @@ *rp = NULL; } security_sk_classify_flow(sk, &fl);- 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,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -