[DCCP] CCID: Improve CCID infrastructure

1. No need for ->ccid_init nor ->ccid_exit, this is what module_{init,exit}
   does and anynways neither ccid2 nor ccid3 were using it.

2. Rename struct ccid to struct ccid_operations and introduce struct ccid
   with a pointer to ccid_operations and rigth after it the rx or tx
   private state.

3. Remove the pointer to the state of the half connections from struct
   dccp_sock, now its derived thru ccid_priv() from the ccid pointer.

Now we also can implement the setsockopt for changing the CCID easily as
no ccid init routines can affect struct dccp_sock in any way that prevents
other CCIDs from working if a CCID switch operation is asked by apps.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c
index 3328d23..b40c456 100644
--- a/net/dccp/ccids/ccid2.c
+++ b/net/dccp/ccids/ccid2.c
@@ -52,16 +52,6 @@
 
 static const int ccid2_seq_len = 128;
 
-static inline struct ccid2_hc_tx_sock *ccid2_hc_tx_sk(const struct sock *sk)
-{
-	return dccp_sk(sk)->dccps_hc_tx_ccid_private;
-}
-
-static inline struct ccid2_hc_rx_sock *ccid2_hc_rx_sk(const struct sock *sk)
-{
-	return dccp_sk(sk)->dccps_hc_rx_ccid_private;
-}
-
 #ifdef CCID2_DEBUG
 static void ccid2_hc_tx_check_sanity(const struct ccid2_hc_tx_sock *hctx)
 {
@@ -707,19 +697,12 @@
 	ccid2_hc_tx_check_sanity(hctx);
 }
 
-static int ccid2_hc_tx_init(struct sock *sk)
+static int ccid2_hc_tx_init(struct ccid *ccid, struct sock *sk)
 {
-	struct dccp_sock *dp = dccp_sk(sk);
-        struct ccid2_hc_tx_sock *hctx;
+        struct ccid2_hc_tx_sock *hctx = ccid_priv(ccid);
 	int seqcount = ccid2_seq_len;
 	int i;
 
-        dp->dccps_hc_tx_ccid_private = kzalloc(sizeof(*hctx), gfp_any());
-        if (dp->dccps_hc_tx_ccid_private == NULL)
-                return -ENOMEM;
-
-        hctx = ccid2_hc_tx_sk(sk);
-
 	/* XXX init variables with proper values */
 	hctx->ccid2hctx_cwnd	  = 1;
 	hctx->ccid2hctx_ssthresh  = 10;
@@ -728,11 +711,9 @@
 	/* XXX init ~ to window size... */
 	hctx->ccid2hctx_seqbuf = kmalloc(sizeof(*hctx->ccid2hctx_seqbuf) *
 					 seqcount, gfp_any());
-	if (hctx->ccid2hctx_seqbuf == NULL) {
-		kfree(dp->dccps_hc_tx_ccid_private);
-		dp->dccps_hc_tx_ccid_private = NULL;
+	if (hctx->ccid2hctx_seqbuf == NULL)
 		return -ENOMEM;
-	}
+
 	for (i = 0; i < (seqcount - 1); i++) {
 		hctx->ccid2hctx_seqbuf[i].ccid2s_next =
 					&hctx->ccid2hctx_seqbuf[i + 1];
@@ -763,15 +744,11 @@
 
 static void ccid2_hc_tx_exit(struct sock *sk)
 {
-	struct dccp_sock *dp = dccp_sk(sk);
         struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk);
 
 	ccid2_hc_tx_kill_rto_timer(sk);
-
 	kfree(hctx->ccid2hctx_seqbuf);
-
-	kfree(dp->dccps_hc_tx_ccid_private);
-	dp->dccps_hc_tx_ccid_private = NULL;
+	hctx->ccid2hctx_seqbuf = NULL;
 }
 
 static void ccid2_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
@@ -791,33 +768,17 @@
 	}
 }
 
-static int ccid2_hc_rx_init(struct sock *sk)
-{
-	struct dccp_sock *dp = dccp_sk(sk);
-        dp->dccps_hc_rx_ccid_private = kzalloc(sizeof(struct ccid2_hc_rx_sock),
-					       gfp_any());
-        return dp->dccps_hc_rx_ccid_private == NULL ? -ENOMEM : 0;
-}
-
-static void ccid2_hc_rx_exit(struct sock *sk)
-{
-	struct dccp_sock *dp = dccp_sk(sk);
-
-	kfree(dp->dccps_hc_rx_ccid_private);
-	dp->dccps_hc_rx_ccid_private = NULL;
-}
-
-static struct ccid ccid2 = {
+static struct ccid_operations ccid2 = {
 	.ccid_id		= 2,
 	.ccid_name		= "ccid2",
 	.ccid_owner		= THIS_MODULE,
+	.ccid_hc_tx_obj_size	= sizeof(struct ccid2_hc_tx_sock),
 	.ccid_hc_tx_init	= ccid2_hc_tx_init,
 	.ccid_hc_tx_exit	= ccid2_hc_tx_exit,
 	.ccid_hc_tx_send_packet	= ccid2_hc_tx_send_packet,
 	.ccid_hc_tx_packet_sent	= ccid2_hc_tx_packet_sent,
 	.ccid_hc_tx_packet_recv	= ccid2_hc_tx_packet_recv,
-	.ccid_hc_rx_init	= ccid2_hc_rx_init,
-	.ccid_hc_rx_exit	= ccid2_hc_rx_exit,
+	.ccid_hc_rx_obj_size	= sizeof(struct ccid2_hc_rx_sock),
 	.ccid_hc_rx_packet_recv	= ccid2_hc_rx_packet_recv,
 };