]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - net/dccp/output.c
Merge branch 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[mv-sheeva.git] / net / dccp / output.c
index 45b91853f5aee3d452d5795da832b9e1f04651ed..784d302105439434ef7182e9a4f7b7d167a44baa 100644 (file)
@@ -242,7 +242,7 @@ static void dccp_xmit_packet(struct sock *sk)
 {
        int err, len;
        struct dccp_sock *dp = dccp_sk(sk);
-       struct sk_buff *skb = skb_dequeue(&sk->sk_write_queue);
+       struct sk_buff *skb = dccp_qpolicy_pop(sk);
 
        if (unlikely(skb == NULL))
                return;
@@ -283,6 +283,15 @@ static void dccp_xmit_packet(struct sock *sk)
         * any local drop will eventually be reported via receiver feedback.
         */
        ccid_hc_tx_packet_sent(dp->dccps_hc_tx_ccid, sk, len);
+
+       /*
+        * If the CCID needs to transfer additional header options out-of-band
+        * (e.g. Ack Vectors or feature-negotiation options), it activates this
+        * flag to schedule a Sync. The Sync will automatically incorporate all
+        * currently pending header options, thus clearing the backlog.
+        */
+       if (dp->dccps_sync_scheduled)
+               dccp_send_sync(sk, dp->dccps_gsr, DCCP_PKT_SYNC);
 }
 
 /**
@@ -336,7 +345,7 @@ void dccp_write_xmit(struct sock *sk)
        struct dccp_sock *dp = dccp_sk(sk);
        struct sk_buff *skb;
 
-       while ((skb = skb_peek(&sk->sk_write_queue))) {
+       while ((skb = dccp_qpolicy_top(sk))) {
                int rc = ccid_hc_tx_send_packet(dp->dccps_hc_tx_ccid, sk, skb);
 
                switch (ccid_packet_dequeue_eval(rc)) {
@@ -350,8 +359,7 @@ void dccp_write_xmit(struct sock *sk)
                        dccp_xmit_packet(sk);
                        break;
                case CCID_PACKET_ERR:
-                       skb_dequeue(&sk->sk_write_queue);
-                       kfree_skb(skb);
+                       dccp_qpolicy_drop(sk, skb);
                        dccp_pr_debug("packet discarded due to err=%d\n", rc);
                }
        }
@@ -636,6 +644,12 @@ void dccp_send_sync(struct sock *sk, const u64 ackno,
        DCCP_SKB_CB(skb)->dccpd_type = pkt_type;
        DCCP_SKB_CB(skb)->dccpd_ack_seq = ackno;
 
+       /*
+        * Clear the flag in case the Sync was scheduled for out-of-band data,
+        * such as carrying a long Ack Vector.
+        */
+       dccp_sk(sk)->dccps_sync_scheduled = 0;
+
        dccp_transmit_skb(sk, skb);
 }