diff options
| -rw-r--r-- | include/linux/sysctl.h | 1 | ||||
| -rw-r--r-- | include/net/sctp/structs.h | 16 | ||||
| -rw-r--r-- | net/sctp/associola.c | 9 | ||||
| -rw-r--r-- | net/sctp/endpointola.c | 3 | ||||
| -rw-r--r-- | net/sctp/input.c | 20 | ||||
| -rw-r--r-- | net/sctp/protocol.c | 3 | ||||
| -rw-r--r-- | net/sctp/sm_statefuns.c | 22 | ||||
| -rw-r--r-- | net/sctp/socket.c | 4 | ||||
| -rw-r--r-- | net/sctp/sysctl.c | 8 | ||||
| -rw-r--r-- | net/sctp/ulpevent.c | 24 |
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 */ | ||
| 104 | static 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 */ | ||
| 111 | static 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 | |||
| 118 | struct sctp_input_cb { | 103 | struct 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 | |||
