]> err.no Git - linux-2.6/blobdiff - net/dccp/output.c
Pull kvm-patches into release branch
[linux-2.6] / net / dccp / output.c
index b2e17910930dab5b5b0d8e327322551e75635f32..3d7d628d870d394d391af91b63a8a69c3adbf5c0 100644 (file)
@@ -126,22 +126,37 @@ 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 = icsk->icsk_af_ops->queue_xmit(skb, 0);
                return net_xmit_eval(err);
        }
        return -ENOBUFS;
 }
 
+/**
+ * dccp_determine_ccmps  -  Find out about CCID-specfic packet-size limits
+ * We only consider the HC-sender CCID for setting the CCMPS (RFC 4340, 14.),
+ * since the RX CCID is restricted to feedback packets (Acks), which are small
+ * in comparison with the data traffic. A value of 0 means "no current CCMPS".
+ */
+static u32 dccp_determine_ccmps(const struct dccp_sock *dp)
+{
+       const struct ccid *tx_ccid = dp->dccps_hc_tx_ccid;
+
+       if (tx_ccid == NULL || tx_ccid->ccid_ops == NULL)
+               return 0;
+       return tx_ccid->ccid_ops->ccid_ccmps;
+}
+
 unsigned int dccp_sync_mss(struct sock *sk, u32 pmtu)
 {
        struct inet_connection_sock *icsk = inet_csk(sk);
        struct dccp_sock *dp = dccp_sk(sk);
-       int mss_now = (pmtu - icsk->icsk_af_ops->net_header_len -
-                      sizeof(struct dccp_hdr) - sizeof(struct dccp_hdr_ext));
+       u32 ccmps = dccp_determine_ccmps(dp);
+       int cur_mps = ccmps ? min(pmtu, ccmps) : pmtu;
 
-       /* Now subtract optional transport overhead */
-       mss_now -= icsk->icsk_ext_hdr_len;
+       /* Account for header lengths and IPv4/v6 option overhead */
+       cur_mps -= (icsk->icsk_af_ops->net_header_len + icsk->icsk_ext_hdr_len +
+                   sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext));
 
        /*
         * FIXME: this should come from the CCID infrastructure, where, say,
@@ -151,13 +166,13 @@ unsigned int dccp_sync_mss(struct sock *sk, u32 pmtu)
         * make it a multiple of 4
         */
 
-       mss_now -= ((5 + 6 + 10 + 6 + 6 + 6 + 3) / 4) * 4;
+       cur_mps -= ((5 + 6 + 10 + 6 + 6 + 6 + 3) / 4) * 4;
 
        /* And store cached results */
        icsk->icsk_pmtu_cookie = pmtu;
-       dp->dccps_mss_cache = mss_now;
+       dp->dccps_mss_cache = cur_mps;
 
-       return mss_now;
+       return cur_mps;
 }
 
 EXPORT_SYMBOL_GPL(dccp_sync_mss);
@@ -303,7 +318,7 @@ struct sk_buff *dccp_make_response(struct sock *sk, struct dst_entry *dst,
        DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_RESPONSE;
        DCCP_SKB_CB(skb)->dccpd_seq  = dreq->dreq_iss;
 
-       if (dccp_insert_options(sk, skb)) {
+       if (dccp_insert_options_rsk(dreq, skb)) {
                kfree_skb(skb);
                return NULL;
        }