diff options
author | Xin Long <lucien.xin@gmail.com> | 2015-12-30 10:50:47 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-01-05 12:24:01 -0500 |
commit | 4f0087812648b7611157ae22954acfaed820d24e (patch) | |
tree | 51dfe36a54bdf7161e188c3818d6d046d4d66c08 /net/sctp/input.c | |
parent | d6c0256a60e685214cc8cc2b886809f11efc0084 (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.c | 39 |
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 | |||
1008 | hit: | ||
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 */ |
1016 | static | 997 | static |
1017 | struct sctp_association *sctp_lookup_association(struct net *net, | 998 | struct 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 | } |