]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - net/dccp/proto.c
Merge git://git.infradead.org/~dedekind/ubi-2.6
[linux-2.6-omap-h63xx.git] / net / dccp / proto.c
index 60f40ec72ff3c0507ac319dca5a45f31183fef88..9dfe2470962c7dd966f93243cdefb29b377f914e 100644 (file)
@@ -27,7 +27,6 @@
 #include <net/xfrm.h>
 
 #include <asm/ioctls.h>
-#include <asm/semaphore.h>
 #include <linux/spinlock.h>
 #include <linux/timer.h>
 #include <linux/delay.h>
@@ -78,7 +77,7 @@ void dccp_set_state(struct sock *sk, const int state)
                sk->sk_prot->unhash(sk);
                if (inet_csk(sk)->icsk_bind_hash != NULL &&
                    !(sk->sk_userlocks & SOCK_BINDPORT_LOCK))
-                       inet_put_port(&dccp_hashinfo, sk);
+                       inet_put_port(sk);
                /* fall through */
        default:
                if (oldstate == DCCP_OPEN)
@@ -173,20 +172,6 @@ const char *dccp_state_name(const int state)
 
 EXPORT_SYMBOL_GPL(dccp_state_name);
 
-void dccp_hash(struct sock *sk)
-{
-       inet_hash(&dccp_hashinfo, sk);
-}
-
-EXPORT_SYMBOL_GPL(dccp_hash);
-
-void dccp_unhash(struct sock *sk)
-{
-       inet_unhash(&dccp_hashinfo, sk);
-}
-
-EXPORT_SYMBOL_GPL(dccp_unhash);
-
 int dccp_init_sock(struct sock *sk, const __u8 ctl_sock_initialized)
 {
        struct dccp_sock *dp = dccp_sk(sk);
@@ -268,7 +253,7 @@ int dccp_destroy_sock(struct sock *sk)
 
        /* Clean up a referenced DCCP bind bucket. */
        if (inet_csk(sk)->icsk_bind_hash != NULL)
-               inet_put_port(&dccp_hashinfo, sk);
+               inet_put_port(sk);
 
        kfree(dp->dccps_service_list);
        dp->dccps_service_list = NULL;
@@ -551,6 +536,12 @@ static int do_dccp_setsockopt(struct sock *sk, int level, int optname,
                                                     (struct dccp_so_feat __user *)
                                                     optval);
                break;
+       case DCCP_SOCKOPT_SERVER_TIMEWAIT:
+               if (dp->dccps_role != DCCP_ROLE_SERVER)
+                       err = -EOPNOTSUPP;
+               else
+                       dp->dccps_server_timewait = (val != 0);
+               break;
        case DCCP_SOCKOPT_SEND_CSCOV:   /* sender side, RFC 4340, sec. 9.2 */
                if (val < 0 || val > 15)
                        err = -EINVAL;
@@ -651,15 +642,15 @@ static int do_dccp_getsockopt(struct sock *sk, int level, int optname,
                                               (__be32 __user *)optval, optlen);
        case DCCP_SOCKOPT_GET_CUR_MPS:
                val = dp->dccps_mss_cache;
-               len = sizeof(val);
+               break;
+       case DCCP_SOCKOPT_SERVER_TIMEWAIT:
+               val = dp->dccps_server_timewait;
                break;
        case DCCP_SOCKOPT_SEND_CSCOV:
                val = dp->dccps_pcslen;
-               len = sizeof(val);
                break;
        case DCCP_SOCKOPT_RECV_CSCOV:
                val = dp->dccps_pcrlen;
-               len = sizeof(val);
                break;
        case 128 ... 191:
                return ccid_hc_rx_getsockopt(dp->dccps_hc_rx_ccid, sk, optname,
@@ -671,6 +662,7 @@ static int do_dccp_getsockopt(struct sock *sk, int level, int optname,
                return -ENOPROTOOPT;
        }
 
+       len = sizeof(val);
        if (put_user(len, optlen) || copy_to_user(optval, &val, len))
                return -EFAULT;
 
@@ -918,7 +910,8 @@ static void dccp_terminate_connection(struct sock *sk)
        case DCCP_OPEN:
                dccp_send_close(sk, 1);
 
-               if (dccp_sk(sk)->dccps_role == DCCP_ROLE_SERVER)
+               if (dccp_sk(sk)->dccps_role == DCCP_ROLE_SERVER &&
+                   !dccp_sk(sk)->dccps_server_timewait)
                        next_state = DCCP_ACTIVE_CLOSEREQ;
                else
                        next_state = DCCP_CLOSING;
@@ -996,24 +989,6 @@ adjudge_to_death:
        if (state != DCCP_CLOSED && sk->sk_state == DCCP_CLOSED)
                goto out;
 
-       /*
-        * The last release_sock may have processed the CLOSE or RESET
-        * packet moving sock to CLOSED state, if not we have to fire
-        * the CLOSE/CLOSEREQ retransmission timer, see "8.3. Termination"
-        * in draft-ietf-dccp-spec-11. -acme
-        */
-       if (sk->sk_state == DCCP_CLOSING) {
-               /* FIXME: should start at 2 * RTT */
-               /* Timer for repeating the CLOSE/CLOSEREQ until an answer. */
-               inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
-                                         inet_csk(sk)->icsk_rto,
-                                         DCCP_RTO_MAX);
-#if 0
-               /* Yeah, we should use sk->sk_prot->orphan_count, etc */
-               dccp_set_state(sk, DCCP_CLOSED);
-#endif
-       }
-
        if (sk->sk_state == DCCP_CLOSED)
                inet_csk_destroy_sock(sk);
 
@@ -1034,33 +1009,14 @@ void dccp_shutdown(struct sock *sk, int how)
 
 EXPORT_SYMBOL_GPL(dccp_shutdown);
 
-static int __init dccp_mib_init(void)
+static inline int dccp_mib_init(void)
 {
-       int rc = -ENOMEM;
-
-       dccp_statistics[0] = alloc_percpu(struct dccp_mib);
-       if (dccp_statistics[0] == NULL)
-               goto out;
-
-       dccp_statistics[1] = alloc_percpu(struct dccp_mib);
-       if (dccp_statistics[1] == NULL)
-               goto out_free_one;
-
-       rc = 0;
-out:
-       return rc;
-out_free_one:
-       free_percpu(dccp_statistics[0]);
-       dccp_statistics[0] = NULL;
-       goto out;
-
+       return snmp_mib_init((void**)dccp_statistics, sizeof(struct dccp_mib));
 }
 
-static void dccp_mib_exit(void)
+static inline void dccp_mib_exit(void)
 {
-       free_percpu(dccp_statistics[0]);
-       free_percpu(dccp_statistics[1]);
-       dccp_statistics[0] = dccp_statistics[1] = NULL;
+       snmp_mib_free((void**)dccp_statistics);
 }
 
 static int thash_entries;
@@ -1081,6 +1037,9 @@ static int __init dccp_init(void)
        int ehash_order, bhash_order, i;
        int rc = -ENOBUFS;
 
+       BUILD_BUG_ON(sizeof(struct dccp_skb_cb) >
+                    FIELD_SIZEOF(struct sk_buff, cb));
+
        dccp_hashinfo.bind_bucket_cachep =
                kmem_cache_create("dccp_bind_bucket",
                                  sizeof(struct inet_bind_bucket), 0,