vserver 2.0 rc7
[linux-2.6.git] / net / ipv4 / af_inet.c
index edf4570..f0b0511 100644 (file)
@@ -7,7 +7,7 @@
  *
  * Version:    $Id: af_inet.c,v 1.137 2002/02/01 22:01:03 davem Exp $
  *
- * Authors:    Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors:    Ross Biro
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  *             Florian La Roche, <flla@stud.uni-sb.de>
  *             Alan Cox, <A.Cox@swansea.ac.uk>
@@ -73,7 +73,6 @@
 #include <linux/socket.h>
 #include <linux/in.h>
 #include <linux/kernel.h>
-#include <linux/major.h>
 #include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/timer.h>
 #ifdef CONFIG_IP_MROUTE
 #include <linux/mroute.h>
 #endif
+#include <linux/vs_limit.h>
 
 DEFINE_SNMP_STAT(struct linux_mib, net_statistics);
 
@@ -121,22 +121,17 @@ atomic_t inet_sock_nr;
 
 extern void ip_mc_drop_socket(struct sock *sk);
 
-/* Per protocol sock slabcache */
-kmem_cache_t *tcp_sk_cachep;
-static kmem_cache_t *udp_sk_cachep;
-static kmem_cache_t *raw4_sk_cachep;
-
 /* The inetsw table contains everything that inet_create needs to
  * build a new socket.
  */
 static struct list_head inetsw[SOCK_MAX];
-static spinlock_t inetsw_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(inetsw_lock);
 
 /* New destruction routine */
 
 void inet_sock_destruct(struct sock *sk)
 {
-       struct inet_opt *inet = inet_sk(sk);
+       struct inet_sock *inet = inet_sk(sk);
 
        __skb_queue_purge(&sk->sk_receive_queue);
        __skb_queue_purge(&sk->sk_error_queue);
@@ -166,86 +161,19 @@ void inet_sock_destruct(struct sock *sk)
 #endif
 }
 
-void inet_sock_release(struct sock *sk)
-{
-       if (sk->sk_prot->destroy)
-               sk->sk_prot->destroy(sk);
-
-       /* Observation: when inet_sock_release is called, processes have
-        * no access to socket. But net still has.
-        * Step one, detach it from networking:
-        *
-        * A. Remove from hash tables.
-        */
-
-       sk->sk_prot->unhash(sk);
-
-       /* In this point socket cannot receive new packets,
-        * but it is possible that some packets are in flight
-        * because some CPU runs receiver and did hash table lookup
-        * before we unhashed socket. They will achieve receive queue
-        * and will be purged by socket destructor.
-        *
-        * Also we still have packets pending on receive
-        * queue and probably, our own packets waiting in device queues.
-        * sock_destroy will drain receive queue, but transmitted
-        * packets will delay socket destruction until the last reference
-        * will be released.
-        */
-
-       sock_orphan(sk);
-
-       xfrm_sk_free_policy(sk);
-
-#ifdef INET_REFCNT_DEBUG
-       if (atomic_read(&sk->sk_refcnt) != 1)
-               printk(KERN_DEBUG "Destruction inet %p delayed, c=%d\n",
-                      sk, atomic_read(&sk->sk_refcnt));
-#endif
-       sock_put(sk);
-}
-
-
 /*
  *     The routines beyond this point handle the behaviour of an AF_INET
  *     socket object. Mostly it punts to the subprotocols of IP to do
  *     the work.
  */
 
-/*
- *     Set socket options on an inet socket.
- */
-int inet_setsockopt(struct socket *sock, int level, int optname,
-                   char *optval, int optlen)
-{
-       struct sock *sk = sock->sk;
-
-       return sk->sk_prot->setsockopt(sk, level, optname, optval, optlen);
-}
-
-/*
- *     Get a socket option on an AF_INET socket.
- *
- *     FIX: POSIX 1003.1g is very ambiguous here. It states that
- *     asynchronous errors should be reported by getsockopt. We assume
- *     this means if you specify SO_ERROR (otherwise whats the point of it).
- */
-
-int inet_getsockopt(struct socket *sock, int level, int optname,
-                   char *optval, int *optlen)
-{
-       struct sock *sk = sock->sk;
-
-       return sk->sk_prot->getsockopt(sk, level, optname, optval, optlen);
-}
-
 /*
  *     Automatically bind an unbound socket.
  */
 
 static int inet_autobind(struct sock *sk)
 {
-       struct inet_opt *inet;
+       struct inet_sock *inet;
        /* We may need to bind the socket. */
        lock_sock(sk);
        inet = inet_sk(sk);
@@ -295,28 +223,6 @@ out:
        return err;
 }
 
