X-Git-Url: http://git.agner.ch/gitweb/?a=blobdiff_plain;f=net%2Fsctp%2Fendpointola.c;h=286a8dbb63b7f56924bc99961e5a469c56429013;hb=958b7f37ee0fb2846c8d44310a68ae9605614ff9;hp=35c49ff2d0621b445dbced33f74894663a189b4d;hpb=e823aff2d6eb43083abcc75a32ddfb167c324089;p=linux-drm-fsl-dcu.git diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c index 35c49ff2d062..286a8dbb63b7 100644 --- a/net/sctp/endpointola.c +++ b/net/sctp/endpointola.c @@ -61,7 +61,7 @@ #include /* Forward declarations for internal helpers. */ -static void sctp_endpoint_bh_rcv(struct sctp_endpoint *ep); +static void sctp_endpoint_bh_rcv(struct work_struct *work); /* * Initialize the base fields of the endpoint structure. @@ -72,6 +72,10 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep, { memset(ep, 0, sizeof(struct sctp_endpoint)); + ep->digest = kzalloc(SCTP_SIGNATURE_SIZE, gfp); + if (!ep->digest) + return NULL; + /* Initialize the base structure. */ /* What type of endpoint are we? */ ep->base.type = SCTP_EP_TYPE_SOCKET; @@ -85,8 +89,7 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep, sctp_inq_init(&ep->base.inqueue); /* Set its top-half handler */ - sctp_inq_set_th_handler(&ep->base.inqueue, - (void (*)(void *))sctp_endpoint_bh_rcv, ep); + sctp_inq_set_th_handler(&ep->base.inqueue, sctp_endpoint_bh_rcv); /* Initialize the bind addr area */ sctp_bind_addr_init(&ep->base.bind_addr, 0); @@ -144,6 +147,13 @@ void sctp_endpoint_add_asoc(struct sctp_endpoint *ep, { struct sock *sk = ep->base.sk; + /* If this is a temporary association, don't bother + * since we'll be removing it shortly and don't + * want anyone to find it anyway. + */ + if (asoc->temp) + return; + /* Now just add it to our list of asocs */ list_add_tail(&asoc->asocs, &ep->asocs); @@ -175,6 +185,9 @@ static void sctp_endpoint_destroy(struct sctp_endpoint *ep) /* Free up the HMAC transform. */ crypto_free_hash(sctp_sk(ep->base.sk)->hmac); + /* Free the digest buffer */ + kfree(ep->digest); + /* Cleanup. */ sctp_inq_free(&ep->base.inqueue); sctp_bind_addr_free(&ep->base.bind_addr); @@ -216,7 +229,7 @@ struct sctp_endpoint *sctp_endpoint_is_match(struct sctp_endpoint *ep, struct sctp_endpoint *retval; sctp_read_lock(&ep->base.addr_lock); - if (ep->base.bind_addr.port == laddr->v4.sin_port) { + if (htons(ep->base.bind_addr.port) == laddr->v4.sin_port) { if (sctp_bind_addr_match(&ep->base.bind_addr, laddr, sctp_sk(ep->base.sk))) { retval = ep; @@ -244,7 +257,7 @@ static struct sctp_association *__sctp_endpoint_lookup_assoc( struct sctp_association *asoc; struct list_head *pos; - rport = paddr->v4.sin_port; + rport = ntohs(paddr->v4.sin_port); list_for_each(pos, &ep->asocs) { asoc = list_entry(pos, struct sctp_association, asocs); @@ -304,8 +317,11 @@ int sctp_endpoint_is_peeled_off(struct sctp_endpoint *ep, /* Do delayed input processing. This is scheduled by sctp_rcv(). * This may be called on BH or task time. */ -static void sctp_endpoint_bh_rcv(struct sctp_endpoint *ep) +static void sctp_endpoint_bh_rcv(struct work_struct *work) { + struct sctp_endpoint *ep = + container_of(work, struct sctp_endpoint, + base.inqueue.immediate); struct sctp_association *asoc; struct sock *sk; struct sctp_transport *transport; @@ -353,7 +369,7 @@ static void sctp_endpoint_bh_rcv(struct sctp_endpoint *ep) chunk->transport->last_time_heard = jiffies; error = sctp_do_sm(SCTP_EVENT_T_CHUNK, subtype, state, - ep, asoc, chunk, GFP_ATOMIC); + ep, asoc, chunk, GFP_ATOMIC); if (error && chunk) chunk->pdiscard = 1;