]> err.no Git - linux-2.6/blobdiff - net/sctp/endpointola.c
[MAC80211]: PS mode fix
[linux-2.6] / net / sctp / endpointola.c
index a2b5537215144473b9362e4ef94cc050c5373527..22371185efb64bebfc669126ba7ee24606c9f546 100644 (file)
@@ -50,7 +50,6 @@
  */
 
 #include <linux/types.h>
-#include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/in.h>
 #include <linux/random.h>      /* get_random_bytes() */
@@ -72,6 +71,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;
@@ -89,7 +92,6 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep,
 
        /* Initialize the bind addr area */
        sctp_bind_addr_init(&ep->base.bind_addr, 0);
-       rwlock_init(&ep->base.addr_lock);
 
        /* Remember who we are attached to.  */
        ep->base.sk = sk;
@@ -100,6 +102,7 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep,
 
        /* Use SCTP specific send buffer space queues.  */
        ep->sndbuf_policy = sctp_sndbuf_policy;
+
        sk->sk_write_space = sctp_write_space;
        sock_set_flag(sk, SOCK_USE_WRITE_QUEUE);
 
@@ -181,6 +184,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);
@@ -219,21 +225,14 @@ void sctp_endpoint_put(struct sctp_endpoint *ep)
 struct sctp_endpoint *sctp_endpoint_is_match(struct sctp_endpoint *ep,
                                               const union sctp_addr *laddr)
 {
-       struct sctp_endpoint *retval;
+       struct sctp_endpoint *retval = NULL;
 
-       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))) {
+                                        sctp_sk(ep->base.sk)))
                        retval = ep;
-                       goto out;
-               }
        }
 
-       retval = NULL;
-
-out:
-       sctp_read_unlock(&ep->base.addr_lock);
        return retval;
 }
 
@@ -250,14 +249,12 @@ 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);
                if (rport == asoc->peer.port) {
-                       sctp_read_lock(&asoc->base.addr_lock);
                        *transport = sctp_assoc_lookup_paddr(asoc, paddr);
-                       sctp_read_unlock(&asoc->base.addr_lock);
 
                        if (*transport)
                                return asoc;
@@ -289,20 +286,17 @@ struct sctp_association *sctp_endpoint_lookup_assoc(
 int sctp_endpoint_is_peeled_off(struct sctp_endpoint *ep,
                                const union sctp_addr *paddr)
 {
-       struct list_head *pos;
        struct sctp_sockaddr_entry *addr;
        struct sctp_bind_addr *bp;
 
-       sctp_read_lock(&ep->base.addr_lock);
        bp = &ep->base.bind_addr;
-       list_for_each(pos, &bp->address_list) {
-               addr = list_entry(pos, struct sctp_sockaddr_entry, list);
-               if (sctp_has_association(&addr->a, paddr)) {
-                       sctp_read_unlock(&ep->base.addr_lock);
+       /* This function is called with the socket lock held,
+        * so the address_list can not change.
+        */
+       list_for_each_entry(addr, &bp->address_list, list) {
+               if (sctp_has_association(&addr->a, paddr))
                        return 1;
-               }
        }
-       sctp_read_unlock(&ep->base.addr_lock);
 
        return 0;
 }
@@ -362,7 +356,7 @@ static void sctp_endpoint_bh_rcv(struct work_struct *work)
                        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;