diff options
Diffstat (limited to 'net/dccp/output.c')
-rw-r--r-- | net/dccp/output.c | 47 |
1 files changed, 27 insertions, 20 deletions
diff --git a/net/dccp/output.c b/net/dccp/output.c index 74ff87025878..efd7ffb903a1 100644 --- a/net/dccp/output.c +++ b/net/dccp/output.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
16 | #include <linux/skbuff.h> | 16 | #include <linux/skbuff.h> |
17 | 17 | ||
18 | #include <net/inet_sock.h> | ||
18 | #include <net/sock.h> | 19 | #include <net/sock.h> |
19 | 20 | ||
20 | #include "ackvec.h" | 21 | #include "ackvec.h" |
@@ -43,6 +44,7 @@ static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb) | |||
43 | { | 44 | { |
44 | if (likely(skb != NULL)) { | 45 | if (likely(skb != NULL)) { |
45 | const struct inet_sock *inet = inet_sk(sk); | 46 | const struct inet_sock *inet = inet_sk(sk); |
47 | const struct inet_connection_sock *icsk = inet_csk(sk); | ||
46 | struct dccp_sock *dp = dccp_sk(sk); | 48 | struct dccp_sock *dp = dccp_sk(sk); |
47 | struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb); | 49 | struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb); |
48 | struct dccp_hdr *dh; | 50 | struct dccp_hdr *dh; |
@@ -108,8 +110,7 @@ static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb) | |||
108 | break; | 110 | break; |
109 | } | 111 | } |
110 | 112 | ||
111 | dh->dccph_checksum = dccp_v4_checksum(skb, inet->saddr, | 113 | icsk->icsk_af_ops->send_check(sk, skb->len, skb); |
112 | inet->daddr); | ||
113 | 114 | ||
114 | if (set_ack) | 115 | if (set_ack) |
115 | dccp_event_ack_sent(sk); | 116 | dccp_event_ack_sent(sk); |
@@ -117,7 +118,7 @@ static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb) | |||
117 | DCCP_INC_STATS(DCCP_MIB_OUTSEGS); | 118 | DCCP_INC_STATS(DCCP_MIB_OUTSEGS); |
118 | 119 | ||
119 | memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); | 120 | memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); |
120 | err = ip_queue_xmit(skb, 0); | 121 | err = icsk->icsk_af_ops->queue_xmit(skb, 0); |
121 | if (err <= 0) | 122 | if (err <= 0) |
122 | return err; | 123 | return err; |
123 | 124 | ||
@@ -134,20 +135,13 @@ static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb) | |||
134 | 135 | ||
135 | unsigned int dccp_sync_mss(struct sock *sk, u32 pmtu) | 136 | unsigned int dccp_sync_mss(struct sock *sk, u32 pmtu) |
136 | { | 137 | { |
138 | struct inet_connection_sock *icsk = inet_csk(sk); | ||
137 | struct dccp_sock *dp = dccp_sk(sk); | 139 | struct dccp_sock *dp = dccp_sk(sk); |
138 | int mss_now; | 140 | int mss_now = (pmtu - icsk->icsk_af_ops->net_header_len - |
139 | 141 | sizeof(struct dccp_hdr) - sizeof(struct dccp_hdr_ext)); | |
140 | /* | ||
141 | * FIXME: we really should be using the af_specific thing to support | ||
142 | * IPv6. | ||
143 | * mss_now = pmtu - tp->af_specific->net_header_len - | ||
144 | * sizeof(struct dccp_hdr) - sizeof(struct dccp_hdr_ext); | ||
145 | */ | ||
146 | mss_now = pmtu - sizeof(struct iphdr) - sizeof(struct dccp_hdr) - | ||
147 | sizeof(struct dccp_hdr_ext); | ||
148 | 142 | ||
149 | /* Now subtract optional transport overhead */ | 143 | /* Now subtract optional transport overhead */ |
150 | mss_now -= dp->dccps_ext_header_len; | 144 | mss_now -= icsk->icsk_ext_hdr_len; |
151 | 145 | ||
152 | /* | 146 | /* |
153 | * FIXME: this should come from the CCID infrastructure, where, say, | 147 | * FIXME: this should come from the CCID infrastructure, where, say, |
@@ -160,12 +154,14 @@ unsigned int dccp_sync_mss(struct sock *sk, u32 pmtu) | |||
160 | mss_now -= ((5 + 6 + 10 + 6 + 6 + 6 + 3) / 4) * 4; | 154 | mss_now -= ((5 + 6 + 10 + 6 + 6 + 6 + 3) / 4) * 4; |
161 | 155 | ||
162 | /* And store cached results */ | 156 | /* And store cached results */ |
163 | dp->dccps_pmtu_cookie = pmtu; | 157 | icsk->icsk_pmtu_cookie = pmtu; |
164 | dp->dccps_mss_cache = mss_now; | 158 | dp->dccps_mss_cache = mss_now; |
165 | 159 | ||
166 | return mss_now; | 160 | return mss_now; |
167 | } | 161 | } |
168 | 162 | ||
163 | EXPORT_SYMBOL_GPL(dccp_sync_mss); | ||
164 | |||
169 | void dccp_write_space(struct sock *sk) | 165 | void dccp_write_space(struct sock *sk) |
170 | { | 166 | { |
171 | read_lock(&sk->sk_callback_lock); | 167 | read_lock(&sk->sk_callback_lock); |
@@ -266,7 +262,7 @@ int dccp_write_xmit(struct sock *sk, struct sk_buff *skb, long *timeo) | |||
266 | 262 | ||
267 | int dccp_retransmit_skb(struct sock *sk, struct sk_buff *skb) | 263 | int dccp_retransmit_skb(struct sock *sk, struct sk_buff *skb) |
268 | { | 264 | { |
269 | if (inet_sk_rebuild_header(sk) != 0) | 265 | if (inet_csk(sk)->icsk_af_ops->rebuild_header(sk) != 0) |
270 | return -EHOSTUNREACH; /* Routing failure or similar. */ | 266 | return -EHOSTUNREACH; /* Routing failure or similar. */ |
271 | 267 | ||
272 | return dccp_transmit_skb(sk, (skb_cloned(skb) ? | 268 | return dccp_transmit_skb(sk, (skb_cloned(skb) ? |
@@ -321,6 +317,8 @@ struct sk_buff *dccp_make_response(struct sock *sk, struct dst_entry *dst, | |||
321 | return skb; | 317 | return skb; |
322 | } | 318 | } |
323 | 319 | ||
320 | EXPORT_SYMBOL_GPL(dccp_make_response); | ||
321 | |||
324 | struct sk_buff *dccp_make_reset(struct sock *sk, struct dst_entry *dst, | 322 | struct sk_buff *dccp_make_reset(struct sock *sk, struct dst_entry *dst, |
325 | const enum dccp_reset_codes code) | 323 | const enum dccp_reset_codes code) |
326 | 324 | ||
@@ -377,6 +375,7 @@ struct sk_buff *dccp_make_reset(struct sock *sk, struct dst_entry *dst, | |||
377 | */ | 375 | */ |
378 | static inline void dccp_connect_init(struct sock *sk) | 376 | static inline void dccp_connect_init(struct sock *sk) |
379 | { | 377 | { |
378 | struct dccp_sock *dp = dccp_sk(sk); | ||
380 | struct dst_entry *dst = __sk_dst_get(sk); | 379 | struct dst_entry *dst = __sk_dst_get(sk); |
381 | struct inet_connection_sock *icsk = inet_csk(sk); | 380 | struct inet_connection_sock *icsk = inet_csk(sk); |
382 | 381 | ||
@@ -385,10 +384,16 @@ static inline void dccp_connect_init(struct sock *sk) | |||
385 | 384 | ||
386 | dccp_sync_mss(sk, dst_mtu(dst)); | 385 | dccp_sync_mss(sk, dst_mtu(dst)); |
387 | 386 | ||
388 | /* | 387 | dccp_update_gss(sk, dp->dccps_iss); |
389 | * FIXME: set dp->{dccps_swh,dccps_swl}, with | 388 | /* |
390 | * something like dccp_inc_seq | 389 | * SWL and AWL are initially adjusted so that they are not less than |
391 | */ | 390 | * the initial Sequence Numbers received and sent, respectively: |
391 | * SWL := max(GSR + 1 - floor(W/4), ISR), | ||
392 | * AWL := max(GSS - W' + 1, ISS). | ||
393 | * These adjustments MUST be applied only at the beginning of the | ||
394 | * connection. | ||
395 | */ | ||
396 | dccp_set_seqno(&dp->dccps_awl, max48(dp->dccps_awl, dp->dccps_iss)); | ||
392 | 397 | ||
393 | icsk->icsk_retransmits = 0; | 398 | icsk->icsk_retransmits = 0; |
394 | } | 399 | } |
@@ -420,6 +425,8 @@ int dccp_connect(struct sock *sk) | |||
420 | return 0; | 425 | return 0; |
421 | } | 426 | } |
422 | 427 | ||
428 | EXPORT_SYMBOL_GPL(dccp_connect); | ||
429 | |||
423 | void dccp_send_ack(struct sock *sk) | 430 | void dccp_send_ack(struct sock *sk) |
424 | { | 431 | { |
425 | /* If we have been reset, we may not send again. */ | 432 | /* If we have been reset, we may not send again. */ |