aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/sctp/endpointola.c34
1 files changed, 22 insertions, 12 deletions
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c
index 2d2d81ef4a69..68f0556efcc6 100644
--- a/net/sctp/endpointola.c
+++ b/net/sctp/endpointola.c
@@ -328,24 +328,34 @@ static struct sctp_association *__sctp_endpoint_lookup_assoc(
328 const union sctp_addr *paddr, 328 const union sctp_addr *paddr,
329 struct sctp_transport **transport) 329 struct sctp_transport **transport)
330{ 330{
331 struct sctp_association *asoc = NULL;
332 struct sctp_transport *t = NULL;
333 struct sctp_hashbucket *head;
334 struct sctp_ep_common *epb;
335 int hash;
331 int rport; 336 int rport;
332 struct sctp_association *asoc;
333 struct list_head *pos;
334 337
338 *transport = NULL;
335 rport = ntohs(paddr->v4.sin_port); 339 rport = ntohs(paddr->v4.sin_port);
336 340
337 list_for_each(pos, &ep->asocs) { 341 hash = sctp_assoc_hashfn(ep->base.bind_addr.port, rport);
338 asoc = list_entry(pos, struct sctp_association, asocs); 342 head = &sctp_assoc_hashtable[hash];
339 if (rport == asoc->peer.port) { 343 read_lock(&head->lock);
340 *transport = sctp_assoc_lookup_paddr(asoc, paddr); 344 for (epb = head->chain; epb; epb = epb->next) {
341 345 asoc = sctp_assoc(epb);
342 if (*transport) 346 if (asoc->ep != ep || rport != asoc->peer.port)
343 return asoc; 347 goto next;
348
349 t = sctp_assoc_lookup_paddr(asoc, paddr);
350 if (t) {
351 *transport = t;
352 break;
344 } 353 }
354next:
355 asoc = NULL;
345 } 356 }
346 357 read_unlock(&head->lock);
347 *transport = NULL; 358 return asoc;
348 return NULL;
349} 359}
350 360
351/* Lookup association on an endpoint based on a peer address. BH-safe. */ 361/* Lookup association on an endpoint based on a peer address. BH-safe. */