Commit 247d0d19 authored by Jon Grimm's avatar Jon Grimm

[SCTP] Break out sctp_assoc_valid() from sctp_id2assoc().

sctp_id2assoc() was trying to do too many things.  Break out, so
sctp_assoc_bh_rcv() can just find out whether the assoc is valid.
parent ec7bf6c1
...@@ -281,7 +281,7 @@ struct sctp_association *sctp_association_init(struct sctp_association *asoc, ...@@ -281,7 +281,7 @@ struct sctp_association *sctp_association_init(struct sctp_association *asoc,
asoc->default_flags = sp->default_flags; asoc->default_flags = sp->default_flags;
asoc->default_context = sp->default_context; asoc->default_context = sp->default_context;
asoc->default_timetolive = sp->default_timetolive; asoc->default_timetolive = sp->default_timetolive;
return asoc; return asoc;
fail_init: fail_init:
...@@ -384,7 +384,7 @@ void sctp_assoc_set_primary(struct sctp_association *asoc, ...@@ -384,7 +384,7 @@ void sctp_assoc_set_primary(struct sctp_association *asoc,
if (transport->active) if (transport->active)
asoc->peer.active_path = transport; asoc->peer.active_path = transport;
/* /*
* SFR-CACC algorithm: * SFR-CACC algorithm:
* Upon the receipt of a request to change the primary * Upon the receipt of a request to change the primary
* destination address, on the data structure for the new * destination address, on the data structure for the new
...@@ -793,6 +793,26 @@ struct sctp_transport *sctp_assoc_is_match(struct sctp_association *asoc, ...@@ -793,6 +793,26 @@ struct sctp_transport *sctp_assoc_is_match(struct sctp_association *asoc,
return transport; return transport;
} }
/* Is this a live association structure. */
int sctp_assoc_valid(struct sock *sk, struct sctp_association *asoc)
{
/* First, verify that this is a kernel address. */
if (!sctp_is_valid_kaddr((unsigned long) asoc))
return 0;
/* Verify that this _is_ an sctp_association
* data structure and if so, that the socket matches.
*/
if (SCTP_ASSOC_EYECATCHER != asoc->eyecatcher)
return 0;
if (asoc->base.sk != sk)
return 0;
/* The association is valid. */
return 1;
}
/* Do delayed input processing. This is scheduled by sctp_rcv(). */ /* Do delayed input processing. This is scheduled by sctp_rcv(). */
static void sctp_assoc_bh_rcv(struct sctp_association *asoc) static void sctp_assoc_bh_rcv(struct sctp_association *asoc)
{ {
...@@ -801,7 +821,6 @@ static void sctp_assoc_bh_rcv(struct sctp_association *asoc) ...@@ -801,7 +821,6 @@ static void sctp_assoc_bh_rcv(struct sctp_association *asoc)
struct sock *sk; struct sock *sk;
struct sctp_inq *inqueue; struct sctp_inq *inqueue;
int state, subtype; int state, subtype;
sctp_assoc_t associd = sctp_assoc2id(asoc);
int error = 0; int error = 0;
/* The association should be held so we should be safe. */ /* The association should be held so we should be safe. */
...@@ -831,7 +850,7 @@ static void sctp_assoc_bh_rcv(struct sctp_association *asoc) ...@@ -831,7 +850,7 @@ static void sctp_assoc_bh_rcv(struct sctp_association *asoc)
/* Check to see if the association is freed in response to /* Check to see if the association is freed in response to
* the incoming chunk. If so, get out of the while loop. * the incoming chunk. If so, get out of the while loop.
*/ */
if (!sctp_id2assoc(sk, associd)) if (!sctp_assoc_valid(sk, asoc))
break; break;
/* If there is an error on chunk, discard this packet. */ /* If there is an error on chunk, discard this packet. */
......
...@@ -101,6 +101,9 @@ static char *sctp_hmac_alg = SCTP_COOKIE_HMAC_ALG; ...@@ -101,6 +101,9 @@ static char *sctp_hmac_alg = SCTP_COOKIE_HMAC_ALG;
extern kmem_cache_t *sctp_bucket_cachep; extern kmem_cache_t *sctp_bucket_cachep;
extern int sctp_assoc_valid(struct sock *sk, struct sctp_association *asoc);
/* Look up the association by its id. If this is not a UDP-style /* Look up the association by its id. If this is not a UDP-style
* socket, the ID field is always ignored. * socket, the ID field is always ignored.
*/ */
...@@ -110,32 +113,24 @@ struct sctp_association *sctp_id2assoc(struct sock *sk, sctp_assoc_t id) ...@@ -110,32 +113,24 @@ struct sctp_association *sctp_id2assoc(struct sock *sk, sctp_assoc_t id)
/* If this is not a UDP-style socket, assoc id should be ignored. */ /* If this is not a UDP-style socket, assoc id should be ignored. */
if (!sctp_style(sk, UDP)) { if (!sctp_style(sk, UDP)) {
/* Return NULL if the socket state is not ESTABLISHED. It /* Return NULL if the socket state is not ESTABLISHED. It
* could be a TCP-style listening socket or a socket which * could be a TCP-style listening socket or a socket which
* hasn't yet called connect() to establish an association. * hasn't yet called connect() to establish an association.
*/ */
if (!sctp_sstate(sk, ESTABLISHED)) if (!sctp_sstate(sk, ESTABLISHED))
return NULL; return NULL;
/* Get the first and the only association from the list. */ /* Get the first and the only association from the list. */
if (!list_empty(&sctp_sk(sk)->ep->asocs)) if (!list_empty(&sctp_sk(sk)->ep->asocs))
asoc = list_entry(sctp_sk(sk)->ep->asocs.next, asoc = list_entry(sctp_sk(sk)->ep->asocs.next,
struct sctp_association, asocs); struct sctp_association, asocs);
return asoc; return asoc;
} }
/* First, verify that this is a kernel address. */ /* Otherwise this is a UDP-style socket. */
if (sctp_is_valid_kaddr((unsigned long) id)) { asoc = (struct sctp_association *)id;
struct sctp_association *temp; if (!sctp_assoc_valid(sk, asoc))
return NULL;
/* Verify that this _is_ an sctp_association
* data structure and if so, that the socket matches.
*/
temp = (struct sctp_association *)id;
if ((SCTP_ASSOC_EYECATCHER == temp->eyecatcher) &&
(temp->base.sk == sk))
asoc = temp;
}
return asoc; return asoc;
} }
...@@ -1456,7 +1451,7 @@ static int sctp_setsockopt_autoclose(struct sock *sk, char *optval, ...@@ -1456,7 +1451,7 @@ static int sctp_setsockopt_autoclose(struct sock *sk, char *optval,
* spp_pathmaxrxt - This contains the maximum number of * spp_pathmaxrxt - This contains the maximum number of
* retransmissions before this address shall be * retransmissions before this address shall be
* considered unreachable. * considered unreachable.
*/ */
static int sctp_setsockopt_peer_addr_params(struct sock *sk, static int sctp_setsockopt_peer_addr_params(struct sock *sk,
char *optval, int optlen) char *optval, int optlen)
{ {
...@@ -2430,7 +2425,7 @@ static int sctp_getsockopt_peeloff(struct sock *sk, int len, char *optval, int * ...@@ -2430,7 +2425,7 @@ static int sctp_getsockopt_peeloff(struct sock *sk, int len, char *optval, int *
* spp_pathmaxrxt - This contains the maximum number of * spp_pathmaxrxt - This contains the maximum number of
* retransmissions before this address shall be * retransmissions before this address shall be
* considered unreachable. * considered unreachable.
*/ */
static int sctp_getsockopt_peer_addr_params(struct sock *sk, int len, static int sctp_getsockopt_peer_addr_params(struct sock *sk, int len,
char *optval, int *optlen) char *optval, int *optlen)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment