summaryrefslogtreecommitdiff
path: root/net/sctp/socket.c
diff options
context:
space:
mode:
authorJakub Kicinski <kuba@kernel.org>2022-01-05 14:36:10 -0800
committerJakub Kicinski <kuba@kernel.org>2022-01-05 14:36:10 -0800
commitb9adba350a841e8233d3e4d8d3c8dede3fc88c46 (patch)
tree2fbaa3fb25cf76d44a510e0c4f96c02622e268f9 /net/sctp/socket.c
parent4e4f325a0a55907b14f579e6b1a38c53755e3de2 (diff)
parent75acfdb6fd922598a408a0d864486aeb167c1a97 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
No conflicts. Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'net/sctp/socket.c')
-rw-r--r--net/sctp/socket.c22
1 files changed, 15 insertions, 7 deletions
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index f548c67c7cff..3e1a9600be5e 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -5312,23 +5312,31 @@ int sctp_for_each_endpoint(int (*cb)(struct sctp_endpoint *, void *),
}
EXPORT_SYMBOL_GPL(sctp_for_each_endpoint);
-int sctp_transport_lookup_process(int (*cb)(struct sctp_transport *, void *),
- struct net *net,
+int sctp_transport_lookup_process(sctp_callback_t cb, struct net *net,
const union sctp_addr *laddr,
const union sctp_addr *paddr, void *p)
{
struct sctp_transport *transport;
- int err;
+ struct sctp_endpoint *ep;
+ int err = -ENOENT;
rcu_read_lock();
transport = sctp_addrs_lookup_transport(net, laddr, paddr);
+ if (!transport) {
+ rcu_read_unlock();
+ return err;
+ }
+ ep = transport->asoc->ep;
+ if (!sctp_endpoint_hold(ep)) { /* asoc can be peeled off */
+ sctp_transport_put(transport);
+ rcu_read_unlock();
+ return err;
+ }
rcu_read_unlock();
- if (!transport)
- return -ENOENT;
- err = cb(transport, p);
+ err = cb(ep, transport, p);
+ sctp_endpoint_put(ep);
sctp_transport_put(transport);
-
return err;
}
EXPORT_SYMBOL_GPL(sctp_transport_lookup_process);