-static __inline__ kmem_cache_t *inet_sk_slab(int protocol)
-{
-       kmem_cache_t* rc = tcp_sk_cachep;
-
-       if (protocol == IPPROTO_UDP)
-               rc = udp_sk_cachep;
-       else if (protocol == IPPROTO_RAW)
-               rc = raw4_sk_cachep;
-       return rc;
-}
-
-static __inline__ int inet_sk_size(int protocol)
-{
-       int rc = sizeof(struct tcp_sock);
-
-       if (protocol == IPPROTO_UDP)
-               rc = sizeof(struct udp_sock);
-       else if (protocol == IPPROTO_RAW)
-               rc = sizeof(struct raw_sock);
-       return rc;
-}
-
 /*
  *     Create an inet socket.
  */
@@ -326,14 +232,13 @@ static int inet_create(struct socket *sock, int protocol)
        struct sock *sk;
        struct list_head *p;
        struct inet_protosw *answer;
-       struct inet_opt *inet;
-       int err = -ENOBUFS;
+       struct inet_sock *inet;
+       struct proto *answer_prot;
+       unsigned char answer_flags;
+       char answer_no_check;
+       int err;
 
        sock->state = SS_UNCONNECTED;
-       sk = sk_alloc(PF_INET, GFP_KERNEL, inet_sk_size(protocol),
-                     inet_sk_slab(protocol));
-       if (!sk)
-               goto out;
 
        /* Look for the requested type/protocol pair. */
        answer = NULL;
@@ -359,21 +264,35 @@ static int inet_create(struct socket *sock, int protocol)
 
        err = -ESOCKTNOSUPPORT;
        if (!answer)
-               goto out_sk_free;
+               goto out_rcu_unlock;
        err = -EPERM;
+       if ((protocol == IPPROTO_ICMP) && vx_ccaps(VXC_RAW_ICMP))
+               goto override;
        if (answer->capability > 0 && !capable(answer->capability))
-               goto out_sk_free;
+               goto out_rcu_unlock;
+override:
        err = -EPROTONOSUPPORT;
        if (!protocol)
-               goto out_sk_free;
-       err = 0;
+               goto out_rcu_unlock;
+
        sock->ops = answer->ops;
-       sk->sk_prot = answer->prot;
-       sk->sk_no_check = answer->no_check;
-       if (INET_PROTOSW_REUSE & answer->flags)
-               sk->sk_reuse = 1;
+       answer_prot = answer->prot;
+       answer_no_check = answer->no_check;
+       answer_flags = answer->flags;
        rcu_read_unlock();
 
+       BUG_TRAP(answer_prot->slab != NULL);
+
+       err = -ENOBUFS;
+       sk = sk_alloc(PF_INET, GFP_KERNEL, answer_prot, 1);
+       if (sk == NULL)
+               goto out;
+
+       err = 0;
+       sk->sk_no_check = answer_no_check;
+       if (INET_PROTOSW_REUSE & answer_flags)
+               sk->sk_reuse = 1;
+
        inet = inet_sk(sk);
 
        if (SOCK_RAW == sock->type) {
@@ -390,10 +309,8 @@ static int inet_create(struct socket *sock, int protocol)
        inet->id = 0;
 
        sock_init_data(sock, sk);
-       sk_set_owner(sk, THIS_MODULE);
 
        sk->sk_destruct    = inet_sock_destruct;
-       sk->sk_zapped      = 0;
        sk->sk_family      = PF_INET;
        sk->sk_protocol    = protocol;
        sk->sk_backlog_rcv = sk->sk_prot->backlog_rcv;
@@ -422,13 +339,12 @@ static int inet_create(struct socket *sock, int protocol)
        if (sk->sk_prot->init) {
                err = sk->sk_prot->init(sk);
                if (err)
-                       inet_sock_release(sk);
+                       sk_common_release(sk);
        }
 out:
        return err;
-out_sk_free:
+out_rcu_unlock:
        rcu_read_unlock();
-       sk_free(sk);
        goto out;
 }
 
