linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / net / dccp / output.c
index 58669be..efd7ffb 100644 (file)
@@ -10,6 +10,7 @@
  *     2 of the License, or (at your option) any later version.
  */
 
+#include <linux/config.h>
 #include <linux/dccp.h>
 #include <linux/kernel.h>
 #include <linux/skbuff.h>
@@ -26,7 +27,7 @@ static inline void dccp_event_ack_sent(struct sock *sk)
        inet_csk_clear_xmit_timer(sk, ICSK_TIME_DACK);
 }
 
-static void dccp_skb_entail(struct sock *sk, struct sk_buff *skb)
+static inline void dccp_skb_entail(struct sock *sk, struct sk_buff *skb)
 {
        skb_set_owner_w(skb, sk);
        WARN_ON(sk->sk_send_head);
@@ -48,7 +49,7 @@ static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb)
                struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb);
                struct dccp_hdr *dh;
                /* XXX For now we're using only 48 bits sequence numbers */
-               const u32 dccp_header_size = sizeof(*dh) +
+               const int dccp_header_size = sizeof(*dh) +
                                             sizeof(struct dccp_hdr_ext) +
                                          dccp_packet_hdr_len(dcb->dccpd_type);
                int err, set_ack = 1;
@@ -63,10 +64,6 @@ static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb)
                case DCCP_PKT_DATAACK:
                        break;
 
-               case DCCP_PKT_REQUEST:
-                       set_ack = 0;
-                       /* fall through */
-
                case DCCP_PKT_SYNC:
                case DCCP_PKT_SYNCACK:
                        ackno = dcb->dccpd_seq;
@@ -82,11 +79,7 @@ static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb)
                }
 
                dcb->dccpd_seq = dp->dccps_gss;
-
-               if (dccp_insert_options(sk, skb)) {
-                       kfree_skb(skb);
-                       return -EPROTO;
-               }
+               dccp_insert_options(sk, skb);
                
                skb->h.raw = skb_push(skb, dccp_header_size);
                dh = dccp_hdr(skb);
