summaryrefslogtreecommitdiffstats
path: root/net/sctp/input.c
diff options
context:
space:
mode:
authorXin Long <lucien.xin@gmail.com>2015-12-30 16:50:47 +0100
committerDavid S. Miller <davem@davemloft.net>2016-01-05 18:24:01 +0100
commit4f0087812648b7611157ae22954acfaed820d24e (patch)
tree51dfe36a54bdf7161e188c3818d6d046d4d66c08 /net/sctp/input.c
parentsctp: add the rhashtable apis for sctp global transport hashtable (diff)
downloadlinux-4f0087812648b7611157ae22954acfaed820d24e.tar.xz
linux-4f0087812648b7611157ae22954acfaed820d24e.zip
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(
const union sctp_addr *peer,
struct sctp_transport **pt)
{
- struct sctp_hashbucket *head;
- struct sctp_ep_common *epb;
- struct sctp_association *asoc;
- struct sctp_transport *transport;
- int hash;
+ struct sctp_transport *t;
- /* Optimize here for direct hit, only listening connections can
- * have wildcards anyways.
- */
- hash = sctp_assoc_hashfn(net, ntohs(local->v4.sin_port),
- ntohs(peer->v4.sin_port));
- head = &sctp_assoc_hashtable[hash];
- read_lock(&head->lock);
- sctp_for_each_hentry(epb, &head->chain) {
- asoc = sctp_assoc(epb);
- transport = sctp_assoc_is_match(asoc, net, local, peer);
- if (transport)
- goto hit;
- }
+ t = sctp_addrs_lookup_transport(net, local, peer);
+ if (!t || t->dead || t->asoc->temp)
+ return NULL;
- read_unlock(&head->lock);
+ sctp_association_hold(t->asoc);
+ *pt = t;
- return NULL;
-
-hit:
- *pt = transport;
- sctp_association_hold(asoc);
- read_unlock(&head->lock);
- return asoc;
+ return t->asoc;
}
-/* Look up an association. BH-safe. */
+/* Look up an association. protected by RCU read lock */
static
struct sctp_association *sctp_lookup_association(struct net *net,
const union sctp_addr *laddr,
@@ -1021,9 +1002,9 @@ struct sctp_association *sctp_lookup_association(struct net *net,
{
struct sctp_association *asoc;
- local_bh_disable();
+ rcu_read_lock();
asoc = __sctp_lookup_association(net, laddr, paddr, transportp);
- local_bh_enable();
+ rcu_read_unlock();
return asoc;
}