X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=net%2Fipv6%2Fxfrm6_tunnel.c;h=9616a63cc4314fb8c47ee4857793d3cf18338f33;hb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;hp=5766a133411a358a2427c74ab107f370f1d4a1ec;hpb=a2c21200f1c81b08cb55e417b68150bba439b646;p=linux-2.6.git diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c index 5766a1334..9616a63cc 100644 --- a/net/ipv6/xfrm6_tunnel.c +++ b/net/ipv6/xfrm6_tunnel.c @@ -343,9 +343,8 @@ void xfrm6_tunnel_free_spi(xfrm_address_t *saddr) EXPORT_SYMBOL(xfrm6_tunnel_free_spi); -static int xfrm6_tunnel_output(struct sk_buff **pskb) +static int xfrm6_tunnel_output(struct sk_buff *skb) { - struct sk_buff *skb = *pskb; struct ipv6hdr *top_iph; top_iph = (struct ipv6hdr *)skb->data; @@ -356,17 +355,6 @@ static int xfrm6_tunnel_output(struct sk_buff **pskb) static int xfrm6_tunnel_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_buff *skb) { - if (!pskb_may_pull(skb, sizeof(struct ipv6hdr))) - return -EINVAL; - - skb->mac.raw = skb->nh.raw; - skb->nh.raw = skb->data; - dst_release(skb->dst); - skb->dst = NULL; - skb->protocol = htons(ETH_P_IPV6); - skb->pkt_type = PACKET_HOST; - netif_rx(skb); - return 0; } @@ -413,49 +401,15 @@ static int xfrm6_tunnel_rcv(struct sk_buff **pskb, unsigned int *nhoffp) { struct sk_buff *skb = *pskb; struct xfrm6_tunnel *handler = xfrm6_tunnel_handler; - struct xfrm_state *x = NULL; struct ipv6hdr *iph = skb->nh.ipv6h; - int err = 0; u32 spi; /* device-like_ip6ip6_handler() */ - if (handler) { - err = handler->handler(pskb, nhoffp); - if (!err) - goto out; - } + if (handler && handler->handler(pskb, nhoffp) == 0) + return 0; spi = xfrm6_tunnel_spi_lookup((xfrm_address_t *)&iph->saddr); - x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, - spi, - IPPROTO_IPV6, AF_INET6); - - if (!x) - goto drop; - - spin_lock(&x->lock); - - if (unlikely(x->km.state != XFRM_STATE_VALID)) - goto drop_unlock; - - err = xfrm6_tunnel_input(x, NULL, skb); - if (err) - goto drop_unlock; - - x->curlft.bytes += skb->len; - x->curlft.packets++; - spin_unlock(&x->lock); - xfrm_state_put(x); - -out: - return 0; - -drop_unlock: - spin_unlock(&x->lock); - xfrm_state_put(x); -drop: - kfree_skb(skb); - return -1; + return xfrm6_rcv_spi(pskb, nhoffp, spi); } static void xfrm6_tunnel_err(struct sk_buff *skb, struct inet6_skb_parm *opt, @@ -517,6 +471,9 @@ static int xfrm6_tunnel_init_state(struct xfrm_state *x, void *args) if (!x->props.mode) return -EINVAL; + if (x->encap) + return -EINVAL; + x->props.header_len = sizeof(struct ipv6hdr); return 0; @@ -543,31 +500,32 @@ static struct inet6_protocol xfrm6_tunnel_protocol = { .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL, }; -void __init xfrm6_tunnel_init(void) +static int __init xfrm6_tunnel_init(void) { X6TPRINTK3(KERN_DEBUG "%s()\n", __FUNCTION__); if (xfrm_register_type(&xfrm6_tunnel_type, AF_INET6) < 0) { X6TPRINTK1(KERN_ERR "xfrm6_tunnel init: can't add xfrm type\n"); - return; + return -EAGAIN; } if (inet6_add_protocol(&xfrm6_tunnel_protocol, IPPROTO_IPV6) < 0) { X6TPRINTK1(KERN_ERR "xfrm6_tunnel init(): can't add protocol\n"); xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6); - return; + return -EAGAIN; } if (xfrm6_tunnel_spi_init() < 0) { X6TPRINTK1(KERN_ERR "xfrm6_tunnel init: failed to initialize spi\n"); inet6_del_protocol(&xfrm6_tunnel_protocol, IPPROTO_IPV6); xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6); - return; + return -EAGAIN; } + return 0; } -void __exit xfrm6_tunnel_fini(void) +static void __exit xfrm6_tunnel_fini(void) { X6TPRINTK3(KERN_DEBUG "%s()\n", __FUNCTION__); @@ -579,3 +537,7 @@ void __exit xfrm6_tunnel_fini(void) X6TPRINTK1(KERN_ERR "xfrm6_tunnel close: can't remove xfrm type\n"); } + +module_init(xfrm6_tunnel_init); +module_exit(xfrm6_tunnel_fini); +MODULE_LICENSE("GPL");