Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / net / ipv6 / xfrm6_tunnel.c
index ffcadd6..d37768e 100644 (file)
@@ -28,9 +28,9 @@
 #include <net/ip.h>
 #include <net/xfrm.h>
 #include <net/ipv6.h>
-#include <net/protocol.h>
 #include <linux/ipv6.h>
 #include <linux/icmpv6.h>
+#include <linux/mutex.h>
 
 #ifdef CONFIG_IPV6_XFRM6_TUNNEL_DEBUG
 # define X6TDEBUG      3
@@ -79,7 +79,7 @@ static u32 xfrm6_tunnel_spi;
 #define XFRM6_TUNNEL_SPI_MIN   1
 #define XFRM6_TUNNEL_SPI_MAX   0xffffffff
 
-static kmem_cache_t *xfrm6_tunnel_spi_kmem;
+static kmem_cache_t *xfrm6_tunnel_spi_kmem __read_mostly;
 
 #define XFRM6_TUNNEL_SPI_BYADDR_HSIZE 256
 #define XFRM6_TUNNEL_SPI_BYSPI_HSIZE 256
@@ -259,8 +259,7 @@ try_next_2:;
        spi = 0;
        goto out;
 alloc_spi:
-       X6TPRINTK3(KERN_DEBUG "%s(): allocate new spi for "
-                             "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", 
+       X6TPRINTK3(KERN_DEBUG "%s(): allocate new spi for " NIP6_FMT "\n",
                              __FUNCTION__, 
                              NIP6(*(struct in6_addr *)saddr));
        x6spi = kmem_cache_alloc(xfrm6_tunnel_spi_kmem, SLAB_ATOMIC);
@@ -323,9 +322,8 @@ void xfrm6_tunnel_free_spi(xfrm_address_t *saddr)
                                  list_byaddr)
        {
                if (memcmp(&x6spi->addr, saddr, sizeof(x6spi->addr)) == 0) {
-                       X6TPRINTK3(KERN_DEBUG "%s(): x6spi object "
-                                             "for %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x "
-                                             "found at %p\n",
+                       X6TPRINTK3(KERN_DEBUG "%s(): x6spi object for " NIP6_FMT 
+                                             " found at %p\n",
                                   __FUNCTION__, 
                                   NIP6(*(struct in6_addr *)saddr),
                                   x6spi);
@@ -353,76 +351,23 @@ static int xfrm6_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)
        return 0;
 }
 
-static int xfrm6_tunnel_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_buff *skb)
+static int xfrm6_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
 {
        return 0;
 }
 
-static struct xfrm6_tunnel *xfrm6_tunnel_handler;
-static DECLARE_MUTEX(xfrm6_tunnel_sem);
-
-int xfrm6_tunnel_register(struct xfrm6_tunnel *handler)
+static int xfrm6_tunnel_rcv(struct sk_buff *skb)
 {
-       int ret;
-
-       down(&xfrm6_tunnel_sem);
-       ret = 0;
-       if (xfrm6_tunnel_handler != NULL)
-               ret = -EINVAL;
-       if (!ret)
-               xfrm6_tunnel_handler = handler;
-       up(&xfrm6_tunnel_sem);
-
-       return ret;
-}
-
-EXPORT_SYMBOL(xfrm6_tunnel_register);
-
-int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler)
-{
-       int ret;
-
-       down(&xfrm6_tunnel_sem);
-       ret = 0;
-       if (xfrm6_tunnel_handler != handler)
-               ret = -EINVAL;
-       if (!ret)
-               xfrm6_tunnel_handler = NULL;
-       up(&xfrm6_tunnel_sem);
-
-       synchronize_net();
-
-       return ret;
-}
-
-EXPORT_SYMBOL(xfrm6_tunnel_deregister);
-
-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 ipv6hdr *iph = skb->nh.ipv6h;
        u32 spi;
 
-       /* device-like_ip6ip6_handler() */
-       if (handler && handler->handler(pskb, nhoffp) == 0)
-               return 0;
-
        spi = xfrm6_tunnel_spi_lookup((xfrm_address_t *)&iph->saddr);
-       return xfrm6_rcv_spi(pskb, nhoffp, spi);
+       return xfrm6_rcv_spi(skb, spi);
 }
 
-static void xfrm6_tunnel_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
-                            int type, int code, int offset, __u32 info)
+static int xfrm6_tunnel_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
+                           int type, int code, int offset, __u32 info)
 {
-       struct xfrm6_tunnel *handler = xfrm6_tunnel_handler;
-
-       /* call here first for device-like ip6ip6 err handling */
-       if (handler) {
-               handler->err_handler(skb, opt, type, code, offset, info);
-               return;
-       }
-
        /* xfrm6_tunnel native err handling */
        switch (type) {
        case ICMPV6_DEST_UNREACH: 
@@ -463,10 +408,11 @@ static void xfrm6_tunnel_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
        default:
                break;
        }
-       return;
+
+       return 0;
 }
 
-static int xfrm6_tunnel_init_state(struct xfrm_state *x, void *args)
+static int xfrm6_tunnel_init_state(struct xfrm_state *x)
 {
        if (!x->props.mode)
                return -EINVAL;
@@ -494,10 +440,10 @@ static struct xfrm_type xfrm6_tunnel_type = {
        .output         = xfrm6_tunnel_output,
 };
 
-static struct inet6_protocol xfrm6_tunnel_protocol = {
+static struct xfrm6_tunnel xfrm6_tunnel_handler = {
        .handler        = xfrm6_tunnel_rcv,
-       .err_handler    = xfrm6_tunnel_err, 
-       .flags          = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
+       .err_handler    = xfrm6_tunnel_err,
+       .priority       = 2,
 };
 
 static int __init xfrm6_tunnel_init(void)
@@ -509,16 +455,16 @@ static int __init xfrm6_tunnel_init(void)
                           "xfrm6_tunnel init: can't add xfrm type\n");
                return -EAGAIN;
        }
-       if (inet6_add_protocol(&xfrm6_tunnel_protocol, IPPROTO_IPV6) < 0) {
+       if (xfrm6_tunnel_register(&xfrm6_tunnel_handler)) {
                X6TPRINTK1(KERN_ERR
-                          "xfrm6_tunnel init(): can't add protocol\n");
+                          "xfrm6_tunnel init(): can't add handler\n");
                xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6);
                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);
+               xfrm6_tunnel_deregister(&xfrm6_tunnel_handler);
                xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6);
                return -EAGAIN;
        }
@@ -530,9 +476,9 @@ static void __exit xfrm6_tunnel_fini(void)
        X6TPRINTK3(KERN_DEBUG "%s()\n", __FUNCTION__);
 
        xfrm6_tunnel_spi_fini();
-       if (inet6_del_protocol(&xfrm6_tunnel_protocol, IPPROTO_IPV6) < 0)
+       if (xfrm6_tunnel_deregister(&xfrm6_tunnel_handler))
                X6TPRINTK1(KERN_ERR 
-                          "xfrm6_tunnel close: can't remove protocol\n");
+                          "xfrm6_tunnel close: can't remove handler\n");
        if (xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6) < 0)
                X6TPRINTK1(KERN_ERR
                           "xfrm6_tunnel close: can't remove xfrm type\n");