* [BK PATCH] 2.6 SCTP updates.
@ 2003-10-02 23:46 Sridhar Samudrala
2003-10-03 9:48 ` David S. Miller
0 siblings, 1 reply; 11+ messages in thread
From: Sridhar Samudrala @ 2003-10-02 23:46 UTC (permalink / raw)
To: davem; +Cc: netdev
Hi Dave,
Please do a
bk pull http://linux-lksctp.bkbits.net/lksctp-2.5
to get the following udpates to SCTP on top of linux 2.6.0-test6
The changesets include fixes for a couple of arch specific issues with ppc64
and parisc64, few ADDIP extension related patches and a bug fix.
# This patch includes the following deltas:
# ChangeSet 1.1375 -> 1.1377
# net/sctp/associola.c 1.59 -> 1.61
# net/sctp/sm_statefuns.c 1.63 -> 1.64
# net/sctp/endpointola.c 1.28 -> 1.29
# net/sctp/sm_make_chunk.c 1.61 -> 1.64
# include/net/sctp/sctp.h 1.50 -> 1.52
# net/sctp/sysctl.c 1.13 -> 1.14
# include/net/sctp/sm.h 1.29 -> 1.31
# include/linux/sctp.h 1.8 -> 1.9
# net/sctp/sm_sideeffect.c 1.48 -> 1.49
# net/sctp/bind_addr.c 1.21 -> 1.22
# include/net/sctp/command.h 1.14 -> 1.15
# include/net/sctp/structs.h 1.73 -> 1.75
# net/sctp/socket.c 1.96 -> 1.99
#
# The following is the BitKeeper ChangeSet Log
#
#ChangeSet@1.1377, 2003-10-02 11:36:34-07:00, sri@us.ibm.com
# [SCTP] Fix bugs in conversions between msecs and jiffies.
#
#ChangeSet@1.1376, 2003-09-29 12:04:57-07:00, sri@us.ibm.com
# Merge us.ibm.com:/home/sridhar/BK/linux-2.6.0-test6
# into us.ibm.com:/home/sridhar/BK/lksctp-2.6.0-test6
#
#ChangeSet@1.1217.15.5, 2003-09-29 10:23:40-07:00, sri@us.ibm.com
# [SCTP] Convert tv_add from static inline to a macro to fix an obscure
# assembler problem with parisc64.
#
#ChangeSet@1.1217.15.4, 2003-09-22 14:29:35-07:00, sri@us.ibm.com
# [SCTP] ADDIP: Support for the creation of ASCONF_ACK chunk (Kevin).
#
#ChangeSet@1.1217.15.3, 2003-09-18 14:44:14-07:00, sri@us.ibm.com
# [SCTP] ADDIP: Handle ERROR chunk in response to an ASCONF chunk.
#
# Disable sending any further ASCONF chunks and stop its T-4 timer if
# the peer responds to an ASCONF with an ERROR chunk.
#
#ChangeSet@1.1217.15.2, 2003-09-18 14:39:59-07:00, sri@us.ibm.com
# [SCTP] ADDIP: Support to send ASCONF chunk with ADD/DEL IP params.
#
#ChangeSet@1.1217.15.1, 2003-09-09 11:03:31-07:00, sri@us.ibm.com
# [SCTP] PPC64 port: Don't overload the optval arg of ADDRS_NUM socket
# options with different types for input and output. Instead use it only
# as an input arg and return the no. of addresses in the return value.
Thanks
Sridhar
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [BK PATCH] 2.6 SCTP updates.
2003-10-02 23:46 [BK PATCH] 2.6 SCTP updates Sridhar Samudrala
@ 2003-10-03 9:48 ` David S. Miller
0 siblings, 0 replies; 11+ messages in thread
From: David S. Miller @ 2003-10-03 9:48 UTC (permalink / raw)
To: Sridhar Samudrala; +Cc: netdev
On Thu, 2 Oct 2003 16:46:06 -0700 (PDT)
Sridhar Samudrala <sri@us.ibm.com> wrote:
> Please do a
> bk pull http://linux-lksctp.bkbits.net/lksctp-2.5
> to get the following udpates to SCTP on top of linux 2.6.0-test6
>
> The changesets include fixes for a couple of arch specific issues with ppc64
> and parisc64, few ADDIP extension related patches and a bug fix.
Pulled, thanks a lot Sridhar.
^ permalink raw reply [flat|nested] 11+ messages in thread
* [BK PATCH] 2.6 SCTP updates
@ 2004-02-14 0:07 Sridhar Samudrala
2004-02-14 5:52 ` David S. Miller
0 siblings, 1 reply; 11+ messages in thread
From: Sridhar Samudrala @ 2004-02-14 0:07 UTC (permalink / raw)
To: davem; +Cc: netdev, lksctp-developers
Hi Dave,
Please do a
bk pull http://linux-lksctp.bkbits.net/lksctp-2.5.work
to get the following fixes to SCTP on top of linux 2.6.2.
# This patch includes the following deltas:
# ChangeSet 1.1551 -> 1.1554
# net/sctp/ssnmap.c 1.2 -> 1.3
# net/sctp/socket.c 1.105 -> 1.107
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 04/02/12 sri@us.ibm.com 1.1552
# [SCTP] Use __get_free_pages() to allocate ssnmap.
#
# This is needed to avoid kmalloc()'s 128K limit when an association is
# initialized with a large no. of streams(more than 65000 inbound +
# outbound streams).
# --------------------------------------------
# 04/02/12 sri@us.ibm.com 1.1553
# [SCTP] Fix SCTP_INITMSG set socket option so that a parameter with 0
# value will not change its current value.
# --------------------------------------------
# 04/02/13 sri@us.ibm.com 1.1554
# [SCTP] Fix sctp_getladdrs()/sctp_getpaddrs() API so that the port
# value in the returned addresses is in network byte order.
# --------------------------------------------
Thanks
Sridhar
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [BK PATCH] 2.6 SCTP updates
2004-02-14 0:07 Sridhar Samudrala
@ 2004-02-14 5:52 ` David S. Miller
2004-02-16 5:55 ` Sridhar Samudrala
0 siblings, 1 reply; 11+ messages in thread
From: David S. Miller @ 2004-02-14 5:52 UTC (permalink / raw)
To: Sridhar Samudrala; +Cc: netdev, lksctp-developers
On Fri, 13 Feb 2004 16:07:05 -0800 (PST)
Sridhar Samudrala <sri@us.ibm.com> wrote:
> Please do a
> bk pull http://linux-lksctp.bkbits.net/lksctp-2.5.work
> to get the following fixes to SCTP on top of linux 2.6.2.
I am pulling this, however I strongly disagree with this change:
> # 04/02/12 sri@us.ibm.com 1.1552
> # [SCTP] Use __get_free_pages() to allocate ssnmap.
> #
> # This is needed to avoid kmalloc()'s 128K limit when an association is
> # initialized with a large no. of streams(more than 65000 inbound +
> # outbound streams).
This is madness because it means that every assosciation created eats
at least PAGE_SIZE bytes of memory, even if the ssnmap is tiny.
Maybe you should just brance between two allocation schemes based upon
what sctp_ssnmap_size() returns.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [BK PATCH] 2.6 SCTP updates
2004-02-14 5:52 ` David S. Miller
@ 2004-02-16 5:55 ` Sridhar Samudrala
0 siblings, 0 replies; 11+ messages in thread
From: Sridhar Samudrala @ 2004-02-16 5:55 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, lksctp-developers
On Fri, 13 Feb 2004, David S. Miller wrote:
> On Fri, 13 Feb 2004 16:07:05 -0800 (PST)
> Sridhar Samudrala <sri@us.ibm.com> wrote:
>
> > Please do a
> > bk pull http://linux-lksctp.bkbits.net/lksctp-2.5.work
> > to get the following fixes to SCTP on top of linux 2.6.2.
>
> I am pulling this, however I strongly disagree with this change:
>
> > # 04/02/12 sri@us.ibm.com 1.1552
> > # [SCTP] Use __get_free_pages() to allocate ssnmap.
> > #
> > # This is needed to avoid kmalloc()'s 128K limit when an association is
> > # initialized with a large no. of streams(more than 65000 inbound +
> > # outbound streams).
>
> This is madness because it means that every assosciation created eats
> at least PAGE_SIZE bytes of memory, even if the ssnmap is tiny.
>
> Maybe you should just brance between two allocation schemes based upon
> what sctp_ssnmap_size() returns.
Yes, I didn't realize that this will waste lots of memory for associations
with a few streams. Here is a patch that fixes it by reverting back to
kmalloc() for allocs < 128K.
I have pushed it to both 2.6 and 2.4 bk trees. You can pull them from
http://linux-lksctp.bkbits.net/lksctp-2.5.work
http://linux-lksctp.bkbits.net/lksctp-2.4.work
# This patch includes the following deltas:
# ChangeSet 1.1554 -> 1.1555
# net/sctp/ssnmap.c 1.3 -> 1.4
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 04/02/15 sri@us.ibm.com 1.1555
# [SCTP] Revert back to use kmalloc() for ssnmap allocs of sizes < 128K.
# --------------------------------------------
#
diff -Nru a/net/sctp/ssnmap.c b/net/sctp/ssnmap.c
--- a/net/sctp/ssnmap.c Sun Feb 15 21:34:49 2004
+++ b/net/sctp/ssnmap.c Sun Feb 15 21:34:49 2004
@@ -40,6 +40,7 @@
#include <net/sctp/sctp.h>
#include <net/sctp/sm.h>
+#define MAX_KMALLOC_SIZE 131072
/* Storage size needed for map includes 2 headers and then the
* specific needs of in or out streams.
@@ -56,11 +57,14 @@
struct sctp_ssnmap *sctp_ssnmap_new(__u16 in, __u16 out, int gfp)
{
struct sctp_ssnmap *retval;
- int order;
-
- order = get_order(sctp_ssnmap_size(in,out));
- retval = (struct sctp_ssnmap *)__get_free_pages(gfp, order);
+ int size;
+ size = sctp_ssnmap_size(in, out);
+ if (size <= MAX_KMALLOC_SIZE)
+ retval = kmalloc(size, gfp);
+ else
+ retval = (struct sctp_ssnmap *)
+ __get_free_pages(gfp, get_order(size));
if (!retval)
goto fail;
@@ -73,7 +77,10 @@
return retval;
fail_map:
- free_pages((unsigned long)retval, order);
+ if (size <= MAX_KMALLOC_SIZE)
+ kfree(retval);
+ else
+ free_pages((unsigned long)retval, get_order(size));
fail:
return NULL;
}
@@ -109,9 +116,13 @@
void sctp_ssnmap_free(struct sctp_ssnmap *map)
{
if (map && map->malloced) {
- free_pages((unsigned long)map,
- get_order(sctp_ssnmap_size(map->in.len,
- map->out.len)));
+ int size;
+
+ size = sctp_ssnmap_size(map->in.len, map->out.len);
+ if (size <= MAX_KMALLOC_SIZE)
+ kfree(map);
+ else
+ free_pages((unsigned long)map, get_order(size));
SCTP_DBG_OBJCNT_DEC(ssnmap);
}
}
Thanks
Sridhar
^ permalink raw reply [flat|nested] 11+ messages in thread
* [BK PATCH] 2.6 SCTP updates.
@ 2004-03-23 20:13 Sridhar Samudrala
2004-03-24 20:01 ` David S. Miller
0 siblings, 1 reply; 11+ messages in thread
From: Sridhar Samudrala @ 2004-03-23 20:13 UTC (permalink / raw)
To: davem; +Cc: netdev
Hi Dave,
please do a
bk pull http://linux-lksctp.bkbits.net/lksctp-2.5.work
to get the following updates to SCTP on top of linux 2.6.5-rc2.
# This patch includes the following deltas:
# ChangeSet 1.1817 -> 1.1819
# net/sctp/sm_make_chunk.c 1.66 -> 1.67
# net/sctp/ulpevent.c 1.23 -> 1.24
# net/sctp/Kconfig 1.11 -> 1.12
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 04/03/23 sri@us.ibm.com 1.1818
# [SCTP] Don't do any ppid byte-order conversions as it is opaque to SCTP.
# --------------------------------------------
# 04/03/23 sri@us.ibm.com 1.1819
# [SCTP] Avoid the use of hackish CONFIG_IPV6_SCTP__ option.
# --------------------------------------------
#
diff -Nru a/net/sctp/Kconfig b/net/sctp/Kconfig
--- a/net/sctp/Kconfig Tue Mar 23 11:54:23 2004
+++ b/net/sctp/Kconfig Tue Mar 23 11:54:23 2004
@@ -5,14 +5,9 @@
menu "SCTP Configuration (EXPERIMENTAL)"
depends on INET && EXPERIMENTAL
-config IPV6_SCTP__
- tristate
- default y if IPV6=n
- default IPV6 if IPV6
-
config IP_SCTP
tristate "The SCTP Protocol (EXPERIMENTAL)"
- depends on IPV6_SCTP__
+ depends on IPV6 || IPV6=n
---help---
Stream Control Transmission Protocol
@@ -61,6 +56,7 @@
choice
prompt "SCTP: Cookie HMAC Algorithm"
depends on IP_SCTP
+ default SCTP_HMAC_MD5
help
HMAC algorithm to be used during association initialization. It
is strongly recommended to use HMAC-SHA1 or HMAC-MD5. See
diff -Nru a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
--- a/net/sctp/sm_make_chunk.c Tue Mar 23 11:54:23 2004
+++ b/net/sctp/sm_make_chunk.c Tue Mar 23 11:54:23 2004
@@ -516,7 +516,7 @@
*/
dp.tsn = 0;
dp.stream = htons(sinfo->sinfo_stream);
- dp.ppid = htonl(sinfo->sinfo_ppid);
+ dp.ppid = sinfo->sinfo_ppid;
/* Set the flags for an unordered send. */
if (sinfo->sinfo_flags & MSG_UNORDERED) {
diff -Nru a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c
--- a/net/sctp/ulpevent.c Tue Mar 23 11:54:23 2004
+++ b/net/sctp/ulpevent.c Tue Mar 23 11:54:23 2004
@@ -663,7 +663,7 @@
* for and this information is passed opaquely by the SCTP stack from
* one end to the other.
*/
- info->sinfo_ppid = ntohl(chunk->subh.data_hdr->ppid);
+ info->sinfo_ppid = chunk->subh.data_hdr->ppid;
/* Sockets API Extensions for SCTP
* Section 5.2.2 SCTP Header Information Structure (SCTP_SNDRCV)
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [BK PATCH] 2.6 SCTP updates.
2004-03-23 20:13 Sridhar Samudrala
@ 2004-03-24 20:01 ` David S. Miller
0 siblings, 0 replies; 11+ messages in thread
From: David S. Miller @ 2004-03-24 20:01 UTC (permalink / raw)
To: Sridhar Samudrala; +Cc: netdev
On Tue, 23 Mar 2004 12:13:56 -0800 (PST)
Sridhar Samudrala <sri@us.ibm.com> wrote:
> please do a
> bk pull http://linux-lksctp.bkbits.net/lksctp-2.5.work
> to get the following updates to SCTP on top of linux 2.6.5-rc2.
Pulled, thanks.
^ permalink raw reply [flat|nested] 11+ messages in thread
* [BK PATCH] 2.6 SCTP updates.
@ 2004-04-06 17:28 Sridhar Samudrala
0 siblings, 0 replies; 11+ messages in thread
From: Sridhar Samudrala @ 2004-04-06 17:28 UTC (permalink / raw)
To: davem; +Cc: netdev, lksctp-developers
Hi Dave,
Please do a
bk pull http://linux-lksctp.bkbits.net/lksctp-2.5.work
to get the following updates to SCTP on top of linux 2.6.5
Thanks
Sridhar
# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
# 2004/04/06 07:32:30-07:00 sri@us.ibm.com
# [SCTP] Use id to ptr translation service in lib/idr.c to assign and
# validate ids of associations.
#
# This patch avoids the use of virt_addr_valid() to validate the address
# of associations passed by the user. Currently the address of an
# association is used as its id. virt_addr_valid doesn't work as
# expected when PAGEALLOC debugging is enabled.
#
# net/sctp/socket.c
# net/sctp/sm_make_chunk.c
# net/sctp/protocol.c
# net/sctp/associola.c
# include/net/sctp/structs.h
# include/net/sctp/sctp.h
# ChangeSet
# 2004/04/06 07:24:04-07:00 sri@us.ibm.com
# [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 00:28:31-07:00 sri@us.ibm.com
# [SCTP] Fix typo in entry name of the remove_proc_entry() call.
#
# net/sctp/objcnt.c
#
diff -Nru a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
--- a/include/net/sctp/sctp.h Tue Apr 6 07:35:28 2004
+++ b/include/net/sctp/sctp.h Tue Apr 6 07:35:28 2004
@@ -1,5 +1,5 @@
/* SCTP kernel reference Implementation
- * (C) Copyright IBM Corp. 2001, 2003
+ * (C) Copyright IBM Corp. 2001, 2004
* Copyright (c) 1999-2000 Cisco, Inc.
* Copyright (c) 1999-2001 Motorola, Inc.
* Copyright (c) 2001-2003 Intel Corp.
@@ -78,6 +78,7 @@
#include <linux/proc_fs.h>
#include <linux/spinlock.h>
#include <linux/jiffies.h>
+#include <linux/idr.h>
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
#include <net/ipv6.h>
@@ -223,24 +224,6 @@
#define SCTP_INC_STATS_USER(field) SNMP_INC_STATS_USER(sctp_statistics, field)
#define SCTP_DEC_STATS(field) SNMP_DEC_STATS(sctp_statistics, field)
-/* Determine if this is a valid kernel address. */
-static inline int sctp_is_valid_kaddr(unsigned long addr)
-{
- struct page *page;
-
- /* Make sure the address is not in the user address space. */
- if (addr < PAGE_OFFSET)
- return 0;
-
- page = virt_to_page(addr);
-
- /* Is this page valid? */
- if (!virt_addr_valid(addr) || PageReserved(page))
- return 0;
-
- return 1;
-}
-
#endif /* !TEST_FRAME */
@@ -357,7 +340,7 @@
/* Map an association to an assoc_id. */
static inline sctp_assoc_t sctp_assoc2id(const struct sctp_association *asoc)
{
- return (sctp_assoc_t) asoc;
+ return (asoc?asoc->assoc_id:NULL);
}
/* Look up the association by its id. */
@@ -518,6 +501,9 @@
extern struct proto sctp_prot;
extern struct proc_dir_entry *proc_net_sctp;
void sctp_put_port(struct sock *sk);
+
+extern struct idr sctp_assocs_id;
+extern spinlock_t sctp_assocs_id_lock;
/* Static inline functions. */
diff -Nru a/include/net/sctp/structs.h b/include/net/sctp/structs.h
--- a/include/net/sctp/structs.h Tue Apr 6 07:35:28 2004
+++ b/include/net/sctp/structs.h Tue Apr 6 07:35:28 2004
@@ -1,5 +1,5 @@
/* SCTP kernel reference Implementation
- * (C) Copyright IBM Corp. 2001, 2003
+ * (C) Copyright IBM Corp. 2001, 2004
* Copyright (c) 1999-2000 Cisco, Inc.
* Copyright (c) 1999-2001 Motorola, Inc.
* Copyright (c) 2001 Intel Corp.
@@ -1282,11 +1282,8 @@
/* Associations on the same socket. */
struct list_head asocs;
- /* This is a signature that lets us know that this is a
- * struct sctp_association data structure. Used for mapping an
- * association id to an association.
- */
- __u32 eyecatcher;
+ /* association id. */
+ sctp_assoc_t assoc_id;
/* This is our parent endpoint. */
struct sctp_endpoint *ep;
diff -Nru a/include/net/sctp/ulpevent.h b/include/net/sctp/ulpevent.h
--- a/include/net/sctp/ulpevent.h Tue Apr 6 07:35:27 2004
+++ b/include/net/sctp/ulpevent.h Tue Apr 6 07:35:27 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/associola.c b/net/sctp/associola.c
--- a/net/sctp/associola.c Tue Apr 6 07:35:27 2004
+++ b/net/sctp/associola.c Tue Apr 6 07:35:27 2004
@@ -1,5 +1,5 @@
/* SCTP kernel reference Implementation
- * (C) Copyright IBM Corp. 2001, 2003
+ * (C) Copyright IBM Corp. 2001, 2004
* Copyright (c) 1999-2000 Cisco, Inc.
* Copyright (c) 1999-2001 Motorola, Inc.
* Copyright (c) 2001 Intel Corp.
@@ -276,7 +276,7 @@
asoc->need_ecne = 0;
- asoc->eyecatcher = SCTP_ASSOC_EYECATCHER;
+ asoc->assoc_id = (sctp_assoc_t)-1;
/* Assume that peer would support both address types unless we are
* told otherwise.
@@ -360,8 +360,6 @@
sctp_transport_free(transport);
}
- asoc->eyecatcher = 0;
-
/* Free any cached ASCONF_ACK chunk. */
if (asoc->addip_last_asconf_ack)
sctp_chunk_free(asoc->addip_last_asconf_ack);
@@ -381,6 +379,12 @@
sctp_endpoint_put(asoc->ep);
sock_put(asoc->base.sk);
+ if ((int)asoc->assoc_id != -1) {
+ spin_lock_bh(&sctp_assocs_id_lock);
+ idr_remove(&sctp_assocs_id, (int)asoc->assoc_id);
+ spin_unlock_bh(&sctp_assocs_id_lock);
+ }
+
if (asoc->base.malloced) {
kfree(asoc);
SCTP_DBG_OBJCNT_DEC(assoc);
@@ -856,26 +860,6 @@
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(). */
static void sctp_assoc_bh_rcv(struct sctp_association *asoc)
{
@@ -891,6 +875,7 @@
sk = asoc->base.sk;
inqueue = &asoc->base.inqueue;
+ sctp_association_hold(asoc);
while (NULL != (chunk = sctp_inq_pop(inqueue))) {
state = asoc->state;
subtype = chunk->chunk_hdr->type;
@@ -913,14 +898,14 @@
/* Check to see if the association is freed in response to
* the incoming chunk. If so, get out of the while loop.
*/
- if (!sctp_assoc_valid(sk, asoc))
+ if (asoc->base.dead)
break;
/* If there is an error on chunk, discard this packet. */
if (error && chunk)
chunk->pdiscard = 1;
}
-
+ sctp_association_put(asoc);
}
/* This routine moves an association from its old sk to a new sk. */
diff -Nru a/net/sctp/ipv6.c b/net/sctp/ipv6.c
--- a/net/sctp/ipv6.c Tue Apr 6 07:35:28 2004
+++ b/net/sctp/ipv6.c Tue Apr 6 07:35:28 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
@@ -698,7 +698,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 07:35:27 2004
+++ b/net/sctp/objcnt.c Tue Apr 6 07:35:27 2004
@@ -1,5 +1,5 @@
/* SCTP kernel reference Implementation
- * Copyright (c) 2001 International Business Machines Corp.
+ * (C) Copyright IBM Corp. 2001, 2004
*
* This file is part of the SCTP kernel reference Implementation
*
@@ -134,7 +134,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 07:35:28 2004
+++ b/net/sctp/protocol.c Tue Apr 6 07:35:28 2004
@@ -64,6 +64,9 @@
struct proc_dir_entry *proc_net_sctp;
DEFINE_SNMP_STAT(struct sctp_mib, sctp_statistics);
+struct idr sctp_assocs_id;
+spinlock_t sctp_assocs_id_lock = SPIN_LOCK_UNLOCKED;
+
/* This is the global socket data structure used for responding to
* the Out-of-the-blue (OOTB) packets. A control sock will be created
* for this socket at the initialization time.
@@ -721,7 +724,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;
@@ -1048,6 +1051,9 @@
/* Initialize default stream count setup information. */
sctp_max_instreams = SCTP_DEFAULT_INSTREAMS;
sctp_max_outstreams = SCTP_DEFAULT_OUTSTREAMS;
+
+ /* Initialize handle used for association ids. */
+ idr_init(&sctp_assocs_id);
/* Size and allocate the association hash table.
* The methodology is similar to that of the tcp hash tables.
diff -Nru a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
--- a/net/sctp/sm_make_chunk.c Tue Apr 6 07:35:28 2004
+++ b/net/sctp/sm_make_chunk.c Tue Apr 6 07:35:28 2004
@@ -1,5 +1,5 @@
/* SCTP kernel reference Implementation
- * (C) Copyright IBM Corp. 2001, 2003
+ * (C) Copyright IBM Corp. 2001, 2004
* Copyright (c) 1999-2000 Cisco, Inc.
* Copyright (c) 1999-2001 Motorola, Inc.
* Copyright (c) 2001-2002 Intel Corp.
@@ -1817,10 +1817,23 @@
/* Allocate storage for the negotiated streams if it is not a temporary * association.
*/
if (!asoc->temp) {
+ sctp_assoc_t assoc_id;
+
asoc->ssnmap = sctp_ssnmap_new(asoc->c.sinit_max_instreams,
asoc->c.sinit_num_ostreams, gfp);
if (!asoc->ssnmap)
- goto nomem_ssnmap;
+ goto clean_up;
+
+ do {
+ if (unlikely(!idr_pre_get(&sctp_assocs_id, gfp)))
+ goto clean_up;
+ spin_lock_bh(&sctp_assocs_id_lock);
+ assoc_id = (sctp_assoc_t)idr_get_new(&sctp_assocs_id,
+ (void *)asoc);
+ spin_unlock_bh(&sctp_assocs_id_lock);
+ } while (unlikely((int)assoc_id == -1));
+
+ asoc->assoc_id = assoc_id;
}
/* ADDIP Section 4.1 ASCONF Chunk Procedures
@@ -1836,7 +1849,6 @@
asoc->peer.addip_serial = asoc->peer.i.initial_tsn - 1;
return 1;
-nomem_ssnmap:
clean_up:
/* Release the transport structures. */
list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) {
diff -Nru a/net/sctp/socket.c b/net/sctp/socket.c
--- a/net/sctp/socket.c Tue Apr 6 07:35:28 2004
+++ b/net/sctp/socket.c Tue Apr 6 07:35:28 2004
@@ -135,8 +135,14 @@
}
/* Otherwise this is a UDP-style socket. */
- asoc = (struct sctp_association *)id;
- if (!sctp_assoc_valid(sk, asoc))
+ if (!id || (id == (sctp_assoc_t)-1))
+ return NULL;
+
+ spin_lock_bh(&sctp_assocs_id_lock);
+ asoc = (struct sctp_association *)idr_find(&sctp_assocs_id, (int)id);
+ spin_unlock_bh(&sctp_assocs_id_lock);
+
+ if (!asoc || (asoc->base.sk != sk) || asoc->base.dead)
return NULL;
return asoc;
@@ -1498,8 +1504,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))
@@ -4477,7 +4482,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);
}
@@ -4506,7 +4511,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 07:35:28 2004
+++ b/net/sctp/ulpevent.c Tue Apr 6 07:35:28 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 07:35:28 2004
+++ b/net/sctp/ulpqueue.c Tue Apr 6 07:35:28 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);
^ permalink raw reply [flat|nested] 11+ messages in thread
* [BK PATCH] 2.6 SCTP updates
@ 2004-07-24 0:18 Sridhar Samudrala
2004-07-25 5:27 ` David S. Miller
0 siblings, 1 reply; 11+ messages in thread
From: Sridhar Samudrala @ 2004-07-24 0:18 UTC (permalink / raw)
To: davem; +Cc: netdev, lksctp-developers
Dave,
Please do a
bk pull http://linux-lksctp.bkbits.net/lksctp-2.5.work
to get the following SCTP updates to 2.6.8-rc2.
Thanks
Sridhar
# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
# 2004/07/23 16:41:31-07:00 sri@us.ibm.com
# [SCTP] Mark chunks as ineligible for fast retransmit after they are
# retransmitted. Also mark any chunks that could not be fit in the
# PMTU sized packet as ineligible for fast retransmit.
#
# Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>
#
# net/sctp/outqueue.c
#
# ChangeSet
# 2004/07/22 23:22:01-07:00 sri@us.ibm.com
# [SCTP] Fix missing '+' in the computation of sack chunk size in
# sctp_sm_pull_sack().
#
# Signed-off-by: Jorge Hernandez <jhh@lucent.com>
# Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>
#
# net/sctp/sm_statefuns.c
#
# ChangeSet
# 2004/07/22 23:18:24-07:00 sri@us.ibm.com
# [SCTP] Use idr_get_new_above() with a starting id of 1 to avoid returning
# an associd of 0.
#
# Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>
#
# net/sctp/sm_make_chunk.c
#
# ChangeSet
# 2004/07/22 23:15:55-07:00 sri@us.ibm.com
# [SCTP] Fix issues with handling stale cookie error over multihoming
# associations.
#
# Signed-off-by: Jorge Hernandez <jhh@lucent.com>
# Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>
#
# net/sctp/sm_statefuns.c
# net/sctp/sm_sideeffect.c
# include/net/sctp/command.h
#
# ChangeSet
# 2004/07/22 23:13:05-07:00 sri@us.ibm.com
# [SCTP] Fix data not being delivered to user in SHUTDOWN_SENT state.
#
# Also cleaned up sctp_sf_eat_data_6_2() and sctp_sf_eat_data_fast_4_4()
# as they have a lot of common code.
#
# Signed-off-by: Jorge Hernandez <jhh@lucent.com>
# Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>
#
# net/sctp/sm_statefuns.c
# net/sctp/associola.c
# include/net/sctp/sm.h
# include/net/sctp/constants.h
#
# ChangeSet
# 2004/07/22 23:09:04-07:00 sri@us.ibm.com
# [SCTP] Set/Get default SCTP_PEER_ADDR_PARAMS for endpoint when associd
# and peer address are 0.
#
# Signed-off-by: Anand R. Setlur <asetlur@lucent.com>
# Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>
#
# net/sctp/socket.c
#
diff -Nru a/include/net/sctp/command.h b/include/net/sctp/command.h
--- a/include/net/sctp/command.h 2004-07-23 17:08:07 -07:00
+++ b/include/net/sctp/command.h 2004-07-23 17:08:07 -07:00
@@ -94,6 +94,9 @@
SCTP_CMD_REPORT_FWDTSN, /* Report new cumulative TSN Ack. */
SCTP_CMD_PROCESS_FWDTSN, /* Skips were reported, so process further. */
SCTP_CMD_CLEAR_INIT_TAG, /* Clears association peer's inittag. */
+ SCTP_CMD_DEL_NON_PRIMARY, /* Removes non-primary peer transports. */
+ SCTP_CMD_T3_RTX_TIMERS_STOP, /* Stops T3-rtx pending timers */
+ SCTP_CMD_FORCE_PRIM_RETRAN, /* Forces retrans. over primary path. */
SCTP_CMD_LAST
} sctp_verb_t;
diff -Nru a/include/net/sctp/constants.h b/include/net/sctp/constants.h
--- a/include/net/sctp/constants.h 2004-07-23 17:08:07 -07:00
+++ b/include/net/sctp/constants.h 2004-07-23 17:08:07 -07:00
@@ -175,6 +175,10 @@
SCTP_IERROR_BAD_TAG,
SCTP_IERROR_BIG_GAP,
SCTP_IERROR_DUP_TSN,
+ SCTP_IERROR_HIGH_TSN,
+ SCTP_IERROR_IGNORE_TSN,
+ SCTP_IERROR_NO_DATA,
+ SCTP_IERROR_BAD_STREAM,
} sctp_ierror_t;
diff -Nru a/include/net/sctp/sm.h b/include/net/sctp/sm.h
--- a/include/net/sctp/sm.h 2004-07-23 17:08:07 -07:00
+++ b/include/net/sctp/sm.h 2004-07-23 17:08:07 -07:00
@@ -322,6 +322,9 @@
const struct sctp_chunk *chunk,
sctp_cmd_seq_t *commands,
struct sctp_chunk *err_chunk);
+int sctp_eat_data(const struct sctp_association *asoc,
+ struct sctp_chunk *chunk,
+ sctp_cmd_seq_t *commands);
/* 3rd level prototypes */
__u32 sctp_generate_tag(const struct sctp_endpoint *);
diff -Nru a/net/sctp/associola.c b/net/sctp/associola.c
--- a/net/sctp/associola.c 2004-07-23 17:08:07 -07:00
+++ b/net/sctp/associola.c 2004-07-23 17:08:07 -07:00
@@ -1093,6 +1093,7 @@
case SCTP_STATE_ESTABLISHED:
case SCTP_STATE_SHUTDOWN_PENDING:
case SCTP_STATE_SHUTDOWN_RECEIVED:
+ case SCTP_STATE_SHUTDOWN_SENT:
if ((asoc->rwnd > asoc->a_rwnd) &&
((asoc->rwnd - asoc->a_rwnd) >=
min_t(__u32, (asoc->base.sk->sk_rcvbuf >> 1), asoc->pmtu)))
diff -Nru a/net/sctp/outqueue.c b/net/sctp/outqueue.c
--- a/net/sctp/outqueue.c 2004-07-23 17:08:07 -07:00
+++ b/net/sctp/outqueue.c 2004-07-23 17:08:07 -07:00
@@ -525,10 +525,10 @@
int rtx_timeout, int *start_timer)
{
struct list_head *lqueue;
- struct list_head *lchunk;
+ struct list_head *lchunk, *lchunk1;
struct sctp_transport *transport = pkt->transport;
sctp_xmit_t status;
- struct sctp_chunk *chunk;
+ struct sctp_chunk *chunk, *chunk1;
struct sctp_association *asoc;
int error = 0;
@@ -615,6 +615,12 @@
* the transmitted list.
*/
list_add_tail(lchunk, &transport->transmitted);
+
+ /* Mark the chunk as ineligible for fast retransmit
+ * after it is retransmitted.
+ */
+ chunk->fast_retransmit = 0;
+
*start_timer = 1;
q->empty = 0;
@@ -622,6 +628,18 @@
lchunk = sctp_list_dequeue(lqueue);
break;
};
+
+ /* If we are here due to a retransmit timeout or a fast
+ * retransmit and if there are any chunks left in the retransmit
+ * queue that could not fit in the PMTU sized packet, they need * to be marked as ineligible for a subsequent fast retransmit.
+ */
+ if (rtx_timeout && !lchunk) {
+ list_for_each(lchunk1, lqueue) {
+ chunk1 = list_entry(lchunk1, struct sctp_chunk,
+ transmitted_list);
+ chunk1->fast_retransmit = 0;
+ }
+ }
}
return error;
diff -Nru a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
--- a/net/sctp/sm_make_chunk.c 2004-07-23 17:08:07 -07:00
+++ b/net/sctp/sm_make_chunk.c 2004-07-23 17:08:07 -07:00
@@ -1846,9 +1846,8 @@
if (unlikely(!idr_pre_get(&sctp_assocs_id, gfp)))
goto clean_up;
spin_lock_bh(&sctp_assocs_id_lock);
- error = idr_get_new(&sctp_assocs_id,
- (void *)asoc,
- &assoc_id);
+ error = idr_get_new_above(&sctp_assocs_id, (void *)asoc, 1,
+ &assoc_id);
spin_unlock_bh(&sctp_assocs_id_lock);
if (error == -EAGAIN)
goto retry;
diff -Nru a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
--- a/net/sctp/sm_sideeffect.c 2004-07-23 17:08:07 -07:00
+++ b/net/sctp/sm_sideeffect.c 2004-07-23 17:08:07 -07:00
@@ -529,6 +529,23 @@
}
}
+/* Helper function to stop any pending T3-RTX timers */
+static void sctp_cmd_t3_rtx_timers_stop(sctp_cmd_seq_t *cmds,
+ struct sctp_association *asoc)
+{
+ struct sctp_transport *t;
+ struct list_head *pos;
+
+ list_for_each(pos, &asoc->peer.transport_addr_list) {
+ t = list_entry(pos, struct sctp_transport, transports);
+ if (timer_pending(&t->T3_rtx_timer) &&
+ del_timer(&t->T3_rtx_timer)) {
+ sctp_transport_put(t);
+ }
+ }
+}
+
+
/* Helper function to update the heartbeat timer. */
static void sctp_cmd_hb_timer_update(sctp_cmd_seq_t *cmds,
struct sctp_association *asoc,
@@ -749,6 +766,26 @@
return;
}
+/* Helper function to remove the association non-primary peer
+ * transports.
+ */
+static void sctp_cmd_del_non_primary(struct sctp_association *asoc)
+{
+ struct sctp_transport *t;
+ struct list_head *pos;
+ struct list_head *temp;
+
+ list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) {
+ t = list_entry(pos, struct sctp_transport, transports);
+ if (!sctp_cmp_addr_exact(&t->ipaddr,
+ &asoc->peer.primary_addr)) {
+ sctp_assoc_del_peer(asoc, &t->ipaddr);
+ }
+ }
+
+ return;
+}
+
/* These three macros allow us to pull the debugging code out of the
* main flow of sctp_do_sm() to keep attention focused on the real
* functionality there.
@@ -1048,6 +1085,27 @@
if (cmd->obj.ptr)
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
SCTP_CHUNK(cmd->obj.ptr));
+
+ /* FIXME - Eventually come up with a cleaner way to
+ * enabling COOKIE-ECHO + DATA bundling during
+ * multihoming stale cookie scenarios, the following
+ * command plays with asoc->peer.retran_path to
+ * avoid the problem of sending the COOKIE-ECHO and
+ * DATA in different paths, which could result
+ * in the association being ABORTed if the DATA chunk
+ * is processed first by the server. Checking the
+ * init error counter simply causes this command
+ * to be executed only during failed attempts of
+ * association establishment.
+ */
+ if ((asoc->peer.retran_path !=
+ asoc->peer.primary_path) &&
+ (asoc->counters[SCTP_COUNTER_INIT_ERROR] > 0)) {
+ sctp_add_cmd_sf(commands,
+ SCTP_CMD_FORCE_PRIM_RETRAN,
+ SCTP_NULL());
+ }
+
break;
case SCTP_CMD_GEN_SHUTDOWN:
@@ -1281,6 +1339,19 @@
break;
case SCTP_CMD_CLEAR_INIT_TAG:
asoc->peer.i.init_tag = 0;
+ break;
+ case SCTP_CMD_DEL_NON_PRIMARY:
+ sctp_cmd_del_non_primary(asoc);
+ break;
+ case SCTP_CMD_T3_RTX_TIMERS_STOP:
+ sctp_cmd_t3_rtx_timers_stop(commands, asoc);
+ break;
+ case SCTP_CMD_FORCE_PRIM_RETRAN:
+ t = asoc->peer.retran_path;
+ asoc->peer.retran_path = asoc->peer.primary_path;
+ error = sctp_outq_uncork(&asoc->outqueue);
+ local_cork = 0;
+ asoc->peer.retran_path = t;
break;
default:
printk(KERN_WARNING "Impossible command: %u, %p\n",
diff -Nru a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
--- a/net/sctp/sm_statefuns.c 2004-07-23 17:08:07 -07:00
+++ b/net/sctp/sm_statefuns.c 2004-07-23 17:08:07 -07:00
@@ -472,8 +472,6 @@
*/
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
- sctp_add_cmd_sf(commands, SCTP_CMD_COUNTER_RESET,
- SCTP_COUNTER(SCTP_COUNTER_INIT_ERROR));
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START,
SCTP_TO(SCTP_EVENT_TIMEOUT_T1_COOKIE));
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
@@ -674,6 +672,15 @@
if (!sctp_vtag_verify(chunk, asoc))
return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+ /* Reset init error count upon receipt of COOKIE-ACK,
+ * to avoid problems with the managemement of this
+ * counter in stale cookie situations when a transition back
+ * from the COOKIE-ECHOED state to the COOKIE-WAIT
+ * state is performed.
+ */
+ sctp_add_cmd_sf(commands, SCTP_CMD_COUNTER_RESET,
+ SCTP_COUNTER(SCTP_COUNTER_INIT_ERROR));
+
/* RFC 2960 5.1 Normal Establishment of an Association
*
* E) Upon reception of the COOKIE ACK, endpoint "A" will move
@@ -1872,8 +1879,6 @@
time_t stale;
sctp_cookie_preserve_param_t bht;
sctp_errhdr_t *err;
- struct list_head *pos;
- struct sctp_transport *t;
struct sctp_chunk *reply;
struct sctp_bind_addr *bp;
int attempts;
@@ -1920,20 +1925,27 @@
/* Clear peer's init_tag cached in assoc as we are sending a new INIT */
sctp_add_cmd_sf(commands, SCTP_CMD_CLEAR_INIT_TAG, SCTP_NULL());
+ /* Stop pending T3-rtx and heartbeat timers */
+ sctp_add_cmd_sf(commands, SCTP_CMD_T3_RTX_TIMERS_STOP, SCTP_NULL());
+ sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_STOP, SCTP_NULL());
+
+ /* Delete non-primary peer ip addresses since we are transitioning
+ * back to the COOKIE-WAIT state
+ */
+ sctp_add_cmd_sf(commands, SCTP_CMD_DEL_NON_PRIMARY, SCTP_NULL());
+
+ /* If we've sent any data bundled with COOKIE-ECHO we will need to
+ * resend
+ */
+ sctp_add_cmd_sf(commands, SCTP_CMD_RETRAN,
+ SCTP_TRANSPORT(asoc->peer.primary_path));
+
/* Cast away the const modifier, as we want to just
* rerun it through as a sideffect.
*/
sctp_add_cmd_sf(commands, SCTP_CMD_COUNTER_INC,
SCTP_COUNTER(SCTP_COUNTER_INIT_ERROR));
- /* If we've sent any data bundled with COOKIE-ECHO we need to
- * resend.
- */
- list_for_each(pos, &asoc->peer.transport_addr_list) {
- t = list_entry(pos, struct sctp_transport, transports);
- sctp_add_cmd_sf(commands, SCTP_CMD_RETRAN, SCTP_TRANSPORT(t));
- }
-
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
SCTP_TO(SCTP_EVENT_TIMEOUT_T1_COOKIE));
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
@@ -2321,12 +2333,7 @@
sctp_cmd_seq_t *commands)
{
struct sctp_chunk *chunk = arg;
- sctp_datahdr_t *data_hdr;
- struct sctp_chunk *err;
- size_t datalen;
- sctp_verb_t deliver;
- int tmp;
- __u32 tsn;
+ int error;
if (!sctp_vtag_verify(chunk, asoc)) {
sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG,
@@ -2334,158 +2341,22 @@
return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
}
- data_hdr = chunk->subh.data_hdr = (sctp_datahdr_t *)chunk->skb->data;
- skb_pull(chunk->skb, sizeof(sctp_datahdr_t));
-
- tsn = ntohl(data_hdr->tsn);
- SCTP_DEBUG_PRINTK("eat_data: TSN 0x%x.\n", tsn);
-
- /* ASSERT: Now skb->data is really the user data. */
-
- /* Process ECN based congestion.
- *
- * Since the chunk structure is reused for all chunks within
- * a packet, we use ecn_ce_done to track if we've already
- * done CE processing for this packet.
- *
- * We need to do ECN processing even if we plan to discard the
- * chunk later.
- */
-
- if (!chunk->ecn_ce_done) {
- struct sctp_af *af;
- chunk->ecn_ce_done = 1;
-
- af = sctp_get_af_specific(
- ipver2af(chunk->skb->nh.iph->version));
-
- if (af && af->is_ce(chunk->skb) && asoc->peer.ecn_capable) {
- /* Do real work as sideffect. */
- sctp_add_cmd_sf(commands, SCTP_CMD_ECN_CE,
- SCTP_U32(tsn));
- }
- }
-
- tmp = sctp_tsnmap_check(&asoc->peer.tsn_map, tsn);
- if (tmp < 0) {
- /* The TSN is too high--silently discard the chunk and
- * count on it getting retransmitted later.
- */
+ error = sctp_eat_data(asoc, chunk, commands );
+ switch (error) {
+ case SCTP_IERROR_NO_ERROR:
+ break;
+ case SCTP_IERROR_HIGH_TSN:
+ case SCTP_IERROR_BAD_STREAM:
goto discard_noforce;
- } else if (tmp > 0) {
- /* This is a duplicate. Record it. */
- sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_DUP, SCTP_U32(tsn));
+ case SCTP_IERROR_DUP_TSN:
+ case SCTP_IERROR_IGNORE_TSN:
goto discard_force;
+ case SCTP_IERROR_NO_DATA:
+ goto consume;
+ default:
+ BUG();
}
- /* This is a new TSN. */
-
- /* Discard if there is no room in the receive window.
- * Actually, allow a little bit of overflow (up to a MTU).
- */
- datalen = ntohs(chunk->chunk_hdr->length);
- datalen -= sizeof(sctp_data_chunk_t);
-
- deliver = SCTP_CMD_CHUNK_ULP;
-
- /* Think about partial delivery. */
- if ((datalen >= asoc->rwnd) && (!asoc->ulpq.pd_mode)) {
-
- /* Even if we don't accept this chunk there is
- * memory pressure.
- */
- sctp_add_cmd_sf(commands, SCTP_CMD_PART_DELIVER, SCTP_NULL());
- }
-
- /* Spill over rwnd a little bit. Note: While allowed, this spill over
- * seems a bit troublesome in that frag_point varies based on
- * PMTU. In cases, such as loopback, this might be a rather
- * large spill over.
- */
- if (!asoc->rwnd || asoc->rwnd_over ||
- (datalen > asoc->rwnd + asoc->frag_point)) {
-
- /* If this is the next TSN, consider reneging to make
- * room. Note: Playing nice with a confused sender. A
- * malicious sender can still eat up all our buffer
- * space and in the future we may want to detect and
- * do more drastic reneging.
- */
- if (sctp_tsnmap_has_gap(&asoc->peer.tsn_map) &&
- (sctp_tsnmap_get_ctsn(&asoc->peer.tsn_map) + 1) == tsn) {
- SCTP_DEBUG_PRINTK("Reneging for tsn:%u\n", tsn);
- deliver = SCTP_CMD_RENEGE;
- } else {
- SCTP_DEBUG_PRINTK("Discard tsn: %u len: %Zd, "
- "rwnd: %d\n", tsn, datalen,
- asoc->rwnd);
- goto discard_force;
- }
- }
-
- /*
- * Section 3.3.10.9 No User Data (9)
- *
- * Cause of error
- * ---------------
- * No User Data: This error cause is returned to the originator of a
- * DATA chunk if a received DATA chunk has no user data.
- */
- if (unlikely(0 == datalen)) {
- err = sctp_make_abort_no_data(asoc, chunk, tsn);
- if (err) {
- sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
- SCTP_CHUNK(err));
- }
- /* We are going to ABORT, so we might as well stop
- * processing the rest of the chunks in the packet.
- */
- sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET,SCTP_NULL());
- sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
- SCTP_U32(SCTP_ERROR_NO_DATA));
- SCTP_INC_STATS(SctpAborteds);
- SCTP_DEC_STATS(SctpCurrEstab);
- return SCTP_DISPOSITION_CONSUME;
- }
-
- /* If definately accepting the DATA chunk, record its TSN, otherwise
- * wait for renege processing.
- */
- if (SCTP_CMD_CHUNK_ULP == deliver)
- sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_TSN, SCTP_U32(tsn));
-
- /* Note: Some chunks may get overcounted (if we drop) or overcounted
- * if we renege and the chunk arrives again.
- */
- if (chunk->chunk_hdr->flags & SCTP_DATA_UNORDERED)
- SCTP_INC_STATS(SctpInUnorderChunks);
- else
- SCTP_INC_STATS(SctpInOrderChunks);
-
- /* RFC 2960 6.5 Stream Identifier and Stream Sequence Number
- *
- * If an endpoint receive a DATA chunk with an invalid stream
- * identifier, it shall acknowledge the reception of the DATA chunk
- * following the normal procedure, immediately send an ERROR chunk
- * with cause set to "Invalid Stream Identifier" (See Section 3.3.10)
- * and discard the DATA chunk.
- */
- if (ntohs(data_hdr->stream) >= asoc->c.sinit_max_instreams) {
- err = sctp_make_op_error(asoc, chunk, SCTP_ERROR_INV_STRM,
- &data_hdr->stream,
- sizeof(data_hdr->stream));
- if (err)
- sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
- SCTP_CHUNK(err));
- goto discard_noforce;
- }
-
- /* Send the data up to the user. Note: Schedule the
- * SCTP_CMD_CHUNK_ULP cmd before the SCTP_CMD_GEN_SACK, as the SACK
- * chunk needs the updated rwnd.
- */
- sctp_add_cmd_sf(commands, deliver, SCTP_CHUNK(chunk));
-
if (asoc->autoclose) {
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE));
@@ -2551,6 +2422,9 @@
SCTP_TO(SCTP_EVENT_TIMEOUT_SACK));
}
return SCTP_DISPOSITION_DISCARD;
+consume:
+ return SCTP_DISPOSITION_CONSUME;
+
}
/*
@@ -2576,11 +2450,7 @@
sctp_cmd_seq_t *commands)
{
struct sctp_chunk *chunk = arg;
- sctp_datahdr_t *data_hdr;
- struct sctp_chunk *err;
- size_t datalen;
- int tmp;
- __u32 tsn;
+ int error;
if (!sctp_vtag_verify(chunk, asoc)) {
sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG,
@@ -2588,110 +2458,23 @@
return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
}
- data_hdr = chunk->subh.data_hdr = (sctp_datahdr_t *) chunk->skb->data;
- skb_pull(chunk->skb, sizeof(sctp_datahdr_t));
-
- tsn = ntohl(data_hdr->tsn);
-
- SCTP_DEBUG_PRINTK("eat_data: TSN 0x%x.\n", tsn);
-
- /* ASSERT: Now skb->data is really the user data. */
-
- /* Process ECN based congestion.
- *
- * Since the chunk structure is reused for all chunks within
- * a packet, we use ecn_ce_done to track if we've already
- * done CE processing for this packet.
- *
- * We need to do ECN processing even if we plan to discard the
- * chunk later.
- */
- if (!chunk->ecn_ce_done) {
- struct sctp_af *af;
- chunk->ecn_ce_done = 1;
-
- af = sctp_get_af_specific(
- ipver2af(chunk->skb->nh.iph->version));
-
- if (af && af->is_ce(chunk->skb) && asoc->peer.ecn_capable) {
- /* Do real work as sideffect. */
- sctp_add_cmd_sf(commands, SCTP_CMD_ECN_CE,
- SCTP_U32(tsn));
- }
- }
-
- tmp = sctp_tsnmap_check(&asoc->peer.tsn_map, tsn);
- if (tmp < 0) {
- /* The TSN is too high--silently discard the chunk and
- * count on it getting retransmitted later.
- */
- goto gen_shutdown;
- } else if (tmp > 0) {
- /* This is a duplicate. Record it. */
- sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_DUP, SCTP_U32(tsn));
- goto gen_shutdown;
- }
-
- /* This is a new TSN. */
- datalen = ntohs(chunk->chunk_hdr->length);
- datalen -= sizeof(sctp_data_chunk_t);
-
- /*
- * Section 3.3.10.9 No User Data (9)
- *
- * Cause of error
- * ---------------
- * No User Data: This error cause is returned to the originator of a
- * DATA chunk if a received DATA chunk has no user data.
- */
- if (unlikely(0 == datalen)) {
- err = sctp_make_abort_no_data(asoc, chunk, tsn);
- if (err) {
- sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
- SCTP_CHUNK(err));
- }
- /* We are going to ABORT, so we might as well stop
- * processing the rest of the chunks in the packet.
- */
- sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET,SCTP_NULL());
- sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
- SCTP_U32(SCTP_ERROR_NO_DATA));
- SCTP_INC_STATS(SctpAborteds);
- SCTP_DEC_STATS(SctpCurrEstab);
- return SCTP_DISPOSITION_CONSUME;
- }
-
- /* We are accepting this DATA chunk. */
-
- /* Record the fact that we have received this TSN. */
- sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_TSN, SCTP_U32(tsn));
-
- if (chunk->chunk_hdr->flags & SCTP_DATA_UNORDERED)
- SCTP_INC_STATS(SctpInUnorderChunks);
- else
- SCTP_INC_STATS(SctpInOrderChunks);
-
- /* RFC 2960 6.5 Stream Identifier and Stream Sequence Number
- *
- * If an endpoint receive a DATA chunk with an invalid stream
- * identifier, it shall acknowledge the reception of the DATA chunk
- * following the normal procedure, immediately send an ERROR chunk
- * with cause set to "Invalid Stream Identifier" (See Section 3.3.10)
- * and discard the DATA chunk.
- */
- if (ntohs(data_hdr->stream) >= asoc->c.sinit_max_instreams) {
- err = sctp_make_op_error(asoc, chunk, SCTP_ERROR_INV_STRM,
- &data_hdr->stream,
- sizeof(data_hdr->stream));
- if (err) {
- sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
- SCTP_CHUNK(err));
- }
+ error = sctp_eat_data(asoc, chunk, commands );
+ switch (error) {
+ case SCTP_IERROR_NO_ERROR:
+ case SCTP_IERROR_HIGH_TSN:
+ case SCTP_IERROR_DUP_TSN:
+ case SCTP_IERROR_IGNORE_TSN:
+ case SCTP_IERROR_BAD_STREAM:
+ break;
+ case SCTP_IERROR_NO_DATA:
+ goto consume;
+ default:
+ BUG();
}
/* Go a head and force a SACK, since we are shutting down. */
-gen_shutdown:
+
/* Implementor's Guide.
*
* While in SHUTDOWN-SENT state, the SHUTDOWN sender MUST immediately
@@ -2707,6 +2490,8 @@
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN));
}
+
+consume:
return SCTP_DISPOSITION_CONSUME;
}
@@ -4709,7 +4494,7 @@
num_blocks = ntohs(sack->num_gap_ack_blocks);
num_dup_tsns = ntohs(sack->num_dup_tsns);
len = sizeof(struct sctp_sackhdr);
- len = (num_blocks + num_dup_tsns) * sizeof(__u32);
+ len += (num_blocks + num_dup_tsns) * sizeof(__u32);
if (len > chunk->skb->len)
return NULL;
@@ -4847,4 +4632,172 @@
} else
sctp_chunk_free (err_chunk);
}
+}
+
+
+/* Process a data chunk */
+int sctp_eat_data(const struct sctp_association *asoc,
+ struct sctp_chunk *chunk,
+ sctp_cmd_seq_t *commands)
+{
+ sctp_datahdr_t *data_hdr;
+ struct sctp_chunk *err;
+ size_t datalen;
+ sctp_verb_t deliver;
+ int tmp;
+ __u32 tsn;
+
+ data_hdr = chunk->subh.data_hdr = (sctp_datahdr_t *)chunk->skb->data;
+ skb_pull(chunk->skb, sizeof(sctp_datahdr_t));
+
+ tsn = ntohl(data_hdr->tsn);
+ SCTP_DEBUG_PRINTK("eat_data: TSN 0x%x.\n", tsn);
+
+ /* ASSERT: Now skb->data is really the user data. */
+
+ /* Process ECN based congestion.
+ *
+ * Since the chunk structure is reused for all chunks within
+ * a packet, we use ecn_ce_done to track if we've already
+ * done CE processing for this packet.
+ *
+ * We need to do ECN processing even if we plan to discard the
+ * chunk later.
+ */
+
+ if (!chunk->ecn_ce_done) {
+ struct sctp_af *af;
+ chunk->ecn_ce_done = 1;
+
+ af = sctp_get_af_specific(
+ ipver2af(chunk->skb->nh.iph->version));
+
+ if (af && af->is_ce(chunk->skb) && asoc->peer.ecn_capable) {
+ /* Do real work as sideffect. */
+ sctp_add_cmd_sf(commands, SCTP_CMD_ECN_CE,
+ SCTP_U32(tsn));
+ }
+ }
+
+ tmp = sctp_tsnmap_check(&asoc->peer.tsn_map, tsn);
+ if (tmp < 0) {
+ /* The TSN is too high--silently discard the chunk and
+ * count on it getting retransmitted later.
+ */
+ return SCTP_IERROR_HIGH_TSN;
+ } else if (tmp > 0) {
+ /* This is a duplicate. Record it. */
+ sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_DUP, SCTP_U32(tsn));
+ return SCTP_IERROR_DUP_TSN;
+ }
+
+ /* This is a new TSN. */
+
+ /* Discard if there is no room in the receive window.
+ * Actually, allow a little bit of overflow (up to a MTU).
+ */
+ datalen = ntohs(chunk->chunk_hdr->length);
+ datalen -= sizeof(sctp_data_chunk_t);
+
+ deliver = SCTP_CMD_CHUNK_ULP;
+
+ /* Think about partial delivery. */
+ if ((datalen >= asoc->rwnd) && (!asoc->ulpq.pd_mode)) {
+
+ /* Even if we don't accept this chunk there is
+ * memory pressure.
+ */
+ sctp_add_cmd_sf(commands, SCTP_CMD_PART_DELIVER, SCTP_NULL());
+ }
+
+ /* Spill over rwnd a little bit. Note: While allowed, this spill over
+ * seems a bit troublesome in that frag_point varies based on
+ * PMTU. In cases, such as loopback, this might be a rather
+ * large spill over.
+ */
+ if (!asoc->rwnd || asoc->rwnd_over ||
+ (datalen > asoc->rwnd + asoc->frag_point)) {
+
+ /* If this is the next TSN, consider reneging to make
+ * room. Note: Playing nice with a confused sender. A
+ * malicious sender can still eat up all our buffer
+ * space and in the future we may want to detect and
+ * do more drastic reneging.
+ */
+ if (sctp_tsnmap_has_gap(&asoc->peer.tsn_map) &&
+ (sctp_tsnmap_get_ctsn(&asoc->peer.tsn_map) + 1) == tsn) {
+ SCTP_DEBUG_PRINTK("Reneging for tsn:%u\n", tsn);
+ deliver = SCTP_CMD_RENEGE;
+ } else {
+ SCTP_DEBUG_PRINTK("Discard tsn: %u len: %Zd, "
+ "rwnd: %d\n", tsn, datalen,
+ asoc->rwnd);
+ return SCTP_IERROR_IGNORE_TSN;
+ }
+ }
+
+ /*
+ * Section 3.3.10.9 No User Data (9)
+ *
+ * Cause of error
+ * ---------------
+ * No User Data: This error cause is returned to the originator of a
+ * DATA chunk if a received DATA chunk has no user data.
+ */
+ if (unlikely(0 == datalen)) {
+ err = sctp_make_abort_no_data(asoc, chunk, tsn);
+ if (err) {
+ sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
+ SCTP_CHUNK(err));
+ }
+ /* We are going to ABORT, so we might as well stop
+ * processing the rest of the chunks in the packet.
+ */
+ sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET,SCTP_NULL());
+ sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
+ SCTP_U32(SCTP_ERROR_NO_DATA));
+ SCTP_INC_STATS(SctpAborteds);
+ SCTP_DEC_STATS(SctpCurrEstab);
+ return SCTP_IERROR_NO_DATA;
+ }
+
+ /* If definately accepting the DATA chunk, record its TSN, otherwise
+ * wait for renege processing.
+ */
+ if (SCTP_CMD_CHUNK_ULP == deliver)
+ sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_TSN, SCTP_U32(tsn));
+
+ /* Note: Some chunks may get overcounted (if we drop) or overcounted
+ * if we renege and the chunk arrives again.
+ */
+ if (chunk->chunk_hdr->flags & SCTP_DATA_UNORDERED)
+ SCTP_INC_STATS(SctpInUnorderChunks);
+ else
+ SCTP_INC_STATS(SctpInOrderChunks);
+
+ /* RFC 2960 6.5 Stream Identifier and Stream Sequence Number
+ *
+ * If an endpoint receive a DATA chunk with an invalid stream
+ * identifier, it shall acknowledge the reception of the DATA chunk
+ * following the normal procedure, immediately send an ERROR chunk
+ * with cause set to "Invalid Stream Identifier" (See Section 3.3.10)
+ * and discard the DATA chunk.
+ */
+ if (ntohs(data_hdr->stream) >= asoc->c.sinit_max_instreams) {
+ err = sctp_make_op_error(asoc, chunk, SCTP_ERROR_INV_STRM,
+ &data_hdr->stream,
+ sizeof(data_hdr->stream));
+ if (err)
+ sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
+ SCTP_CHUNK(err));
+ return SCTP_IERROR_BAD_STREAM;
+ }
+
+ /* Send the data up to the user. Note: Schedule the
+ * SCTP_CMD_CHUNK_ULP cmd before the SCTP_CMD_GEN_SACK, as the SACK
+ * chunk needs the updated rwnd.
+ */
+ sctp_add_cmd_sf(commands, deliver, SCTP_CHUNK(chunk));
+
+ return SCTP_IERROR_NO_ERROR;
}
diff -Nru a/net/sctp/socket.c b/net/sctp/socket.c
--- a/net/sctp/socket.c 2004-07-23 17:08:07 -07:00
+++ b/net/sctp/socket.c 2004-07-23 17:08:07 -07:00
@@ -1697,6 +1697,32 @@
if (copy_from_user(¶ms, optval, optlen))
return -EFAULT;
+ /*
+ * API 7. Socket Options (setting the default value for the endpoint)
+ * All options that support specific settings on an association by
+ * filling in either an association id variable or a sockaddr_storage
+ * SHOULD also support setting of the same value for the entire endpoint
+ * (i.e. future associations). To accomplish this the following logic is
+ * used when setting one of these options:
+
+ * c) If neither the sockaddr_storage or association identification is
+ * set i.e. the sockaddr_storage is set to all 0's (INADDR_ANY) and
+ * the association identification is 0, the settings are a default
+ * and to be applied to the endpoint (all future associations).
+ */
+
+ /* update default value for endpoint (all future associations) */
+ if (!params.spp_assoc_id &&
+ sctp_is_any(( union sctp_addr *)¶ms.spp_address)) {
+ if (params.spp_hbinterval)
+ sctp_sk(sk)->paddrparam.spp_hbinterval =
+ params.spp_hbinterval;
+ if (sctp_max_retrans_path)
+ sctp_sk(sk)->paddrparam.spp_pathmaxrxt =
+ params.spp_pathmaxrxt;
+ return 0;
+ }
+
trans = sctp_addr_id2transport(sk, ¶ms.spp_address,
params.spp_assoc_id);
if (!trans)
@@ -2864,6 +2890,17 @@
if (copy_from_user(¶ms, optval, len))
return -EFAULT;
+ /* If no association id is specified retrieve the default value
+ * for the endpoint that will be used for all future associations
+ */
+ if (!params.spp_assoc_id &&
+ sctp_is_any(( union sctp_addr *)¶ms.spp_address)) {
+ params.spp_hbinterval = sctp_sk(sk)->paddrparam.spp_hbinterval;
+ params.spp_pathmaxrxt = sctp_sk(sk)->paddrparam.spp_pathmaxrxt;
+
+ goto done;
+ }
+
trans = sctp_addr_id2transport(sk, ¶ms.spp_address,
params.spp_assoc_id);
if (!trans)
@@ -2883,6 +2920,7 @@
*/
params.spp_pathmaxrxt = trans->error_threshold;
+done:
if (copy_to_user(optval, ¶ms, len))
return -EFAULT;
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [BK PATCH] 2.6 SCTP updates
2004-07-24 0:18 Sridhar Samudrala
@ 2004-07-25 5:27 ` David S. Miller
2004-07-26 13:51 ` Sridhar Samudrala
0 siblings, 1 reply; 11+ messages in thread
From: David S. Miller @ 2004-07-25 5:27 UTC (permalink / raw)
To: Sridhar Samudrala; +Cc: netdev, lksctp-developers
On Fri, 23 Jul 2004 17:18:11 -0700 (PDT)
Sridhar Samudrala <sri@us.ibm.com> wrote:
> Please do a
> bk pull http://linux-lksctp.bkbits.net/lksctp-2.5.work
>
> to get the following SCTP updates to 2.6.8-rc2.
Pulled, thanks Sridhar. Will there be a 2.4.x version of
any of these SCTP changes?
Thanks again.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [BK PATCH] 2.6 SCTP updates
2004-07-25 5:27 ` David S. Miller
@ 2004-07-26 13:51 ` Sridhar Samudrala
0 siblings, 0 replies; 11+ messages in thread
From: Sridhar Samudrala @ 2004-07-26 13:51 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, lksctp-developers
David S. Miller wrote:
>On Fri, 23 Jul 2004 17:18:11 -0700 (PDT)
>Sridhar Samudrala <sri@us.ibm.com> wrote:
>
>
>
>>Please do a
>> bk pull http://linux-lksctp.bkbits.net/lksctp-2.5.work
>>
>>to get the following SCTP updates to 2.6.8-rc2.
>>
>>
>
>Pulled, thanks Sridhar. Will there be a 2.4.x version of
>any of these SCTP changes?
>
>
>
Dave,
I plan to submit a 2.4 version of these patches along with the 2.6
sparse cleanup stuff
so that both the codebases don't deviate too much, but it may be a
couple of weeks
from now. I am currently at an SCTP interop event and will be on
vacation next week.
Thanks
Sridhar
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2004-07-26 13:51 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-10-02 23:46 [BK PATCH] 2.6 SCTP updates Sridhar Samudrala
2003-10-03 9:48 ` David S. Miller
-- strict thread matches above, loose matches on Subject: below --
2004-02-14 0:07 Sridhar Samudrala
2004-02-14 5:52 ` David S. Miller
2004-02-16 5:55 ` Sridhar Samudrala
2004-03-23 20:13 Sridhar Samudrala
2004-03-24 20:01 ` David S. Miller
2004-04-06 17:28 Sridhar Samudrala
2004-07-24 0:18 Sridhar Samudrala
2004-07-25 5:27 ` David S. Miller
2004-07-26 13:51 ` Sridhar Samudrala
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).