diff options
author | David S. Miller <davem@sunset.davemloft.net> | 2006-01-19 19:53:02 -0500 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-01-19 19:53:02 -0500 |
commit | cf9e50a920be24b734fb91f19b8844f8509cb981 (patch) | |
tree | a077c31bcfe9844bcfa7ff1fe07364b5b7958622 | |
parent | 0f36b018b2e314d45af86449f1a97facb1fbe300 (diff) | |
parent | a7d1f1b66c05ef4ebb58a34be7caad9af15546a4 (diff) |
Merge master.kernel.org:/pub/scm/linux/kernel/git/sridhar/lksctp-2.6
-rw-r--r-- | include/net/sctp/sctp.h | 2 | ||||
-rw-r--r-- | include/net/sctp/structs.h | 89 | ||||
-rw-r--r-- | net/sctp/input.c | 75 | ||||
-rw-r--r-- | net/sctp/inqueue.c | 4 | ||||
-rw-r--r-- | net/sctp/proc.c | 32 | ||||
-rw-r--r-- | net/sctp/sm_make_chunk.c | 16 | ||||
-rw-r--r-- | net/sctp/sm_sideeffect.c | 4 | ||||
-rw-r--r-- | net/sctp/sm_statefuns.c | 2 | ||||
-rw-r--r-- | net/sctp/socket.c | 6 | ||||
-rw-r--r-- | net/sctp/sysctl.c | 7 | ||||
-rw-r--r-- | net/sctp/transport.c | 2 |
11 files changed, 155 insertions, 84 deletions
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h index a553f39f6aee..e673b2c984e9 100644 --- a/include/net/sctp/sctp.h +++ b/include/net/sctp/sctp.h | |||
@@ -175,6 +175,8 @@ void sctp_icmp_frag_needed(struct sock *, struct sctp_association *, | |||
175 | void sctp_icmp_proto_unreachable(struct sock *sk, | 175 | void sctp_icmp_proto_unreachable(struct sock *sk, |
176 | struct sctp_association *asoc, | 176 | struct sctp_association *asoc, |
177 | struct sctp_transport *t); | 177 | struct sctp_transport *t); |
178 | void sctp_backlog_migrate(struct sctp_association *assoc, | ||
179 | struct sock *oldsk, struct sock *newsk); | ||
178 | 180 | ||
179 | /* | 181 | /* |
180 | * Section: Macros, externs, and inlines | 182 | * Section: Macros, externs, and inlines |
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index f5c22d77feab..8c522ae031bb 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h | |||
@@ -127,9 +127,9 @@ extern struct sctp_globals { | |||
127 | * RTO.Alpha - 1/8 (3 when converted to right shifts.) | 127 | * RTO.Alpha - 1/8 (3 when converted to right shifts.) |
128 | * RTO.Beta - 1/4 (2 when converted to right shifts.) | 128 | * RTO.Beta - 1/4 (2 when converted to right shifts.) |
129 | */ | 129 | */ |
130 | __u32 rto_initial; | 130 | unsigned long rto_initial; |
131 | __u32 rto_min; | 131 | unsigned long rto_min; |
132 | __u32 rto_max; | 132 | unsigned long rto_max; |
133 | 133 | ||
134 | /* Note: rto_alpha and rto_beta are really defined as inverse | 134 | /* Note: rto_alpha and rto_beta are really defined as inverse |
135 | * powers of two to facilitate integer operations. | 135 | * powers of two to facilitate integer operations. |
@@ -140,12 +140,18 @@ extern struct sctp_globals { | |||
140 | /* Max.Burst - 4 */ | 140 | /* Max.Burst - 4 */ |
141 | int max_burst; | 141 | int max_burst; |
142 | 142 | ||
143 | /* Valid.Cookie.Life - 60 seconds */ | ||
144 | int valid_cookie_life; | ||
145 | |||
146 | /* Whether Cookie Preservative is enabled(1) or not(0) */ | 143 | /* Whether Cookie Preservative is enabled(1) or not(0) */ |
147 | int cookie_preserve_enable; | 144 | int cookie_preserve_enable; |
148 | 145 | ||
146 | /* Valid.Cookie.Life - 60 seconds */ | ||
147 | unsigned long valid_cookie_life; | ||
148 | |||
149 | /* Delayed SACK timeout 200ms default*/ | ||
150 | unsigned long sack_timeout; | ||
151 | |||
152 | /* HB.interval - 30 seconds */ | ||
153 | unsigned long hb_interval; | ||
154 | |||
149 | /* Association.Max.Retrans - 10 attempts | 155 | /* Association.Max.Retrans - 10 attempts |
150 | * Path.Max.Retrans - 5 attempts (per destination address) | 156 | * Path.Max.Retrans - 5 attempts (per destination address) |
151 | * Max.Init.Retransmits - 8 attempts | 157 | * Max.Init.Retransmits - 8 attempts |
@@ -168,12 +174,6 @@ extern struct sctp_globals { | |||
168 | */ | 174 | */ |
169 | int rcvbuf_policy; | 175 | int rcvbuf_policy; |
170 | 176 | ||
171 | /* Delayed SACK timeout 200ms default*/ | ||
172 | int sack_timeout; | ||
173 | |||
174 | /* HB.interval - 30 seconds */ | ||
175 | int hb_interval; | ||
176 | |||
177 | /* The following variables are implementation specific. */ | 177 | /* The following variables are implementation specific. */ |
178 | 178 | ||
179 | /* Default initialization values to be applied to new associations. */ | 179 | /* Default initialization values to be applied to new associations. */ |
@@ -405,8 +405,9 @@ struct sctp_cookie { | |||
405 | /* The format of our cookie that we send to our peer. */ | 405 | /* The format of our cookie that we send to our peer. */ |
406 | struct sctp_signed_cookie { | 406 | struct sctp_signed_cookie { |
407 | __u8 signature[SCTP_SECRET_SIZE]; | 407 | __u8 signature[SCTP_SECRET_SIZE]; |
408 | __u32 __pad; /* force sctp_cookie alignment to 64 bits */ | ||
408 | struct sctp_cookie c; | 409 | struct sctp_cookie c; |
409 | }; | 410 | } __attribute__((packed)); |
410 | 411 | ||
411 | /* This is another convenience type to allocate memory for address | 412 | /* This is another convenience type to allocate memory for address |
412 | * params for the maximum size and pass such structures around | 413 | * params for the maximum size and pass such structures around |
@@ -827,7 +828,7 @@ struct sctp_transport { | |||
827 | __u32 rtt; /* This is the most recent RTT. */ | 828 | __u32 rtt; /* This is the most recent RTT. */ |
828 | 829 | ||
829 | /* RTO : The current retransmission timeout value. */ | 830 | /* RTO : The current retransmission timeout value. */ |
830 | __u32 rto; | 831 | unsigned long rto; |
831 | 832 | ||
832 | /* RTTVAR : The current RTT variation. */ | 833 | /* RTTVAR : The current RTT variation. */ |
833 | __u32 rttvar; | 834 | __u32 rttvar; |
@@ -877,22 +878,10 @@ struct sctp_transport { | |||
877 | /* Heartbeat interval: The endpoint sends out a Heartbeat chunk to | 878 | /* Heartbeat interval: The endpoint sends out a Heartbeat chunk to |
878 | * the destination address every heartbeat interval. | 879 | * the destination address every heartbeat interval. |
879 | */ | 880 | */ |
880 | __u32 hbinterval; | 881 | unsigned long hbinterval; |
881 | |||
882 | /* This is the max_retrans value for the transport and will | ||
883 | * be initialized from the assocs value. This can be changed | ||
884 | * using SCTP_SET_PEER_ADDR_PARAMS socket option. | ||
885 | */ | ||
886 | __u16 pathmaxrxt; | ||
887 | |||
888 | /* PMTU : The current known path MTU. */ | ||
889 | __u32 pathmtu; | ||
890 | 882 | ||
891 | /* SACK delay timeout */ | 883 | /* SACK delay timeout */ |
892 | __u32 sackdelay; | 884 | unsigned long sackdelay; |
893 | |||
894 | /* Flags controling Heartbeat, SACK delay, and Path MTU Discovery. */ | ||
895 | __u32 param_flags; | ||
896 | 885 | ||
897 | /* When was the last time (in jiffies) that we heard from this | 886 | /* When was the last time (in jiffies) that we heard from this |
898 | * transport? We use this to pick new active and retran paths. | 887 | * transport? We use this to pick new active and retran paths. |
@@ -904,6 +893,18 @@ struct sctp_transport { | |||
904 | */ | 893 | */ |
905 | unsigned long last_time_ecne_reduced; | 894 | unsigned long last_time_ecne_reduced; |
906 | 895 | ||
896 | /* This is the max_retrans value for the transport and will | ||
897 | * be initialized from the assocs value. This can be changed | ||
898 | * using SCTP_SET_PEER_ADDR_PARAMS socket option. | ||
899 | */ | ||
900 | __u16 pathmaxrxt; | ||
901 | |||
902 | /* PMTU : The current known path MTU. */ | ||
903 | __u32 pathmtu; | ||
904 | |||
905 | /* Flags controling Heartbeat, SACK delay, and Path MTU Discovery. */ | ||
906 | __u32 param_flags; | ||
907 | |||
907 | /* The number of times INIT has been sent on this transport. */ | 908 | /* The number of times INIT has been sent on this transport. */ |
908 | int init_sent_count; | 909 | int init_sent_count; |
909 | 910 | ||
@@ -1249,6 +1250,14 @@ struct sctp_endpoint { | |||
1249 | int last_key; | 1250 | int last_key; |
1250 | int key_changed_at; | 1251 | int key_changed_at; |
1251 | 1252 | ||
1253 | /* digest: This is a digest of the sctp cookie. This field is | ||
1254 | * only used on the receive path when we try to validate | ||
1255 | * that the cookie has not been tampered with. We put | ||
1256 | * this here so we pre-allocate this once and can re-use | ||
1257 | * on every receive. | ||
1258 | */ | ||
1259 | __u8 digest[SCTP_SIGNATURE_SIZE]; | ||
1260 | |||
1252 | /* sendbuf acct. policy. */ | 1261 | /* sendbuf acct. policy. */ |
1253 | __u32 sndbuf_policy; | 1262 | __u32 sndbuf_policy; |
1254 | 1263 | ||
@@ -1499,9 +1508,9 @@ struct sctp_association { | |||
1499 | * These values will be initialized by system defaults, but can | 1508 | * These values will be initialized by system defaults, but can |
1500 | * be modified via the SCTP_RTOINFO socket option. | 1509 | * be modified via the SCTP_RTOINFO socket option. |
1501 | */ | 1510 | */ |
1502 | __u32 rto_initial; | 1511 | unsigned long rto_initial; |
1503 | __u32 rto_max; | 1512 | unsigned long rto_max; |
1504 | __u32 rto_min; | 1513 | unsigned long rto_min; |
1505 | 1514 | ||
1506 | /* Maximum number of new data packets that can be sent in a burst. */ | 1515 | /* Maximum number of new data packets that can be sent in a burst. */ |
1507 | int max_burst; | 1516 | int max_burst; |
@@ -1519,13 +1528,13 @@ struct sctp_association { | |||
1519 | __u16 init_retries; | 1528 | __u16 init_retries; |
1520 | 1529 | ||
1521 | /* The largest timeout or RTO value to use in attempting an INIT */ | 1530 | /* The largest timeout or RTO value to use in attempting an INIT */ |
1522 | __u16 max_init_timeo; | 1531 | unsigned long max_init_timeo; |
1523 | 1532 | ||
1524 | /* Heartbeat interval: The endpoint sends out a Heartbeat chunk to | 1533 | /* Heartbeat interval: The endpoint sends out a Heartbeat chunk to |
1525 | * the destination address every heartbeat interval. This value | 1534 | * the destination address every heartbeat interval. This value |
1526 | * will be inherited by all new transports. | 1535 | * will be inherited by all new transports. |
1527 | */ | 1536 | */ |
1528 | __u32 hbinterval; | 1537 | unsigned long hbinterval; |
1529 | 1538 | ||
1530 | /* This is the max_retrans value for new transports in the | 1539 | /* This is the max_retrans value for new transports in the |
1531 | * association. | 1540 | * association. |
@@ -1537,13 +1546,14 @@ struct sctp_association { | |||
1537 | */ | 1546 | */ |
1538 | __u32 pathmtu; | 1547 | __u32 pathmtu; |
1539 | 1548 | ||
1540 | /* SACK delay timeout */ | ||
1541 | __u32 sackdelay; | ||
1542 | |||
1543 | /* Flags controling Heartbeat, SACK delay, and Path MTU Discovery. */ | 1549 | /* Flags controling Heartbeat, SACK delay, and Path MTU Discovery. */ |
1544 | __u32 param_flags; | 1550 | __u32 param_flags; |
1545 | 1551 | ||
1546 | int timeouts[SCTP_NUM_TIMEOUT_TYPES]; | 1552 | /* SACK delay timeout */ |
1553 | unsigned long sackdelay; | ||
1554 | |||
1555 | |||
1556 | unsigned long timeouts[SCTP_NUM_TIMEOUT_TYPES]; | ||
1547 | struct timer_list timers[SCTP_NUM_TIMEOUT_TYPES]; | 1557 | struct timer_list timers[SCTP_NUM_TIMEOUT_TYPES]; |
1548 | 1558 | ||
1549 | /* Transport to which SHUTDOWN chunk was last sent. */ | 1559 | /* Transport to which SHUTDOWN chunk was last sent. */ |
@@ -1648,7 +1658,10 @@ struct sctp_association { | |||
1648 | /* How many duplicated TSNs have we seen? */ | 1658 | /* How many duplicated TSNs have we seen? */ |
1649 | int numduptsns; | 1659 | int numduptsns; |
1650 | 1660 | ||
1651 | /* Number of seconds of idle time before an association is closed. */ | 1661 | /* Number of seconds of idle time before an association is closed. |
1662 | * In the association context, this is really used as a boolean | ||
1663 | * since the real timeout is stored in the timeouts array | ||
1664 | */ | ||
1652 | __u32 autoclose; | 1665 | __u32 autoclose; |
1653 | 1666 | ||
1654 | /* These are to support | 1667 | /* These are to support |
diff --git a/net/sctp/input.c b/net/sctp/input.c index 4aa6fc60357c..cb78b50868ee 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c | |||
@@ -257,20 +257,26 @@ int sctp_rcv(struct sk_buff *skb) | |||
257 | */ | 257 | */ |
258 | sctp_bh_lock_sock(sk); | 258 | sctp_bh_lock_sock(sk); |
259 | 259 | ||
260 | /* It is possible that the association could have moved to a different | ||
261 | * socket if it is peeled off. If so, update the sk. | ||
262 | */ | ||
263 | if (sk != rcvr->sk) { | ||
264 | sctp_bh_lock_sock(rcvr->sk); | ||
265 | sctp_bh_unlock_sock(sk); | ||
266 | sk = rcvr->sk; | ||
267 | } | ||
268 | |||
260 | if (sock_owned_by_user(sk)) | 269 | if (sock_owned_by_user(sk)) |
261 | sk_add_backlog(sk, skb); | 270 | sk_add_backlog(sk, skb); |
262 | else | 271 | else |
263 | sctp_backlog_rcv(sk, skb); | 272 | sctp_backlog_rcv(sk, skb); |
264 | 273 | ||
265 | /* Release the sock and any reference counts we took in the | 274 | /* Release the sock and the sock ref we took in the lookup calls. |
266 | * lookup calls. | 275 | * The asoc/ep ref will be released in sctp_backlog_rcv. |
267 | */ | 276 | */ |
268 | sctp_bh_unlock_sock(sk); | 277 | sctp_bh_unlock_sock(sk); |
269 | if (asoc) | ||
270 | sctp_association_put(asoc); | ||
271 | else | ||
272 | sctp_endpoint_put(ep); | ||
273 | sock_put(sk); | 278 | sock_put(sk); |
279 | |||
274 | return ret; | 280 | return ret; |
275 | 281 | ||
276 | discard_it: | 282 | discard_it: |
@@ -296,12 +302,50 @@ discard_release: | |||
296 | int sctp_backlog_rcv(struct sock *sk, struct sk_buff *skb) | 302 | int sctp_backlog_rcv(struct sock *sk, struct sk_buff *skb) |
297 | { | 303 | { |
298 | struct sctp_chunk *chunk = SCTP_INPUT_CB(skb)->chunk; | 304 | struct sctp_chunk *chunk = SCTP_INPUT_CB(skb)->chunk; |
299 | struct sctp_inq *inqueue = &chunk->rcvr->inqueue; | 305 | struct sctp_inq *inqueue = NULL; |
300 | 306 | struct sctp_ep_common *rcvr = NULL; | |
301 | sctp_inq_push(inqueue, chunk); | 307 | |
308 | rcvr = chunk->rcvr; | ||
309 | |||
310 | BUG_TRAP(rcvr->sk == sk); | ||
311 | |||
312 | if (rcvr->dead) { | ||
313 | sctp_chunk_free(chunk); | ||
314 | } else { | ||
315 | inqueue = &chunk->rcvr->inqueue; | ||
316 | sctp_inq_push(inqueue, chunk); | ||
317 | } | ||
318 | |||
319 | /* Release the asoc/ep ref we took in the lookup calls in sctp_rcv. */ | ||
320 | if (SCTP_EP_TYPE_ASSOCIATION == rcvr->type) | ||
321 | sctp_association_put(sctp_assoc(rcvr)); | ||
322 | else | ||
323 | sctp_endpoint_put(sctp_ep(rcvr)); | ||
324 | |||
302 | return 0; | 325 | return 0; |
303 | } | 326 | } |
304 | 327 | ||
328 | void sctp_backlog_migrate(struct sctp_association *assoc, | ||
329 | struct sock *oldsk, struct sock *newsk) | ||
330 | { | ||
331 | struct sk_buff *skb; | ||
332 | struct sctp_chunk *chunk; | ||
333 | |||
334 | skb = oldsk->sk_backlog.head; | ||
335 | oldsk->sk_backlog.head = oldsk->sk_backlog.tail = NULL; | ||
336 | while (skb != NULL) { | ||
337 | struct sk_buff *next = skb->next; | ||
338 | |||
339 | chunk = SCTP_INPUT_CB(skb)->chunk; | ||
340 | skb->next = NULL; | ||
341 | if (&assoc->base == chunk->rcvr) | ||
342 | sk_add_backlog(newsk, skb); | ||
343 | else | ||
344 | sk_add_backlog(oldsk, skb); | ||
345 | skb = next; | ||
346 | } | ||
347 | } | ||
348 | |||
305 | /* Handle icmp frag needed error. */ | 349 | /* Handle icmp frag needed error. */ |
306 | void sctp_icmp_frag_needed(struct sock *sk, struct sctp_association *asoc, | 350 | void sctp_icmp_frag_needed(struct sock *sk, struct sctp_association *asoc, |
307 | struct sctp_transport *t, __u32 pmtu) | 351 | struct sctp_transport *t, __u32 pmtu) |
@@ -544,10 +588,16 @@ int sctp_rcv_ootb(struct sk_buff *skb) | |||
544 | sctp_errhdr_t *err; | 588 | sctp_errhdr_t *err; |
545 | 589 | ||
546 | ch = (sctp_chunkhdr_t *) skb->data; | 590 | ch = (sctp_chunkhdr_t *) skb->data; |
547 | ch_end = ((__u8 *) ch) + WORD_ROUND(ntohs(ch->length)); | ||
548 | 591 | ||
549 | /* Scan through all the chunks in the packet. */ | 592 | /* Scan through all the chunks in the packet. */ |
550 | while (ch_end > (__u8 *)ch && ch_end < skb->tail) { | 593 | do { |
594 | /* Break out if chunk length is less then minimal. */ | ||
595 | if (ntohs(ch->length) < sizeof(sctp_chunkhdr_t)) | ||
596 | break; | ||
597 | |||
598 | ch_end = ((__u8 *)ch) + WORD_ROUND(ntohs(ch->length)); | ||
599 | if (ch_end > skb->tail) | ||
600 | break; | ||
551 | 601 | ||
552 | /* RFC 8.4, 2) If the OOTB packet contains an ABORT chunk, the | 602 | /* RFC 8.4, 2) If the OOTB packet contains an ABORT chunk, the |
553 | * receiver MUST silently discard the OOTB packet and take no | 603 | * receiver MUST silently discard the OOTB packet and take no |
@@ -578,8 +628,7 @@ int sctp_rcv_ootb(struct sk_buff *skb) | |||
578 | } | 628 | } |
579 | 629 | ||
580 | ch = (sctp_chunkhdr_t *) ch_end; | 630 | ch = (sctp_chunkhdr_t *) ch_end; |
581 | ch_end = ((__u8 *) ch) + WORD_ROUND(ntohs(ch->length)); | 631 | } while (ch_end < skb->tail); |
582 | } | ||
583 | 632 | ||
584 | return 0; | 633 | return 0; |
585 | 634 | ||
diff --git a/net/sctp/inqueue.c b/net/sctp/inqueue.c index 2d33922c044b..297b8951463e 100644 --- a/net/sctp/inqueue.c +++ b/net/sctp/inqueue.c | |||
@@ -73,8 +73,10 @@ void sctp_inq_free(struct sctp_inq *queue) | |||
73 | /* If there is a packet which is currently being worked on, | 73 | /* If there is a packet which is currently being worked on, |
74 | * free it as well. | 74 | * free it as well. |
75 | */ | 75 | */ |
76 | if (queue->in_progress) | 76 | if (queue->in_progress) { |
77 | sctp_chunk_free(queue->in_progress); | 77 | sctp_chunk_free(queue->in_progress); |
78 | queue->in_progress = NULL; | ||
79 | } | ||
78 | 80 | ||
79 | if (queue->malloced) { | 81 | if (queue->malloced) { |
80 | /* Dump the master memory segment. */ | 82 | /* Dump the master memory segment. */ |
diff --git a/net/sctp/proc.c b/net/sctp/proc.c index 6e4dc28874d7..d47a52c303a8 100644 --- a/net/sctp/proc.c +++ b/net/sctp/proc.c | |||
@@ -176,7 +176,7 @@ static void sctp_seq_dump_remote_addrs(struct seq_file *seq, struct sctp_associa | |||
176 | 176 | ||
177 | static void * sctp_eps_seq_start(struct seq_file *seq, loff_t *pos) | 177 | static void * sctp_eps_seq_start(struct seq_file *seq, loff_t *pos) |
178 | { | 178 | { |
179 | if (*pos > sctp_ep_hashsize) | 179 | if (*pos >= sctp_ep_hashsize) |
180 | return NULL; | 180 | return NULL; |
181 | 181 | ||
182 | if (*pos < 0) | 182 | if (*pos < 0) |
@@ -185,8 +185,6 @@ static void * sctp_eps_seq_start(struct seq_file *seq, loff_t *pos) | |||
185 | if (*pos == 0) | 185 | if (*pos == 0) |
186 | seq_printf(seq, " ENDPT SOCK STY SST HBKT LPORT UID INODE LADDRS\n"); | 186 | seq_printf(seq, " ENDPT SOCK STY SST HBKT LPORT UID INODE LADDRS\n"); |
187 | 187 | ||
188 | ++*pos; | ||
189 | |||
190 | return (void *)pos; | 188 | return (void *)pos; |
191 | } | 189 | } |
192 | 190 | ||
@@ -198,11 +196,9 @@ static void sctp_eps_seq_stop(struct seq_file *seq, void *v) | |||
198 | 196 | ||
199 | static void * sctp_eps_seq_next(struct seq_file *seq, void *v, loff_t *pos) | 197 | static void * sctp_eps_seq_next(struct seq_file *seq, void *v, loff_t *pos) |
200 | { | 198 | { |
201 | if (*pos > sctp_ep_hashsize) | 199 | if (++*pos >= sctp_ep_hashsize) |
202 | return NULL; | 200 | return NULL; |
203 | 201 | ||
204 | ++*pos; | ||
205 | |||
206 | return pos; | 202 | return pos; |
207 | } | 203 | } |
208 | 204 | ||
@@ -214,19 +210,19 @@ static int sctp_eps_seq_show(struct seq_file *seq, void *v) | |||
214 | struct sctp_ep_common *epb; | 210 | struct sctp_ep_common *epb; |
215 | struct sctp_endpoint *ep; | 211 | struct sctp_endpoint *ep; |
216 | struct sock *sk; | 212 | struct sock *sk; |
217 | int hash = *(int *)v; | 213 | int hash = *(loff_t *)v; |
218 | 214 | ||
219 | if (hash > sctp_ep_hashsize) | 215 | if (hash >= sctp_ep_hashsize) |
220 | return -ENOMEM; | 216 | return -ENOMEM; |
221 | 217 | ||
222 | head = &sctp_ep_hashtable[hash-1]; | 218 | head = &sctp_ep_hashtable[hash]; |
223 | sctp_local_bh_disable(); | 219 | sctp_local_bh_disable(); |
224 | read_lock(&head->lock); | 220 | read_lock(&head->lock); |
225 | for (epb = head->chain; epb; epb = epb->next) { | 221 | for (epb = head->chain; epb; epb = epb->next) { |
226 | ep = sctp_ep(epb); | 222 | ep = sctp_ep(epb); |
227 | sk = epb->sk; | 223 | sk = epb->sk; |
228 | seq_printf(seq, "%8p %8p %-3d %-3d %-4d %-5d %5d %5lu ", ep, sk, | 224 | seq_printf(seq, "%8p %8p %-3d %-3d %-4d %-5d %5d %5lu ", ep, sk, |
229 | sctp_sk(sk)->type, sk->sk_state, hash-1, | 225 | sctp_sk(sk)->type, sk->sk_state, hash, |
230 | epb->bind_addr.port, | 226 | epb->bind_addr.port, |
231 | sock_i_uid(sk), sock_i_ino(sk)); | 227 | sock_i_uid(sk), sock_i_ino(sk)); |
232 | 228 | ||
@@ -283,7 +279,7 @@ void sctp_eps_proc_exit(void) | |||
283 | 279 | ||
284 | static void * sctp_assocs_seq_start(struct seq_file *seq, loff_t *pos) | 280 | static void * sctp_assocs_seq_start(struct seq_file *seq, loff_t *pos) |
285 | { | 281 | { |
286 | if (*pos > sctp_assoc_hashsize) | 282 | if (*pos >= sctp_assoc_hashsize) |
287 | return NULL; | 283 | return NULL; |
288 | 284 | ||
289 | if (*pos < 0) | 285 | if (*pos < 0) |
@@ -293,8 +289,6 @@ static void * sctp_assocs_seq_start(struct seq_file *seq, loff_t *pos) | |||
293 | seq_printf(seq, " ASSOC SOCK STY SST ST HBKT ASSOC-ID TX_QUEUE RX_QUEUE UID INODE LPORT " | 289 | seq_printf(seq, " ASSOC SOCK STY SST ST HBKT ASSOC-ID TX_QUEUE RX_QUEUE UID INODE LPORT " |
294 | "RPORT LADDRS <-> RADDRS\n"); | 290 | "RPORT LADDRS <-> RADDRS\n"); |
295 | 291 | ||
296 | ++*pos; | ||
297 | |||
298 | return (void *)pos; | 292 | return (void *)pos; |
299 | } | 293 | } |
300 | 294 | ||
@@ -306,11 +300,9 @@ static void sctp_assocs_seq_stop(struct seq_file *seq, void *v) | |||
306 | 300 | ||
307 | static void * sctp_assocs_seq_next(struct seq_file *seq, void *v, loff_t *pos) | 301 | static void * sctp_assocs_seq_next(struct seq_file *seq, void *v, loff_t *pos) |
308 | { | 302 | { |
309 | if (*pos > sctp_assoc_hashsize) | 303 | if (++*pos >= sctp_assoc_hashsize) |
310 | return NULL; | 304 | return NULL; |
311 | 305 | ||
312 | ++*pos; | ||
313 | |||
314 | return pos; | 306 | return pos; |
315 | } | 307 | } |
316 | 308 | ||
@@ -321,12 +313,12 @@ static int sctp_assocs_seq_show(struct seq_file *seq, void *v) | |||
321 | struct sctp_ep_common *epb; | 313 | struct sctp_ep_common *epb; |
322 | struct sctp_association *assoc; | 314 | struct sctp_association *assoc; |
323 | struct sock *sk; | 315 | struct sock *sk; |
324 | int hash = *(int *)v; | 316 | int hash = *(loff_t *)v; |
325 | 317 | ||
326 | if (hash > sctp_assoc_hashsize) | 318 | if (hash >= sctp_assoc_hashsize) |
327 | return -ENOMEM; | 319 | return -ENOMEM; |
328 | 320 | ||
329 | head = &sctp_assoc_hashtable[hash-1]; | 321 | head = &sctp_assoc_hashtable[hash]; |
330 | sctp_local_bh_disable(); | 322 | sctp_local_bh_disable(); |
331 | read_lock(&head->lock); | 323 | read_lock(&head->lock); |
332 | for (epb = head->chain; epb; epb = epb->next) { | 324 | for (epb = head->chain; epb; epb = epb->next) { |
@@ -335,7 +327,7 @@ static int sctp_assocs_seq_show(struct seq_file *seq, void *v) | |||
335 | seq_printf(seq, | 327 | seq_printf(seq, |
336 | "%8p %8p %-3d %-3d %-2d %-4d %4d %8d %8d %7d %5lu %-5d %5d ", | 328 | "%8p %8p %-3d %-3d %-2d %-4d %4d %8d %8d %7d %5lu %-5d %5d ", |
337 | assoc, sk, sctp_sk(sk)->type, sk->sk_state, | 329 | assoc, sk, sctp_sk(sk)->type, sk->sk_state, |
338 | assoc->state, hash-1, assoc->assoc_id, | 330 | assoc->state, hash, assoc->assoc_id, |
339 | (sk->sk_rcvbuf - assoc->rwnd), | 331 | (sk->sk_rcvbuf - assoc->rwnd), |
340 | assoc->sndbuf_used, | 332 | assoc->sndbuf_used, |
341 | sock_i_uid(sk), sock_i_ino(sk), | 333 | sock_i_uid(sk), sock_i_ino(sk), |
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index 556c495c6922..5e0de3c0eead 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c | |||
@@ -1275,7 +1275,12 @@ static sctp_cookie_param_t *sctp_pack_cookie(const struct sctp_endpoint *ep, | |||
1275 | unsigned int keylen; | 1275 | unsigned int keylen; |
1276 | char *key; | 1276 | char *key; |
1277 | 1277 | ||
1278 | headersize = sizeof(sctp_paramhdr_t) + SCTP_SECRET_SIZE; | 1278 | /* Header size is static data prior to the actual cookie, including |
1279 | * any padding. | ||
1280 | */ | ||
1281 | headersize = sizeof(sctp_paramhdr_t) + | ||
1282 | (sizeof(struct sctp_signed_cookie) - | ||
1283 | sizeof(struct sctp_cookie)); | ||
1279 | bodysize = sizeof(struct sctp_cookie) | 1284 | bodysize = sizeof(struct sctp_cookie) |
1280 | + ntohs(init_chunk->chunk_hdr->length) + addrs_len; | 1285 | + ntohs(init_chunk->chunk_hdr->length) + addrs_len; |
1281 | 1286 | ||
@@ -1354,7 +1359,7 @@ struct sctp_association *sctp_unpack_cookie( | |||
1354 | struct sctp_signed_cookie *cookie; | 1359 | struct sctp_signed_cookie *cookie; |
1355 | struct sctp_cookie *bear_cookie; | 1360 | struct sctp_cookie *bear_cookie; |
1356 | int headersize, bodysize, fixed_size; | 1361 | int headersize, bodysize, fixed_size; |
1357 | __u8 digest[SCTP_SIGNATURE_SIZE]; | 1362 | __u8 *digest = ep->digest; |
1358 | struct scatterlist sg; | 1363 | struct scatterlist sg; |
1359 | unsigned int keylen, len; | 1364 | unsigned int keylen, len; |
1360 | char *key; | 1365 | char *key; |
@@ -1362,7 +1367,12 @@ struct sctp_association *sctp_unpack_cookie( | |||
1362 | struct sk_buff *skb = chunk->skb; | 1367 | struct sk_buff *skb = chunk->skb; |
1363 | struct timeval tv; | 1368 | struct timeval tv; |
1364 | 1369 | ||
1365 | headersize = sizeof(sctp_chunkhdr_t) + SCTP_SECRET_SIZE; | 1370 | /* Header size is static data prior to the actual cookie, including |
1371 | * any padding. | ||
1372 | */ | ||
1373 | headersize = sizeof(sctp_chunkhdr_t) + | ||
1374 | (sizeof(struct sctp_signed_cookie) - | ||
1375 | sizeof(struct sctp_cookie)); | ||
1366 | bodysize = ntohs(chunk->chunk_hdr->length) - headersize; | 1376 | bodysize = ntohs(chunk->chunk_hdr->length) - headersize; |
1367 | fixed_size = headersize + sizeof(struct sctp_cookie); | 1377 | fixed_size = headersize + sizeof(struct sctp_cookie); |
1368 | 1378 | ||
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index b8b38aba92b3..8d1dc24bab4c 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c | |||
@@ -1300,7 +1300,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type, | |||
1300 | "T1 INIT Timeout adjustment" | 1300 | "T1 INIT Timeout adjustment" |
1301 | " init_err_counter: %d" | 1301 | " init_err_counter: %d" |
1302 | " cycle: %d" | 1302 | " cycle: %d" |
1303 | " timeout: %d\n", | 1303 | " timeout: %ld\n", |
1304 | asoc->init_err_counter, | 1304 | asoc->init_err_counter, |
1305 | asoc->init_cycle, | 1305 | asoc->init_cycle, |
1306 | asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT]); | 1306 | asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT]); |
@@ -1328,7 +1328,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type, | |||
1328 | SCTP_DEBUG_PRINTK( | 1328 | SCTP_DEBUG_PRINTK( |
1329 | "T1 COOKIE Timeout adjustment" | 1329 | "T1 COOKIE Timeout adjustment" |
1330 | " init_err_counter: %d" | 1330 | " init_err_counter: %d" |
1331 | " timeout: %d\n", | 1331 | " timeout: %ld\n", |
1332 | asoc->init_err_counter, | 1332 | asoc->init_err_counter, |
1333 | asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE]); | 1333 | asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE]); |
1334 | 1334 | ||
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index 477d7f80dba6..71c9a961c321 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
@@ -3090,6 +3090,8 @@ sctp_disposition_t sctp_sf_ootb(const struct sctp_endpoint *ep, | |||
3090 | break; | 3090 | break; |
3091 | 3091 | ||
3092 | ch_end = ((__u8 *)ch) + WORD_ROUND(ntohs(ch->length)); | 3092 | ch_end = ((__u8 *)ch) + WORD_ROUND(ntohs(ch->length)); |
3093 | if (ch_end > skb->tail) | ||
3094 | break; | ||
3093 | 3095 | ||
3094 | if (SCTP_CID_SHUTDOWN_ACK == ch->type) | 3096 | if (SCTP_CID_SHUTDOWN_ACK == ch->type) |
3095 | ootb_shut_ack = 1; | 3097 | ootb_shut_ack = 1; |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index c98ee375ba5e..fb1821d9f338 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -2995,7 +2995,7 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk) | |||
2995 | sp->hbinterval = jiffies_to_msecs(sctp_hb_interval); | 2995 | sp->hbinterval = jiffies_to_msecs(sctp_hb_interval); |
2996 | sp->pathmaxrxt = sctp_max_retrans_path; | 2996 | sp->pathmaxrxt = sctp_max_retrans_path; |
2997 | sp->pathmtu = 0; // allow default discovery | 2997 | sp->pathmtu = 0; // allow default discovery |
2998 | sp->sackdelay = sctp_sack_timeout; | 2998 | sp->sackdelay = jiffies_to_msecs(sctp_sack_timeout); |
2999 | sp->param_flags = SPP_HB_ENABLE | | 2999 | sp->param_flags = SPP_HB_ENABLE | |
3000 | SPP_PMTUD_ENABLE | | 3000 | SPP_PMTUD_ENABLE | |
3001 | SPP_SACKDELAY_ENABLE; | 3001 | SPP_SACKDELAY_ENABLE; |
@@ -5602,8 +5602,12 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk, | |||
5602 | */ | 5602 | */ |
5603 | newsp->type = type; | 5603 | newsp->type = type; |
5604 | 5604 | ||
5605 | spin_lock_bh(&oldsk->sk_lock.slock); | ||
5606 | /* Migrate the backlog from oldsk to newsk. */ | ||
5607 | sctp_backlog_migrate(assoc, oldsk, newsk); | ||
5605 | /* Migrate the association to the new socket. */ | 5608 | /* Migrate the association to the new socket. */ |
5606 | sctp_assoc_migrate(assoc, newsk); | 5609 | sctp_assoc_migrate(assoc, newsk); |
5610 | spin_unlock_bh(&oldsk->sk_lock.slock); | ||
5607 | 5611 | ||
5608 | /* If the association on the newsk is already closed before accept() | 5612 | /* If the association on the newsk is already closed before accept() |
5609 | * is called, set RCV_SHUTDOWN flag. | 5613 | * is called, set RCV_SHUTDOWN flag. |
diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c index fcd7096c953d..dc6f3ff32358 100644 --- a/net/sctp/sysctl.c +++ b/net/sctp/sysctl.c | |||
@@ -159,12 +159,9 @@ static ctl_table sctp_table[] = { | |||
159 | .ctl_name = NET_SCTP_PRESERVE_ENABLE, | 159 | .ctl_name = NET_SCTP_PRESERVE_ENABLE, |
160 | .procname = "cookie_preserve_enable", | 160 | .procname = "cookie_preserve_enable", |
161 | .data = &sctp_cookie_preserve_enable, | 161 | .data = &sctp_cookie_preserve_enable, |
162 | .maxlen = sizeof(long), | 162 | .maxlen = sizeof(int), |
163 | .mode = 0644, | 163 | .mode = 0644, |
164 | .proc_handler = &proc_doulongvec_ms_jiffies_minmax, | 164 | .proc_handler = &proc_dointvec |
165 | .strategy = &sctp_sysctl_jiffies_ms, | ||
166 | .extra1 = &rto_timer_min, | ||
167 | .extra2 = &rto_timer_max | ||
168 | }, | 165 | }, |
169 | { | 166 | { |
170 | .ctl_name = NET_SCTP_RTO_ALPHA, | 167 | .ctl_name = NET_SCTP_RTO_ALPHA, |
diff --git a/net/sctp/transport.c b/net/sctp/transport.c index 68d73e2dd155..160f62ad1cc5 100644 --- a/net/sctp/transport.c +++ b/net/sctp/transport.c | |||
@@ -350,7 +350,7 @@ void sctp_transport_update_rto(struct sctp_transport *tp, __u32 rtt) | |||
350 | tp->rto_pending = 0; | 350 | tp->rto_pending = 0; |
351 | 351 | ||
352 | SCTP_DEBUG_PRINTK("%s: transport: %p, rtt: %d, srtt: %d " | 352 | SCTP_DEBUG_PRINTK("%s: transport: %p, rtt: %d, srtt: %d " |
353 | "rttvar: %d, rto: %d\n", __FUNCTION__, | 353 | "rttvar: %d, rto: %ld\n", __FUNCTION__, |
354 | tp, rtt, tp->srtt, tp->rttvar, tp->rto); | 354 | tp, rtt, tp->srtt, tp->rttvar, tp->rto); |
355 | } | 355 | } |
356 | 356 | ||