aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/dccp/ccid.h2
-rw-r--r--net/dccp/output.c30
2 files changed, 25 insertions, 7 deletions
diff --git a/net/dccp/ccid.h b/net/dccp/ccid.h
index e3cdd8afc801..fdeae7b57319 100644
--- a/net/dccp/ccid.h
+++ b/net/dccp/ccid.h
@@ -27,6 +27,7 @@ struct tcp_info;
27 * struct ccid_operations - Interface to Congestion-Control Infrastructure 27 * struct ccid_operations - Interface to Congestion-Control Infrastructure
28 * 28 *
29 * @ccid_id: numerical CCID ID (up to %CCID_MAX, cf. table 5 in RFC 4340, 10.) 29 * @ccid_id: numerical CCID ID (up to %CCID_MAX, cf. table 5 in RFC 4340, 10.)
30 * @ccid_ccmps: the CCMPS including network/transport headers (0 when disabled)
30 * @ccid_name: alphabetical identifier string for @ccid_id 31 * @ccid_name: alphabetical identifier string for @ccid_id
31 * @ccid_owner: module which implements/owns this CCID 32 * @ccid_owner: module which implements/owns this CCID
32 * @ccid_hc_{r,t}x_slab: memory pool for the receiver/sender half-connection 33 * @ccid_hc_{r,t}x_slab: memory pool for the receiver/sender half-connection
@@ -45,6 +46,7 @@ struct tcp_info;
45 */ 46 */
46struct ccid_operations { 47struct ccid_operations {
47 unsigned char ccid_id; 48 unsigned char ccid_id;
49 __u32 ccid_ccmps;
48 const char *ccid_name; 50 const char *ccid_name;
49 struct module *ccid_owner; 51 struct module *ccid_owner;
50 struct kmem_cache *ccid_hc_rx_slab, 52 struct kmem_cache *ccid_hc_rx_slab,
diff --git a/net/dccp/output.c b/net/dccp/output.c
index 5589a5e581f4..3b763db3d863 100644
--- a/net/dccp/output.c
+++ b/net/dccp/output.c
@@ -133,15 +133,31 @@ static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb)
133 return -ENOBUFS; 133 return -ENOBUFS;
134} 134}
135 135
136/**
137 * dccp_determine_ccmps - Find out about CCID-specfic packet-size limits
138 * We only consider the HC-sender CCID for setting the CCMPS (RFC 4340, 14.),
139 * since the RX CCID is restricted to feedback packets (Acks), which are small
140 * in comparison with the data traffic. A value of 0 means "no current CCMPS".
141 */
142static u32 dccp_determine_ccmps(const struct dccp_sock *dp)
143{
144 const struct ccid *tx_ccid = dp->dccps_hc_tx_ccid;
145
146 if (tx_ccid == NULL || tx_ccid->ccid_ops == NULL)
147 return 0;
148 return tx_ccid->ccid_ops->ccid_ccmps;
149}
150
136unsigned int dccp_sync_mss(struct sock *sk, u32 pmtu) 151unsigned int dccp_sync_mss(struct sock *sk, u32 pmtu)
137{ 152{
138 struct inet_connection_sock *icsk = inet_csk(sk); 153 struct inet_connection_sock *icsk = inet_csk(sk);
139 struct dccp_sock *dp = dccp_sk(sk); 154 struct dccp_sock *dp = dccp_sk(sk);
140 int mss_now = (pmtu - icsk->icsk_af_ops->net_header_len - 155 u32 ccmps = dccp_determine_ccmps(dp);
141 sizeof(struct dccp_hdr) - sizeof(struct dccp_hdr_ext)); 156 int cur_mps = ccmps ? min(pmtu, ccmps) : pmtu;
142 157
143 /* Now subtract optional transport overhead */ 158 /* Account for header lengths and IPv4/v6 option overhead */
144 mss_now -= icsk->icsk_ext_hdr_len; 159 cur_mps -= (icsk->icsk_af_ops->net_header_len + icsk->icsk_ext_hdr_len +
160 sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext));
145 161
146 /* 162 /*
147 * FIXME: this should come from the CCID infrastructure, where, say, 163 * FIXME: this should come from the CCID infrastructure, where, say,
@@ -151,13 +167,13 @@ unsigned int dccp_sync_mss(struct sock *sk, u32 pmtu)
151 * make it a multiple of 4 167 * make it a multiple of 4
152 */ 168 */
153 169
154 mss_now -= ((5 + 6 + 10 + 6 + 6 + 6 + 3) / 4) * 4; 170 cur_mps -= ((5 + 6 + 10 + 6 + 6 + 6 + 3) / 4) * 4;
155 171
156 /* And store cached results */ 172 /* And store cached results */
157 icsk->icsk_pmtu_cookie = pmtu; 173 icsk->icsk_pmtu_cookie = pmtu;
158 dp->dccps_mss_cache = mss_now; 174 dp->dccps_mss_cache = cur_mps;
159 175
160 return mss_now; 176 return cur_mps;
161} 177}
162 178
163EXPORT_SYMBOL_GPL(dccp_sync_mss); 179EXPORT_SYMBOL_GPL(dccp_sync_mss);