diff options
Diffstat (limited to 'net/dccp')
-rw-r--r-- | net/dccp/ccid.c | 4 | ||||
-rw-r--r-- | net/dccp/ccids/ccid2.c | 109 | ||||
-rw-r--r-- | net/dccp/ccids/ccid2.h | 25 | ||||
-rw-r--r-- | net/dccp/input.c | 61 | ||||
-rw-r--r-- | net/dccp/ipv4.c | 1 | ||||
-rw-r--r-- | net/dccp/ipv6.c | 9 | ||||
-rw-r--r-- | net/dccp/output.c | 14 |
7 files changed, 153 insertions, 70 deletions
diff --git a/net/dccp/ccid.c b/net/dccp/ccid.c index 36479ca61e0..48b585a5cba 100644 --- a/net/dccp/ccid.c +++ b/net/dccp/ccid.c | |||
@@ -118,7 +118,7 @@ static int ccid_activate(struct ccid_operations *ccid_ops) | |||
118 | if (ccid_ops->ccid_hc_tx_slab == NULL) | 118 | if (ccid_ops->ccid_hc_tx_slab == NULL) |
119 | goto out_free_rx_slab; | 119 | goto out_free_rx_slab; |
120 | 120 | ||
121 | pr_info("CCID: Activated CCID %d (%s)\n", | 121 | pr_info("DCCP: Activated CCID %d (%s)\n", |
122 | ccid_ops->ccid_id, ccid_ops->ccid_name); | 122 | ccid_ops->ccid_id, ccid_ops->ccid_name); |
123 | err = 0; | 123 | err = 0; |
124 | out: | 124 | out: |
@@ -136,7 +136,7 @@ static void ccid_deactivate(struct ccid_operations *ccid_ops) | |||
136 | ccid_kmem_cache_destroy(ccid_ops->ccid_hc_rx_slab); | 136 | ccid_kmem_cache_destroy(ccid_ops->ccid_hc_rx_slab); |
137 | ccid_ops->ccid_hc_rx_slab = NULL; | 137 | ccid_ops->ccid_hc_rx_slab = NULL; |
138 | 138 | ||
139 | pr_info("CCID: Deactivated CCID %d (%s)\n", | 139 | pr_info("DCCP: Deactivated CCID %d (%s)\n", |
140 | ccid_ops->ccid_id, ccid_ops->ccid_name); | 140 | ccid_ops->ccid_id, ccid_ops->ccid_name); |
141 | } | 141 | } |
142 | 142 | ||
diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c index fadecd20d75..0462040fc81 100644 --- a/net/dccp/ccids/ccid2.c +++ b/net/dccp/ccids/ccid2.c | |||
@@ -153,17 +153,93 @@ out: | |||
153 | sock_put(sk); | 153 | sock_put(sk); |
154 | } | 154 | } |
155 | 155 | ||
156 | /* | ||
157 | * Congestion window validation (RFC 2861). | ||
158 | */ | ||
159 | static int ccid2_do_cwv = 1; | ||
160 | module_param(ccid2_do_cwv, bool, 0644); | ||
161 | MODULE_PARM_DESC(ccid2_do_cwv, "Perform RFC2861 Congestion Window Validation"); | ||
162 | |||
163 | /** | ||
164 | * ccid2_update_used_window - Track how much of cwnd is actually used | ||
165 | * This is done in addition to CWV. The sender needs to have an idea of how many | ||
166 | * packets may be in flight, to set the local Sequence Window value accordingly | ||
167 | * (RFC 4340, 7.5.2). The CWV mechanism is exploited to keep track of the | ||
168 | * maximum-used window. We use an EWMA low-pass filter to filter out noise. | ||
169 | */ | ||
170 | static void ccid2_update_used_window(struct ccid2_hc_tx_sock *hc, u32 new_wnd) | ||
171 | { | ||
172 | hc->tx_expected_wnd = (3 * hc->tx_expected_wnd + new_wnd) / 4; | ||
173 | } | ||
174 | |||
175 | /* This borrows the code of tcp_cwnd_application_limited() */ | ||
176 | static void ccid2_cwnd_application_limited(struct sock *sk, const u32 now) | ||
177 | { | ||
178 | struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk); | ||
179 | /* don't reduce cwnd below the initial window (IW) */ | ||
180 | u32 init_win = rfc3390_bytes_to_packets(dccp_sk(sk)->dccps_mss_cache), | ||
181 | win_used = max(hc->tx_cwnd_used, init_win); | ||
182 | |||
183 | if (win_used < hc->tx_cwnd) { | ||
184 | hc->tx_ssthresh = max(hc->tx_ssthresh, | ||
185 | (hc->tx_cwnd >> 1) + (hc->tx_cwnd >> 2)); | ||
186 | hc->tx_cwnd = (hc->tx_cwnd + win_used) >> 1; | ||
187 | } | ||
188 | hc->tx_cwnd_used = 0; | ||
189 | hc->tx_cwnd_stamp = now; | ||
190 | } | ||
191 | |||
192 | /* This borrows the code of tcp_cwnd_restart() */ | ||
193 | static void ccid2_cwnd_restart(struct sock *sk, const u32 now) | ||
194 | { | ||
195 | struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk); | ||
196 | u32 cwnd = hc->tx_cwnd, restart_cwnd, | ||
197 | iwnd = rfc3390_bytes_to_packets(dccp_sk(sk)->dccps_mss_cache); | ||
198 | |||
199 | hc->tx_ssthresh = max(hc->tx_ssthresh, (cwnd >> 1) + (cwnd >> 2)); | ||
200 | |||
201 | /* don't reduce cwnd below the initial window (IW) */ | ||
202 | restart_cwnd = min(cwnd, iwnd); | ||
203 | cwnd >>= (now - hc->tx_lsndtime) / hc->tx_rto; | ||
204 | hc->tx_cwnd = max(cwnd, restart_cwnd); | ||
205 | |||
206 | hc->tx_cwnd_stamp = now; | ||
207 | hc->tx_cwnd_used = 0; | ||
208 | } | ||
209 | |||
156 | static void ccid2_hc_tx_packet_sent(struct sock *sk, unsigned int len) | 210 | static void ccid2_hc_tx_packet_sent(struct sock *sk, unsigned int len) |
157 | { | 211 | { |
158 | struct dccp_sock *dp = dccp_sk(sk); | 212 | struct dccp_sock *dp = dccp_sk(sk); |
159 | struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk); | 213 | struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk); |
214 | const u32 now = ccid2_time_stamp; | ||
160 | struct ccid2_seq *next; | 215 | struct ccid2_seq *next; |
161 | 216 | ||
162 | hc->tx_pipe++; | 217 | /* slow-start after idle periods (RFC 2581, RFC 2861) */ |
218 | if (ccid2_do_cwv && !hc->tx_pipe && | ||
219 | (s32)(now - hc->tx_lsndtime) >= hc->tx_rto) | ||
220 | ccid2_cwnd_restart(sk, now); | ||
221 | |||
222 | hc->tx_lsndtime = now; | ||
223 | hc->tx_pipe += 1; | ||
224 | |||
225 | /* see whether cwnd was fully used (RFC 2861), update expected window */ | ||
226 | if (ccid2_cwnd_network_limited(hc)) { | ||
227 | ccid2_update_used_window(hc, hc->tx_cwnd); | ||
228 | hc->tx_cwnd_used = 0; | ||
229 | hc->tx_cwnd_stamp = now; | ||
230 | } else { | ||
231 | if (hc->tx_pipe > hc->tx_cwnd_used) | ||
232 | hc->tx_cwnd_used = hc->tx_pipe; | ||
233 | |||
234 | ccid2_update_used_window(hc, hc->tx_cwnd_used); | ||
235 | |||
236 | if (ccid2_do_cwv && (s32)(now - hc->tx_cwnd_stamp) >= hc->tx_rto) | ||
237 | ccid2_cwnd_application_limited(sk, now); | ||
238 | } | ||
163 | 239 | ||
164 | hc->tx_seqh->ccid2s_seq = dp->dccps_gss; | 240 | hc->tx_seqh->ccid2s_seq = dp->dccps_gss; |
165 | hc->tx_seqh->ccid2s_acked = 0; | 241 | hc->tx_seqh->ccid2s_acked = 0; |
166 | hc->tx_seqh->ccid2s_sent = ccid2_time_stamp; | 242 | hc->tx_seqh->ccid2s_sent = now; |
167 | 243 | ||
168 | next = hc->tx_seqh->ccid2s_next; | 244 | next = hc->tx_seqh->ccid2s_next; |
169 | /* check if we need to alloc more space */ | 245 | /* check if we need to alloc more space */ |
@@ -583,15 +659,6 @@ done: | |||
583 | dccp_ackvec_parsed_cleanup(&hc->tx_av_chunks); | 659 | dccp_ackvec_parsed_cleanup(&hc->tx_av_chunks); |
584 | } | 660 | } |
585 | 661 | ||
586 | /* | ||
587 | * Convert RFC 3390 larger initial window into an equivalent number of packets. | ||
588 | * This is based on the numbers specified in RFC 5681, 3.1. | ||
589 | */ | ||
590 | static inline u32 rfc3390_bytes_to_packets(const u32 smss) | ||
591 | { | ||
592 | return smss <= 1095 ? 4 : (smss > 2190 ? 2 : 3); | ||
593 | } | ||
594 | |||
595 | static int ccid2_hc_tx_init(struct ccid *ccid, struct sock *sk) | 662 | static int ccid2_hc_tx_init(struct ccid *ccid, struct sock *sk) |
596 | { | 663 | { |
597 | struct ccid2_hc_tx_sock *hc = ccid_priv(ccid); | 664 | struct ccid2_hc_tx_sock *hc = ccid_priv(ccid); |
@@ -603,6 +670,7 @@ static int ccid2_hc_tx_init(struct ccid *ccid, struct sock *sk) | |||
603 | 670 | ||
604 | /* Use larger initial windows (RFC 4341, section 5). */ | 671 | /* Use larger initial windows (RFC 4341, section 5). */ |
605 | hc->tx_cwnd = rfc3390_bytes_to_packets(dp->dccps_mss_cache); | 672 | hc->tx_cwnd = rfc3390_bytes_to_packets(dp->dccps_mss_cache); |
673 | hc->tx_expected_wnd = hc->tx_cwnd; | ||
606 | 674 | ||
607 | /* Make sure that Ack Ratio is enabled and within bounds. */ | 675 | /* Make sure that Ack Ratio is enabled and within bounds. */ |
608 | max_ratio = DIV_ROUND_UP(hc->tx_cwnd, 2); | 676 | max_ratio = DIV_ROUND_UP(hc->tx_cwnd, 2); |
@@ -615,7 +683,8 @@ static int ccid2_hc_tx_init(struct ccid *ccid, struct sock *sk) | |||
615 | 683 | ||
616 | hc->tx_rto = DCCP_TIMEOUT_INIT; | 684 | hc->tx_rto = DCCP_TIMEOUT_INIT; |
617 | hc->tx_rpdupack = -1; | 685 | hc->tx_rpdupack = -1; |
618 | hc->tx_last_cong = ccid2_time_stamp; | 686 | hc->tx_last_cong = hc->tx_lsndtime = hc->tx_cwnd_stamp = ccid2_time_stamp; |
687 | hc->tx_cwnd_used = 0; | ||
619 | setup_timer(&hc->tx_rtotimer, ccid2_hc_tx_rto_expire, | 688 | setup_timer(&hc->tx_rtotimer, ccid2_hc_tx_rto_expire, |
620 | (unsigned long)sk); | 689 | (unsigned long)sk); |
621 | INIT_LIST_HEAD(&hc->tx_av_chunks); | 690 | INIT_LIST_HEAD(&hc->tx_av_chunks); |
@@ -636,18 +705,14 @@ static void ccid2_hc_tx_exit(struct sock *sk) | |||
636 | 705 | ||
637 | static void ccid2_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb) | 706 | static void ccid2_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb) |
638 | { | 707 | { |
639 | const struct dccp_sock *dp = dccp_sk(sk); | ||
640 | struct ccid2_hc_rx_sock *hc = ccid2_hc_rx_sk(sk); | 708 | struct ccid2_hc_rx_sock *hc = ccid2_hc_rx_sk(sk); |
641 | 709 | ||
642 | switch (DCCP_SKB_CB(skb)->dccpd_type) { | 710 | if (!dccp_data_packet(skb)) |
643 | case DCCP_PKT_DATA: | 711 | return; |
644 | case DCCP_PKT_DATAACK: | 712 | |
645 | hc->rx_data++; | 713 | if (++hc->rx_num_data_pkts >= dccp_sk(sk)->dccps_r_ack_ratio) { |
646 | if (hc->rx_data >= dp->dccps_r_ack_ratio) { | 714 | dccp_send_ack(sk); |
647 | dccp_send_ack(sk); | 715 | hc->rx_num_data_pkts = 0; |
648 | hc->rx_data = 0; | ||
649 | } | ||
650 | break; | ||
651 | } | 716 | } |
652 | } | 717 | } |
653 | 718 | ||
diff --git a/net/dccp/ccids/ccid2.h b/net/dccp/ccids/ccid2.h index e9985dafc2c..f585d330e1e 100644 --- a/net/dccp/ccids/ccid2.h +++ b/net/dccp/ccids/ccid2.h | |||
@@ -53,6 +53,10 @@ struct ccid2_seq { | |||
53 | * @tx_rttvar: moving average/maximum of @mdev_max | 53 | * @tx_rttvar: moving average/maximum of @mdev_max |
54 | * @tx_rto: RTO value deriving from SRTT and RTTVAR (RFC 2988) | 54 | * @tx_rto: RTO value deriving from SRTT and RTTVAR (RFC 2988) |
55 | * @tx_rtt_seq: to decay RTTVAR at most once per flight | 55 | * @tx_rtt_seq: to decay RTTVAR at most once per flight |
56 | * @tx_cwnd_used: actually used cwnd, W_used of RFC 2861 | ||
57 | * @tx_expected_wnd: moving average of @tx_cwnd_used | ||
58 | * @tx_cwnd_stamp: to track idle periods in CWV | ||
59 | * @tx_lsndtime: last time (in jiffies) a data packet was sent | ||
56 | * @tx_rpseq: last consecutive seqno | 60 | * @tx_rpseq: last consecutive seqno |
57 | * @tx_rpdupack: dupacks since rpseq | 61 | * @tx_rpdupack: dupacks since rpseq |
58 | * @tx_av_chunks: list of Ack Vectors received on current skb | 62 | * @tx_av_chunks: list of Ack Vectors received on current skb |
@@ -76,6 +80,12 @@ struct ccid2_hc_tx_sock { | |||
76 | u64 tx_rtt_seq:48; | 80 | u64 tx_rtt_seq:48; |
77 | struct timer_list tx_rtotimer; | 81 | struct timer_list tx_rtotimer; |
78 | 82 | ||
83 | /* Congestion Window validation (optional, RFC 2861) */ | ||
84 | u32 tx_cwnd_used, | ||
85 | tx_expected_wnd, | ||
86 | tx_cwnd_stamp, | ||
87 | tx_lsndtime; | ||
88 | |||
79 | u64 tx_rpseq; | 89 | u64 tx_rpseq; |
80 | int tx_rpdupack; | 90 | int tx_rpdupack; |
81 | u32 tx_last_cong; | 91 | u32 tx_last_cong; |
@@ -88,8 +98,21 @@ static inline bool ccid2_cwnd_network_limited(struct ccid2_hc_tx_sock *hc) | |||
88 | return hc->tx_pipe >= hc->tx_cwnd; | 98 | return hc->tx_pipe >= hc->tx_cwnd; |
89 | } | 99 | } |
90 | 100 | ||
101 | /* | ||
102 | * Convert RFC 3390 larger initial window into an equivalent number of packets. | ||
103 | * This is based on the numbers specified in RFC 5681, 3.1. | ||
104 | */ | ||
105 | static inline u32 rfc3390_bytes_to_packets(const u32 smss) | ||
106 | { | ||
107 | return smss <= 1095 ? 4 : (smss > 2190 ? 2 : 3); | ||
108 | } | ||
109 | |||
110 | /** | ||
111 | * struct ccid2_hc_rx_sock - Receiving end of CCID-2 half-connection | ||
112 | * @rx_num_data_pkts: number of data packets received since last feedback | ||
113 | */ | ||
91 | struct ccid2_hc_rx_sock { | 114 | struct ccid2_hc_rx_sock { |
92 | int rx_data; | 115 | u32 rx_num_data_pkts; |
93 | }; | 116 | }; |
94 | 117 | ||
95 | static inline struct ccid2_hc_tx_sock *ccid2_hc_tx_sk(const struct sock *sk) | 118 | static inline struct ccid2_hc_tx_sock *ccid2_hc_tx_sk(const struct sock *sk) |
diff --git a/net/dccp/input.c b/net/dccp/input.c index 4222e7a654b..51d5fe5fffb 100644 --- a/net/dccp/input.c +++ b/net/dccp/input.c | |||
@@ -619,20 +619,31 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb, | |||
619 | return 1; | 619 | return 1; |
620 | } | 620 | } |
621 | 621 | ||
622 | if (sk->sk_state != DCCP_REQUESTING && sk->sk_state != DCCP_RESPOND) { | 622 | /* Step 6: Check sequence numbers (omitted in LISTEN/REQUEST state) */ |
623 | if (dccp_check_seqno(sk, skb)) | 623 | if (sk->sk_state != DCCP_REQUESTING && dccp_check_seqno(sk, skb)) |
624 | goto discard; | 624 | goto discard; |
625 | |||
626 | /* | ||
627 | * Step 8: Process options and mark acknowledgeable | ||
628 | */ | ||
629 | if (dccp_parse_options(sk, NULL, skb)) | ||
630 | return 1; | ||
631 | 625 | ||
632 | dccp_handle_ackvec_processing(sk, skb); | 626 | /* |
633 | dccp_deliver_input_to_ccids(sk, skb); | 627 | * Step 7: Check for unexpected packet types |
628 | * If (S.is_server and P.type == Response) | ||
629 | * or (S.is_client and P.type == Request) | ||
630 | * or (S.state == RESPOND and P.type == Data), | ||
631 | * Send Sync packet acknowledging P.seqno | ||
632 | * Drop packet and return | ||
633 | */ | ||
634 | if ((dp->dccps_role != DCCP_ROLE_CLIENT && | ||
635 | dh->dccph_type == DCCP_PKT_RESPONSE) || | ||
636 | (dp->dccps_role == DCCP_ROLE_CLIENT && | ||
637 | dh->dccph_type == DCCP_PKT_REQUEST) || | ||
638 | (sk->sk_state == DCCP_RESPOND && dh->dccph_type == DCCP_PKT_DATA)) { | ||
639 | dccp_send_sync(sk, dcb->dccpd_seq, DCCP_PKT_SYNC); | ||
640 | goto discard; | ||
634 | } | 641 | } |
635 | 642 | ||
643 | /* Step 8: Process options */ | ||
644 | if (dccp_parse_options(sk, NULL, skb)) | ||
645 | return 1; | ||
646 | |||
636 | /* | 647 | /* |
637 | * Step 9: Process Reset | 648 | * Step 9: Process Reset |
638 | * If P.type == Reset, | 649 | * If P.type == Reset, |
@@ -640,31 +651,15 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb, | |||
640 | * S.state := TIMEWAIT | 651 | * S.state := TIMEWAIT |
641 | * Set TIMEWAIT timer | 652 | * Set TIMEWAIT timer |
642 | * Drop packet and return | 653 | * Drop packet and return |
643 | */ | 654 | */ |
644 | if (dh->dccph_type == DCCP_PKT_RESET) { | 655 | if (dh->dccph_type == DCCP_PKT_RESET) { |
645 | dccp_rcv_reset(sk, skb); | 656 | dccp_rcv_reset(sk, skb); |
646 | return 0; | 657 | return 0; |
647 | /* | 658 | } else if (dh->dccph_type == DCCP_PKT_CLOSEREQ) { /* Step 13 */ |
648 | * Step 7: Check for unexpected packet types | ||
649 | * If (S.is_server and P.type == Response) | ||
650 | * or (S.is_client and P.type == Request) | ||
651 | * or (S.state == RESPOND and P.type == Data), | ||
652 | * Send Sync packet acknowledging P.seqno | ||
653 | * Drop packet and return | ||
654 | */ | ||
655 | } else if ((dp->dccps_role != DCCP_ROLE_CLIENT && | ||
656 | dh->dccph_type == DCCP_PKT_RESPONSE) || | ||
657 | (dp->dccps_role == DCCP_ROLE_CLIENT && | ||
658 | dh->dccph_type == DCCP_PKT_REQUEST) || | ||
659 | (sk->sk_state == DCCP_RESPOND && | ||
660 | dh->dccph_type == DCCP_PKT_DATA)) { | ||
661 | dccp_send_sync(sk, dcb->dccpd_seq, DCCP_PKT_SYNC); | ||
662 | goto discard; | ||
663 | } else if (dh->dccph_type == DCCP_PKT_CLOSEREQ) { | ||
664 | if (dccp_rcv_closereq(sk, skb)) | 659 | if (dccp_rcv_closereq(sk, skb)) |
665 | return 0; | 660 | return 0; |
666 | goto discard; | 661 | goto discard; |
667 | } else if (dh->dccph_type == DCCP_PKT_CLOSE) { | 662 | } else if (dh->dccph_type == DCCP_PKT_CLOSE) { /* Step 14 */ |
668 | if (dccp_rcv_close(sk, skb)) | 663 | if (dccp_rcv_close(sk, skb)) |
669 | return 0; | 664 | return 0; |
670 | goto discard; | 665 | goto discard; |
@@ -679,8 +674,12 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb, | |||
679 | __kfree_skb(skb); | 674 | __kfree_skb(skb); |
680 | return 0; | 675 | return 0; |
681 | 676 | ||
682 | case DCCP_RESPOND: | ||
683 | case DCCP_PARTOPEN: | 677 | case DCCP_PARTOPEN: |
678 | /* Step 8: if using Ack Vectors, mark packet acknowledgeable */ | ||
679 | dccp_handle_ackvec_processing(sk, skb); | ||
680 | dccp_deliver_input_to_ccids(sk, skb); | ||
681 | /* fall through */ | ||
682 | case DCCP_RESPOND: | ||
684 | queued = dccp_rcv_respond_partopen_state_process(sk, skb, | 683 | queued = dccp_rcv_respond_partopen_state_process(sk, skb, |
685 | dh, len); | 684 | dh, len); |
686 | break; | 685 | break; |
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c index 8c36adfd191..332639b56f4 100644 --- a/net/dccp/ipv4.c +++ b/net/dccp/ipv4.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <net/timewait_sock.h> | 26 | #include <net/timewait_sock.h> |
27 | #include <net/tcp_states.h> | 27 | #include <net/tcp_states.h> |
28 | #include <net/xfrm.h> | 28 | #include <net/xfrm.h> |
29 | #include <net/secure_seq.h> | ||
29 | 30 | ||
30 | #include "ackvec.h" | 31 | #include "ackvec.h" |
31 | #include "ccid.h" | 32 | #include "ccid.h" |
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c index 8dc4348774a..b74f76117dc 100644 --- a/net/dccp/ipv6.c +++ b/net/dccp/ipv6.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <net/transp_v6.h> | 29 | #include <net/transp_v6.h> |
30 | #include <net/ip6_checksum.h> | 30 | #include <net/ip6_checksum.h> |
31 | #include <net/xfrm.h> | 31 | #include <net/xfrm.h> |
32 | #include <net/secure_seq.h> | ||
32 | 33 | ||
33 | #include "dccp.h" | 34 | #include "dccp.h" |
34 | #include "ipv6.h" | 35 | #include "ipv6.h" |
@@ -69,13 +70,7 @@ static inline void dccp_v6_send_check(struct sock *sk, struct sk_buff *skb) | |||
69 | dh->dccph_checksum = dccp_v6_csum_finish(skb, &np->saddr, &np->daddr); | 70 | dh->dccph_checksum = dccp_v6_csum_finish(skb, &np->saddr, &np->daddr); |
70 | } | 71 | } |
71 | 72 | ||
72 | static inline __u32 secure_dccpv6_sequence_number(__be32 *saddr, __be32 *daddr, | 73 | static inline __u64 dccp_v6_init_sequence(struct sk_buff *skb) |
73 | __be16 sport, __be16 dport ) | ||
74 | { | ||
75 | return secure_tcpv6_sequence_number(saddr, daddr, sport, dport); | ||
76 | } | ||
77 | |||
78 | static inline __u32 dccp_v6_init_sequence(struct sk_buff *skb) | ||
79 | { | 74 | { |
80 | return secure_dccpv6_sequence_number(ipv6_hdr(skb)->daddr.s6_addr32, | 75 | return secure_dccpv6_sequence_number(ipv6_hdr(skb)->daddr.s6_addr32, |
81 | ipv6_hdr(skb)->saddr.s6_addr32, | 76 | ipv6_hdr(skb)->saddr.s6_addr32, |
diff --git a/net/dccp/output.c b/net/dccp/output.c index fab108e51e5..dede3edb884 100644 --- a/net/dccp/output.c +++ b/net/dccp/output.c | |||
@@ -27,11 +27,13 @@ static inline void dccp_event_ack_sent(struct sock *sk) | |||
27 | inet_csk_clear_xmit_timer(sk, ICSK_TIME_DACK); | 27 | inet_csk_clear_xmit_timer(sk, ICSK_TIME_DACK); |
28 | } | 28 | } |
29 | 29 | ||
30 | static void dccp_skb_entail(struct sock *sk, struct sk_buff *skb) | 30 | /* enqueue @skb on sk_send_head for retransmission, return clone to send now */ |
31 | static struct sk_buff *dccp_skb_entail(struct sock *sk, struct sk_buff *skb) | ||
31 | { | 32 | { |
32 | skb_set_owner_w(skb, sk); | 33 | skb_set_owner_w(skb, sk); |
33 | WARN_ON(sk->sk_send_head); | 34 | WARN_ON(sk->sk_send_head); |
34 | sk->sk_send_head = skb; | 35 | sk->sk_send_head = skb; |
36 | return skb_clone(sk->sk_send_head, gfp_any()); | ||
35 | } | 37 | } |
36 | 38 | ||
37 | /* | 39 | /* |
@@ -552,8 +554,7 @@ int dccp_connect(struct sock *sk) | |||
552 | 554 | ||
553 | DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_REQUEST; | 555 | DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_REQUEST; |
554 | 556 | ||
555 | dccp_skb_entail(sk, skb); | 557 | dccp_transmit_skb(sk, dccp_skb_entail(sk, skb)); |
556 | dccp_transmit_skb(sk, skb_clone(skb, GFP_KERNEL)); | ||
557 | DCCP_INC_STATS(DCCP_MIB_ACTIVEOPENS); | 558 | DCCP_INC_STATS(DCCP_MIB_ACTIVEOPENS); |
558 | 559 | ||
559 | /* Timer for repeating the REQUEST until an answer. */ | 560 | /* Timer for repeating the REQUEST until an answer. */ |
@@ -678,8 +679,7 @@ void dccp_send_close(struct sock *sk, const int active) | |||
678 | DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_CLOSE; | 679 | DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_CLOSE; |
679 | 680 | ||
680 | if (active) { | 681 | if (active) { |
681 | dccp_skb_entail(sk, skb); | 682 | skb = dccp_skb_entail(sk, skb); |
682 | dccp_transmit_skb(sk, skb_clone(skb, prio)); | ||
683 | /* | 683 | /* |
684 | * Retransmission timer for active-close: RFC 4340, 8.3 requires | 684 | * Retransmission timer for active-close: RFC 4340, 8.3 requires |
685 | * to retransmit the Close/CloseReq until the CLOSING/CLOSEREQ | 685 | * to retransmit the Close/CloseReq until the CLOSING/CLOSEREQ |
@@ -692,6 +692,6 @@ void dccp_send_close(struct sock *sk, const int active) | |||
692 | */ | 692 | */ |
693 | inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, | 693 | inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, |
694 | DCCP_TIMEOUT_INIT, DCCP_RTO_MAX); | 694 | DCCP_TIMEOUT_INIT, DCCP_RTO_MAX); |
695 | } else | 695 | } |
696 | dccp_transmit_skb(sk, skb); | 696 | dccp_transmit_skb(sk, skb); |
697 | } | 697 | } |