diff options
Diffstat (limited to 'include/net/sock.h')
| -rw-r--r-- | include/net/sock.h | 20 | 
1 files changed, 17 insertions, 3 deletions
diff --git a/include/net/sock.h b/include/net/sock.h index 6cb1676e409..1ad6435f252 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -51,6 +51,7 @@  #include <linux/skbuff.h>	/* struct sk_buff */  #include <linux/mm.h>  #include <linux/security.h> +#include <linux/slab.h>  #include <linux/filter.h>  #include <linux/rculist_nulls.h> @@ -73,7 +74,7 @@  					printk(KERN_DEBUG msg); } while (0)  #else  /* Validate arguments and do nothing */ -static void inline int __attribute__ ((format (printf, 2, 3))) +static inline void __attribute__ ((format (printf, 2, 3)))  SOCK_DEBUG(struct sock *sk, const char *msg, ...)  {  } @@ -253,6 +254,8 @@ struct sock {  	struct {  		struct sk_buff *head;  		struct sk_buff *tail; +		int len; +		int limit;  	} sk_backlog;  	wait_queue_head_t	*sk_sleep;  	struct dst_entry	*sk_dst_cache; @@ -589,8 +592,8 @@ static inline int sk_stream_memory_free(struct sock *sk)  	return sk->sk_wmem_queued < sk->sk_sndbuf;  } -/* The per-socket spinlock must be held here. */ -static inline void sk_add_backlog(struct sock *sk, struct sk_buff *skb) +/* OOB backlog add */ +static inline void __sk_add_backlog(struct sock *sk, struct sk_buff *skb)  {  	if (!sk->sk_backlog.tail) {  		sk->sk_backlog.head = sk->sk_backlog.tail = skb; @@ -601,6 +604,17 @@ static inline void sk_add_backlog(struct sock *sk, struct sk_buff *skb)  	skb->next = NULL;  } +/* The per-socket spinlock must be held here. */ +static inline __must_check int sk_add_backlog(struct sock *sk, struct sk_buff *skb) +{ +	if (sk->sk_backlog.len >= max(sk->sk_backlog.limit, sk->sk_rcvbuf << 1)) +		return -ENOBUFS; + +	__sk_add_backlog(sk, skb); +	sk->sk_backlog.len += skb->truesize; +	return 0; +} +  static inline int sk_backlog_rcv(struct sock *sk, struct sk_buff *skb)  {  	return sk->sk_backlog_rcv(sk, skb);  |