X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=net%2Fipv4%2Fxfrm4_tunnel.c;h=f8ceaa127c836d4bc6e626ae95eebf22f190a04d;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=0d1a0b0c7901265a7b76823365435aed1b6bd286;hpb=9bf4aaab3e101692164d49b7ca357651eb691cb6;p=linux-2.6.git diff --git a/net/ipv4/xfrm4_tunnel.c b/net/ipv4/xfrm4_tunnel.c index 0d1a0b0c7..f8ceaa127 100644 --- a/net/ipv4/xfrm4_tunnel.c +++ b/net/ipv4/xfrm4_tunnel.c @@ -4,13 +4,14 @@ */ #include +#include +#include #include #include #include -static int ipip_output(struct sk_buff **pskb) +static int ipip_output(struct xfrm_state *x, struct sk_buff *skb) { - struct sk_buff *skb = *pskb; struct iphdr *iph; iph = skb->nh.iph; @@ -20,70 +21,19 @@ static int ipip_output(struct sk_buff **pskb) return 0; } -static int ipip_xfrm_rcv(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_buff *skb) +static int ipip_xfrm_rcv(struct xfrm_state *x, struct sk_buff *skb) { return 0; } -static struct xfrm_tunnel *ipip_handler; -static DECLARE_MUTEX(xfrm4_tunnel_sem); - -int xfrm4_tunnel_register(struct xfrm_tunnel *handler) -{ - int ret; - - down(&xfrm4_tunnel_sem); - ret = 0; - if (ipip_handler != NULL) - ret = -EINVAL; - if (!ret) - ipip_handler = handler; - up(&xfrm4_tunnel_sem); - - return ret; -} - -int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler) -{ - int ret; - - down(&xfrm4_tunnel_sem); - ret = 0; - if (ipip_handler != handler) - ret = -EINVAL; - if (!ret) - ipip_handler = NULL; - up(&xfrm4_tunnel_sem); - - synchronize_net(); - - return ret; -} - -static int ipip_rcv(struct sk_buff *skb) -{ - struct xfrm_tunnel *handler = ipip_handler; - - /* Tunnel devices take precedence. */ - if (handler && handler->handler(skb) == 0) - return 0; - - return xfrm4_rcv_encap(skb, 0); -} - -static void ipip_err(struct sk_buff *skb, u32 info) -{ - struct xfrm_tunnel *handler = ipip_handler; - u32 arg = info; - - if (handler) - handler->err_handler(skb, &arg); -} - -static int ipip_init_state(struct xfrm_state *x, void *args) +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); return 0; @@ -103,10 +53,15 @@ static struct xfrm_type ipip_type = { .output = ipip_output }; -static struct net_protocol ipip_protocol = { - .handler = ipip_rcv, - .err_handler = ipip_err, - .no_policy = 1, +static int xfrm_tunnel_err(struct sk_buff *skb, u32 info) +{ + return -ENOENT; +} + +static struct xfrm_tunnel xfrm_tunnel_handler = { + .handler = xfrm4_rcv, + .err_handler = xfrm_tunnel_err, + .priority = 2, }; static int __init ipip_init(void) @@ -115,8 +70,8 @@ static int __init ipip_init(void) printk(KERN_INFO "ipip init: can't add xfrm type\n"); return -EAGAIN; } - if (inet_add_protocol(&ipip_protocol, IPPROTO_IPIP) < 0) { - printk(KERN_INFO "ipip init: can't add protocol\n"); + if (xfrm4_tunnel_register(&xfrm_tunnel_handler)) { + printk(KERN_INFO "ipip init: can't add xfrm handler\n"); xfrm_unregister_type(&ipip_type, AF_INET); return -EAGAIN; } @@ -125,8 +80,8 @@ static int __init ipip_init(void) static void __exit ipip_fini(void) { - if (inet_del_protocol(&ipip_protocol, IPPROTO_IPIP) < 0) - printk(KERN_INFO "ipip close: can't remove protocol\n"); + if (xfrm4_tunnel_deregister(&xfrm_tunnel_handler)) + printk(KERN_INFO "ipip close: can't remove xfrm handler\n"); if (xfrm_unregister_type(&ipip_type, AF_INET) < 0) printk(KERN_INFO "ipip close: can't remove xfrm type\n"); }