netdev
[Top] [All Lists]

[BK PATCH] 2.4 SCTP updates

To: davem@xxxxxxxxxx
Subject: [BK PATCH] 2.4 SCTP updates
From: Sridhar Samudrala <sri@xxxxxxxxxx>
Date: Tue, 6 Apr 2004 12:09:26 -0700 (PDT)
Cc: netdev@xxxxxxxxxxx, lksctp-developers@xxxxxxxxxxxxxxxxxxxxx
Sender: netdev-bounce@xxxxxxxxxxx
Hi Dave

Please do a
        bk pull http://linux-lksctp.bkbits.net/lksctp-2.4.work
to get the following updates to SCTP on top of linux 2.4.26-rc2

This includes 2 of the 3 patches i submitted for 2.6.

lib/idr.c is not present in 2.4 and hence i could not remove the use of
address of association as its id and virt_addr_valid(). I guess it should be
OK for now as PAGEALLOC debugging is not available with 2.4.
may be we should backport idr.c to 2.4 or come up with a similar service.

Thanks
Sridhar


# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
#   2004/04/06 09:28:32-07:00 sri@xxxxxxxxxx
#   [SCTP] Update sctp_ulpevent structure to include assoc pointer and
#   only the receive specific fields of sctp_sndrcvinfo.
#
# net/sctp/ulpqueue.c
# net/sctp/ulpevent.c
# net/sctp/socket.c
# net/sctp/protocol.c
# net/sctp/ipv6.c
# include/net/sctp/ulpevent.h
#
# ChangeSet
#   2004/04/06 07:54:05-07:00 sri@xxxxxxxxxx
#   [SCTP] Fix typo in entry name of the remove_proc_entry() call.
#
# net/sctp/objcnt.c
#
diff -Nru a/include/net/sctp/ulpevent.h b/include/net/sctp/ulpevent.h
--- a/include/net/sctp/ulpevent.h       Tue Apr  6 11:54:30 2004
+++ b/include/net/sctp/ulpevent.h       Tue Apr  6 11:54:30 2004
@@ -1,7 +1,7 @@
 /* SCTP kernel reference Implementation
+ * (C) Copyright IBM Corp. 2001, 2004
  * Copyright (c) 1999-2000 Cisco, Inc.
  * Copyright (c) 1999-2001 Motorola, Inc.
- * Copyright (c) 2001 International Business Machines, Corp.
  * Copyright (c) 2001 Intel Corp.
  * Copyright (c) 2001 Nokia, Inc.
  * Copyright (c) 2001 La Monte H.P. Yarroll
@@ -54,7 +54,13 @@
  * growing this structure as it is at the maximum limit now.
  */
 struct sctp_ulpevent {
-       struct sctp_sndrcvinfo sndrcvinfo;
+       struct sctp_association *asoc;
+       __u16 stream;
+       __u16 ssn;
+       __u16 flags;
+       __u32 ppid;
+       __u32 tsn;
+       __u32 cumtsn;
        int msg_flags;
        int iif;
 };
diff -Nru a/net/sctp/ipv6.c b/net/sctp/ipv6.c
--- a/net/sctp/ipv6.c   Tue Apr  6 11:54:30 2004
+++ b/net/sctp/ipv6.c   Tue Apr  6 11:54:30 2004
@@ -1,7 +1,7 @@
 /* SCTP kernel reference Implementation
+ * (C) Copyright IBM Corp. 2002, 2004
  * Copyright (c) 2001 Nokia, Inc.
  * Copyright (c) 2001 La Monte H.P. Yarroll
- * Copyright (c) 2002-2003 International Business Machines, Corp.
  * Copyright (c) 2002-2003 Intel Corp.
  *
  * This file is part of the SCTP kernel reference Implementation
@@ -703,7 +703,7 @@
                union sctp_addr *addr;
                struct sctp_association *asoc;

-               asoc = event->sndrcvinfo.sinfo_assoc_id;
+               asoc = event->asoc;
                sctp_inet6_msgname(msgname, addrlen);
                sin6 = (struct sockaddr_in6 *)msgname;
                sin6->sin6_port = htons(asoc->peer.port);
diff -Nru a/net/sctp/objcnt.c b/net/sctp/objcnt.c
--- a/net/sctp/objcnt.c Tue Apr  6 11:54:30 2004
+++ b/net/sctp/objcnt.c Tue Apr  6 11:54:30 2004
@@ -132,7 +132,7 @@
 /* Cleanup the objcount entry in the proc filesystem.  */
 void sctp_dbg_objcnt_exit(void)
 {
-       remove_proc_entry("sctp_dbg_objcount", proc_net_sctp);
+       remove_proc_entry("sctp_dbg_objcnt", proc_net_sctp);
 }


