aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2007-10-26 06:50:02 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-26 06:50:02 -0400
commit8c56a347c1dfbe384b1ffb65d8828faa36dbaea4 (patch)
tree44dfa8621b387fc76168db3858996466b278f38e
parentd892afe2ca905ddb00a4f16927c8b465cdd31b20 (diff)
parent24c667db59a9cc4caaafe4f77f6f4ef85899a454 (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/acme/net-2.6
-rw-r--r--include/linux/dccp.h12
-rw-r--r--net/dccp/ccids/ccid2.c4
-rw-r--r--net/dccp/ccids/ccid3.c15
-rw-r--r--net/dccp/input.c48
-rw-r--r--net/dccp/ipv4.c6
-rw-r--r--net/dccp/ipv6.c4
-rw-r--r--net/dccp/options.c33
7 files changed, 79 insertions, 43 deletions
diff --git a/include/linux/dccp.h b/include/linux/dccp.h
index f3fc4392e93d..333c3ea82a5d 100644
--- a/include/linux/dccp.h
+++ b/include/linux/dccp.h
@@ -144,6 +144,8 @@ enum dccp_reset_codes {
144 DCCP_RESET_CODE_TOO_BUSY, 144 DCCP_RESET_CODE_TOO_BUSY,
145 DCCP_RESET_CODE_BAD_INIT_COOKIE, 145 DCCP_RESET_CODE_BAD_INIT_COOKIE,
146 DCCP_RESET_CODE_AGGRESSION_PENALTY, 146 DCCP_RESET_CODE_AGGRESSION_PENALTY,
147
148 DCCP_MAX_RESET_CODES /* Leave at the end! */
147}; 149};
148 150
149/* DCCP options */ 151/* DCCP options */
@@ -270,10 +272,9 @@ static inline struct dccp_hdr *dccp_zeroed_hdr(struct sk_buff *skb, int headlen)
270 return memset(skb_transport_header(skb), 0, headlen); 272 return memset(skb_transport_header(skb), 0, headlen);
271} 273}
272 274
273static inline struct dccp_hdr_ext *dccp_hdrx(const struct sk_buff *skb) 275static inline struct dccp_hdr_ext *dccp_hdrx(const struct dccp_hdr *dh)
274{ 276{
275 return (struct dccp_hdr_ext *)(skb_transport_header(skb) + 277 return (struct dccp_hdr_ext *)((unsigned char *)dh + sizeof(*dh));
276 sizeof(struct dccp_hdr));
277} 278}
278 279
279static inline unsigned int __dccp_basic_hdr_len(const struct dccp_hdr *dh) 280static inline unsigned int __dccp_basic_hdr_len(const struct dccp_hdr *dh)
@@ -287,13 +288,12 @@ static inline unsigned int dccp_basic_hdr_len(const struct sk_buff *skb)
287 return __dccp_basic_hdr_len(dh); 288 return __dccp_basic_hdr_len(dh);
288} 289}
289 290
290static inline __u64 dccp_hdr_seq(const struct sk_buff *skb) 291static inline __u64 dccp_hdr_seq(const struct dccp_hdr *dh)
291{ 292{
292 const struct dccp_hdr *dh = dccp_hdr(skb);
293 __u64 seq_nr = ntohs(dh->dccph_seq); 293 __u64 seq_nr = ntohs(dh->dccph_seq);
294 294
295 if (dh->dccph_x != 0) 295 if (dh->dccph_x != 0)
296 seq_nr = (seq_nr << 32) + ntohl(dccp_hdrx(skb)->dccph_seq_low); 296 seq_nr = (seq_nr << 32) + ntohl(dccp_hdrx(dh)->dccph_seq_low);
297 else 297 else
298 seq_nr += (u32)dh->dccph_seq2 << 16; 298 seq_nr += (u32)dh->dccph_seq2 << 16;
299 299
diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c
index 426008e3b7e3..d694656b8800 100644
--- a/net/dccp/ccids/ccid2.c
+++ b/net/dccp/ccids/ccid2.c
@@ -750,20 +750,16 @@ static int ccid2_hc_tx_init(struct ccid *ccid, struct sock *sk)
750 */ 750 */
751 hctx->ccid2hctx_ssthresh = ~0; 751 hctx->ccid2hctx_ssthresh = ~0;
752 hctx->ccid2hctx_numdupack = 3; 752 hctx->ccid2hctx_numdupack = 3;
753 hctx->ccid2hctx_seqbufc = 0;
754 753
755 /* XXX init ~ to window size... */ 754 /* XXX init ~ to window size... */
756 if (ccid2_hc_tx_alloc_seq(hctx)) 755 if (ccid2_hc_tx_alloc_seq(hctx))
757 return -ENOMEM; 756 return -ENOMEM;
758 757
759 hctx->ccid2hctx_sent = 0;
760 hctx->ccid2hctx_rto = 3 * HZ; 758 hctx->ccid2hctx_rto = 3 * HZ;
761 ccid2_change_srtt(hctx, -1); 759 ccid2_change_srtt(hctx, -1);
762 hctx->ccid2hctx_rttvar = -1; 760 hctx->ccid2hctx_rttvar = -1;
763 hctx->ccid2hctx_lastrtt = 0;
764 hctx->ccid2hctx_rpdupack = -1; 761 hctx->ccid2hctx_rpdupack = -1;
765 hctx->ccid2hctx_last_cong = jiffies; 762 hctx->ccid2hctx_last_cong = jiffies;
766 hctx->ccid2hctx_high_ack = 0;
767 763
768 hctx->ccid2hctx_rtotimer.function = &ccid2_hc_tx_rto_expire; 764 hctx->ccid2hctx_rtotimer.function = &ccid2_hc_tx_rto_expire;
769 hctx->ccid2hctx_rtotimer.data = (unsigned long)sk; 765 hctx->ccid2hctx_rtotimer.data = (unsigned long)sk;
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c
index 25772c326172..19b33586333d 100644
--- a/net/dccp/ccids/ccid3.c
+++ b/net/dccp/ccids/ccid3.c
@@ -40,6 +40,8 @@
40#include "lib/tfrc.h" 40#include "lib/tfrc.h"
41#include "ccid3.h" 41#include "ccid3.h"
42 42
43#include <asm/unaligned.h>
44
43#ifdef CONFIG_IP_DCCP_CCID3_DEBUG 45#ifdef CONFIG_IP_DCCP_CCID3_DEBUG
44static int ccid3_debug; 46static int ccid3_debug;
45#define ccid3_pr_debug(format, a...) DCCP_PR_DEBUG(ccid3_debug, format, ##a) 47#define ccid3_pr_debug(format, a...) DCCP_PR_DEBUG(ccid3_debug, format, ##a)
@@ -544,6 +546,7 @@ static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option,
544 const struct dccp_sock *dp = dccp_sk(sk); 546 const struct dccp_sock *dp = dccp_sk(sk);
545 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk); 547 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
546 struct ccid3_options_received *opt_recv; 548 struct ccid3_options_received *opt_recv;
549 __be32 opt_val;
547 550
548 opt_recv = &hctx->ccid3hctx_options_received; 551 opt_recv = &hctx->ccid3hctx_options_received;
549 552
@@ -563,8 +566,8 @@ static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option,
563 dccp_role(sk), sk, len); 566 dccp_role(sk), sk, len);
564 rc = -EINVAL; 567 rc = -EINVAL;
565 } else { 568 } else {
566 opt_recv->ccid3or_loss_event_rate = 569 opt_val = get_unaligned((__be32 *)value);
567 ntohl(*(__be32 *)value); 570 opt_recv->ccid3or_loss_event_rate = ntohl(opt_val);
568 ccid3_pr_debug("%s(%p), LOSS_EVENT_RATE=%u\n", 571 ccid3_pr_debug("%s(%p), LOSS_EVENT_RATE=%u\n",
569 dccp_role(sk), sk, 572 dccp_role(sk), sk,
570 opt_recv->ccid3or_loss_event_rate); 573 opt_recv->ccid3or_loss_event_rate);
@@ -585,8 +588,8 @@ static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option,
585 dccp_role(sk), sk, len); 588 dccp_role(sk), sk, len);
586 rc = -EINVAL; 589 rc = -EINVAL;
587 } else { 590 } else {
588 opt_recv->ccid3or_receive_rate = 591 opt_val = get_unaligned((__be32 *)value);
589 ntohl(*(__be32 *)value); 592 opt_recv->ccid3or_receive_rate = ntohl(opt_val);
590 ccid3_pr_debug("%s(%p), RECEIVE_RATE=%u\n", 593 ccid3_pr_debug("%s(%p), RECEIVE_RATE=%u\n",
591 dccp_role(sk), sk, 594 dccp_role(sk), sk,
592 opt_recv->ccid3or_receive_rate); 595 opt_recv->ccid3or_receive_rate);
@@ -601,8 +604,6 @@ static int ccid3_hc_tx_init(struct ccid *ccid, struct sock *sk)
601{ 604{
602 struct ccid3_hc_tx_sock *hctx = ccid_priv(ccid); 605 struct ccid3_hc_tx_sock *hctx = ccid_priv(ccid);
603 606
604 hctx->ccid3hctx_s = 0;
605 hctx->ccid3hctx_rtt = 0;
606 hctx->ccid3hctx_state = TFRC_SSTATE_NO_SENT; 607 hctx->ccid3hctx_state = TFRC_SSTATE_NO_SENT;
607 INIT_LIST_HEAD(&hctx->ccid3hctx_hist); 608 INIT_LIST_HEAD(&hctx->ccid3hctx_hist);
608 609
@@ -963,8 +964,6 @@ static int ccid3_hc_rx_init(struct ccid *ccid, struct sock *sk)
963 INIT_LIST_HEAD(&hcrx->ccid3hcrx_li_hist); 964 INIT_LIST_HEAD(&hcrx->ccid3hcrx_li_hist);
964 hcrx->ccid3hcrx_tstamp_last_feedback = 965 hcrx->ccid3hcrx_tstamp_last_feedback =
965 hcrx->ccid3hcrx_tstamp_last_ack = ktime_get_real(); 966 hcrx->ccid3hcrx_tstamp_last_ack = ktime_get_real();
966 hcrx->ccid3hcrx_s = 0;
967 hcrx->ccid3hcrx_rtt = 0;
968 return 0; 967 return 0;
969} 968}
970 969
diff --git a/net/dccp/input.c b/net/dccp/input.c
index 3560a2a875a0..1ce101062824 100644
--- a/net/dccp/input.c
+++ b/net/dccp/input.c
@@ -58,6 +58,42 @@ static void dccp_rcv_closereq(struct sock *sk, struct sk_buff *skb)
58 dccp_send_close(sk, 0); 58 dccp_send_close(sk, 0);
59} 59}
60 60
61static u8 dccp_reset_code_convert(const u8 code)
62{
63 const u8 error_code[] = {
64 [DCCP_RESET_CODE_CLOSED] = 0, /* normal termination */
65 [DCCP_RESET_CODE_UNSPECIFIED] = 0, /* nothing known */
66 [DCCP_RESET_CODE_ABORTED] = ECONNRESET,
67
68 [DCCP_RESET_CODE_NO_CONNECTION] = ECONNREFUSED,
69 [DCCP_RESET_CODE_CONNECTION_REFUSED] = ECONNREFUSED,
70 [DCCP_RESET_CODE_TOO_BUSY] = EUSERS,
71 [DCCP_RESET_CODE_AGGRESSION_PENALTY] = EDQUOT,
72
73 [DCCP_RESET_CODE_PACKET_ERROR] = ENOMSG,
74 [DCCP_RESET_CODE_BAD_INIT_COOKIE] = EBADR,
75 [DCCP_RESET_CODE_BAD_SERVICE_CODE] = EBADRQC,
76 [DCCP_RESET_CODE_OPTION_ERROR] = EILSEQ,
77 [DCCP_RESET_CODE_MANDATORY_ERROR] = EOPNOTSUPP,
78 };
79
80 return code >= DCCP_MAX_RESET_CODES ? 0 : error_code[code];
81}
82
83static void dccp_rcv_reset(struct sock *sk, struct sk_buff *skb)
84{
85 u8 err = dccp_reset_code_convert(dccp_hdr_reset(skb)->dccph_reset_code);
86
87 sk->sk_err = err;
88
89 /* Queue the equivalent of TCP fin so that dccp_recvmsg exits the loop */
90 dccp_fin(sk, skb);
91
92 if (err && !sock_flag(sk, SOCK_DEAD))
93 sk_wake_async(sk, 0, POLL_ERR);
94 dccp_time_wait(sk, DCCP_TIME_WAIT, 0);
95}
96
61static void dccp_event_ack_recv(struct sock *sk, struct sk_buff *skb) 97static void dccp_event_ack_recv(struct sock *sk, struct sk_buff *skb)
62{ 98{
63 struct dccp_sock *dp = dccp_sk(sk); 99 struct dccp_sock *dp = dccp_sk(sk);
@@ -191,9 +227,8 @@ static int __dccp_rcv_established(struct sock *sk, struct sk_buff *skb,
191 * S.state := TIMEWAIT 227 * S.state := TIMEWAIT
192 * Set TIMEWAIT timer 228 * Set TIMEWAIT timer
193 * Drop packet and return 229 * Drop packet and return
194 */ 230 */
195 dccp_fin(sk, skb); 231 dccp_rcv_reset(sk, skb);
196 dccp_time_wait(sk, DCCP_TIME_WAIT, 0);
197 return 0; 232 return 0;
198 case DCCP_PKT_CLOSEREQ: 233 case DCCP_PKT_CLOSEREQ:
199 dccp_rcv_closereq(sk, skb); 234 dccp_rcv_closereq(sk, skb);
@@ -521,12 +556,7 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
521 * Drop packet and return 556 * Drop packet and return
522 */ 557 */
523 if (dh->dccph_type == DCCP_PKT_RESET) { 558 if (dh->dccph_type == DCCP_PKT_RESET) {
524 /* 559 dccp_rcv_reset(sk, skb);
525 * Queue the equivalent of TCP fin so that dccp_recvmsg
526 * exits the loop
527 */
528 dccp_fin(sk, skb);
529 dccp_time_wait(sk, DCCP_TIME_WAIT, 0);
530 return 0; 560 return 0;
531 /* 561 /*
532 * Step 7: Check for unexpected packet types 562 * Step 7: Check for unexpected packet types
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index 222549ab274a..01a6a808bdb7 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -241,8 +241,8 @@ static void dccp_v4_err(struct sk_buff *skb, u32 info)
241 goto out; 241 goto out;
242 242
243 dp = dccp_sk(sk); 243 dp = dccp_sk(sk);
244 seq = dccp_hdr_seq(skb); 244 seq = dccp_hdr_seq(dh);
245 if (sk->sk_state != DCCP_LISTEN && 245 if ((1 << sk->sk_state) & ~(DCCPF_REQUESTING | DCCPF_LISTEN) &&
246 !between48(seq, dp->dccps_swl, dp->dccps_swh)) { 246 !between48(seq, dp->dccps_swl, dp->dccps_swh)) {
247 NET_INC_STATS_BH(LINUX_MIB_OUTOFWINDOWICMPS); 247 NET_INC_STATS_BH(LINUX_MIB_OUTOFWINDOWICMPS);
248 goto out; 248 goto out;
@@ -795,7 +795,7 @@ static int dccp_v4_rcv(struct sk_buff *skb)
795 795
796 dh = dccp_hdr(skb); 796 dh = dccp_hdr(skb);
797 797
798 DCCP_SKB_CB(skb)->dccpd_seq = dccp_hdr_seq(skb); 798 DCCP_SKB_CB(skb)->dccpd_seq = dccp_hdr_seq(dh);
799 DCCP_SKB_CB(skb)->dccpd_type = dh->dccph_type; 799 DCCP_SKB_CB(skb)->dccpd_type = dh->dccph_type;
800 800
801 dccp_pr_debug("%8.8s " 801 dccp_pr_debug("%8.8s "
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
index bbadd6681b83..62428ff137dd 100644
--- a/net/dccp/ipv6.c
+++ b/net/dccp/ipv6.c
@@ -173,7 +173,7 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
173 173
174 icmpv6_err_convert(type, code, &err); 174 icmpv6_err_convert(type, code, &err);
175 175
176 seq = DCCP_SKB_CB(skb)->dccpd_seq; 176 seq = dccp_hdr_seq(dh);
177 /* Might be for an request_sock */ 177 /* Might be for an request_sock */
178 switch (sk->sk_state) { 178 switch (sk->sk_state) {
179 struct request_sock *req, **prev; 179 struct request_sock *req, **prev;
@@ -787,7 +787,7 @@ static int dccp_v6_rcv(struct sk_buff *skb)
787 787
788 dh = dccp_hdr(skb); 788 dh = dccp_hdr(skb);
789 789
790 DCCP_SKB_CB(skb)->dccpd_seq = dccp_hdr_seq(skb); 790 DCCP_SKB_CB(skb)->dccpd_seq = dccp_hdr_seq(dh);
791 DCCP_SKB_CB(skb)->dccpd_type = dh->dccph_type; 791 DCCP_SKB_CB(skb)->dccpd_type = dh->dccph_type;
792 792
793 if (dccp_packet_without_ack(skb)) 793 if (dccp_packet_without_ack(skb))
diff --git a/net/dccp/options.c b/net/dccp/options.c
index d361b5533309..d286cffe2c49 100644
--- a/net/dccp/options.c
+++ b/net/dccp/options.c
@@ -14,6 +14,7 @@
14#include <linux/dccp.h> 14#include <linux/dccp.h>
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/types.h> 16#include <linux/types.h>
17#include <asm/unaligned.h>
17#include <linux/kernel.h> 18#include <linux/kernel.h>
18#include <linux/skbuff.h> 19#include <linux/skbuff.h>
19 20
@@ -59,6 +60,7 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb)
59 unsigned char opt, len; 60 unsigned char opt, len;
60 unsigned char *value; 61 unsigned char *value;
61 u32 elapsed_time; 62 u32 elapsed_time;
63 __be32 opt_val;
62 int rc; 64 int rc;
63 int mandatory = 0; 65 int mandatory = 0;
64 66
@@ -145,7 +147,8 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb)
145 if (len != 4) 147 if (len != 4)
146 goto out_invalid_option; 148 goto out_invalid_option;
147 149
148 opt_recv->dccpor_timestamp = ntohl(*(__be32 *)value); 150 opt_val = get_unaligned((__be32 *)value);
151 opt_recv->dccpor_timestamp = ntohl(opt_val);
149 152
150 dp->dccps_timestamp_echo = opt_recv->dccpor_timestamp; 153 dp->dccps_timestamp_echo = opt_recv->dccpor_timestamp;
151 dp->dccps_timestamp_time = ktime_get_real(); 154 dp->dccps_timestamp_time = ktime_get_real();
@@ -159,7 +162,8 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb)
159 if (len != 4 && len != 6 && len != 8) 162 if (len != 4 && len != 6 && len != 8)
160 goto out_invalid_option; 163 goto out_invalid_option;
161 164
162 opt_recv->dccpor_timestamp_echo = ntohl(*(__be32 *)value); 165 opt_val = get_unaligned((__be32 *)value);
166 opt_recv->dccpor_timestamp_echo = ntohl(opt_val);
163 167
164 dccp_pr_debug("%s rx opt: TIMESTAMP_ECHO=%u, len=%d, " 168 dccp_pr_debug("%s rx opt: TIMESTAMP_ECHO=%u, len=%d, "
165 "ackno=%llu", dccp_role(sk), 169 "ackno=%llu", dccp_role(sk),
@@ -168,16 +172,20 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb)
168 (unsigned long long) 172 (unsigned long long)
169 DCCP_SKB_CB(skb)->dccpd_ack_seq); 173 DCCP_SKB_CB(skb)->dccpd_ack_seq);
170 174
175 value += 4;
171 176
172 if (len == 4) { 177 if (len == 4) { /* no elapsed time included */
173 dccp_pr_debug_cat("\n"); 178 dccp_pr_debug_cat("\n");
174 break; 179 break;
175 } 180 }
176 181
177 if (len == 6) 182 if (len == 6) { /* 2-byte elapsed time */
178 elapsed_time = ntohs(*(__be16 *)(value + 4)); 183 __be16 opt_val2 = get_unaligned((__be16 *)value);
179 else 184 elapsed_time = ntohs(opt_val2);
180 elapsed_time = ntohl(*(__be32 *)(value + 4)); 185 } else { /* 4-byte elapsed time */
186 opt_val = get_unaligned((__be32 *)value);
187 elapsed_time = ntohl(opt_val);
188 }
181 189
182 dccp_pr_debug_cat(", ELAPSED_TIME=%u\n", elapsed_time); 190 dccp_pr_debug_cat(", ELAPSED_TIME=%u\n", elapsed_time);
183 191
@@ -192,10 +200,13 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb)
192 if (pkt_type == DCCP_PKT_DATA) 200 if (pkt_type == DCCP_PKT_DATA)
193 continue; 201 continue;
194 202
195 if (len == 2) 203 if (len == 2) {
196 elapsed_time = ntohs(*(__be16 *)value); 204 __be16 opt_val2 = get_unaligned((__be16 *)value);
197 else 205 elapsed_time = ntohs(opt_val2);
198 elapsed_time = ntohl(*(__be32 *)value); 206 } else {
207 opt_val = get_unaligned((__be32 *)value);
208 elapsed_time = ntohl(opt_val);
209 }
199 210
200 if (elapsed_time > opt_recv->dccpor_elapsed_time) 211 if (elapsed_time > opt_recv->dccpor_elapsed_time)
201 opt_recv->dccpor_elapsed_time = elapsed_time; 212 opt_recv->dccpor_elapsed_time = elapsed_time;