* Backport various SCTP changesets from 2.6.19, recommended by Vlad Yasevich

(closes: #397946)

svn path=/dists/trunk/linux-2.6/; revision=7788
This commit is contained in:
dann frazier 2006-11-13 07:42:27 +00:00
parent 5198201eda
commit 5d53f96934
9 changed files with 1128 additions and 1 deletions

6
debian/changelog vendored
View File

@ -22,7 +22,11 @@ linux-2.6 (2.6.18-6) UNRELEASED; urgency=low
[ Martin Michlmayr ]
- arm: Set CONFIG_BINFMT_MISC=m
-- maximilian attems <maks@sternwelten.at> Fri, 10 Nov 2006 08:57:45 +0100
[ dann frazier ]
* Backport various SCTP changesets from 2.6.19, recommended by Vlad Yasevich
(closes: #397946)
-- dann frazier <dannf@debian.org> Mon, 13 Nov 2006 00:39:30 -0700
linux-2.6 (2.6.18-5) unstable; urgency=low

View File

@ -0,0 +1,331 @@
From: Sridhar Samudrala <sri@us.ibm.com>
Date: Tue, 22 Aug 2006 07:15:33 +0000 (-0700)
Subject: [SCTP]: Extend /proc/net/sctp/snmp to provide more statistics.
X-Git-Tag: v2.6.19-rc1
X-Git-Url: http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=ac0b04627269ff16c3c7ab854a65fe6780c6e3e5
[SCTP]: Extend /proc/net/sctp/snmp to provide more statistics.
This patch adds more statistics info under /proc/net/sctp/snmp
that should be useful for debugging. The additional events that
are counted now include timer expirations, retransmits, packet
and data chunk discards.
The Data chunk discards include all the cases where a data chunk
is discarded including high tsn, bad stream, dup tsn and the most
useful one(out of receive buffer/rwnd).
Also moved the SCTP MIB data structures from the generic include
directories to include/sctp/sctp.h.
Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
--- a/include/linux/snmp.h
+++ b/include/linux/snmp.h
@@ -160,39 +160,6 @@ enum
__UDP_MIB_MAX
};
-/* sctp mib definitions */
-/*
- * draft-ietf-sigtran-sctp-mib-07.txt
- */
-enum
-{
- SCTP_MIB_NUM = 0,
- SCTP_MIB_CURRESTAB, /* CurrEstab */
- SCTP_MIB_ACTIVEESTABS, /* ActiveEstabs */
- SCTP_MIB_PASSIVEESTABS, /* PassiveEstabs */
- SCTP_MIB_ABORTEDS, /* Aborteds */
- SCTP_MIB_SHUTDOWNS, /* Shutdowns */
- SCTP_MIB_OUTOFBLUES, /* OutOfBlues */
- SCTP_MIB_CHECKSUMERRORS, /* ChecksumErrors */
- SCTP_MIB_OUTCTRLCHUNKS, /* OutCtrlChunks */
- SCTP_MIB_OUTORDERCHUNKS, /* OutOrderChunks */
- SCTP_MIB_OUTUNORDERCHUNKS, /* OutUnorderChunks */
- SCTP_MIB_INCTRLCHUNKS, /* InCtrlChunks */
- SCTP_MIB_INORDERCHUNKS, /* InOrderChunks */
- SCTP_MIB_INUNORDERCHUNKS, /* InUnorderChunks */
- SCTP_MIB_FRAGUSRMSGS, /* FragUsrMsgs */
- SCTP_MIB_REASMUSRMSGS, /* ReasmUsrMsgs */
- SCTP_MIB_OUTSCTPPACKS, /* OutSCTPPacks */
- SCTP_MIB_INSCTPPACKS, /* InSCTPPacks */
- SCTP_MIB_RTOALGORITHM, /* RtoAlgorithm */
- SCTP_MIB_RTOMIN, /* RtoMin */
- SCTP_MIB_RTOMAX, /* RtoMax */
- SCTP_MIB_RTOINITIAL, /* RtoInitial */
- SCTP_MIB_VALCOOKIELIFE, /* ValCookieLife */
- SCTP_MIB_MAXINITRETR, /* MaxInitRetr */
- __SCTP_MIB_MAX
-};
-
/* linux mib definitions */
enum
{
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -216,6 +216,50 @@ DECLARE_SNMP_STAT(struct sctp_mib, sctp_
#endif /* !TEST_FRAME */
+/* sctp mib definitions */
+enum
+{
+ SCTP_MIB_NUM = 0,
+ SCTP_MIB_CURRESTAB, /* CurrEstab */
+ SCTP_MIB_ACTIVEESTABS, /* ActiveEstabs */
+ SCTP_MIB_PASSIVEESTABS, /* PassiveEstabs */
+ SCTP_MIB_ABORTEDS, /* Aborteds */
+ SCTP_MIB_SHUTDOWNS, /* Shutdowns */
+ SCTP_MIB_OUTOFBLUES, /* OutOfBlues */
+ SCTP_MIB_CHECKSUMERRORS, /* ChecksumErrors */
+ SCTP_MIB_OUTCTRLCHUNKS, /* OutCtrlChunks */
+ SCTP_MIB_OUTORDERCHUNKS, /* OutOrderChunks */
+ SCTP_MIB_OUTUNORDERCHUNKS, /* OutUnorderChunks */
+ SCTP_MIB_INCTRLCHUNKS, /* InCtrlChunks */
+ SCTP_MIB_INORDERCHUNKS, /* InOrderChunks */
+ SCTP_MIB_INUNORDERCHUNKS, /* InUnorderChunks */
+ SCTP_MIB_FRAGUSRMSGS, /* FragUsrMsgs */
+ SCTP_MIB_REASMUSRMSGS, /* ReasmUsrMsgs */
+ SCTP_MIB_OUTSCTPPACKS, /* OutSCTPPacks */
+ SCTP_MIB_INSCTPPACKS, /* InSCTPPacks */
+ SCTP_MIB_T1_INIT_EXPIREDS,
+ SCTP_MIB_T1_COOKIE_EXPIREDS,
+ SCTP_MIB_T2_SHUTDOWN_EXPIREDS,
+ SCTP_MIB_T3_RTX_EXPIREDS,
+ SCTP_MIB_T4_RTO_EXPIREDS,
+ SCTP_MIB_T5_SHUTDOWN_GUARD_EXPIREDS,
+ SCTP_MIB_DELAY_SACK_EXPIREDS,
+ SCTP_MIB_AUTOCLOSE_EXPIREDS,
+ SCTP_MIB_T3_RETRANSMITS,
+ SCTP_MIB_PMTUD_RETRANSMITS,
+ SCTP_MIB_FAST_RETRANSMITS,
+ SCTP_MIB_IN_PKT_SOFTIRQ,
+ SCTP_MIB_IN_PKT_BACKLOG,
+ SCTP_MIB_IN_PKT_DISCARDS,
+ SCTP_MIB_IN_DATA_CHUNK_DISCARDS,
+ __SCTP_MIB_MAX
+};
+
+#define SCTP_MIB_MAX __SCTP_MIB_MAX
+struct sctp_mib {
+ unsigned long mibs[SCTP_MIB_MAX];
+} __SNMP_MIB_ALIGN__;
+
/* Print debugging messages. */
#if SCTP_DEBUG
--- a/include/net/snmp.h
+++ b/include/net/snmp.h
@@ -100,12 +100,6 @@ struct udp_mib {
unsigned long mibs[UDP_MIB_MAX];
} __SNMP_MIB_ALIGN__;
-/* SCTP */
-#define SCTP_MIB_MAX __SCTP_MIB_MAX
-struct sctp_mib {
- unsigned long mibs[SCTP_MIB_MAX];
-} __SNMP_MIB_ALIGN__;
-
/* Linux */
#define LINUX_MIB_MAX __LINUX_MIB_MAX
struct linux_mib {
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -255,10 +255,13 @@ int sctp_rcv(struct sk_buff *skb)
*/
sctp_bh_lock_sock(sk);
- if (sock_owned_by_user(sk))
+ if (sock_owned_by_user(sk)) {
+ SCTP_INC_STATS_BH(SCTP_MIB_IN_PKT_BACKLOG);
sctp_add_backlog(sk, skb);
- else
+ } else {
+ SCTP_INC_STATS_BH(SCTP_MIB_IN_PKT_SOFTIRQ);
sctp_inq_push(&chunk->rcvr->inqueue, chunk);
+ }
sctp_bh_unlock_sock(sk);
@@ -271,6 +274,7 @@ int sctp_rcv(struct sk_buff *skb)
return 0;
discard_it:
+ SCTP_INC_STATS_BH(SCTP_MIB_IN_PKT_DISCARDS);
kfree_skb(skb);
return 0;
--- a/net/sctp/inqueue.c
+++ b/net/sctp/inqueue.c
@@ -87,7 +87,7 @@ void sctp_inq_free(struct sctp_inq *queu
/* Put a new packet in an SCTP inqueue.
* We assume that packet->sctp_hdr is set and in host byte order.
*/
-void sctp_inq_push(struct sctp_inq *q, struct sctp_chunk *packet)
+void sctp_inq_push(struct sctp_inq *q, struct sctp_chunk *chunk)
{
/* Directly call the packet handling routine. */
@@ -96,7 +96,7 @@ void sctp_inq_push(struct sctp_inq *q, s
* Eventually, we should clean up inqueue to not rely
* on the BH related data structures.
*/
- list_add_tail(&packet->list, &q->in_chunk_list);
+ list_add_tail(&chunk->list, &q->in_chunk_list);
q->immediate.func(q->immediate.data);
}
--- a/net/sctp/outqueue.c
+++ b/net/sctp/outqueue.c
@@ -467,6 +467,7 @@ void sctp_retransmit(struct sctp_outq *q
switch(reason) {
case SCTP_RTXR_T3_RTX:
+ SCTP_INC_STATS(SCTP_MIB_T3_RETRANSMITS);
sctp_transport_lower_cwnd(transport, SCTP_LOWER_CWND_T3_RTX);
/* Update the retran path if the T3-rtx timer has expired for
* the current retran path.
@@ -475,12 +476,15 @@ void sctp_retransmit(struct sctp_outq *q
sctp_assoc_update_retran_path(transport->asoc);
break;
case SCTP_RTXR_FAST_RTX:
+ SCTP_INC_STATS(SCTP_MIB_FAST_RETRANSMITS);
sctp_transport_lower_cwnd(transport, SCTP_LOWER_CWND_FAST_RTX);
fast_retransmit = 1;
break;
case SCTP_RTXR_PMTUD:
- default:
+ SCTP_INC_STATS(SCTP_MIB_PMTUD_RETRANSMITS);
break;
+ default:
+ BUG();
}
sctp_retransmit_mark(q, transport, fast_retransmit);
--- a/net/sctp/proc.c
+++ b/net/sctp/proc.c
@@ -57,6 +57,21 @@ static struct snmp_mib sctp_snmp_list[]
SNMP_MIB_ITEM("SctpReasmUsrMsgs", SCTP_MIB_REASMUSRMSGS),
SNMP_MIB_ITEM("SctpOutSCTPPacks", SCTP_MIB_OUTSCTPPACKS),
SNMP_MIB_ITEM("SctpInSCTPPacks", SCTP_MIB_INSCTPPACKS),
+ SNMP_MIB_ITEM("SctpT1InitExpireds", SCTP_MIB_T1_INIT_EXPIREDS),
+ SNMP_MIB_ITEM("SctpT1CookieExpireds", SCTP_MIB_T1_COOKIE_EXPIREDS),
+ SNMP_MIB_ITEM("SctpT2ShutdownExpireds", SCTP_MIB_T2_SHUTDOWN_EXPIREDS),
+ SNMP_MIB_ITEM("SctpT3RtxExpireds", SCTP_MIB_T3_RTX_EXPIREDS),
+ SNMP_MIB_ITEM("SctpT4RtoExpireds", SCTP_MIB_T4_RTO_EXPIREDS),
+ SNMP_MIB_ITEM("SctpT5ShutdownGuardExpireds", SCTP_MIB_T5_SHUTDOWN_GUARD_EXPIREDS),
+ SNMP_MIB_ITEM("SctpDelaySackExpireds", SCTP_MIB_DELAY_SACK_EXPIREDS),
+ SNMP_MIB_ITEM("SctpAutocloseExpireds", SCTP_MIB_AUTOCLOSE_EXPIREDS),
+ SNMP_MIB_ITEM("SctpT3Retransmits", SCTP_MIB_T3_RETRANSMITS),
+ SNMP_MIB_ITEM("SctpPmtudRetransmits", SCTP_MIB_PMTUD_RETRANSMITS),
+ SNMP_MIB_ITEM("SctpFastRetransmits", SCTP_MIB_FAST_RETRANSMITS),
+ SNMP_MIB_ITEM("SctpInPktSoftirq", SCTP_MIB_IN_PKT_SOFTIRQ),
+ SNMP_MIB_ITEM("SctpInPktBacklog", SCTP_MIB_IN_PKT_BACKLOG),
+ SNMP_MIB_ITEM("SctpInPktDiscards", SCTP_MIB_IN_PKT_DISCARDS),
+ SNMP_MIB_ITEM("SctpInDataChunkDiscards", SCTP_MIB_IN_DATA_CHUNK_DISCARDS),
SNMP_MIB_SENTINEL
};
@@ -328,8 +343,8 @@ static int sctp_assocs_seq_show(struct s
"%8p %8p %-3d %-3d %-2d %-4d %4d %8d %8d %7d %5lu %-5d %5d ",
assoc, sk, sctp_sk(sk)->type, sk->sk_state,
assoc->state, hash, assoc->assoc_id,
- (sk->sk_rcvbuf - assoc->rwnd),
assoc->sndbuf_used,
+ (sk->sk_rcvbuf - assoc->rwnd),
sock_i_uid(sk), sock_i_ino(sk),
epb->bind_addr.port,
assoc->peer.port);
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -2663,9 +2663,11 @@ sctp_disposition_t sctp_sf_eat_data_6_2(
break;
case SCTP_IERROR_HIGH_TSN:
case SCTP_IERROR_BAD_STREAM:
+ SCTP_INC_STATS(SCTP_MIB_IN_DATA_CHUNK_DISCARDS);
goto discard_noforce;
case SCTP_IERROR_DUP_TSN:
case SCTP_IERROR_IGNORE_TSN:
+ SCTP_INC_STATS(SCTP_MIB_IN_DATA_CHUNK_DISCARDS);
goto discard_force;
case SCTP_IERROR_NO_DATA:
goto consume;
@@ -3652,6 +3654,7 @@ sctp_disposition_t sctp_sf_pdiscard(cons
void *arg,
sctp_cmd_seq_t *commands)
{
+ SCTP_INC_STATS(SCTP_MIB_IN_PKT_DISCARDS);
sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET, SCTP_NULL());
return SCTP_DISPOSITION_CONSUME;
@@ -4548,6 +4551,8 @@ sctp_disposition_t sctp_sf_do_6_3_3_rtx(
{
struct sctp_transport *transport = arg;
+ SCTP_INC_STATS(SCTP_MIB_T3_RTX_EXPIREDS);
+
if (asoc->overall_error_count >= asoc->max_retrans) {
sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
SCTP_ERROR(ETIMEDOUT));
@@ -4616,6 +4621,7 @@ sctp_disposition_t sctp_sf_do_6_2_sack(c
void *arg,
sctp_cmd_seq_t *commands)
{
+ SCTP_INC_STATS(SCTP_MIB_DELAY_SACK_EXPIREDS);
sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SACK, SCTP_FORCE());
return SCTP_DISPOSITION_CONSUME;
}
@@ -4650,6 +4656,7 @@ sctp_disposition_t sctp_sf_t1_init_timer
int attempts = asoc->init_err_counter + 1;
SCTP_DEBUG_PRINTK("Timer T1 expired (INIT).\n");
+ SCTP_INC_STATS(SCTP_MIB_T1_INIT_EXPIREDS);
if (attempts <= asoc->max_init_attempts) {
bp = (struct sctp_bind_addr *) &asoc->base.bind_addr;
@@ -4709,6 +4716,7 @@ sctp_disposition_t sctp_sf_t1_cookie_tim
int attempts = asoc->init_err_counter + 1;
SCTP_DEBUG_PRINTK("Timer T1 expired (COOKIE-ECHO).\n");
+ SCTP_INC_STATS(SCTP_MIB_T1_COOKIE_EXPIREDS);
if (attempts <= asoc->max_init_attempts) {
repl = sctp_make_cookie_echo(asoc, NULL);
@@ -4753,6 +4761,8 @@ sctp_disposition_t sctp_sf_t2_timer_expi
struct sctp_chunk *reply = NULL;
SCTP_DEBUG_PRINTK("Timer T2 expired.\n");
+ SCTP_INC_STATS(SCTP_MIB_T2_SHUTDOWN_EXPIREDS);
+
if (asoc->overall_error_count >= asoc->max_retrans) {
sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
SCTP_ERROR(ETIMEDOUT));
@@ -4814,6 +4824,8 @@ sctp_disposition_t sctp_sf_t4_timer_expi
struct sctp_chunk *chunk = asoc->addip_last_asconf;
struct sctp_transport *transport = chunk->transport;
+ SCTP_INC_STATS(SCTP_MIB_T4_RTO_EXPIREDS);
+
/* ADDIP 4.1 B1) Increment the error counters and perform path failure
* detection on the appropriate destination address as defined in
* RFC2960 [5] section 8.1 and 8.2.
@@ -4880,6 +4892,7 @@ sctp_disposition_t sctp_sf_t5_timer_expi
struct sctp_chunk *reply = NULL;
SCTP_DEBUG_PRINTK("Timer T5 expired.\n");
+ SCTP_INC_STATS(SCTP_MIB_T5_SHUTDOWN_GUARD_EXPIREDS);
reply = sctp_make_abort(asoc, NULL, 0);
if (!reply)
@@ -4910,6 +4923,8 @@ sctp_disposition_t sctp_sf_autoclose_tim
{
int disposition;
+ SCTP_INC_STATS(SCTP_MIB_AUTOCLOSE_EXPIREDS);
+
/* From 9.2 Shutdown of an Association
* Upon receipt of the SHUTDOWN primitive from its upper
* layer, the endpoint enters SHUTDOWN-PENDING state and

View File

@ -0,0 +1,28 @@
From: Vladislav Yasevich <vladislav.yasevich@hp.com>
Date: Tue, 22 Aug 2006 07:23:13 +0000 (-0700)
Subject: [SCTP]: Fix IPv6 address flag setting when doing peel-off/accept.
X-Git-Tag: v2.6.19-rc1
X-Git-Url: http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=eb5fa39f5ef490c72901b547ac5e7211efd47d56
[SCTP]: Fix IPv6 address flag setting when doing peel-off/accept.
During accept/peeloff we try to copy the list of bound addresses from
the original endpoint to the new one. However, we forgot to set the flag
to say that IPv6 is allowed on the new endpoint.
Signed-off-by: Vladislav Yasevich <vladislav.yasevich@hp.com>
Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -5619,6 +5619,8 @@ static void sctp_sock_migrate(struct soc
/* Copy the bind_addr list from the original endpoint to the new
* endpoint so that we can handle restarts properly
*/
+ if (PF_INET6 == assoc->base.sk->sk_family)
+ flags = SCTP_ADDR6_ALLOWED;
if (assoc->peer.ipv4_address)
flags |= SCTP_ADDR4_PEERSUPP;
if (assoc->peer.ipv6_address)

View File

@ -0,0 +1,424 @@
From: Vladislav Yasevich <vladislav.yasevich@hp.com>
Date: Tue, 22 Aug 2006 20:29:17 +0000 (-0700)
Subject: [SCTP]: Remove multiple levels of msecs to jiffies conversions.
X-Git-Tag: v2.6.19-rc1
X-Git-Url: http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=3fd091e73b81f131e1567c4d4a1ec042940bf2f7
[SCTP]: Remove multiple levels of msecs to jiffies conversions.
The SCTP sysctl entries are displayed in milliseconds, but stored
internally in jiffies. This results in multiple levels of msecs to
jiffies conversion and as a result produces a truncation error. This
patch makes things consistent in that we store and display defaults
in milliseconds and only convert once for use by association.
This patch also adds some sane min/max values so that we don't go off
the deep end.
Signed-off-by: Vladislav Yasevich <vladislav.yasevich@hp.com>
Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
--- a/include/net/sctp/constants.h
+++ b/include/net/sctp/constants.h
@@ -264,10 +264,10 @@ enum { SCTP_MAX_DUP_TSNS = 16 };
enum { SCTP_MAX_GABS = 16 };
/* Heartbeat interval - 30 secs */
-#define SCTP_DEFAULT_TIMEOUT_HEARTBEAT (30 * HZ)
+#define SCTP_DEFAULT_TIMEOUT_HEARTBEAT (30*1000)
/* Delayed sack timer - 200ms */
-#define SCTP_DEFAULT_TIMEOUT_SACK ((200 * HZ) / 1000)
+#define SCTP_DEFAULT_TIMEOUT_SACK (200)
/* RTO.Initial - 3 seconds
* RTO.Min - 1 second
@@ -275,9 +275,9 @@ enum { SCTP_MAX_GABS = 16 };
* RTO.Alpha - 1/8
* RTO.Beta - 1/4
*/
-#define SCTP_RTO_INITIAL (3 * HZ)
-#define SCTP_RTO_MIN (1 * HZ)
-#define SCTP_RTO_MAX (60 * HZ)
+#define SCTP_RTO_INITIAL (3 * 1000)
+#define SCTP_RTO_MIN (1 * 1000)
+#define SCTP_RTO_MAX (60 * 1000)
#define SCTP_RTO_ALPHA 3 /* 1/8 when converted to right shifts. */
#define SCTP_RTO_BETA 2 /* 1/4 when converted to right shifts. */
@@ -290,8 +290,7 @@ enum { SCTP_MAX_GABS = 16 };
#define SCTP_DEF_MAX_INIT 6
#define SCTP_DEF_MAX_SEND 10
-#define SCTP_DEFAULT_COOKIE_LIFE_SEC 60 /* seconds */
-#define SCTP_DEFAULT_COOKIE_LIFE_USEC 0 /* microseconds */
+#define SCTP_DEFAULT_COOKIE_LIFE (60 * 1000) /* 60 seconds */
#define SCTP_DEFAULT_MINWINDOW 1500 /* default minimum rwnd size */
#define SCTP_DEFAULT_MAXWINDOW 65535 /* default rwnd size */
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -128,9 +128,9 @@ extern struct sctp_globals {
* RTO.Alpha - 1/8 (3 when converted to right shifts.)
* RTO.Beta - 1/4 (2 when converted to right shifts.)
*/
- unsigned long rto_initial;
- unsigned long rto_min;
- unsigned long rto_max;
+ unsigned int rto_initial;
+ unsigned int rto_min;
+ unsigned int rto_max;
/* Note: rto_alpha and rto_beta are really defined as inverse
* powers of two to facilitate integer operations.
@@ -145,13 +145,13 @@ extern struct sctp_globals {
int cookie_preserve_enable;
/* Valid.Cookie.Life - 60 seconds */
- unsigned long valid_cookie_life;
+ unsigned int valid_cookie_life;
/* Delayed SACK timeout 200ms default*/
- unsigned long sack_timeout;
+ unsigned int sack_timeout;
/* HB.interval - 30 seconds */
- unsigned long hb_interval;
+ unsigned int hb_interval;
/* Association.Max.Retrans - 10 attempts
* Path.Max.Retrans - 5 attempts (per destination address)
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -1049,7 +1049,7 @@ SCTP_STATIC __init int sctp_init(void)
sctp_rto_beta = SCTP_RTO_BETA;
/* Valid.Cookie.Life - 60 seconds */
- sctp_valid_cookie_life = 60 * HZ;
+ sctp_valid_cookie_life = SCTP_DEFAULT_COOKIE_LIFE;
/* Whether Cookie Preservative is enabled(1) or not(0) */
sctp_cookie_preserve_enable = 1;
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3045,14 +3045,14 @@ SCTP_STATIC int sctp_init_sock(struct so
sp->initmsg.sinit_num_ostreams = sctp_max_outstreams;
sp->initmsg.sinit_max_instreams = sctp_max_instreams;
sp->initmsg.sinit_max_attempts = sctp_max_retrans_init;
- sp->initmsg.sinit_max_init_timeo = jiffies_to_msecs(sctp_rto_max);
+ sp->initmsg.sinit_max_init_timeo = sctp_rto_max;
/* Initialize default RTO related parameters. These parameters can
* be modified for with the SCTP_RTOINFO socket option.
*/
- sp->rtoinfo.srto_initial = jiffies_to_msecs(sctp_rto_initial);
- sp->rtoinfo.srto_max = jiffies_to_msecs(sctp_rto_max);
- sp->rtoinfo.srto_min = jiffies_to_msecs(sctp_rto_min);
+ sp->rtoinfo.srto_initial = sctp_rto_initial;
+ sp->rtoinfo.srto_max = sctp_rto_max;
+ sp->rtoinfo.srto_min = sctp_rto_min;
/* Initialize default association related parameters. These parameters
* can be modified with the SCTP_ASSOCINFO socket option.
@@ -3061,8 +3061,7 @@ SCTP_STATIC int sctp_init_sock(struct so
sp->assocparams.sasoc_number_peer_destinations = 0;
sp->assocparams.sasoc_peer_rwnd = 0;
sp->assocparams.sasoc_local_rwnd = 0;
- sp->assocparams.sasoc_cookie_life =
- jiffies_to_msecs(sctp_valid_cookie_life);
+ sp->assocparams.sasoc_cookie_life = sctp_valid_cookie_life;
/* Initialize default event subscriptions. By default, all the
* options are off.
@@ -3072,10 +3071,10 @@ SCTP_STATIC int sctp_init_sock(struct so
/* Default Peer Address Parameters. These defaults can
* be modified via SCTP_PEER_ADDR_PARAMS
*/
- sp->hbinterval = jiffies_to_msecs(sctp_hb_interval);
+ sp->hbinterval = sctp_hb_interval;
sp->pathmaxrxt = sctp_max_retrans_path;
sp->pathmtu = 0; // allow default discovery
- sp->sackdelay = jiffies_to_msecs(sctp_sack_timeout);
+ sp->sackdelay = sctp_sack_timeout;
sp->param_flags = SPP_HB_ENABLE |
SPP_PMTUD_ENABLE |
SPP_SACKDELAY_ENABLE;
--- a/net/sctp/sysctl.c
+++ b/net/sctp/sysctl.c
@@ -45,9 +45,10 @@
#include <net/sctp/sctp.h>
#include <linux/sysctl.h>
-static ctl_handler sctp_sysctl_jiffies_ms;
-static long rto_timer_min = 1;
-static long rto_timer_max = 86400000; /* One day */
+static int zero = 0;
+static int one = 1;
+static int timer_max = 86400000; /* ms in one day */
+static int int_max = INT_MAX;
static long sack_timer_min = 1;
static long sack_timer_max = 500;
@@ -56,45 +57,45 @@ static ctl_table sctp_table[] = {
.ctl_name = NET_SCTP_RTO_INITIAL,
.procname = "rto_initial",
.data = &sctp_rto_initial,
- .maxlen = sizeof(long),
+ .maxlen = sizeof(unsigned int),
.mode = 0644,
- .proc_handler = &proc_doulongvec_ms_jiffies_minmax,
- .strategy = &sctp_sysctl_jiffies_ms,
- .extra1 = &rto_timer_min,
- .extra2 = &rto_timer_max
+ .proc_handler = &proc_dointvec_minmax,
+ .strategy = &sysctl_intvec,
+ .extra1 = &one,
+ .extra2 = &timer_max
},
{
.ctl_name = NET_SCTP_RTO_MIN,
.procname = "rto_min",
.data = &sctp_rto_min,
- .maxlen = sizeof(long),
+ .maxlen = sizeof(unsigned int),
.mode = 0644,
- .proc_handler = &proc_doulongvec_ms_jiffies_minmax,
- .strategy = &sctp_sysctl_jiffies_ms,
- .extra1 = &rto_timer_min,
- .extra2 = &rto_timer_max
+ .proc_handler = &proc_dointvec_minmax,
+ .strategy = &sysctl_intvec,
+ .extra1 = &one,
+ .extra2 = &timer_max
},
{
.ctl_name = NET_SCTP_RTO_MAX,
.procname = "rto_max",
.data = &sctp_rto_max,
- .maxlen = sizeof(long),
+ .maxlen = sizeof(unsigned int),
.mode = 0644,
- .proc_handler = &proc_doulongvec_ms_jiffies_minmax,
- .strategy = &sctp_sysctl_jiffies_ms,
- .extra1 = &rto_timer_min,
- .extra2 = &rto_timer_max
+ .proc_handler = &proc_dointvec_minmax,
+ .strategy = &sysctl_intvec,
+ .extra1 = &one,
+ .extra2 = &timer_max
},
{
.ctl_name = NET_SCTP_VALID_COOKIE_LIFE,
.procname = "valid_cookie_life",
.data = &sctp_valid_cookie_life,
- .maxlen = sizeof(long),
+ .maxlen = sizeof(unsigned int),
.mode = 0644,
- .proc_handler = &proc_doulongvec_ms_jiffies_minmax,
- .strategy = &sctp_sysctl_jiffies_ms,
- .extra1 = &rto_timer_min,
- .extra2 = &rto_timer_max
+ .proc_handler = &proc_dointvec_minmax,
+ .strategy = &sysctl_intvec,
+ .extra1 = &one,
+ .extra2 = &timer_max
},
{
.ctl_name = NET_SCTP_MAX_BURST,
@@ -102,7 +103,10 @@ static ctl_table sctp_table[] = {
.data = &sctp_max_burst,
.maxlen = sizeof(int),
.mode = 0644,
- .proc_handler = &proc_dointvec
+ .proc_handler = &proc_dointvec_minmax,
+ .strategy = &sysctl_intvec,
+ .extra1 = &zero,
+ .extra2 = &int_max
},
{
.ctl_name = NET_SCTP_ASSOCIATION_MAX_RETRANS,
@@ -110,7 +114,10 @@ static ctl_table sctp_table[] = {
.data = &sctp_max_retrans_association,
.maxlen = sizeof(int),
.mode = 0644,
- .proc_handler = &proc_dointvec
+ .proc_handler = &proc_dointvec_minmax,
+ .strategy = &sysctl_intvec,
+ .extra1 = &one,
+ .extra2 = &int_max
},
{
.ctl_name = NET_SCTP_SNDBUF_POLICY,
@@ -118,7 +125,8 @@ static ctl_table sctp_table[] = {
.data = &sctp_sndbuf_policy,
.maxlen = sizeof(int),
.mode = 0644,
- .proc_handler = &proc_dointvec
+ .proc_handler = &proc_dointvec,
+ .strategy = &sysctl_intvec
},
{
.ctl_name = NET_SCTP_RCVBUF_POLICY,
@@ -126,7 +134,8 @@ static ctl_table sctp_table[] = {
.data = &sctp_rcvbuf_policy,
.maxlen = sizeof(int),
.mode = 0644,
- .proc_handler = &proc_dointvec
+ .proc_handler = &proc_dointvec,
+ .strategy = &sysctl_intvec
},
{
.ctl_name = NET_SCTP_PATH_MAX_RETRANS,
@@ -134,7 +143,10 @@ static ctl_table sctp_table[] = {
.data = &sctp_max_retrans_path,
.maxlen = sizeof(int),
.mode = 0644,
- .proc_handler = &proc_dointvec
+ .proc_handler = &proc_dointvec_minmax,
+ .strategy = &sysctl_intvec,
+ .extra1 = &one,
+ .extra2 = &int_max
},
{
.ctl_name = NET_SCTP_MAX_INIT_RETRANSMITS,
@@ -142,18 +154,21 @@ static ctl_table sctp_table[] = {
.data = &sctp_max_retrans_init,
.maxlen = sizeof(int),
.mode = 0644,
- .proc_handler = &proc_dointvec
+ .proc_handler = &proc_dointvec_minmax,
+ .strategy = &sysctl_intvec,
+ .extra1 = &one,
+ .extra2 = &int_max
},
{
.ctl_name = NET_SCTP_HB_INTERVAL,
.procname = "hb_interval",
.data = &sctp_hb_interval,
- .maxlen = sizeof(long),
+ .maxlen = sizeof(unsigned int),
.mode = 0644,
- .proc_handler = &proc_doulongvec_ms_jiffies_minmax,
- .strategy = &sctp_sysctl_jiffies_ms,
- .extra1 = &rto_timer_min,
- .extra2 = &rto_timer_max
+ .proc_handler = &proc_dointvec_minmax,
+ .strategy = &sysctl_intvec,
+ .extra1 = &one,
+ .extra2 = &timer_max
},
{
.ctl_name = NET_SCTP_PRESERVE_ENABLE,
@@ -161,23 +176,26 @@ static ctl_table sctp_table[] = {
.data = &sctp_cookie_preserve_enable,
.maxlen = sizeof(int),
.mode = 0644,
- .proc_handler = &proc_dointvec
+ .proc_handler = &proc_dointvec,
+ .strategy = &sysctl_intvec
},
{
.ctl_name = NET_SCTP_RTO_ALPHA,
.procname = "rto_alpha_exp_divisor",
.data = &sctp_rto_alpha,
.maxlen = sizeof(int),
- .mode = 0644,
- .proc_handler = &proc_dointvec
+ .mode = 0444,
+ .proc_handler = &proc_dointvec,
+ .strategy = &sysctl_intvec
},
{
.ctl_name = NET_SCTP_RTO_BETA,
.procname = "rto_beta_exp_divisor",
.data = &sctp_rto_beta,
.maxlen = sizeof(int),
- .mode = 0644,
- .proc_handler = &proc_dointvec
+ .mode = 0444,
+ .proc_handler = &proc_dointvec,
+ .strategy = &sysctl_intvec
},
{
.ctl_name = NET_SCTP_ADDIP_ENABLE,
@@ -185,7 +203,8 @@ static ctl_table sctp_table[] = {
.data = &sctp_addip_enable,
.maxlen = sizeof(int),
.mode = 0644,
- .proc_handler = &proc_dointvec
+ .proc_handler = &proc_dointvec,
+ .strategy = &sysctl_intvec
},
{
.ctl_name = NET_SCTP_PRSCTP_ENABLE,
@@ -193,7 +212,8 @@ static ctl_table sctp_table[] = {
.data = &sctp_prsctp_enable,
.maxlen = sizeof(int),
.mode = 0644,
- .proc_handler = &proc_dointvec
+ .proc_handler = &proc_dointvec,
+ .strategy = &sysctl_intvec
},
{
.ctl_name = NET_SCTP_SACK_TIMEOUT,
@@ -201,8 +221,8 @@ static ctl_table sctp_table[] = {
.data = &sctp_sack_timeout,
.maxlen = sizeof(long),
.mode = 0644,
- .proc_handler = &proc_doulongvec_ms_jiffies_minmax,
- .strategy = &sctp_sysctl_jiffies_ms,
+ .proc_handler = &proc_dointvec_minmax,
+ .strategy = &sysctl_intvec,
.extra1 = &sack_timer_min,
.extra2 = &sack_timer_max,
},
@@ -242,37 +262,3 @@ void sctp_sysctl_unregister(void)
{
unregister_sysctl_table(sctp_sysctl_header);
}
-
-/* Strategy function to convert jiffies to milliseconds. */
-static int sctp_sysctl_jiffies_ms(ctl_table *table, int __user *name, int nlen,
- void __user *oldval, size_t __user *oldlenp,
- void __user *newval, size_t newlen, void **context) {
-
- if (oldval) {
- size_t olen;
-
- if (oldlenp) {
- if (get_user(olen, oldlenp))
- return -EFAULT;
-
- if (olen != sizeof (int))
- return -EINVAL;
- }
- if (put_user((*(int *)(table->data) * 1000) / HZ,
- (int __user *)oldval) ||
- (oldlenp && put_user(sizeof (int), oldlenp)))
- return -EFAULT;
- }
- if (newval && newlen) {
- int new;
-
- if (newlen != sizeof (int))
- return -EINVAL;
-
- if (get_user(new, (int __user *)newval))
- return -EFAULT;
-
- *(int *)(table->data) = (new * HZ) / 1000;
- }
- return 1;
-}
--- a/net/sctp/transport.c
+++ b/net/sctp/transport.c
@@ -75,7 +75,7 @@ static struct sctp_transport *sctp_trans
* parameter 'RTO.Initial'.
*/
peer->rtt = 0;
- peer->rto = sctp_rto_initial;
+ peer->rto = msecs_to_jiffies(sctp_rto_initial);
peer->rttvar = 0;
peer->srtt = 0;
peer->rto_pending = 0;

View File

@ -0,0 +1,56 @@
From: Sridhar Samudrala <sri@us.ibm.com>
Date: Sat, 30 Sep 2006 00:09:05 +0000 (-0700)
Subject: [SCTP]: Include sk_buff overhead while updating the peer's receive window.
X-Git-Tag: v2.6.19-rc1
X-Git-Url: http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=cd49788563d3b9e2ec0b316fa57aef1c0cb3bd4b
[SCTP]: Include sk_buff overhead while updating the peer's receive window.
Currently if the sender is sending small messages, it can cause a receiver
to run out of receive buffer space even when the advertised receive window
is still open and results in packet drops and retransmissions. Including
a overhead while updating the sender's view of peer receive window will
reduce the chances of receive buffer space overshooting the receive window.
Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
--- a/net/sctp/output.c
+++ b/net/sctp/output.c
@@ -633,7 +633,7 @@ static sctp_xmit_t sctp_packet_append_da
* data will fit or delay in hopes of bundling a full
* sized packet.
*/
- if (len < asoc->pathmtu - packet->overhead) {
+ if (len < asoc->frag_point) {
retval = SCTP_XMIT_NAGLE_DELAY;
goto finish;
}
@@ -645,7 +645,13 @@ static sctp_xmit_t sctp_packet_append_da
/* Keep track of how many bytes are in flight to the receiver. */
asoc->outqueue.outstanding_bytes += datasize;
- /* Update our view of the receiver's rwnd. */
+ /* Update our view of the receiver's rwnd. Include sk_buff overhead
+ * while updating peer.rwnd so that it reduces the chances of a
+ * receiver running out of receive buffer space even when receive
+ * window is still open. This can happen when a sender is sending
+ * sending small messages.
+ */
+ datasize += sizeof(struct sk_buff);
if (datasize < rwnd)
rwnd -= datasize;
else
--- a/net/sctp/outqueue.c
+++ b/net/sctp/outqueue.c
@@ -416,7 +416,8 @@ void sctp_retransmit_mark(struct sctp_ou
* (Section 7.2.4)), add the data size of those
* chunks to the rwnd.
*/
- q->asoc->peer.rwnd += sctp_data_size(chunk);
+ q->asoc->peer.rwnd += (sctp_data_size(chunk) +
+ sizeof(struct sk_buff));
q->outstanding_bytes -= sctp_data_size(chunk);
transport->flight_size -= sctp_data_size(chunk);

View File

@ -0,0 +1,24 @@
From: Vlad Yasevich <vladislav.yasevich@hp.com>
Date: Sat, 30 Sep 2006 00:09:34 +0000 (-0700)
Subject: [SCTP]: Use correct mask when disabling PMTUD.
X-Git-Tag: v2.6.19-rc1
X-Git-Url: http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=b56bab46f3220eb6b1f71c000faa44c6b13fb148
[SCTP]: Use correct mask when disabling PMTUD.
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>
---
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -388,7 +388,7 @@ void sctp_icmp_frag_needed(struct sock *
* pmtu discovery on this transport.
*/
t->pathmtu = SCTP_DEFAULT_MINSEGMENT;
- t->param_flags = (t->param_flags & ~SPP_HB) |
+ t->param_flags = (t->param_flags & ~SPP_PMTUD) |
SPP_PMTUD_DISABLE;
} else {
t->pathmtu = pmtu;

View File

@ -0,0 +1,54 @@
From: Vlad Yasevich <vladislav.yasevich@hp.com>
Date: Sat, 30 Sep 2006 00:10:03 +0000 (-0700)
Subject: [SCTP]: Do not timestamp every SCTP packet.
X-Git-Tag: v2.6.19-rc1
X-Git-Url: http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=f236218b7292bccb0f8754a0feb5d9e9a06fe5a2
[SCTP]: Do not timestamp every SCTP packet.
We only need the timestamp on COOKIE-ECHO chunks, so instead of always
timestamping every SCTP packet, let common code timestamp if the socket
option is set. For COOKIE-ECHO, simply get the time of day if we don't
have a timestamp. This introduces a small possibility that the cookie
may be considered expired, but it will be renegotiated.
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>
---
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -218,12 +218,6 @@ int sctp_rcv(struct sk_buff *skb)
}
}
- /* SCTP seems to always need a timestamp right now (FIXME) */
- if (skb->tstamp.off_sec == 0) {
- __net_timestamp(skb);
- sock_enable_timestamp(sk);
- }
-
if (!xfrm_policy_check(sk, XFRM_POLICY_IN, skb, family))
goto discard_release;
nf_reset(skb);
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -1447,8 +1447,16 @@ no_hmac:
/* Check to see if the cookie is stale. If there is already
* an association, there is no need to check cookie's expiration
* for init collision case of lost COOKIE ACK.
+ * If skb has been timestamped, then use the stamp, otherwise
+ * use current time. This introduces a small possibility that
+ * that a cookie may be considered expired, but his would only slow
+ * down the new association establishment instead of every packet.
*/
- skb_get_timestamp(skb, &tv);
+ if (sock_flag(ep->base.sk, SOCK_TIMESTAMP))
+ skb_get_timestamp(skb, &tv);
+ else
+ do_gettimeofday(&tv);
+
if (!asoc && tv_lt(bear_cookie->expiration, tv)) {
__u16 len;
/*

View File

@ -0,0 +1,199 @@
From: Vlad Yasevich <vladislav.yasevich@hp.com>
Date: Tue, 10 Oct 2006 04:34:04 +0000 (-0700)
Subject: [SCTP]: Fix receive buffer accounting.
X-Git-Tag: v2.6.19-rc2
X-Git-Url: http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=331c4ee7faa4ee1e1404c872a139784753100498
[SCTP]: Fix receive buffer accounting.
When doing receiver buffer accounting, we always used skb->truesize.
This is problematic when processing bundled DATA chunks because for
every DATA chunk that could be small part of one large skb, we would
charge the size of the entire skb. The new approach is to store the
size of the DATA chunk we are accounting for in the sctp_ulpevent
structure and use that stored value for accounting.
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>
---
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -139,6 +139,7 @@ int sctp_inet_listen(struct socket *sock
void sctp_write_space(struct sock *sk);
unsigned int sctp_poll(struct file *file, struct socket *sock,
poll_table *wait);
+void sctp_sock_rfree(struct sk_buff *skb);
/*
* sctp/primitive.c
@@ -444,6 +445,19 @@ static inline struct list_head *sctp_lis
return result;
}
+/* SCTP version of skb_set_owner_r. We need this one because
+ * of the way we have to do receive buffer accounting on bundled
+ * chunks.
+ */
+static inline void sctp_skb_set_owner_r(struct sk_buff *skb, struct sock *sk)
+{
+ struct sctp_ulpevent *event = sctp_skb2event(skb);
+
+ skb->sk = sk;
+ skb->destructor = sctp_sock_rfree;
+ atomic_add(event->rmem_len, &sk->sk_rmem_alloc);
+}
+
/* Tests if the list has one and only one entry. */
static inline int sctp_list_single_entry(struct list_head *head)
{
--- a/include/net/sctp/ulpevent.h
+++ b/include/net/sctp/ulpevent.h
@@ -63,6 +63,7 @@ struct sctp_ulpevent {
__u32 cumtsn;
int msg_flags;
int iif;
+ unsigned int rmem_len;
};
/* Retrieve the skb this event sits inside of. */
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -5362,6 +5362,20 @@ static void sctp_wfree(struct sk_buff *s
sctp_association_put(asoc);
}
+/* Do accounting for the receive space on the socket.
+ * Accounting for the association is done in ulpevent.c
+ * We set this as a destructor for the cloned data skbs so that
+ * accounting is done at the correct time.
+ */
+void sctp_sock_rfree(struct sk_buff *skb)
+{
+ struct sock *sk = skb->sk;
+ struct sctp_ulpevent *event = sctp_skb2event(skb);
+
+ atomic_sub(event->rmem_len, &sk->sk_rmem_alloc);
+}
+
+
/* Helper function to wait for space in the sndbuf. */
static int sctp_wait_for_sndbuf(struct sctp_association *asoc, long *timeo_p,
size_t msg_len)
@@ -5634,10 +5648,10 @@ static void sctp_sock_migrate(struct soc
sctp_skb_for_each(skb, &oldsk->sk_receive_queue, tmp) {
event = sctp_skb2event(skb);
if (event->asoc == assoc) {
- sock_rfree(skb);
+ sctp_sock_rfree(skb);
__skb_unlink(skb, &oldsk->sk_receive_queue);
__skb_queue_tail(&newsk->sk_receive_queue, skb);
- skb_set_owner_r(skb, newsk);
+ sctp_skb_set_owner_r(skb, newsk);
}
}
@@ -5665,10 +5679,10 @@ static void sctp_sock_migrate(struct soc
sctp_skb_for_each(skb, &oldsp->pd_lobby, tmp) {
event = sctp_skb2event(skb);
if (event->asoc == assoc) {
- sock_rfree(skb);
+ sctp_sock_rfree(skb);
__skb_unlink(skb, &oldsp->pd_lobby);
__skb_queue_tail(queue, skb);
- skb_set_owner_r(skb, newsk);
+ sctp_skb_set_owner_r(skb, newsk);
}
}
--- a/net/sctp/ulpevent.c
+++ b/net/sctp/ulpevent.c
@@ -55,10 +55,13 @@ static void sctp_ulpevent_release_frag_d
/* Initialize an ULP event from an given skb. */
-SCTP_STATIC void sctp_ulpevent_init(struct sctp_ulpevent *event, int msg_flags)
+SCTP_STATIC void sctp_ulpevent_init(struct sctp_ulpevent *event,
+ int msg_flags,
+ unsigned int len)
{
memset(event, 0, sizeof(struct sctp_ulpevent));
event->msg_flags = msg_flags;
+ event->rmem_len = len;
}
/* Create a new sctp_ulpevent. */
@@ -73,7 +76,7 @@ SCTP_STATIC struct sctp_ulpevent *sctp_u
goto fail;
event = sctp_skb2event(skb);
- sctp_ulpevent_init(event, msg_flags);
+ sctp_ulpevent_init(event, msg_flags, skb->truesize);
return event;
@@ -101,17 +104,16 @@ static inline void sctp_ulpevent_set_own
sctp_association_hold((struct sctp_association *)asoc);
skb = sctp_event2skb(event);
event->asoc = (struct sctp_association *)asoc;
- atomic_add(skb->truesize, &event->asoc->rmem_alloc);
- skb_set_owner_r(skb, asoc->base.sk);
+ atomic_add(event->rmem_len, &event->asoc->rmem_alloc);
+ sctp_skb_set_owner_r(skb, asoc->base.sk);
}
/* A simple destructor to give up the reference to the association. */
static inline void sctp_ulpevent_release_owner(struct sctp_ulpevent *event)
{
struct sctp_association *asoc = event->asoc;
- struct sk_buff *skb = sctp_event2skb(event);
- atomic_sub(skb->truesize, &asoc->rmem_alloc);
+ atomic_sub(event->rmem_len, &asoc->rmem_alloc);
sctp_association_put(asoc);
}
@@ -372,7 +374,7 @@ struct sctp_ulpevent *sctp_ulpevent_make
/* Embed the event fields inside the cloned skb. */
event = sctp_skb2event(skb);
- sctp_ulpevent_init(event, MSG_NOTIFICATION);
+ sctp_ulpevent_init(event, MSG_NOTIFICATION, skb->truesize);
sre = (struct sctp_remote_error *)
skb_push(skb, sizeof(struct sctp_remote_error));
@@ -464,7 +466,7 @@ struct sctp_ulpevent *sctp_ulpevent_make
/* Embed the event fields inside the cloned skb. */
event = sctp_skb2event(skb);
- sctp_ulpevent_init(event, MSG_NOTIFICATION);
+ sctp_ulpevent_init(event, MSG_NOTIFICATION, skb->truesize);
ssf = (struct sctp_send_failed *)
skb_push(skb, sizeof(struct sctp_send_failed));
@@ -682,8 +684,11 @@ struct sctp_ulpevent *sctp_ulpevent_make
/* Embed the event fields inside the cloned skb. */
event = sctp_skb2event(skb);
- /* Initialize event with flags 0. */
- sctp_ulpevent_init(event, 0);
+ /* Initialize event with flags 0 and correct length
+ * Since this is a clone of the original skb, only account for
+ * the data of this chunk as other chunks will be accounted separately.
+ */
+ sctp_ulpevent_init(event, 0, skb->len + sizeof(struct sk_buff));
sctp_ulpevent_receive_data(event, asoc);
--- a/net/sctp/ulpqueue.c
+++ b/net/sctp/ulpqueue.c
@@ -309,7 +309,7 @@ static struct sctp_ulpevent *sctp_make_r
if (!new)
return NULL; /* try again later */
- new->sk = f_frag->sk;
+ sctp_skb_set_owner_r(new, f_frag->sk);
skb_shinfo(new)->frag_list = pos;
} else

View File

@ -6,3 +6,10 @@
+ features/mm-install_page-cleanup.patch
+ features/mm-do_wp_page-fixup.patch
+ features/mm-msync-cleanup.patch
+ features/all/sctp-backports-1.patch
+ features/all/sctp-backports-2.patch
+ features/all/sctp-backports-3.patch
+ features/all/sctp-backports-4.patch
+ features/all/sctp-backports-5.patch
+ features/all/sctp-backports-6.patch
+ features/all/sctp-backports-7.patch