diff -Nru a/net/sctp/protocol.c b/net/sctp/protocol.c
--- a/net/sctp/protocol.c       Tue Apr  6 11:54:30 2004
+++ b/net/sctp/protocol.c       Tue Apr  6 11:54:30 2004
@@ -719,7 +719,7 @@
        if (msgname) {
                struct sctp_association *asoc;

-               asoc = event->sndrcvinfo.sinfo_assoc_id;
+               asoc = event->asoc;
                sctp_inet_msgname(msgname, addr_len);
                sin = (struct sockaddr_in *)msgname;
                sinfrom = &asoc->peer.primary_addr.v4;
diff -Nru a/net/sctp/socket.c b/net/sctp/socket.c
--- a/net/sctp/socket.c Tue Apr  6 11:54:30 2004
+++ b/net/sctp/socket.c Tue Apr  6 11:54:30 2004
@@ -1495,8 +1495,7 @@
                 * rwnd by that amount. If all the data in the skb is read,
                 * rwnd is updated when the event is freed.
                 */
-               sctp_assoc_rwnd_increase(event->sndrcvinfo.sinfo_assoc_id,
-                                        copied);
+               sctp_assoc_rwnd_increase(event->asoc, copied);
                goto out;
        } else if ((event->msg_flags & MSG_NOTIFICATION) ||
                   (event->msg_flags & MSG_EOR))
