]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Network patches from DaveM for the 2.6.17 queue
authorChris Wright <chrisw@sous-sol.org>
Tue, 20 Jun 2006 08:10:04 +0000 (01:10 -0700)
committerChris Wright <chrisw@sous-sol.org>
Tue, 20 Jun 2006 08:10:04 +0000 (01:10 -0700)
queue-2.6.17/ethtool-fix-ufo-typo.patch [new file with mode: 0644]
queue-2.6.17/ipv6-sum-real-space-for-rtas.patch [new file with mode: 0644]
queue-2.6.17/pfkeyv2-fix-inconsistent-typing-in-struct-sadb_x_kmprivate.patch [new file with mode: 0644]
queue-2.6.17/reject-sctp-packets-with-broadcast-addresses.patch [new file with mode: 0644]
queue-2.6.17/sctp-fix-persistent-slowdown-in-sctp-when-a-gap-ack-consumes-rx-buffer.patch [new file with mode: 0644]
queue-2.6.17/sctp-limit-association-max_retrans-setting-in-setsockopt.patch [new file with mode: 0644]
queue-2.6.17/sctp-reset-rtt_in_progress-for-the-chunk-when-processing-its-sack.patch [new file with mode: 0644]
queue-2.6.17/sctp-send-only-1-window-update-sack-per-message.patch [new file with mode: 0644]
queue-2.6.17/series

