aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp
diff options
context:
space:
mode:
Diffstat (limited to 'net/sctp')
-rw-r--r--net/sctp/associola.c31
-rw-r--r--net/sctp/endpointola.c3
-rw-r--r--net/sctp/input.c6
-rw-r--r--net/sctp/proc.c9
-rw-r--r--net/sctp/socket.c9
5 files changed, 25 insertions, 33 deletions
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index 2f95f5a5145d..43cd0dd9149d 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -1591,32 +1591,31 @@ int sctp_assoc_lookup_laddr(struct sctp_association *asoc,
1591/* Set an association id for a given association */ 1591/* Set an association id for a given association */
1592int sctp_assoc_set_id(struct sctp_association *asoc, gfp_t gfp) 1592int sctp_assoc_set_id(struct sctp_association *asoc, gfp_t gfp)
1593{ 1593{
1594 int assoc_id; 1594 bool preload = gfp & __GFP_WAIT;
1595 int error = 0; 1595 int ret;
1596 1596
1597 /* If the id is already assigned, keep it. */ 1597 /* If the id is already assigned, keep it. */
1598 if (asoc->assoc_id) 1598 if (asoc->assoc_id)
1599 return error; 1599 return 0;
1600retry:
1601 if (unlikely(!idr_pre_get(&sctp_assocs_id, gfp)))
1602 return -ENOMEM;
1603 1600
1601 if (preload)
1602 idr_preload(gfp);
1604 spin_lock_bh(&sctp_assocs_id_lock); 1603 spin_lock_bh(&sctp_assocs_id_lock);
1605 error = idr_get_new_above(&sctp_assocs_id, (void *)asoc, 1604 /* 0 is not a valid id, idr_low is always >= 1 */
1606 idr_low, &assoc_id); 1605 ret = idr_alloc(&sctp_assocs_id, asoc, idr_low, 0, GFP_NOWAIT);
1607 if (!error) { 1606 if (ret >= 0) {
1608 idr_low = assoc_id + 1; 1607 idr_low = ret + 1;
1609 if (idr_low == INT_MAX) 1608 if (idr_low == INT_MAX)
1610 idr_low = 1; 1609 idr_low = 1;
1611 } 1610 }
1612 spin_unlock_bh(&sctp_assocs_id_lock); 1611 spin_unlock_bh(&sctp_assocs_id_lock);
1613 if (error == -EAGAIN) 1612 if (preload)
1614 goto retry; 1613 idr_preload_end();
1615 else if (error) 1614 if (ret < 0)
1616 return error; 1615 return ret;
1617 1616
1618 asoc->assoc_id = (sctp_assoc_t) assoc_id; 1617 asoc->assoc_id = (sctp_assoc_t)ret;
1619 return error; 1618 return 0;
1620} 1619}
1621 1620
1622/* Free the ASCONF queue */ 1621/* Free the ASCONF queue */
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c
index 9a680c075141..12ed45dbe75d 100644
--- a/net/sctp/endpointola.c
+++ b/net/sctp/endpointola.c
@@ -332,7 +332,6 @@ static struct sctp_association *__sctp_endpoint_lookup_assoc(
332 struct sctp_transport *t = NULL; 332 struct sctp_transport *t = NULL;
333 struct sctp_hashbucket *head; 333 struct sctp_hashbucket *head;
334 struct sctp_ep_common *epb; 334 struct sctp_ep_common *epb;
335 struct hlist_node *node;
336 int hash; 335 int hash;
337 int rport; 336 int rport;
338 337
@@ -350,7 +349,7 @@ static struct sctp_association *__sctp_endpoint_lookup_assoc(
350 rport); 349 rport);
351 head = &sctp_assoc_hashtable[hash]; 350 head = &sctp_assoc_hashtable[hash];
352 read_lock(&head->lock); 351 read_lock(&head->lock);
353 sctp_for_each_hentry(epb, node, &head->chain) { 352 sctp_for_each_hentry(epb, &head->chain) {
354 tmp = sctp_assoc(epb); 353 tmp = sctp_assoc(epb);
355 if (tmp->ep != ep || rport != tmp->peer.port) 354 if (tmp->ep != ep || rport != tmp->peer.port)
356 continue; 355 continue;
diff --git a/net/sctp/input.c b/net/sctp/input.c
index 965bbbbe48d4..4b2c83146aa7 100644
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -784,13 +784,12 @@ static struct sctp_endpoint *__sctp_rcv_lookup_endpoint(struct net *net,
784 struct sctp_hashbucket *head; 784 struct sctp_hashbucket *head;
785 struct sctp_ep_common *epb; 785 struct sctp_ep_common *epb;
786 struct sctp_endpoint *ep; 786 struct sctp_endpoint *ep;
787 struct hlist_node *node;
788 int hash; 787 int hash;
789 788
790 hash = sctp_ep_hashfn(net, ntohs(laddr->v4.sin_port)); 789 hash = sctp_ep_hashfn(net, ntohs(laddr->v4.sin_port));
791 head = &sctp_ep_hashtable[hash]; 790 head = &sctp_ep_hashtable[hash];
792 read_lock(&head->lock); 791 read_lock(&head->lock);
793 sctp_for_each_hentry(epb, node, &head->chain) { 792 sctp_for_each_hentry(epb, &head->chain) {
794 ep = sctp_ep(epb); 793 ep = sctp_ep(epb);
795 if (sctp_endpoint_is_match(ep, net, laddr)) 794 if (sctp_endpoint_is_match(ep, net, laddr))
796 goto hit; 795 goto hit;
@@ -876,7 +875,6 @@ static struct sctp_association *__sctp_lookup_association(
876 struct sctp_ep_common *epb; 875 struct sctp_ep_common *epb;
877 struct sctp_association *asoc; 876 struct sctp_association *asoc;
878 struct sctp_transport *transport; 877 struct sctp_transport *transport;
879 struct hlist_node *node;
880 int hash; 878 int hash;
881 879
882 /* Optimize here for direct hit, only listening connections can 880 /* Optimize here for direct hit, only listening connections can
@@ -886,7 +884,7 @@ static struct sctp_association *__sctp_lookup_association(
886 ntohs(peer->v4.sin_port)); 884 ntohs(peer->v4.sin_port));
887 head = &sctp_assoc_hashtable[hash]; 885 head = &sctp_assoc_hashtable[hash];
888 read_lock(&head->lock); 886 read_lock(&head->lock);
889 sctp_for_each_hentry(epb, node, &head->chain) { 887 sctp_for_each_hentry(epb, &head->chain) {
890 asoc = sctp_assoc(epb); 888 asoc = sctp_assoc(epb);
891 transport = sctp_assoc_is_match(asoc, net, local, peer); 889 transport = sctp_assoc_is_match(asoc, net, local, peer);
892 if (transport) 890 if (transport)
diff --git a/net/sctp/proc.c b/net/sctp/proc.c
index 8c19e97262ca..ab3bba8cb0a8 100644
--- a/net/sctp/proc.c
+++ b/net/sctp/proc.c
@@ -213,7 +213,6 @@ static int sctp_eps_seq_show(struct seq_file *seq, void *v)
213 struct sctp_ep_common *epb; 213 struct sctp_ep_common *epb;
214 struct sctp_endpoint *ep; 214 struct sctp_endpoint *ep;
215 struct sock *sk; 215 struct sock *sk;
216 struct hlist_node *node;
217 int hash = *(loff_t *)v; 216 int hash = *(loff_t *)v;
218 217
219 if (hash >= sctp_ep_hashsize) 218 if (hash >= sctp_ep_hashsize)
@@ -222,7 +221,7 @@ static int sctp_eps_seq_show(struct seq_file *seq, void *v)
222 head = &sctp_ep_hashtable[hash]; 221 head = &sctp_ep_hashtable[hash];
223 sctp_local_bh_disable(); 222 sctp_local_bh_disable();
224 read_lock(&head->lock); 223 read_lock(&head->lock);
225 sctp_for_each_hentry(epb, node, &head->chain) { 224 sctp_for_each_hentry(epb, &head->chain) {
226 ep = sctp_ep(epb); 225 ep = sctp_ep(epb);
227 sk = epb->sk; 226 sk = epb->sk;
228 if (!net_eq(sock_net(sk), seq_file_net(seq))) 227 if (!net_eq(sock_net(sk), seq_file_net(seq)))
@@ -321,7 +320,6 @@ static int sctp_assocs_seq_show(struct seq_file *seq, void *v)
321 struct sctp_ep_common *epb; 320 struct sctp_ep_common *epb;
322 struct sctp_association *assoc; 321 struct sctp_association *assoc;
323 struct sock *sk; 322 struct sock *sk;
324 struct hlist_node *node;
325 int hash = *(loff_t *)v; 323 int hash = *(loff_t *)v;
326 324
327 if (hash >= sctp_assoc_hashsize) 325 if (hash >= sctp_assoc_hashsize)
@@ -330,7 +328,7 @@ static int sctp_assocs_seq_show(struct seq_file *seq, void *v)
330 head = &sctp_assoc_hashtable[hash]; 328 head = &sctp_assoc_hashtable[hash];
331 sctp_local_bh_disable(); 329 sctp_local_bh_disable();
332 read_lock(&head->lock); 330 read_lock(&head->lock);
333 sctp_for_each_hentry(epb, node, &head->chain) { 331 sctp_for_each_hentry(epb, &head->chain) {
334 assoc = sctp_assoc(epb); 332 assoc = sctp_assoc(epb);
335 sk = epb->sk; 333 sk = epb->sk;
336 if (!net_eq(sock_net(sk), seq_file_net(seq))) 334 if (!net_eq(sock_net(sk), seq_file_net(seq)))
@@ -436,7 +434,6 @@ static int sctp_remaddr_seq_show(struct seq_file *seq, void *v)
436 struct sctp_hashbucket *head; 434 struct sctp_hashbucket *head;
437 struct sctp_ep_common *epb; 435 struct sctp_ep_common *epb;
438 struct sctp_association *assoc; 436 struct sctp_association *assoc;
439 struct hlist_node *node;
440 struct sctp_transport *tsp; 437 struct sctp_transport *tsp;
441 int hash = *(loff_t *)v; 438 int hash = *(loff_t *)v;
442 439
@@ -447,7 +444,7 @@ static int sctp_remaddr_seq_show(struct seq_file *seq, void *v)
447 sctp_local_bh_disable(); 444 sctp_local_bh_disable();
448 read_lock(&head->lock); 445 read_lock(&head->lock);
449 rcu_read_lock(); 446 rcu_read_lock();
450 sctp_for_each_hentry(epb, node, &head->chain) { 447 sctp_for_each_hentry(epb, &head->chain) {
451 if (!net_eq(sock_net(epb->sk), seq_file_net(seq))) 448 if (!net_eq(sock_net(epb->sk), seq_file_net(seq)))
452 continue; 449 continue;
453 assoc = sctp_assoc(epb); 450 assoc = sctp_assoc(epb);
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 9ef5c7312e12..b9070736b8d9 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -5882,8 +5882,7 @@ static struct sctp_bind_bucket *sctp_bucket_create(
5882static long sctp_get_port_local(struct sock *sk, union sctp_addr *addr) 5882static long sctp_get_port_local(struct sock *sk, union sctp_addr *addr)
5883{ 5883{
5884 struct sctp_bind_hashbucket *head; /* hash list */ 5884 struct sctp_bind_hashbucket *head; /* hash list */
5885 struct sctp_bind_bucket *pp; /* hash list port iterator */ 5885 struct sctp_bind_bucket *pp;
5886 struct hlist_node *node;
5887 unsigned short snum; 5886 unsigned short snum;
5888 int ret; 5887 int ret;
5889 5888
@@ -5910,7 +5909,7 @@ static long sctp_get_port_local(struct sock *sk, union sctp_addr *addr)
5910 index = sctp_phashfn(sock_net(sk), rover); 5909 index = sctp_phashfn(sock_net(sk), rover);
5911 head = &sctp_port_hashtable[index]; 5910 head = &sctp_port_hashtable[index];
5912 sctp_spin_lock(&head->lock); 5911 sctp_spin_lock(&head->lock);
5913 sctp_for_each_hentry(pp, node, &head->chain) 5912 sctp_for_each_hentry(pp, &head->chain)
5914 if ((pp->port == rover) && 5913 if ((pp->port == rover) &&
5915 net_eq(sock_net(sk), pp->net)) 5914 net_eq(sock_net(sk), pp->net))
5916 goto next; 5915 goto next;
@@ -5938,7 +5937,7 @@ static long sctp_get_port_local(struct sock *sk, union sctp_addr *addr)
5938 */ 5937 */
5939 head = &sctp_port_hashtable[sctp_phashfn(sock_net(sk), snum)]; 5938 head = &sctp_port_hashtable[sctp_phashfn(sock_net(sk), snum)];
5940 sctp_spin_lock(&head->lock); 5939 sctp_spin_lock(&head->lock);
5941 sctp_for_each_hentry(pp, node, &head->chain) { 5940 sctp_for_each_hentry(pp, &head->chain) {
5942 if ((pp->port == snum) && net_eq(pp->net, sock_net(sk))) 5941 if ((pp->port == snum) && net_eq(pp->net, sock_net(sk)))
5943 goto pp_found; 5942 goto pp_found;
5944 } 5943 }
@@ -5970,7 +5969,7 @@ pp_found:
5970 * that this port/socket (sk) combination are already 5969 * that this port/socket (sk) combination are already
5971 * in an endpoint. 5970 * in an endpoint.
5972 */ 5971 */
5973 sk_for_each_bound(sk2, node, &pp->owner) { 5972 sk_for_each_bound(sk2, &pp->owner) {
5974 struct sctp_endpoint *ep2; 5973 struct sctp_endpoint *ep2;
5975 ep2 = sctp_sk(sk2)->ep; 5974 ep2 = sctp_sk(sk2)->ep;
5976 5975