diff options
Diffstat (limited to 'include/net')
| -rw-r--r-- | include/net/act_api.h | 2 | ||||
| -rw-r--r-- | include/net/bluetooth/rfcomm.h | 12 | ||||
| -rw-r--r-- | include/net/cfg80211.h | 5 | ||||
| -rw-r--r-- | include/net/gen_stats.h | 10 | ||||
| -rw-r--r-- | include/net/netfilter/xt_rateest.h | 2 | ||||
| -rw-r--r-- | include/net/rose.h | 2 | ||||
| -rw-r--r-- | include/net/sch_generic.h | 2 | ||||
| -rw-r--r-- | include/net/sock.h | 101 | ||||
| -rw-r--r-- | include/net/tcp.h | 5 | 
9 files changed, 118 insertions, 23 deletions
diff --git a/include/net/act_api.h b/include/net/act_api.h index 565eed8fe49..c05fd717c58 100644 --- a/include/net/act_api.h +++ b/include/net/act_api.h @@ -16,7 +16,7 @@ struct tcf_common {  	u32				tcfc_capab;  	int				tcfc_action;  	struct tcf_t			tcfc_tm; -	struct gnet_stats_basic		tcfc_bstats; +	struct gnet_stats_basic_packed	tcfc_bstats;  	struct gnet_stats_queue		tcfc_qstats;  	struct gnet_stats_rate_est	tcfc_rate_est;  	spinlock_t			tcfc_lock; diff --git a/include/net/bluetooth/rfcomm.h b/include/net/bluetooth/rfcomm.h index 80072611d26..c274993234e 100644 --- a/include/net/bluetooth/rfcomm.h +++ b/include/net/bluetooth/rfcomm.h @@ -355,7 +355,17 @@ struct rfcomm_dev_list_req {  };  int  rfcomm_dev_ioctl(struct sock *sk, unsigned int cmd, void __user *arg); + +#ifdef CONFIG_BT_RFCOMM_TTY  int  rfcomm_init_ttys(void);  void rfcomm_cleanup_ttys(void); - +#else +static inline int rfcomm_init_ttys(void) +{ +	return 0; +} +static inline void rfcomm_cleanup_ttys(void) +{ +} +#endif  #endif /* __RFCOMM_H */ diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 1a21895b732..d1892d66701 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -979,6 +979,10 @@ struct cfg80211_ops {   * 	channels at a later time. This can be used for devices which do not   * 	have calibration information gauranteed for frequencies or settings   * 	outside of its regulatory domain. + * @disable_beacon_hints: enable this if your driver needs to ensure that + *	passive scan flags and beaconing flags may not be lifted by cfg80211 + *	due to regulatory beacon hints. For more information on beacon + *	hints read the documenation for regulatory_hint_found_beacon()   * @reg_notifier: the driver's regulatory notification callback   * @regd: the driver's regulatory domain, if one was requested via   * 	the regulatory_hint() API. This can be used by the driver @@ -1004,6 +1008,7 @@ struct wiphy {  	bool custom_regulatory;  	bool strict_regulatory; +	bool disable_beacon_hints;  	enum cfg80211_signal_type signal_type; diff --git a/include/net/gen_stats.h b/include/net/gen_stats.h index d136b5240ef..c1488553e34 100644 --- a/include/net/gen_stats.h +++ b/include/net/gen_stats.h @@ -28,7 +28,7 @@ extern int gnet_stats_start_copy_compat(struct sk_buff *skb, int type,  					spinlock_t *lock, struct gnet_dump *d);  extern int gnet_stats_copy_basic(struct gnet_dump *d, -				 struct gnet_stats_basic *b); +				 struct gnet_stats_basic_packed *b);  extern int gnet_stats_copy_rate_est(struct gnet_dump *d,  				    struct gnet_stats_rate_est *r);  extern int gnet_stats_copy_queue(struct gnet_dump *d, @@ -37,14 +37,14 @@ extern int gnet_stats_copy_app(struct gnet_dump *d, void *st, int len);  extern int gnet_stats_finish_copy(struct gnet_dump *d); -extern int gen_new_estimator(struct gnet_stats_basic *bstats, +extern int gen_new_estimator(struct gnet_stats_basic_packed *bstats,  			     struct gnet_stats_rate_est *rate_est,  			     spinlock_t *stats_lock, struct nlattr *opt); -extern void gen_kill_estimator(struct gnet_stats_basic *bstats, +extern void gen_kill_estimator(struct gnet_stats_basic_packed *bstats,  			       struct gnet_stats_rate_est *rate_est); -extern int gen_replace_estimator(struct gnet_stats_basic *bstats, +extern int gen_replace_estimator(struct gnet_stats_basic_packed *bstats,  				 struct gnet_stats_rate_est *rate_est,  				 spinlock_t *stats_lock, struct nlattr *opt); -extern bool gen_estimator_active(const struct gnet_stats_basic *bstats, +extern bool gen_estimator_active(const struct gnet_stats_basic_packed *bstats,  				 const struct gnet_stats_rate_est *rate_est);  #endif diff --git a/include/net/netfilter/xt_rateest.h b/include/net/netfilter/xt_rateest.h index 65d594dffbf..ddbf37e1961 100644 --- a/include/net/netfilter/xt_rateest.h +++ b/include/net/netfilter/xt_rateest.h @@ -8,7 +8,7 @@ struct xt_rateest {  	spinlock_t			lock;  	struct gnet_estimator		params;  	struct gnet_stats_rate_est	rstats; -	struct gnet_stats_basic		bstats; +	struct gnet_stats_basic_packed	bstats;  };  extern struct xt_rateest *xt_rateest_lookup(const char *name); diff --git a/include/net/rose.h b/include/net/rose.h index cbd5364b2c8..5ba9f02731e 100644 --- a/include/net/rose.h +++ b/include/net/rose.h @@ -156,7 +156,7 @@ extern int  sysctl_rose_maximum_vcs;  extern int  sysctl_rose_window_size;  extern int  rosecmp(rose_address *, rose_address *);  extern int  rosecmpm(rose_address *, rose_address *, unsigned short); -extern const char *rose2asc(const rose_address *); +extern char *rose2asc(char *buf, const rose_address *);  extern struct sock *rose_find_socket(unsigned int, struct rose_neigh *);  extern void rose_kill_by_neigh(struct rose_neigh *);  extern unsigned int rose_new_lci(struct rose_neigh *); diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index 964ffa0d881..5482e9582f5 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -72,7 +72,7 @@ struct Qdisc  	 */  	unsigned long		state;  	struct sk_buff_head	q; -	struct gnet_stats_basic bstats; +	struct gnet_stats_basic_packed bstats;  	struct gnet_stats_queue	qstats;  }; diff --git a/include/net/sock.h b/include/net/sock.h index 352f06bbd7a..950409dcec3 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -54,6 +54,7 @@  #include <linux/filter.h>  #include <linux/rculist_nulls.h> +#include <linux/poll.h>  #include <asm/atomic.h>  #include <net/dst.h> @@ -103,15 +104,15 @@ struct net;  /**   *	struct sock_common - minimal network layer representation of sockets + *	@skc_node: main hash linkage for various protocol lookup tables + *	@skc_nulls_node: main hash linkage for UDP/UDP-Lite protocol + *	@skc_refcnt: reference count + *	@skc_hash: hash value used with various protocol lookup tables   *	@skc_family: network address family   *	@skc_state: Connection state   *	@skc_reuse: %SO_REUSEADDR setting   *	@skc_bound_dev_if: bound device index if != 0 - *	@skc_node: main hash linkage for various protocol lookup tables - *	@skc_nulls_node: main hash linkage for UDP/UDP-Lite protocol   *	@skc_bind_node: bind hash linkage for various protocol lookup tables - *	@skc_refcnt: reference count - *	@skc_hash: hash value used with various protocol lookup tables   *	@skc_prot: protocol handlers inside a network family   *	@skc_net: reference to the network namespace of this socket   * @@ -119,17 +120,21 @@ struct net;   *	for struct sock and struct inet_timewait_sock.   */  struct sock_common { -	unsigned short		skc_family; -	volatile unsigned char	skc_state; -	unsigned char		skc_reuse; -	int			skc_bound_dev_if; +	/* +	 * first fields are not copied in sock_copy() +	 */  	union {  		struct hlist_node	skc_node;  		struct hlist_nulls_node skc_nulls_node;  	}; -	struct hlist_node	skc_bind_node;  	atomic_t		skc_refcnt; +  	unsigned int		skc_hash; +	unsigned short		skc_family; +	volatile unsigned char	skc_state; +	unsigned char		skc_reuse; +	int			skc_bound_dev_if; +	struct hlist_node	skc_bind_node;  	struct proto		*skc_prot;  #ifdef CONFIG_NET_NS  	struct net	 	*skc_net; @@ -207,15 +212,17 @@ struct sock {  	 * don't add nothing before this first member (__sk_common) --acme  	 */  	struct sock_common	__sk_common; +#define sk_node			__sk_common.skc_node +#define sk_nulls_node		__sk_common.skc_nulls_node +#define sk_refcnt		__sk_common.skc_refcnt + +#define sk_copy_start		__sk_common.skc_hash +#define sk_hash			__sk_common.skc_hash  #define sk_family		__sk_common.skc_family  #define sk_state		__sk_common.skc_state  #define sk_reuse		__sk_common.skc_reuse  #define sk_bound_dev_if		__sk_common.skc_bound_dev_if -#define sk_node			__sk_common.skc_node -#define sk_nulls_node		__sk_common.skc_nulls_node  #define sk_bind_node		__sk_common.skc_bind_node -#define sk_refcnt		__sk_common.skc_refcnt -#define sk_hash			__sk_common.skc_hash  #define sk_prot			__sk_common.skc_prot  #define sk_net			__sk_common.skc_net  	kmemcheck_bitfield_begin(flags); @@ -1241,6 +1248,74 @@ static inline int sk_has_allocations(const struct sock *sk)  	return sk_wmem_alloc_get(sk) || sk_rmem_alloc_get(sk);  } +/** + * sk_has_sleeper - check if there are any waiting processes + * @sk: socket + * + * Returns true if socket has waiting processes + * + * The purpose of the sk_has_sleeper and sock_poll_wait is to wrap the memory + * barrier call. They were added due to the race found within the tcp code. + * + * Consider following tcp code paths: + * + * CPU1                  CPU2 + * + * sys_select            receive packet + *   ...                 ... + *   __add_wait_queue    update tp->rcv_nxt + *   ...                 ... + *   tp->rcv_nxt check   sock_def_readable + *   ...                 { + *   schedule               ... + *                          if (sk->sk_sleep && waitqueue_active(sk->sk_sleep)) + *                              wake_up_interruptible(sk->sk_sleep) + *                          ... + *                       } + * + * The race for tcp fires when the __add_wait_queue changes done by CPU1 stay + * in its cache, and so does the tp->rcv_nxt update on CPU2 side.  The CPU1 + * could then endup calling schedule and sleep forever if there are no more + * data on the socket. + * + * The sk_has_sleeper is always called right after a call to read_lock, so we + * can use smp_mb__after_lock barrier. + */ +static inline int sk_has_sleeper(struct sock *sk) +{ +	/* +	 * We need to be sure we are in sync with the +	 * add_wait_queue modifications to the wait queue. +	 * +	 * This memory barrier is paired in the sock_poll_wait. +	 */ +	smp_mb__after_lock(); +	return sk->sk_sleep && waitqueue_active(sk->sk_sleep); +} + +/** + * sock_poll_wait - place memory barrier behind the poll_wait call. + * @filp:           file + * @wait_address:   socket wait queue + * @p:              poll_table + * + * See the comments in the sk_has_sleeper function. + */ +static inline void sock_poll_wait(struct file *filp, +		wait_queue_head_t *wait_address, poll_table *p) +{ +	if (p && wait_address) { +		poll_wait(filp, wait_address, p); +		/* +		 * We need to be sure we are in sync with the +		 * socket flags modification. +		 * +		 * This memory barrier is paired in the sk_has_sleeper. +		*/ +		smp_mb(); +	} +} +  /*   * 	Queue a received datagram if it will fit. Stream and sequenced   *	protocols can't normally use this as they need to fit buffers in diff --git a/include/net/tcp.h b/include/net/tcp.h index 19f4150f4d4..88af8430647 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -1425,6 +1425,11 @@ struct tcp_request_sock_ops {  #ifdef CONFIG_TCP_MD5SIG  	struct tcp_md5sig_key	*(*md5_lookup) (struct sock *sk,  						struct request_sock *req); +	int			(*calc_md5_hash) (char *location, +						  struct tcp_md5sig_key *md5, +						  struct sock *sk, +						  struct request_sock *req, +						  struct sk_buff *skb);  #endif  };  |