diff options
| -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 | ||