@@ -472,10 +388,14 @@ int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
 {
        struct sockaddr_in *addr = (struct sockaddr_in *)uaddr;
        struct sock *sk = sock->sk;
-       struct inet_opt *inet = inet_sk(sk);
+       struct inet_sock *inet = inet_sk(sk);
        unsigned short snum;
        int chk_addr_ret;
        int err;
+       __u32 s_addr;   /* Address used for validation */
+       __u32 s_addr1;  /* Address used for socket */
+       __u32 s_addr2;  /* Broadcast address for the socket */
+       struct nx_info *nxi = sk->sk_nx_info;
 
        /* If the socket has its own bind function then use it. (RAW) */
        if (sk->sk_prot->bind) {
@@ -486,7 +406,40 @@ int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
        if (addr_len < sizeof(struct sockaddr_in))
                goto out;
 
-       chk_addr_ret = inet_addr_type(addr->sin_addr.s_addr);
+       s_addr = addr->sin_addr.s_addr;
+       s_addr1 = s_addr;
+       s_addr2 = 0xffffffffl;
+
+       vxdprintk(VXD_CBIT(net, 3),
+               "inet_bind(%p)* %p,%p;%lx %d.%d.%d.%d",
+               sk, sk->sk_nx_info, sk->sk_socket,
+               (sk->sk_socket?sk->sk_socket->flags:0),
+               VXD_QUAD(s_addr));
+       if (nxi) {
+               __u32 v4_bcast = nxi->v4_bcast;
+               __u32 ipv4root = nxi->ipv4[0];
+               int nbipv4 = nxi->nbipv4;
+
+               if (s_addr == 0) {
+                       /* bind to any for 1-n */
+                       s_addr = ipv4root;
+                       s_addr1 = (nbipv4 > 1) ? 0 : s_addr;
+                       s_addr2 = v4_bcast;
+               } else if (s_addr == 0x0100007f) {
+                       /* rewrite localhost to ipv4root */
+                       s_addr = ipv4root;
+                       s_addr1 = ipv4root;
+               } else if (s_addr != v4_bcast) {
+                       /* normal address bind */
+                       if (!addr_in_nx_info(nxi, s_addr))
+                               return -EADDRNOTAVAIL;
+               }
+       }
+       chk_addr_ret = inet_addr_type(s_addr);
+
+       vxdprintk(VXD_CBIT(net, 3),
+               "inet_bind(%p) %d.%d.%d.%d, %d.%d.%d.%d, %d.%d.%d.%d",
+               sk, VXD_QUAD(s_addr), VXD_QUAD(s_addr1), VXD_QUAD(s_addr2));
 
        /* Not specified by any standard per-se, however it breaks too
         * many applications when removed.  It is unfortunate since
@@ -498,7 +451,7 @@ int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
        err = -EADDRNOTAVAIL;
        if (!sysctl_ip_nonlocal_bind &&
            !inet->freebind &&
-           addr->sin_addr.s_addr != INADDR_ANY &&
+           s_addr != INADDR_ANY &&
            chk_addr_ret != RTN_LOCAL &&
            chk_addr_ret != RTN_MULTICAST &&
            chk_addr_ret != RTN_BROADCAST)
@@ -523,7 +476,8 @@ int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
        if (sk->sk_state != TCP_CLOSE || inet->num)
                goto out_release_sock;
 
-       inet->rcv_saddr = inet->saddr = addr->sin_addr.s_addr;
+       inet->rcv_saddr = inet->saddr = s_addr1;
+       inet->rcv_saddr2 = s_addr2;
        if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST)
                inet->saddr = 0;  /* Use device */
 
@@ -706,7 +660,7 @@ int inet_getname(struct socket *sock, struct sockaddr *uaddr,
                        int *uaddr_len, int peer)
 {
        struct sock *sk         = sock->sk;
-       struct inet_opt *inet   = inet_sk(sk);
+       struct inet_sock *inet  = inet_sk(sk);
        struct sockaddr_in *sin = (struct sockaddr_in *)uaddr;
 
        sin->sin_family = AF_INET;
@@ -729,22 +683,6 @@ int inet_getname(struct socket *sock, struct sockaddr *uaddr,
        return 0;
 }
 
-
-int inet_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
-                size_t size, int flags)
-{
-       struct sock *sk = sock->sk;
-       int addr_len = 0;
-       int err;
-
-       err = sk->sk_prot->recvmsg(iocb, sk, msg, size, flags & MSG_DONTWAIT,
-                                  flags & ~MSG_DONTWAIT, &addr_len);
-       if (err >= 0)
-               msg->msg_namelen = addr_len;
-       return err;
-}
-
-
 int inet_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
                 size_t size)
 {
@@ -758,7 +696,7 @@ int inet_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
 }
 
 
-ssize_t inet_sendpage(struct socket *sock, struct page *page, int offset, size_t size, int flags)
+static ssize_t inet_sendpage(struct socket *sock, struct page *page, int offset, size_t size, int flags)
 {
        struct sock *sk = sock->sk;
 
@@ -843,17 +781,17 @@ int inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 
        switch (cmd) {
                case SIOCGSTAMP:
-                       err = sock_get_timestamp(sk, (struct timeval *)arg);
+                       err = sock_get_timestamp(sk, (struct timeval __user *)arg);
                        break;
                case SIOCADDRT:
                case SIOCDELRT:
                case SIOCRTMSG:
-                       err = ip_rt_ioctl(cmd, (void *)arg);
+                       err = ip_rt_ioctl(cmd, (void __user *)arg);
                        break;
                case SIOCDARP:
                case SIOCGARP:
                case SIOCSARP:
-                       err = arp_ioctl(cmd, (void *)arg);
+                       err = arp_ioctl(cmd, (void __user *)arg);
                        break;
                case SIOCGIFADDR:
                case SIOCSIFADDR:
@@ -866,13 +804,13 @@ int inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                case SIOCSIFPFLAGS:
                case SIOCGIFPFLAGS:
                case SIOCSIFFLAGS:
-                       err = devinet_ioctl(cmd, (void *)arg);
+                       err = devinet_ioctl(cmd, (void __user *)arg);
                        break;
                default:
                        if (!sk->sk_prot->ioctl ||
                            (err = sk->sk_prot->ioctl(sk, cmd, arg)) ==
                                                                -ENOIOCTLCMD)
-                               err = dev_ioctl(cmd, (void *)arg);
+                               err = dev_ioctl(cmd, (void __user *)arg);
                        break;
        }
        return err;
@@ -891,15 +829,40 @@ struct proto_ops inet_stream_ops = {
        .ioctl =        inet_ioctl,
        .listen =       inet_listen,
        .shutdown =     inet_shutdown,
-       .setsockopt =   inet_setsockopt,
-       .getsockopt =   inet_getsockopt,
+       .setsockopt =   sock_common_setsockopt,
+       .getsockopt =   sock_common_getsockopt,
        .sendmsg =      inet_sendmsg,
-       .recvmsg =      inet_recvmsg,
+       .recvmsg =      sock_common_recvmsg,
        .mmap =         sock_no_mmap,
        .sendpage =     tcp_sendpage
 };
 
 struct proto_ops inet_dgram_ops = {
+       .family =       PF_INET,
+       .owner =        THIS_MODULE,
+       .release =      inet_release,
+       .bind =         inet_bind,
+       .connect =      inet_dgram_connect,
+       .socketpair =   sock_no_socketpair,
+       .accept =       sock_no_accept,
+       .getname =      inet_getname,
+       .poll =         udp_poll,
+       .ioctl =        inet_ioctl,
+       .listen =       sock_no_listen,
+       .shutdown =     inet_shutdown,
+       .setsockopt =   sock_common_setsockopt,
+       .getsockopt =   sock_common_getsockopt,
+       .sendmsg =      inet_sendmsg,
+       .recvmsg =      sock_common_recvmsg,
+       .mmap =         sock_no_mmap,
+       .sendpage =     inet_sendpage,
+};
+
+/*
+ * For SOCK_RAW sockets; should be the same as inet_dgram_ops but without
+ * udp_poll
+ */
+static struct proto_ops inet_sockraw_ops = {
        .family =       PF_INET,
        .owner =        THIS_MODULE,
        .release =      inet_release,
@@ -912,15 +875,15 @@ struct proto_ops inet_dgram_ops = {
        .ioctl =        inet_ioctl,
        .listen =       sock_no_listen,
        .shutdown =     inet_shutdown,
-       .setsockopt =   inet_setsockopt,
-       .getsockopt =   inet_getsockopt,
+       .setsockopt =   sock_common_setsockopt,
+       .getsockopt =   sock_common_getsockopt,
        .sendmsg =      inet_sendmsg,
-       .recvmsg =      inet_recvmsg,
+       .recvmsg =      sock_common_recvmsg,
        .mmap =         sock_no_mmap,
        .sendpage =     inet_sendpage,
 };
 
-struct net_proto_family inet_family_ops = {
+static struct net_proto_family inet_family_ops = {
        .family = PF_INET,
        .create = inet_create,
        .owner  = THIS_MODULE,
@@ -960,7 +923,7 @@ static struct inet_protosw inetsw_array[] =
                .type =       SOCK_RAW,
                .protocol =   IPPROTO_IP,       /* wild card */
                .prot =       &raw_prot,
-               .ops =        &inet_dgram_ops,
+               .ops =        &inet_sockraw_ops,
                .capability = CAP_NET_RAW,
                .no_check =   UDP_CSUM_DEFAULT,
                .flags =      INET_PROTOSW_REUSE,
@@ -978,7 +941,7 @@ void inet_register_protosw(struct inet_protosw *p)
 
        spin_lock_bh(&inetsw_lock);
 
-       if (p->type > SOCK_MAX)
+       if (p->type >= SOCK_MAX)
                goto out_illegal;
 
        /* If we are trying to override a permanent protocol, bail. */
@@ -1041,24 +1004,24 @@ void inet_unregister_protosw(struct inet_protosw *p)
 }
 
 #ifdef CONFIG_IP_MULTICAST
-static struct inet_protocol igmp_protocol = {
+static struct net_protocol igmp_protocol = {
        .handler =      igmp_rcv,
 };
 #endif
 
-static struct inet_protocol tcp_protocol = {
+static struct net_protocol tcp_protocol = {
        .handler =      tcp_v4_rcv,
        .err_handler =  tcp_v4_err,
        .no_policy =    1,
 };
 
-static struct inet_protocol udp_protocol = {
+static struct net_protocol udp_protocol = {
        .handler =      udp_rcv,
        .err_handler =  udp_err,
        .no_policy =    1,
 };
 
-static struct inet_protocol icmp_protocol = {
+static struct net_protocol icmp_protocol = {
        .handler =      icmp_rcv,
 };
 
@@ -1066,8 +1029,8 @@ static int __init init_ipv4_mibs(void)
 {
        net_statistics[0] = alloc_percpu(struct linux_mib);
        net_statistics[1] = alloc_percpu(struct linux_mib);
-       ip_statistics[0] = alloc_percpu(struct ip_mib);
-       ip_statistics[1] = alloc_percpu(struct ip_mib);
+       ip_statistics[0] = alloc_percpu(struct ipstats_mib);
+       ip_statistics[1] = alloc_percpu(struct ipstats_mib);
        icmp_statistics[0] = alloc_percpu(struct icmp_mib);
        icmp_statistics[1] = alloc_percpu(struct icmp_mib);
        tcp_statistics[0] = alloc_percpu(struct tcp_mib);
@@ -1085,7 +1048,7 @@ static int __init init_ipv4_mibs(void)
        return 0;
 }
 
-int ipv4_proc_init(void);
+static int ipv4_proc_init(void);
 extern void ipfrag_init(void);
 
 static int __init inet_init(void)
@@ -1093,24 +1056,25 @@ static int __init inet_init(void)
        struct sk_buff *dummy_skb;
        struct inet_protosw *q;
        struct list_head *r;
+       int rc = -EINVAL;
 
        if (sizeof(struct inet_skb_parm) > sizeof(dummy_skb->cb)) {
                printk(KERN_CRIT "%s: panic\n", __FUNCTION__);
-               return -EINVAL;
+               goto out;
        }
 
-       tcp_sk_cachep = kmem_cache_create("tcp_sock",
-                                         sizeof(struct tcp_sock), 0,
-                                         SLAB_HWCACHE_ALIGN, 0, 0);
-       udp_sk_cachep = kmem_cache_create("udp_sock",
-                                         sizeof(struct udp_sock), 0,
-                                         SLAB_HWCACHE_ALIGN, 0, 0);
-       raw4_sk_cachep = kmem_cache_create("raw4_sock",
-                                          sizeof(struct raw_sock), 0,
-                                          SLAB_HWCACHE_ALIGN, 0, 0);
-       if (!tcp_sk_cachep || !udp_sk_cachep || !raw4_sk_cachep)
-               printk(KERN_CRIT
-                      "inet_init: Can't create protocol sock SLAB caches!\n");
+       rc = proto_register(&tcp_prot, 1);
+       if (rc)
+               goto out;
+
+       rc = proto_register(&udp_prot, 1);
+       if (rc)
+               goto out_unregister_tcp_proto;
+
+       rc = proto_register(&raw_prot, 1);
+       if (rc)
+               goto out_unregister_udp_proto;
+
        /*
         *      Tell SOCKET that we are alive... 
         */
@@ -1180,7 +1144,14 @@ static int __init inet_init(void)
 
        ipfrag_init();
 
-       return 0;
+       rc = 0;
+out:
+       return rc;
+out_unregister_tcp_proto:
+       proto_unregister(&tcp_prot);
+out_unregister_udp_proto:
+       proto_unregister(&udp_prot);
+       goto out;
 }
 
 module_init(inet_init);
@@ -1198,7 +1169,7 @@ extern void tcp4_proc_exit(void);
 extern int  udp4_proc_init(void);
 extern void udp4_proc_exit(void);
 
-int __init ipv4_proc_init(void)
+static int __init ipv4_proc_init(void)
 {
        int rc = 0;
 
@@ -1228,7 +1199,7 @@ out_raw:
 }
 
 #else /* CONFIG_PROC_FS */
-int __init ipv4_proc_init(void)
+static int __init ipv4_proc_init(void)
 {
        return 0;
 }
@@ -1240,25 +1211,19 @@ EXPORT_SYMBOL(inet_accept);
 EXPORT_SYMBOL(inet_bind);
 EXPORT_SYMBOL(inet_dgram_connect);
 EXPORT_SYMBOL(inet_dgram_ops);
-EXPORT_SYMBOL(inet_family_ops);
 EXPORT_SYMBOL(inet_getname);
-EXPORT_SYMBOL(inet_getsockopt);
 EXPORT_SYMBOL(inet_ioctl);
 EXPORT_SYMBOL(inet_listen);
-EXPORT_SYMBOL(inet_recvmsg);
 EXPORT_SYMBOL(inet_register_protosw);
 EXPORT_SYMBOL(inet_release);
 EXPORT_SYMBOL(inet_sendmsg);
-EXPORT_SYMBOL(inet_setsockopt);
 EXPORT_SYMBOL(inet_shutdown);
 EXPORT_SYMBOL(inet_sock_destruct);
-EXPORT_SYMBOL(inet_sock_release);
 EXPORT_SYMBOL(inet_stream_connect);
 EXPORT_SYMBOL(inet_stream_ops);
 EXPORT_SYMBOL(inet_unregister_protosw);
 EXPORT_SYMBOL(net_statistics);
-EXPORT_SYMBOL(tcp_protocol);
-EXPORT_SYMBOL(udp_protocol);
+EXPORT_SYMBOL(sysctl_ip_nonlocal_bind);
 
 #ifdef INET_REFCNT_DEBUG
 EXPORT_SYMBOL(inet_sock_nr);