summaryrefslogtreecommitdiffstats
path: root/net/sctp/input.c
diff options
context:
space:
mode:
authorXin Long <lucien.xin@gmail.com>2015-12-30 10:50:47 -0500
committerDavid S. Miller <davem@davemloft.net>2016-01-05 12:24:01 -0500
commit4f0087812648b7611157ae22954acfaed820d24e (patch)
tree51dfe36a54bdf7161e188c3818d6d046d4d66c08 /net/sctp/input.c
parentd6c0256a60e685214cc8cc2b886809f11efc0084 (diff)
sctp: apply rhashtable api to send/recv path
apply lookup apis to two functions, for __sctp_endpoint_lookup_assoc and __sctp_lookup_association, it's invoked in the protection of sock lock, it will be safe, but sctp_lookup_association need to call rcu_read_lock() and to detect the t->dead to protect it. Signed-off-by: Xin Long <lucien.xin@gmail.com> Signed-off-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sctp/input.c')
-rw-r--r--net/sctp/input.c39
1 files changed, 10 insertions, 29 deletions
diff --git a/net/sctp/input.c b/net/sctp/input.c
index bac8278b176b..6f075d835764 100644
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -981,38 +981,19 @@ static struct sctp_association *__sctp_lookup_association(
981 const union sctp_addr *peer, 981 const union sctp_addr *peer,
982 struct sctp_transport **pt) 982 struct sctp_transport **pt)
983{ 983{
984 struct sctp_hashbucket *head; 984 struct sctp_transport *t;
985 struct sctp_ep_common *epb;
986 struct sctp_association *asoc;
987 struct sctp_transport *transport;
988 int hash;
989 985
990 /* Optimize here for direct hit, only listening connections can 986 t = sctp_addrs_lookup_transport(net, local, peer);
991 * have wildcards anyways. 987 if (!t || t->dead || t->asoc->temp)
992 */ 988 return NULL;
993 hash = sctp_assoc_hashfn(net, ntohs(local->v4.sin_port),
994 ntohs(peer->v4.sin_port));
995 head = &sctp_assoc_hashtable[hash];
996 read_lock(&head->lock);
997 sctp_for_each_hentry(epb, &head->chain) {
998 asoc = sctp_assoc(epb);
999 transport = sctp_assoc_is_match(asoc, net, local, peer);
1000 if (transport)
1001 goto hit;
1002 }
1003 989
1004 read_unlock(&head->lock); 990 sctp_association_hold(t->asoc);
991 *pt = t;
1005 992
1006 return NULL; 993 return t->asoc;
1007
1008hit:
1009 *pt = transport;
1010 sctp_association_hold(asoc);
1011 read_unlock(&head->lock);
1012 return asoc;
1013} 994}
1014 995
1015/* Look up an association. BH-safe. */ 996/* Look up an association. protected by RCU read lock */
1016static 997static
1017struct sctp_association *sctp_lookup_association(struct net *net, 998struct sctp_association *sctp_lookup_association(struct net *net,
1018 const union sctp_addr *laddr, 999 const union sctp_addr *laddr,
@@ -1021,9 +1002,9 @@ struct sctp_association *sctp_lookup_association(struct net *net,
1021{ 1002{
1022 struct sctp_association *asoc; 1003 struct sctp_association *asoc;
1023 1004
1024 local_bh_disable(); 1005 rcu_read_lock();
1025 asoc = __sctp_lookup_association(net, laddr, paddr, transportp); 1006 asoc = __sctp_lookup_association(net, laddr, paddr, transportp);
1026 local_bh_enable(); 1007 rcu_read_unlock();
1027 1008
1028 return asoc; 1009 return asoc;
1029} 1010}