diff --git a/queue-2.6.17/ethtool-fix-ufo-typo.patch b/queue-2.6.17/ethtool-fix-ufo-typo.patch
new file mode 100644 (file)
index 0000000..77d9d81
--- /dev/null
@@ -0,0 +1,39 @@
+From stable-bounces@linux.kernel.org  Tue Jun 20 00:09:54 2006
+Date: Tue, 20 Jun 2006 00:09:30 -0700 (PDT)
+From: David Miller <davem@davemloft.net>
+To: stable@kernel.org
+Cc: 
+Subject: ETHTOOL: Fix UFO typo
+
+From: Herbert Xu <herbert@gondor.apana.org.au>
+
+The function ethtool_get_ufo was referring to ETHTOOL_GTSO instead of
+ETHTOOL_GUFO.
+
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+
+ net/core/ethtool.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- linux-2.6.17.1.orig/net/core/ethtool.c
++++ linux-2.6.17.1/net/core/ethtool.c
+@@ -591,7 +591,7 @@ static int ethtool_set_tso(struct net_de
+ static int ethtool_get_ufo(struct net_device *dev, char __user *useraddr)
+ {
+-      struct ethtool_value edata = { ETHTOOL_GTSO };
++      struct ethtool_value edata = { ETHTOOL_GUFO };
+       if (!dev->ethtool_ops->get_ufo)
+               return -EOPNOTSUPP;
+@@ -600,6 +600,7 @@ static int ethtool_get_ufo(struct net_de
+                return -EFAULT;
+       return 0;
+ }
++
+ static int ethtool_set_ufo(struct net_device *dev, char __user *useraddr)
+ {
+       struct ethtool_value edata;
diff --git a/queue-2.6.17/ipv6-sum-real-space-for-rtas.patch b/queue-2.6.17/ipv6-sum-real-space-for-rtas.patch
new file mode 100644 (file)
index 0000000..816d85d
--- /dev/null
@@ -0,0 +1,93 @@
+From stable-bounces@linux.kernel.org  Tue Jun 20 00:03:17 2006
+Date: Tue, 20 Jun 2006 00:02:51 -0700 (PDT)
+From: David Miller <davem@davemloft.net>
+To: stable@kernel.org
+Cc: 
+Subject: IPV6: Sum real space for RTAs.
+
+From: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
+
+This patch fixes RTNLGRP_IPV6_IFINFO netlink notifications.  Issue
+pointed out by Patrick McHardy <kaber@trash.net>.
+
+Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
+Acked-by: Patrick McHardy <kaber@trash.net>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+
+ net/ipv6/addrconf.c |   28 ++++++++++++++++++++++++----
+ 1 file changed, 24 insertions(+), 4 deletions(-)
+
+--- linux-2.6.17.1.orig/net/ipv6/addrconf.c
++++ linux-2.6.17.1/net/ipv6/addrconf.c
+@@ -2860,6 +2860,11 @@ inet6_rtm_newaddr(struct sk_buff *skb, s
+       return inet6_addr_add(ifm->ifa_index, pfx, ifm->ifa_prefixlen);
+ }
++/* Maximum length of ifa_cacheinfo attributes */
++#define INET6_IFADDR_RTA_SPACE \
++              RTA_SPACE(16) /* IFA_ADDRESS */ + \
++              RTA_SPACE(sizeof(struct ifa_cacheinfo)) /* CACHEINFO */
++
+ static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa,
+                            u32 pid, u32 seq, int event, unsigned int flags)
+ {
+@@ -3092,7 +3097,7 @@ static int inet6_dump_ifacaddr(struct sk
+ static void inet6_ifa_notify(int event, struct inet6_ifaddr *ifa)
+ {
+       struct sk_buff *skb;
+-      int size = NLMSG_SPACE(sizeof(struct ifaddrmsg)+128);
++      int size = NLMSG_SPACE(sizeof(struct ifaddrmsg) + INET6_IFADDR_RTA_SPACE);
+       skb = alloc_skb(size, GFP_ATOMIC);
+       if (!skb) {
+@@ -3142,6 +3147,17 @@ static void inline ipv6_store_devconf(st
+ #endif
+ }
++/* Maximum length of ifinfomsg attributes */
++#define INET6_IFINFO_RTA_SPACE \
++              RTA_SPACE(IFNAMSIZ) /* IFNAME */ + \
++              RTA_SPACE(MAX_ADDR_LEN) /* ADDRESS */ + \
++              RTA_SPACE(sizeof(u32)) /* MTU */ + \
++              RTA_SPACE(sizeof(int)) /* LINK */ + \
++              RTA_SPACE(0) /* PROTINFO */ + \
++              RTA_SPACE(sizeof(u32)) /* FLAGS */ + \
++              RTA_SPACE(sizeof(struct ifla_cacheinfo)) /* CACHEINFO */ + \
++              RTA_SPACE(sizeof(__s32[DEVCONF_MAX])) /* CONF */
++
+ static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev, 
+                            u32 pid, u32 seq, int event, unsigned int flags)
+ {
+@@ -3235,8 +3251,7 @@ static int inet6_dump_ifinfo(struct sk_b
+ void inet6_ifinfo_notify(int event, struct inet6_dev *idev)
+ {
+       struct sk_buff *skb;
+-      /* 128 bytes ?? */
+-      int size = NLMSG_SPACE(sizeof(struct ifinfomsg)+128);
++      int size = NLMSG_SPACE(sizeof(struct ifinfomsg) + INET6_IFINFO_RTA_SPACE);
+       
+       skb = alloc_skb(size, GFP_ATOMIC);
+       if (!skb) {
+@@ -3252,6 +3267,11 @@ void inet6_ifinfo_notify(int event, stru
+       netlink_broadcast(rtnl, skb, 0, RTNLGRP_IPV6_IFINFO, GFP_ATOMIC);
+ }
++/* Maximum length of prefix_cacheinfo attributes */
++#define INET6_PREFIX_RTA_SPACE \
++              RTA_SPACE(sizeof(((struct prefix_info *)NULL)->prefix)) /* ADDRESS */ + \
++              RTA_SPACE(sizeof(struct prefix_cacheinfo)) /* CACHEINFO */
++
+ static int inet6_fill_prefix(struct sk_buff *skb, struct inet6_dev *idev,
+                       struct prefix_info *pinfo, u32 pid, u32 seq, 
+                       int event, unsigned int flags)
+@@ -3296,7 +3316,7 @@ static void inet6_prefix_notify(int even
+                        struct prefix_info *pinfo)
+ {
+       struct sk_buff *skb;
+-      int size = NLMSG_SPACE(sizeof(struct prefixmsg)+128);
++      int size = NLMSG_SPACE(sizeof(struct prefixmsg) + INET6_PREFIX_RTA_SPACE);
+       skb = alloc_skb(size, GFP_ATOMIC);
+       if (!skb) {
diff --git a/queue-2.6.17/pfkeyv2-fix-inconsistent-typing-in-struct-sadb_x_kmprivate.patch b/queue-2.6.17/pfkeyv2-fix-inconsistent-typing-in-struct-sadb_x_kmprivate.patch
new file mode 100644 (file)
index 0000000..f994868
--- /dev/null
@@ -0,0 +1,31 @@
+From stable-bounces@linux.kernel.org  Tue Jun 20 00:03:59 2006
+Date: Tue, 20 Jun 2006 00:03:34 -0700 (PDT)
+From: David Miller <davem@davemloft.net>
+To: stable@kernel.org
+Cc: 
+Subject: PFKEYV2: Fix inconsistent typing in struct sadb_x_kmprivate.
+
+From: Tushar Gohad <tgohad@mvista.com>
+
+Fixes inconsistent use of "uint32_t" vs. "u_int32_t".
+Fix pfkeyv2 userspace builds.
+
+Signed-off-by: Tushar Gohad <tgohad@mvista.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+
+ include/linux/pfkeyv2.h |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- linux-2.6.17.1.orig/include/linux/pfkeyv2.h
++++ linux-2.6.17.1/include/linux/pfkeyv2.h
+@@ -159,7 +159,7 @@ struct sadb_spirange {
+ struct sadb_x_kmprivate {
+       uint16_t        sadb_x_kmprivate_len;
+       uint16_t        sadb_x_kmprivate_exttype;
+-      u_int32_t       sadb_x_kmprivate_reserved;
++      uint32_t        sadb_x_kmprivate_reserved;
+ } __attribute__((packed));
+ /* sizeof(struct sadb_x_kmprivate) == 8 */
diff --git a/queue-2.6.17/reject-sctp-packets-with-broadcast-addresses.patch b/queue-2.6.17/reject-sctp-packets-with-broadcast-addresses.patch
new file mode 100644 (file)
index 0000000..cd0fd49
--- /dev/null
@@ -0,0 +1,103 @@
+From stable-bounces@linux.kernel.org  Tue Jun 20 00:05:17 2006
+Date: Tue, 20 Jun 2006 00:04:53 -0700 (PDT)
+From: David Miller <davem@davemloft.net>
+To: stable@kernel.org
+Cc: 
+Subject: [SCTP]: Reject sctp packets with broadcast addresses.
+
+From: Vlad Yasevich <vladislav.yasevich@hp.com>
+
+Make SCTP handle broadcast properly
+
+Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
+Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+
+ include/net/sctp/structs.h |    3 ++-
+ net/sctp/input.c           |    3 ++-
+ net/sctp/ipv6.c            |    6 ++++--
+ net/sctp/protocol.c        |    8 +++++++-
+ net/sctp/socket.c          |    2 +-
+ 5 files changed, 16 insertions(+), 6 deletions(-)
+
+--- linux-2.6.17.1.orig/include/net/sctp/structs.h
++++ linux-2.6.17.1/include/net/sctp/structs.h
+@@ -555,7 +555,8 @@ struct sctp_af {
+       int             (*to_addr_param) (const union sctp_addr *,
+                                         union sctp_addr_param *); 
+       int             (*addr_valid)   (union sctp_addr *,
+-                                       struct sctp_sock *);
++                                       struct sctp_sock *,
++                                       const struct sk_buff *);
+       sctp_scope_t    (*scope) (union sctp_addr *);
+       void            (*inaddr_any)   (union sctp_addr *, unsigned short);
+       int             (*is_any)       (const union sctp_addr *);
+--- linux-2.6.17.1.orig/net/sctp/input.c
++++ linux-2.6.17.1/net/sctp/input.c
+@@ -170,7 +170,8 @@ int sctp_rcv(struct sk_buff *skb)
+        * IP broadcast addresses cannot be used in an SCTP transport
+        * address."
+        */
+-      if (!af->addr_valid(&src, NULL) || !af->addr_valid(&dest, NULL))
++      if (!af->addr_valid(&src, NULL, skb) ||
++          !af->addr_valid(&dest, NULL, skb))
+               goto discard_it;
+       asoc = __sctp_rcv_lookup(skb, &src, &dest, &transport);
+--- linux-2.6.17.1.orig/net/sctp/ipv6.c
++++ linux-2.6.17.1/net/sctp/ipv6.c
+@@ -523,7 +523,9 @@ static int sctp_v6_available(union sctp_
+  * Return 0 - If the address is a non-unicast or an illegal address.
+  * Return 1 - If the address is a unicast.
+  */
+-static int sctp_v6_addr_valid(union sctp_addr *addr, struct sctp_sock *sp)
++static int sctp_v6_addr_valid(union sctp_addr *addr,
++                            struct sctp_sock *sp,
++                            const struct sk_buff *skb)
+ {
+       int ret = ipv6_addr_type(&addr->v6.sin6_addr);
+@@ -537,7 +539,7 @@ static int sctp_v6_addr_valid(union sctp
+               if (sp && ipv6_only_sock(sctp_opt2sk(sp)))
+                       return 0;
+               sctp_v6_map_v4(addr);
+-              return sctp_get_af_specific(AF_INET)->addr_valid(addr, sp);
++              return sctp_get_af_specific(AF_INET)->addr_valid(addr, sp, skb);
+       }
+       /* Is this a non-unicast address */
+--- linux-2.6.17.1.orig/net/sctp/protocol.c
++++ linux-2.6.17.1/net/sctp/protocol.c
+@@ -365,12 +365,18 @@ static int sctp_v4_is_any(const union sc
+  * Return 0 - If the address is a non-unicast or an illegal address.
+  * Return 1 - If the address is a unicast.
+  */
+-static int sctp_v4_addr_valid(union sctp_addr *addr, struct sctp_sock *sp)
++static int sctp_v4_addr_valid(union sctp_addr *addr,
++                            struct sctp_sock *sp,
++                            const struct sk_buff *skb)
+ {
+       /* Is this a non-unicast address or a unusable SCTP address? */
+       if (IS_IPV4_UNUSABLE_ADDRESS(&addr->v4.sin_addr.s_addr))
+               return 0;
++      /* Is this a broadcast address? */
++      if (skb && ((struct rtable *)skb->dst)->rt_flags & RTCF_BROADCAST)
++              return 0;
++
+       return 1;
+ }
+--- linux-2.6.17.1.orig/net/sctp/socket.c
++++ linux-2.6.17.1/net/sctp/socket.c
+@@ -172,7 +172,7 @@ static inline int sctp_verify_addr(struc
+               return -EINVAL;
+       /* Is this a valid SCTP address?  */
+-      if (!af->addr_valid(addr, sctp_sk(sk)))
++      if (!af->addr_valid(addr, sctp_sk(sk), NULL))
+               return -EINVAL;
+       if (!sctp_sk(sk)->pf->send_verify(sctp_sk(sk), (addr)))
diff --git a/queue-2.6.17/sctp-fix-persistent-slowdown-in-sctp-when-a-gap-ack-consumes-rx-buffer.patch b/queue-2.6.17/sctp-fix-persistent-slowdown-in-sctp-when-a-gap-ack-consumes-rx-buffer.patch
new file mode 100644 (file)
index 0000000..fdea08b
--- /dev/null
@@ -0,0 +1,55 @@
+From stable-bounces@linux.kernel.org  Tue Jun 20 00:09:44 2006
+Date: Tue, 20 Jun 2006 00:09:03 -0700 (PDT)
+From: David Miller <davem@davemloft.net>
+To: stable@kernel.org
+Cc: 
+Subject: SCTP: Fix persistent slowdown in sctp when a gap ack consumes rx buffer.
+
+From: Neil Horman <nhorman@tuxdriver.com>
+
+In the event that our entire receive buffer is full with a series of
+chunks that represent a single gap-ack, and then we accept a chunk
+(or chunks) that fill in the gap between the ctsn and the first gap,
+we renege chunks from the end of the buffer, which effectively does
+nothing but move our gap to the end of our received tsn stream. This
+does little but move our missing tsns down stream a little, and, if the
+sender is sending sufficiently large retransmit frames, the result is a
+perpetual slowdown which can never be recovered from, since the only
+chunk that can be accepted to allow progress in the tsn stream necessitates
+that a new gap be created to make room for it. This leads to a constant
+need for retransmits, and subsequent receiver stalls. The fix I've come up
+with is to deliver the frame without reneging if we have a full receive
+buffer and the receiving sockets sk_receive_queue is empty(indicating that
+the receive buffer is being blocked by a missing tsn).
+
+Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
+Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+
+ net/sctp/sm_statefuns.c |   10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+--- linux-2.6.17.1.orig/net/sctp/sm_statefuns.c
++++ linux-2.6.17.1/net/sctp/sm_statefuns.c
+@@ -5293,10 +5293,18 @@ static int sctp_eat_data(const struct sc
+        * 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.
++       * NOTE: If we have a full receive buffer here, we only renege if
++       * our receiver can still make progress without the tsn being
++       * received. We do this because in the event that the associations
++       * receive queue is empty we are filling a leading gap, and since
++       * reneging moves the gap to the end of the tsn stream, we are likely
++       * to stall again very shortly. Avoiding the renege when we fill a
++       * leading gap is a good heuristic for avoiding such steady state
++       * stalls.
+        */
+       if (!asoc->rwnd || asoc->rwnd_over ||
+           (datalen > asoc->rwnd + asoc->frag_point) ||
+-          rcvbuf_over) {
++          (rcvbuf_over && (!skb_queue_len(&sk->sk_receive_queue)))) {
+               /* If this is the next TSN, consider reneging to make
+                * room.   Note: Playing nice with a confused sender.  A
diff --git a/queue-2.6.17/sctp-limit-association-max_retrans-setting-in-setsockopt.patch b/queue-2.6.17/sctp-limit-association-max_retrans-setting-in-setsockopt.patch
new file mode 100644 (file)
index 0000000..39b8800
--- /dev/null
@@ -0,0 +1,62 @@
+From stable-bounces@linux.kernel.org  Tue Jun 20 00:04:43 2006
+Date: Tue, 20 Jun 2006 00:04:18 -0700 (PDT)
+From: David Miller <davem@davemloft.net>
+To: stable@kernel.org
+Cc: 
+Subject: SCTP: Limit association max_retrans setting in setsockopt.
+
+From: Vlad Yasevich <vladislav.yasevich@hp.com>
+
+When using ASSOCINFO socket option, we need to limit the number of
+maximum association retransmissions to be no greater than the sum
+of all the path retransmissions. This is specified in Section 7.1.2
+of the SCTP socket API draft.
+However, we only do this if the association has multiple paths. If
+there is only one path, the protocol stack will use the
+assoc_max_retrans setting when trying to retransmit packets.
+
+Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
+Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+
+ net/sctp/socket.c |   26 +++++++++++++++++++++++++-
+ 1 file changed, 25 insertions(+), 1 deletion(-)
+
+--- linux-2.6.17.1.orig/net/sctp/socket.c
++++ linux-2.6.17.1/net/sctp/socket.c
+@@ -2530,8 +2530,32 @@ static int sctp_setsockopt_associnfo(str
+       /* Set the values to the specific association */
+       if (asoc) {
+-              if (assocparams.sasoc_asocmaxrxt != 0)
++              if (assocparams.sasoc_asocmaxrxt != 0) {
++                      __u32 path_sum = 0;
++                      int   paths = 0;
++                      struct list_head *pos;
++                      struct sctp_transport *peer_addr;
++
++                      list_for_each(pos, &asoc->peer.transport_addr_list) {
++                              peer_addr = list_entry(pos,
++                                              struct sctp_transport,
++                                              transports);
++                              path_sum += peer_addr->pathmaxrxt;
++                              paths++;
++                      }
++
++                      /* Only validate asocmaxrxt if we have more then
++                       * one path/transport.  We do this because path
++                       * retransmissions are only counted when we have more
++                       * then one path.
++                       */
++                      if (paths > 1 &&
++                          assocparams.sasoc_asocmaxrxt > path_sum)
++                              return -EINVAL;
++
+                       asoc->max_retrans = assocparams.sasoc_asocmaxrxt;
++              }
++
+               if (assocparams.sasoc_cookie_life != 0) {
+                       asoc->cookie_life.tv_sec =
+                                       assocparams.sasoc_cookie_life / 1000;
diff --git a/queue-2.6.17/sctp-reset-rtt_in_progress-for-the-chunk-when-processing-its-sack.patch b/queue-2.6.17/sctp-reset-rtt_in_progress-for-the-chunk-when-processing-its-sack.patch
new file mode 100644 (file)
index 0000000..f901e31
--- /dev/null
@@ -0,0 +1,26 @@
+From stable-bounces@linux.kernel.org  Tue Jun 20 00:06:54 2006
+Date: Tue, 20 Jun 2006 00:06:27 -0700 (PDT)
+From: David Miller <davem@davemloft.net>
+To: stable@kernel.org
+Cc: 
+Subject: SCTP: Reset rtt_in_progress for the chunk when processing its sack.
+
+Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
+Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+
+ net/sctp/outqueue.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- linux-2.6.17.1.orig/net/sctp/outqueue.c
++++ linux-2.6.17.1/net/sctp/outqueue.c
+@@ -1262,6 +1262,7 @@ static void sctp_check_transmitted(struc
+                               if (!tchunk->tsn_gap_acked &&
+                                   !tchunk->resent &&
+                                   tchunk->rtt_in_progress) {
++                                      tchunk->rtt_in_progress = 0;
+                                       rtt = jiffies - tchunk->sent_at;
+                                       sctp_transport_update_rto(transport,
+                                                                 rtt);
diff --git a/queue-2.6.17/sctp-send-only-1-window-update-sack-per-message.patch b/queue-2.6.17/sctp-send-only-1-window-update-sack-per-message.patch
new file mode 100644 (file)
index 0000000..2dc49b4
--- /dev/null
@@ -0,0 +1,85 @@
+From stable-bounces@linux.kernel.org  Tue Jun 20 00:08:57 2006
+Date: Tue, 20 Jun 2006 00:08:29 -0700 (PDT)
+From: David Miller <davem@davemloft.net>
+To: stable@kernel.org
+Cc: 
+Subject: SCTP: Send only 1 window update SACK per message.
+
+From: Tsutomu Fujii <t-fujii@nb.jp.nec.com>
+
+Right now, every time we increase our rwnd by more then MTU bytes, we
+trigger a SACK.  When processing large messages, this will generate a
+SACK for almost every other SCTP fragment. However since we are freeing
+the entire message at the same time, we might as well collapse the SACK
+generation to 1.
+
+Signed-off-by: Tsutomu Fujii <t-fujii@nb.jp.nec.com>
+Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
+Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+
+ net/sctp/ulpevent.c |   30 ++++++++++++++++++++++++++++--
+ 1 file changed, 28 insertions(+), 2 deletions(-)
+
+--- linux-2.6.17.1.orig/net/sctp/ulpevent.c
++++ linux-2.6.17.1/net/sctp/ulpevent.c
+@@ -51,6 +51,8 @@
+ static void sctp_ulpevent_receive_data(struct sctp_ulpevent *event,
+                                      struct sctp_association *asoc);
+ static void sctp_ulpevent_release_data(struct sctp_ulpevent *event);
++static void sctp_ulpevent_release_frag_data(struct sctp_ulpevent *event);
++
+ /* Initialize an ULP event from an given skb.  */
+ SCTP_STATIC void sctp_ulpevent_init(struct sctp_ulpevent *event, int msg_flags)
+@@ -883,6 +885,7 @@ static void sctp_ulpevent_receive_data(s
+ static void sctp_ulpevent_release_data(struct sctp_ulpevent *event)
+ {
+       struct sk_buff *skb, *frag;
++      unsigned int    len;
+       /* Current stack structures assume that the rcv buffer is
+        * per socket.   For UDP style sockets this is not true as
+@@ -892,7 +895,30 @@ static void sctp_ulpevent_release_data(s
+        */
+       skb = sctp_event2skb(event);
+-      sctp_assoc_rwnd_increase(event->asoc, skb_headlen(skb));
++      len = skb->len;
++
++      if (!skb->data_len)
++              goto done;
++
++      /* Don't forget the fragments. */
++      for (frag = skb_shinfo(skb)->frag_list; frag; frag = frag->next) {
++              /* NOTE:  skb_shinfos are recursive. Although IP returns
++               * skb's with only 1 level of fragments, SCTP reassembly can
++               * increase the levels.
++               */
++              sctp_ulpevent_release_frag_data(sctp_skb2event(frag));
++      }
++
++done:
++      sctp_assoc_rwnd_increase(event->asoc, len);
++      sctp_ulpevent_release_owner(event);
++}
++
++static void sctp_ulpevent_release_frag_data(struct sctp_ulpevent *event)
++{
++      struct sk_buff *skb, *frag;
++
++      skb = sctp_event2skb(event);
+       if (!skb->data_len)
+               goto done;
+@@ -903,7 +929,7 @@ static void sctp_ulpevent_release_data(s
+                * skb's with only 1 level of fragments, SCTP reassembly can
+                * increase the levels.
+                */
+-              sctp_ulpevent_release_data(sctp_skb2event(frag));
++              sctp_ulpevent_release_frag_data(sctp_skb2event(frag));
+       }
+ done:
index 18951cdb999c92aeede1b55415a0b89418b51e2b..739856dfe7eeb901045f97f5229b8ed801471c3e 100644 (file)
@@ -1,2 +1,10 @@
 usb-whiteheat-fix-firmware-spurious-errors.patch
 serial-parport_serial-should-depend-on-serial_8250_pci.patch
+ipv6-sum-real-space-for-rtas.patch
+pfkeyv2-fix-inconsistent-typing-in-struct-sadb_x_kmprivate.patch
+sctp-limit-association-max_retrans-setting-in-setsockopt.patch
+reject-sctp-packets-with-broadcast-addresses.patch
+sctp-reset-rtt_in_progress-for-the-chunk-when-processing-its-sack.patch
+sctp-send-only-1-window-update-sack-per-message.patch
+sctp-fix-persistent-slowdown-in-sctp-when-a-gap-ack-consumes-rx-buffer.patch
+ethtool-fix-ufo-typo.patch