Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 049b3ff5 authored by Neil Horman's avatar Neil Horman Committed by David S. Miller
Browse files

[SCTP]: Include ulpevents in socket receive buffer accounting.



Also introduces a sysctl option to configure the receive buffer
accounting policy to be either at socket or association level.
Default is all the associations on the same socket share the
receive buffer.

Signed-off-by: default avatarNeil Horman <nhorman@tuxdriver.com>
Signed-off-by: default avatarSridhar Samudrala <sri@us.ibm.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 19c7e9ee
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -715,6 +715,7 @@ enum {
	NET_SCTP_PRSCTP_ENABLE		 = 14,
	NET_SCTP_SNDBUF_POLICY		 = 15,
	NET_SCTP_SACK_TIMEOUT		 = 16,
	NET_SCTP_RCVBUF_POLICY		 = 17,
};

/* /proc/sys/net/bridge */
+16 −0
Original line number Diff line number Diff line
@@ -161,6 +161,13 @@ extern struct sctp_globals {
	 */
	int sndbuf_policy;

	/*
	 * Policy for preforming sctp/socket accounting
	 * 0   - do socket level accounting, all assocs share sk_rcvbuf
	 * 1   - do sctp accounting, each asoc may use sk_rcvbuf bytes
	 */
	int rcvbuf_policy;

	/* Delayed SACK timeout  200ms default*/
	int sack_timeout;

@@ -218,6 +225,7 @@ extern struct sctp_globals {
#define sctp_cookie_preserve_enable	(sctp_globals.cookie_preserve_enable)
#define sctp_max_retrans_association	(sctp_globals.max_retrans_association)
#define sctp_sndbuf_policy	 	(sctp_globals.sndbuf_policy)
#define sctp_rcvbuf_policy	 	(sctp_globals.rcvbuf_policy)
#define sctp_max_retrans_path		(sctp_globals.max_retrans_path)
#define sctp_max_retrans_init		(sctp_globals.max_retrans_init)
#define sctp_sack_timeout		(sctp_globals.sack_timeout)
@@ -1224,6 +1232,9 @@ struct sctp_endpoint {

	/* sendbuf acct. policy.	*/
	__u32 sndbuf_policy;

	/* rcvbuf acct. policy.	*/
	__u32 rcvbuf_policy;
};

/* Recover the outter endpoint structure. */
@@ -1550,6 +1561,11 @@ struct sctp_association {
	 */
	int sndbuf_used;

	/* This is the amount of memory that this association has allocated
	 * in the receive path at any given time.
	 */
	atomic_t rmem_alloc;

	/* This is the wait queue head for send requests waiting on
	 * the association sndbuf space.
	 */
+7 −2
Original line number Diff line number Diff line
@@ -177,10 +177,10 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
	 * RFC 6 - A SCTP receiver MUST be able to receive a minimum of
	 * 1500 bytes in one SCTP packet.
	 */
	if (sk->sk_rcvbuf < SCTP_DEFAULT_MINWINDOW)
	if ((sk->sk_rcvbuf/2) < SCTP_DEFAULT_MINWINDOW)
		asoc->rwnd = SCTP_DEFAULT_MINWINDOW;
	else
		asoc->rwnd = sk->sk_rcvbuf;
		asoc->rwnd = sk->sk_rcvbuf/2;

	asoc->a_rwnd = asoc->rwnd;

@@ -192,6 +192,9 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
	/* Set the sndbuf size for transmit.  */
	asoc->sndbuf_used = 0;

	/* Initialize the receive memory counter */
	atomic_set(&asoc->rmem_alloc, 0);

	init_waitqueue_head(&asoc->wait);

	asoc->c.my_vtag = sctp_generate_tag(ep);
@@ -400,6 +403,8 @@ static void sctp_association_destroy(struct sctp_association *asoc)
		spin_unlock_bh(&sctp_assocs_id_lock);
	}

	BUG_TRAP(!atomic_read(&asoc->rmem_alloc));

	if (asoc->base.malloced) {
		kfree(asoc);
		SCTP_DBG_OBJCNT_DEC(assoc);
+3 −0
Original line number Diff line number Diff line
@@ -104,6 +104,9 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep,
	sk->sk_write_space = sctp_write_space;
	sock_set_flag(sk, SOCK_USE_WRITE_QUEUE);

	/* Get the receive buffer policy for this endpoint */
	ep->rcvbuf_policy = sctp_rcvbuf_policy;

	/* Initialize the secret key used with cookie. */
	get_random_bytes(&ep->secret_key[0], SCTP_SECRET_SIZE);
	ep->last_key = ep->current_key = 0;
+0 −20
Original line number Diff line number Diff line
@@ -100,21 +100,6 @@ static inline int sctp_rcv_checksum(struct sk_buff *skb)
	return 0;
}

/* The free routine for skbuffs that sctp receives */
static void sctp_rfree(struct sk_buff *skb)
{
	atomic_sub(sizeof(struct sctp_chunk),&skb->sk->sk_rmem_alloc);
	sock_rfree(skb);
}

/* The ownership wrapper routine to do receive buffer accounting */
static void sctp_rcv_set_owner_r(struct sk_buff *skb, struct sock *sk)
{
	skb_set_owner_r(skb,sk);
	skb->destructor = sctp_rfree;
	atomic_add(sizeof(struct sctp_chunk),&sk->sk_rmem_alloc);
}

struct sctp_input_cb {
	union {
		struct inet_skb_parm	h4;
@@ -217,9 +202,6 @@ int sctp_rcv(struct sk_buff *skb)
		rcvr = &ep->base;
	}

	if (atomic_read(&sk->sk_rmem_alloc) >= sk->sk_rcvbuf)
		goto discard_release;

	/*
	 * RFC 2960, 8.4 - Handle "Out of the blue" Packets.
	 * An SCTP packet is called an "out of the blue" (OOTB)
@@ -256,8 +238,6 @@ int sctp_rcv(struct sk_buff *skb)
	}
	SCTP_INPUT_CB(skb)->chunk = chunk;

	sctp_rcv_set_owner_r(skb,sk);

	/* Remember what endpoint is to handle this packet. */
	chunk->rcvr = rcvr;

Loading