[DCCP]: Introduce dccp_ipv4_af_ops
authorArnaldo Carvalho de Melo <acme@mandriva.com>
Wed, 14 Dec 2005 07:16:16 +0000 (23:16 -0800)
committerDavid S. Miller <davem@sunset.davemloft.net>
Tue, 3 Jan 2006 21:10:40 +0000 (13:10 -0800)
And make the core DCCP code AF agnostic, just like TCP, now its time
to work on net/dccp/ipv6.c, we are close to the end!

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/dccp/input.c
net/dccp/ipv4.c
net/dccp/minisocks.c
net/dccp/output.c
net/dccp/proto.c

index 3454d59..c81488f 100644 (file)
@@ -329,7 +329,7 @@ static int dccp_rcv_request_sent_state_process(struct sock *sk,
                dccp_set_state(sk, DCCP_PARTOPEN);
 
                /* Make sure socket is routed, for correct metrics. */
-               inet_sk_rebuild_header(sk);
+               icsk->icsk_af_ops->rebuild_header(sk);
 
                if (!sock_flag(sk, SOCK_DEAD)) {
                        sk->sk_state_change(sk);
@@ -444,7 +444,8 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
         */
        if (sk->sk_state == DCCP_LISTEN) {
                if (dh->dccph_type == DCCP_PKT_REQUEST) {
-                       if (dccp_v4_conn_request(sk, skb) < 0)
+                       if (inet_csk(sk)->icsk_af_ops->conn_request(sk,
+                                                                   skb) < 0)
                                return 1;
 
                        /* FIXME: do congestion control initialization */
index 1ac3e30..0ce7d0f 100644 (file)
@@ -607,6 +607,15 @@ out:
        sock_put(sk);
 }
 
+/* This routine computes an IPv4 DCCP checksum. */
+static void dccp_v4_send_check(struct sock *sk, int len, struct sk_buff *skb)
+{
+       const struct inet_sock *inet = inet_sk(sk);
+       struct dccp_hdr *dh = dccp_hdr(skb);
+
+       dh->dccph_checksum = dccp_v4_checksum(skb, inet->saddr, inet->daddr);
+}
+
 int dccp_v4_send_reset(struct sock *sk, enum dccp_reset_codes code)
 {
        struct sk_buff *skb;
@@ -1195,6 +1204,19 @@ do_time_wait:
        goto no_dccp_socket;
 }
 
+struct inet_connection_sock_af_ops dccp_ipv4_af_ops = {
+       .queue_xmit     = ip_queue_xmit,
+       .send_check     = dccp_v4_send_check,
+       .rebuild_header = inet_sk_rebuild_header,
+       .conn_request   = dccp_v4_conn_request,
+       .syn_recv_sock  = dccp_v4_request_recv_sock,
+       .net_header_len = sizeof(struct iphdr),
+       .setsockopt     = ip_setsockopt,
+       .getsockopt     = ip_getsockopt,
+       .addr2sockaddr  = inet_csk_addr2sockaddr,
+       .sockaddr_len   = sizeof(struct sockaddr_in),
+};
+
 static int dccp_v4_init_sock(struct sock *sk)
 {
        struct dccp_sock *dp = dccp_sk(sk);
@@ -1240,6 +1262,7 @@ static int dccp_v4_init_sock(struct sock *sk)
        inet_csk(sk)->icsk_rto = DCCP_TIMEOUT_INIT;
        sk->sk_state = DCCP_CLOSED;
        sk->sk_write_space = dccp_write_space;
+       inet_csk(sk)->icsk_af_ops = &dccp_ipv4_af_ops;
        dp->dccps_mss_cache = 536;
        dp->dccps_role = DCCP_ROLE_UNDEFINED;
        dp->dccps_service = DCCP_SERVICE_INVALID_VALUE;
index 1393461..c7ff80c 100644 (file)
@@ -214,7 +214,7 @@ struct sock *dccp_check_req(struct sock *sk, struct sk_buff *skb,
                goto drop;
        }
 
-       child = dccp_v4_request_recv_sock(sk, skb, req, NULL);
+       child = inet_csk(sk)->icsk_af_ops->syn_recv_sock(sk, skb, req, NULL);
        if (child == NULL)
                goto listen_overflow;
 
index 74ff870..f358805 100644 (file)
@@ -43,6 +43,7 @@ static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb)
 {
        if (likely(skb != NULL)) {
                const struct inet_sock *inet = inet_sk(sk);
+               const struct inet_connection_sock *icsk = inet_csk(sk);
                struct dccp_sock *dp = dccp_sk(sk);
                struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb);
                struct dccp_hdr *dh;
@@ -108,8 +109,7 @@ static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb)
                        break;
                }
 
-               dh->dccph_checksum = dccp_v4_checksum(skb, inet->saddr,
-                                                     inet->daddr);
+               icsk->icsk_af_ops->send_check(sk, skb->len, skb);
 
                if (set_ack)
                        dccp_event_ack_sent(sk);
@@ -117,7 +117,7 @@ static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb)
                DCCP_INC_STATS(DCCP_MIB_OUTSEGS);
 
                memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
-               err = ip_queue_xmit(skb, 0);
+               err = icsk->icsk_af_ops->queue_xmit(skb, 0);
                if (err <= 0)
                        return err;
 
@@ -135,16 +135,14 @@ static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb)
 unsigned int dccp_sync_mss(struct sock *sk, u32 pmtu)
 {
        struct dccp_sock *dp = dccp_sk(sk);
-       int mss_now;
-
        /*
         * FIXME: we really should be using the af_specific thing to support
         *        IPv6.
         * mss_now = pmtu - tp->af_specific->net_header_len -
         *           sizeof(struct dccp_hdr) - sizeof(struct dccp_hdr_ext);
         */
-       mss_now = pmtu - sizeof(struct iphdr) - sizeof(struct dccp_hdr) -
-                 sizeof(struct dccp_hdr_ext);
+       int mss_now = (pmtu - inet_csk(sk)->icsk_af_ops->net_header_len -
+                      sizeof(struct dccp_hdr) - sizeof(struct dccp_hdr_ext));
 
        /* Now subtract optional transport overhead */
        mss_now -= dp->dccps_ext_header_len;
@@ -266,7 +264,7 @@ int dccp_write_xmit(struct sock *sk, struct sk_buff *skb, long *timeo)
 
 int dccp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
 {
-       if (inet_sk_rebuild_header(sk) != 0)
+       if (inet_csk(sk)->icsk_af_ops->rebuild_header(sk) != 0)
                return -EHOSTUNREACH; /* Routing failure or similar. */
 
        return dccp_transmit_skb(sk, (skb_cloned(skb) ?
index 8a6b2a9..7b30c12 100644 (file)
@@ -254,7 +254,9 @@ int dccp_setsockopt(struct sock *sk, int level, int optname,
        int val;
 
        if (level != SOL_DCCP)
-               return ip_setsockopt(sk, level, optname, optval, optlen);
+               return inet_csk(sk)->icsk_af_ops->setsockopt(sk, level,
+                                                            optname, optval,
+                                                            optlen);
 
        if (optlen < sizeof(int))
                return -EINVAL;
@@ -320,8 +322,9 @@ int dccp_getsockopt(struct sock *sk, int level, int optname,
        int val, len;
 
        if (level != SOL_DCCP)
-               return ip_getsockopt(sk, level, optname, optval, optlen);
-
+               return inet_csk(sk)->icsk_af_ops->getsockopt(sk, level,
+                                                            optname, optval,
+                                                            optlen);
        if (get_user(len, optlen))
                return -EFAULT;