diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
commit | c71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch) | |
tree | ecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /net/sctp | |
parent | ea53c912f8a86a8567697115b6a0d8152beee5c8 (diff) | |
parent | 6a00f206debf8a5c8899055726ad127dbeeed098 (diff) |
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts:
litmus/sched_cedf.c
Diffstat (limited to 'net/sctp')
-rw-r--r-- | net/sctp/associola.c | 43 | ||||
-rw-r--r-- | net/sctp/auth.c | 6 | ||||
-rw-r--r-- | net/sctp/bind_addr.c | 12 | ||||
-rw-r--r-- | net/sctp/chunk.c | 2 | ||||
-rw-r--r-- | net/sctp/debug.c | 1 | ||||
-rw-r--r-- | net/sctp/endpointola.c | 20 | ||||
-rw-r--r-- | net/sctp/input.c | 24 | ||||
-rw-r--r-- | net/sctp/inqueue.c | 2 | ||||
-rw-r--r-- | net/sctp/ipv6.c | 215 | ||||
-rw-r--r-- | net/sctp/objcnt.c | 5 | ||||
-rw-r--r-- | net/sctp/output.c | 23 | ||||
-rw-r--r-- | net/sctp/outqueue.c | 81 | ||||
-rw-r--r-- | net/sctp/probe.c | 5 | ||||
-rw-r--r-- | net/sctp/proc.c | 4 | ||||
-rw-r--r-- | net/sctp/protocol.c | 119 | ||||
-rw-r--r-- | net/sctp/sm_make_chunk.c | 81 | ||||
-rw-r--r-- | net/sctp/sm_sideeffect.c | 55 | ||||
-rw-r--r-- | net/sctp/sm_statefuns.c | 175 | ||||
-rw-r--r-- | net/sctp/sm_statetable.c | 122 | ||||
-rw-r--r-- | net/sctp/socket.c | 249 | ||||
-rw-r--r-- | net/sctp/sysctl.c | 4 | ||||
-rw-r--r-- | net/sctp/transport.c | 36 | ||||
-rw-r--r-- | net/sctp/tsnmap.c | 2 | ||||
-rw-r--r-- | net/sctp/ulpevent.c | 48 | ||||
-rw-r--r-- | net/sctp/ulpqueue.c | 9 |
25 files changed, 778 insertions, 565 deletions
diff --git a/net/sctp/associola.c b/net/sctp/associola.c index 0b85e5256434..4a62888f2e43 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c | |||
@@ -48,6 +48,8 @@ | |||
48 | * be incorporated into the next SCTP release. | 48 | * be incorporated into the next SCTP release. |
49 | */ | 49 | */ |
50 | 50 | ||
51 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
52 | |||
51 | #include <linux/types.h> | 53 | #include <linux/types.h> |
52 | #include <linux/fcntl.h> | 54 | #include <linux/fcntl.h> |
53 | #include <linux/poll.h> | 55 | #include <linux/poll.h> |
@@ -62,6 +64,7 @@ | |||
62 | /* Forward declarations for internal functions. */ | 64 | /* Forward declarations for internal functions. */ |
63 | static void sctp_assoc_bh_rcv(struct work_struct *work); | 65 | static void sctp_assoc_bh_rcv(struct work_struct *work); |
64 | static void sctp_assoc_free_asconf_acks(struct sctp_association *asoc); | 66 | static void sctp_assoc_free_asconf_acks(struct sctp_association *asoc); |
67 | static void sctp_assoc_free_asconf_queue(struct sctp_association *asoc); | ||
65 | 68 | ||
66 | /* Keep track of the new idr low so that we don't re-use association id | 69 | /* Keep track of the new idr low so that we don't re-use association id |
67 | * numbers too fast. It is protected by they idr spin lock is in the | 70 | * numbers too fast. It is protected by they idr spin lock is in the |
@@ -441,12 +444,7 @@ void sctp_association_free(struct sctp_association *asoc) | |||
441 | 444 | ||
442 | asoc->peer.transport_count = 0; | 445 | asoc->peer.transport_count = 0; |
443 | 446 | ||
444 | /* Free any cached ASCONF_ACK chunk. */ | 447 | sctp_asconf_queue_teardown(asoc); |
445 | sctp_assoc_free_asconf_acks(asoc); | ||
446 | |||
447 | /* Free any cached ASCONF chunk. */ | ||
448 | if (asoc->addip_last_asconf) | ||
449 | sctp_chunk_free(asoc->addip_last_asconf); | ||
450 | 448 | ||
451 | /* AUTH - Free the endpoint shared keys */ | 449 | /* AUTH - Free the endpoint shared keys */ |
452 | sctp_auth_destroy_keys(&asoc->endpoint_shared_keys); | 450 | sctp_auth_destroy_keys(&asoc->endpoint_shared_keys); |
@@ -567,6 +565,8 @@ void sctp_assoc_rm_peer(struct sctp_association *asoc, | |||
567 | sctp_assoc_set_primary(asoc, transport); | 565 | sctp_assoc_set_primary(asoc, transport); |
568 | if (asoc->peer.active_path == peer) | 566 | if (asoc->peer.active_path == peer) |
569 | asoc->peer.active_path = transport; | 567 | asoc->peer.active_path = transport; |
568 | if (asoc->peer.retran_path == peer) | ||
569 | asoc->peer.retran_path = transport; | ||
570 | if (asoc->peer.last_data_from == peer) | 570 | if (asoc->peer.last_data_from == peer) |
571 | asoc->peer.last_data_from = transport; | 571 | asoc->peer.last_data_from = transport; |
572 | 572 | ||
@@ -1087,7 +1087,6 @@ static void sctp_assoc_bh_rcv(struct work_struct *work) | |||
1087 | base.inqueue.immediate); | 1087 | base.inqueue.immediate); |
1088 | struct sctp_endpoint *ep; | 1088 | struct sctp_endpoint *ep; |
1089 | struct sctp_chunk *chunk; | 1089 | struct sctp_chunk *chunk; |
1090 | struct sock *sk; | ||
1091 | struct sctp_inq *inqueue; | 1090 | struct sctp_inq *inqueue; |
1092 | int state; | 1091 | int state; |
1093 | sctp_subtype_t subtype; | 1092 | sctp_subtype_t subtype; |
@@ -1095,7 +1094,6 @@ static void sctp_assoc_bh_rcv(struct work_struct *work) | |||
1095 | 1094 | ||
1096 | /* The association should be held so we should be safe. */ | 1095 | /* The association should be held so we should be safe. */ |
1097 | ep = asoc->ep; | 1096 | ep = asoc->ep; |
1098 | sk = asoc->base.sk; | ||
1099 | 1097 | ||
1100 | inqueue = &asoc->base.inqueue; | 1098 | inqueue = &asoc->base.inqueue; |
1101 | sctp_association_hold(asoc); | 1099 | sctp_association_hold(asoc); |
@@ -1323,6 +1321,8 @@ void sctp_assoc_update_retran_path(struct sctp_association *asoc) | |||
1323 | 1321 | ||
1324 | if (t) | 1322 | if (t) |
1325 | asoc->peer.retran_path = t; | 1323 | asoc->peer.retran_path = t; |
1324 | else | ||
1325 | t = asoc->peer.retran_path; | ||
1326 | 1326 | ||
1327 | SCTP_DEBUG_PRINTK_IPADDR("sctp_assoc_update_retran_path:association" | 1327 | SCTP_DEBUG_PRINTK_IPADDR("sctp_assoc_update_retran_path:association" |
1328 | " %p addr: ", | 1328 | " %p addr: ", |
@@ -1574,6 +1574,18 @@ retry: | |||
1574 | return error; | 1574 | return error; |
1575 | } | 1575 | } |
1576 | 1576 | ||
1577 | /* Free the ASCONF queue */ | ||
1578 | static void sctp_assoc_free_asconf_queue(struct sctp_association *asoc) | ||
1579 | { | ||
1580 | struct sctp_chunk *asconf; | ||
1581 | struct sctp_chunk *tmp; | ||
1582 | |||
1583 | list_for_each_entry_safe(asconf, tmp, &asoc->addip_chunk_list, list) { | ||
1584 | list_del_init(&asconf->list); | ||
1585 | sctp_chunk_free(asconf); | ||
1586 | } | ||
1587 | } | ||
1588 | |||
1577 | /* Free asconf_ack cache */ | 1589 | /* Free asconf_ack cache */ |
1578 | static void sctp_assoc_free_asconf_acks(struct sctp_association *asoc) | 1590 | static void sctp_assoc_free_asconf_acks(struct sctp_association *asoc) |
1579 | { | 1591 | { |
@@ -1593,7 +1605,7 @@ void sctp_assoc_clean_asconf_ack_cache(const struct sctp_association *asoc) | |||
1593 | struct sctp_chunk *ack; | 1605 | struct sctp_chunk *ack; |
1594 | struct sctp_chunk *tmp; | 1606 | struct sctp_chunk *tmp; |
1595 | 1607 | ||
1596 | /* We can remove all the entries from the queue upto | 1608 | /* We can remove all the entries from the queue up to |
1597 | * the "Peer-Sequence-Number". | 1609 | * the "Peer-Sequence-Number". |
1598 | */ | 1610 | */ |
1599 | list_for_each_entry_safe(ack, tmp, &asoc->asconf_ack_list, | 1611 | list_for_each_entry_safe(ack, tmp, &asoc->asconf_ack_list, |
@@ -1626,3 +1638,16 @@ struct sctp_chunk *sctp_assoc_lookup_asconf_ack( | |||
1626 | 1638 | ||
1627 | return NULL; | 1639 | return NULL; |
1628 | } | 1640 | } |
1641 | |||
1642 | void sctp_asconf_queue_teardown(struct sctp_association *asoc) | ||
1643 | { | ||
1644 | /* Free any cached ASCONF_ACK chunk. */ | ||
1645 | sctp_assoc_free_asconf_acks(asoc); | ||
1646 | |||
1647 | /* Free the ASCONF queue. */ | ||
1648 | sctp_assoc_free_asconf_queue(asoc); | ||
1649 | |||
1650 | /* Free any cached ASCONF chunk. */ | ||
1651 | if (asoc->addip_last_asconf) | ||
1652 | sctp_chunk_free(asoc->addip_last_asconf); | ||
1653 | } | ||
diff --git a/net/sctp/auth.c b/net/sctp/auth.c index ddbbf7c81fa1..865e68fef21c 100644 --- a/net/sctp/auth.c +++ b/net/sctp/auth.c | |||
@@ -113,7 +113,7 @@ struct sctp_shared_key *sctp_auth_shkey_create(__u16 key_id, gfp_t gfp) | |||
113 | return new; | 113 | return new; |
114 | } | 114 | } |
115 | 115 | ||
116 | /* Free the shared key stucture */ | 116 | /* Free the shared key structure */ |
117 | static void sctp_auth_shkey_free(struct sctp_shared_key *sh_key) | 117 | static void sctp_auth_shkey_free(struct sctp_shared_key *sh_key) |
118 | { | 118 | { |
119 | BUG_ON(!list_empty(&sh_key->key_list)); | 119 | BUG_ON(!list_empty(&sh_key->key_list)); |
@@ -122,7 +122,7 @@ static void sctp_auth_shkey_free(struct sctp_shared_key *sh_key) | |||
122 | kfree(sh_key); | 122 | kfree(sh_key); |
123 | } | 123 | } |
124 | 124 | ||
125 | /* Destory the entire key list. This is done during the | 125 | /* Destroy the entire key list. This is done during the |
126 | * associon and endpoint free process. | 126 | * associon and endpoint free process. |
127 | */ | 127 | */ |
128 | void sctp_auth_destroy_keys(struct list_head *keys) | 128 | void sctp_auth_destroy_keys(struct list_head *keys) |
@@ -324,7 +324,7 @@ static struct sctp_auth_bytes *sctp_auth_asoc_create_secret( | |||
324 | if (!peer_key_vector || !local_key_vector) | 324 | if (!peer_key_vector || !local_key_vector) |
325 | goto out; | 325 | goto out; |
326 | 326 | ||
327 | /* Figure out the order in wich the key_vectors will be | 327 | /* Figure out the order in which the key_vectors will be |
328 | * added to the endpoint shared key. | 328 | * added to the endpoint shared key. |
329 | * SCTP-AUTH, Section 6.1: | 329 | * SCTP-AUTH, Section 6.1: |
330 | * This is performed by selecting the numerically smaller key | 330 | * This is performed by selecting the numerically smaller key |
diff --git a/net/sctp/bind_addr.c b/net/sctp/bind_addr.c index faf71d179e46..83e3011c19ca 100644 --- a/net/sctp/bind_addr.c +++ b/net/sctp/bind_addr.c | |||
@@ -140,14 +140,12 @@ void sctp_bind_addr_init(struct sctp_bind_addr *bp, __u16 port) | |||
140 | /* Dispose of the address list. */ | 140 | /* Dispose of the address list. */ |
141 | static void sctp_bind_addr_clean(struct sctp_bind_addr *bp) | 141 | static void sctp_bind_addr_clean(struct sctp_bind_addr *bp) |
142 | { | 142 | { |
143 | struct sctp_sockaddr_entry *addr; | 143 | struct sctp_sockaddr_entry *addr, *temp; |
144 | struct list_head *pos, *temp; | ||
145 | 144 | ||
146 | /* Empty the bind address list. */ | 145 | /* Empty the bind address list. */ |
147 | list_for_each_safe(pos, temp, &bp->address_list) { | 146 | list_for_each_entry_safe(addr, temp, &bp->address_list, list) { |
148 | addr = list_entry(pos, struct sctp_sockaddr_entry, list); | 147 | list_del_rcu(&addr->list); |
149 | list_del(pos); | 148 | kfree_rcu(addr, rcu); |
150 | kfree(addr); | ||
151 | SCTP_DBG_OBJCNT_DEC(addr); | 149 | SCTP_DBG_OBJCNT_DEC(addr); |
152 | } | 150 | } |
153 | } | 151 | } |
@@ -219,7 +217,7 @@ int sctp_del_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *del_addr) | |||
219 | } | 217 | } |
220 | 218 | ||
221 | if (found) { | 219 | if (found) { |
222 | call_rcu(&addr->rcu, sctp_local_addr_free); | 220 | kfree_rcu(addr, rcu); |
223 | SCTP_DBG_OBJCNT_DEC(addr); | 221 | SCTP_DBG_OBJCNT_DEC(addr); |
224 | return 0; | 222 | return 0; |
225 | } | 223 | } |
diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c index 476caaf100ed..6c8556459a75 100644 --- a/net/sctp/chunk.c +++ b/net/sctp/chunk.c | |||
@@ -37,6 +37,8 @@ | |||
37 | * be incorporated into the next SCTP release. | 37 | * be incorporated into the next SCTP release. |
38 | */ | 38 | */ |
39 | 39 | ||
40 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
41 | |||
40 | #include <linux/types.h> | 42 | #include <linux/types.h> |
41 | #include <linux/kernel.h> | 43 | #include <linux/kernel.h> |
42 | #include <linux/net.h> | 44 | #include <linux/net.h> |
diff --git a/net/sctp/debug.c b/net/sctp/debug.c index bf24fa697de2..ec997cfe0a7e 100644 --- a/net/sctp/debug.c +++ b/net/sctp/debug.c | |||
@@ -98,7 +98,6 @@ const char *sctp_cname(const sctp_subtype_t cid) | |||
98 | 98 | ||
99 | /* These are printable forms of the states. */ | 99 | /* These are printable forms of the states. */ |
100 | const char *const sctp_state_tbl[SCTP_STATE_NUM_STATES] = { | 100 | const char *const sctp_state_tbl[SCTP_STATE_NUM_STATES] = { |
101 | "STATE_EMPTY", | ||
102 | "STATE_CLOSED", | 101 | "STATE_CLOSED", |
103 | "STATE_COOKIE_WAIT", | 102 | "STATE_COOKIE_WAIT", |
104 | "STATE_COOKIE_ECHOED", | 103 | "STATE_COOKIE_ECHOED", |
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c index e10acc01c75f..c8cc24e282c3 100644 --- a/net/sctp/endpointola.c +++ b/net/sctp/endpointola.c | |||
@@ -325,6 +325,7 @@ static struct sctp_association *__sctp_endpoint_lookup_assoc( | |||
325 | struct sctp_transport **transport) | 325 | struct sctp_transport **transport) |
326 | { | 326 | { |
327 | struct sctp_association *asoc = NULL; | 327 | struct sctp_association *asoc = NULL; |
328 | struct sctp_association *tmp; | ||
328 | struct sctp_transport *t = NULL; | 329 | struct sctp_transport *t = NULL; |
329 | struct sctp_hashbucket *head; | 330 | struct sctp_hashbucket *head; |
330 | struct sctp_ep_common *epb; | 331 | struct sctp_ep_common *epb; |
@@ -333,25 +334,32 @@ static struct sctp_association *__sctp_endpoint_lookup_assoc( | |||
333 | int rport; | 334 | int rport; |
334 | 335 | ||
335 | *transport = NULL; | 336 | *transport = NULL; |
337 | |||
338 | /* If the local port is not set, there can't be any associations | ||
339 | * on this endpoint. | ||
340 | */ | ||
341 | if (!ep->base.bind_addr.port) | ||
342 | goto out; | ||
343 | |||
336 | rport = ntohs(paddr->v4.sin_port); | 344 | rport = ntohs(paddr->v4.sin_port); |
337 | 345 | ||
338 | hash = sctp_assoc_hashfn(ep->base.bind_addr.port, rport); | 346 | hash = sctp_assoc_hashfn(ep->base.bind_addr.port, rport); |
339 | head = &sctp_assoc_hashtable[hash]; | 347 | head = &sctp_assoc_hashtable[hash]; |
340 | read_lock(&head->lock); | 348 | read_lock(&head->lock); |
341 | sctp_for_each_hentry(epb, node, &head->chain) { | 349 | sctp_for_each_hentry(epb, node, &head->chain) { |
342 | asoc = sctp_assoc(epb); | 350 | tmp = sctp_assoc(epb); |
343 | if (asoc->ep != ep || rport != asoc->peer.port) | 351 | if (tmp->ep != ep || rport != tmp->peer.port) |
344 | goto next; | 352 | continue; |
345 | 353 | ||
346 | t = sctp_assoc_lookup_paddr(asoc, paddr); | 354 | t = sctp_assoc_lookup_paddr(tmp, paddr); |
347 | if (t) { | 355 | if (t) { |
356 | asoc = tmp; | ||
348 | *transport = t; | 357 | *transport = t; |
349 | break; | 358 | break; |
350 | } | 359 | } |
351 | next: | ||
352 | asoc = NULL; | ||
353 | } | 360 | } |
354 | read_unlock(&head->lock); | 361 | read_unlock(&head->lock); |
362 | out: | ||
355 | return asoc; | 363 | return asoc; |
356 | } | 364 | } |
357 | 365 | ||
diff --git a/net/sctp/input.c b/net/sctp/input.c index ea2192444ce6..741ed1648838 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c | |||
@@ -565,7 +565,7 @@ void sctp_err_finish(struct sock *sk, struct sctp_association *asoc) | |||
565 | */ | 565 | */ |
566 | void sctp_v4_err(struct sk_buff *skb, __u32 info) | 566 | void sctp_v4_err(struct sk_buff *skb, __u32 info) |
567 | { | 567 | { |
568 | struct iphdr *iph = (struct iphdr *)skb->data; | 568 | const struct iphdr *iph = (const struct iphdr *)skb->data; |
569 | const int ihlen = iph->ihl * 4; | 569 | const int ihlen = iph->ihl * 4; |
570 | const int type = icmp_hdr(skb)->type; | 570 | const int type = icmp_hdr(skb)->type; |
571 | const int code = icmp_hdr(skb)->code; | 571 | const int code = icmp_hdr(skb)->code; |
@@ -661,7 +661,6 @@ static int sctp_rcv_ootb(struct sk_buff *skb) | |||
661 | { | 661 | { |
662 | sctp_chunkhdr_t *ch; | 662 | sctp_chunkhdr_t *ch; |
663 | __u8 *ch_end; | 663 | __u8 *ch_end; |
664 | sctp_errhdr_t *err; | ||
665 | 664 | ||
666 | ch = (sctp_chunkhdr_t *) skb->data; | 665 | ch = (sctp_chunkhdr_t *) skb->data; |
667 | 666 | ||
@@ -697,20 +696,6 @@ static int sctp_rcv_ootb(struct sk_buff *skb) | |||
697 | if (SCTP_CID_INIT == ch->type && (void *)ch != skb->data) | 696 | if (SCTP_CID_INIT == ch->type && (void *)ch != skb->data) |
698 | goto discard; | 697 | goto discard; |
699 | 698 | ||
700 | /* RFC 8.4, 7) If the packet contains a "Stale cookie" ERROR | ||
701 | * or a COOKIE ACK the SCTP Packet should be silently | ||
702 | * discarded. | ||
703 | */ | ||
704 | if (SCTP_CID_COOKIE_ACK == ch->type) | ||
705 | goto discard; | ||
706 | |||
707 | if (SCTP_CID_ERROR == ch->type) { | ||
708 | sctp_walk_errors(err, ch) { | ||
709 | if (SCTP_ERROR_STALE_COOKIE == err->cause) | ||
710 | goto discard; | ||
711 | } | ||
712 | } | ||
713 | |||
714 | ch = (sctp_chunkhdr_t *) ch_end; | 699 | ch = (sctp_chunkhdr_t *) ch_end; |
715 | } while (ch_end < skb_tail_pointer(skb)); | 700 | } while (ch_end < skb_tail_pointer(skb)); |
716 | 701 | ||
@@ -948,14 +933,11 @@ static struct sctp_association *__sctp_rcv_init_lookup(struct sk_buff *skb, | |||
948 | union sctp_addr addr; | 933 | union sctp_addr addr; |
949 | union sctp_addr *paddr = &addr; | 934 | union sctp_addr *paddr = &addr; |
950 | struct sctphdr *sh = sctp_hdr(skb); | 935 | struct sctphdr *sh = sctp_hdr(skb); |
951 | sctp_chunkhdr_t *ch; | ||
952 | union sctp_params params; | 936 | union sctp_params params; |
953 | sctp_init_chunk_t *init; | 937 | sctp_init_chunk_t *init; |
954 | struct sctp_transport *transport; | 938 | struct sctp_transport *transport; |
955 | struct sctp_af *af; | 939 | struct sctp_af *af; |
956 | 940 | ||
957 | ch = (sctp_chunkhdr_t *) skb->data; | ||
958 | |||
959 | /* | 941 | /* |
960 | * This code will NOT touch anything inside the chunk--it is | 942 | * This code will NOT touch anything inside the chunk--it is |
961 | * strictly READ-ONLY. | 943 | * strictly READ-ONLY. |
@@ -1020,7 +1002,7 @@ static struct sctp_association *__sctp_rcv_asconf_lookup( | |||
1020 | /* Skip over the ADDIP header and find the Address parameter */ | 1002 | /* Skip over the ADDIP header and find the Address parameter */ |
1021 | param = (union sctp_addr_param *)(asconf + 1); | 1003 | param = (union sctp_addr_param *)(asconf + 1); |
1022 | 1004 | ||
1023 | af = sctp_get_af_specific(param_type2af(param->v4.param_hdr.type)); | 1005 | af = sctp_get_af_specific(param_type2af(param->p.type)); |
1024 | if (unlikely(!af)) | 1006 | if (unlikely(!af)) |
1025 | return NULL; | 1007 | return NULL; |
1026 | 1008 | ||
@@ -1037,7 +1019,7 @@ static struct sctp_association *__sctp_rcv_asconf_lookup( | |||
1037 | * association. | 1019 | * association. |
1038 | * | 1020 | * |
1039 | * This means that any chunks that can help us identify the association need | 1021 | * This means that any chunks that can help us identify the association need |
1040 | * to be looked at to find this assocation. | 1022 | * to be looked at to find this association. |
1041 | */ | 1023 | */ |
1042 | static struct sctp_association *__sctp_rcv_walk_lookup(struct sk_buff *skb, | 1024 | static struct sctp_association *__sctp_rcv_walk_lookup(struct sk_buff *skb, |
1043 | const union sctp_addr *laddr, | 1025 | const union sctp_addr *laddr, |
diff --git a/net/sctp/inqueue.c b/net/sctp/inqueue.c index ccb6dc48d15b..397296fb156f 100644 --- a/net/sctp/inqueue.c +++ b/net/sctp/inqueue.c | |||
@@ -43,6 +43,8 @@ | |||
43 | * be incorporated into the next SCTP release. | 43 | * be incorporated into the next SCTP release. |
44 | */ | 44 | */ |
45 | 45 | ||
46 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
47 | |||
46 | #include <net/sctp/sctp.h> | 48 | #include <net/sctp/sctp.h> |
47 | #include <net/sctp/sm.h> | 49 | #include <net/sctp/sm.h> |
48 | #include <linux/interrupt.h> | 50 | #include <linux/interrupt.h> |
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index 732689140fb8..0bb0d7cb9f10 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c | |||
@@ -47,6 +47,8 @@ | |||
47 | * be incorporated into the next SCTP release. | 47 | * be incorporated into the next SCTP release. |
48 | */ | 48 | */ |
49 | 49 | ||
50 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
51 | |||
50 | #include <linux/module.h> | 52 | #include <linux/module.h> |
51 | #include <linux/errno.h> | 53 | #include <linux/errno.h> |
52 | #include <linux/types.h> | 54 | #include <linux/types.h> |
@@ -78,6 +80,13 @@ | |||
78 | 80 | ||
79 | #include <asm/uaccess.h> | 81 | #include <asm/uaccess.h> |
80 | 82 | ||
83 | static inline int sctp_v6_addr_match_len(union sctp_addr *s1, | ||
84 | union sctp_addr *s2); | ||
85 | static void sctp_v6_to_addr(union sctp_addr *addr, struct in6_addr *saddr, | ||
86 | __be16 port); | ||
87 | static int sctp_v6_cmp_addr(const union sctp_addr *addr1, | ||
88 | const union sctp_addr *addr2); | ||
89 | |||
81 | /* Event handler for inet6 address addition/deletion events. | 90 | /* Event handler for inet6 address addition/deletion events. |
82 | * The sctp_local_addr_list needs to be protocted by a spin lock since | 91 | * The sctp_local_addr_list needs to be protocted by a spin lock since |
83 | * multiple notifiers (say IPv4 and IPv6) may be running at the same | 92 | * multiple notifiers (say IPv4 and IPv6) may be running at the same |
@@ -121,7 +130,7 @@ static int sctp_inet6addr_event(struct notifier_block *this, unsigned long ev, | |||
121 | } | 130 | } |
122 | spin_unlock_bh(&sctp_local_addr_lock); | 131 | spin_unlock_bh(&sctp_local_addr_lock); |
123 | if (found) | 132 | if (found) |
124 | call_rcu(&addr->rcu, sctp_local_addr_free); | 133 | kfree_rcu(addr, rcu); |
125 | break; | 134 | break; |
126 | } | 135 | } |
127 | 136 | ||
@@ -199,76 +208,146 @@ static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *transport) | |||
199 | { | 208 | { |
200 | struct sock *sk = skb->sk; | 209 | struct sock *sk = skb->sk; |
201 | struct ipv6_pinfo *np = inet6_sk(sk); | 210 | struct ipv6_pinfo *np = inet6_sk(sk); |
202 | struct flowi fl; | 211 | struct flowi6 fl6; |
203 | 212 | ||
204 | memset(&fl, 0, sizeof(fl)); | 213 | memset(&fl6, 0, sizeof(fl6)); |
205 | 214 | ||
206 | fl.proto = sk->sk_protocol; | 215 | fl6.flowi6_proto = sk->sk_protocol; |
207 | 216 | ||
208 | /* Fill in the dest address from the route entry passed with the skb | 217 | /* Fill in the dest address from the route entry passed with the skb |
209 | * and the source address from the transport. | 218 | * and the source address from the transport. |
210 | */ | 219 | */ |
211 | ipv6_addr_copy(&fl.fl6_dst, &transport->ipaddr.v6.sin6_addr); | 220 | ipv6_addr_copy(&fl6.daddr, &transport->ipaddr.v6.sin6_addr); |
212 | ipv6_addr_copy(&fl.fl6_src, &transport->saddr.v6.sin6_addr); | 221 | ipv6_addr_copy(&fl6.saddr, &transport->saddr.v6.sin6_addr); |
213 | 222 | ||
214 | fl.fl6_flowlabel = np->flow_label; | 223 | fl6.flowlabel = np->flow_label; |
215 | IP6_ECN_flow_xmit(sk, fl.fl6_flowlabel); | 224 | IP6_ECN_flow_xmit(sk, fl6.flowlabel); |
216 | if (ipv6_addr_type(&fl.fl6_src) & IPV6_ADDR_LINKLOCAL) | 225 | if (ipv6_addr_type(&fl6.saddr) & IPV6_ADDR_LINKLOCAL) |
217 | fl.oif = transport->saddr.v6.sin6_scope_id; | 226 | fl6.flowi6_oif = transport->saddr.v6.sin6_scope_id; |
218 | else | 227 | else |
219 | fl.oif = sk->sk_bound_dev_if; | 228 | fl6.flowi6_oif = sk->sk_bound_dev_if; |
220 | 229 | ||
221 | if (np->opt && np->opt->srcrt) { | 230 | if (np->opt && np->opt->srcrt) { |
222 | struct rt0_hdr *rt0 = (struct rt0_hdr *) np->opt->srcrt; | 231 | struct rt0_hdr *rt0 = (struct rt0_hdr *) np->opt->srcrt; |
223 | ipv6_addr_copy(&fl.fl6_dst, rt0->addr); | 232 | ipv6_addr_copy(&fl6.daddr, rt0->addr); |
224 | } | 233 | } |
225 | 234 | ||
226 | SCTP_DEBUG_PRINTK("%s: skb:%p, len:%d, src:%pI6 dst:%pI6\n", | 235 | SCTP_DEBUG_PRINTK("%s: skb:%p, len:%d, src:%pI6 dst:%pI6\n", |
227 | __func__, skb, skb->len, | 236 | __func__, skb, skb->len, |
228 | &fl.fl6_src, &fl.fl6_dst); | 237 | &fl6.saddr, &fl6.daddr); |
229 | 238 | ||
230 | SCTP_INC_STATS(SCTP_MIB_OUTSCTPPACKS); | 239 | SCTP_INC_STATS(SCTP_MIB_OUTSCTPPACKS); |
231 | 240 | ||
232 | if (!(transport->param_flags & SPP_PMTUD_ENABLE)) | 241 | if (!(transport->param_flags & SPP_PMTUD_ENABLE)) |
233 | skb->local_df = 1; | 242 | skb->local_df = 1; |
234 | 243 | ||
235 | return ip6_xmit(sk, skb, &fl, np->opt); | 244 | return ip6_xmit(sk, skb, &fl6, np->opt); |
236 | } | 245 | } |
237 | 246 | ||
238 | /* Returns the dst cache entry for the given source and destination ip | 247 | /* Returns the dst cache entry for the given source and destination ip |
239 | * addresses. | 248 | * addresses. |
240 | */ | 249 | */ |
241 | static struct dst_entry *sctp_v6_get_dst(struct sctp_association *asoc, | 250 | static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr, |
242 | union sctp_addr *daddr, | 251 | struct flowi *fl, struct sock *sk) |
243 | union sctp_addr *saddr) | ||
244 | { | 252 | { |
245 | struct dst_entry *dst; | 253 | struct sctp_association *asoc = t->asoc; |
246 | struct flowi fl; | 254 | struct dst_entry *dst = NULL; |
255 | struct flowi6 *fl6 = &fl->u.ip6; | ||
256 | struct sctp_bind_addr *bp; | ||
257 | struct sctp_sockaddr_entry *laddr; | ||
258 | union sctp_addr *baddr = NULL; | ||
259 | union sctp_addr *daddr = &t->ipaddr; | ||
260 | union sctp_addr dst_saddr; | ||
261 | __u8 matchlen = 0; | ||
262 | __u8 bmatchlen; | ||
263 | sctp_scope_t scope; | ||
247 | 264 | ||
248 | memset(&fl, 0, sizeof(fl)); | 265 | memset(fl6, 0, sizeof(struct flowi6)); |
249 | ipv6_addr_copy(&fl.fl6_dst, &daddr->v6.sin6_addr); | 266 | ipv6_addr_copy(&fl6->daddr, &daddr->v6.sin6_addr); |
267 | fl6->fl6_dport = daddr->v6.sin6_port; | ||
268 | fl6->flowi6_proto = IPPROTO_SCTP; | ||
250 | if (ipv6_addr_type(&daddr->v6.sin6_addr) & IPV6_ADDR_LINKLOCAL) | 269 | if (ipv6_addr_type(&daddr->v6.sin6_addr) & IPV6_ADDR_LINKLOCAL) |
251 | fl.oif = daddr->v6.sin6_scope_id; | 270 | fl6->flowi6_oif = daddr->v6.sin6_scope_id; |
252 | 271 | ||
272 | SCTP_DEBUG_PRINTK("%s: DST=%pI6 ", __func__, &fl6->daddr); | ||
253 | 273 | ||
254 | SCTP_DEBUG_PRINTK("%s: DST=%pI6 ", __func__, &fl.fl6_dst); | 274 | if (asoc) |
275 | fl6->fl6_sport = htons(asoc->base.bind_addr.port); | ||
255 | 276 | ||
256 | if (saddr) { | 277 | if (saddr) { |
257 | ipv6_addr_copy(&fl.fl6_src, &saddr->v6.sin6_addr); | 278 | ipv6_addr_copy(&fl6->saddr, &saddr->v6.sin6_addr); |
258 | SCTP_DEBUG_PRINTK("SRC=%pI6 - ", &fl.fl6_src); | 279 | fl6->fl6_sport = saddr->v6.sin6_port; |
280 | SCTP_DEBUG_PRINTK("SRC=%pI6 - ", &fl6->saddr); | ||
281 | } | ||
282 | |||
283 | dst = ip6_dst_lookup_flow(sk, fl6, NULL, false); | ||
284 | if (!asoc || saddr) | ||
285 | goto out; | ||
286 | |||
287 | bp = &asoc->base.bind_addr; | ||
288 | scope = sctp_scope(daddr); | ||
289 | /* ip6_dst_lookup has filled in the fl6->saddr for us. Check | ||
290 | * to see if we can use it. | ||
291 | */ | ||
292 | if (!IS_ERR(dst)) { | ||
293 | /* Walk through the bind address list and look for a bind | ||
294 | * address that matches the source address of the returned dst. | ||
295 | */ | ||
296 | sctp_v6_to_addr(&dst_saddr, &fl6->saddr, htons(bp->port)); | ||
297 | rcu_read_lock(); | ||
298 | list_for_each_entry_rcu(laddr, &bp->address_list, list) { | ||
299 | if (!laddr->valid || (laddr->state != SCTP_ADDR_SRC)) | ||
300 | continue; | ||
301 | |||
302 | /* Do not compare against v4 addrs */ | ||
303 | if ((laddr->a.sa.sa_family == AF_INET6) && | ||
304 | (sctp_v6_cmp_addr(&dst_saddr, &laddr->a))) { | ||
305 | rcu_read_unlock(); | ||
306 | goto out; | ||
307 | } | ||
308 | } | ||
309 | rcu_read_unlock(); | ||
310 | /* None of the bound addresses match the source address of the | ||
311 | * dst. So release it. | ||
312 | */ | ||
313 | dst_release(dst); | ||
314 | dst = NULL; | ||
315 | } | ||
316 | |||
317 | /* Walk through the bind address list and try to get the | ||
318 | * best source address for a given destination. | ||
319 | */ | ||
320 | rcu_read_lock(); | ||
321 | list_for_each_entry_rcu(laddr, &bp->address_list, list) { | ||
322 | if (!laddr->valid && laddr->state != SCTP_ADDR_SRC) | ||
323 | continue; | ||
324 | if ((laddr->a.sa.sa_family == AF_INET6) && | ||
325 | (scope <= sctp_scope(&laddr->a))) { | ||
326 | bmatchlen = sctp_v6_addr_match_len(daddr, &laddr->a); | ||
327 | if (!baddr || (matchlen < bmatchlen)) { | ||
328 | baddr = &laddr->a; | ||
329 | matchlen = bmatchlen; | ||
330 | } | ||
331 | } | ||
332 | } | ||
333 | rcu_read_unlock(); | ||
334 | if (baddr) { | ||
335 | ipv6_addr_copy(&fl6->saddr, &baddr->v6.sin6_addr); | ||
336 | fl6->fl6_sport = baddr->v6.sin6_port; | ||
337 | dst = ip6_dst_lookup_flow(sk, fl6, NULL, false); | ||
259 | } | 338 | } |
260 | 339 | ||
261 | dst = ip6_route_output(&init_net, NULL, &fl); | 340 | out: |
262 | if (!dst->error) { | 341 | if (!IS_ERR(dst)) { |
263 | struct rt6_info *rt; | 342 | struct rt6_info *rt; |
264 | rt = (struct rt6_info *)dst; | 343 | rt = (struct rt6_info *)dst; |
344 | t->dst = dst; | ||
265 | SCTP_DEBUG_PRINTK("rt6_dst:%pI6 rt6_src:%pI6\n", | 345 | SCTP_DEBUG_PRINTK("rt6_dst:%pI6 rt6_src:%pI6\n", |
266 | &rt->rt6i_dst.addr, &rt->rt6i_src.addr); | 346 | &rt->rt6i_dst.addr, &fl6->saddr); |
267 | return dst; | 347 | } else { |
348 | t->dst = NULL; | ||
349 | SCTP_DEBUG_PRINTK("NO ROUTE\n"); | ||
268 | } | 350 | } |
269 | SCTP_DEBUG_PRINTK("NO ROUTE\n"); | ||
270 | dst_release(dst); | ||
271 | return NULL; | ||
272 | } | 351 | } |
273 | 352 | ||
274 | /* Returns the number of consecutive initial bits that match in the 2 ipv6 | 353 | /* Returns the number of consecutive initial bits that match in the 2 ipv6 |
@@ -284,64 +363,18 @@ static inline int sctp_v6_addr_match_len(union sctp_addr *s1, | |||
284 | * and asoc's bind address list. | 363 | * and asoc's bind address list. |
285 | */ | 364 | */ |
286 | static void sctp_v6_get_saddr(struct sctp_sock *sk, | 365 | static void sctp_v6_get_saddr(struct sctp_sock *sk, |
287 | struct sctp_association *asoc, | 366 | struct sctp_transport *t, |
288 | struct dst_entry *dst, | 367 | struct flowi *fl) |
289 | union sctp_addr *daddr, | ||
290 | union sctp_addr *saddr) | ||
291 | { | 368 | { |
292 | struct sctp_bind_addr *bp; | 369 | struct flowi6 *fl6 = &fl->u.ip6; |
293 | struct sctp_sockaddr_entry *laddr; | 370 | union sctp_addr *saddr = &t->saddr; |
294 | sctp_scope_t scope; | ||
295 | union sctp_addr *baddr = NULL; | ||
296 | __u8 matchlen = 0; | ||
297 | __u8 bmatchlen; | ||
298 | 371 | ||
299 | SCTP_DEBUG_PRINTK("%s: asoc:%p dst:%p daddr:%pI6 ", | 372 | SCTP_DEBUG_PRINTK("%s: asoc:%p dst:%p\n", __func__, t->asoc, t->dst); |
300 | __func__, asoc, dst, &daddr->v6.sin6_addr); | ||
301 | |||
302 | if (!asoc) { | ||
303 | ipv6_dev_get_saddr(sock_net(sctp_opt2sk(sk)), | ||
304 | dst ? ip6_dst_idev(dst)->dev : NULL, | ||
305 | &daddr->v6.sin6_addr, | ||
306 | inet6_sk(&sk->inet.sk)->srcprefs, | ||
307 | &saddr->v6.sin6_addr); | ||
308 | SCTP_DEBUG_PRINTK("saddr from ipv6_get_saddr: %pI6\n", | ||
309 | &saddr->v6.sin6_addr); | ||
310 | return; | ||
311 | } | ||
312 | |||
313 | scope = sctp_scope(daddr); | ||
314 | |||
315 | bp = &asoc->base.bind_addr; | ||
316 | 373 | ||
317 | /* Go through the bind address list and find the best source address | 374 | if (t->dst) { |
318 | * that matches the scope of the destination address. | 375 | saddr->v6.sin6_family = AF_INET6; |
319 | */ | 376 | ipv6_addr_copy(&saddr->v6.sin6_addr, &fl6->saddr); |
320 | rcu_read_lock(); | ||
321 | list_for_each_entry_rcu(laddr, &bp->address_list, list) { | ||
322 | if (!laddr->valid) | ||
323 | continue; | ||
324 | if ((laddr->state == SCTP_ADDR_SRC) && | ||
325 | (laddr->a.sa.sa_family == AF_INET6) && | ||
326 | (scope <= sctp_scope(&laddr->a))) { | ||
327 | bmatchlen = sctp_v6_addr_match_len(daddr, &laddr->a); | ||
328 | if (!baddr || (matchlen < bmatchlen)) { | ||
329 | baddr = &laddr->a; | ||
330 | matchlen = bmatchlen; | ||
331 | } | ||
332 | } | ||
333 | } | ||
334 | |||
335 | if (baddr) { | ||
336 | memcpy(saddr, baddr, sizeof(union sctp_addr)); | ||
337 | SCTP_DEBUG_PRINTK("saddr: %pI6\n", &saddr->v6.sin6_addr); | ||
338 | } else { | ||
339 | printk(KERN_ERR "%s: asoc:%p Could not find a valid source " | ||
340 | "address for the dest:%pI6\n", | ||
341 | __func__, asoc, &daddr->v6.sin6_addr); | ||
342 | } | 377 | } |
343 | |||
344 | rcu_read_unlock(); | ||
345 | } | 378 | } |
346 | 379 | ||
347 | /* Make a copy of all potential local addresses. */ | 380 | /* Make a copy of all potential local addresses. */ |
@@ -463,14 +496,13 @@ static int sctp_v6_to_addr_param(const union sctp_addr *addr, | |||
463 | return length; | 496 | return length; |
464 | } | 497 | } |
465 | 498 | ||
466 | /* Initialize a sctp_addr from a dst_entry. */ | 499 | /* Initialize a sctp_addr from struct in6_addr. */ |
467 | static void sctp_v6_dst_saddr(union sctp_addr *addr, struct dst_entry *dst, | 500 | static void sctp_v6_to_addr(union sctp_addr *addr, struct in6_addr *saddr, |
468 | __be16 port) | 501 | __be16 port) |
469 | { | 502 | { |
470 | struct rt6_info *rt = (struct rt6_info *)dst; | ||
471 | addr->sa.sa_family = AF_INET6; | 503 | addr->sa.sa_family = AF_INET6; |
472 | addr->v6.sin6_port = port; | 504 | addr->v6.sin6_port = port; |
473 | ipv6_addr_copy(&addr->v6.sin6_addr, &rt->rt6i_src.addr); | 505 | ipv6_addr_copy(&addr->v6.sin6_addr, saddr); |
474 | } | 506 | } |
475 | 507 | ||
476 | /* Compare addresses exactly. | 508 | /* Compare addresses exactly. |
@@ -529,7 +561,7 @@ static int sctp_v6_is_any(const union sctp_addr *addr) | |||
529 | static int sctp_v6_available(union sctp_addr *addr, struct sctp_sock *sp) | 561 | static int sctp_v6_available(union sctp_addr *addr, struct sctp_sock *sp) |
530 | { | 562 | { |
531 | int type; | 563 | int type; |
532 | struct in6_addr *in6 = (struct in6_addr *)&addr->v6.sin6_addr; | 564 | const struct in6_addr *in6 = (const struct in6_addr *)&addr->v6.sin6_addr; |
533 | 565 | ||
534 | type = ipv6_addr_type(in6); | 566 | type = ipv6_addr_type(in6); |
535 | if (IPV6_ADDR_ANY == type) | 567 | if (IPV6_ADDR_ANY == type) |
@@ -957,7 +989,6 @@ static struct sctp_af sctp_af_inet6 = { | |||
957 | .to_sk_daddr = sctp_v6_to_sk_daddr, | 989 | .to_sk_daddr = sctp_v6_to_sk_daddr, |
958 | .from_addr_param = sctp_v6_from_addr_param, | 990 | .from_addr_param = sctp_v6_from_addr_param, |
959 | .to_addr_param = sctp_v6_to_addr_param, | 991 | .to_addr_param = sctp_v6_to_addr_param, |
960 | .dst_saddr = sctp_v6_dst_saddr, | ||
961 | .cmp_addr = sctp_v6_cmp_addr, | 992 | .cmp_addr = sctp_v6_cmp_addr, |
962 | .scope = sctp_v6_scope, | 993 | .scope = sctp_v6_scope, |
963 | .addr_valid = sctp_v6_addr_valid, | 994 | .addr_valid = sctp_v6_addr_valid, |
diff --git a/net/sctp/objcnt.c b/net/sctp/objcnt.c index f73ec0ea93ba..8ef8e7d9eb61 100644 --- a/net/sctp/objcnt.c +++ b/net/sctp/objcnt.c | |||
@@ -38,6 +38,8 @@ | |||
38 | * be incorporated into the next SCTP release. | 38 | * be incorporated into the next SCTP release. |
39 | */ | 39 | */ |
40 | 40 | ||
41 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
42 | |||
41 | #include <linux/kernel.h> | 43 | #include <linux/kernel.h> |
42 | #include <net/sctp/sctp.h> | 44 | #include <net/sctp/sctp.h> |
43 | 45 | ||
@@ -134,8 +136,7 @@ void sctp_dbg_objcnt_init(void) | |||
134 | ent = proc_create("sctp_dbg_objcnt", 0, | 136 | ent = proc_create("sctp_dbg_objcnt", 0, |
135 | proc_net_sctp, &sctp_objcnt_ops); | 137 | proc_net_sctp, &sctp_objcnt_ops); |
136 | if (!ent) | 138 | if (!ent) |
137 | printk(KERN_WARNING | 139 | pr_warn("sctp_dbg_objcnt: Unable to create /proc entry.\n"); |
138 | "sctp_dbg_objcnt: Unable to create /proc entry.\n"); | ||
139 | } | 140 | } |
140 | 141 | ||
141 | /* Cleanup the objcount entry in the proc filesystem. */ | 142 | /* Cleanup the objcount entry in the proc filesystem. */ |
diff --git a/net/sctp/output.c b/net/sctp/output.c index bcc4590ccaf2..08b3cead6503 100644 --- a/net/sctp/output.c +++ b/net/sctp/output.c | |||
@@ -41,6 +41,8 @@ | |||
41 | * be incorporated into the next SCTP release. | 41 | * be incorporated into the next SCTP release. |
42 | */ | 42 | */ |
43 | 43 | ||
44 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
45 | |||
44 | #include <linux/types.h> | 46 | #include <linux/types.h> |
45 | #include <linux/kernel.h> | 47 | #include <linux/kernel.h> |
46 | #include <linux/wait.h> | 48 | #include <linux/wait.h> |
@@ -498,23 +500,20 @@ int sctp_packet_transmit(struct sctp_packet *packet) | |||
498 | * Note: Adler-32 is no longer applicable, as has been replaced | 500 | * Note: Adler-32 is no longer applicable, as has been replaced |
499 | * by CRC32-C as described in <draft-ietf-tsvwg-sctpcsum-02.txt>. | 501 | * by CRC32-C as described in <draft-ietf-tsvwg-sctpcsum-02.txt>. |
500 | */ | 502 | */ |
501 | if (!sctp_checksum_disable && | 503 | if (!sctp_checksum_disable) { |
502 | !(dst->dev->features & (NETIF_F_NO_CSUM | NETIF_F_SCTP_CSUM))) { | 504 | if (!(dst->dev->features & NETIF_F_SCTP_CSUM)) { |
503 | __u32 crc32 = sctp_start_cksum((__u8 *)sh, cksum_buf_len); | 505 | __u32 crc32 = sctp_start_cksum((__u8 *)sh, cksum_buf_len); |
504 | 506 | ||
505 | /* 3) Put the resultant value into the checksum field in the | 507 | /* 3) Put the resultant value into the checksum field in the |
506 | * common header, and leave the rest of the bits unchanged. | 508 | * common header, and leave the rest of the bits unchanged. |
507 | */ | 509 | */ |
508 | sh->checksum = sctp_end_cksum(crc32); | 510 | sh->checksum = sctp_end_cksum(crc32); |
509 | } else { | 511 | } else { |
510 | if (dst->dev->features & NETIF_F_SCTP_CSUM) { | 512 | /* no need to seed pseudo checksum for SCTP */ |
511 | /* no need to seed psuedo checksum for SCTP */ | ||
512 | nskb->ip_summed = CHECKSUM_PARTIAL; | 513 | nskb->ip_summed = CHECKSUM_PARTIAL; |
513 | nskb->csum_start = (skb_transport_header(nskb) - | 514 | nskb->csum_start = (skb_transport_header(nskb) - |
514 | nskb->head); | 515 | nskb->head); |
515 | nskb->csum_offset = offsetof(struct sctphdr, checksum); | 516 | nskb->csum_offset = offsetof(struct sctphdr, checksum); |
516 | } else { | ||
517 | nskb->ip_summed = CHECKSUM_UNNECESSARY; | ||
518 | } | 517 | } |
519 | } | 518 | } |
520 | 519 | ||
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index c04b2eb59186..d03682109b7a 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c | |||
@@ -46,6 +46,8 @@ | |||
46 | * be incorporated into the next SCTP release. | 46 | * be incorporated into the next SCTP release. |
47 | */ | 47 | */ |
48 | 48 | ||
49 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
50 | |||
49 | #include <linux/types.h> | 51 | #include <linux/types.h> |
50 | #include <linux/list.h> /* For struct list_head */ | 52 | #include <linux/list.h> /* For struct list_head */ |
51 | #include <linux/socket.h> | 53 | #include <linux/socket.h> |
@@ -129,7 +131,8 @@ static inline int sctp_cacc_skip_3_1_d(struct sctp_transport *primary, | |||
129 | static inline int sctp_cacc_skip_3_1_f(struct sctp_transport *transport, | 131 | static inline int sctp_cacc_skip_3_1_f(struct sctp_transport *transport, |
130 | int count_of_newacks) | 132 | int count_of_newacks) |
131 | { | 133 | { |
132 | if (count_of_newacks < 2 && !transport->cacc.cacc_saw_newack) | 134 | if (count_of_newacks < 2 && |
135 | (transport && !transport->cacc.cacc_saw_newack)) | ||
133 | return 1; | 136 | return 1; |
134 | return 0; | 137 | return 0; |
135 | } | 138 | } |
@@ -175,13 +178,13 @@ static inline int sctp_cacc_skip_3_2(struct sctp_transport *primary, __u32 tsn) | |||
175 | * 3) If the missing report count for TSN t is to be | 178 | * 3) If the missing report count for TSN t is to be |
176 | * incremented according to [RFC2960] and | 179 | * incremented according to [RFC2960] and |
177 | * [SCTP_STEWART-2002], and CHANGEOVER_ACTIVE is set, | 180 | * [SCTP_STEWART-2002], and CHANGEOVER_ACTIVE is set, |
178 | * then the sender MUST futher execute steps 3.1 and | 181 | * then the sender MUST further execute steps 3.1 and |
179 | * 3.2 to determine if the missing report count for | 182 | * 3.2 to determine if the missing report count for |
180 | * TSN t SHOULD NOT be incremented. | 183 | * TSN t SHOULD NOT be incremented. |
181 | * | 184 | * |
182 | * 3.3) If 3.1 and 3.2 do not dictate that the missing | 185 | * 3.3) If 3.1 and 3.2 do not dictate that the missing |
183 | * report count for t should not be incremented, then | 186 | * report count for t should not be incremented, then |
184 | * the sender SOULD increment missing report count for | 187 | * the sender SHOULD increment missing report count for |
185 | * t (according to [RFC2960] and [SCTP_STEWART_2002]). | 188 | * t (according to [RFC2960] and [SCTP_STEWART_2002]). |
186 | */ | 189 | */ |
187 | static inline int sctp_cacc_skip(struct sctp_transport *primary, | 190 | static inline int sctp_cacc_skip(struct sctp_transport *primary, |
@@ -317,7 +320,6 @@ int sctp_outq_tail(struct sctp_outq *q, struct sctp_chunk *chunk) | |||
317 | * chunk. | 320 | * chunk. |
318 | */ | 321 | */ |
319 | switch (q->asoc->state) { | 322 | switch (q->asoc->state) { |
320 | case SCTP_STATE_EMPTY: | ||
321 | case SCTP_STATE_CLOSED: | 323 | case SCTP_STATE_CLOSED: |
322 | case SCTP_STATE_SHUTDOWN_PENDING: | 324 | case SCTP_STATE_SHUTDOWN_PENDING: |
323 | case SCTP_STATE_SHUTDOWN_SENT: | 325 | case SCTP_STATE_SHUTDOWN_SENT: |
@@ -543,13 +545,11 @@ static int sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt, | |||
543 | struct sctp_transport *transport = pkt->transport; | 545 | struct sctp_transport *transport = pkt->transport; |
544 | sctp_xmit_t status; | 546 | sctp_xmit_t status; |
545 | struct sctp_chunk *chunk, *chunk1; | 547 | struct sctp_chunk *chunk, *chunk1; |
546 | struct sctp_association *asoc; | ||
547 | int fast_rtx; | 548 | int fast_rtx; |
548 | int error = 0; | 549 | int error = 0; |
549 | int timer = 0; | 550 | int timer = 0; |
550 | int done = 0; | 551 | int done = 0; |
551 | 552 | ||
552 | asoc = q->asoc; | ||
553 | lqueue = &q->retransmit; | 553 | lqueue = &q->retransmit; |
554 | fast_rtx = q->fast_rtx; | 554 | fast_rtx = q->fast_rtx; |
555 | 555 | ||
@@ -577,6 +577,13 @@ static int sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt, | |||
577 | * try to send as much as possible. | 577 | * try to send as much as possible. |
578 | */ | 578 | */ |
579 | list_for_each_entry_safe(chunk, chunk1, lqueue, transmitted_list) { | 579 | list_for_each_entry_safe(chunk, chunk1, lqueue, transmitted_list) { |
580 | /* If the chunk is abandoned, move it to abandoned list. */ | ||
581 | if (sctp_chunk_abandoned(chunk)) { | ||
582 | list_del_init(&chunk->transmitted_list); | ||
583 | sctp_insert_list(&q->abandoned, | ||
584 | &chunk->transmitted_list); | ||
585 | continue; | ||
586 | } | ||
580 | 587 | ||
581 | /* Make sure that Gap Acked TSNs are not retransmitted. A | 588 | /* Make sure that Gap Acked TSNs are not retransmitted. A |
582 | * simple approach is just to move such TSNs out of the | 589 | * simple approach is just to move such TSNs out of the |
@@ -618,9 +625,12 @@ redo: | |||
618 | 625 | ||
619 | /* If we are retransmitting, we should only | 626 | /* If we are retransmitting, we should only |
620 | * send a single packet. | 627 | * send a single packet. |
628 | * Otherwise, try appending this chunk again. | ||
621 | */ | 629 | */ |
622 | if (rtx_timeout || fast_rtx) | 630 | if (rtx_timeout || fast_rtx) |
623 | done = 1; | 631 | done = 1; |
632 | else | ||
633 | goto redo; | ||
624 | 634 | ||
625 | /* Bundle next chunk in the next round. */ | 635 | /* Bundle next chunk in the next round. */ |
626 | break; | 636 | break; |
@@ -843,7 +853,7 @@ static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout) | |||
843 | case SCTP_CID_ECN_CWR: | 853 | case SCTP_CID_ECN_CWR: |
844 | case SCTP_CID_ASCONF_ACK: | 854 | case SCTP_CID_ASCONF_ACK: |
845 | one_packet = 1; | 855 | one_packet = 1; |
846 | /* Fall throught */ | 856 | /* Fall through */ |
847 | 857 | ||
848 | case SCTP_CID_SACK: | 858 | case SCTP_CID_SACK: |
849 | case SCTP_CID_HEARTBEAT: | 859 | case SCTP_CID_HEARTBEAT: |
@@ -1463,23 +1473,23 @@ static void sctp_check_transmitted(struct sctp_outq *q, | |||
1463 | /* Display the end of the | 1473 | /* Display the end of the |
1464 | * current range. | 1474 | * current range. |
1465 | */ | 1475 | */ |
1466 | SCTP_DEBUG_PRINTK("-%08x", | 1476 | SCTP_DEBUG_PRINTK_CONT("-%08x", |
1467 | dbg_last_ack_tsn); | 1477 | dbg_last_ack_tsn); |
1468 | } | 1478 | } |
1469 | 1479 | ||
1470 | /* Start a new range. */ | 1480 | /* Start a new range. */ |
1471 | SCTP_DEBUG_PRINTK(",%08x", tsn); | 1481 | SCTP_DEBUG_PRINTK_CONT(",%08x", tsn); |
1472 | dbg_ack_tsn = tsn; | 1482 | dbg_ack_tsn = tsn; |
1473 | break; | 1483 | break; |
1474 | 1484 | ||
1475 | case 1: /* The last TSN was NOT ACKed. */ | 1485 | case 1: /* The last TSN was NOT ACKed. */ |
1476 | if (dbg_last_kept_tsn != dbg_kept_tsn) { | 1486 | if (dbg_last_kept_tsn != dbg_kept_tsn) { |
1477 | /* Display the end of current range. */ | 1487 | /* Display the end of current range. */ |
1478 | SCTP_DEBUG_PRINTK("-%08x", | 1488 | SCTP_DEBUG_PRINTK_CONT("-%08x", |
1479 | dbg_last_kept_tsn); | 1489 | dbg_last_kept_tsn); |
1480 | } | 1490 | } |
1481 | 1491 | ||
1482 | SCTP_DEBUG_PRINTK("\n"); | 1492 | SCTP_DEBUG_PRINTK_CONT("\n"); |
1483 | 1493 | ||
1484 | /* FALL THROUGH... */ | 1494 | /* FALL THROUGH... */ |
1485 | default: | 1495 | default: |
@@ -1526,18 +1536,18 @@ static void sctp_check_transmitted(struct sctp_outq *q, | |||
1526 | break; | 1536 | break; |
1527 | 1537 | ||
1528 | if (dbg_last_kept_tsn != dbg_kept_tsn) | 1538 | if (dbg_last_kept_tsn != dbg_kept_tsn) |
1529 | SCTP_DEBUG_PRINTK("-%08x", | 1539 | SCTP_DEBUG_PRINTK_CONT("-%08x", |
1530 | dbg_last_kept_tsn); | 1540 | dbg_last_kept_tsn); |
1531 | 1541 | ||
1532 | SCTP_DEBUG_PRINTK(",%08x", tsn); | 1542 | SCTP_DEBUG_PRINTK_CONT(",%08x", tsn); |
1533 | dbg_kept_tsn = tsn; | 1543 | dbg_kept_tsn = tsn; |
1534 | break; | 1544 | break; |
1535 | 1545 | ||
1536 | case 0: | 1546 | case 0: |
1537 | if (dbg_last_ack_tsn != dbg_ack_tsn) | 1547 | if (dbg_last_ack_tsn != dbg_ack_tsn) |
1538 | SCTP_DEBUG_PRINTK("-%08x", | 1548 | SCTP_DEBUG_PRINTK_CONT("-%08x", |
1539 | dbg_last_ack_tsn); | 1549 | dbg_last_ack_tsn); |
1540 | SCTP_DEBUG_PRINTK("\n"); | 1550 | SCTP_DEBUG_PRINTK_CONT("\n"); |
1541 | 1551 | ||
1542 | /* FALL THROUGH... */ | 1552 | /* FALL THROUGH... */ |
1543 | default: | 1553 | default: |
@@ -1556,22 +1566,24 @@ static void sctp_check_transmitted(struct sctp_outq *q, | |||
1556 | switch (dbg_prt_state) { | 1566 | switch (dbg_prt_state) { |
1557 | case 0: | 1567 | case 0: |
1558 | if (dbg_last_ack_tsn != dbg_ack_tsn) { | 1568 | if (dbg_last_ack_tsn != dbg_ack_tsn) { |
1559 | SCTP_DEBUG_PRINTK("-%08x\n", dbg_last_ack_tsn); | 1569 | SCTP_DEBUG_PRINTK_CONT("-%08x\n", dbg_last_ack_tsn); |
1560 | } else { | 1570 | } else { |
1561 | SCTP_DEBUG_PRINTK("\n"); | 1571 | SCTP_DEBUG_PRINTK_CONT("\n"); |
1562 | } | 1572 | } |
1563 | break; | 1573 | break; |
1564 | 1574 | ||
1565 | case 1: | 1575 | case 1: |
1566 | if (dbg_last_kept_tsn != dbg_kept_tsn) { | 1576 | if (dbg_last_kept_tsn != dbg_kept_tsn) { |
1567 | SCTP_DEBUG_PRINTK("-%08x\n", dbg_last_kept_tsn); | 1577 | SCTP_DEBUG_PRINTK_CONT("-%08x\n", dbg_last_kept_tsn); |
1568 | } else { | 1578 | } else { |
1569 | SCTP_DEBUG_PRINTK("\n"); | 1579 | SCTP_DEBUG_PRINTK_CONT("\n"); |
1570 | } | 1580 | } |
1571 | } | 1581 | } |
1572 | #endif /* SCTP_DEBUG */ | 1582 | #endif /* SCTP_DEBUG */ |
1573 | if (transport) { | 1583 | if (transport) { |
1574 | if (bytes_acked) { | 1584 | if (bytes_acked) { |
1585 | struct sctp_association *asoc = transport->asoc; | ||
1586 | |||
1575 | /* We may have counted DATA that was migrated | 1587 | /* We may have counted DATA that was migrated |
1576 | * to this transport due to DEL-IP operation. | 1588 | * to this transport due to DEL-IP operation. |
1577 | * Subtract those bytes, since the were never | 1589 | * Subtract those bytes, since the were never |
@@ -1590,6 +1602,17 @@ static void sctp_check_transmitted(struct sctp_outq *q, | |||
1590 | transport->error_count = 0; | 1602 | transport->error_count = 0; |
1591 | transport->asoc->overall_error_count = 0; | 1603 | transport->asoc->overall_error_count = 0; |
1592 | 1604 | ||
1605 | /* | ||
1606 | * While in SHUTDOWN PENDING, we may have started | ||
1607 | * the T5 shutdown guard timer after reaching the | ||
1608 | * retransmission limit. Stop that timer as soon | ||
1609 | * as the receiver acknowledged any data. | ||
1610 | */ | ||
1611 | if (asoc->state == SCTP_STATE_SHUTDOWN_PENDING && | ||
1612 | del_timer(&asoc->timers | ||
1613 | [SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD])) | ||
1614 | sctp_association_put(asoc); | ||
1615 | |||
1593 | /* Mark the destination transport address as | 1616 | /* Mark the destination transport address as |
1594 | * active if it is not so marked. | 1617 | * active if it is not so marked. |
1595 | */ | 1618 | */ |
@@ -1619,10 +1642,15 @@ static void sctp_check_transmitted(struct sctp_outq *q, | |||
1619 | * A sender is doing zero window probing when the | 1642 | * A sender is doing zero window probing when the |
1620 | * receiver's advertised window is zero, and there is | 1643 | * receiver's advertised window is zero, and there is |
1621 | * only one data chunk in flight to the receiver. | 1644 | * only one data chunk in flight to the receiver. |
1645 | * | ||
1646 | * Allow the association to timeout while in SHUTDOWN | ||
1647 | * PENDING or SHUTDOWN RECEIVED in case the receiver | ||
1648 | * stays in zero window mode forever. | ||
1622 | */ | 1649 | */ |
1623 | if (!q->asoc->peer.rwnd && | 1650 | if (!q->asoc->peer.rwnd && |
1624 | !list_empty(&tlist) && | 1651 | !list_empty(&tlist) && |
1625 | (sack_ctsn+2 == q->asoc->next_tsn)) { | 1652 | (sack_ctsn+2 == q->asoc->next_tsn) && |
1653 | q->asoc->state < SCTP_STATE_SHUTDOWN_PENDING) { | ||
1626 | SCTP_DEBUG_PRINTK("%s: SACK received for zero " | 1654 | SCTP_DEBUG_PRINTK("%s: SACK received for zero " |
1627 | "window probe: %u\n", | 1655 | "window probe: %u\n", |
1628 | __func__, sack_ctsn); | 1656 | __func__, sack_ctsn); |
@@ -1683,8 +1711,9 @@ static void sctp_mark_missing(struct sctp_outq *q, | |||
1683 | /* SFR-CACC may require us to skip marking | 1711 | /* SFR-CACC may require us to skip marking |
1684 | * this chunk as missing. | 1712 | * this chunk as missing. |
1685 | */ | 1713 | */ |
1686 | if (!transport || !sctp_cacc_skip(primary, transport, | 1714 | if (!transport || !sctp_cacc_skip(primary, |
1687 | count_of_newacks, tsn)) { | 1715 | chunk->transport, |
1716 | count_of_newacks, tsn)) { | ||
1688 | chunk->tsn_missing_report++; | 1717 | chunk->tsn_missing_report++; |
1689 | 1718 | ||
1690 | SCTP_DEBUG_PRINTK( | 1719 | SCTP_DEBUG_PRINTK( |
diff --git a/net/sctp/probe.c b/net/sctp/probe.c index db3a42b8b349..bc6cd75cc1dc 100644 --- a/net/sctp/probe.c +++ b/net/sctp/probe.c | |||
@@ -22,6 +22,8 @@ | |||
22 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 22 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
23 | */ | 23 | */ |
24 | 24 | ||
25 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
26 | |||
25 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
26 | #include <linux/kprobes.h> | 28 | #include <linux/kprobes.h> |
27 | #include <linux/socket.h> | 29 | #include <linux/socket.h> |
@@ -117,6 +119,7 @@ static const struct file_operations sctpprobe_fops = { | |||
117 | .owner = THIS_MODULE, | 119 | .owner = THIS_MODULE, |
118 | .open = sctpprobe_open, | 120 | .open = sctpprobe_open, |
119 | .read = sctpprobe_read, | 121 | .read = sctpprobe_read, |
122 | .llseek = noop_llseek, | ||
120 | }; | 123 | }; |
121 | 124 | ||
122 | sctp_disposition_t jsctp_sf_eat_sack(const struct sctp_endpoint *ep, | 125 | sctp_disposition_t jsctp_sf_eat_sack(const struct sctp_endpoint *ep, |
@@ -192,7 +195,7 @@ static __init int sctpprobe_init(void) | |||
192 | if (ret) | 195 | if (ret) |
193 | goto remove_proc; | 196 | goto remove_proc; |
194 | 197 | ||
195 | pr_info("SCTP probe registered (port=%d)\n", port); | 198 | pr_info("probe registered (port=%d)\n", port); |
196 | 199 | ||
197 | return 0; | 200 | return 0; |
198 | 201 | ||
diff --git a/net/sctp/proc.c b/net/sctp/proc.c index 61aacfbbaa92..05a6ce214714 100644 --- a/net/sctp/proc.c +++ b/net/sctp/proc.c | |||
@@ -212,7 +212,7 @@ static int sctp_eps_seq_show(struct seq_file *seq, void *v) | |||
212 | sctp_for_each_hentry(epb, node, &head->chain) { | 212 | sctp_for_each_hentry(epb, node, &head->chain) { |
213 | ep = sctp_ep(epb); | 213 | ep = sctp_ep(epb); |
214 | sk = epb->sk; | 214 | sk = epb->sk; |
215 | seq_printf(seq, "%8p %8p %-3d %-3d %-4d %-5d %5d %5lu ", ep, sk, | 215 | seq_printf(seq, "%8pK %8pK %-3d %-3d %-4d %-5d %5d %5lu ", ep, sk, |
216 | sctp_sk(sk)->type, sk->sk_state, hash, | 216 | sctp_sk(sk)->type, sk->sk_state, hash, |
217 | epb->bind_addr.port, | 217 | epb->bind_addr.port, |
218 | sock_i_uid(sk), sock_i_ino(sk)); | 218 | sock_i_uid(sk), sock_i_ino(sk)); |
@@ -316,7 +316,7 @@ static int sctp_assocs_seq_show(struct seq_file *seq, void *v) | |||
316 | assoc = sctp_assoc(epb); | 316 | assoc = sctp_assoc(epb); |
317 | sk = epb->sk; | 317 | sk = epb->sk; |
318 | seq_printf(seq, | 318 | seq_printf(seq, |
319 | "%8p %8p %-3d %-3d %-2d %-4d " | 319 | "%8pK %8pK %-3d %-3d %-2d %-4d " |
320 | "%4d %8d %8d %7d %5lu %-5d %5d ", | 320 | "%4d %8d %8d %7d %5lu %-5d %5d ", |
321 | assoc, sk, sctp_sk(sk)->type, sk->sk_state, | 321 | assoc, sk, sctp_sk(sk)->type, sk->sk_state, |
322 | assoc->state, hash, | 322 | assoc->state, hash, |
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 5027b83f1cc0..207175b2f40a 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c | |||
@@ -46,6 +46,8 @@ | |||
46 | * be incorporated into the next SCTP release. | 46 | * be incorporated into the next SCTP release. |
47 | */ | 47 | */ |
48 | 48 | ||
49 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
50 | |||
49 | #include <linux/module.h> | 51 | #include <linux/module.h> |
50 | #include <linux/init.h> | 52 | #include <linux/init.h> |
51 | #include <linux/netdevice.h> | 53 | #include <linux/netdevice.h> |
@@ -90,7 +92,7 @@ static struct sctp_af *sctp_af_v6_specific; | |||
90 | struct kmem_cache *sctp_chunk_cachep __read_mostly; | 92 | struct kmem_cache *sctp_chunk_cachep __read_mostly; |
91 | struct kmem_cache *sctp_bucket_cachep __read_mostly; | 93 | struct kmem_cache *sctp_bucket_cachep __read_mostly; |
92 | 94 | ||
93 | int sysctl_sctp_mem[3]; | 95 | long sysctl_sctp_mem[3]; |
94 | int sysctl_sctp_rmem[3]; | 96 | int sysctl_sctp_rmem[3]; |
95 | int sysctl_sctp_wmem[3]; | 97 | int sysctl_sctp_wmem[3]; |
96 | 98 | ||
@@ -228,13 +230,6 @@ static void sctp_free_local_addr_list(void) | |||
228 | } | 230 | } |
229 | } | 231 | } |
230 | 232 | ||
231 | void sctp_local_addr_free(struct rcu_head *head) | ||
232 | { | ||
233 | struct sctp_sockaddr_entry *e = container_of(head, | ||
234 | struct sctp_sockaddr_entry, rcu); | ||
235 | kfree(e); | ||
236 | } | ||
237 | |||
238 | /* Copy the local addresses which are valid for 'scope' into 'bp'. */ | 233 | /* Copy the local addresses which are valid for 'scope' into 'bp'. */ |
239 | int sctp_copy_local_addr_list(struct sctp_bind_addr *bp, sctp_scope_t scope, | 234 | int sctp_copy_local_addr_list(struct sctp_bind_addr *bp, sctp_scope_t scope, |
240 | gfp_t gfp, int copy_flags) | 235 | gfp_t gfp, int copy_flags) |
@@ -337,13 +332,12 @@ static int sctp_v4_to_addr_param(const union sctp_addr *addr, | |||
337 | } | 332 | } |
338 | 333 | ||
339 | /* Initialize a sctp_addr from a dst_entry. */ | 334 | /* Initialize a sctp_addr from a dst_entry. */ |
340 | static void sctp_v4_dst_saddr(union sctp_addr *saddr, struct dst_entry *dst, | 335 | static void sctp_v4_dst_saddr(union sctp_addr *saddr, struct flowi4 *fl4, |
341 | __be16 port) | 336 | __be16 port) |
342 | { | 337 | { |
343 | struct rtable *rt = (struct rtable *)dst; | ||
344 | saddr->v4.sin_family = AF_INET; | 338 | saddr->v4.sin_family = AF_INET; |
345 | saddr->v4.sin_port = port; | 339 | saddr->v4.sin_port = port; |
346 | saddr->v4.sin_addr.s_addr = rt->rt_src; | 340 | saddr->v4.sin_addr.s_addr = fl4->saddr; |
347 | } | 341 | } |
348 | 342 | ||
349 | /* Compare two addresses exactly. */ | 343 | /* Compare two addresses exactly. */ |
@@ -461,37 +455,38 @@ static sctp_scope_t sctp_v4_scope(union sctp_addr *addr) | |||
461 | * addresses. If an association is passed, trys to get a dst entry with a | 455 | * addresses. If an association is passed, trys to get a dst entry with a |
462 | * source address that matches an address in the bind address list. | 456 | * source address that matches an address in the bind address list. |
463 | */ | 457 | */ |
464 | static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc, | 458 | static void sctp_v4_get_dst(struct sctp_transport *t, union sctp_addr *saddr, |
465 | union sctp_addr *daddr, | 459 | struct flowi *fl, struct sock *sk) |
466 | union sctp_addr *saddr) | ||
467 | { | 460 | { |
461 | struct sctp_association *asoc = t->asoc; | ||
468 | struct rtable *rt; | 462 | struct rtable *rt; |
469 | struct flowi fl; | 463 | struct flowi4 *fl4 = &fl->u.ip4; |
470 | struct sctp_bind_addr *bp; | 464 | struct sctp_bind_addr *bp; |
471 | struct sctp_sockaddr_entry *laddr; | 465 | struct sctp_sockaddr_entry *laddr; |
472 | struct dst_entry *dst = NULL; | 466 | struct dst_entry *dst = NULL; |
467 | union sctp_addr *daddr = &t->ipaddr; | ||
473 | union sctp_addr dst_saddr; | 468 | union sctp_addr dst_saddr; |
474 | 469 | ||
475 | memset(&fl, 0x0, sizeof(struct flowi)); | 470 | memset(fl4, 0x0, sizeof(struct flowi4)); |
476 | fl.fl4_dst = daddr->v4.sin_addr.s_addr; | 471 | fl4->daddr = daddr->v4.sin_addr.s_addr; |
477 | fl.fl_ip_dport = daddr->v4.sin_port; | 472 | fl4->fl4_dport = daddr->v4.sin_port; |
478 | fl.proto = IPPROTO_SCTP; | 473 | fl4->flowi4_proto = IPPROTO_SCTP; |
479 | if (asoc) { | 474 | if (asoc) { |
480 | fl.fl4_tos = RT_CONN_FLAGS(asoc->base.sk); | 475 | fl4->flowi4_tos = RT_CONN_FLAGS(asoc->base.sk); |
481 | fl.oif = asoc->base.sk->sk_bound_dev_if; | 476 | fl4->flowi4_oif = asoc->base.sk->sk_bound_dev_if; |
482 | fl.fl_ip_sport = htons(asoc->base.bind_addr.port); | 477 | fl4->fl4_sport = htons(asoc->base.bind_addr.port); |
483 | } | 478 | } |
484 | if (saddr) { | 479 | if (saddr) { |
485 | fl.fl4_src = saddr->v4.sin_addr.s_addr; | 480 | fl4->saddr = saddr->v4.sin_addr.s_addr; |
486 | fl.fl_ip_sport = saddr->v4.sin_port; | 481 | fl4->fl4_sport = saddr->v4.sin_port; |
487 | } | 482 | } |
488 | 483 | ||
489 | SCTP_DEBUG_PRINTK("%s: DST:%pI4, SRC:%pI4 - ", | 484 | SCTP_DEBUG_PRINTK("%s: DST:%pI4, SRC:%pI4 - ", |
490 | __func__, &fl.fl4_dst, &fl.fl4_src); | 485 | __func__, &fl4->daddr, &fl4->saddr); |
491 | 486 | ||
492 | if (!ip_route_output_key(&init_net, &rt, &fl)) { | 487 | rt = ip_route_output_key(&init_net, fl4); |
488 | if (!IS_ERR(rt)) | ||
493 | dst = &rt->dst; | 489 | dst = &rt->dst; |
494 | } | ||
495 | 490 | ||
496 | /* If there is no association or if a source address is passed, no | 491 | /* If there is no association or if a source address is passed, no |
497 | * more validation is required. | 492 | * more validation is required. |
@@ -505,7 +500,7 @@ static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc, | |||
505 | /* Walk through the bind address list and look for a bind | 500 | /* Walk through the bind address list and look for a bind |
506 | * address that matches the source address of the returned dst. | 501 | * address that matches the source address of the returned dst. |
507 | */ | 502 | */ |
508 | sctp_v4_dst_saddr(&dst_saddr, dst, htons(bp->port)); | 503 | sctp_v4_dst_saddr(&dst_saddr, fl4, htons(bp->port)); |
509 | rcu_read_lock(); | 504 | rcu_read_lock(); |
510 | list_for_each_entry_rcu(laddr, &bp->address_list, list) { | 505 | list_for_each_entry_rcu(laddr, &bp->address_list, list) { |
511 | if (!laddr->valid || (laddr->state != SCTP_ADDR_SRC)) | 506 | if (!laddr->valid || (laddr->state != SCTP_ADDR_SRC)) |
@@ -531,9 +526,10 @@ static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc, | |||
531 | continue; | 526 | continue; |
532 | if ((laddr->state == SCTP_ADDR_SRC) && | 527 | if ((laddr->state == SCTP_ADDR_SRC) && |
533 | (AF_INET == laddr->a.sa.sa_family)) { | 528 | (AF_INET == laddr->a.sa.sa_family)) { |
534 | fl.fl4_src = laddr->a.v4.sin_addr.s_addr; | 529 | fl4->saddr = laddr->a.v4.sin_addr.s_addr; |
535 | fl.fl_ip_sport = laddr->a.v4.sin_port; | 530 | fl4->fl4_sport = laddr->a.v4.sin_port; |
536 | if (!ip_route_output_key(&init_net, &rt, &fl)) { | 531 | rt = ip_route_output_key(&init_net, fl4); |
532 | if (!IS_ERR(rt)) { | ||
537 | dst = &rt->dst; | 533 | dst = &rt->dst; |
538 | goto out_unlock; | 534 | goto out_unlock; |
539 | } | 535 | } |
@@ -543,33 +539,27 @@ static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc, | |||
543 | out_unlock: | 539 | out_unlock: |
544 | rcu_read_unlock(); | 540 | rcu_read_unlock(); |
545 | out: | 541 | out: |
542 | t->dst = dst; | ||
546 | if (dst) | 543 | if (dst) |
547 | SCTP_DEBUG_PRINTK("rt_dst:%pI4, rt_src:%pI4\n", | 544 | SCTP_DEBUG_PRINTK("rt_dst:%pI4, rt_src:%pI4\n", |
548 | &rt->rt_dst, &rt->rt_src); | 545 | &fl4->daddr, &fl4->saddr); |
549 | else | 546 | else |
550 | SCTP_DEBUG_PRINTK("NO ROUTE\n"); | 547 | SCTP_DEBUG_PRINTK("NO ROUTE\n"); |
551 | |||
552 | return dst; | ||
553 | } | 548 | } |
554 | 549 | ||
555 | /* For v4, the source address is cached in the route entry(dst). So no need | 550 | /* For v4, the source address is cached in the route entry(dst). So no need |
556 | * to cache it separately and hence this is an empty routine. | 551 | * to cache it separately and hence this is an empty routine. |
557 | */ | 552 | */ |
558 | static void sctp_v4_get_saddr(struct sctp_sock *sk, | 553 | static void sctp_v4_get_saddr(struct sctp_sock *sk, |
559 | struct sctp_association *asoc, | 554 | struct sctp_transport *t, |
560 | struct dst_entry *dst, | 555 | struct flowi *fl) |
561 | union sctp_addr *daddr, | ||
562 | union sctp_addr *saddr) | ||
563 | { | 556 | { |
564 | struct rtable *rt = (struct rtable *)dst; | 557 | union sctp_addr *saddr = &t->saddr; |
565 | 558 | struct rtable *rt = (struct rtable *)t->dst; | |
566 | if (!asoc) | ||
567 | return; | ||
568 | 559 | ||
569 | if (rt) { | 560 | if (rt) { |
570 | saddr->v4.sin_family = AF_INET; | 561 | saddr->v4.sin_family = AF_INET; |
571 | saddr->v4.sin_port = htons(asoc->base.bind_addr.port); | 562 | saddr->v4.sin_addr.s_addr = fl->u.ip4.saddr; |
572 | saddr->v4.sin_addr.s_addr = rt->rt_src; | ||
573 | } | 563 | } |
574 | } | 564 | } |
575 | 565 | ||
@@ -678,7 +668,7 @@ static int sctp_inetaddr_event(struct notifier_block *this, unsigned long ev, | |||
678 | } | 668 | } |
679 | spin_unlock_bh(&sctp_local_addr_lock); | 669 | spin_unlock_bh(&sctp_local_addr_lock); |
680 | if (found) | 670 | if (found) |
681 | call_rcu(&addr->rcu, sctp_local_addr_free); | 671 | kfree_rcu(addr, rcu); |
682 | break; | 672 | break; |
683 | } | 673 | } |
684 | 674 | ||
@@ -707,8 +697,7 @@ static int sctp_ctl_sock_init(void) | |||
707 | &init_net); | 697 | &init_net); |
708 | 698 | ||
709 | if (err < 0) { | 699 | if (err < 0) { |
710 | printk(KERN_ERR | 700 | pr_err("Failed to create the SCTP control socket\n"); |
711 | "SCTP: Failed to create the SCTP control socket.\n"); | ||
712 | return err; | 701 | return err; |
713 | } | 702 | } |
714 | return 0; | 703 | return 0; |
@@ -798,7 +787,7 @@ static void sctp_inet_skb_msgname(struct sk_buff *skb, char *msgname, int *len) | |||
798 | static int sctp_inet_af_supported(sa_family_t family, struct sctp_sock *sp) | 787 | static int sctp_inet_af_supported(sa_family_t family, struct sctp_sock *sp) |
799 | { | 788 | { |
800 | /* PF_INET only supports AF_INET addresses. */ | 789 | /* PF_INET only supports AF_INET addresses. */ |
801 | return (AF_INET == family); | 790 | return AF_INET == family; |
802 | } | 791 | } |
803 | 792 | ||
804 | /* Address matching with wildcards allowed. */ | 793 | /* Address matching with wildcards allowed. */ |
@@ -852,14 +841,14 @@ static inline int sctp_v4_xmit(struct sk_buff *skb, | |||
852 | 841 | ||
853 | SCTP_DEBUG_PRINTK("%s: skb:%p, len:%d, src:%pI4, dst:%pI4\n", | 842 | SCTP_DEBUG_PRINTK("%s: skb:%p, len:%d, src:%pI4, dst:%pI4\n", |
854 | __func__, skb, skb->len, | 843 | __func__, skb, skb->len, |
855 | &skb_rtable(skb)->rt_src, | 844 | &transport->fl.u.ip4.saddr, |
856 | &skb_rtable(skb)->rt_dst); | 845 | &transport->fl.u.ip4.daddr); |
857 | 846 | ||
858 | inet->pmtudisc = transport->param_flags & SPP_PMTUD_ENABLE ? | 847 | inet->pmtudisc = transport->param_flags & SPP_PMTUD_ENABLE ? |
859 | IP_PMTUDISC_DO : IP_PMTUDISC_DONT; | 848 | IP_PMTUDISC_DO : IP_PMTUDISC_DONT; |
860 | 849 | ||
861 | SCTP_INC_STATS(SCTP_MIB_OUTSCTPPACKS); | 850 | SCTP_INC_STATS(SCTP_MIB_OUTSCTPPACKS); |
862 | return ip_queue_xmit(skb); | 851 | return ip_queue_xmit(skb, &transport->fl); |
863 | } | 852 | } |
864 | 853 | ||
865 | static struct sctp_af sctp_af_inet; | 854 | static struct sctp_af sctp_af_inet; |
@@ -948,7 +937,6 @@ static struct sctp_af sctp_af_inet = { | |||
948 | .to_sk_daddr = sctp_v4_to_sk_daddr, | 937 | .to_sk_daddr = sctp_v4_to_sk_daddr, |
949 | .from_addr_param = sctp_v4_from_addr_param, | 938 | .from_addr_param = sctp_v4_from_addr_param, |
950 | .to_addr_param = sctp_v4_to_addr_param, | 939 | .to_addr_param = sctp_v4_to_addr_param, |
951 | .dst_saddr = sctp_v4_dst_saddr, | ||
952 | .cmp_addr = sctp_v4_cmp_addr, | 940 | .cmp_addr = sctp_v4_cmp_addr, |
953 | .addr_valid = sctp_v4_addr_valid, | 941 | .addr_valid = sctp_v4_addr_valid, |
954 | .inaddr_any = sctp_v4_inaddr_any, | 942 | .inaddr_any = sctp_v4_inaddr_any, |
@@ -1070,7 +1058,6 @@ SCTP_STATIC __init int sctp_init(void) | |||
1070 | int status = -EINVAL; | 1058 | int status = -EINVAL; |
1071 | unsigned long goal; | 1059 | unsigned long goal; |
1072 | unsigned long limit; | 1060 | unsigned long limit; |
1073 | unsigned long nr_pages; | ||
1074 | int max_share; | 1061 | int max_share; |
1075 | int order; | 1062 | int order; |
1076 | 1063 | ||
@@ -1160,15 +1147,7 @@ SCTP_STATIC __init int sctp_init(void) | |||
1160 | /* Initialize handle used for association ids. */ | 1147 | /* Initialize handle used for association ids. */ |
1161 | idr_init(&sctp_assocs_id); | 1148 | idr_init(&sctp_assocs_id); |
1162 | 1149 | ||
1163 | /* Set the pressure threshold to be a fraction of global memory that | 1150 | limit = nr_free_buffer_pages() / 8; |
1164 | * is up to 1/2 at 256 MB, decreasing toward zero with the amount of | ||
1165 | * memory, with a floor of 128 pages. | ||
1166 | * Note this initializes the data in sctpv6_prot too | ||
1167 | * Unabashedly stolen from tcp_init | ||
1168 | */ | ||
1169 | nr_pages = totalram_pages - totalhigh_pages; | ||
1170 | limit = min(nr_pages, 1UL<<(28-PAGE_SHIFT)) >> (20-PAGE_SHIFT); | ||
1171 | limit = (limit * (nr_pages >> (20-PAGE_SHIFT))) >> (PAGE_SHIFT-11); | ||
1172 | limit = max(limit, 128UL); | 1151 | limit = max(limit, 128UL); |
1173 | sysctl_sctp_mem[0] = limit / 4 * 3; | 1152 | sysctl_sctp_mem[0] = limit / 4 * 3; |
1174 | sysctl_sctp_mem[1] = limit; | 1153 | sysctl_sctp_mem[1] = limit; |
@@ -1203,10 +1182,10 @@ SCTP_STATIC __init int sctp_init(void) | |||
1203 | if ((sctp_assoc_hashsize > (64 * 1024)) && order > 0) | 1182 | if ((sctp_assoc_hashsize > (64 * 1024)) && order > 0) |
1204 | continue; | 1183 | continue; |
1205 | sctp_assoc_hashtable = (struct sctp_hashbucket *) | 1184 | sctp_assoc_hashtable = (struct sctp_hashbucket *) |
1206 | __get_free_pages(GFP_ATOMIC, order); | 1185 | __get_free_pages(GFP_ATOMIC|__GFP_NOWARN, order); |
1207 | } while (!sctp_assoc_hashtable && --order > 0); | 1186 | } while (!sctp_assoc_hashtable && --order > 0); |
1208 | if (!sctp_assoc_hashtable) { | 1187 | if (!sctp_assoc_hashtable) { |
1209 | printk(KERN_ERR "SCTP: Failed association hash alloc.\n"); | 1188 | pr_err("Failed association hash alloc\n"); |
1210 | status = -ENOMEM; | 1189 | status = -ENOMEM; |
1211 | goto err_ahash_alloc; | 1190 | goto err_ahash_alloc; |
1212 | } | 1191 | } |
@@ -1220,7 +1199,7 @@ SCTP_STATIC __init int sctp_init(void) | |||
1220 | sctp_ep_hashtable = (struct sctp_hashbucket *) | 1199 | sctp_ep_hashtable = (struct sctp_hashbucket *) |
1221 | kmalloc(64 * sizeof(struct sctp_hashbucket), GFP_KERNEL); | 1200 | kmalloc(64 * sizeof(struct sctp_hashbucket), GFP_KERNEL); |
1222 | if (!sctp_ep_hashtable) { | 1201 | if (!sctp_ep_hashtable) { |
1223 | printk(KERN_ERR "SCTP: Failed endpoint_hash alloc.\n"); | 1202 | pr_err("Failed endpoint_hash alloc\n"); |
1224 | status = -ENOMEM; | 1203 | status = -ENOMEM; |
1225 | goto err_ehash_alloc; | 1204 | goto err_ehash_alloc; |
1226 | } | 1205 | } |
@@ -1236,10 +1215,10 @@ SCTP_STATIC __init int sctp_init(void) | |||
1236 | if ((sctp_port_hashsize > (64 * 1024)) && order > 0) | 1215 | if ((sctp_port_hashsize > (64 * 1024)) && order > 0) |
1237 | continue; | 1216 | continue; |
1238 | sctp_port_hashtable = (struct sctp_bind_hashbucket *) | 1217 | sctp_port_hashtable = (struct sctp_bind_hashbucket *) |
1239 | __get_free_pages(GFP_ATOMIC, order); | 1218 | __get_free_pages(GFP_ATOMIC|__GFP_NOWARN, order); |
1240 | } while (!sctp_port_hashtable && --order > 0); | 1219 | } while (!sctp_port_hashtable && --order > 0); |
1241 | if (!sctp_port_hashtable) { | 1220 | if (!sctp_port_hashtable) { |
1242 | printk(KERN_ERR "SCTP: Failed bind hash alloc."); | 1221 | pr_err("Failed bind hash alloc\n"); |
1243 | status = -ENOMEM; | 1222 | status = -ENOMEM; |
1244 | goto err_bhash_alloc; | 1223 | goto err_bhash_alloc; |
1245 | } | 1224 | } |
@@ -1248,8 +1227,7 @@ SCTP_STATIC __init int sctp_init(void) | |||
1248 | INIT_HLIST_HEAD(&sctp_port_hashtable[i].chain); | 1227 | INIT_HLIST_HEAD(&sctp_port_hashtable[i].chain); |
1249 | } | 1228 | } |
1250 | 1229 | ||
1251 | printk(KERN_INFO "SCTP: Hash tables configured " | 1230 | pr_info("Hash tables configured (established %d bind %d)\n", |
1252 | "(established %d bind %d)\n", | ||
1253 | sctp_assoc_hashsize, sctp_port_hashsize); | 1231 | sctp_assoc_hashsize, sctp_port_hashsize); |
1254 | 1232 | ||
1255 | /* Disable ADDIP by default. */ | 1233 | /* Disable ADDIP by default. */ |
@@ -1290,8 +1268,7 @@ SCTP_STATIC __init int sctp_init(void) | |||
1290 | 1268 | ||
1291 | /* Initialize the control inode/socket for handling OOTB packets. */ | 1269 | /* Initialize the control inode/socket for handling OOTB packets. */ |
1292 | if ((status = sctp_ctl_sock_init())) { | 1270 | if ((status = sctp_ctl_sock_init())) { |
1293 | printk (KERN_ERR | 1271 | pr_err("Failed to initialize the SCTP control sock\n"); |
1294 | "SCTP: Failed to initialize the SCTP control sock.\n"); | ||
1295 | goto err_ctl_sock_init; | 1272 | goto err_ctl_sock_init; |
1296 | } | 1273 | } |
1297 | 1274 | ||
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index 246f92924658..58eb27fed4b4 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c | |||
@@ -50,6 +50,8 @@ | |||
50 | * be incorporated into the next SCTP release. | 50 | * be incorporated into the next SCTP release. |
51 | */ | 51 | */ |
52 | 52 | ||
53 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
54 | |||
53 | #include <linux/types.h> | 55 | #include <linux/types.h> |
54 | #include <linux/kernel.h> | 56 | #include <linux/kernel.h> |
55 | #include <linux/ip.h> | 57 | #include <linux/ip.h> |
@@ -1073,20 +1075,28 @@ nodata: | |||
1073 | 1075 | ||
1074 | /* Make a HEARTBEAT chunk. */ | 1076 | /* Make a HEARTBEAT chunk. */ |
1075 | struct sctp_chunk *sctp_make_heartbeat(const struct sctp_association *asoc, | 1077 | struct sctp_chunk *sctp_make_heartbeat(const struct sctp_association *asoc, |
1076 | const struct sctp_transport *transport, | 1078 | const struct sctp_transport *transport) |
1077 | const void *payload, const size_t paylen) | ||
1078 | { | 1079 | { |
1079 | struct sctp_chunk *retval = sctp_make_chunk(asoc, SCTP_CID_HEARTBEAT, | 1080 | struct sctp_chunk *retval; |
1080 | 0, paylen); | 1081 | sctp_sender_hb_info_t hbinfo; |
1082 | |||
1083 | retval = sctp_make_chunk(asoc, SCTP_CID_HEARTBEAT, 0, sizeof(hbinfo)); | ||
1081 | 1084 | ||
1082 | if (!retval) | 1085 | if (!retval) |
1083 | goto nodata; | 1086 | goto nodata; |
1084 | 1087 | ||
1088 | hbinfo.param_hdr.type = SCTP_PARAM_HEARTBEAT_INFO; | ||
1089 | hbinfo.param_hdr.length = htons(sizeof(sctp_sender_hb_info_t)); | ||
1090 | hbinfo.daddr = transport->ipaddr; | ||
1091 | hbinfo.sent_at = jiffies; | ||
1092 | hbinfo.hb_nonce = transport->hb_nonce; | ||
1093 | |||
1085 | /* Cast away the 'const', as this is just telling the chunk | 1094 | /* Cast away the 'const', as this is just telling the chunk |
1086 | * what transport it belongs to. | 1095 | * what transport it belongs to. |
1087 | */ | 1096 | */ |
1088 | retval->transport = (struct sctp_transport *) transport; | 1097 | retval->transport = (struct sctp_transport *) transport; |
1089 | retval->subh.hbs_hdr = sctp_addto_chunk(retval, paylen, payload); | 1098 | retval->subh.hbs_hdr = sctp_addto_chunk(retval, sizeof(hbinfo), |
1099 | &hbinfo); | ||
1090 | 1100 | ||
1091 | nodata: | 1101 | nodata: |
1092 | return retval; | 1102 | return retval; |
@@ -2027,11 +2037,11 @@ static sctp_ierror_t sctp_process_unk_param(const struct sctp_association *asoc, | |||
2027 | *errp = sctp_make_op_error_fixed(asoc, chunk); | 2037 | *errp = sctp_make_op_error_fixed(asoc, chunk); |
2028 | 2038 | ||
2029 | if (*errp) { | 2039 | if (*errp) { |
2030 | sctp_init_cause_fixed(*errp, SCTP_ERROR_UNKNOWN_PARAM, | 2040 | if (!sctp_init_cause_fixed(*errp, SCTP_ERROR_UNKNOWN_PARAM, |
2031 | WORD_ROUND(ntohs(param.p->length))); | 2041 | WORD_ROUND(ntohs(param.p->length)))) |
2032 | sctp_addto_chunk_fixed(*errp, | 2042 | sctp_addto_chunk_fixed(*errp, |
2033 | WORD_ROUND(ntohs(param.p->length)), | 2043 | WORD_ROUND(ntohs(param.p->length)), |
2034 | param.v); | 2044 | param.v); |
2035 | } else { | 2045 | } else { |
2036 | /* If there is no memory for generating the ERROR | 2046 | /* If there is no memory for generating the ERROR |
2037 | * report as specified, an ABORT will be triggered | 2047 | * report as specified, an ABORT will be triggered |
@@ -2240,14 +2250,17 @@ int sctp_verify_init(const struct sctp_association *asoc, | |||
2240 | * Returns 0 on failure, else success. | 2250 | * Returns 0 on failure, else success. |
2241 | * FIXME: This is an association method. | 2251 | * FIXME: This is an association method. |
2242 | */ | 2252 | */ |
2243 | int sctp_process_init(struct sctp_association *asoc, sctp_cid_t cid, | 2253 | int sctp_process_init(struct sctp_association *asoc, struct sctp_chunk *chunk, |
2244 | const union sctp_addr *peer_addr, | 2254 | const union sctp_addr *peer_addr, |
2245 | sctp_init_chunk_t *peer_init, gfp_t gfp) | 2255 | sctp_init_chunk_t *peer_init, gfp_t gfp) |
2246 | { | 2256 | { |
2247 | union sctp_params param; | 2257 | union sctp_params param; |
2248 | struct sctp_transport *transport; | 2258 | struct sctp_transport *transport; |
2249 | struct list_head *pos, *temp; | 2259 | struct list_head *pos, *temp; |
2260 | struct sctp_af *af; | ||
2261 | union sctp_addr addr; | ||
2250 | char *cookie; | 2262 | char *cookie; |
2263 | int src_match = 0; | ||
2251 | 2264 | ||
2252 | /* We must include the address that the INIT packet came from. | 2265 | /* We must include the address that the INIT packet came from. |
2253 | * This is the only address that matters for an INIT packet. | 2266 | * This is the only address that matters for an INIT packet. |
@@ -2259,18 +2272,31 @@ int sctp_process_init(struct sctp_association *asoc, sctp_cid_t cid, | |||
2259 | * added as the primary transport. The source address seems to | 2272 | * added as the primary transport. The source address seems to |
2260 | * be a a better choice than any of the embedded addresses. | 2273 | * be a a better choice than any of the embedded addresses. |
2261 | */ | 2274 | */ |
2262 | if (peer_addr) { | 2275 | if(!sctp_assoc_add_peer(asoc, peer_addr, gfp, SCTP_ACTIVE)) |
2263 | if(!sctp_assoc_add_peer(asoc, peer_addr, gfp, SCTP_ACTIVE)) | 2276 | goto nomem; |
2264 | goto nomem; | 2277 | |
2265 | } | 2278 | if (sctp_cmp_addr_exact(sctp_source(chunk), peer_addr)) |
2279 | src_match = 1; | ||
2266 | 2280 | ||
2267 | /* Process the initialization parameters. */ | 2281 | /* Process the initialization parameters. */ |
2268 | sctp_walk_params(param, peer_init, init_hdr.params) { | 2282 | sctp_walk_params(param, peer_init, init_hdr.params) { |
2283 | if (!src_match && (param.p->type == SCTP_PARAM_IPV4_ADDRESS || | ||
2284 | param.p->type == SCTP_PARAM_IPV6_ADDRESS)) { | ||
2285 | af = sctp_get_af_specific(param_type2af(param.p->type)); | ||
2286 | af->from_addr_param(&addr, param.addr, | ||
2287 | chunk->sctp_hdr->source, 0); | ||
2288 | if (sctp_cmp_addr_exact(sctp_source(chunk), &addr)) | ||
2289 | src_match = 1; | ||
2290 | } | ||
2269 | 2291 | ||
2270 | if (!sctp_process_param(asoc, param, peer_addr, gfp)) | 2292 | if (!sctp_process_param(asoc, param, peer_addr, gfp)) |
2271 | goto clean_up; | 2293 | goto clean_up; |
2272 | } | 2294 | } |
2273 | 2295 | ||
2296 | /* source address of chunk may not match any valid address */ | ||
2297 | if (!src_match) | ||
2298 | goto clean_up; | ||
2299 | |||
2274 | /* AUTH: After processing the parameters, make sure that we | 2300 | /* AUTH: After processing the parameters, make sure that we |
2275 | * have all the required info to potentially do authentications. | 2301 | * have all the required info to potentially do authentications. |
2276 | */ | 2302 | */ |
@@ -2921,7 +2947,7 @@ static __be16 sctp_process_asconf_param(struct sctp_association *asoc, | |||
2921 | asconf_param->param_hdr.type != SCTP_PARAM_SET_PRIMARY) | 2947 | asconf_param->param_hdr.type != SCTP_PARAM_SET_PRIMARY) |
2922 | return SCTP_ERROR_UNKNOWN_PARAM; | 2948 | return SCTP_ERROR_UNKNOWN_PARAM; |
2923 | 2949 | ||
2924 | switch (addr_param->v4.param_hdr.type) { | 2950 | switch (addr_param->p.type) { |
2925 | case SCTP_PARAM_IPV6_ADDRESS: | 2951 | case SCTP_PARAM_IPV6_ADDRESS: |
2926 | if (!asoc->peer.ipv6_address) | 2952 | if (!asoc->peer.ipv6_address) |
2927 | return SCTP_ERROR_DNS_FAILED; | 2953 | return SCTP_ERROR_DNS_FAILED; |
@@ -2934,7 +2960,7 @@ static __be16 sctp_process_asconf_param(struct sctp_association *asoc, | |||
2934 | return SCTP_ERROR_DNS_FAILED; | 2960 | return SCTP_ERROR_DNS_FAILED; |
2935 | } | 2961 | } |
2936 | 2962 | ||
2937 | af = sctp_get_af_specific(param_type2af(addr_param->v4.param_hdr.type)); | 2963 | af = sctp_get_af_specific(param_type2af(addr_param->p.type)); |
2938 | if (unlikely(!af)) | 2964 | if (unlikely(!af)) |
2939 | return SCTP_ERROR_DNS_FAILED; | 2965 | return SCTP_ERROR_DNS_FAILED; |
2940 | 2966 | ||
@@ -3098,16 +3124,16 @@ struct sctp_chunk *sctp_process_asconf(struct sctp_association *asoc, | |||
3098 | /* Skip the address parameter and store a pointer to the first | 3124 | /* Skip the address parameter and store a pointer to the first |
3099 | * asconf parameter. | 3125 | * asconf parameter. |
3100 | */ | 3126 | */ |
3101 | length = ntohs(addr_param->v4.param_hdr.length); | 3127 | length = ntohs(addr_param->p.length); |
3102 | asconf_param = (sctp_addip_param_t *)((void *)addr_param + length); | 3128 | asconf_param = (sctp_addip_param_t *)((void *)addr_param + length); |
3103 | chunk_len -= length; | 3129 | chunk_len -= length; |
3104 | 3130 | ||
3105 | /* create an ASCONF_ACK chunk. | 3131 | /* create an ASCONF_ACK chunk. |
3106 | * Based on the definitions of parameters, we know that the size of | 3132 | * Based on the definitions of parameters, we know that the size of |
3107 | * ASCONF_ACK parameters are less than or equal to the twice of ASCONF | 3133 | * ASCONF_ACK parameters are less than or equal to the fourfold of ASCONF |
3108 | * parameters. | 3134 | * parameters. |
3109 | */ | 3135 | */ |
3110 | asconf_ack = sctp_make_asconf_ack(asoc, serial, chunk_len * 2); | 3136 | asconf_ack = sctp_make_asconf_ack(asoc, serial, chunk_len * 4); |
3111 | if (!asconf_ack) | 3137 | if (!asconf_ack) |
3112 | goto done; | 3138 | goto done; |
3113 | 3139 | ||
@@ -3175,7 +3201,7 @@ static void sctp_asconf_param_success(struct sctp_association *asoc, | |||
3175 | ((void *)asconf_param + sizeof(sctp_addip_param_t)); | 3201 | ((void *)asconf_param + sizeof(sctp_addip_param_t)); |
3176 | 3202 | ||
3177 | /* We have checked the packet before, so we do not check again. */ | 3203 | /* We have checked the packet before, so we do not check again. */ |
3178 | af = sctp_get_af_specific(param_type2af(addr_param->v4.param_hdr.type)); | 3204 | af = sctp_get_af_specific(param_type2af(addr_param->p.type)); |
3179 | af->from_addr_param(&addr, addr_param, htons(bp->port), 0); | 3205 | af->from_addr_param(&addr, addr_param, htons(bp->port), 0); |
3180 | 3206 | ||
3181 | switch (asconf_param->param_hdr.type) { | 3207 | switch (asconf_param->param_hdr.type) { |
@@ -3191,11 +3217,8 @@ static void sctp_asconf_param_success(struct sctp_association *asoc, | |||
3191 | local_bh_enable(); | 3217 | local_bh_enable(); |
3192 | list_for_each_entry(transport, &asoc->peer.transport_addr_list, | 3218 | list_for_each_entry(transport, &asoc->peer.transport_addr_list, |
3193 | transports) { | 3219 | transports) { |
3194 | if (transport->state == SCTP_ACTIVE) | ||
3195 | continue; | ||
3196 | dst_release(transport->dst); | 3220 | dst_release(transport->dst); |
3197 | sctp_transport_route(transport, NULL, | 3221 | transport->dst = NULL; |
3198 | sctp_sk(asoc->base.sk)); | ||
3199 | } | 3222 | } |
3200 | break; | 3223 | break; |
3201 | case SCTP_PARAM_DEL_IP: | 3224 | case SCTP_PARAM_DEL_IP: |
@@ -3205,8 +3228,7 @@ static void sctp_asconf_param_success(struct sctp_association *asoc, | |||
3205 | list_for_each_entry(transport, &asoc->peer.transport_addr_list, | 3228 | list_for_each_entry(transport, &asoc->peer.transport_addr_list, |
3206 | transports) { | 3229 | transports) { |
3207 | dst_release(transport->dst); | 3230 | dst_release(transport->dst); |
3208 | sctp_transport_route(transport, NULL, | 3231 | transport->dst = NULL; |
3209 | sctp_sk(asoc->base.sk)); | ||
3210 | } | 3232 | } |
3211 | break; | 3233 | break; |
3212 | default: | 3234 | default: |
@@ -3302,7 +3324,7 @@ int sctp_process_asconf_ack(struct sctp_association *asoc, | |||
3302 | /* Skip the address parameter in the last asconf sent and store a | 3324 | /* Skip the address parameter in the last asconf sent and store a |
3303 | * pointer to the first asconf parameter. | 3325 | * pointer to the first asconf parameter. |
3304 | */ | 3326 | */ |
3305 | length = ntohs(addr_param->v4.param_hdr.length); | 3327 | length = ntohs(addr_param->p.length); |
3306 | asconf_param = (sctp_addip_param_t *)((void *)addr_param + length); | 3328 | asconf_param = (sctp_addip_param_t *)((void *)addr_param + length); |
3307 | asconf_len -= length; | 3329 | asconf_len -= length; |
3308 | 3330 | ||
@@ -3373,7 +3395,6 @@ struct sctp_chunk *sctp_make_fwdtsn(const struct sctp_association *asoc, | |||
3373 | struct sctp_fwdtsn_skip *skiplist) | 3395 | struct sctp_fwdtsn_skip *skiplist) |
3374 | { | 3396 | { |
3375 | struct sctp_chunk *retval = NULL; | 3397 | struct sctp_chunk *retval = NULL; |
3376 | struct sctp_fwdtsn_chunk *ftsn_chunk; | ||
3377 | struct sctp_fwdtsn_hdr ftsn_hdr; | 3398 | struct sctp_fwdtsn_hdr ftsn_hdr; |
3378 | struct sctp_fwdtsn_skip skip; | 3399 | struct sctp_fwdtsn_skip skip; |
3379 | size_t hint; | 3400 | size_t hint; |
@@ -3386,8 +3407,6 @@ struct sctp_chunk *sctp_make_fwdtsn(const struct sctp_association *asoc, | |||
3386 | if (!retval) | 3407 | if (!retval) |
3387 | return NULL; | 3408 | return NULL; |
3388 | 3409 | ||
3389 | ftsn_chunk = (struct sctp_fwdtsn_chunk *)retval->subh.fwdtsn_hdr; | ||
3390 | |||
3391 | ftsn_hdr.new_cum_tsn = htonl(new_cum_tsn); | 3410 | ftsn_hdr.new_cum_tsn = htonl(new_cum_tsn); |
3392 | retval->subh.fwdtsn_hdr = | 3411 | retval->subh.fwdtsn_hdr = |
3393 | sctp_addto_chunk(retval, sizeof(ftsn_hdr), &ftsn_hdr); | 3412 | sctp_addto_chunk(retval, sizeof(ftsn_hdr), &ftsn_hdr); |
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index f5e5e27cac5e..6e0f88295aaf 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c | |||
@@ -47,6 +47,8 @@ | |||
47 | * be incorporated into the next SCTP release. | 47 | * be incorporated into the next SCTP release. |
48 | */ | 48 | */ |
49 | 49 | ||
50 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
51 | |||
50 | #include <linux/skbuff.h> | 52 | #include <linux/skbuff.h> |
51 | #include <linux/types.h> | 53 | #include <linux/types.h> |
52 | #include <linux/socket.h> | 54 | #include <linux/socket.h> |
@@ -480,7 +482,7 @@ static void sctp_do_8_2_transport_strike(struct sctp_association *asoc, | |||
480 | * If the timer was a heartbeat, we only increment error counts | 482 | * If the timer was a heartbeat, we only increment error counts |
481 | * when we already have an outstanding HEARTBEAT that has not | 483 | * when we already have an outstanding HEARTBEAT that has not |
482 | * been acknowledged. | 484 | * been acknowledged. |
483 | * Additionaly, some tranport states inhibit error increments. | 485 | * Additionally, some tranport states inhibit error increments. |
484 | */ | 486 | */ |
485 | if (!is_hb) { | 487 | if (!is_hb) { |
486 | asoc->overall_error_count++; | 488 | asoc->overall_error_count++; |
@@ -593,8 +595,7 @@ static int sctp_cmd_process_init(sctp_cmd_seq_t *commands, | |||
593 | * fail during INIT processing (due to malloc problems), | 595 | * fail during INIT processing (due to malloc problems), |
594 | * just return the error and stop processing the stack. | 596 | * just return the error and stop processing the stack. |
595 | */ | 597 | */ |
596 | if (!sctp_process_init(asoc, chunk->chunk_hdr->type, | 598 | if (!sctp_process_init(asoc, chunk, sctp_source(chunk), peer_init, gfp)) |
597 | sctp_source(chunk), peer_init, gfp)) | ||
598 | error = -ENOMEM; | 599 | error = -ENOMEM; |
599 | else | 600 | else |
600 | error = 0; | 601 | error = 0; |
@@ -669,10 +670,19 @@ static void sctp_cmd_transport_on(sctp_cmd_seq_t *cmds, | |||
669 | /* 8.3 Upon the receipt of the HEARTBEAT ACK, the sender of the | 670 | /* 8.3 Upon the receipt of the HEARTBEAT ACK, the sender of the |
670 | * HEARTBEAT should clear the error counter of the destination | 671 | * HEARTBEAT should clear the error counter of the destination |
671 | * transport address to which the HEARTBEAT was sent. | 672 | * transport address to which the HEARTBEAT was sent. |
672 | * The association's overall error count is also cleared. | ||
673 | */ | 673 | */ |
674 | t->error_count = 0; | 674 | t->error_count = 0; |
675 | t->asoc->overall_error_count = 0; | 675 | |
676 | /* | ||
677 | * Although RFC4960 specifies that the overall error count must | ||
678 | * be cleared when a HEARTBEAT ACK is received, we make an | ||
679 | * exception while in SHUTDOWN PENDING. If the peer keeps its | ||
680 | * window shut forever, we may never be able to transmit our | ||
681 | * outstanding data and rely on the retransmission limit be reached | ||
682 | * to shutdown the association. | ||
683 | */ | ||
684 | if (t->asoc->state != SCTP_STATE_SHUTDOWN_PENDING) | ||
685 | t->asoc->overall_error_count = 0; | ||
676 | 686 | ||
677 | /* Clear the hb_sent flag to signal that we had a good | 687 | /* Clear the hb_sent flag to signal that we had a good |
678 | * acknowledgement. | 688 | * acknowledgement. |
@@ -1146,26 +1156,23 @@ static int sctp_side_effects(sctp_event_t event_type, sctp_subtype_t subtype, | |||
1146 | 1156 | ||
1147 | case SCTP_DISPOSITION_VIOLATION: | 1157 | case SCTP_DISPOSITION_VIOLATION: |
1148 | if (net_ratelimit()) | 1158 | if (net_ratelimit()) |
1149 | printk(KERN_ERR "sctp protocol violation state %d " | 1159 | pr_err("protocol violation state %d chunkid %d\n", |
1150 | "chunkid %d\n", state, subtype.chunk); | 1160 | state, subtype.chunk); |
1151 | break; | 1161 | break; |
1152 | 1162 | ||
1153 | case SCTP_DISPOSITION_NOT_IMPL: | 1163 | case SCTP_DISPOSITION_NOT_IMPL: |
1154 | printk(KERN_WARNING "sctp unimplemented feature in state %d, " | 1164 | pr_warn("unimplemented feature in state %d, event_type %d, event_id %d\n", |
1155 | "event_type %d, event_id %d\n", | 1165 | state, event_type, subtype.chunk); |
1156 | state, event_type, subtype.chunk); | ||
1157 | break; | 1166 | break; |
1158 | 1167 | ||
1159 | case SCTP_DISPOSITION_BUG: | 1168 | case SCTP_DISPOSITION_BUG: |
1160 | printk(KERN_ERR "sctp bug in state %d, " | 1169 | pr_err("bug in state %d, event_type %d, event_id %d\n", |
1161 | "event_type %d, event_id %d\n", | ||
1162 | state, event_type, subtype.chunk); | 1170 | state, event_type, subtype.chunk); |
1163 | BUG(); | 1171 | BUG(); |
1164 | break; | 1172 | break; |
1165 | 1173 | ||
1166 | default: | 1174 | default: |
1167 | printk(KERN_ERR "sctp impossible disposition %d " | 1175 | pr_err("impossible disposition %d in state %d, event_type %d, event_id %d\n", |
1168 | "in state %d, event_type %d, event_id %d\n", | ||
1169 | status, state, event_type, subtype.chunk); | 1176 | status, state, event_type, subtype.chunk); |
1170 | BUG(); | 1177 | BUG(); |
1171 | break; | 1178 | break; |
@@ -1416,12 +1423,6 @@ static int sctp_cmd_interpreter(sctp_event_t event_type, | |||
1416 | SCTP_RTXR_T3_RTX); | 1423 | SCTP_RTXR_T3_RTX); |
1417 | break; | 1424 | break; |
1418 | 1425 | ||
1419 | case SCTP_CMD_TRANSMIT: | ||
1420 | /* Kick start transmission. */ | ||
1421 | error = sctp_outq_uncork(&asoc->outqueue); | ||
1422 | local_cork = 0; | ||
1423 | break; | ||
1424 | |||
1425 | case SCTP_CMD_ECN_CE: | 1426 | case SCTP_CMD_ECN_CE: |
1426 | /* Do delayed CE processing. */ | 1427 | /* Do delayed CE processing. */ |
1427 | sctp_do_ecn_ce_work(asoc, cmd->obj.u32); | 1428 | sctp_do_ecn_ce_work(asoc, cmd->obj.u32); |
@@ -1445,6 +1446,13 @@ static int sctp_cmd_interpreter(sctp_event_t event_type, | |||
1445 | sctp_cmd_setup_t2(commands, asoc, cmd->obj.ptr); | 1446 | sctp_cmd_setup_t2(commands, asoc, cmd->obj.ptr); |
1446 | break; | 1447 | break; |
1447 | 1448 | ||
1449 | case SCTP_CMD_TIMER_START_ONCE: | ||
1450 | timer = &asoc->timers[cmd->obj.to]; | ||
1451 | |||
1452 | if (timer_pending(timer)) | ||
1453 | break; | ||
1454 | /* fall through */ | ||
1455 | |||
1448 | case SCTP_CMD_TIMER_START: | 1456 | case SCTP_CMD_TIMER_START: |
1449 | timer = &asoc->timers[cmd->obj.to]; | 1457 | timer = &asoc->timers[cmd->obj.to]; |
1450 | timeout = asoc->timeouts[cmd->obj.to]; | 1458 | timeout = asoc->timeouts[cmd->obj.to]; |
@@ -1678,9 +1686,12 @@ static int sctp_cmd_interpreter(sctp_event_t event_type, | |||
1678 | case SCTP_CMD_SEND_NEXT_ASCONF: | 1686 | case SCTP_CMD_SEND_NEXT_ASCONF: |
1679 | sctp_cmd_send_asconf(asoc); | 1687 | sctp_cmd_send_asconf(asoc); |
1680 | break; | 1688 | break; |
1689 | case SCTP_CMD_PURGE_ASCONF_QUEUE: | ||
1690 | sctp_asconf_queue_teardown(asoc); | ||
1691 | break; | ||
1681 | default: | 1692 | default: |
1682 | printk(KERN_WARNING "Impossible command: %u, %p\n", | 1693 | pr_warn("Impossible command: %u, %p\n", |
1683 | cmd->verb, cmd->obj.ptr); | 1694 | cmd->verb, cmd->obj.ptr); |
1684 | break; | 1695 | break; |
1685 | } | 1696 | } |
1686 | 1697 | ||
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index d344dc481ccc..246117142b5c 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
@@ -50,6 +50,8 @@ | |||
50 | * be incorporated into the next SCTP release. | 50 | * be incorporated into the next SCTP release. |
51 | */ | 51 | */ |
52 | 52 | ||
53 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
54 | |||
53 | #include <linux/types.h> | 55 | #include <linux/types.h> |
54 | #include <linux/kernel.h> | 56 | #include <linux/kernel.h> |
55 | #include <linux/ip.h> | 57 | #include <linux/ip.h> |
@@ -391,8 +393,7 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep, | |||
391 | goto nomem_init; | 393 | goto nomem_init; |
392 | 394 | ||
393 | /* The call, sctp_process_init(), can fail on memory allocation. */ | 395 | /* The call, sctp_process_init(), can fail on memory allocation. */ |
394 | if (!sctp_process_init(new_asoc, chunk->chunk_hdr->type, | 396 | if (!sctp_process_init(new_asoc, chunk, sctp_source(chunk), |
395 | sctp_source(chunk), | ||
396 | (sctp_init_chunk_t *)chunk->chunk_hdr, | 397 | (sctp_init_chunk_t *)chunk->chunk_hdr, |
397 | GFP_ATOMIC)) | 398 | GFP_ATOMIC)) |
398 | goto nomem_init; | 399 | goto nomem_init; |
@@ -549,7 +550,7 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const struct sctp_endpoint *ep, | |||
549 | * | 550 | * |
550 | * This means that if we only want to abort associations | 551 | * This means that if we only want to abort associations |
551 | * in an authenticated way (i.e AUTH+ABORT), then we | 552 | * in an authenticated way (i.e AUTH+ABORT), then we |
552 | * can't destroy this association just becuase the packet | 553 | * can't destroy this association just because the packet |
553 | * was malformed. | 554 | * was malformed. |
554 | */ | 555 | */ |
555 | if (sctp_auth_recv_cid(SCTP_CID_ABORT, asoc)) | 556 | if (sctp_auth_recv_cid(SCTP_CID_ABORT, asoc)) |
@@ -723,7 +724,7 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep, | |||
723 | */ | 724 | */ |
724 | peer_init = &chunk->subh.cookie_hdr->c.peer_init[0]; | 725 | peer_init = &chunk->subh.cookie_hdr->c.peer_init[0]; |
725 | 726 | ||
726 | if (!sctp_process_init(new_asoc, chunk->chunk_hdr->type, | 727 | if (!sctp_process_init(new_asoc, chunk, |
727 | &chunk->subh.cookie_hdr->c.peer_addr, | 728 | &chunk->subh.cookie_hdr->c.peer_addr, |
728 | peer_init, GFP_ATOMIC)) | 729 | peer_init, GFP_ATOMIC)) |
729 | goto nomem_init; | 730 | goto nomem_init; |
@@ -940,18 +941,9 @@ static sctp_disposition_t sctp_sf_heartbeat(const struct sctp_endpoint *ep, | |||
940 | { | 941 | { |
941 | struct sctp_transport *transport = (struct sctp_transport *) arg; | 942 | struct sctp_transport *transport = (struct sctp_transport *) arg; |
942 | struct sctp_chunk *reply; | 943 | struct sctp_chunk *reply; |
943 | sctp_sender_hb_info_t hbinfo; | ||
944 | size_t paylen = 0; | ||
945 | |||
946 | hbinfo.param_hdr.type = SCTP_PARAM_HEARTBEAT_INFO; | ||
947 | hbinfo.param_hdr.length = htons(sizeof(sctp_sender_hb_info_t)); | ||
948 | hbinfo.daddr = transport->ipaddr; | ||
949 | hbinfo.sent_at = jiffies; | ||
950 | hbinfo.hb_nonce = transport->hb_nonce; | ||
951 | 944 | ||
952 | /* Send a heartbeat to our peer. */ | 945 | /* Send a heartbeat to our peer. */ |
953 | paylen = sizeof(sctp_sender_hb_info_t); | 946 | reply = sctp_make_heartbeat(asoc, transport); |
954 | reply = sctp_make_heartbeat(asoc, transport, &hbinfo, paylen); | ||
955 | if (!reply) | 947 | if (!reply) |
956 | return SCTP_DISPOSITION_NOMEM; | 948 | return SCTP_DISPOSITION_NOMEM; |
957 | 949 | ||
@@ -1138,18 +1130,16 @@ sctp_disposition_t sctp_sf_backbeat_8_3(const struct sctp_endpoint *ep, | |||
1138 | if (unlikely(!link)) { | 1130 | if (unlikely(!link)) { |
1139 | if (from_addr.sa.sa_family == AF_INET6) { | 1131 | if (from_addr.sa.sa_family == AF_INET6) { |
1140 | if (net_ratelimit()) | 1132 | if (net_ratelimit()) |
1141 | printk(KERN_WARNING | 1133 | pr_warn("%s association %p could not find address %pI6\n", |
1142 | "%s association %p could not find address %pI6\n", | 1134 | __func__, |
1143 | __func__, | 1135 | asoc, |
1144 | asoc, | 1136 | &from_addr.v6.sin6_addr); |
1145 | &from_addr.v6.sin6_addr); | ||
1146 | } else { | 1137 | } else { |
1147 | if (net_ratelimit()) | 1138 | if (net_ratelimit()) |
1148 | printk(KERN_WARNING | 1139 | pr_warn("%s association %p could not find address %pI4\n", |
1149 | "%s association %p could not find address %pI4\n", | 1140 | __func__, |
1150 | __func__, | 1141 | asoc, |
1151 | asoc, | 1142 | &from_addr.v4.sin_addr.s_addr); |
1152 | &from_addr.v4.sin_addr.s_addr); | ||
1153 | } | 1143 | } |
1154 | return SCTP_DISPOSITION_DISCARD; | 1144 | return SCTP_DISPOSITION_DISCARD; |
1155 | } | 1145 | } |
@@ -1464,8 +1454,7 @@ static sctp_disposition_t sctp_sf_do_unexpected_init( | |||
1464 | * Verification Tag and Peers Verification tag into a reserved | 1454 | * Verification Tag and Peers Verification tag into a reserved |
1465 | * place (local tie-tag and per tie-tag) within the state cookie. | 1455 | * place (local tie-tag and per tie-tag) within the state cookie. |
1466 | */ | 1456 | */ |
1467 | if (!sctp_process_init(new_asoc, chunk->chunk_hdr->type, | 1457 | if (!sctp_process_init(new_asoc, chunk, sctp_source(chunk), |
1468 | sctp_source(chunk), | ||
1469 | (sctp_init_chunk_t *)chunk->chunk_hdr, | 1458 | (sctp_init_chunk_t *)chunk->chunk_hdr, |
1470 | GFP_ATOMIC)) | 1459 | GFP_ATOMIC)) |
1471 | goto nomem; | 1460 | goto nomem; |
@@ -1546,7 +1535,7 @@ cleanup: | |||
1546 | } | 1535 | } |
1547 | 1536 | ||
1548 | /* | 1537 | /* |
1549 | * Handle simultanous INIT. | 1538 | * Handle simultaneous INIT. |
1550 | * This means we started an INIT and then we got an INIT request from | 1539 | * This means we started an INIT and then we got an INIT request from |
1551 | * our peer. | 1540 | * our peer. |
1552 | * | 1541 | * |
@@ -1694,8 +1683,7 @@ static sctp_disposition_t sctp_sf_do_dupcook_a(const struct sctp_endpoint *ep, | |||
1694 | */ | 1683 | */ |
1695 | peer_init = &chunk->subh.cookie_hdr->c.peer_init[0]; | 1684 | peer_init = &chunk->subh.cookie_hdr->c.peer_init[0]; |
1696 | 1685 | ||
1697 | if (!sctp_process_init(new_asoc, chunk->chunk_hdr->type, | 1686 | if (!sctp_process_init(new_asoc, chunk, sctp_source(chunk), peer_init, |
1698 | sctp_source(chunk), peer_init, | ||
1699 | GFP_ATOMIC)) | 1687 | GFP_ATOMIC)) |
1700 | goto nomem; | 1688 | goto nomem; |
1701 | 1689 | ||
@@ -1730,11 +1718,21 @@ static sctp_disposition_t sctp_sf_do_dupcook_a(const struct sctp_endpoint *ep, | |||
1730 | return SCTP_DISPOSITION_CONSUME; | 1718 | return SCTP_DISPOSITION_CONSUME; |
1731 | } | 1719 | } |
1732 | 1720 | ||
1733 | /* For now, fail any unsent/unacked data. Consider the optional | 1721 | /* For now, stop pending T3-rtx and SACK timers, fail any unsent/unacked |
1734 | * choice of resending of this data. | 1722 | * data. Consider the optional choice of resending of this data. |
1735 | */ | 1723 | */ |
1724 | sctp_add_cmd_sf(commands, SCTP_CMD_T3_RTX_TIMERS_STOP, SCTP_NULL()); | ||
1725 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, | ||
1726 | SCTP_TO(SCTP_EVENT_TIMEOUT_SACK)); | ||
1736 | sctp_add_cmd_sf(commands, SCTP_CMD_PURGE_OUTQUEUE, SCTP_NULL()); | 1727 | sctp_add_cmd_sf(commands, SCTP_CMD_PURGE_OUTQUEUE, SCTP_NULL()); |
1737 | 1728 | ||
1729 | /* Stop pending T4-rto timer, teardown ASCONF queue, ASCONF-ACK queue | ||
1730 | * and ASCONF-ACK cache. | ||
1731 | */ | ||
1732 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, | ||
1733 | SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO)); | ||
1734 | sctp_add_cmd_sf(commands, SCTP_CMD_PURGE_ASCONF_QUEUE, SCTP_NULL()); | ||
1735 | |||
1738 | repl = sctp_make_cookie_ack(new_asoc, chunk); | 1736 | repl = sctp_make_cookie_ack(new_asoc, chunk); |
1739 | if (!repl) | 1737 | if (!repl) |
1740 | goto nomem; | 1738 | goto nomem; |
@@ -1780,8 +1778,7 @@ static sctp_disposition_t sctp_sf_do_dupcook_b(const struct sctp_endpoint *ep, | |||
1780 | * side effects--it is safe to run them here. | 1778 | * side effects--it is safe to run them here. |
1781 | */ | 1779 | */ |
1782 | peer_init = &chunk->subh.cookie_hdr->c.peer_init[0]; | 1780 | peer_init = &chunk->subh.cookie_hdr->c.peer_init[0]; |
1783 | if (!sctp_process_init(new_asoc, chunk->chunk_hdr->type, | 1781 | if (!sctp_process_init(new_asoc, chunk, sctp_source(chunk), peer_init, |
1784 | sctp_source(chunk), peer_init, | ||
1785 | GFP_ATOMIC)) | 1782 | GFP_ATOMIC)) |
1786 | goto nomem; | 1783 | goto nomem; |
1787 | 1784 | ||
@@ -2079,7 +2076,7 @@ sctp_disposition_t sctp_sf_shutdown_pending_abort( | |||
2079 | * RFC 2960, Section 3.3.7 | 2076 | * RFC 2960, Section 3.3.7 |
2080 | * If an endpoint receives an ABORT with a format error or for an | 2077 | * If an endpoint receives an ABORT with a format error or for an |
2081 | * association that doesn't exist, it MUST silently discard it. | 2078 | * association that doesn't exist, it MUST silently discard it. |
2082 | * Becasue the length is "invalid", we can't really discard just | 2079 | * Because the length is "invalid", we can't really discard just |
2083 | * as we do not know its true length. So, to be safe, discard the | 2080 | * as we do not know its true length. So, to be safe, discard the |
2084 | * packet. | 2081 | * packet. |
2085 | */ | 2082 | */ |
@@ -2120,7 +2117,7 @@ sctp_disposition_t sctp_sf_shutdown_sent_abort(const struct sctp_endpoint *ep, | |||
2120 | * RFC 2960, Section 3.3.7 | 2117 | * RFC 2960, Section 3.3.7 |
2121 | * If an endpoint receives an ABORT with a format error or for an | 2118 | * If an endpoint receives an ABORT with a format error or for an |
2122 | * association that doesn't exist, it MUST silently discard it. | 2119 | * association that doesn't exist, it MUST silently discard it. |
2123 | * Becasue the length is "invalid", we can't really discard just | 2120 | * Because the length is "invalid", we can't really discard just |
2124 | * as we do not know its true length. So, to be safe, discard the | 2121 | * as we do not know its true length. So, to be safe, discard the |
2125 | * packet. | 2122 | * packet. |
2126 | */ | 2123 | */ |
@@ -2381,7 +2378,7 @@ sctp_disposition_t sctp_sf_do_9_1_abort(const struct sctp_endpoint *ep, | |||
2381 | * RFC 2960, Section 3.3.7 | 2378 | * RFC 2960, Section 3.3.7 |
2382 | * If an endpoint receives an ABORT with a format error or for an | 2379 | * If an endpoint receives an ABORT with a format error or for an |
2383 | * association that doesn't exist, it MUST silently discard it. | 2380 | * association that doesn't exist, it MUST silently discard it. |
2384 | * Becasue the length is "invalid", we can't really discard just | 2381 | * Because the length is "invalid", we can't really discard just |
2385 | * as we do not know its true length. So, to be safe, discard the | 2382 | * as we do not know its true length. So, to be safe, discard the |
2386 | * packet. | 2383 | * packet. |
2387 | */ | 2384 | */ |
@@ -2412,8 +2409,15 @@ static sctp_disposition_t __sctp_sf_do_9_1_abort(const struct sctp_endpoint *ep, | |||
2412 | 2409 | ||
2413 | /* See if we have an error cause code in the chunk. */ | 2410 | /* See if we have an error cause code in the chunk. */ |
2414 | len = ntohs(chunk->chunk_hdr->length); | 2411 | len = ntohs(chunk->chunk_hdr->length); |
2415 | if (len >= sizeof(struct sctp_chunkhdr) + sizeof(struct sctp_errhdr)) | 2412 | if (len >= sizeof(struct sctp_chunkhdr) + sizeof(struct sctp_errhdr)) { |
2413 | |||
2414 | sctp_errhdr_t *err; | ||
2415 | sctp_walk_errors(err, chunk->chunk_hdr); | ||
2416 | if ((void *)err != (void *)chunk->chunk_end) | ||
2417 | return sctp_sf_pdiscard(ep, asoc, type, arg, commands); | ||
2418 | |||
2416 | error = ((sctp_errhdr_t *)chunk->skb->data)->cause; | 2419 | error = ((sctp_errhdr_t *)chunk->skb->data)->cause; |
2420 | } | ||
2417 | 2421 | ||
2418 | sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, SCTP_ERROR(ECONNRESET)); | 2422 | sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, SCTP_ERROR(ECONNRESET)); |
2419 | /* ASSOC_FAILED will DELETE_TCB. */ | 2423 | /* ASSOC_FAILED will DELETE_TCB. */ |
@@ -2448,7 +2452,7 @@ sctp_disposition_t sctp_sf_cookie_wait_abort(const struct sctp_endpoint *ep, | |||
2448 | * RFC 2960, Section 3.3.7 | 2452 | * RFC 2960, Section 3.3.7 |
2449 | * If an endpoint receives an ABORT with a format error or for an | 2453 | * If an endpoint receives an ABORT with a format error or for an |
2450 | * association that doesn't exist, it MUST silently discard it. | 2454 | * association that doesn't exist, it MUST silently discard it. |
2451 | * Becasue the length is "invalid", we can't really discard just | 2455 | * Because the length is "invalid", we can't really discard just |
2452 | * as we do not know its true length. So, to be safe, discard the | 2456 | * as we do not know its true length. So, to be safe, discard the |
2453 | * packet. | 2457 | * packet. |
2454 | */ | 2458 | */ |
@@ -3204,6 +3208,7 @@ sctp_disposition_t sctp_sf_operr_notify(const struct sctp_endpoint *ep, | |||
3204 | sctp_cmd_seq_t *commands) | 3208 | sctp_cmd_seq_t *commands) |
3205 | { | 3209 | { |
3206 | struct sctp_chunk *chunk = arg; | 3210 | struct sctp_chunk *chunk = arg; |
3211 | sctp_errhdr_t *err; | ||
3207 | 3212 | ||
3208 | if (!sctp_vtag_verify(chunk, asoc)) | 3213 | if (!sctp_vtag_verify(chunk, asoc)) |
3209 | return sctp_sf_pdiscard(ep, asoc, type, arg, commands); | 3214 | return sctp_sf_pdiscard(ep, asoc, type, arg, commands); |
@@ -3212,6 +3217,10 @@ sctp_disposition_t sctp_sf_operr_notify(const struct sctp_endpoint *ep, | |||
3212 | if (!sctp_chunk_length_valid(chunk, sizeof(sctp_operr_chunk_t))) | 3217 | if (!sctp_chunk_length_valid(chunk, sizeof(sctp_operr_chunk_t))) |
3213 | return sctp_sf_violation_chunklen(ep, asoc, type, arg, | 3218 | return sctp_sf_violation_chunklen(ep, asoc, type, arg, |
3214 | commands); | 3219 | commands); |
3220 | sctp_walk_errors(err, chunk->chunk_hdr); | ||
3221 | if ((void *)err != (void *)chunk->chunk_end) | ||
3222 | return sctp_sf_violation_paramlen(ep, asoc, type, arg, | ||
3223 | (void *)err, commands); | ||
3215 | 3224 | ||
3216 | sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_OPERR, | 3225 | sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_OPERR, |
3217 | SCTP_CHUNK(chunk)); | 3226 | SCTP_CHUNK(chunk)); |
@@ -3320,8 +3329,10 @@ sctp_disposition_t sctp_sf_ootb(const struct sctp_endpoint *ep, | |||
3320 | struct sctp_chunk *chunk = arg; | 3329 | struct sctp_chunk *chunk = arg; |
3321 | struct sk_buff *skb = chunk->skb; | 3330 | struct sk_buff *skb = chunk->skb; |
3322 | sctp_chunkhdr_t *ch; | 3331 | sctp_chunkhdr_t *ch; |
3332 | sctp_errhdr_t *err; | ||
3323 | __u8 *ch_end; | 3333 | __u8 *ch_end; |
3324 | int ootb_shut_ack = 0; | 3334 | int ootb_shut_ack = 0; |
3335 | int ootb_cookie_ack = 0; | ||
3325 | 3336 | ||
3326 | SCTP_INC_STATS(SCTP_MIB_OUTOFBLUES); | 3337 | SCTP_INC_STATS(SCTP_MIB_OUTOFBLUES); |
3327 | 3338 | ||
@@ -3346,6 +3357,23 @@ sctp_disposition_t sctp_sf_ootb(const struct sctp_endpoint *ep, | |||
3346 | if (SCTP_CID_ABORT == ch->type) | 3357 | if (SCTP_CID_ABORT == ch->type) |
3347 | return sctp_sf_pdiscard(ep, asoc, type, arg, commands); | 3358 | return sctp_sf_pdiscard(ep, asoc, type, arg, commands); |
3348 | 3359 | ||
3360 | /* RFC 8.4, 7) If the packet contains a "Stale cookie" ERROR | ||
3361 | * or a COOKIE ACK the SCTP Packet should be silently | ||
3362 | * discarded. | ||
3363 | */ | ||
3364 | |||
3365 | if (SCTP_CID_COOKIE_ACK == ch->type) | ||
3366 | ootb_cookie_ack = 1; | ||
3367 | |||
3368 | if (SCTP_CID_ERROR == ch->type) { | ||
3369 | sctp_walk_errors(err, ch) { | ||
3370 | if (SCTP_ERROR_STALE_COOKIE == err->cause) { | ||
3371 | ootb_cookie_ack = 1; | ||
3372 | break; | ||
3373 | } | ||
3374 | } | ||
3375 | } | ||
3376 | |||
3349 | /* Report violation if chunk len overflows */ | 3377 | /* Report violation if chunk len overflows */ |
3350 | ch_end = ((__u8 *)ch) + WORD_ROUND(ntohs(ch->length)); | 3378 | ch_end = ((__u8 *)ch) + WORD_ROUND(ntohs(ch->length)); |
3351 | if (ch_end > skb_tail_pointer(skb)) | 3379 | if (ch_end > skb_tail_pointer(skb)) |
@@ -3357,6 +3385,8 @@ sctp_disposition_t sctp_sf_ootb(const struct sctp_endpoint *ep, | |||
3357 | 3385 | ||
3358 | if (ootb_shut_ack) | 3386 | if (ootb_shut_ack) |
3359 | return sctp_sf_shut_8_4_5(ep, asoc, type, arg, commands); | 3387 | return sctp_sf_shut_8_4_5(ep, asoc, type, arg, commands); |
3388 | else if (ootb_cookie_ack) | ||
3389 | return sctp_sf_pdiscard(ep, asoc, type, arg, commands); | ||
3360 | else | 3390 | else |
3361 | return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands); | 3391 | return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands); |
3362 | } | 3392 | } |
@@ -3855,7 +3885,7 @@ gen_shutdown: | |||
3855 | } | 3885 | } |
3856 | 3886 | ||
3857 | /* | 3887 | /* |
3858 | * SCTP-AUTH Section 6.3 Receving authenticated chukns | 3888 | * SCTP-AUTH Section 6.3 Receiving authenticated chukns |
3859 | * | 3889 | * |
3860 | * The receiver MUST use the HMAC algorithm indicated in the HMAC | 3890 | * The receiver MUST use the HMAC algorithm indicated in the HMAC |
3861 | * Identifier field. If this algorithm was not specified by the | 3891 | * Identifier field. If this algorithm was not specified by the |
@@ -4231,7 +4261,7 @@ static sctp_disposition_t sctp_sf_abort_violation( | |||
4231 | * | 4261 | * |
4232 | * This means that if we only want to abort associations | 4262 | * This means that if we only want to abort associations |
4233 | * in an authenticated way (i.e AUTH+ABORT), then we | 4263 | * in an authenticated way (i.e AUTH+ABORT), then we |
4234 | * can't destroy this association just becuase the packet | 4264 | * can't destroy this association just because the packet |
4235 | * was malformed. | 4265 | * was malformed. |
4236 | */ | 4266 | */ |
4237 | if (sctp_auth_recv_cid(SCTP_CID_ABORT, asoc)) | 4267 | if (sctp_auth_recv_cid(SCTP_CID_ABORT, asoc)) |
@@ -4343,8 +4373,9 @@ static sctp_disposition_t sctp_sf_violation_chunklen( | |||
4343 | 4373 | ||
4344 | /* | 4374 | /* |
4345 | * Handle a protocol violation when the parameter length is invalid. | 4375 | * Handle a protocol violation when the parameter length is invalid. |
4346 | * "Invalid" length is identified as smaller than the minimal length a | 4376 | * If the length is smaller than the minimum length of a given parameter, |
4347 | * given parameter can be. | 4377 | * or accumulated length in multi parameters exceeds the end of the chunk, |
4378 | * the length is considered as invalid. | ||
4348 | */ | 4379 | */ |
4349 | static sctp_disposition_t sctp_sf_violation_paramlen( | 4380 | static sctp_disposition_t sctp_sf_violation_paramlen( |
4350 | const struct sctp_endpoint *ep, | 4381 | const struct sctp_endpoint *ep, |
@@ -4402,9 +4433,9 @@ static sctp_disposition_t sctp_sf_violation_ctsn( | |||
4402 | } | 4433 | } |
4403 | 4434 | ||
4404 | /* Handle protocol violation of an invalid chunk bundling. For example, | 4435 | /* Handle protocol violation of an invalid chunk bundling. For example, |
4405 | * when we have an association and we recieve bundled INIT-ACK, or | 4436 | * when we have an association and we receive bundled INIT-ACK, or |
4406 | * SHUDOWN-COMPLETE, our peer is clearly violationg the "MUST NOT bundle" | 4437 | * SHUDOWN-COMPLETE, our peer is clearly violationg the "MUST NOT bundle" |
4407 | * statement from the specs. Additinally, there might be an attacker | 4438 | * statement from the specs. Additionally, there might be an attacker |
4408 | * on the path and we may not want to continue this communication. | 4439 | * on the path and we may not want to continue this communication. |
4409 | */ | 4440 | */ |
4410 | static sctp_disposition_t sctp_sf_violation_chunk( | 4441 | static sctp_disposition_t sctp_sf_violation_chunk( |
@@ -5056,6 +5087,30 @@ sctp_disposition_t sctp_sf_ignore_primitive( | |||
5056 | ***************************************************************************/ | 5087 | ***************************************************************************/ |
5057 | 5088 | ||
5058 | /* | 5089 | /* |
5090 | * When the SCTP stack has no more user data to send or retransmit, this | ||
5091 | * notification is given to the user. Also, at the time when a user app | ||
5092 | * subscribes to this event, if there is no data to be sent or | ||
5093 | * retransmit, the stack will immediately send up this notification. | ||
5094 | */ | ||
5095 | sctp_disposition_t sctp_sf_do_no_pending_tsn( | ||
5096 | const struct sctp_endpoint *ep, | ||
5097 | const struct sctp_association *asoc, | ||
5098 | const sctp_subtype_t type, | ||
5099 | void *arg, | ||
5100 | sctp_cmd_seq_t *commands) | ||
5101 | { | ||
5102 | struct sctp_ulpevent *event; | ||
5103 | |||
5104 | event = sctp_ulpevent_make_sender_dry_event(asoc, GFP_ATOMIC); | ||
5105 | if (!event) | ||
5106 | return SCTP_DISPOSITION_NOMEM; | ||
5107 | |||
5108 | sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(event)); | ||
5109 | |||
5110 | return SCTP_DISPOSITION_CONSUME; | ||
5111 | } | ||
5112 | |||
5113 | /* | ||
5059 | * Start the shutdown negotiation. | 5114 | * Start the shutdown negotiation. |
5060 | * | 5115 | * |
5061 | * From Section 9.2: | 5116 | * From Section 9.2: |
@@ -5099,7 +5154,7 @@ sctp_disposition_t sctp_sf_do_9_2_start_shutdown( | |||
5099 | * The sender of the SHUTDOWN MAY also start an overall guard timer | 5154 | * The sender of the SHUTDOWN MAY also start an overall guard timer |
5100 | * 'T5-shutdown-guard' to bound the overall time for shutdown sequence. | 5155 | * 'T5-shutdown-guard' to bound the overall time for shutdown sequence. |
5101 | */ | 5156 | */ |
5102 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START, | 5157 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART, |
5103 | SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD)); | 5158 | SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD)); |
5104 | 5159 | ||
5105 | if (asoc->autoclose) | 5160 | if (asoc->autoclose) |
@@ -5244,14 +5299,28 @@ sctp_disposition_t sctp_sf_do_6_3_3_rtx(const struct sctp_endpoint *ep, | |||
5244 | SCTP_INC_STATS(SCTP_MIB_T3_RTX_EXPIREDS); | 5299 | SCTP_INC_STATS(SCTP_MIB_T3_RTX_EXPIREDS); |
5245 | 5300 | ||
5246 | if (asoc->overall_error_count >= asoc->max_retrans) { | 5301 | if (asoc->overall_error_count >= asoc->max_retrans) { |
5247 | sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, | 5302 | if (asoc->state == SCTP_STATE_SHUTDOWN_PENDING) { |
5248 | SCTP_ERROR(ETIMEDOUT)); | 5303 | /* |
5249 | /* CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */ | 5304 | * We are here likely because the receiver had its rwnd |
5250 | sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, | 5305 | * closed for a while and we have not been able to |
5251 | SCTP_PERR(SCTP_ERROR_NO_ERROR)); | 5306 | * transmit the locally queued data within the maximum |
5252 | SCTP_INC_STATS(SCTP_MIB_ABORTEDS); | 5307 | * retransmission attempts limit. Start the T5 |
5253 | SCTP_DEC_STATS(SCTP_MIB_CURRESTAB); | 5308 | * shutdown guard timer to give the receiver one last |
5254 | return SCTP_DISPOSITION_DELETE_TCB; | 5309 | * chance and some additional time to recover before |
5310 | * aborting. | ||
5311 | */ | ||
5312 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START_ONCE, | ||
5313 | SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD)); | ||
5314 | } else { | ||
5315 | sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, | ||
5316 | SCTP_ERROR(ETIMEDOUT)); | ||
5317 | /* CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */ | ||
5318 | sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, | ||
5319 | SCTP_PERR(SCTP_ERROR_NO_ERROR)); | ||
5320 | SCTP_INC_STATS(SCTP_MIB_ABORTEDS); | ||
5321 | SCTP_DEC_STATS(SCTP_MIB_CURRESTAB); | ||
5322 | return SCTP_DISPOSITION_DELETE_TCB; | ||
5323 | } | ||
5255 | } | 5324 | } |
5256 | 5325 | ||
5257 | /* E1) For the destination address for which the timer | 5326 | /* E1) For the destination address for which the timer |
diff --git a/net/sctp/sm_statetable.c b/net/sctp/sm_statetable.c index 6d9b3aafcc5d..7c211a7f90f4 100644 --- a/net/sctp/sm_statetable.c +++ b/net/sctp/sm_statetable.c | |||
@@ -46,6 +46,8 @@ | |||
46 | * be incorporated into the next SCTP release. | 46 | * be incorporated into the next SCTP release. |
47 | */ | 47 | */ |
48 | 48 | ||
49 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
50 | |||
49 | #include <linux/skbuff.h> | 51 | #include <linux/skbuff.h> |
50 | #include <net/sctp/sctp.h> | 52 | #include <net/sctp/sctp.h> |
51 | #include <net/sctp/sm.h> | 53 | #include <net/sctp/sm.h> |
@@ -66,15 +68,19 @@ static const sctp_sm_table_entry_t bug = { | |||
66 | .name = "sctp_sf_bug" | 68 | .name = "sctp_sf_bug" |
67 | }; | 69 | }; |
68 | 70 | ||
69 | #define DO_LOOKUP(_max, _type, _table) \ | 71 | #define DO_LOOKUP(_max, _type, _table) \ |
70 | if ((event_subtype._type > (_max))) { \ | 72 | ({ \ |
71 | printk(KERN_WARNING \ | 73 | const sctp_sm_table_entry_t *rtn; \ |
72 | "sctp table %p possible attack:" \ | 74 | \ |
73 | " event %d exceeds max %d\n", \ | 75 | if ((event_subtype._type > (_max))) { \ |
74 | _table, event_subtype._type, _max); \ | 76 | pr_warn("table %p possible attack: event %d exceeds max %d\n", \ |
75 | return &bug; \ | 77 | _table, event_subtype._type, _max); \ |
76 | } \ | 78 | rtn = &bug; \ |
77 | return &_table[event_subtype._type][(int)state]; | 79 | } else \ |
80 | rtn = &_table[event_subtype._type][(int)state]; \ | ||
81 | \ | ||
82 | rtn; \ | ||
83 | }) | ||
78 | 84 | ||
79 | const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, | 85 | const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, |
80 | sctp_state_t state, | 86 | sctp_state_t state, |
@@ -83,21 +89,15 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, | |||
83 | switch (event_type) { | 89 | switch (event_type) { |
84 | case SCTP_EVENT_T_CHUNK: | 90 | case SCTP_EVENT_T_CHUNK: |
85 | return sctp_chunk_event_lookup(event_subtype.chunk, state); | 91 | return sctp_chunk_event_lookup(event_subtype.chunk, state); |
86 | break; | ||
87 | case SCTP_EVENT_T_TIMEOUT: | 92 | case SCTP_EVENT_T_TIMEOUT: |
88 | DO_LOOKUP(SCTP_EVENT_TIMEOUT_MAX, timeout, | 93 | return DO_LOOKUP(SCTP_EVENT_TIMEOUT_MAX, timeout, |
89 | timeout_event_table); | 94 | timeout_event_table); |
90 | break; | ||
91 | |||
92 | case SCTP_EVENT_T_OTHER: | 95 | case SCTP_EVENT_T_OTHER: |
93 | DO_LOOKUP(SCTP_EVENT_OTHER_MAX, other, other_event_table); | 96 | return DO_LOOKUP(SCTP_EVENT_OTHER_MAX, other, |
94 | break; | 97 | other_event_table); |
95 | |||
96 | case SCTP_EVENT_T_PRIMITIVE: | 98 | case SCTP_EVENT_T_PRIMITIVE: |
97 | DO_LOOKUP(SCTP_EVENT_PRIMITIVE_MAX, primitive, | 99 | return DO_LOOKUP(SCTP_EVENT_PRIMITIVE_MAX, primitive, |
98 | primitive_event_table); | 100 | primitive_event_table); |
99 | break; | ||
100 | |||
101 | default: | 101 | default: |
102 | /* Yikes! We got an illegal event type. */ | 102 | /* Yikes! We got an illegal event type. */ |
103 | return &bug; | 103 | return &bug; |
@@ -107,8 +107,6 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, | |||
107 | #define TYPE_SCTP_FUNC(func) {.fn = func, .name = #func} | 107 | #define TYPE_SCTP_FUNC(func) {.fn = func, .name = #func} |
108 | 108 | ||
109 | #define TYPE_SCTP_DATA { \ | 109 | #define TYPE_SCTP_DATA { \ |
110 | /* SCTP_STATE_EMPTY */ \ | ||
111 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ | ||
112 | /* SCTP_STATE_CLOSED */ \ | 110 | /* SCTP_STATE_CLOSED */ \ |
113 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ | 111 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ |
114 | /* SCTP_STATE_COOKIE_WAIT */ \ | 112 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -128,8 +126,6 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, | |||
128 | } /* TYPE_SCTP_DATA */ | 126 | } /* TYPE_SCTP_DATA */ |
129 | 127 | ||
130 | #define TYPE_SCTP_INIT { \ | 128 | #define TYPE_SCTP_INIT { \ |
131 | /* SCTP_STATE_EMPTY */ \ | ||
132 | TYPE_SCTP_FUNC(sctp_sf_bug), \ | ||
133 | /* SCTP_STATE_CLOSED */ \ | 129 | /* SCTP_STATE_CLOSED */ \ |
134 | TYPE_SCTP_FUNC(sctp_sf_do_5_1B_init), \ | 130 | TYPE_SCTP_FUNC(sctp_sf_do_5_1B_init), \ |
135 | /* SCTP_STATE_COOKIE_WAIT */ \ | 131 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -149,8 +145,6 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, | |||
149 | } /* TYPE_SCTP_INIT */ | 145 | } /* TYPE_SCTP_INIT */ |
150 | 146 | ||
151 | #define TYPE_SCTP_INIT_ACK { \ | 147 | #define TYPE_SCTP_INIT_ACK { \ |
152 | /* SCTP_STATE_EMPTY */ \ | ||
153 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ | ||
154 | /* SCTP_STATE_CLOSED */ \ | 148 | /* SCTP_STATE_CLOSED */ \ |
155 | TYPE_SCTP_FUNC(sctp_sf_do_5_2_3_initack), \ | 149 | TYPE_SCTP_FUNC(sctp_sf_do_5_2_3_initack), \ |
156 | /* SCTP_STATE_COOKIE_WAIT */ \ | 150 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -170,8 +164,6 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, | |||
170 | } /* TYPE_SCTP_INIT_ACK */ | 164 | } /* TYPE_SCTP_INIT_ACK */ |
171 | 165 | ||
172 | #define TYPE_SCTP_SACK { \ | 166 | #define TYPE_SCTP_SACK { \ |
173 | /* SCTP_STATE_EMPTY */ \ | ||
174 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ | ||
175 | /* SCTP_STATE_CLOSED */ \ | 167 | /* SCTP_STATE_CLOSED */ \ |
176 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ | 168 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ |
177 | /* SCTP_STATE_COOKIE_WAIT */ \ | 169 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -191,8 +183,6 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, | |||
191 | } /* TYPE_SCTP_SACK */ | 183 | } /* TYPE_SCTP_SACK */ |
192 | 184 | ||
193 | #define TYPE_SCTP_HEARTBEAT { \ | 185 | #define TYPE_SCTP_HEARTBEAT { \ |
194 | /* SCTP_STATE_EMPTY */ \ | ||
195 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ | ||
196 | /* SCTP_STATE_CLOSED */ \ | 186 | /* SCTP_STATE_CLOSED */ \ |
197 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ | 187 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ |
198 | /* SCTP_STATE_COOKIE_WAIT */ \ | 188 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -213,8 +203,6 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, | |||
213 | } /* TYPE_SCTP_HEARTBEAT */ | 203 | } /* TYPE_SCTP_HEARTBEAT */ |
214 | 204 | ||
215 | #define TYPE_SCTP_HEARTBEAT_ACK { \ | 205 | #define TYPE_SCTP_HEARTBEAT_ACK { \ |
216 | /* SCTP_STATE_EMPTY */ \ | ||
217 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ | ||
218 | /* SCTP_STATE_CLOSED */ \ | 206 | /* SCTP_STATE_CLOSED */ \ |
219 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ | 207 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ |
220 | /* SCTP_STATE_COOKIE_WAIT */ \ | 208 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -234,8 +222,6 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, | |||
234 | } /* TYPE_SCTP_HEARTBEAT_ACK */ | 222 | } /* TYPE_SCTP_HEARTBEAT_ACK */ |
235 | 223 | ||
236 | #define TYPE_SCTP_ABORT { \ | 224 | #define TYPE_SCTP_ABORT { \ |
237 | /* SCTP_STATE_EMPTY */ \ | ||
238 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ | ||
239 | /* SCTP_STATE_CLOSED */ \ | 225 | /* SCTP_STATE_CLOSED */ \ |
240 | TYPE_SCTP_FUNC(sctp_sf_pdiscard), \ | 226 | TYPE_SCTP_FUNC(sctp_sf_pdiscard), \ |
241 | /* SCTP_STATE_COOKIE_WAIT */ \ | 227 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -255,8 +241,6 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, | |||
255 | } /* TYPE_SCTP_ABORT */ | 241 | } /* TYPE_SCTP_ABORT */ |
256 | 242 | ||
257 | #define TYPE_SCTP_SHUTDOWN { \ | 243 | #define TYPE_SCTP_SHUTDOWN { \ |
258 | /* SCTP_STATE_EMPTY */ \ | ||
259 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ | ||
260 | /* SCTP_STATE_CLOSED */ \ | 244 | /* SCTP_STATE_CLOSED */ \ |
261 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ | 245 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ |
262 | /* SCTP_STATE_COOKIE_WAIT */ \ | 246 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -276,8 +260,6 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, | |||
276 | } /* TYPE_SCTP_SHUTDOWN */ | 260 | } /* TYPE_SCTP_SHUTDOWN */ |
277 | 261 | ||
278 | #define TYPE_SCTP_SHUTDOWN_ACK { \ | 262 | #define TYPE_SCTP_SHUTDOWN_ACK { \ |
279 | /* SCTP_STATE_EMPTY */ \ | ||
280 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ | ||
281 | /* SCTP_STATE_CLOSED */ \ | 263 | /* SCTP_STATE_CLOSED */ \ |
282 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ | 264 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ |
283 | /* SCTP_STATE_COOKIE_WAIT */ \ | 265 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -297,8 +279,6 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, | |||
297 | } /* TYPE_SCTP_SHUTDOWN_ACK */ | 279 | } /* TYPE_SCTP_SHUTDOWN_ACK */ |
298 | 280 | ||
299 | #define TYPE_SCTP_ERROR { \ | 281 | #define TYPE_SCTP_ERROR { \ |
300 | /* SCTP_STATE_EMPTY */ \ | ||
301 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ | ||
302 | /* SCTP_STATE_CLOSED */ \ | 282 | /* SCTP_STATE_CLOSED */ \ |
303 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ | 283 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ |
304 | /* SCTP_STATE_COOKIE_WAIT */ \ | 284 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -318,8 +298,6 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, | |||
318 | } /* TYPE_SCTP_ERROR */ | 298 | } /* TYPE_SCTP_ERROR */ |
319 | 299 | ||
320 | #define TYPE_SCTP_COOKIE_ECHO { \ | 300 | #define TYPE_SCTP_COOKIE_ECHO { \ |
321 | /* SCTP_STATE_EMPTY */ \ | ||
322 | TYPE_SCTP_FUNC(sctp_sf_bug), \ | ||
323 | /* SCTP_STATE_CLOSED */ \ | 301 | /* SCTP_STATE_CLOSED */ \ |
324 | TYPE_SCTP_FUNC(sctp_sf_do_5_1D_ce), \ | 302 | TYPE_SCTP_FUNC(sctp_sf_do_5_1D_ce), \ |
325 | /* SCTP_STATE_COOKIE_WAIT */ \ | 303 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -339,8 +317,6 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, | |||
339 | } /* TYPE_SCTP_COOKIE_ECHO */ | 317 | } /* TYPE_SCTP_COOKIE_ECHO */ |
340 | 318 | ||
341 | #define TYPE_SCTP_COOKIE_ACK { \ | 319 | #define TYPE_SCTP_COOKIE_ACK { \ |
342 | /* SCTP_STATE_EMPTY */ \ | ||
343 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ | ||
344 | /* SCTP_STATE_CLOSED */ \ | 320 | /* SCTP_STATE_CLOSED */ \ |
345 | TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \ | 321 | TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \ |
346 | /* SCTP_STATE_COOKIE_WAIT */ \ | 322 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -360,8 +336,6 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, | |||
360 | } /* TYPE_SCTP_COOKIE_ACK */ | 336 | } /* TYPE_SCTP_COOKIE_ACK */ |
361 | 337 | ||
362 | #define TYPE_SCTP_ECN_ECNE { \ | 338 | #define TYPE_SCTP_ECN_ECNE { \ |
363 | /* SCTP_STATE_EMPTY */ \ | ||
364 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ | ||
365 | /* SCTP_STATE_CLOSED */ \ | 339 | /* SCTP_STATE_CLOSED */ \ |
366 | TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \ | 340 | TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \ |
367 | /* SCTP_STATE_COOKIE_WAIT */ \ | 341 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -381,8 +355,6 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, | |||
381 | } /* TYPE_SCTP_ECN_ECNE */ | 355 | } /* TYPE_SCTP_ECN_ECNE */ |
382 | 356 | ||
383 | #define TYPE_SCTP_ECN_CWR { \ | 357 | #define TYPE_SCTP_ECN_CWR { \ |
384 | /* SCTP_STATE_EMPTY */ \ | ||
385 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ | ||
386 | /* SCTP_STATE_CLOSED */ \ | 358 | /* SCTP_STATE_CLOSED */ \ |
387 | TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \ | 359 | TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \ |
388 | /* SCTP_STATE_COOKIE_WAIT */ \ | 360 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -402,8 +374,6 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, | |||
402 | } /* TYPE_SCTP_ECN_CWR */ | 374 | } /* TYPE_SCTP_ECN_CWR */ |
403 | 375 | ||
404 | #define TYPE_SCTP_SHUTDOWN_COMPLETE { \ | 376 | #define TYPE_SCTP_SHUTDOWN_COMPLETE { \ |
405 | /* SCTP_STATE_EMPTY */ \ | ||
406 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ | ||
407 | /* SCTP_STATE_CLOSED */ \ | 377 | /* SCTP_STATE_CLOSED */ \ |
408 | TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \ | 378 | TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \ |
409 | /* SCTP_STATE_COOKIE_WAIT */ \ | 379 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -446,8 +416,6 @@ static const sctp_sm_table_entry_t chunk_event_table[SCTP_NUM_BASE_CHUNK_TYPES][ | |||
446 | }; /* state_fn_t chunk_event_table[][] */ | 416 | }; /* state_fn_t chunk_event_table[][] */ |
447 | 417 | ||
448 | #define TYPE_SCTP_ASCONF { \ | 418 | #define TYPE_SCTP_ASCONF { \ |
449 | /* SCTP_STATE_EMPTY */ \ | ||
450 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ | ||
451 | /* SCTP_STATE_CLOSED */ \ | 419 | /* SCTP_STATE_CLOSED */ \ |
452 | TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \ | 420 | TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \ |
453 | /* SCTP_STATE_COOKIE_WAIT */ \ | 421 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -467,8 +435,6 @@ static const sctp_sm_table_entry_t chunk_event_table[SCTP_NUM_BASE_CHUNK_TYPES][ | |||
467 | } /* TYPE_SCTP_ASCONF */ | 435 | } /* TYPE_SCTP_ASCONF */ |
468 | 436 | ||
469 | #define TYPE_SCTP_ASCONF_ACK { \ | 437 | #define TYPE_SCTP_ASCONF_ACK { \ |
470 | /* SCTP_STATE_EMPTY */ \ | ||
471 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ | ||
472 | /* SCTP_STATE_CLOSED */ \ | 438 | /* SCTP_STATE_CLOSED */ \ |
473 | TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \ | 439 | TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \ |
474 | /* SCTP_STATE_COOKIE_WAIT */ \ | 440 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -496,8 +462,6 @@ static const sctp_sm_table_entry_t addip_chunk_event_table[SCTP_NUM_ADDIP_CHUNK_ | |||
496 | }; /*state_fn_t addip_chunk_event_table[][] */ | 462 | }; /*state_fn_t addip_chunk_event_table[][] */ |
497 | 463 | ||
498 | #define TYPE_SCTP_FWD_TSN { \ | 464 | #define TYPE_SCTP_FWD_TSN { \ |
499 | /* SCTP_STATE_EMPTY */ \ | ||
500 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ | ||
501 | /* SCTP_STATE_CLOSED */ \ | 465 | /* SCTP_STATE_CLOSED */ \ |
502 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ | 466 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ |
503 | /* SCTP_STATE_COOKIE_WAIT */ \ | 467 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -524,8 +488,6 @@ static const sctp_sm_table_entry_t prsctp_chunk_event_table[SCTP_NUM_PRSCTP_CHUN | |||
524 | }; /*state_fn_t prsctp_chunk_event_table[][] */ | 488 | }; /*state_fn_t prsctp_chunk_event_table[][] */ |
525 | 489 | ||
526 | #define TYPE_SCTP_AUTH { \ | 490 | #define TYPE_SCTP_AUTH { \ |
527 | /* SCTP_STATE_EMPTY */ \ | ||
528 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ | ||
529 | /* SCTP_STATE_CLOSED */ \ | 491 | /* SCTP_STATE_CLOSED */ \ |
530 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ | 492 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ |
531 | /* SCTP_STATE_COOKIE_WAIT */ \ | 493 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -553,8 +515,6 @@ static const sctp_sm_table_entry_t auth_chunk_event_table[SCTP_NUM_AUTH_CHUNK_TY | |||
553 | 515 | ||
554 | static const sctp_sm_table_entry_t | 516 | static const sctp_sm_table_entry_t |
555 | chunk_event_table_unknown[SCTP_STATE_NUM_STATES] = { | 517 | chunk_event_table_unknown[SCTP_STATE_NUM_STATES] = { |
556 | /* SCTP_STATE_EMPTY */ | ||
557 | TYPE_SCTP_FUNC(sctp_sf_ootb), | ||
558 | /* SCTP_STATE_CLOSED */ | 518 | /* SCTP_STATE_CLOSED */ |
559 | TYPE_SCTP_FUNC(sctp_sf_ootb), | 519 | TYPE_SCTP_FUNC(sctp_sf_ootb), |
560 | /* SCTP_STATE_COOKIE_WAIT */ | 520 | /* SCTP_STATE_COOKIE_WAIT */ |
@@ -575,8 +535,6 @@ chunk_event_table_unknown[SCTP_STATE_NUM_STATES] = { | |||
575 | 535 | ||
576 | 536 | ||
577 | #define TYPE_SCTP_PRIMITIVE_ASSOCIATE { \ | 537 | #define TYPE_SCTP_PRIMITIVE_ASSOCIATE { \ |
578 | /* SCTP_STATE_EMPTY */ \ | ||
579 | TYPE_SCTP_FUNC(sctp_sf_bug), \ | ||
580 | /* SCTP_STATE_CLOSED */ \ | 538 | /* SCTP_STATE_CLOSED */ \ |
581 | TYPE_SCTP_FUNC(sctp_sf_do_prm_asoc), \ | 539 | TYPE_SCTP_FUNC(sctp_sf_do_prm_asoc), \ |
582 | /* SCTP_STATE_COOKIE_WAIT */ \ | 540 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -596,8 +554,6 @@ chunk_event_table_unknown[SCTP_STATE_NUM_STATES] = { | |||
596 | } /* TYPE_SCTP_PRIMITIVE_ASSOCIATE */ | 554 | } /* TYPE_SCTP_PRIMITIVE_ASSOCIATE */ |
597 | 555 | ||
598 | #define TYPE_SCTP_PRIMITIVE_SHUTDOWN { \ | 556 | #define TYPE_SCTP_PRIMITIVE_SHUTDOWN { \ |
599 | /* SCTP_STATE_EMPTY */ \ | ||
600 | TYPE_SCTP_FUNC(sctp_sf_bug), \ | ||
601 | /* SCTP_STATE_CLOSED */ \ | 557 | /* SCTP_STATE_CLOSED */ \ |
602 | TYPE_SCTP_FUNC(sctp_sf_error_closed), \ | 558 | TYPE_SCTP_FUNC(sctp_sf_error_closed), \ |
603 | /* SCTP_STATE_COOKIE_WAIT */ \ | 559 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -617,8 +573,6 @@ chunk_event_table_unknown[SCTP_STATE_NUM_STATES] = { | |||
617 | } /* TYPE_SCTP_PRIMITIVE_SHUTDOWN */ | 573 | } /* TYPE_SCTP_PRIMITIVE_SHUTDOWN */ |
618 | 574 | ||
619 | #define TYPE_SCTP_PRIMITIVE_ABORT { \ | 575 | #define TYPE_SCTP_PRIMITIVE_ABORT { \ |
620 | /* SCTP_STATE_EMPTY */ \ | ||
621 | TYPE_SCTP_FUNC(sctp_sf_bug), \ | ||
622 | /* SCTP_STATE_CLOSED */ \ | 576 | /* SCTP_STATE_CLOSED */ \ |
623 | TYPE_SCTP_FUNC(sctp_sf_error_closed), \ | 577 | TYPE_SCTP_FUNC(sctp_sf_error_closed), \ |
624 | /* SCTP_STATE_COOKIE_WAIT */ \ | 578 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -638,8 +592,6 @@ chunk_event_table_unknown[SCTP_STATE_NUM_STATES] = { | |||
638 | } /* TYPE_SCTP_PRIMITIVE_ABORT */ | 592 | } /* TYPE_SCTP_PRIMITIVE_ABORT */ |
639 | 593 | ||
640 | #define TYPE_SCTP_PRIMITIVE_SEND { \ | 594 | #define TYPE_SCTP_PRIMITIVE_SEND { \ |
641 | /* SCTP_STATE_EMPTY */ \ | ||
642 | TYPE_SCTP_FUNC(sctp_sf_bug), \ | ||
643 | /* SCTP_STATE_CLOSED */ \ | 595 | /* SCTP_STATE_CLOSED */ \ |
644 | TYPE_SCTP_FUNC(sctp_sf_error_closed), \ | 596 | TYPE_SCTP_FUNC(sctp_sf_error_closed), \ |
645 | /* SCTP_STATE_COOKIE_WAIT */ \ | 597 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -659,8 +611,6 @@ chunk_event_table_unknown[SCTP_STATE_NUM_STATES] = { | |||
659 | } /* TYPE_SCTP_PRIMITIVE_SEND */ | 611 | } /* TYPE_SCTP_PRIMITIVE_SEND */ |
660 | 612 | ||
661 | #define TYPE_SCTP_PRIMITIVE_REQUESTHEARTBEAT { \ | 613 | #define TYPE_SCTP_PRIMITIVE_REQUESTHEARTBEAT { \ |
662 | /* SCTP_STATE_EMPTY */ \ | ||
663 | TYPE_SCTP_FUNC(sctp_sf_bug), \ | ||
664 | /* SCTP_STATE_CLOSED */ \ | 614 | /* SCTP_STATE_CLOSED */ \ |
665 | TYPE_SCTP_FUNC(sctp_sf_error_closed), \ | 615 | TYPE_SCTP_FUNC(sctp_sf_error_closed), \ |
666 | /* SCTP_STATE_COOKIE_WAIT */ \ | 616 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -680,8 +630,6 @@ chunk_event_table_unknown[SCTP_STATE_NUM_STATES] = { | |||
680 | } /* TYPE_SCTP_PRIMITIVE_REQUESTHEARTBEAT */ | 630 | } /* TYPE_SCTP_PRIMITIVE_REQUESTHEARTBEAT */ |
681 | 631 | ||
682 | #define TYPE_SCTP_PRIMITIVE_ASCONF { \ | 632 | #define TYPE_SCTP_PRIMITIVE_ASCONF { \ |
683 | /* SCTP_STATE_EMPTY */ \ | ||
684 | TYPE_SCTP_FUNC(sctp_sf_bug), \ | ||
685 | /* SCTP_STATE_CLOSED */ \ | 633 | /* SCTP_STATE_CLOSED */ \ |
686 | TYPE_SCTP_FUNC(sctp_sf_error_closed), \ | 634 | TYPE_SCTP_FUNC(sctp_sf_error_closed), \ |
687 | /* SCTP_STATE_COOKIE_WAIT */ \ | 635 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -713,8 +661,6 @@ static const sctp_sm_table_entry_t primitive_event_table[SCTP_NUM_PRIMITIVE_TYPE | |||
713 | }; | 661 | }; |
714 | 662 | ||
715 | #define TYPE_SCTP_OTHER_NO_PENDING_TSN { \ | 663 | #define TYPE_SCTP_OTHER_NO_PENDING_TSN { \ |
716 | /* SCTP_STATE_EMPTY */ \ | ||
717 | TYPE_SCTP_FUNC(sctp_sf_bug), \ | ||
718 | /* SCTP_STATE_CLOSED */ \ | 664 | /* SCTP_STATE_CLOSED */ \ |
719 | TYPE_SCTP_FUNC(sctp_sf_ignore_other), \ | 665 | TYPE_SCTP_FUNC(sctp_sf_ignore_other), \ |
720 | /* SCTP_STATE_COOKIE_WAIT */ \ | 666 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -722,7 +668,7 @@ static const sctp_sm_table_entry_t primitive_event_table[SCTP_NUM_PRIMITIVE_TYPE | |||
722 | /* SCTP_STATE_COOKIE_ECHOED */ \ | 668 | /* SCTP_STATE_COOKIE_ECHOED */ \ |
723 | TYPE_SCTP_FUNC(sctp_sf_ignore_other), \ | 669 | TYPE_SCTP_FUNC(sctp_sf_ignore_other), \ |
724 | /* SCTP_STATE_ESTABLISHED */ \ | 670 | /* SCTP_STATE_ESTABLISHED */ \ |
725 | TYPE_SCTP_FUNC(sctp_sf_ignore_other), \ | 671 | TYPE_SCTP_FUNC(sctp_sf_do_no_pending_tsn), \ |
726 | /* SCTP_STATE_SHUTDOWN_PENDING */ \ | 672 | /* SCTP_STATE_SHUTDOWN_PENDING */ \ |
727 | TYPE_SCTP_FUNC(sctp_sf_do_9_2_start_shutdown), \ | 673 | TYPE_SCTP_FUNC(sctp_sf_do_9_2_start_shutdown), \ |
728 | /* SCTP_STATE_SHUTDOWN_SENT */ \ | 674 | /* SCTP_STATE_SHUTDOWN_SENT */ \ |
@@ -734,8 +680,6 @@ static const sctp_sm_table_entry_t primitive_event_table[SCTP_NUM_PRIMITIVE_TYPE | |||
734 | } | 680 | } |
735 | 681 | ||
736 | #define TYPE_SCTP_OTHER_ICMP_PROTO_UNREACH { \ | 682 | #define TYPE_SCTP_OTHER_ICMP_PROTO_UNREACH { \ |
737 | /* SCTP_STATE_EMPTY */ \ | ||
738 | TYPE_SCTP_FUNC(sctp_sf_bug), \ | ||
739 | /* SCTP_STATE_CLOSED */ \ | 683 | /* SCTP_STATE_CLOSED */ \ |
740 | TYPE_SCTP_FUNC(sctp_sf_ignore_other), \ | 684 | TYPE_SCTP_FUNC(sctp_sf_ignore_other), \ |
741 | /* SCTP_STATE_COOKIE_WAIT */ \ | 685 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -760,8 +704,6 @@ static const sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_ | |||
760 | }; | 704 | }; |
761 | 705 | ||
762 | #define TYPE_SCTP_EVENT_TIMEOUT_NONE { \ | 706 | #define TYPE_SCTP_EVENT_TIMEOUT_NONE { \ |
763 | /* SCTP_STATE_EMPTY */ \ | ||
764 | TYPE_SCTP_FUNC(sctp_sf_bug), \ | ||
765 | /* SCTP_STATE_CLOSED */ \ | 707 | /* SCTP_STATE_CLOSED */ \ |
766 | TYPE_SCTP_FUNC(sctp_sf_bug), \ | 708 | TYPE_SCTP_FUNC(sctp_sf_bug), \ |
767 | /* SCTP_STATE_COOKIE_WAIT */ \ | 709 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -781,8 +723,6 @@ static const sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_ | |||
781 | } | 723 | } |
782 | 724 | ||
783 | #define TYPE_SCTP_EVENT_TIMEOUT_T1_COOKIE { \ | 725 | #define TYPE_SCTP_EVENT_TIMEOUT_T1_COOKIE { \ |
784 | /* SCTP_STATE_EMPTY */ \ | ||
785 | TYPE_SCTP_FUNC(sctp_sf_bug), \ | ||
786 | /* SCTP_STATE_CLOSED */ \ | 726 | /* SCTP_STATE_CLOSED */ \ |
787 | TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \ | 727 | TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \ |
788 | /* SCTP_STATE_COOKIE_WAIT */ \ | 728 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -802,8 +742,6 @@ static const sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_ | |||
802 | } | 742 | } |
803 | 743 | ||
804 | #define TYPE_SCTP_EVENT_TIMEOUT_T1_INIT { \ | 744 | #define TYPE_SCTP_EVENT_TIMEOUT_T1_INIT { \ |
805 | /* SCTP_STATE_EMPTY */ \ | ||
806 | TYPE_SCTP_FUNC(sctp_sf_bug), \ | ||
807 | /* SCTP_STATE_CLOSED */ \ | 745 | /* SCTP_STATE_CLOSED */ \ |
808 | TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \ | 746 | TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \ |
809 | /* SCTP_STATE_COOKIE_WAIT */ \ | 747 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -823,8 +761,6 @@ static const sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_ | |||
823 | } | 761 | } |
824 | 762 | ||
825 | #define TYPE_SCTP_EVENT_TIMEOUT_T2_SHUTDOWN { \ | 763 | #define TYPE_SCTP_EVENT_TIMEOUT_T2_SHUTDOWN { \ |
826 | /* SCTP_STATE_EMPTY */ \ | ||
827 | TYPE_SCTP_FUNC(sctp_sf_bug), \ | ||
828 | /* SCTP_STATE_CLOSED */ \ | 764 | /* SCTP_STATE_CLOSED */ \ |
829 | TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \ | 765 | TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \ |
830 | /* SCTP_STATE_COOKIE_WAIT */ \ | 766 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -844,8 +780,6 @@ static const sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_ | |||
844 | } | 780 | } |
845 | 781 | ||
846 | #define TYPE_SCTP_EVENT_TIMEOUT_T3_RTX { \ | 782 | #define TYPE_SCTP_EVENT_TIMEOUT_T3_RTX { \ |
847 | /* SCTP_STATE_EMPTY */ \ | ||
848 | TYPE_SCTP_FUNC(sctp_sf_bug), \ | ||
849 | /* SCTP_STATE_CLOSED */ \ | 783 | /* SCTP_STATE_CLOSED */ \ |
850 | TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \ | 784 | TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \ |
851 | /* SCTP_STATE_COOKIE_WAIT */ \ | 785 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -865,8 +799,6 @@ static const sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_ | |||
865 | } | 799 | } |
866 | 800 | ||
867 | #define TYPE_SCTP_EVENT_TIMEOUT_T4_RTO { \ | 801 | #define TYPE_SCTP_EVENT_TIMEOUT_T4_RTO { \ |
868 | /* SCTP_STATE_EMPTY */ \ | ||
869 | TYPE_SCTP_FUNC(sctp_sf_bug), \ | ||
870 | /* SCTP_STATE_CLOSED */ \ | 802 | /* SCTP_STATE_CLOSED */ \ |
871 | TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \ | 803 | TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \ |
872 | /* SCTP_STATE_COOKIE_WAIT */ \ | 804 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -886,8 +818,6 @@ static const sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_ | |||
886 | } | 818 | } |
887 | 819 | ||
888 | #define TYPE_SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD { \ | 820 | #define TYPE_SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD { \ |
889 | /* SCTP_STATE_EMPTY */ \ | ||
890 | TYPE_SCTP_FUNC(sctp_sf_bug), \ | ||
891 | /* SCTP_STATE_CLOSED */ \ | 821 | /* SCTP_STATE_CLOSED */ \ |
892 | TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \ | 822 | TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \ |
893 | /* SCTP_STATE_COOKIE_WAIT */ \ | 823 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -897,7 +827,7 @@ static const sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_ | |||
897 | /* SCTP_STATE_ESTABLISHED */ \ | 827 | /* SCTP_STATE_ESTABLISHED */ \ |
898 | TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \ | 828 | TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \ |
899 | /* SCTP_STATE_SHUTDOWN_PENDING */ \ | 829 | /* SCTP_STATE_SHUTDOWN_PENDING */ \ |
900 | TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \ | 830 | TYPE_SCTP_FUNC(sctp_sf_t5_timer_expire), \ |
901 | /* SCTP_STATE_SHUTDOWN_SENT */ \ | 831 | /* SCTP_STATE_SHUTDOWN_SENT */ \ |
902 | TYPE_SCTP_FUNC(sctp_sf_t5_timer_expire), \ | 832 | TYPE_SCTP_FUNC(sctp_sf_t5_timer_expire), \ |
903 | /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ | 833 | /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ |
@@ -907,8 +837,6 @@ static const sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_ | |||
907 | } | 837 | } |
908 | 838 | ||
909 | #define TYPE_SCTP_EVENT_TIMEOUT_HEARTBEAT { \ | 839 | #define TYPE_SCTP_EVENT_TIMEOUT_HEARTBEAT { \ |
910 | /* SCTP_STATE_EMPTY */ \ | ||
911 | TYPE_SCTP_FUNC(sctp_sf_bug), \ | ||
912 | /* SCTP_STATE_CLOSED */ \ | 840 | /* SCTP_STATE_CLOSED */ \ |
913 | TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \ | 841 | TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \ |
914 | /* SCTP_STATE_COOKIE_WAIT */ \ | 842 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -928,8 +856,6 @@ static const sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_ | |||
928 | } | 856 | } |
929 | 857 | ||
930 | #define TYPE_SCTP_EVENT_TIMEOUT_SACK { \ | 858 | #define TYPE_SCTP_EVENT_TIMEOUT_SACK { \ |
931 | /* SCTP_STATE_EMPTY */ \ | ||
932 | TYPE_SCTP_FUNC(sctp_sf_bug), \ | ||
933 | /* SCTP_STATE_CLOSED */ \ | 859 | /* SCTP_STATE_CLOSED */ \ |
934 | TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \ | 860 | TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \ |
935 | /* SCTP_STATE_COOKIE_WAIT */ \ | 861 | /* SCTP_STATE_COOKIE_WAIT */ \ |
@@ -949,8 +875,6 @@ static const sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_ | |||
949 | } | 875 | } |
950 | 876 | ||
951 | #define TYPE_SCTP_EVENT_TIMEOUT_AUTOCLOSE { \ | 877 | #define TYPE_SCTP_EVENT_TIMEOUT_AUTOCLOSE { \ |
952 | /* SCTP_STATE_EMPTY */ \ | ||
953 | TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \ | ||
954 | /* SCTP_STATE_CLOSED */ \ | 878 | /* SCTP_STATE_CLOSED */ \ |
955 | TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \ | 879 | TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \ |
956 | /* SCTP_STATE_COOKIE_WAIT */ \ | 880 | /* SCTP_STATE_COOKIE_WAIT */ \ |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index fbb70770ad05..d3ccf7973c59 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -57,6 +57,8 @@ | |||
57 | * be incorporated into the next SCTP release. | 57 | * be incorporated into the next SCTP release. |
58 | */ | 58 | */ |
59 | 59 | ||
60 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
61 | |||
60 | #include <linux/types.h> | 62 | #include <linux/types.h> |
61 | #include <linux/kernel.h> | 63 | #include <linux/kernel.h> |
62 | #include <linux/wait.h> | 64 | #include <linux/wait.h> |
@@ -109,12 +111,12 @@ static void sctp_sock_migrate(struct sock *, struct sock *, | |||
109 | static char *sctp_hmac_alg = SCTP_COOKIE_HMAC_ALG; | 111 | static char *sctp_hmac_alg = SCTP_COOKIE_HMAC_ALG; |
110 | 112 | ||
111 | extern struct kmem_cache *sctp_bucket_cachep; | 113 | extern struct kmem_cache *sctp_bucket_cachep; |
112 | extern int sysctl_sctp_mem[3]; | 114 | extern long sysctl_sctp_mem[3]; |
113 | extern int sysctl_sctp_rmem[3]; | 115 | extern int sysctl_sctp_rmem[3]; |
114 | extern int sysctl_sctp_wmem[3]; | 116 | extern int sysctl_sctp_wmem[3]; |
115 | 117 | ||
116 | static int sctp_memory_pressure; | 118 | static int sctp_memory_pressure; |
117 | static atomic_t sctp_memory_allocated; | 119 | static atomic_long_t sctp_memory_allocated; |
118 | struct percpu_counter sctp_sockets_allocated; | 120 | struct percpu_counter sctp_sockets_allocated; |
119 | 121 | ||
120 | static void sctp_enter_memory_pressure(struct sock *sk) | 122 | static void sctp_enter_memory_pressure(struct sock *sk) |
@@ -656,11 +658,15 @@ static int sctp_bindx_rem(struct sock *sk, struct sockaddr *addrs, int addrcnt) | |||
656 | goto err_bindx_rem; | 658 | goto err_bindx_rem; |
657 | } | 659 | } |
658 | 660 | ||
659 | if (sa_addr->v4.sin_port != htons(bp->port)) { | 661 | if (sa_addr->v4.sin_port && |
662 | sa_addr->v4.sin_port != htons(bp->port)) { | ||
660 | retval = -EINVAL; | 663 | retval = -EINVAL; |
661 | goto err_bindx_rem; | 664 | goto err_bindx_rem; |
662 | } | 665 | } |
663 | 666 | ||
667 | if (!sa_addr->v4.sin_port) | ||
668 | sa_addr->v4.sin_port = htons(bp->port); | ||
669 | |||
664 | /* FIXME - There is probably a need to check if sk->sk_saddr and | 670 | /* FIXME - There is probably a need to check if sk->sk_saddr and |
665 | * sk->sk_rcv_addr are currently set to one of the addresses to | 671 | * sk->sk_rcv_addr are currently set to one of the addresses to |
666 | * be removed. This is something which needs to be looked into | 672 | * be removed. This is something which needs to be looked into |
@@ -1191,7 +1197,7 @@ out_free: | |||
1191 | * an endpoint that is multi-homed. Much like sctp_bindx() this call | 1197 | * an endpoint that is multi-homed. Much like sctp_bindx() this call |
1192 | * allows a caller to specify multiple addresses at which a peer can be | 1198 | * allows a caller to specify multiple addresses at which a peer can be |
1193 | * reached. The way the SCTP stack uses the list of addresses to set up | 1199 | * reached. The way the SCTP stack uses the list of addresses to set up |
1194 | * the association is implementation dependant. This function only | 1200 | * the association is implementation dependent. This function only |
1195 | * specifies that the stack will try to make use of all the addresses in | 1201 | * specifies that the stack will try to make use of all the addresses in |
1196 | * the list when needed. | 1202 | * the list when needed. |
1197 | * | 1203 | * |
@@ -1378,6 +1384,7 @@ SCTP_STATIC void sctp_close(struct sock *sk, long timeout) | |||
1378 | struct sctp_endpoint *ep; | 1384 | struct sctp_endpoint *ep; |
1379 | struct sctp_association *asoc; | 1385 | struct sctp_association *asoc; |
1380 | struct list_head *pos, *temp; | 1386 | struct list_head *pos, *temp; |
1387 | unsigned int data_was_unread; | ||
1381 | 1388 | ||
1382 | SCTP_DEBUG_PRINTK("sctp_close(sk: 0x%p, timeout:%ld)\n", sk, timeout); | 1389 | SCTP_DEBUG_PRINTK("sctp_close(sk: 0x%p, timeout:%ld)\n", sk, timeout); |
1383 | 1390 | ||
@@ -1387,6 +1394,10 @@ SCTP_STATIC void sctp_close(struct sock *sk, long timeout) | |||
1387 | 1394 | ||
1388 | ep = sctp_sk(sk)->ep; | 1395 | ep = sctp_sk(sk)->ep; |
1389 | 1396 | ||
1397 | /* Clean up any skbs sitting on the receive queue. */ | ||
1398 | data_was_unread = sctp_queue_purge_ulpevents(&sk->sk_receive_queue); | ||
1399 | data_was_unread += sctp_queue_purge_ulpevents(&sctp_sk(sk)->pd_lobby); | ||
1400 | |||
1390 | /* Walk all associations on an endpoint. */ | 1401 | /* Walk all associations on an endpoint. */ |
1391 | list_for_each_safe(pos, temp, &ep->asocs) { | 1402 | list_for_each_safe(pos, temp, &ep->asocs) { |
1392 | asoc = list_entry(pos, struct sctp_association, asocs); | 1403 | asoc = list_entry(pos, struct sctp_association, asocs); |
@@ -1404,7 +1415,9 @@ SCTP_STATIC void sctp_close(struct sock *sk, long timeout) | |||
1404 | } | 1415 | } |
1405 | } | 1416 | } |
1406 | 1417 | ||
1407 | if (sock_flag(sk, SOCK_LINGER) && !sk->sk_lingertime) { | 1418 | if (data_was_unread || !skb_queue_empty(&asoc->ulpq.lobby) || |
1419 | !skb_queue_empty(&asoc->ulpq.reasm) || | ||
1420 | (sock_flag(sk, SOCK_LINGER) && !sk->sk_lingertime)) { | ||
1408 | struct sctp_chunk *chunk; | 1421 | struct sctp_chunk *chunk; |
1409 | 1422 | ||
1410 | chunk = sctp_make_abort_user(asoc, NULL, 0); | 1423 | chunk = sctp_make_abort_user(asoc, NULL, 0); |
@@ -1414,10 +1427,6 @@ SCTP_STATIC void sctp_close(struct sock *sk, long timeout) | |||
1414 | sctp_primitive_SHUTDOWN(asoc, NULL); | 1427 | sctp_primitive_SHUTDOWN(asoc, NULL); |
1415 | } | 1428 | } |
1416 | 1429 | ||
1417 | /* Clean up any skbs sitting on the receive queue. */ | ||
1418 | sctp_queue_purge_ulpevents(&sk->sk_receive_queue); | ||
1419 | sctp_queue_purge_ulpevents(&sctp_sk(sk)->pd_lobby); | ||
1420 | |||
1421 | /* On a TCP-style socket, block for at most linger_time if set. */ | 1430 | /* On a TCP-style socket, block for at most linger_time if set. */ |
1422 | if (sctp_style(sk, TCP) && timeout) | 1431 | if (sctp_style(sk, TCP) && timeout) |
1423 | sctp_wait_for_close(sk, timeout); | 1432 | sctp_wait_for_close(sk, timeout); |
@@ -1490,7 +1499,7 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
1490 | struct sctp_chunk *chunk; | 1499 | struct sctp_chunk *chunk; |
1491 | union sctp_addr to; | 1500 | union sctp_addr to; |
1492 | struct sockaddr *msg_name = NULL; | 1501 | struct sockaddr *msg_name = NULL; |
1493 | struct sctp_sndrcvinfo default_sinfo = { 0 }; | 1502 | struct sctp_sndrcvinfo default_sinfo; |
1494 | struct sctp_sndrcvinfo *sinfo; | 1503 | struct sctp_sndrcvinfo *sinfo; |
1495 | struct sctp_initmsg *sinit; | 1504 | struct sctp_initmsg *sinit; |
1496 | sctp_assoc_t associd = 0; | 1505 | sctp_assoc_t associd = 0; |
@@ -1754,6 +1763,7 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
1754 | /* If the user didn't specify SNDRCVINFO, make up one with | 1763 | /* If the user didn't specify SNDRCVINFO, make up one with |
1755 | * some defaults. | 1764 | * some defaults. |
1756 | */ | 1765 | */ |
1766 | memset(&default_sinfo, 0, sizeof(default_sinfo)); | ||
1757 | default_sinfo.sinfo_stream = asoc->default_stream; | 1767 | default_sinfo.sinfo_stream = asoc->default_stream; |
1758 | default_sinfo.sinfo_flags = asoc->default_flags; | 1768 | default_sinfo.sinfo_flags = asoc->default_flags; |
1759 | default_sinfo.sinfo_ppid = asoc->default_ppid; | 1769 | default_sinfo.sinfo_ppid = asoc->default_ppid; |
@@ -1784,12 +1794,10 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
1784 | goto out_free; | 1794 | goto out_free; |
1785 | } | 1795 | } |
1786 | 1796 | ||
1787 | if (sinfo) { | 1797 | /* Check for invalid stream. */ |
1788 | /* Check for invalid stream. */ | 1798 | if (sinfo->sinfo_stream >= asoc->c.sinit_num_ostreams) { |
1789 | if (sinfo->sinfo_stream >= asoc->c.sinit_num_ostreams) { | 1799 | err = -EINVAL; |
1790 | err = -EINVAL; | 1800 | goto out_free; |
1791 | goto out_free; | ||
1792 | } | ||
1793 | } | 1801 | } |
1794 | 1802 | ||
1795 | timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT); | 1803 | timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT); |
@@ -2068,10 +2076,33 @@ static int sctp_setsockopt_disable_fragments(struct sock *sk, | |||
2068 | static int sctp_setsockopt_events(struct sock *sk, char __user *optval, | 2076 | static int sctp_setsockopt_events(struct sock *sk, char __user *optval, |
2069 | unsigned int optlen) | 2077 | unsigned int optlen) |
2070 | { | 2078 | { |
2079 | struct sctp_association *asoc; | ||
2080 | struct sctp_ulpevent *event; | ||
2081 | |||
2071 | if (optlen > sizeof(struct sctp_event_subscribe)) | 2082 | if (optlen > sizeof(struct sctp_event_subscribe)) |
2072 | return -EINVAL; | 2083 | return -EINVAL; |
2073 | if (copy_from_user(&sctp_sk(sk)->subscribe, optval, optlen)) | 2084 | if (copy_from_user(&sctp_sk(sk)->subscribe, optval, optlen)) |
2074 | return -EFAULT; | 2085 | return -EFAULT; |
2086 | |||
2087 | /* | ||
2088 | * At the time when a user app subscribes to SCTP_SENDER_DRY_EVENT, | ||
2089 | * if there is no data to be sent or retransmit, the stack will | ||
2090 | * immediately send up this notification. | ||
2091 | */ | ||
2092 | if (sctp_ulpevent_type_enabled(SCTP_SENDER_DRY_EVENT, | ||
2093 | &sctp_sk(sk)->subscribe)) { | ||
2094 | asoc = sctp_id2assoc(sk, 0); | ||
2095 | |||
2096 | if (asoc && sctp_outq_is_empty(&asoc->outqueue)) { | ||
2097 | event = sctp_ulpevent_make_sender_dry_event(asoc, | ||
2098 | GFP_ATOMIC); | ||
2099 | if (!event) | ||
2100 | return -ENOMEM; | ||
2101 | |||
2102 | sctp_ulpq_tail_event(&asoc->ulpq, event); | ||
2103 | } | ||
2104 | } | ||
2105 | |||
2075 | return 0; | 2106 | return 0; |
2076 | } | 2107 | } |
2077 | 2108 | ||
@@ -2281,7 +2312,7 @@ static int sctp_apply_peer_addr_params(struct sctp_paddrparams *params, | |||
2281 | trans->param_flags = | 2312 | trans->param_flags = |
2282 | (trans->param_flags & ~SPP_PMTUD) | pmtud_change; | 2313 | (trans->param_flags & ~SPP_PMTUD) | pmtud_change; |
2283 | if (update) { | 2314 | if (update) { |
2284 | sctp_transport_pmtu(trans); | 2315 | sctp_transport_pmtu(trans, sctp_opt2sk(sp)); |
2285 | sctp_assoc_sync_pmtu(asoc); | 2316 | sctp_assoc_sync_pmtu(asoc); |
2286 | } | 2317 | } |
2287 | } else if (asoc) { | 2318 | } else if (asoc) { |
@@ -2469,9 +2500,8 @@ static int sctp_setsockopt_delayed_ack(struct sock *sk, | |||
2469 | if (params.sack_delay == 0 && params.sack_freq == 0) | 2500 | if (params.sack_delay == 0 && params.sack_freq == 0) |
2470 | return 0; | 2501 | return 0; |
2471 | } else if (optlen == sizeof(struct sctp_assoc_value)) { | 2502 | } else if (optlen == sizeof(struct sctp_assoc_value)) { |
2472 | printk(KERN_WARNING "SCTP: Use of struct sctp_assoc_value " | 2503 | pr_warn("Use of struct sctp_assoc_value in delayed_ack socket option deprecated\n"); |
2473 | "in delayed_ack socket option deprecated\n"); | 2504 | pr_warn("Use struct sctp_sack_info instead\n"); |
2474 | printk(KERN_WARNING "SCTP: Use struct sctp_sack_info instead\n"); | ||
2475 | if (copy_from_user(¶ms, optval, optlen)) | 2505 | if (copy_from_user(¶ms, optval, optlen)) |
2476 | return -EFAULT; | 2506 | return -EFAULT; |
2477 | 2507 | ||
@@ -2879,10 +2909,8 @@ static int sctp_setsockopt_maxseg(struct sock *sk, char __user *optval, unsigned | |||
2879 | int val; | 2909 | int val; |
2880 | 2910 | ||
2881 | if (optlen == sizeof(int)) { | 2911 | if (optlen == sizeof(int)) { |
2882 | printk(KERN_WARNING | 2912 | pr_warn("Use of int in maxseg socket option deprecated\n"); |
2883 | "SCTP: Use of int in maxseg socket option deprecated\n"); | 2913 | pr_warn("Use struct sctp_assoc_value instead\n"); |
2884 | printk(KERN_WARNING | ||
2885 | "SCTP: Use struct sctp_assoc_value instead\n"); | ||
2886 | if (copy_from_user(&val, optval, optlen)) | 2914 | if (copy_from_user(&val, optval, optlen)) |
2887 | return -EFAULT; | 2915 | return -EFAULT; |
2888 | params.assoc_id = 0; | 2916 | params.assoc_id = 0; |
@@ -2929,14 +2957,13 @@ static int sctp_setsockopt_peer_primary_addr(struct sock *sk, char __user *optva | |||
2929 | unsigned int optlen) | 2957 | unsigned int optlen) |
2930 | { | 2958 | { |
2931 | struct sctp_sock *sp; | 2959 | struct sctp_sock *sp; |
2932 | struct sctp_endpoint *ep; | ||
2933 | struct sctp_association *asoc = NULL; | 2960 | struct sctp_association *asoc = NULL; |
2934 | struct sctp_setpeerprim prim; | 2961 | struct sctp_setpeerprim prim; |
2935 | struct sctp_chunk *chunk; | 2962 | struct sctp_chunk *chunk; |
2963 | struct sctp_af *af; | ||
2936 | int err; | 2964 | int err; |
2937 | 2965 | ||
2938 | sp = sctp_sk(sk); | 2966 | sp = sctp_sk(sk); |
2939 | ep = sp->ep; | ||
2940 | 2967 | ||
2941 | if (!sctp_addip_enable) | 2968 | if (!sctp_addip_enable) |
2942 | return -EPERM; | 2969 | return -EPERM; |
@@ -2960,6 +2987,13 @@ static int sctp_setsockopt_peer_primary_addr(struct sock *sk, char __user *optva | |||
2960 | if (!sctp_state(asoc, ESTABLISHED)) | 2987 | if (!sctp_state(asoc, ESTABLISHED)) |
2961 | return -ENOTCONN; | 2988 | return -ENOTCONN; |
2962 | 2989 | ||
2990 | af = sctp_get_af_specific(prim.sspp_addr.ss_family); | ||
2991 | if (!af) | ||
2992 | return -EINVAL; | ||
2993 | |||
2994 | if (!af->addr_valid((union sctp_addr *)&prim.sspp_addr, sp, NULL)) | ||
2995 | return -EADDRNOTAVAIL; | ||
2996 | |||
2963 | if (!sctp_assoc_lookup_laddr(asoc, (union sctp_addr *)&prim.sspp_addr)) | 2997 | if (!sctp_assoc_lookup_laddr(asoc, (union sctp_addr *)&prim.sspp_addr)) |
2964 | return -EADDRNOTAVAIL; | 2998 | return -EADDRNOTAVAIL; |
2965 | 2999 | ||
@@ -3132,10 +3166,8 @@ static int sctp_setsockopt_maxburst(struct sock *sk, | |||
3132 | int assoc_id = 0; | 3166 | int assoc_id = 0; |
3133 | 3167 | ||
3134 | if (optlen == sizeof(int)) { | 3168 | if (optlen == sizeof(int)) { |
3135 | printk(KERN_WARNING | 3169 | pr_warn("Use of int in max_burst socket option deprecated\n"); |
3136 | "SCTP: Use of int in max_burst socket option deprecated\n"); | 3170 | pr_warn("Use struct sctp_assoc_value instead\n"); |
3137 | printk(KERN_WARNING | ||
3138 | "SCTP: Use struct sctp_assoc_value instead\n"); | ||
3139 | if (copy_from_user(&val, optval, optlen)) | 3171 | if (copy_from_user(&val, optval, optlen)) |
3140 | return -EFAULT; | 3172 | return -EFAULT; |
3141 | } else if (optlen == sizeof(struct sctp_assoc_value)) { | 3173 | } else if (optlen == sizeof(struct sctp_assoc_value)) { |
@@ -3212,14 +3244,9 @@ static int sctp_setsockopt_hmac_ident(struct sock *sk, | |||
3212 | if (optlen < sizeof(struct sctp_hmacalgo)) | 3244 | if (optlen < sizeof(struct sctp_hmacalgo)) |
3213 | return -EINVAL; | 3245 | return -EINVAL; |
3214 | 3246 | ||
3215 | hmacs = kmalloc(optlen, GFP_KERNEL); | 3247 | hmacs= memdup_user(optval, optlen); |
3216 | if (!hmacs) | 3248 | if (IS_ERR(hmacs)) |
3217 | return -ENOMEM; | 3249 | return PTR_ERR(hmacs); |
3218 | |||
3219 | if (copy_from_user(hmacs, optval, optlen)) { | ||
3220 | err = -EFAULT; | ||
3221 | goto out; | ||
3222 | } | ||
3223 | 3250 | ||
3224 | idents = hmacs->shmac_num_idents; | 3251 | idents = hmacs->shmac_num_idents; |
3225 | if (idents == 0 || idents > SCTP_AUTH_NUM_HMACS || | 3252 | if (idents == 0 || idents > SCTP_AUTH_NUM_HMACS || |
@@ -3254,14 +3281,9 @@ static int sctp_setsockopt_auth_key(struct sock *sk, | |||
3254 | if (optlen <= sizeof(struct sctp_authkey)) | 3281 | if (optlen <= sizeof(struct sctp_authkey)) |
3255 | return -EINVAL; | 3282 | return -EINVAL; |
3256 | 3283 | ||
3257 | authkey = kmalloc(optlen, GFP_KERNEL); | 3284 | authkey= memdup_user(optval, optlen); |
3258 | if (!authkey) | 3285 | if (IS_ERR(authkey)) |
3259 | return -ENOMEM; | 3286 | return PTR_ERR(authkey); |
3260 | |||
3261 | if (copy_from_user(authkey, optval, optlen)) { | ||
3262 | ret = -EFAULT; | ||
3263 | goto out; | ||
3264 | } | ||
3265 | 3287 | ||
3266 | if (authkey->sca_keylength > optlen - sizeof(struct sctp_authkey)) { | 3288 | if (authkey->sca_keylength > optlen - sizeof(struct sctp_authkey)) { |
3267 | ret = -EINVAL; | 3289 | ret = -EINVAL; |
@@ -3423,7 +3445,7 @@ SCTP_STATIC int sctp_setsockopt(struct sock *sk, int level, int optname, | |||
3423 | retval = sctp_setsockopt_peer_addr_params(sk, optval, optlen); | 3445 | retval = sctp_setsockopt_peer_addr_params(sk, optval, optlen); |
3424 | break; | 3446 | break; |
3425 | 3447 | ||
3426 | case SCTP_DELAYED_ACK: | 3448 | case SCTP_DELAYED_SACK: |
3427 | retval = sctp_setsockopt_delayed_ack(sk, optval, optlen); | 3449 | retval = sctp_setsockopt_delayed_ack(sk, optval, optlen); |
3428 | break; | 3450 | break; |
3429 | case SCTP_PARTIAL_DELIVERY_POINT: | 3451 | case SCTP_PARTIAL_DELIVERY_POINT: |
@@ -3606,7 +3628,40 @@ out: | |||
3606 | /* The SCTP ioctl handler. */ | 3628 | /* The SCTP ioctl handler. */ |
3607 | SCTP_STATIC int sctp_ioctl(struct sock *sk, int cmd, unsigned long arg) | 3629 | SCTP_STATIC int sctp_ioctl(struct sock *sk, int cmd, unsigned long arg) |
3608 | { | 3630 | { |
3609 | return -ENOIOCTLCMD; | 3631 | int rc = -ENOTCONN; |
3632 | |||
3633 | sctp_lock_sock(sk); | ||
3634 | |||
3635 | /* | ||
3636 | * SEQPACKET-style sockets in LISTENING state are valid, for | ||
3637 | * SCTP, so only discard TCP-style sockets in LISTENING state. | ||
3638 | */ | ||
3639 | if (sctp_style(sk, TCP) && sctp_sstate(sk, LISTENING)) | ||
3640 | goto out; | ||
3641 | |||
3642 | switch (cmd) { | ||
3643 | case SIOCINQ: { | ||
3644 | struct sk_buff *skb; | ||
3645 | unsigned int amount = 0; | ||
3646 | |||
3647 | skb = skb_peek(&sk->sk_receive_queue); | ||
3648 | if (skb != NULL) { | ||
3649 | /* | ||
3650 | * We will only return the amount of this packet since | ||
3651 | * that is all that will be read. | ||
3652 | */ | ||
3653 | amount = skb->len; | ||
3654 | } | ||
3655 | rc = put_user(amount, (int __user *)arg); | ||
3656 | break; | ||
3657 | } | ||
3658 | default: | ||
3659 | rc = -ENOIOCTLCMD; | ||
3660 | break; | ||
3661 | } | ||
3662 | out: | ||
3663 | sctp_release_sock(sk); | ||
3664 | return rc; | ||
3610 | } | 3665 | } |
3611 | 3666 | ||
3612 | /* This is the function which gets called during socket creation to | 3667 | /* This is the function which gets called during socket creation to |
@@ -3865,7 +3920,7 @@ static int sctp_getsockopt_sctp_status(struct sock *sk, int len, | |||
3865 | } | 3920 | } |
3866 | 3921 | ||
3867 | out: | 3922 | out: |
3868 | return (retval); | 3923 | return retval; |
3869 | } | 3924 | } |
3870 | 3925 | ||
3871 | 3926 | ||
@@ -3921,7 +3976,7 @@ static int sctp_getsockopt_peer_addr_info(struct sock *sk, int len, | |||
3921 | } | 3976 | } |
3922 | 3977 | ||
3923 | out: | 3978 | out: |
3924 | return (retval); | 3979 | return retval; |
3925 | } | 3980 | } |
3926 | 3981 | ||
3927 | /* 7.1.12 Enable/Disable message fragmentation (SCTP_DISABLE_FRAGMENTS) | 3982 | /* 7.1.12 Enable/Disable message fragmentation (SCTP_DISABLE_FRAGMENTS) |
@@ -4292,9 +4347,8 @@ static int sctp_getsockopt_delayed_ack(struct sock *sk, int len, | |||
4292 | if (copy_from_user(¶ms, optval, len)) | 4347 | if (copy_from_user(¶ms, optval, len)) |
4293 | return -EFAULT; | 4348 | return -EFAULT; |
4294 | } else if (len == sizeof(struct sctp_assoc_value)) { | 4349 | } else if (len == sizeof(struct sctp_assoc_value)) { |
4295 | printk(KERN_WARNING "SCTP: Use of struct sctp_assoc_value " | 4350 | pr_warn("Use of struct sctp_assoc_value in delayed_ack socket option deprecated\n"); |
4296 | "in delayed_ack socket option deprecated\n"); | 4351 | pr_warn("Use struct sctp_sack_info instead\n"); |
4297 | printk(KERN_WARNING "SCTP: Use struct sctp_sack_info instead\n"); | ||
4298 | if (copy_from_user(¶ms, optval, len)) | 4352 | if (copy_from_user(¶ms, optval, len)) |
4299 | return -EFAULT; | 4353 | return -EFAULT; |
4300 | } else | 4354 | } else |
@@ -4940,10 +4994,8 @@ static int sctp_getsockopt_maxseg(struct sock *sk, int len, | |||
4940 | struct sctp_association *asoc; | 4994 | struct sctp_association *asoc; |
4941 | 4995 | ||
4942 | if (len == sizeof(int)) { | 4996 | if (len == sizeof(int)) { |
4943 | printk(KERN_WARNING | 4997 | pr_warn("Use of int in maxseg socket option deprecated\n"); |
4944 | "SCTP: Use of int in maxseg socket option deprecated\n"); | 4998 | pr_warn("Use struct sctp_assoc_value instead\n"); |
4945 | printk(KERN_WARNING | ||
4946 | "SCTP: Use struct sctp_assoc_value instead\n"); | ||
4947 | params.assoc_id = 0; | 4999 | params.assoc_id = 0; |
4948 | } else if (len >= sizeof(struct sctp_assoc_value)) { | 5000 | } else if (len >= sizeof(struct sctp_assoc_value)) { |
4949 | len = sizeof(struct sctp_assoc_value); | 5001 | len = sizeof(struct sctp_assoc_value); |
@@ -5018,7 +5070,7 @@ static int sctp_getsockopt_partial_delivery_point(struct sock *sk, int len, | |||
5018 | if (copy_to_user(optval, &val, len)) | 5070 | if (copy_to_user(optval, &val, len)) |
5019 | return -EFAULT; | 5071 | return -EFAULT; |
5020 | 5072 | ||
5021 | return -ENOTSUPP; | 5073 | return 0; |
5022 | } | 5074 | } |
5023 | 5075 | ||
5024 | /* | 5076 | /* |
@@ -5034,10 +5086,8 @@ static int sctp_getsockopt_maxburst(struct sock *sk, int len, | |||
5034 | struct sctp_association *asoc; | 5086 | struct sctp_association *asoc; |
5035 | 5087 | ||
5036 | if (len == sizeof(int)) { | 5088 | if (len == sizeof(int)) { |
5037 | printk(KERN_WARNING | 5089 | pr_warn("Use of int in max_burst socket option deprecated\n"); |
5038 | "SCTP: Use of int in max_burst socket option deprecated\n"); | 5090 | pr_warn("Use struct sctp_assoc_value instead\n"); |
5039 | printk(KERN_WARNING | ||
5040 | "SCTP: Use struct sctp_assoc_value instead\n"); | ||
5041 | params.assoc_id = 0; | 5091 | params.assoc_id = 0; |
5042 | } else if (len >= sizeof(struct sctp_assoc_value)) { | 5092 | } else if (len >= sizeof(struct sctp_assoc_value)) { |
5043 | len = sizeof(struct sctp_assoc_value); | 5093 | len = sizeof(struct sctp_assoc_value); |
@@ -5252,6 +5302,55 @@ static int sctp_getsockopt_assoc_number(struct sock *sk, int len, | |||
5252 | return 0; | 5302 | return 0; |
5253 | } | 5303 | } |
5254 | 5304 | ||
5305 | /* | ||
5306 | * 8.2.6. Get the Current Identifiers of Associations | ||
5307 | * (SCTP_GET_ASSOC_ID_LIST) | ||
5308 | * | ||
5309 | * This option gets the current list of SCTP association identifiers of | ||
5310 | * the SCTP associations handled by a one-to-many style socket. | ||
5311 | */ | ||
5312 | static int sctp_getsockopt_assoc_ids(struct sock *sk, int len, | ||
5313 | char __user *optval, int __user *optlen) | ||
5314 | { | ||
5315 | struct sctp_sock *sp = sctp_sk(sk); | ||
5316 | struct sctp_association *asoc; | ||
5317 | struct sctp_assoc_ids *ids; | ||
5318 | u32 num = 0; | ||
5319 | |||
5320 | if (sctp_style(sk, TCP)) | ||
5321 | return -EOPNOTSUPP; | ||
5322 | |||
5323 | if (len < sizeof(struct sctp_assoc_ids)) | ||
5324 | return -EINVAL; | ||
5325 | |||
5326 | list_for_each_entry(asoc, &(sp->ep->asocs), asocs) { | ||
5327 | num++; | ||
5328 | } | ||
5329 | |||
5330 | if (len < sizeof(struct sctp_assoc_ids) + sizeof(sctp_assoc_t) * num) | ||
5331 | return -EINVAL; | ||
5332 | |||
5333 | len = sizeof(struct sctp_assoc_ids) + sizeof(sctp_assoc_t) * num; | ||
5334 | |||
5335 | ids = kmalloc(len, GFP_KERNEL); | ||
5336 | if (unlikely(!ids)) | ||
5337 | return -ENOMEM; | ||
5338 | |||
5339 | ids->gaids_number_of_ids = num; | ||
5340 | num = 0; | ||
5341 | list_for_each_entry(asoc, &(sp->ep->asocs), asocs) { | ||
5342 | ids->gaids_assoc_id[num++] = asoc->assoc_id; | ||
5343 | } | ||
5344 | |||
5345 | if (put_user(len, optlen) || copy_to_user(optval, ids, len)) { | ||
5346 | kfree(ids); | ||
5347 | return -EFAULT; | ||
5348 | } | ||
5349 | |||
5350 | kfree(ids); | ||
5351 | return 0; | ||
5352 | } | ||
5353 | |||
5255 | SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname, | 5354 | SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname, |
5256 | char __user *optval, int __user *optlen) | 5355 | char __user *optval, int __user *optlen) |
5257 | { | 5356 | { |
@@ -5300,7 +5399,7 @@ SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname, | |||
5300 | retval = sctp_getsockopt_peer_addr_params(sk, len, optval, | 5399 | retval = sctp_getsockopt_peer_addr_params(sk, len, optval, |
5301 | optlen); | 5400 | optlen); |
5302 | break; | 5401 | break; |
5303 | case SCTP_DELAYED_ACK: | 5402 | case SCTP_DELAYED_SACK: |
5304 | retval = sctp_getsockopt_delayed_ack(sk, len, optval, | 5403 | retval = sctp_getsockopt_delayed_ack(sk, len, optval, |
5305 | optlen); | 5404 | optlen); |
5306 | break; | 5405 | break; |
@@ -5384,6 +5483,9 @@ SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname, | |||
5384 | case SCTP_GET_ASSOC_NUMBER: | 5483 | case SCTP_GET_ASSOC_NUMBER: |
5385 | retval = sctp_getsockopt_assoc_number(sk, len, optval, optlen); | 5484 | retval = sctp_getsockopt_assoc_number(sk, len, optval, optlen); |
5386 | break; | 5485 | break; |
5486 | case SCTP_GET_ASSOC_ID_LIST: | ||
5487 | retval = sctp_getsockopt_assoc_ids(sk, len, optval, optlen); | ||
5488 | break; | ||
5387 | default: | 5489 | default: |
5388 | retval = -ENOPROTOOPT; | 5490 | retval = -ENOPROTOOPT; |
5389 | break; | 5491 | break; |
@@ -5580,7 +5682,7 @@ static int sctp_get_port(struct sock *sk, unsigned short snum) | |||
5580 | /* Note: sk->sk_num gets filled in if ephemeral port request. */ | 5682 | /* Note: sk->sk_num gets filled in if ephemeral port request. */ |
5581 | ret = sctp_get_port_local(sk, &addr); | 5683 | ret = sctp_get_port_local(sk, &addr); |
5582 | 5684 | ||
5583 | return (ret ? 1 : 0); | 5685 | return ret ? 1 : 0; |
5584 | } | 5686 | } |
5585 | 5687 | ||
5586 | /* | 5688 | /* |
@@ -5597,8 +5699,7 @@ SCTP_STATIC int sctp_listen_start(struct sock *sk, int backlog) | |||
5597 | tfm = crypto_alloc_hash(sctp_hmac_alg, 0, CRYPTO_ALG_ASYNC); | 5699 | tfm = crypto_alloc_hash(sctp_hmac_alg, 0, CRYPTO_ALG_ASYNC); |
5598 | if (IS_ERR(tfm)) { | 5700 | if (IS_ERR(tfm)) { |
5599 | if (net_ratelimit()) { | 5701 | if (net_ratelimit()) { |
5600 | printk(KERN_INFO | 5702 | pr_info("failed to load transform for %s: %ld\n", |
5601 | "SCTP: failed to load transform for %s: %ld\n", | ||
5602 | sctp_hmac_alg, PTR_ERR(tfm)); | 5703 | sctp_hmac_alg, PTR_ERR(tfm)); |
5603 | } | 5704 | } |
5604 | return -ENOSYS; | 5705 | return -ENOSYS; |
@@ -5727,13 +5828,12 @@ unsigned int sctp_poll(struct file *file, struct socket *sock, poll_table *wait) | |||
5727 | if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue)) | 5828 | if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue)) |
5728 | mask |= POLLERR; | 5829 | mask |= POLLERR; |
5729 | if (sk->sk_shutdown & RCV_SHUTDOWN) | 5830 | if (sk->sk_shutdown & RCV_SHUTDOWN) |
5730 | mask |= POLLRDHUP; | 5831 | mask |= POLLRDHUP | POLLIN | POLLRDNORM; |
5731 | if (sk->sk_shutdown == SHUTDOWN_MASK) | 5832 | if (sk->sk_shutdown == SHUTDOWN_MASK) |
5732 | mask |= POLLHUP; | 5833 | mask |= POLLHUP; |
5733 | 5834 | ||
5734 | /* Is it readable? Reconsider this code with TCP-style support. */ | 5835 | /* Is it readable? Reconsider this code with TCP-style support. */ |
5735 | if (!skb_queue_empty(&sk->sk_receive_queue) || | 5836 | if (!skb_queue_empty(&sk->sk_receive_queue)) |
5736 | (sk->sk_shutdown & RCV_SHUTDOWN)) | ||
5737 | mask |= POLLIN | POLLRDNORM; | 5837 | mask |= POLLIN | POLLRDNORM; |
5738 | 5838 | ||
5739 | /* The association is either gone or not ready. */ | 5839 | /* The association is either gone or not ready. */ |
@@ -6024,7 +6124,7 @@ static struct sk_buff *sctp_skb_recv_datagram(struct sock *sk, int flags, | |||
6024 | * will suddenly eat the receive_queue. | 6124 | * will suddenly eat the receive_queue. |
6025 | * | 6125 | * |
6026 | * Look at current nfs client by the way... | 6126 | * Look at current nfs client by the way... |
6027 | * However, this function was corrent in any case. 8) | 6127 | * However, this function was correct in any case. 8) |
6028 | */ | 6128 | */ |
6029 | if (flags & MSG_PEEK) { | 6129 | if (flags & MSG_PEEK) { |
6030 | spin_lock_bh(&sk->sk_receive_queue.lock); | 6130 | spin_lock_bh(&sk->sk_receive_queue.lock); |
@@ -6071,15 +6171,16 @@ static void __sctp_write_space(struct sctp_association *asoc) | |||
6071 | wake_up_interruptible(&asoc->wait); | 6171 | wake_up_interruptible(&asoc->wait); |
6072 | 6172 | ||
6073 | if (sctp_writeable(sk)) { | 6173 | if (sctp_writeable(sk)) { |
6074 | if (sk_sleep(sk) && waitqueue_active(sk_sleep(sk))) | 6174 | wait_queue_head_t *wq = sk_sleep(sk); |
6075 | wake_up_interruptible(sk_sleep(sk)); | 6175 | |
6176 | if (wq && waitqueue_active(wq)) | ||
6177 | wake_up_interruptible(wq); | ||
6076 | 6178 | ||
6077 | /* Note that we try to include the Async I/O support | 6179 | /* Note that we try to include the Async I/O support |
6078 | * here by modeling from the current TCP/UDP code. | 6180 | * here by modeling from the current TCP/UDP code. |
6079 | * We have not tested with it yet. | 6181 | * We have not tested with it yet. |
6080 | */ | 6182 | */ |
6081 | if (sock->wq->fasync_list && | 6183 | if (!(sk->sk_shutdown & SEND_SHUTDOWN)) |
6082 | !(sk->sk_shutdown & SEND_SHUTDOWN)) | ||
6083 | sock_wake_async(sock, | 6184 | sock_wake_async(sock, |
6084 | SOCK_WAKE_SPACE, POLL_OUT); | 6185 | SOCK_WAKE_SPACE, POLL_OUT); |
6085 | } | 6186 | } |
diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c index 832590bbe0c0..50cb57f0919e 100644 --- a/net/sctp/sysctl.c +++ b/net/sctp/sysctl.c | |||
@@ -54,7 +54,7 @@ static int sack_timer_max = 500; | |||
54 | static int addr_scope_max = 3; /* check sctp_scope_policy_t in include/net/sctp/constants.h for max entries */ | 54 | static int addr_scope_max = 3; /* check sctp_scope_policy_t in include/net/sctp/constants.h for max entries */ |
55 | static int rwnd_scale_max = 16; | 55 | static int rwnd_scale_max = 16; |
56 | 56 | ||
57 | extern int sysctl_sctp_mem[3]; | 57 | extern long sysctl_sctp_mem[3]; |
58 | extern int sysctl_sctp_rmem[3]; | 58 | extern int sysctl_sctp_rmem[3]; |
59 | extern int sysctl_sctp_wmem[3]; | 59 | extern int sysctl_sctp_wmem[3]; |
60 | 60 | ||
@@ -203,7 +203,7 @@ static ctl_table sctp_table[] = { | |||
203 | .data = &sysctl_sctp_mem, | 203 | .data = &sysctl_sctp_mem, |
204 | .maxlen = sizeof(sysctl_sctp_mem), | 204 | .maxlen = sizeof(sysctl_sctp_mem), |
205 | .mode = 0644, | 205 | .mode = 0644, |
206 | .proc_handler = proc_dointvec, | 206 | .proc_handler = proc_doulongvec_minmax |
207 | }, | 207 | }, |
208 | { | 208 | { |
209 | .procname = "sctp_rmem", | 209 | .procname = "sctp_rmem", |
diff --git a/net/sctp/transport.c b/net/sctp/transport.c index 132046cb82fc..394c57ca2f54 100644 --- a/net/sctp/transport.c +++ b/net/sctp/transport.c | |||
@@ -48,6 +48,8 @@ | |||
48 | * be incorporated into the next SCTP release. | 48 | * be incorporated into the next SCTP release. |
49 | */ | 49 | */ |
50 | 50 | ||
51 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
52 | |||
51 | #include <linux/slab.h> | 53 | #include <linux/slab.h> |
52 | #include <linux/types.h> | 54 | #include <linux/types.h> |
53 | #include <linux/random.h> | 55 | #include <linux/random.h> |
@@ -209,15 +211,17 @@ void sctp_transport_set_owner(struct sctp_transport *transport, | |||
209 | } | 211 | } |
210 | 212 | ||
211 | /* Initialize the pmtu of a transport. */ | 213 | /* Initialize the pmtu of a transport. */ |
212 | void sctp_transport_pmtu(struct sctp_transport *transport) | 214 | void sctp_transport_pmtu(struct sctp_transport *transport, struct sock *sk) |
213 | { | 215 | { |
214 | struct dst_entry *dst; | 216 | /* If we don't have a fresh route, look one up */ |
215 | 217 | if (!transport->dst || transport->dst->obsolete > 1) { | |
216 | dst = transport->af_specific->get_dst(NULL, &transport->ipaddr, NULL); | 218 | dst_release(transport->dst); |
219 | transport->af_specific->get_dst(transport, &transport->saddr, | ||
220 | &transport->fl, sk); | ||
221 | } | ||
217 | 222 | ||
218 | if (dst) { | 223 | if (transport->dst) { |
219 | transport->pathmtu = dst_mtu(dst); | 224 | transport->pathmtu = dst_mtu(transport->dst); |
220 | dst_release(dst); | ||
221 | } else | 225 | } else |
222 | transport->pathmtu = SCTP_DEFAULT_MAXSEGMENT; | 226 | transport->pathmtu = SCTP_DEFAULT_MAXSEGMENT; |
223 | } | 227 | } |
@@ -244,10 +248,9 @@ void sctp_transport_update_pmtu(struct sctp_transport *t, u32 pmtu) | |||
244 | struct dst_entry *dst; | 248 | struct dst_entry *dst; |
245 | 249 | ||
246 | if (unlikely(pmtu < SCTP_DEFAULT_MINSEGMENT)) { | 250 | if (unlikely(pmtu < SCTP_DEFAULT_MINSEGMENT)) { |
247 | printk(KERN_WARNING "%s: Reported pmtu %d too low, " | 251 | pr_warn("%s: Reported pmtu %d too low, using default minimum of %d\n", |
248 | "using default minimum of %d\n", | 252 | __func__, pmtu, |
249 | __func__, pmtu, | 253 | SCTP_DEFAULT_MINSEGMENT); |
250 | SCTP_DEFAULT_MINSEGMENT); | ||
251 | /* Use default minimum segment size and disable | 254 | /* Use default minimum segment size and disable |
252 | * pmtu discovery on this transport. | 255 | * pmtu discovery on this transport. |
253 | */ | 256 | */ |
@@ -269,22 +272,19 @@ void sctp_transport_route(struct sctp_transport *transport, | |||
269 | { | 272 | { |
270 | struct sctp_association *asoc = transport->asoc; | 273 | struct sctp_association *asoc = transport->asoc; |
271 | struct sctp_af *af = transport->af_specific; | 274 | struct sctp_af *af = transport->af_specific; |
272 | union sctp_addr *daddr = &transport->ipaddr; | ||
273 | struct dst_entry *dst; | ||
274 | 275 | ||
275 | dst = af->get_dst(asoc, daddr, saddr); | 276 | af->get_dst(transport, saddr, &transport->fl, sctp_opt2sk(opt)); |
276 | 277 | ||
277 | if (saddr) | 278 | if (saddr) |
278 | memcpy(&transport->saddr, saddr, sizeof(union sctp_addr)); | 279 | memcpy(&transport->saddr, saddr, sizeof(union sctp_addr)); |
279 | else | 280 | else |
280 | af->get_saddr(opt, asoc, dst, daddr, &transport->saddr); | 281 | af->get_saddr(opt, transport, &transport->fl); |
281 | 282 | ||
282 | transport->dst = dst; | ||
283 | if ((transport->param_flags & SPP_PMTUD_DISABLE) && transport->pathmtu) { | 283 | if ((transport->param_flags & SPP_PMTUD_DISABLE) && transport->pathmtu) { |
284 | return; | 284 | return; |
285 | } | 285 | } |
286 | if (dst) { | 286 | if (transport->dst) { |
287 | transport->pathmtu = dst_mtu(dst); | 287 | transport->pathmtu = dst_mtu(transport->dst); |
288 | 288 | ||
289 | /* Initialize sk->sk_rcv_saddr, if the transport is the | 289 | /* Initialize sk->sk_rcv_saddr, if the transport is the |
290 | * association's active path for getsockname(). | 290 | * association's active path for getsockname(). |
diff --git a/net/sctp/tsnmap.c b/net/sctp/tsnmap.c index 747d5412c463..f1e40cebc981 100644 --- a/net/sctp/tsnmap.c +++ b/net/sctp/tsnmap.c | |||
@@ -344,7 +344,7 @@ __u16 sctp_tsnmap_num_gabs(struct sctp_tsnmap *map, | |||
344 | 344 | ||
345 | /* Refresh the gap ack information. */ | 345 | /* Refresh the gap ack information. */ |
346 | if (sctp_tsnmap_has_gap(map)) { | 346 | if (sctp_tsnmap_has_gap(map)) { |
347 | __u16 start, end; | 347 | __u16 start = 0, end = 0; |
348 | sctp_tsnmap_iter_init(map, &iter); | 348 | sctp_tsnmap_iter_init(map, &iter); |
349 | while (sctp_tsnmap_next_gap_ack(map, &iter, | 349 | while (sctp_tsnmap_next_gap_ack(map, &iter, |
350 | &start, | 350 | &start, |
diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c index aa72e89c3ee1..8a84017834c2 100644 --- a/net/sctp/ulpevent.c +++ b/net/sctp/ulpevent.c | |||
@@ -554,7 +554,7 @@ struct sctp_ulpevent *sctp_ulpevent_make_send_failed( | |||
554 | memcpy(&ssf->ssf_info, &chunk->sinfo, sizeof(struct sctp_sndrcvinfo)); | 554 | memcpy(&ssf->ssf_info, &chunk->sinfo, sizeof(struct sctp_sndrcvinfo)); |
555 | 555 | ||
556 | /* Per TSVWG discussion with Randy. Allow the application to | 556 | /* Per TSVWG discussion with Randy. Allow the application to |
557 | * ressemble a fragmented message. | 557 | * reassemble a fragmented message. |
558 | */ | 558 | */ |
559 | ssf->ssf_info.sinfo_flags = chunk->chunk_hdr->flags; | 559 | ssf->ssf_info.sinfo_flags = chunk->chunk_hdr->flags; |
560 | 560 | ||
@@ -843,7 +843,7 @@ struct sctp_ulpevent *sctp_ulpevent_make_authkey( | |||
843 | ak = (struct sctp_authkey_event *) | 843 | ak = (struct sctp_authkey_event *) |
844 | skb_put(skb, sizeof(struct sctp_authkey_event)); | 844 | skb_put(skb, sizeof(struct sctp_authkey_event)); |
845 | 845 | ||
846 | ak->auth_type = SCTP_AUTHENTICATION_INDICATION; | 846 | ak->auth_type = SCTP_AUTHENTICATION_EVENT; |
847 | ak->auth_flags = 0; | 847 | ak->auth_flags = 0; |
848 | ak->auth_length = sizeof(struct sctp_authkey_event); | 848 | ak->auth_length = sizeof(struct sctp_authkey_event); |
849 | 849 | ||
@@ -862,6 +862,34 @@ fail: | |||
862 | return NULL; | 862 | return NULL; |
863 | } | 863 | } |
864 | 864 | ||
865 | /* | ||
866 | * Socket Extensions for SCTP | ||
867 | * 6.3.10. SCTP_SENDER_DRY_EVENT | ||
868 | */ | ||
869 | struct sctp_ulpevent *sctp_ulpevent_make_sender_dry_event( | ||
870 | const struct sctp_association *asoc, gfp_t gfp) | ||
871 | { | ||
872 | struct sctp_ulpevent *event; | ||
873 | struct sctp_sender_dry_event *sdry; | ||
874 | struct sk_buff *skb; | ||
875 | |||
876 | event = sctp_ulpevent_new(sizeof(struct sctp_sender_dry_event), | ||
877 | MSG_NOTIFICATION, gfp); | ||
878 | if (!event) | ||
879 | return NULL; | ||
880 | |||
881 | skb = sctp_event2skb(event); | ||
882 | sdry = (struct sctp_sender_dry_event *) | ||
883 | skb_put(skb, sizeof(struct sctp_sender_dry_event)); | ||
884 | |||
885 | sdry->sender_dry_type = SCTP_SENDER_DRY_EVENT; | ||
886 | sdry->sender_dry_flags = 0; | ||
887 | sdry->sender_dry_length = sizeof(struct sctp_sender_dry_event); | ||
888 | sctp_ulpevent_set_owner(event, asoc); | ||
889 | sdry->sender_dry_assoc_id = sctp_assoc2id(asoc); | ||
890 | |||
891 | return event; | ||
892 | } | ||
865 | 893 | ||
866 | /* Return the notification type, assuming this is a notification | 894 | /* Return the notification type, assuming this is a notification |
867 | * event. | 895 | * event. |
@@ -1053,9 +1081,19 @@ void sctp_ulpevent_free(struct sctp_ulpevent *event) | |||
1053 | } | 1081 | } |
1054 | 1082 | ||
1055 | /* Purge the skb lists holding ulpevents. */ | 1083 | /* Purge the skb lists holding ulpevents. */ |
1056 | void sctp_queue_purge_ulpevents(struct sk_buff_head *list) | 1084 | unsigned int sctp_queue_purge_ulpevents(struct sk_buff_head *list) |
1057 | { | 1085 | { |
1058 | struct sk_buff *skb; | 1086 | struct sk_buff *skb; |
1059 | while ((skb = skb_dequeue(list)) != NULL) | 1087 | unsigned int data_unread = 0; |
1060 | sctp_ulpevent_free(sctp_skb2event(skb)); | 1088 | |
1089 | while ((skb = skb_dequeue(list)) != NULL) { | ||
1090 | struct sctp_ulpevent *event = sctp_skb2event(skb); | ||
1091 | |||
1092 | if (!sctp_ulpevent_is_notification(event)) | ||
1093 | data_unread += skb->len; | ||
1094 | |||
1095 | sctp_ulpevent_free(event); | ||
1096 | } | ||
1097 | |||
1098 | return data_unread; | ||
1061 | } | 1099 | } |
diff --git a/net/sctp/ulpqueue.c b/net/sctp/ulpqueue.c index c7f7e49609cb..f2d1de7f2ffb 100644 --- a/net/sctp/ulpqueue.c +++ b/net/sctp/ulpqueue.c | |||
@@ -105,11 +105,8 @@ int sctp_ulpq_tail_data(struct sctp_ulpq *ulpq, struct sctp_chunk *chunk, | |||
105 | gfp_t gfp) | 105 | gfp_t gfp) |
106 | { | 106 | { |
107 | struct sk_buff_head temp; | 107 | struct sk_buff_head temp; |
108 | sctp_data_chunk_t *hdr; | ||
109 | struct sctp_ulpevent *event; | 108 | struct sctp_ulpevent *event; |
110 | 109 | ||
111 | hdr = (sctp_data_chunk_t *) chunk->chunk_hdr; | ||
112 | |||
113 | /* Create an event from the incoming chunk. */ | 110 | /* Create an event from the incoming chunk. */ |
114 | event = sctp_ulpevent_make_rcvmsg(chunk->asoc, chunk, gfp); | 111 | event = sctp_ulpevent_make_rcvmsg(chunk->asoc, chunk, gfp); |
115 | if (!event) | 112 | if (!event) |
@@ -243,7 +240,7 @@ int sctp_ulpq_tail_event(struct sctp_ulpq *ulpq, struct sctp_ulpevent *event) | |||
243 | } else { | 240 | } else { |
244 | /* | 241 | /* |
245 | * If fragment interleave is enabled, we | 242 | * If fragment interleave is enabled, we |
246 | * can queue this to the recieve queue instead | 243 | * can queue this to the receive queue instead |
247 | * of the lobby. | 244 | * of the lobby. |
248 | */ | 245 | */ |
249 | if (sctp_sk(sk)->frag_interleave) | 246 | if (sctp_sk(sk)->frag_interleave) |
@@ -743,11 +740,9 @@ static void sctp_ulpq_retrieve_ordered(struct sctp_ulpq *ulpq, | |||
743 | struct sk_buff *pos, *tmp; | 740 | struct sk_buff *pos, *tmp; |
744 | struct sctp_ulpevent *cevent; | 741 | struct sctp_ulpevent *cevent; |
745 | struct sctp_stream *in; | 742 | struct sctp_stream *in; |
746 | __u16 sid, csid; | 743 | __u16 sid, csid, cssn; |
747 | __u16 ssn, cssn; | ||
748 | 744 | ||
749 | sid = event->stream; | 745 | sid = event->stream; |
750 | ssn = event->ssn; | ||
751 | in = &ulpq->asoc->ssnmap->in; | 746 | in = &ulpq->asoc->ssnmap->in; |
752 | 747 | ||
753 | event_list = (struct sk_buff_head *) sctp_event2skb(event)->prev; | 748 | event_list = (struct sk_buff_head *) sctp_event2skb(event)->prev; |