@@ -282,16 +275,17 @@ struct sk_buff *dccp_make_response(struct sock *sk, struct dst_entry *dst,
 {
        struct dccp_hdr *dh;
        struct dccp_request_sock *dreq;
-       const u32 dccp_header_size = sizeof(struct dccp_hdr) +
+       const int dccp_header_size = sizeof(struct dccp_hdr) +
                                     sizeof(struct dccp_hdr_ext) +
                                     sizeof(struct dccp_hdr_response);
-       struct sk_buff *skb = sock_wmalloc(sk, sk->sk_prot->max_header, 1,
+       struct sk_buff *skb = sock_wmalloc(sk, MAX_HEADER + DCCP_MAX_OPT_LEN +
+                                              dccp_header_size, 1,
                                           GFP_ATOMIC);
        if (skb == NULL)
                return NULL;
 
        /* Reserve space for headers. */
-       skb_reserve(skb, sk->sk_prot->max_header);
+       skb_reserve(skb, MAX_HEADER + DCCP_MAX_OPT_LEN + dccp_header_size);
 
        skb->dst = dst_clone(dst);
        skb->csum = 0;
@@ -299,11 +293,7 @@ struct sk_buff *dccp_make_response(struct sock *sk, struct dst_entry *dst,
        dreq = dccp_rsk(req);
        DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_RESPONSE;
        DCCP_SKB_CB(skb)->dccpd_seq  = dreq->dreq_iss;
-
-       if (dccp_insert_options(sk, skb)) {
-               kfree_skb(skb);
-               return NULL;
-       }
+       dccp_insert_options(sk, skb);
 
        skb->h.raw = skb_push(skb, dccp_header_size);
 
@@ -320,28 +310,32 @@ struct sk_buff *dccp_make_response(struct sock *sk, struct dst_entry *dst,
        dccp_hdr_set_ack(dccp_hdr_ack_bits(skb), dreq->dreq_isr);
        dccp_hdr_response(skb)->dccph_resp_service = dreq->dreq_service;
 
+       dh->dccph_checksum = dccp_v4_checksum(skb, inet_rsk(req)->loc_addr,
+                                             inet_rsk(req)->rmt_addr);
+
        DCCP_INC_STATS(DCCP_MIB_OUTSEGS);
        return skb;
 }
 
 EXPORT_SYMBOL_GPL(dccp_make_response);
 
-static struct sk_buff *dccp_make_reset(struct sock *sk, struct dst_entry *dst,
-                                      const enum dccp_reset_codes code)
+struct sk_buff *dccp_make_reset(struct sock *sk, struct dst_entry *dst,
+                               const enum dccp_reset_codes code)
                                   
 {
        struct dccp_hdr *dh;
        struct dccp_sock *dp = dccp_sk(sk);
-       const u32 dccp_header_size = sizeof(struct dccp_hdr) +
+       const int dccp_header_size = sizeof(struct dccp_hdr) +
                                     sizeof(struct dccp_hdr_ext) +
                                     sizeof(struct dccp_hdr_reset);
-       struct sk_buff *skb = sock_wmalloc(sk, sk->sk_prot->max_header, 1,
+       struct sk_buff *skb = sock_wmalloc(sk, MAX_HEADER + DCCP_MAX_OPT_LEN +
+                                              dccp_header_size, 1,
                                           GFP_ATOMIC);
        if (skb == NULL)
                return NULL;
 
        /* Reserve space for headers. */
-       skb_reserve(skb, sk->sk_prot->max_header);
+       skb_reserve(skb, MAX_HEADER + DCCP_MAX_OPT_LEN + dccp_header_size);
 
        skb->dst = dst_clone(dst);
        skb->csum = 0;
@@ -351,11 +345,7 @@ static struct sk_buff *dccp_make_reset(struct sock *sk, struct dst_entry *dst,
        DCCP_SKB_CB(skb)->dccpd_reset_code = code;
        DCCP_SKB_CB(skb)->dccpd_type       = DCCP_PKT_RESET;
        DCCP_SKB_CB(skb)->dccpd_seq        = dp->dccps_gss;
-
-       if (dccp_insert_options(sk, skb)) {
-               kfree_skb(skb);
-               return NULL;
-       }
+       dccp_insert_options(sk, skb);
 
        skb->h.raw = skb_push(skb, dccp_header_size);
 
@@ -372,34 +362,14 @@ static struct sk_buff *dccp_make_reset(struct sock *sk, struct dst_entry *dst,
        dccp_hdr_set_ack(dccp_hdr_ack_bits(skb), dp->dccps_gsr);
 
        dccp_hdr_reset(skb)->dccph_reset_code = code;
-       inet_csk(sk)->icsk_af_ops->send_check(sk, skb->len, skb);
+
+       dh->dccph_checksum = dccp_v4_checksum(skb, inet_sk(sk)->saddr,
+                                             inet_sk(sk)->daddr);
 
        DCCP_INC_STATS(DCCP_MIB_OUTSEGS);
        return skb;
 }
 
-int dccp_send_reset(struct sock *sk, enum dccp_reset_codes code)
-{
-       /*
-        * FIXME: what if rebuild_header fails?
-        * Should we be doing a rebuild_header here?
-        */
-       int err = inet_sk_rebuild_header(sk);
-
-       if (err == 0) {
-               struct sk_buff *skb = dccp_make_reset(sk, sk->sk_dst_cache,
-                                                     code);
-               if (skb != NULL) {
-                       memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
-                       err = inet_csk(sk)->icsk_af_ops->queue_xmit(skb, 0);
-                       if (err == NET_XMIT_CN)
-                               err = 0;
-               }
-       }
-
-       return err;
-}
-
 /*
  * Do all connect socket setups that can be done AF independent.
  */
@@ -435,12 +405,12 @@ int dccp_connect(struct sock *sk)
 
        dccp_connect_init(sk);
 
-       skb = alloc_skb(sk->sk_prot->max_header, sk->sk_allocation);
+       skb = alloc_skb(MAX_DCCP_HEADER + 15, sk->sk_allocation);
        if (unlikely(skb == NULL))
                return -ENOBUFS;
 
        /* Reserve space for headers. */
-       skb_reserve(skb, sk->sk_prot->max_header);
+       skb_reserve(skb, MAX_DCCP_HEADER);
 
        DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_REQUEST;
        skb->csum = 0;
@@ -461,8 +431,7 @@ void dccp_send_ack(struct sock *sk)
 {
        /* If we have been reset, we may not send again. */
        if (sk->sk_state != DCCP_CLOSED) {
-               struct sk_buff *skb = alloc_skb(sk->sk_prot->max_header,
-                                               GFP_ATOMIC);
+               struct sk_buff *skb = alloc_skb(MAX_DCCP_HEADER, GFP_ATOMIC);
 
                if (skb == NULL) {
                        inet_csk_schedule_ack(sk);
@@ -474,7 +443,7 @@ void dccp_send_ack(struct sock *sk)
                }
 
                /* Reserve space for headers */
-               skb_reserve(skb, sk->sk_prot->max_header);
+               skb_reserve(skb, MAX_DCCP_HEADER);
                skb->csum = 0;
                DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_ACK;
                dccp_transmit_skb(sk, skb);
@@ -521,14 +490,14 @@ void dccp_send_sync(struct sock *sk, const u64 seq,
         * dccp_transmit_skb() will set the ownership to this
         * sock.
         */
-       struct sk_buff *skb = alloc_skb(sk->sk_prot->max_header, GFP_ATOMIC);
+       struct sk_buff *skb = alloc_skb(MAX_DCCP_HEADER, GFP_ATOMIC);
 
        if (skb == NULL)
                /* FIXME: how to make sure the sync is sent? */
                return;
 
        /* Reserve space for headers and prepare control bits. */
-       skb_reserve(skb, sk->sk_prot->max_header);
+       skb_reserve(skb, MAX_DCCP_HEADER);
        skb->csum = 0;
        DCCP_SKB_CB(skb)->dccpd_type = pkt_type;
        DCCP_SKB_CB(skb)->dccpd_seq = seq;
@@ -536,8 +505,6 @@ void dccp_send_sync(struct sock *sk, const u64 seq,
        dccp_transmit_skb(sk, skb);
 }
 
-EXPORT_SYMBOL_GPL(dccp_send_sync);
-
 /*
  * Send a DCCP_PKT_CLOSE/CLOSEREQ. The caller locks the socket for us. This
  * cannot be allowed to fail queueing a DCCP_PKT_CLOSE/CLOSEREQ frame under