aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/sysctl.h1
-rw-r--r--include/net/sctp/structs.h16
-rw-r--r--net/sctp/associola.c9
-rw-r--r--net/sctp/endpointola.c3
-rw-r--r--net/sctp/input.c20
-rw-r--r--net/sctp/protocol.c3
-rw-r--r--net/sctp/sm_statefuns.c22
-rw-r--r--net/sctp/socket.c4
-rw-r--r--net/sctp/sysctl.c8
-rw-r--r--net/sctp/ulpevent.c24
10 files changed, 71 insertions, 39 deletions
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index ab2791b3189d..64f203c45378 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -715,6 +715,7 @@ enum {
715 NET_SCTP_PRSCTP_ENABLE = 14, 715 NET_SCTP_PRSCTP_ENABLE = 14,
716 NET_SCTP_SNDBUF_POLICY = 15, 716 NET_SCTP_SNDBUF_POLICY = 15,
717 NET_SCTP_SACK_TIMEOUT = 16, 717 NET_SCTP_SACK_TIMEOUT = 16,
718 NET_SCTP_RCVBUF_POLICY = 17,
718}; 719};
719 720
720/* /proc/sys/net/bridge */ 721/* /proc/sys/net/bridge */
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 2aad4468797e..8e7794ee27ff 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -161,6 +161,13 @@ extern struct sctp_globals {
161 */ 161 */
162 int sndbuf_policy; 162 int sndbuf_policy;
163 163
164 /*
165 * Policy for preforming sctp/socket accounting
166 * 0 - do socket level accounting, all assocs share sk_rcvbuf
167 * 1 - do sctp accounting, each asoc may use sk_rcvbuf bytes
168 */
169 int rcvbuf_policy;
170
164 /* Delayed SACK timeout 200ms default*/ 171 /* Delayed SACK timeout 200ms default*/
165 int sack_timeout; 172 int sack_timeout;
166 173
@@ -218,6 +225,7 @@ extern struct sctp_globals {
218#define sctp_cookie_preserve_enable (sctp_globals.cookie_preserve_enable) 225#define sctp_cookie_preserve_enable (sctp_globals.cookie_preserve_enable)
219#define sctp_max_retrans_association (sctp_globals.max_retrans_association) 226#define sctp_max_retrans_association (sctp_globals.max_retrans_association)
220#define sctp_sndbuf_policy (sctp_globals.sndbuf_policy) 227#define sctp_sndbuf_policy (sctp_globals.sndbuf_policy)
228#define sctp_rcvbuf_policy (sctp_globals.rcvbuf_policy)
221#define sctp_max_retrans_path (sctp_globals.max_retrans_path) 229#define sctp_max_retrans_path (sctp_globals.max_retrans_path)
222#define sctp_max_retrans_init (sctp_globals.max_retrans_init) 230#define sctp_max_retrans_init (sctp_globals.max_retrans_init)
223#define sctp_sack_timeout (sctp_globals.sack_timeout) 231#define sctp_sack_timeout (sctp_globals.sack_timeout)
@@ -1224,6 +1232,9 @@ struct sctp_endpoint {
1224 1232
1225 /* sendbuf acct. policy. */ 1233 /* sendbuf acct. policy. */
1226 __u32 sndbuf_policy; 1234 __u32 sndbuf_policy;
1235
1236 /* rcvbuf acct. policy. */
1237 __u32 rcvbuf_policy;
1227}; 1238};
1228 1239
1229/* Recover the outter endpoint structure. */ 1240/* Recover the outter endpoint structure. */
@@ -1550,6 +1561,11 @@ struct sctp_association {
1550 */ 1561 */
1551 int sndbuf_used; 1562 int sndbuf_used;
1552 1563
1564 /* This is the amount of memory that this association has allocated
1565 * in the receive path at any given time.
1566 */
1567 atomic_t rmem_alloc;
1568
1553 /* This is the wait queue head for send requests waiting on 1569 /* This is the wait queue head for send requests waiting on
1554 * the association sndbuf space. 1570 * the association sndbuf space.
1555 */ 1571 */
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index 5f07ddb19554..dec68a604773 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -177,10 +177,10 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
177 * RFC 6 - A SCTP receiver MUST be able to receive a minimum of 177 * RFC 6 - A SCTP receiver MUST be able to receive a minimum of
178 * 1500 bytes in one SCTP packet. 178 * 1500 bytes in one SCTP packet.
179 */ 179 */
180 if (sk->sk_rcvbuf < SCTP_DEFAULT_MINWINDOW) 180 if ((sk->sk_rcvbuf/2) < SCTP_DEFAULT_MINWINDOW)
181 asoc->rwnd = SCTP_DEFAULT_MINWINDOW; 181 asoc->rwnd = SCTP_DEFAULT_MINWINDOW;
182 else 182 else
183 asoc->rwnd = sk->sk_rcvbuf; 183 asoc->rwnd = sk->sk_rcvbuf/2;
184 184
185 asoc->a_rwnd = asoc->rwnd; 185 asoc->a_rwnd = asoc->rwnd;
186 186
@@ -192,6 +192,9 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
192 /* Set the sndbuf size for transmit. */ 192 /* Set the sndbuf size for transmit. */
193 asoc->sndbuf_used = 0; 193 asoc->sndbuf_used = 0;
194 194
195 /* Initialize the receive memory counter */
196 atomic_set(&asoc->rmem_alloc, 0);
197
195 init_waitqueue_head(&asoc->wait); 198 init_waitqueue_head(&asoc->wait);
196 199
197 asoc->c.my_vtag = sctp_generate_tag(ep); 200 asoc->c.my_vtag = sctp_generate_tag(ep);
@@ -400,6 +403,8 @@ static void sctp_association_destroy(struct sctp_association *asoc)
400 spin_unlock_bh(&sctp_assocs_id_lock); 403 spin_unlock_bh(&sctp_assocs_id_lock);
401 } 404 }
402 405
406 BUG_TRAP(!atomic_read(&asoc->rmem_alloc));
407
403 if (asoc->base.malloced) { 408 if (asoc->base.malloced) {
404 kfree(asoc); 409 kfree(asoc);
405 SCTP_DBG_OBJCNT_DEC(assoc); 410 SCTP_DBG_OBJCNT_DEC(assoc);
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c
index 0df76897f563..67bd53070ee0 100644
--- a/net/sctp/endpointola.c
+++ b/net/sctp/endpointola.c
@@ -104,6 +104,9 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep,
104 sk->sk_write_space = sctp_write_space; 104 sk->sk_write_space = sctp_write_space;
105 sock_set_flag(sk, SOCK_USE_WRITE_QUEUE); 105 sock_set_flag(sk, SOCK_USE_WRITE_QUEUE);
106 106
107 /* Get the receive buffer policy for this endpoint */
108 ep->rcvbuf_policy = sctp_rcvbuf_policy;
109
107 /* Initialize the secret key used with cookie. */ 110 /* Initialize the secret key used with cookie. */
108 get_random_bytes(&ep->secret_key[0], SCTP_SECRET_SIZE); 111 get_random_bytes(&ep->secret_key[0], SCTP_SECRET_SIZE);
109 ep->last_key = ep->current_key = 0; 112 ep->last_key = ep->current_key = 0;
diff --git a/net/sctp/input.c b/net/sctp/input.c
index 28f32243397f..b24ff2c1aef5 100644
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -100,21 +100,6 @@ static inline int sctp_rcv_checksum(struct sk_buff *skb)
100 return 0; 100 return 0;
101} 101}
102 102
103/* The free routine for skbuffs that sctp receives */
104static void sctp_rfree(struct sk_buff *skb)
105{
106 atomic_sub(sizeof(struct sctp_chunk),&skb->sk->sk_rmem_alloc);
107 sock_rfree(skb);
108}
109
110/* The ownership wrapper routine to do receive buffer accounting */
111static void sctp_rcv_set_owner_r(struct sk_buff *skb, struct sock *sk)
112{
113 skb_set_owner_r(skb,sk);
114 skb->destructor = sctp_rfree;
115 atomic_add(sizeof(struct sctp_chunk),&sk->sk_rmem_alloc);
116}
117
118struct sctp_input_cb { 103struct sctp_input_cb {
119 union { 104 union {
120 struct inet_skb_parm h4; 105 struct inet_skb_parm h4;
@@ -217,9 +202,6 @@ int sctp_rcv(struct sk_buff *skb)
217 rcvr = &ep->base; 202 rcvr = &ep->base;
218 } 203 }
219 204
220 if (atomic_read(&sk->sk_rmem_alloc) >= sk->sk_rcvbuf)
221 goto discard_release;
222
223 /* 205 /*
224 * RFC 2960, 8.4 - Handle "Out of the blue" Packets. 206 * RFC 2960, 8.4 - Handle "Out of the blue" Packets.
225 * An SCTP packet is called an "out of the blue" (OOTB) 207 * An SCTP packet is called an "out of the blue" (OOTB)
@@ -256,8 +238,6 @@ int sctp_rcv(struct sk_buff *skb)
256 } 238 }
257 SCTP_INPUT_CB(skb)->chunk = chunk; 239 SCTP_INPUT_CB(skb)->chunk = chunk;
258 240
259 sctp_rcv_set_owner_r(skb,sk);
260
261 /* Remember what endpoint is to handle this packet. */ 241 /* Remember what endpoint is to handle this packet. */
262 chunk->rcvr = rcvr; 242 chunk->rcvr = rcvr;
263 243
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index dc9dff396fad..f775d78aa59d 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -1050,6 +1050,9 @@ SCTP_STATIC __init int sctp_init(void)
1050 /* Sendbuffer growth - do per-socket accounting */ 1050 /* Sendbuffer growth - do per-socket accounting */
1051 sctp_sndbuf_policy = 0; 1051 sctp_sndbuf_policy = 0;
1052 1052
1053 /* Rcvbuffer growth - do per-socket accounting */
1054 sctp_rcvbuf_policy = 0;
1055
1053 /* HB.interval - 30 seconds */ 1056 /* HB.interval - 30 seconds */
1054 sctp_hb_interval = SCTP_DEFAULT_TIMEOUT_HEARTBEAT; 1057 sctp_hb_interval = SCTP_DEFAULT_TIMEOUT_HEARTBEAT;
1055