diff options
author | David S. Miller <davem@sunset.davemloft.net> | 2007-10-26 06:50:02 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-10-26 06:50:02 -0400 |
commit | 8c56a347c1dfbe384b1ffb65d8828faa36dbaea4 (patch) | |
tree | 44dfa8621b387fc76168db3858996466b278f38e /net | |
parent | d892afe2ca905ddb00a4f16927c8b465cdd31b20 (diff) | |
parent | 24c667db59a9cc4caaafe4f77f6f4ef85899a454 (diff) |
Merge master.kernel.org:/pub/scm/linux/kernel/git/acme/net-2.6
Diffstat (limited to 'net')
-rw-r--r-- | net/dccp/ccids/ccid2.c | 4 | ||||
-rw-r--r-- | net/dccp/ccids/ccid3.c | 15 | ||||
-rw-r--r-- | net/dccp/input.c | 48 | ||||
-rw-r--r-- | net/dccp/ipv4.c | 6 | ||||
-rw-r--r-- | net/dccp/ipv6.c | 4 | ||||
-rw-r--r-- | net/dccp/options.c | 33 |
6 files changed, 73 insertions, 37 deletions
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 |
44 | static int ccid3_debug; | 46 | static 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 | ||
61 | static 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 | |||
83 | static 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 | |||
61 | static void dccp_event_ack_recv(struct sock *sk, struct sk_buff *skb) | 97 | static 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; |