[DCCP]: Remove duplicate code for Reset from connected socket
authorGerrit Renker <gerrit@erg.abdn.ac.uk>
Wed, 26 Sep 2007 14:30:02 +0000 (11:30 -0300)
committerDavid S. Miller <davem@sunset.davemloft.net>
Wed, 10 Oct 2007 23:52:42 +0000 (16:52 -0700)
In this patch, duplicated code is removed for the case when a Reset packet is
sent from a connected socket. This code duplication is between dccp_make_reset
and dccp_transmit_skb, which already contained an (up to now entirely unused)
switch statement to fill in the reset code from the DCCP_SKB_CB.

The only thing that has been removed is the call to dst_clone(dst), since
the queue_xmit functions use sk_dst_cache anyway.

I wasn't sure which purpose inet_sk_rebuild_header served, so I left it in.

Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
net/dccp/output.c

index d0c9ec6..f4bde20 100644 (file)
@@ -61,6 +61,7 @@ static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb)
                        set_ack = 0;
                        /* fall through */
                case DCCP_PKT_DATAACK:
+               case DCCP_PKT_RESET:
                        break;
 
                case DCCP_PKT_REQUEST:
@@ -73,8 +74,10 @@ static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb)
                        /* fall through */
                default:
                        /*
-                        * Only data packets should come through with skb->sk
-                        * set.
+                        * Set owner/destructor: some skbs are allocated via
+                        * alloc_skb (e.g. when retransmission may happen).
+                        * Only Data, DataAck, and Reset packets should come
+                        * through here with skb->sk set.
                         */
                        WARN_ON(skb->sk);
                        skb_set_owner_w(skb, sk);
@@ -324,72 +327,29 @@ struct sk_buff *dccp_make_response(struct sock *sk, struct dst_entry *dst,
 
 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 dccp_hdr *dh;
-       struct dccp_sock *dp = dccp_sk(sk);
-       const u32 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,
-                                          GFP_ATOMIC);
-       if (skb == NULL)
-               return NULL;
-
-       /* Reserve space for headers. */
-       skb_reserve(skb, sk->sk_prot->max_header);
-
-       skb->dst = dst_clone(dst);
-
-       dccp_inc_seqno(&dp->dccps_gss);
-
-       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;
-       }
-
-       dh = dccp_zeroed_hdr(skb, dccp_header_size);
-
-       dh->dccph_sport = inet_sk(sk)->sport;
-       dh->dccph_dport = inet_sk(sk)->dport;
-       dh->dccph_doff  = (dccp_header_size +
-                          DCCP_SKB_CB(skb)->dccpd_opt_len) / 4;
-       dh->dccph_type  = DCCP_PKT_RESET;
-       dh->dccph_x     = 1;
-       dccp_hdr_set_seq(dh, dp->dccps_gss);
-       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, 0, skb);
-
-       DCCP_INC_STATS(DCCP_MIB_OUTSEGS);
-       return skb;
-}
-
+/* send Reset on established socket, to close or abort the connection */
 int dccp_send_reset(struct sock *sk, enum dccp_reset_codes code)
 {
+       struct sk_buff *skb;
        /*
         * 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);
-                       return net_xmit_eval(err);
-               }
-       }
+       if (err != 0)
+               return err;
+
+       skb = sock_wmalloc(sk, sk->sk_prot->max_header, 1, GFP_ATOMIC);
+       if (skb == NULL)
+               return -ENOBUFS;
+
+       /* Reserve space for headers and prepare control bits. */
+       skb_reserve(skb, sk->sk_prot->max_header);
+       DCCP_SKB_CB(skb)->dccpd_type       = DCCP_PKT_RESET;
+       DCCP_SKB_CB(skb)->dccpd_reset_code = code;
 
-       return err;
+       return dccp_transmit_skb(sk, skb);
 }
 
 /*