@@ -4486,7 +4485,7 @@
         */
        sctp_skb_for_each(skb, &oldsk->sk_receive_queue, tmp) {
                event = sctp_skb2event(skb);
-               if (event->sndrcvinfo.sinfo_assoc_id == assoc) {
+               if (event->asoc == assoc) {
                        __skb_unlink(skb, skb->list);
                        __skb_queue_tail(&newsk->sk_receive_queue, skb);
                }
@@ -4515,7 +4514,7 @@
                 */
                sctp_skb_for_each(skb, &oldsp->pd_lobby, tmp) {
                        event = sctp_skb2event(skb);
-                       if (event->sndrcvinfo.sinfo_assoc_id == assoc) {
+                       if (event->asoc == assoc) {
                                __skb_unlink(skb, skb->list);
                                __skb_queue_tail(queue, skb);
                        }
diff -Nru a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c
--- a/net/sctp/ulpevent.c       Tue Apr  6 11:54:30 2004
+++ b/net/sctp/ulpevent.c       Tue Apr  6 11:54:30 2004
@@ -1,7 +1,7 @@
 /* SCTP kernel reference Implementation
+ * (C) Copyright IBM Corp. 2001, 2004
  * Copyright (c) 1999-2000 Cisco, Inc.
  * Copyright (c) 1999-2001 Motorola, Inc.
- * Copyright (c) 2001 International Business Machines, Corp.
  * Copyright (c) 2001 Intel Corp.
  * Copyright (c) 2001 Nokia, Inc.
  * Copyright (c) 2001 La Monte H.P. Yarroll
@@ -590,8 +590,7 @@
                                                struct sctp_chunk *chunk,
                                                int gfp)
 {
-       struct sctp_ulpevent *event;
-       struct sctp_sndrcvinfo *info;
+       struct sctp_ulpevent *event = NULL;
        struct sk_buff *skb;
        size_t padding, len;

@@ -624,101 +623,21 @@
        /* Initialize event with flags 0.  */
        sctp_ulpevent_init(event, 0);

-       event->iif = sctp_chunk_iif(chunk);
-
        sctp_ulpevent_receive_data(event, asoc);

-       info = (struct sctp_sndrcvinfo *) &event->sndrcvinfo;
-
-       /* Sockets API Extensions for SCTP
-        * Section 5.2.2 SCTP Header Information Structure (SCTP_SNDRCV)
-        *
-        * sinfo_stream: 16 bits (unsigned integer)
-        *
-        * For recvmsg() the SCTP stack places the message's stream number in
-        * this value.
-        */
-       info->sinfo_stream = ntohs(chunk->subh.data_hdr->stream);
-
-       /* Sockets API Extensions for SCTP
-        * Section 5.2.2 SCTP Header Information Structure (SCTP_SNDRCV)
-        *
-        * sinfo_ssn: 16 bits (unsigned integer)
-        *
-        * For recvmsg() this value contains the stream sequence number that
-        * the remote endpoint placed in the DATA chunk.  For fragmented
-        * messages this is the same number for all deliveries of the message
-        * (if more than one recvmsg() is needed to read the message).
-        */
-       info->sinfo_ssn = ntohs(chunk->subh.data_hdr->ssn);
-
-        /* Sockets API Extensions for SCTP
-        * Section 5.2.2 SCTP Header Information Structure (SCTP_SNDRCV)
-        *
-        * sinfo_ppid: 32 bits (unsigned integer)
-        *
-        * In recvmsg() this value is
-        * the same information that was passed by the upper layer in the peer
-        * application.  Please note that byte order issues are NOT accounted
-        * for and this information is passed opaquely by the SCTP stack from
-        * one end to the other.
-        */
-       info->sinfo_ppid = chunk->subh.data_hdr->ppid;
-
-       /* Sockets API Extensions for SCTP
-        * Section 5.2.2 SCTP Header Information Structure (SCTP_SNDRCV)
-        *
-        * sinfo_flags: 16 bits (unsigned integer)
-        *
-        * This field may contain any of the following flags and is composed of
-        * a bitwise OR of these values.
-        *
-        * recvmsg() flags:
-        *
-        * MSG_UNORDERED - This flag is present when the message was sent
-        *                 non-ordered.
-        */
+       event->stream = ntohs(chunk->subh.data_hdr->stream);
+       event->ssn = ntohs(chunk->subh.data_hdr->ssn);
+       event->ppid = chunk->subh.data_hdr->ppid;
        if (chunk->chunk_hdr->flags & SCTP_DATA_UNORDERED) {
-               info->sinfo_flags |= MSG_UNORDERED;
-
-               /* sinfo_cumtsn: 32 bit (unsigned integer)
-                *
-                * This field will hold the current cumulative TSN as
-                * known by the underlying SCTP layer.  Note this field is
-                * ignored when sending and only valid for a receive
-                * operation when sinfo_flags are set to MSG_UNORDERED.
-                */
-               info->sinfo_cumtsn = sctp_tsnmap_get_ctsn(&asoc->peer.tsn_map);
+               event->flags |= MSG_UNORDERED;
+               event->cumtsn = sctp_tsnmap_get_ctsn(&asoc->peer.tsn_map);
        }
-
-       /* Note:  For reassembly, we need to have the fragmentation bits.
-        * For now, merge these into the msg_flags, since those bit
-        * possitions are not used.
-        */
+       event->tsn = ntohl(chunk->subh.data_hdr->tsn);
        event->msg_flags |= chunk->chunk_hdr->flags;
-
-       /* With 04 draft, tsn moves into sndrcvinfo. */
-       info->sinfo_tsn = ntohl(chunk->subh.data_hdr->tsn);
-
-       /* Context is not used on receive. */
-       info->sinfo_context = 0;
-
-       /* Sockets API Extensions for SCTP
-        * Section 5.2.2 SCTP Header Information Structure (SCTP_SNDRCV)
-        *
-        * sinfo_assoc_id: sizeof (sctp_assoc_t)
-        *
-        * The association handle field, sinfo_assoc_id, holds the identifier
-        * for the association announced in the COMMUNICATION_UP notification.
-        * All notifications for a given association have the same identifier.
-        * Ignored for TCP-style sockets.
-        */
-       info->sinfo_assoc_id = sctp_assoc2id(asoc);
-
-       return event;
+       event->iif = sctp_chunk_iif(chunk);

 fail:
-       return NULL;
+       return event;
 }

 /* Create a partial delivery related event.
@@ -797,11 +716,77 @@
 void sctp_ulpevent_read_sndrcvinfo(const struct sctp_ulpevent *event,
                                   struct msghdr *msghdr)
 {
-       if (!sctp_ulpevent_is_notification(event)) {
-               put_cmsg(msghdr, IPPROTO_SCTP, SCTP_SNDRCV,
-                        sizeof(struct sctp_sndrcvinfo),
-                        (void *) &event->sndrcvinfo);
-       }
+       struct sctp_sndrcvinfo sinfo;
+
+       if (sctp_ulpevent_is_notification(event))
+               return;
+
+       /* Sockets API Extensions for SCTP
+        * Section 5.2.2 SCTP Header Information Structure (SCTP_SNDRCV)
+        *
+        * sinfo_stream: 16 bits (unsigned integer)
+        *
+        * For recvmsg() the SCTP stack places the message's stream number in
+        * this value.
+       */
+       sinfo.sinfo_stream = event->stream;
+       /* sinfo_ssn: 16 bits (unsigned integer)
+        *
+        * For recvmsg() this value contains the stream sequence number that
+        * the remote endpoint placed in the DATA chunk.  For fragmented
+        * messages this is the same number for all deliveries of the message
+        * (if more than one recvmsg() is needed to read the message).
+        */
+       sinfo.sinfo_ssn = event->ssn;
+       /* sinfo_ppid: 32 bits (unsigned integer)
+        *
+        * In recvmsg() this value is
+        * the same information that was passed by the upper layer in the peer
+        * application.  Please note that byte order issues are NOT accounted
+        * for and this information is passed opaquely by the SCTP stack from
+        * one end to the other.
+        */
+       sinfo.sinfo_ppid = event->ppid;
+       /* sinfo_flags: 16 bits (unsigned integer)
+        *
+        * This field may contain any of the following flags and is composed of
+        * a bitwise OR of these values.
+        *
+        * recvmsg() flags:
+        *
+        * MSG_UNORDERED - This flag is present when the message was sent
+        *                 non-ordered.
+        */
+       sinfo.sinfo_flags = event->flags;
+       /* sinfo_tsn: 32 bit (unsigned integer)
+        *
+        * For the receiving side, this field holds a TSN that was
+        * assigned to one of the SCTP Data Chunks.
+        */
+       sinfo.sinfo_tsn = event->tsn;
+       /* sinfo_cumtsn: 32 bit (unsigned integer)
+        *
+        * This field will hold the current cumulative TSN as
+        * known by the underlying SCTP layer.  Note this field is
+        * ignored when sending and only valid for a receive
+        * operation when sinfo_flags are set to MSG_UNORDERED.
+        */
+       sinfo.sinfo_cumtsn = event->cumtsn;
+       /* sinfo_assoc_id: sizeof (sctp_assoc_t)
+        *
+        * The association handle field, sinfo_assoc_id, holds the identifier
+        * for the association announced in the COMMUNICATION_UP notification.
+        * All notifications for a given association have the same identifier.
+        * Ignored for one-to-one style sockets.
+        */
+       sinfo.sinfo_assoc_id = sctp_assoc2id(event->asoc);
+
+       /* These fields are not used while receiving. */
+       sinfo.sinfo_context = 0;
+       sinfo.sinfo_timetolive = 0;
+
+       put_cmsg(msghdr, IPPROTO_SCTP, SCTP_SNDRCV,
+                sizeof(struct sctp_sndrcvinfo), (void *)&sinfo);
 }

 /* Stub skb destructor.  */
@@ -831,14 +816,14 @@
        sctp_association_hold((struct sctp_association *)asoc);
        skb = sctp_event2skb(event);
        skb->sk = asoc->base.sk;
-       event->sndrcvinfo.sinfo_assoc_id = sctp_assoc2id(asoc);
+       event->asoc = (struct sctp_association *)asoc;
        skb->destructor = sctp_stub_rfree;
 }

 /* A simple destructor to give up the reference to the association. */
 static inline void sctp_ulpevent_release_owner(struct sctp_ulpevent *event)
 {
-       sctp_association_put(event->sndrcvinfo.sinfo_assoc_id);
+       sctp_association_put(event->asoc);
 }

 /* Do accounting for bytes received and hold a reference to the association
@@ -880,8 +865,7 @@
         */

        skb = sctp_event2skb(event);
-       sctp_assoc_rwnd_increase(event->sndrcvinfo.sinfo_assoc_id,
-                                skb_headlen(skb));
+       sctp_assoc_rwnd_increase(event->asoc, skb_headlen(skb));

        /* Don't forget the fragments. */
        for (frag = skb_shinfo(skb)->frag_list; frag; frag = frag->next) {
diff -Nru a/net/sctp/ulpqueue.c b/net/sctp/ulpqueue.c
--- a/net/sctp/ulpqueue.c       Tue Apr  6 11:54:30 2004
+++ b/net/sctp/ulpqueue.c       Tue Apr  6 11:54:30 2004
@@ -1,7 +1,7 @@
 /* SCTP kernel reference Implementation
+ * (C) Copyright IBM Corp. 2001, 2004
  * Copyright (c) 1999-2000 Cisco, Inc.
  * Copyright (c) 1999-2001 Motorola, Inc.
- * Copyright (c) 2001-2003 International Business Machines, Corp.
  * Copyright (c) 2001 Intel Corp.
  * Copyright (c) 2001 Nokia, Inc.
  * Copyright (c) 2001 La Monte H.P. Yarroll
@@ -251,7 +251,7 @@
        struct sctp_ulpevent *cevent;
        __u32 tsn, ctsn;

-       tsn = event->sndrcvinfo.sinfo_tsn;
+       tsn = event->tsn;

        /* See if it belongs at the end. */
        pos = skb_peek_tail(&ulpq->reasm);
@@ -262,7 +262,7 @@

        /* Short circuit just dropping it at the end. */
        cevent = sctp_skb2event(pos);
-       ctsn = cevent->sndrcvinfo.sinfo_tsn;
+       ctsn = cevent->tsn;
        if (TSN_lt(ctsn, tsn)) {
                __skb_queue_tail(&ulpq->reasm, sctp_event2skb(event));
                return;
@@ -271,7 +271,7 @@
        /* Find the right place in this list. We store them by TSN.  */
        skb_queue_walk(&ulpq->reasm, pos) {
                cevent = sctp_skb2event(pos);
-               ctsn = cevent->sndrcvinfo.sinfo_tsn;
+               ctsn = cevent->tsn;

                if (TSN_lt(tsn, ctsn))
                        break;
@@ -368,7 +368,7 @@
         */
        skb_queue_walk(&ulpq->reasm, pos) {
                cevent = sctp_skb2event(pos);
-               ctsn = cevent->sndrcvinfo.sinfo_tsn;
+               ctsn = cevent->tsn;

                switch (cevent->msg_flags & SCTP_DATA_FRAG_MASK) {
                case SCTP_DATA_FIRST_FRAG:
@@ -425,7 +425,7 @@

        skb_queue_walk(&ulpq->reasm, pos) {
                cevent = sctp_skb2event(pos);
-               ctsn = cevent->sndrcvinfo.sinfo_tsn;
+               ctsn = cevent->tsn;

                switch (cevent->msg_flags & SCTP_DATA_FRAG_MASK) {
                case SCTP_DATA_MIDDLE_FRAG:
@@ -486,7 +486,7 @@
                /* Do not even bother unless this is the next tsn to
                 * be delivered.
                 */
-               ctsn = event->sndrcvinfo.sinfo_tsn;
+               ctsn = event->tsn;
                ctsnap = sctp_tsnmap_get_ctsn(&ulpq->asoc->peer.tsn_map);
                if (TSN_lte(ctsn, ctsnap))
                        retval = sctp_ulpq_retrieve_partial(ulpq);
@@ -517,7 +517,7 @@

        skb_queue_walk(&ulpq->reasm, pos) {
                cevent = sctp_skb2event(pos);
-               ctsn = cevent->sndrcvinfo.sinfo_tsn;
+               ctsn = cevent->tsn;

                switch (cevent->msg_flags & SCTP_DATA_FRAG_MASK) {
                case SCTP_DATA_FIRST_FRAG:
@@ -563,15 +563,15 @@
        __u16 sid, csid;
        __u16 ssn, cssn;

-       sid = event->sndrcvinfo.sinfo_stream;
-       ssn = event->sndrcvinfo.sinfo_ssn;
+       sid = event->stream;
+       ssn = event->ssn;
        in  = &ulpq->asoc->ssnmap->in;

        /* We are holding the chunks by stream, by SSN.  */
        sctp_skb_for_each(pos, &ulpq->lobby, tmp) {
                cevent = (struct sctp_ulpevent *) pos->cb;
-               csid = cevent->sndrcvinfo.sinfo_stream;
-               cssn = cevent->sndrcvinfo.sinfo_ssn;
+               csid = cevent->stream;
+               cssn = cevent->ssn;

                /* Have we gone too far?  */
                if (csid > sid)
@@ -609,12 +609,12 @@
                return;
        }

-       sid = event->sndrcvinfo.sinfo_stream;
-       ssn = event->sndrcvinfo.sinfo_ssn;
+       sid = event->stream;
+       ssn = event->ssn;

        cevent = (struct sctp_ulpevent *) pos->cb;
-       csid = cevent->sndrcvinfo.sinfo_stream;
-       cssn = cevent->sndrcvinfo.sinfo_ssn;
+       csid = cevent->stream;
+       cssn = cevent->ssn;
        if (sid > csid) {
                __skb_queue_tail(&ulpq->lobby, sctp_event2skb(event));
                return;
@@ -630,8 +630,8 @@
         */
        skb_queue_walk(&ulpq->lobby, pos) {
                cevent = (struct sctp_ulpevent *) pos->cb;
-               csid = cevent->sndrcvinfo.sinfo_stream;
-               cssn = cevent->sndrcvinfo.sinfo_ssn;
+               csid = cevent->stream;
+               cssn = cevent->ssn;

                if (csid > sid)
                        break;
@@ -656,8 +656,8 @@
                return event;

        /* Note: The stream ID must be verified before this routine.  */
-       sid = event->sndrcvinfo.sinfo_stream;
-       ssn = event->sndrcvinfo.sinfo_ssn;
+       sid = event->stream;
+       ssn = event->ssn;
        in  = &ulpq->asoc->ssnmap->in;

        /* Is this the expected SSN for this stream ID?  */
@@ -694,7 +694,7 @@
        while ((skb = __skb_dequeue_tail(&ulpq->lobby))) {
                freed += skb_headlen(skb);
                event = sctp_skb2event(skb);
-               tsn = event->sndrcvinfo.sinfo_tsn;
+               tsn = event->tsn;

                sctp_ulpevent_free(event);
                sctp_tsnmap_renege(tsnmap, tsn);
@@ -720,7 +720,7 @@
        while ((skb = __skb_dequeue_tail(&ulpq->reasm))) {
                freed += skb_headlen(skb);
                event = sctp_skb2event(skb);
-               tsn = event->sndrcvinfo.sinfo_tsn;
+               tsn = event->tsn;

                sctp_ulpevent_free(event);
                sctp_tsnmap_renege(tsnmap, tsn);

<Prev in Thread] Current Thread [Next in Thread>