diff options
Diffstat (limited to 'include/net')
53 files changed, 1379 insertions, 435 deletions
| diff --git a/include/net/act_api.h b/include/net/act_api.h index c739531e1564..06ef7e926a66 100644 --- a/include/net/act_api.h +++ b/include/net/act_api.h @@ -35,21 +35,6 @@ struct tcf_common {  #define tcf_lock	common.tcfc_lock  #define tcf_rcu		common.tcfc_rcu -struct tcf_police { -	struct tcf_common	common; -	int			tcfp_result; -	u32			tcfp_ewma_rate; -	u32			tcfp_burst; -	u32			tcfp_mtu; -	u32			tcfp_toks; -	u32			tcfp_ptoks; -	psched_time_t		tcfp_t_c; -	struct qdisc_rate_table	*tcfp_R_tab; -	struct qdisc_rate_table	*tcfp_P_tab; -}; -#define to_police(pc)	\ -	container_of(pc, struct tcf_police, common) -  struct tcf_hashinfo {  	struct tcf_common	**htab;  	unsigned int		hmask; @@ -91,7 +76,9 @@ struct tc_action_ops {  	int     (*dump)(struct sk_buff *, struct tc_action *, int, int);  	int     (*cleanup)(struct tc_action *, int bind);  	int     (*lookup)(struct tc_action *, u32); -	int     (*init)(struct nlattr *, struct nlattr *, struct tc_action *, int , int); +	int     (*init)(struct net *net, struct nlattr *nla, +			struct nlattr *est, struct tc_action *act, int ovr, +			int bind);  	int     (*walk)(struct sk_buff *, struct netlink_callback *, int, struct tc_action *);  }; @@ -116,8 +103,12 @@ extern int tcf_register_action(struct tc_action_ops *a);  extern int tcf_unregister_action(struct tc_action_ops *a);  extern void tcf_action_destroy(struct tc_action *a, int bind);  extern int tcf_action_exec(struct sk_buff *skb, const struct tc_action *a, struct tcf_result *res); -extern struct tc_action *tcf_action_init(struct nlattr *nla, struct nlattr *est, char *n, int ovr, int bind); -extern struct tc_action *tcf_action_init_1(struct nlattr *nla, struct nlattr *est, char *n, int ovr, int bind); +extern struct tc_action *tcf_action_init(struct net *net, struct nlattr *nla, +					 struct nlattr *est, char *n, int ovr, +					 int bind); +extern struct tc_action *tcf_action_init_1(struct net *net, struct nlattr *nla, +					   struct nlattr *est, char *n, int ovr, +					   int bind);  extern int tcf_action_dump(struct sk_buff *skb, struct tc_action *a, int, int);  extern int tcf_action_dump_old(struct sk_buff *skb, struct tc_action *a, int, int);  extern int tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int, int); diff --git a/include/net/addrconf.h b/include/net/addrconf.h index df4ef9453384..40be2a0d8ae1 100644 --- a/include/net/addrconf.h +++ b/include/net/addrconf.h @@ -15,6 +15,10 @@  #define IPV6_MAX_ADDRESSES		16 +#define ADDRCONF_TIMER_FUZZ_MINUS	(HZ > 50 ? HZ / 50 : 1) +#define ADDRCONF_TIMER_FUZZ		(HZ / 4) +#define ADDRCONF_TIMER_FUZZ_MAX		(HZ) +  #include <linux/in.h>  #include <linux/in6.h> @@ -150,7 +154,31 @@ extern void addrconf_dad_failure(struct inet6_ifaddr *ifp);  extern bool ipv6_chk_mcast_addr(struct net_device *dev,  				const struct in6_addr *group,  				const struct in6_addr *src_addr); -extern bool ipv6_is_mld(struct sk_buff *skb, int nexthdr); + +/* + * identify MLD packets for MLD filter exceptions + */ +static inline bool ipv6_is_mld(struct sk_buff *skb, int nexthdr, int offset) +{ +	struct icmp6hdr *hdr; + +	if (nexthdr != IPPROTO_ICMPV6 || +	    !pskb_network_may_pull(skb, offset + sizeof(struct icmp6hdr))) +		return false; + +	hdr = (struct icmp6hdr *)(skb_network_header(skb) + offset); + +	switch (hdr->icmp6_type) { +	case ICMPV6_MGM_QUERY: +	case ICMPV6_MGM_REPORT: +	case ICMPV6_MGM_REDUCTION: +	case ICMPV6_MLD2_REPORT: +		return true; +	default: +		break; +	} +	return false; +}  extern void addrconf_prefix_rcv(struct net_device *dev,  				u8 *opt, int len, bool sllao); @@ -257,30 +285,55 @@ static inline void addrconf_addr_solict_mult(const struct in6_addr *addr,  		      htonl(0xFF000000) | addr->s6_addr32[3]);  } -static inline int ipv6_addr_is_multicast(const struct in6_addr *addr) +static inline bool ipv6_addr_is_multicast(const struct in6_addr *addr)  {  	return (addr->s6_addr32[0] & htonl(0xFF000000)) == htonl(0xFF000000);  } -static inline int ipv6_addr_is_ll_all_nodes(const struct in6_addr *addr) +static inline bool ipv6_addr_is_ll_all_nodes(const struct in6_addr *addr)  { +#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64 +	__u64 *p = (__u64 *)addr; +	return ((p[0] ^ cpu_to_be64(0xff02000000000000UL)) | (p[1] ^ cpu_to_be64(1))) == 0UL; +#else  	return ((addr->s6_addr32[0] ^ htonl(0xff020000)) |  		addr->s6_addr32[1] | addr->s6_addr32[2] |  		(addr->s6_addr32[3] ^ htonl(0x00000001))) == 0; +#endif  } -static inline int ipv6_addr_is_ll_all_routers(const struct in6_addr *addr) +static inline bool ipv6_addr_is_ll_all_routers(const struct in6_addr *addr)  { +#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64 +	__u64 *p = (__u64 *)addr; +	return ((p[0] ^ cpu_to_be64(0xff02000000000000UL)) | (p[1] ^ cpu_to_be64(2))) == 0UL; +#else  	return ((addr->s6_addr32[0] ^ htonl(0xff020000)) |  		addr->s6_addr32[1] | addr->s6_addr32[2] |  		(addr->s6_addr32[3] ^ htonl(0x00000002))) == 0; +#endif  } -static inline int ipv6_addr_is_isatap(const struct in6_addr *addr) +static inline bool ipv6_addr_is_isatap(const struct in6_addr *addr)  {  	return (addr->s6_addr32[2] | htonl(0x02000000)) == htonl(0x02005EFE);  } +static inline bool ipv6_addr_is_solict_mult(const struct in6_addr *addr) +{ +#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64 +	__u64 *p = (__u64 *)addr; +	return ((p[0] ^ cpu_to_be64(0xff02000000000000UL)) | +		((p[1] ^ cpu_to_be64(0x00000001ff000000UL)) & +		 cpu_to_be64(0xffffffffff000000UL))) == 0UL; +#else +	return ((addr->s6_addr32[0] ^ htonl(0xff020000)) | +		addr->s6_addr32[1] | +		(addr->s6_addr32[2] ^ htonl(0x00000001)) | +		(addr->s6_addr[12] ^ 0xff)) == 0; +#endif +} +  #ifdef CONFIG_PROC_FS  extern int if6_proc_init(void);  extern void if6_proc_exit(void); diff --git a/include/net/bluetooth/a2mp.h b/include/net/bluetooth/a2mp.h index 42f21766c538..487b54c1308f 100644 --- a/include/net/bluetooth/a2mp.h +++ b/include/net/bluetooth/a2mp.h @@ -23,6 +23,7 @@ enum amp_mgr_state {  	READ_LOC_AMP_INFO,  	READ_LOC_AMP_ASSOC,  	READ_LOC_AMP_ASSOC_FINAL, +	WRITE_REMOTE_AMP_ASSOC,  };  struct amp_mgr { @@ -33,7 +34,7 @@ struct amp_mgr {  	struct kref		kref;  	__u8			ident;  	__u8			handle; -	enum amp_mgr_state	state; +	unsigned long		state;  	unsigned long		flags;  	struct list_head	amp_ctrls; @@ -144,5 +145,6 @@ void a2mp_discover_amp(struct l2cap_chan *chan);  void a2mp_send_getinfo_rsp(struct hci_dev *hdev);  void a2mp_send_getampassoc_rsp(struct hci_dev *hdev, u8 status);  void a2mp_send_create_phy_link_req(struct hci_dev *hdev, u8 status); +void a2mp_send_create_phy_link_rsp(struct hci_dev *hdev, u8 status);  #endif /* __A2MP_H */ diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h index 2554b3f5222a..9531beee09b5 100644 --- a/include/net/bluetooth/bluetooth.h +++ b/include/net/bluetooth/bluetooth.h @@ -166,6 +166,29 @@ typedef struct {  #define BDADDR_LE_PUBLIC	0x01  #define BDADDR_LE_RANDOM	0x02 +static inline bool bdaddr_type_is_valid(__u8 type) +{ +	switch (type) { +	case BDADDR_BREDR: +	case BDADDR_LE_PUBLIC: +	case BDADDR_LE_RANDOM: +		return true; +	} + +	return false; +} + +static inline bool bdaddr_type_is_le(__u8 type) +{ +	switch (type) { +	case BDADDR_LE_PUBLIC: +	case BDADDR_LE_RANDOM: +		return true; +	} + +	return false; +} +  #define BDADDR_ANY   (&(bdaddr_t) {{0, 0, 0, 0, 0, 0} })  #define BDADDR_LOCAL (&(bdaddr_t) {{0, 0, 0, 0xff, 0xff, 0xff} }) diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index 45eee08157bb..7f12c25f1fca 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -943,6 +943,12 @@ struct hci_rp_le_read_buffer_size {  	__u8     le_max_pkt;  } __packed; +#define HCI_OP_LE_READ_LOCAL_FEATURES	0x2003 +struct hci_rp_le_read_local_features { +	__u8     status; +	__u8     features[8]; +} __packed; +  #define HCI_OP_LE_READ_ADV_TX_POWER	0x2007  struct hci_rp_le_read_adv_tx_power {  	__u8	status; @@ -995,6 +1001,12 @@ struct hci_cp_le_create_conn {  #define HCI_OP_LE_CREATE_CONN_CANCEL	0x200e +#define HCI_OP_LE_READ_WHITE_LIST_SIZE	0x200f +struct hci_rp_le_read_white_list_size { +	__u8	status; +	__u8	size; +} __packed; +  #define HCI_OP_LE_CONN_UPDATE		0x2013  struct hci_cp_le_conn_update {  	__le16   handle; @@ -1033,6 +1045,12 @@ struct hci_rp_le_ltk_neg_reply {  	__le16	handle;  } __packed; +#define HCI_OP_LE_READ_SUPPORTED_STATES	0x201c +struct hci_rp_le_read_supported_states { +	__u8	status; +	__u8	le_states[8]; +} __packed; +  /* ---- HCI Events ---- */  #define HCI_EV_INQUIRY_COMPLETE		0x01 diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 014a2eaa5389..90cf75afcb02 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -86,6 +86,7 @@ struct bdaddr_list {  struct bt_uuid {  	struct list_head list;  	u8 uuid[16]; +	u8 size;  	u8 svc_hint;  }; @@ -152,6 +153,9 @@ struct hci_dev {  	__u8		minor_class;  	__u8		features[8];  	__u8		host_features[8]; +	__u8		le_features[8]; +	__u8		le_white_list_size; +	__u8		le_states[8];  	__u8		commands[64];  	__u8		hci_ver;  	__u16		hci_rev; @@ -216,6 +220,7 @@ struct hci_dev {  	unsigned long	le_last_tx;  	struct workqueue_struct	*workqueue; +	struct workqueue_struct	*req_workqueue;  	struct work_struct	power_on;  	struct delayed_work	power_off; diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 7588ef44ebaf..cdd33021f831 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -496,7 +496,6 @@ struct l2cap_chan {  	__u16		frames_sent;  	__u16		unacked_frames;  	__u8		retry_count; -	__u16		srej_queue_next;  	__u16		sdu_len;  	struct sk_buff	*sdu;  	struct sk_buff	*sdu_last_frag; diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 8e6a6b73b9c9..d581c6de5d64 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -19,6 +19,7 @@  #include <linux/nl80211.h>  #include <linux/if_ether.h>  #include <linux/ieee80211.h> +#include <linux/net.h>  #include <net/regulatory.h>  /** @@ -99,6 +100,16 @@ enum ieee80211_band {   * @IEEE80211_CHAN_NO_HT40MINUS: extension channel below this channel   * 	is not permitted.   * @IEEE80211_CHAN_NO_OFDM: OFDM is not allowed on this channel. + * @IEEE80211_CHAN_NO_80MHZ: If the driver supports 80 MHz on the band, + *	this flag indicates that an 80 MHz channel cannot use this + *	channel as the control or any of the secondary channels. + *	This may be due to the driver or due to regulatory bandwidth + *	restrictions. + * @IEEE80211_CHAN_NO_160MHZ: If the driver supports 160 MHz on the band, + *	this flag indicates that an 160 MHz channel cannot use this + *	channel as the control or any of the secondary channels. + *	This may be due to the driver or due to regulatory bandwidth + *	restrictions.   */  enum ieee80211_channel_flags {  	IEEE80211_CHAN_DISABLED		= 1<<0, @@ -108,11 +119,16 @@ enum ieee80211_channel_flags {  	IEEE80211_CHAN_NO_HT40PLUS	= 1<<4,  	IEEE80211_CHAN_NO_HT40MINUS	= 1<<5,  	IEEE80211_CHAN_NO_OFDM		= 1<<6, +	IEEE80211_CHAN_NO_80MHZ		= 1<<7, +	IEEE80211_CHAN_NO_160MHZ	= 1<<8,  };  #define IEEE80211_CHAN_NO_HT40 \  	(IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS) +#define IEEE80211_DFS_MIN_CAC_TIME_MS		60000 +#define IEEE80211_DFS_MIN_NOP_TIME_MS		(30 * 60 * 1000) +  /**   * struct ieee80211_channel - channel definition   * @@ -133,6 +149,9 @@ enum ieee80211_channel_flags {   *	to enable this, this is useful only on 5 GHz band.   * @orig_mag: internal use   * @orig_mpwr: internal use + * @dfs_state: current state of this channel. Only relevant if radar is required + *	on this channel. + * @dfs_state_entered: timestamp (jiffies) when the dfs state was entered.   */  struct ieee80211_channel {  	enum ieee80211_band band; @@ -145,6 +164,8 @@ struct ieee80211_channel {  	bool beacon_found;  	u32 orig_flags;  	int orig_mag, orig_mpwr; +	enum nl80211_dfs_state dfs_state; +	unsigned long dfs_state_entered;  };  /** @@ -281,9 +302,13 @@ struct ieee80211_supported_band {  /**   * struct vif_params - describes virtual interface parameters   * @use_4addr: use 4-address frames + * @macaddr: address to use for this virtual interface. This will only + * 	be used for non-netdevice interfaces. If this parameter is set + * 	to zero address the driver may determine the address as needed.   */  struct vif_params {         int use_4addr; +       u8 macaddr[ETH_ALEN];  };  /** @@ -326,7 +351,7 @@ struct cfg80211_chan_def {   * cfg80211_get_chandef_type - return old channel type from chandef   * @chandef: the channel definition   * - * Returns the old channel type (NOHT, HT20, HT40+/-) from a given + * Return: The old channel type (NOHT, HT20, HT40+/-) from a given   * chandef, which must have a bandwidth allowing this conversion.   */  static inline enum nl80211_channel_type @@ -364,7 +389,7 @@ void cfg80211_chandef_create(struct cfg80211_chan_def *chandef,   * @chandef1: first channel definition   * @chandef2: second channel definition   * - * Returns %true if the channels defined by the channel definitions are + * Return: %true if the channels defined by the channel definitions are   * identical, %false otherwise.   */  static inline bool @@ -382,7 +407,7 @@ cfg80211_chandef_identical(const struct cfg80211_chan_def *chandef1,   * @chandef1: first channel definition   * @chandef2: second channel definition   * - * Returns %NULL if the given channel definitions are incompatible, + * Return: %NULL if the given channel definitions are incompatible,   * chandef1 or chandef2 otherwise.   */  const struct cfg80211_chan_def * @@ -392,6 +417,7 @@ cfg80211_chandef_compatible(const struct cfg80211_chan_def *chandef1,  /**   * cfg80211_chandef_valid - check if a channel definition is valid   * @chandef: the channel definition to check + * Return: %true if the channel definition is valid. %false otherwise.   */  bool cfg80211_chandef_valid(const struct cfg80211_chan_def *chandef); @@ -399,7 +425,8 @@ bool cfg80211_chandef_valid(const struct cfg80211_chan_def *chandef);   * cfg80211_chandef_usable - check if secondary channels can be used   * @wiphy: the wiphy to validate against   * @chandef: the channel definition to check - * @prohibited_flags: the regulatory chanenl flags that must not be set + * @prohibited_flags: the regulatory channel flags that must not be set + * Return: %true if secondary channels are usable. %false otherwise.   */  bool cfg80211_chandef_usable(struct wiphy *wiphy,  			     const struct cfg80211_chan_def *chandef, @@ -521,6 +548,26 @@ struct cfg80211_beacon_data {  	size_t probe_resp_len;  }; +struct mac_address { +	u8 addr[ETH_ALEN]; +}; + +/** + * struct cfg80211_acl_data - Access control list data + * + * @acl_policy: ACL policy to be applied on the station's + *	entry specified by mac_addr + * @n_acl_entries: Number of MAC address entries passed + * @mac_addrs: List of MAC addresses of stations to be used for ACL + */ +struct cfg80211_acl_data { +	enum nl80211_acl_policy acl_policy; +	int n_acl_entries; + +	/* Keep it last */ +	struct mac_address mac_addrs[]; +}; +  /**   * struct cfg80211_ap_settings - AP configuration   * @@ -540,6 +587,9 @@ struct cfg80211_beacon_data {   * @inactivity_timeout: time in seconds to determine station's inactivity.   * @p2p_ctwindow: P2P CT Window   * @p2p_opp_ps: P2P opportunistic PS + * @acl: ACL configuration used by the drivers which has support for + *	MAC address based access control + * @radar_required: set if radar detection is required   */  struct cfg80211_ap_settings {  	struct cfg80211_chan_def chandef; @@ -556,6 +606,8 @@ struct cfg80211_ap_settings {  	int inactivity_timeout;  	u8 p2p_ctwindow;  	bool p2p_opp_ps; +	const struct cfg80211_acl_data *acl; +	bool radar_required;  };  /** @@ -574,12 +626,14 @@ enum plink_actions {  /**   * enum station_parameters_apply_mask - station parameter values to apply   * @STATION_PARAM_APPLY_UAPSD: apply new uAPSD parameters (uapsd_queues, max_sp) + * @STATION_PARAM_APPLY_CAPABILITY: apply new capability   *   * Not all station parameters have in-band "no change" signalling,   * for those that don't these flags will are used.   */  enum station_parameters_apply_mask {  	STATION_PARAM_APPLY_UAPSD = BIT(0), +	STATION_PARAM_APPLY_CAPABILITY = BIT(1),  };  /** @@ -608,6 +662,11 @@ enum station_parameters_apply_mask {   * @sta_modify_mask: bitmap indicating which parameters changed   *	(for those that don't have a natural "no change" value),   *	see &enum station_parameters_apply_mask + * @local_pm: local link-specific mesh power save mode (no change when set + *	to unknown) + * @capability: station capability + * @ext_capab: extended capabilities of the station + * @ext_capab_len: number of extended capabilities   */  struct station_parameters {  	u8 *supported_rates; @@ -623,6 +682,10 @@ struct station_parameters {  	struct ieee80211_vht_cap *vht_capa;  	u8 uapsd_queues;  	u8 max_sp; +	enum nl80211_mesh_power_mode local_pm; +	u16 capability; +	u8 *ext_capab; +	u8 ext_capab_len;  };  /** @@ -634,14 +697,16 @@ struct station_parameters {   * @STATION_INFO_INACTIVE_TIME: @inactive_time filled   * @STATION_INFO_RX_BYTES: @rx_bytes filled   * @STATION_INFO_TX_BYTES: @tx_bytes filled + * @STATION_INFO_RX_BYTES64: @rx_bytes filled with 64-bit value + * @STATION_INFO_TX_BYTES64: @tx_bytes filled with 64-bit value   * @STATION_INFO_LLID: @llid filled   * @STATION_INFO_PLID: @plid filled   * @STATION_INFO_PLINK_STATE: @plink_state filled   * @STATION_INFO_SIGNAL: @signal filled   * @STATION_INFO_TX_BITRATE: @txrate fields are filled   *  (tx_bitrate, tx_bitrate_flags and tx_bitrate_mcs) - * @STATION_INFO_RX_PACKETS: @rx_packets filled - * @STATION_INFO_TX_PACKETS: @tx_packets filled + * @STATION_INFO_RX_PACKETS: @rx_packets filled with 32-bit value + * @STATION_INFO_TX_PACKETS: @tx_packets filled with 32-bit value   * @STATION_INFO_TX_RETRIES: @tx_retries filled   * @STATION_INFO_TX_FAILED: @tx_failed filled   * @STATION_INFO_RX_DROP_MISC: @rx_dropped_misc filled @@ -653,6 +718,9 @@ struct station_parameters {   * @STATION_INFO_STA_FLAGS: @sta_flags filled   * @STATION_INFO_BEACON_LOSS_COUNT: @beacon_loss_count filled   * @STATION_INFO_T_OFFSET: @t_offset filled + * @STATION_INFO_LOCAL_PM: @local_pm filled + * @STATION_INFO_PEER_PM: @peer_pm filled + * @STATION_INFO_NONPEER_PM: @nonpeer_pm filled   */  enum station_info_flags {  	STATION_INFO_INACTIVE_TIME	= 1<<0, @@ -676,6 +744,11 @@ enum station_info_flags {  	STATION_INFO_STA_FLAGS		= 1<<18,  	STATION_INFO_BEACON_LOSS_COUNT	= 1<<19,  	STATION_INFO_T_OFFSET		= 1<<20, +	STATION_INFO_LOCAL_PM		= 1<<21, +	STATION_INFO_PEER_PM		= 1<<22, +	STATION_INFO_NONPEER_PM		= 1<<23, +	STATION_INFO_RX_BYTES64		= 1<<24, +	STATION_INFO_TX_BYTES64		= 1<<25,  };  /** @@ -789,13 +862,16 @@ struct sta_bss_parameters {   * @sta_flags: station flags mask & values   * @beacon_loss_count: Number of times beacon loss event has triggered.   * @t_offset: Time offset of the station relative to this host. + * @local_pm: local mesh STA power save mode + * @peer_pm: peer mesh STA power save mode + * @nonpeer_pm: non-peer mesh STA power save mode   */  struct station_info {  	u32 filled;  	u32 connected_time;  	u32 inactive_time; -	u32 rx_bytes; -	u32 tx_bytes; +	u64 rx_bytes; +	u64 tx_bytes;  	u16 llid;  	u16 plid;  	u8 plink_state; @@ -818,6 +894,9 @@ struct station_info {  	u32 beacon_loss_count;  	s64 t_offset; +	enum nl80211_mesh_power_mode local_pm; +	enum nl80211_mesh_power_mode peer_pm; +	enum nl80211_mesh_power_mode nonpeer_pm;  	/*  	 * Note: Add a new enum station_info_flags value for each new field and @@ -993,6 +1072,10 @@ struct bss_parameters {   * @dot11MeshHWMPconfirmationInterval: The minimum interval of time (in TUs)   *	during which a mesh STA can send only one Action frame containing   *	a PREQ element for root path confirmation. + * @power_mode: The default mesh power save mode which will be the initial + *	setting for new peer links. + * @dot11MeshAwakeWindowDuration: The duration in TUs the STA will remain awake + *	after transmitting its beacon.   */  struct mesh_config {  	u16 dot11MeshRetryTimeout; @@ -1020,6 +1103,8 @@ struct mesh_config {  	u32 dot11MeshHWMPactivePathToRootTimeout;  	u16 dot11MeshHWMProotInterval;  	u16 dot11MeshHWMPconfirmationInterval; +	enum nl80211_mesh_power_mode power_mode; +	u16 dot11MeshAwakeWindowDuration;  };  /** @@ -1034,6 +1119,8 @@ struct mesh_config {   * @ie_len: length of vendor information elements   * @is_authenticated: this mesh requires authentication   * @is_secure: this mesh uses security + * @dtim_period: DTIM period to use + * @beacon_interval: beacon interval to use   * @mcast_rate: multicat rate for Mesh Node [6Mbps is the default for 802.11a]   *   * These parameters are fixed when the mesh is created. @@ -1049,6 +1136,8 @@ struct mesh_setup {  	u8 ie_len;  	bool is_authenticated;  	bool is_secure; +	u8 dtim_period; +	u16 beacon_interval;  	int mcast_rate[IEEE80211_NUM_BANDS];  }; @@ -1168,6 +1257,7 @@ struct cfg80211_match_set {   * @n_match_sets: number of match sets   * @wiphy: the wiphy this was for   * @dev: the interface + * @scan_start: start time of the scheduled scan   * @channels: channels to scan   * @rssi_thold: don't report scan results below this threshold (in s32 dBm)   */ @@ -1207,11 +1297,13 @@ enum cfg80211_signal_type {  /**   * struct cfg80211_bss_ie_data - BSS entry IE data + * @tsf: TSF contained in the frame that carried these IEs   * @rcu_head: internal use, for freeing   * @len: length of the IEs   * @data: IE data   */  struct cfg80211_bss_ies { +	u64 tsf;  	struct rcu_head rcu_head;  	int len;  	u8 data[]; @@ -1225,29 +1317,32 @@ struct cfg80211_bss_ies {   *   * @channel: channel this BSS is on   * @bssid: BSSID of the BSS - * @tsf: timestamp of last received update   * @beacon_interval: the beacon interval as from the frame   * @capability: the capability field in host byte order - * @ies: the information elements (Note that there - *	is no guarantee that these are well-formed!); this is a pointer to - *	either the beacon_ies or proberesp_ies depending on whether Probe - *	Response frame has been received + * @ies: the information elements (Note that there is no guarantee that these + *	are well-formed!); this is a pointer to either the beacon_ies or + *	proberesp_ies depending on whether Probe Response frame has been + *	received. It is always non-%NULL.   * @beacon_ies: the information elements from the last Beacon frame + *	(implementation note: if @hidden_beacon_bss is set this struct doesn't + *	own the beacon_ies, but they're just pointers to the ones from the + *	@hidden_beacon_bss struct)   * @proberesp_ies: the information elements from the last Probe Response frame + * @hidden_beacon_bss: in case this BSS struct represents a probe response from + *	a BSS that hides the SSID in its beacon, this points to the BSS struct + *	that holds the beacon data. @beacon_ies is still valid, of course, and + *	points to the same data as hidden_beacon_bss->beacon_ies in that case.   * @signal: signal strength value (type depends on the wiphy's signal_type) - * @free_priv: function pointer to free private data   * @priv: private area for driver use, has at least wiphy->bss_priv_size bytes   */  struct cfg80211_bss { -	u64 tsf; -  	struct ieee80211_channel *channel;  	const struct cfg80211_bss_ies __rcu *ies;  	const struct cfg80211_bss_ies __rcu *beacon_ies;  	const struct cfg80211_bss_ies __rcu *proberesp_ies; -	void (*free_priv)(struct cfg80211_bss *bss); +	struct cfg80211_bss *hidden_beacon_bss;  	s32 signal; @@ -1256,7 +1351,7 @@ struct cfg80211_bss {  	u8 bssid[ETH_ALEN]; -	u8 priv[0] __attribute__((__aligned__(sizeof(void *)))); +	u8 priv[0] __aligned(sizeof(void *));  };  /** @@ -1266,7 +1361,7 @@ struct cfg80211_bss {   *   * Note that the return value is an RCU-protected pointer, so   * rcu_read_lock() must be held when calling this function. - * Returns %NULL if not found. + * Return: %NULL if not found.   */  const u8 *ieee80211_bss_get_ie(struct cfg80211_bss *bss, u8 ie); @@ -1349,6 +1444,8 @@ struct cfg80211_assoc_request {   * @ie: Extra IEs to add to Deauthentication frame or %NULL   * @ie_len: Length of ie buffer in octets   * @reason_code: The reason code for the deauthentication + * @local_state_change: if set, change local state only and + *	do not set a deauth frame   */  struct cfg80211_deauth_request {  	const u8 *bssid; @@ -1434,6 +1531,7 @@ struct cfg80211_ibss_params {   * @ie: IEs for association request   * @ie_len: Length of assoc_ie in octets   * @privacy: indicates whether privacy-enabled APs should be used + * @mfp: indicate whether management frame protection is used   * @crypto: crypto settings   * @key_len: length of WEP key for shared key authentication   * @key_idx: index of WEP key for shared key authentication @@ -1454,6 +1552,7 @@ struct cfg80211_connect_params {  	u8 *ie;  	size_t ie_len;  	bool privacy; +	enum nl80211_mfp mfp;  	struct cfg80211_crypto_settings crypto;  	const u8 *key;  	u8 key_len, key_idx; @@ -1508,6 +1607,7 @@ struct cfg80211_pmksa {   *	one bit per byte, in same format as nl80211   * @pattern: bytes to match where bitmask is 1   * @pattern_len: length of pattern (in bytes) + * @pkt_offset: packet offset (in bytes)   *   * Internal note: @mask and @pattern are allocated in one chunk of   * memory, free @mask only! @@ -1515,6 +1615,42 @@ struct cfg80211_pmksa {  struct cfg80211_wowlan_trig_pkt_pattern {  	u8 *mask, *pattern;  	int pattern_len; +	int pkt_offset; +}; + +/** + * struct cfg80211_wowlan_tcp - TCP connection parameters + * + * @sock: (internal) socket for source port allocation + * @src: source IP address + * @dst: destination IP address + * @dst_mac: destination MAC address + * @src_port: source port + * @dst_port: destination port + * @payload_len: data payload length + * @payload: data payload buffer + * @payload_seq: payload sequence stamping configuration + * @data_interval: interval at which to send data packets + * @wake_len: wakeup payload match length + * @wake_data: wakeup payload match data + * @wake_mask: wakeup payload match mask + * @tokens_size: length of the tokens buffer + * @payload_tok: payload token usage configuration + */ +struct cfg80211_wowlan_tcp { +	struct socket *sock; +	__be32 src, dst; +	u16 src_port, dst_port; +	u8 dst_mac[ETH_ALEN]; +	int payload_len; +	const u8 *payload; +	struct nl80211_wowlan_tcp_data_seq payload_seq; +	u32 data_interval; +	u32 wake_len; +	const u8 *wake_data, *wake_mask; +	u32 tokens_size; +	/* must be last, variable member */ +	struct nl80211_wowlan_tcp_data_token payload_tok;  };  /** @@ -1531,16 +1667,49 @@ struct cfg80211_wowlan_trig_pkt_pattern {   * @eap_identity_req: wake up on EAP identity request packet   * @four_way_handshake: wake up on 4-way handshake   * @rfkill_release: wake up when rfkill is released + * @tcp: TCP connection establishment/wakeup parameters, see nl80211.h. + *	NULL if not configured.   */  struct cfg80211_wowlan {  	bool any, disconnect, magic_pkt, gtk_rekey_failure,  	     eap_identity_req, four_way_handshake,  	     rfkill_release;  	struct cfg80211_wowlan_trig_pkt_pattern *patterns; +	struct cfg80211_wowlan_tcp *tcp;  	int n_patterns;  };  /** + * struct cfg80211_wowlan_wakeup - wakeup report + * @disconnect: woke up by getting disconnected + * @magic_pkt: woke up by receiving magic packet + * @gtk_rekey_failure: woke up by GTK rekey failure + * @eap_identity_req: woke up by EAP identity request packet + * @four_way_handshake: woke up by 4-way handshake + * @rfkill_release: woke up by rfkill being released + * @pattern_idx: pattern that caused wakeup, -1 if not due to pattern + * @packet_present_len: copied wakeup packet data + * @packet_len: original wakeup packet length + * @packet: The packet causing the wakeup, if any. + * @packet_80211:  For pattern match, magic packet and other data + *	frame triggers an 802.3 frame should be reported, for + *	disconnect due to deauth 802.11 frame. This indicates which + *	it is. + * @tcp_match: TCP wakeup packet received + * @tcp_connlost: TCP connection lost or failed to establish + * @tcp_nomoretokens: TCP data ran out of tokens + */ +struct cfg80211_wowlan_wakeup { +	bool disconnect, magic_pkt, gtk_rekey_failure, +	     eap_identity_req, four_way_handshake, +	     rfkill_release, packet_80211, +	     tcp_match, tcp_connlost, tcp_nomoretokens; +	s32 pattern_idx; +	u32 packet_present_len, packet_len; +	const void *packet; +}; + +/**   * struct cfg80211_gtk_rekey_data - rekey data   * @kek: key encryption key   * @kck: key confirmation key @@ -1763,6 +1932,15 @@ struct cfg80211_gtk_rekey_data {   *   * @start_p2p_device: Start the given P2P device.   * @stop_p2p_device: Stop the given P2P device. + * + * @set_mac_acl: Sets MAC address control list in AP and P2P GO mode. + *	Parameters include ACL policy, an array of MAC address of stations + *	and the number of MAC addresses. If there is already a list in driver + *	this new list replaces the existing one. Driver has to clear its ACL + *	when number of MAC addresses entries is passed as 0. Drivers which + *	advertise the support for MAC based ACL have to implement this callback. + * + * @start_radar_detection: Start radar detection in the driver.   */  struct cfg80211_ops {  	int	(*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow); @@ -1983,6 +2161,13 @@ struct cfg80211_ops {  				    struct wireless_dev *wdev);  	void	(*stop_p2p_device)(struct wiphy *wiphy,  				   struct wireless_dev *wdev); + +	int	(*set_mac_acl)(struct wiphy *wiphy, struct net_device *dev, +			       const struct cfg80211_acl_data *params); + +	int	(*start_radar_detection)(struct wiphy *wiphy, +					 struct net_device *dev, +					 struct cfg80211_chan_def *chandef);  };  /* @@ -2092,6 +2277,7 @@ struct ieee80211_iface_limit {   * @beacon_int_infra_match: In this combination, the beacon intervals   *	between infrastructure and AP types must match. This is required   *	only in special cases. + * @radar_detect_widths: bitmap of channel widths supported for radar detection   *   * These examples can be expressed as follows:   * @@ -2144,10 +2330,7 @@ struct ieee80211_iface_combination {  	u16 max_interfaces;  	u8 n_limits;  	bool beacon_int_infra_match; -}; - -struct mac_address { -	u8 addr[ETH_ALEN]; +	u8 radar_detect_widths;  };  struct ieee80211_txrx_stypes { @@ -2181,6 +2364,14 @@ enum wiphy_wowlan_support_flags {  	WIPHY_WOWLAN_RFKILL_RELEASE	= BIT(7),  }; +struct wiphy_wowlan_tcp_support { +	const struct nl80211_wowlan_tcp_data_token_feature *tok; +	u32 data_payload_max; +	u32 data_interval_max; +	u32 wake_payload_max; +	bool seq; +}; +  /**   * struct wiphy_wowlan_support - WoWLAN support data   * @flags: see &enum wiphy_wowlan_support_flags @@ -2188,12 +2379,16 @@ enum wiphy_wowlan_support_flags {   *	(see nl80211.h for the pattern definition)   * @pattern_max_len: maximum length of each pattern   * @pattern_min_len: minimum length of each pattern + * @max_pkt_offset: maximum Rx packet offset + * @tcp: TCP wakeup support information   */  struct wiphy_wowlan_support {  	u32 flags;  	int n_patterns;  	int pattern_max_len;  	int pattern_min_len; +	int max_pkt_offset; +	const struct wiphy_wowlan_tcp_support *tcp;  };  /** @@ -2290,6 +2485,17 @@ struct wiphy_wowlan_support {   * @ap_sme_capa: AP SME capabilities, flags from &enum nl80211_ap_sme_features.   * @ht_capa_mod_mask:  Specify what ht_cap values can be over-ridden.   *	If null, then none can be over-ridden. + * + * @max_acl_mac_addrs: Maximum number of MAC addresses that the device + *	supports for ACL. + * + * @extended_capabilities: extended capabilities supported by the driver, + *	additional capabilities might be supported by userspace; these are + *	the 802.11 extended capabilities ("Extended Capabilities element") + *	and are in the same format as in the information element. See + *	802.11-2012 8.4.2.29 for the defined fields. + * @extended_capabilities_mask: mask of the valid values + * @extended_capabilities_len: length of the extended capabilities   */  struct wiphy {  	/* assign these fields before you register the wiphy */ @@ -2311,6 +2517,8 @@ struct wiphy {  	/* Supported interface modes, OR together BIT(NL80211_IFTYPE_...) */  	u16 interface_modes; +	u16 max_acl_mac_addrs; +  	u32 flags, features;  	u32 ap_sme_capa; @@ -2333,7 +2541,7 @@ struct wiphy {  	u32 rts_threshold;  	u8 coverage_class; -	char fw_version[ETHTOOL_BUSINFO_LEN]; +	char fw_version[ETHTOOL_FWVERS_LEN];  	u32 hw_version;  #ifdef CONFIG_PM @@ -2354,6 +2562,9 @@ struct wiphy {  	 */  	u32 probe_resp_offload; +	const u8 *extended_capabilities, *extended_capabilities_mask; +	u8 extended_capabilities_len; +  	/* If multiple wiphys are registered and you're handed e.g.  	 * a regular netdev with assigned ieee80211_ptr, you won't  	 * know whether it points to a wiphy your driver has registered @@ -2364,12 +2575,12 @@ struct wiphy {  	struct ieee80211_supported_band *bands[IEEE80211_NUM_BANDS];  	/* Lets us get back the wiphy on the callback */ -	int (*reg_notifier)(struct wiphy *wiphy, -			    struct regulatory_request *request); +	void (*reg_notifier)(struct wiphy *wiphy, +			     struct regulatory_request *request);  	/* fields below are read-only, assigned by cfg80211 */ -	const struct ieee80211_regdomain *regd; +	const struct ieee80211_regdomain __rcu *regd;  	/* the item in /sys/class/ieee80211/ points to this,  	 * you need use set_wiphy_dev() (see below) */ @@ -2392,7 +2603,7 @@ struct wiphy {  	const struct iw_handler_def *wext;  #endif -	char priv[0] __attribute__((__aligned__(NETDEV_ALIGN))); +	char priv[0] __aligned(NETDEV_ALIGN);  };  static inline struct net *wiphy_net(struct wiphy *wiphy) @@ -2409,6 +2620,7 @@ static inline void wiphy_net_set(struct wiphy *wiphy, struct net *net)   * wiphy_priv - return priv from wiphy   *   * @wiphy: the wiphy whose priv pointer to return + * Return: The priv of @wiphy.   */  static inline void *wiphy_priv(struct wiphy *wiphy)  { @@ -2420,6 +2632,7 @@ static inline void *wiphy_priv(struct wiphy *wiphy)   * priv_to_wiphy - return the wiphy containing the priv   *   * @priv: a pointer previously returned by wiphy_priv + * Return: The wiphy of @priv.   */  static inline struct wiphy *priv_to_wiphy(void *priv)  { @@ -2442,6 +2655,7 @@ static inline void set_wiphy_dev(struct wiphy *wiphy, struct device *dev)   * wiphy_dev - get wiphy dev pointer   *   * @wiphy: The wiphy whose device struct to look up + * Return: The dev of @wiphy.   */  static inline struct device *wiphy_dev(struct wiphy *wiphy)  { @@ -2452,6 +2666,7 @@ static inline struct device *wiphy_dev(struct wiphy *wiphy)   * wiphy_name - get wiphy name   *   * @wiphy: The wiphy whose name to return + * Return: The name of @wiphy.   */  static inline const char *wiphy_name(const struct wiphy *wiphy)  { @@ -2467,8 +2682,8 @@ static inline const char *wiphy_name(const struct wiphy *wiphy)   * Create a new wiphy and associate the given operations with it.   * @sizeof_priv bytes are allocated for private use.   * - * The returned pointer must be assigned to each netdev's - * ieee80211_ptr for proper operation. + * Return: A pointer to the new wiphy. This pointer must be + * assigned to each netdev's ieee80211_ptr for proper operation.   */  struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv); @@ -2477,7 +2692,7 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv);   *   * @wiphy: The wiphy to register.   * - * Returns a non-negative wiphy index or a negative error code. + * Return: A non-negative wiphy index or a negative error code.   */  extern int wiphy_register(struct wiphy *wiphy); @@ -2529,7 +2744,6 @@ struct cfg80211_cached_keys;   *	the user-set AP, monitor and WDS channel   * @preset_chan: (private) Used by the internal configuration code to   *	track the channel to be used for AP later - * @preset_chantype: (private) the corresponding channel type   * @bssid: (private) Used by the internal configuration code   * @ssid: (private) Used by the internal configuration code   * @ssid_len: (private) Used by the internal configuration code @@ -2548,6 +2762,8 @@ struct cfg80211_cached_keys;   *	beacons, 0 when not valid   * @address: The address for this device, valid only if @netdev is %NULL   * @p2p_started: true if this is a P2P Device that has been started + * @cac_started: true if DFS channel availability check has been started + * @cac_start_time: timestamp (jiffies) when the dfs state was entered.   */  struct wireless_dev {  	struct wiphy *wiphy; @@ -2599,6 +2815,9 @@ struct wireless_dev {  	u32 ap_unexpected_nlportid; +	bool cac_started; +	unsigned long cac_start_time; +  #ifdef CONFIG_CFG80211_WEXT  	/* wext data */  	struct { @@ -2626,6 +2845,7 @@ static inline u8 *wdev_address(struct wireless_dev *wdev)   * wdev_priv - return wiphy priv from wireless_dev   *   * @wdev: The wireless device whose wiphy's priv pointer to return + * Return: The wiphy priv of @wdev.   */  static inline void *wdev_priv(struct wireless_dev *wdev)  { @@ -2643,12 +2863,14 @@ static inline void *wdev_priv(struct wireless_dev *wdev)   * ieee80211_channel_to_frequency - convert channel number to frequency   * @chan: channel number   * @band: band, necessary due to channel number overlap + * Return: The corresponding frequency (in MHz), or 0 if the conversion failed.   */  extern int ieee80211_channel_to_frequency(int chan, enum ieee80211_band band);  /**   * ieee80211_frequency_to_channel - convert frequency to channel number   * @freq: center frequency + * Return: The corresponding channel, or 0 if the conversion failed.   */  extern int ieee80211_frequency_to_channel(int freq); @@ -2665,6 +2887,7 @@ extern struct ieee80211_channel *__ieee80211_get_channel(struct wiphy *wiphy,   * ieee80211_get_channel - get channel struct from wiphy for specified frequency   * @wiphy: the struct wiphy to get the channel for   * @freq: the center frequency of the channel + * Return: The channel struct from @wiphy at @freq.   */  static inline struct ieee80211_channel *  ieee80211_get_channel(struct wiphy *wiphy, int freq) @@ -2679,10 +2902,10 @@ ieee80211_get_channel(struct wiphy *wiphy, int freq)   * @basic_rates: bitmap of basic rates   * @bitrate: the bitrate for which to find the basic rate   * - * This function returns the basic rate corresponding to a given - * bitrate, that is the next lower bitrate contained in the basic - * rate map, which is, for this function, given as a bitmap of - * indices of rates in the band's bitrate table. + * Return: The basic rate corresponding to a given bitrate, that + * is the next lower bitrate contained in the basic rate map, + * which is, for this function, given as a bitmap of indices of + * rates in the band's bitrate table.   */  struct ieee80211_rate *  ieee80211_get_response_rate(struct ieee80211_supported_band *sband, @@ -2775,18 +2998,21 @@ extern const unsigned char bridge_tunnel_header[6];  /**   * ieee80211_get_hdrlen_from_skb - get header length from data   * + * @skb: the frame + *   * Given an skb with a raw 802.11 header at the data pointer this function - * returns the 802.11 header length in bytes (not including encryption - * headers). If the data in the sk_buff is too short to contain a valid 802.11 - * header the function returns 0. + * returns the 802.11 header length.   * - * @skb: the frame + * Return: The 802.11 header length in bytes (not including encryption + * headers). Or 0 if the data in the sk_buff is too short to contain a valid + * 802.11 header.   */  unsigned int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb);  /**   * ieee80211_hdrlen - get header length in bytes from frame control   * @fc: frame control field in little-endian format + * Return: The header length in bytes.   */  unsigned int __attribute_const__ ieee80211_hdrlen(__le16 fc); @@ -2794,7 +3020,7 @@ unsigned int __attribute_const__ ieee80211_hdrlen(__le16 fc);   * ieee80211_get_mesh_hdrlen - get mesh extension header length   * @meshhdr: the mesh extension header, only the flags field   *	(first byte) will be accessed - * Returns the length of the extension header, which is always at + * Return: The length of the extension header, which is always at   * least 6 bytes and at most 18 if address 5 and 6 are present.   */  unsigned int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr); @@ -2812,6 +3038,7 @@ unsigned int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr);   * @skb: the 802.11 data frame   * @addr: the device MAC address   * @iftype: the virtual interface type + * Return: 0 on success. Non-zero on error.   */  int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr,  			   enum nl80211_iftype iftype); @@ -2823,6 +3050,7 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr,   * @iftype: the virtual interface type   * @bssid: the network bssid (used only for iftype STATION and ADHOC)   * @qos: build 802.11 QoS data frame + * Return: 0 on success, or a negative error code.   */  int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr,  			     enum nl80211_iftype iftype, u8 *bssid, bool qos); @@ -2850,6 +3078,7 @@ void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list,  /**   * cfg80211_classify8021d - determine the 802.1p/1d tag for a data frame   * @skb: the data frame + * Return: The 802.1p/1d tag.   */  unsigned int cfg80211_classify8021d(struct sk_buff *skb); @@ -2860,12 +3089,13 @@ unsigned int cfg80211_classify8021d(struct sk_buff *skb);   * @ies: data consisting of IEs   * @len: length of data   * - * This function will return %NULL if the element ID could - * not be found or if the element is invalid (claims to be - * longer than the given data), or a pointer to the first byte - * of the requested element, that is the byte containing the - * element ID. There are no checks on the element length - * other than having to fit into the given data. + * Return: %NULL if the element ID could not be found or if + * the element is invalid (claims to be longer than the given + * data), or a pointer to the first byte of the requested + * element, that is the byte containing the element ID. + * + * Note: There are no checks on the element length other than + * having to fit into the given data.   */  const u8 *cfg80211_find_ie(u8 eid, const u8 *ies, int len); @@ -2877,12 +3107,13 @@ const u8 *cfg80211_find_ie(u8 eid, const u8 *ies, int len);   * @ies: data consisting of IEs   * @len: length of data   * - * This function will return %NULL if the vendor specific element ID - * could not be found or if the element is invalid (claims to be - * longer than the given data), or a pointer to the first byte - * of the requested element, that is the byte containing the - * element ID. There are no checks on the element length - * other than having to fit into the given data. + * Return: %NULL if the vendor specific element ID could not be found or if the + * element is invalid (claims to be longer than the given data), or a pointer to + * the first byte of the requested element, that is the byte containing the + * element ID. + * + * Note: There are no checks on the element length other than having to fit into + * the given data.   */  const u8 *cfg80211_find_vendor_ie(unsigned int oui, u8 oui_type,  				  const u8 *ies, int len); @@ -2915,6 +3146,8 @@ const u8 *cfg80211_find_vendor_ie(unsigned int oui, u8 oui_type,   *   * Drivers should check the return value, its possible you can get   * an -ENOMEM. + * + * Return: 0 on success. -ENOMEM.   */  extern int regulatory_hint(struct wiphy *wiphy, const char *alpha2); @@ -2938,28 +3171,22 @@ extern void wiphy_apply_custom_regulatory(   * freq_reg_info - get regulatory information for the given frequency   * @wiphy: the wiphy for which we want to process this rule for   * @center_freq: Frequency in KHz for which we want regulatory information for - * @desired_bw_khz: the desired max bandwidth you want to use per - *	channel. Note that this is still 20 MHz if you want to use HT40 - *	as HT40 makes use of two channels for its 40 MHz width bandwidth. - *	If set to 0 we'll assume you want the standard 20 MHz. - * @reg_rule: the regulatory rule which we have for this frequency   *   * Use this function to get the regulatory rule for a specific frequency on   * a given wireless device. If the device has a specific regulatory domain   * it wants to follow we respect that unless a country IE has been received   * and processed already.   * - * Returns 0 if it was able to find a valid regulatory rule which does - * apply to the given center_freq otherwise it returns non-zero. It will - * also return -ERANGE if we determine the given center_freq does not even have - * a regulatory rule for a frequency range in the center_freq's band. See - * freq_in_rule_band() for our current definition of a band -- this is purely - * subjective and right now its 802.11 specific. + * Return: A valid pointer, or, when an error occurs, for example if no rule + * can be found, the return value is encoded using ERR_PTR(). Use IS_ERR() to + * check and PTR_ERR() to obtain the numeric return value. The numeric return + * value will be -ERANGE if we determine the given center_freq does not even + * have a regulatory rule for a frequency range in the center_freq's band. + * See freq_in_rule_band() for our current definition of a band -- this is + * purely subjective and right now it's 802.11 specific.   */ -extern int freq_reg_info(struct wiphy *wiphy, -			 u32 center_freq, -			 u32 desired_bw_khz, -			 const struct ieee80211_reg_rule **reg_rule); +const struct ieee80211_reg_rule *freq_reg_info(struct wiphy *wiphy, +					       u32 center_freq);  /*   * callbacks for asynchronous cfg80211 methods, notification @@ -3006,7 +3233,8 @@ void cfg80211_sched_scan_stopped(struct wiphy *wiphy);   * This informs cfg80211 that BSS information was found and   * the BSS should be updated/added.   * - * NOTE: Returns a referenced struct, must be released with cfg80211_put_bss()! + * Return: A referenced struct, must be released with cfg80211_put_bss()! + * Or %NULL on error.   */  struct cfg80211_bss * __must_check  cfg80211_inform_bss_frame(struct wiphy *wiphy, @@ -3031,7 +3259,8 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy,   * This informs cfg80211 that BSS information was found and   * the BSS should be updated/added.   * - * NOTE: Returns a referenced struct, must be released with cfg80211_put_bss()! + * Return: A referenced struct, must be released with cfg80211_put_bss()! + * Or %NULL on error.   */  struct cfg80211_bss * __must_check  cfg80211_inform_bss(struct wiphy *wiphy, @@ -3054,25 +3283,23 @@ cfg80211_get_ibss(struct wiphy *wiphy,  				WLAN_CAPABILITY_IBSS, WLAN_CAPABILITY_IBSS);  } -struct cfg80211_bss *cfg80211_get_mesh(struct wiphy *wiphy, -				       struct ieee80211_channel *channel, -				       const u8 *meshid, size_t meshidlen, -				       const u8 *meshcfg);  /**   * cfg80211_ref_bss - reference BSS struct + * @wiphy: the wiphy this BSS struct belongs to   * @bss: the BSS struct to reference   *   * Increments the refcount of the given BSS struct.   */ -void cfg80211_ref_bss(struct cfg80211_bss *bss); +void cfg80211_ref_bss(struct wiphy *wiphy, struct cfg80211_bss *bss);  /**   * cfg80211_put_bss - unref BSS struct + * @wiphy: the wiphy this BSS struct belongs to   * @bss: the BSS struct   *   * Decrements the refcount of the given BSS struct.   */ -void cfg80211_put_bss(struct cfg80211_bss *bss); +void cfg80211_put_bss(struct wiphy *wiphy, struct cfg80211_bss *bss);  /**   * cfg80211_unlink_bss - unlink BSS from internal data structures @@ -3308,16 +3535,18 @@ void wiphy_rfkill_stop_polling(struct wiphy *wiphy);   * the testmode command. Since it is intended for a reply, calling   * it outside of the @testmode_cmd operation is invalid.   * - * The returned skb (or %NULL if any errors happen) is pre-filled - * with the wiphy index and set up in a way that any data that is - * put into the skb (with skb_put(), nla_put() or similar) will end - * up being within the %NL80211_ATTR_TESTDATA attribute, so all that - * needs to be done with the skb is adding data for the corresponding - * userspace tool which can then read that data out of the testdata - * attribute. You must not modify the skb in any other way. + * The returned skb is pre-filled with the wiphy index and set up in + * a way that any data that is put into the skb (with skb_put(), + * nla_put() or similar) will end up being within the + * %NL80211_ATTR_TESTDATA attribute, so all that needs to be done + * with the skb is adding data for the corresponding userspace tool + * which can then read that data out of the testdata attribute. You + * must not modify the skb in any other way.   *   * When done, call cfg80211_testmode_reply() with the skb and return   * its error code as the result of the @testmode_cmd operation. + * + * Return: An allocated and pre-filled skb. %NULL if any errors happen.   */  struct sk_buff *cfg80211_testmode_alloc_reply_skb(struct wiphy *wiphy,  						  int approxlen); @@ -3327,11 +3556,12 @@ struct sk_buff *cfg80211_testmode_alloc_reply_skb(struct wiphy *wiphy,   * @skb: The skb, must have been allocated with   *	cfg80211_testmode_alloc_reply_skb()   * - * Returns an error code or 0 on success, since calling this - * function will usually be the last thing before returning - * from the @testmode_cmd you should return the error code. - * Note that this function consumes the skb regardless of the - * return value. + * Since calling this function will usually be the last thing + * before returning from the @testmode_cmd you should return + * the error code.  Note that this function consumes the skb + * regardless of the return value. + * + * Return: An error code or 0 on success.   */  int cfg80211_testmode_reply(struct sk_buff *skb); @@ -3345,14 +3575,16 @@ int cfg80211_testmode_reply(struct sk_buff *skb);   * This function allocates and pre-fills an skb for an event on the   * testmode multicast group.   * - * The returned skb (or %NULL if any errors happen) is set up in the - * same way as with cfg80211_testmode_alloc_reply_skb() but prepared - * for an event. As there, you should simply add data to it that will - * then end up in the %NL80211_ATTR_TESTDATA attribute. Again, you must - * not modify the skb in any other way. + * The returned skb is set up in the same way as with + * cfg80211_testmode_alloc_reply_skb() but prepared for an event. As + * there, you should simply add data to it that will then end up in the + * %NL80211_ATTR_TESTDATA attribute. Again, you must not modify the skb + * in any other way.   *   * When done filling the skb, call cfg80211_testmode_event() with the   * skb to send the event. + * + * Return: An allocated and pre-filled skb. %NULL if any errors happen.   */  struct sk_buff *cfg80211_testmode_alloc_event_skb(struct wiphy *wiphy,  						  int approxlen, gfp_t gfp); @@ -3533,13 +3765,13 @@ void cfg80211_conn_failed(struct net_device *dev, const u8 *mac_addr,   * @len: length of the frame data   * @gfp: context flags   * - * Returns %true if a user space application has registered for this frame. + * This function is called whenever an Action frame is received for a station + * mode interface, but is not processed in kernel. + * + * Return: %true if a user space application has registered for this frame.   * For action frames, that makes it responsible for rejecting unrecognized   * action frames; %false otherwise, in which case for action frames the   * driver is responsible for rejecting the frame. - * - * This function is called whenever an Action frame is received for a station - * mode interface, but is not processed in kernel.   */  bool cfg80211_rx_mgmt(struct wireless_dev *wdev, int freq, int sig_dbm,  		      const u8 *buf, size_t len, gfp_t gfp); @@ -3575,6 +3807,31 @@ void cfg80211_cqm_rssi_notify(struct net_device *dev,  			      gfp_t gfp);  /** + * cfg80211_radar_event - radar detection event + * @wiphy: the wiphy + * @chandef: chandef for the current channel + * @gfp: context flags + * + * This function is called when a radar is detected on the current chanenl. + */ +void cfg80211_radar_event(struct wiphy *wiphy, +			  struct cfg80211_chan_def *chandef, gfp_t gfp); + +/** + * cfg80211_cac_event - Channel availability check (CAC) event + * @netdev: network device + * @event: type of event + * @gfp: context flags + * + * This function is called when a Channel availability check (CAC) is finished + * or aborted. This must be called to notify the completion of a CAC process, + * also by full-MAC drivers. + */ +void cfg80211_cac_event(struct net_device *netdev, +			enum nl80211_radar_event event, gfp_t gfp); + + +/**   * cfg80211_cqm_pktloss_notify - notify userspace about packetloss to peer   * @dev: network device   * @peer: peer's MAC address @@ -3631,7 +3888,7 @@ void cfg80211_pmksa_candidate_notify(struct net_device *dev, int index,   * This function is used in AP mode (only!) to inform userspace that   * a spurious class 3 frame was received, to be able to deauth the   * sender. - * Returns %true if the frame was passed to userspace (or this failed + * Return: %true if the frame was passed to userspace (or this failed   * for a reason other than not having a subscription.)   */  bool cfg80211_rx_spurious_frame(struct net_device *dev, @@ -3647,7 +3904,7 @@ bool cfg80211_rx_spurious_frame(struct net_device *dev,   * an associated station sent a 4addr frame but that wasn't expected.   * It is allowed and desirable to send this event only once for each   * station to avoid event flooding. - * Returns %true if the frame was passed to userspace (or this failed + * Return: %true if the frame was passed to userspace (or this failed   * for a reason other than not having a subscription.)   */  bool cfg80211_rx_unexpected_4addr_frame(struct net_device *dev, @@ -3685,8 +3942,8 @@ void cfg80211_report_obss_beacon(struct wiphy *wiphy,   * @wiphy: the wiphy   * @chandef: the channel definition   * - * This function returns true if there is no secondary channel or the secondary - * channel(s) can be used for beaconing (i.e. is not a radar channel etc.) + * Return: %true if there is no secondary channel or the secondary channel(s) + * can be used for beaconing (i.e. is not a radar channel etc.)   */  bool cfg80211_reg_can_beacon(struct wiphy *wiphy,  			     struct cfg80211_chan_def *chandef); @@ -3756,14 +4013,29 @@ void cfg80211_unregister_wdev(struct wireless_dev *wdev);   * The function finds a given P2P attribute in the (vendor) IEs and   * copies its contents to the given buffer.   * - * The return value is a negative error code (-%EILSEQ or -%ENOENT) if - * the data is malformed or the attribute can't be found (respectively), - * or the length of the found attribute (which can be zero). + * Return: A negative error code (-%EILSEQ or -%ENOENT) if the data is + * malformed or the attribute can't be found (respectively), or the + * length of the found attribute (which can be zero).   */  int cfg80211_get_p2p_attr(const u8 *ies, unsigned int len,  			  enum ieee80211_p2p_attr_id attr,  			  u8 *buf, unsigned int bufsize); +/** + * cfg80211_report_wowlan_wakeup - report wakeup from WoWLAN + * @wdev: the wireless device reporting the wakeup + * @wakeup: the wakeup report + * @gfp: allocation flags + * + * This function reports that the given device woke up. If it + * caused the wakeup, report the reason(s), otherwise you may + * pass %NULL as the @wakeup parameter to advertise that something + * else caused the wakeup. + */ +void cfg80211_report_wowlan_wakeup(struct wireless_dev *wdev, +				   struct cfg80211_wowlan_wakeup *wakeup, +				   gfp_t gfp); +  /* Logging, debugging and troubleshooting/diagnostic helpers. */  /* wiphy_printk helpers, similar to dev_printk */ diff --git a/include/net/dn_route.h b/include/net/dn_route.h index 4f7d6a182381..2e9d317c82dc 100644 --- a/include/net/dn_route.h +++ b/include/net/dn_route.h @@ -16,7 +16,7 @@  *******************************************************************************/  extern struct sk_buff *dn_alloc_skb(struct sock *sk, int size, gfp_t pri); -extern int dn_route_output_sock(struct dst_entry **pprt, struct flowidn *, struct sock *sk, int flags); +extern int dn_route_output_sock(struct dst_entry __rcu **pprt, struct flowidn *, struct sock *sk, int flags);  extern int dn_cache_dump(struct sk_buff *skb, struct netlink_callback *cb);  extern void dn_rt_cache_flush(int delay); diff --git a/include/net/dsfield.h b/include/net/dsfield.h index 8a8d4e06900d..e1ad903a8d6a 100644 --- a/include/net/dsfield.h +++ b/include/net/dsfield.h @@ -43,11 +43,9 @@ static inline void ipv4_change_dsfield(struct iphdr *iph,__u8 mask,  static inline void ipv6_change_dsfield(struct ipv6hdr *ipv6h,__u8 mask,      __u8 value)  { -        __u16 tmp; +	__be16 *p = (__force __be16 *)ipv6h; -	tmp = ntohs(*(__be16 *) ipv6h); -	tmp = (tmp & ((mask << 4) | 0xf00f)) | (value << 4); -	*(__be16 *) ipv6h = htons(tmp); +	*p = (*p & htons((((u16)mask << 4) | 0xf00f))) | htons((u16)value << 4);  } diff --git a/include/net/dst.h b/include/net/dst.h index 9a7881066fb3..853cda11e518 100644 --- a/include/net/dst.h +++ b/include/net/dst.h @@ -36,13 +36,9 @@ struct dst_entry {  	struct net_device       *dev;  	struct  dst_ops	        *ops;  	unsigned long		_metrics; -	union { -		unsigned long           expires; -		/* point to where the dst_entry copied from */ -		struct dst_entry        *from; -	}; +	unsigned long           expires;  	struct dst_entry	*path; -	void			*__pad0; +	struct dst_entry	*from;  #ifdef CONFIG_XFRM  	struct xfrm_state	*xfrm;  #else @@ -61,6 +57,7 @@ struct dst_entry {  #define DST_NOPEER		0x0040  #define DST_FAKE_RTABLE		0x0080  #define DST_XFRM_TUNNEL		0x0100 +#define DST_XFRM_QUEUE		0x0200  	unsigned short		pending_confirm; diff --git a/include/net/gro_cells.h b/include/net/gro_cells.h index e5062c955ea6..734d9b5f577a 100644 --- a/include/net/gro_cells.h +++ b/include/net/gro_cells.h @@ -73,8 +73,8 @@ static inline int gro_cells_init(struct gro_cells *gcells, struct net_device *de  	int i;  	gcells->gro_cells_mask = roundup_pow_of_two(netif_get_num_default_rss_queues()) - 1; -	gcells->cells = kcalloc(sizeof(struct gro_cell), -				gcells->gro_cells_mask + 1, +	gcells->cells = kcalloc(gcells->gro_cells_mask + 1, +				sizeof(struct gro_cell),  				GFP_KERNEL);  	if (!gcells->cells)  		return -ENOMEM; diff --git a/include/net/inet6_hashtables.h b/include/net/inet6_hashtables.h index 9e34c877a770..7ca75cbbf75e 100644 --- a/include/net/inet6_hashtables.h +++ b/include/net/inet6_hashtables.h @@ -71,6 +71,8 @@ extern struct sock *__inet6_lookup_established(struct net *net,  extern struct sock *inet6_lookup_listener(struct net *net,  					  struct inet_hashinfo *hashinfo, +					  const struct in6_addr *saddr, +					  const __be16 sport,  					  const struct in6_addr *daddr,  					  const unsigned short hnum,  					  const int dif); @@ -88,7 +90,8 @@ static inline struct sock *__inet6_lookup(struct net *net,  	if (sk)  		return sk; -	return inet6_lookup_listener(net, hashinfo, daddr, hnum, dif); +	return inet6_lookup_listener(net, hashinfo, saddr, sport, +				     daddr, hnum, dif);  }  static inline struct sock *__inet6_lookup_skb(struct inet_hashinfo *hashinfo, diff --git a/include/net/inet_frag.h b/include/net/inet_frag.h index 32786a044718..3f237db0a426 100644 --- a/include/net/inet_frag.h +++ b/include/net/inet_frag.h @@ -1,10 +1,17 @@  #ifndef __NET_FRAG_H__  #define __NET_FRAG_H__ +#include <linux/percpu_counter.h> +  struct netns_frags {  	int			nqueues; -	atomic_t		mem;  	struct list_head	lru_list; +	spinlock_t		lru_lock; + +	/* The percpu_counter "mem" need to be cacheline aligned. +	 *  mem.count must not share cacheline with other writers +	 */ +	struct percpu_counter   mem ____cacheline_aligned_in_smp;  	/* sysctls */  	int			timeout; @@ -13,12 +20,11 @@ struct netns_frags {  };  struct inet_frag_queue { -	struct hlist_node	list; -	struct netns_frags	*net; -	struct list_head	lru_list;   /* lru list member */  	spinlock_t		lock; -	atomic_t		refcnt;  	struct timer_list	timer;      /* when will this queue expire? */ +	struct list_head	lru_list;   /* lru list member */ +	struct hlist_node	list; +	atomic_t		refcnt;  	struct sk_buff		*fragments; /* list of received fragments */  	struct sk_buff		*fragments_tail;  	ktime_t			stamp; @@ -31,24 +37,29 @@ struct inet_frag_queue {  #define INET_FRAG_LAST_IN	1  	u16			max_size; + +	struct netns_frags	*net;  };  #define INETFRAGS_HASHSZ		64  struct inet_frags {  	struct hlist_head	hash[INETFRAGS_HASHSZ]; -	rwlock_t		lock; -	u32			rnd; -	int			qsize; +	/* This rwlock is a global lock (seperate per IPv4, IPv6 and +	 * netfilter). Important to keep this on a seperate cacheline. +	 */ +	rwlock_t		lock ____cacheline_aligned_in_smp;  	int			secret_interval;  	struct timer_list	secret_timer; +	u32			rnd; +	int			qsize;  	unsigned int		(*hashfn)(struct inet_frag_queue *); +	bool			(*match)(struct inet_frag_queue *q, void *arg);  	void			(*constructor)(struct inet_frag_queue *q,  						void *arg);  	void			(*destructor)(struct inet_frag_queue *);  	void			(*skb_free)(struct sk_buff *); -	bool			(*match)(struct inet_frag_queue *q, void *arg);  	void			(*frag_expire)(unsigned long data);  }; @@ -72,4 +83,59 @@ static inline void inet_frag_put(struct inet_frag_queue *q, struct inet_frags *f  		inet_frag_destroy(q, f, NULL);  } +/* Memory Tracking Functions. */ + +/* The default percpu_counter batch size is not big enough to scale to + * fragmentation mem acct sizes. + * The mem size of a 64K fragment is approx: + *  (44 fragments * 2944 truesize) + frag_queue struct(200) = 129736 bytes + */ +static unsigned int frag_percpu_counter_batch = 130000; + +static inline int frag_mem_limit(struct netns_frags *nf) +{ +	return percpu_counter_read(&nf->mem); +} + +static inline void sub_frag_mem_limit(struct inet_frag_queue *q, int i) +{ +	__percpu_counter_add(&q->net->mem, -i, frag_percpu_counter_batch); +} + +static inline void add_frag_mem_limit(struct inet_frag_queue *q, int i) +{ +	__percpu_counter_add(&q->net->mem, i, frag_percpu_counter_batch); +} + +static inline void init_frag_mem_limit(struct netns_frags *nf) +{ +	percpu_counter_init(&nf->mem, 0); +} + +static inline int sum_frag_mem_limit(struct netns_frags *nf) +{ +	return percpu_counter_sum_positive(&nf->mem); +} + +static inline void inet_frag_lru_move(struct inet_frag_queue *q) +{ +	spin_lock(&q->net->lru_lock); +	list_move_tail(&q->lru_list, &q->net->lru_list); +	spin_unlock(&q->net->lru_lock); +} + +static inline void inet_frag_lru_del(struct inet_frag_queue *q) +{ +	spin_lock(&q->net->lru_lock); +	list_del(&q->lru_list); +	spin_unlock(&q->net->lru_lock); +} + +static inline void inet_frag_lru_add(struct netns_frags *nf, +				     struct inet_frag_queue *q) +{ +	spin_lock(&nf->lru_lock); +	list_add_tail(&q->lru_list, &nf->lru_list); +	spin_unlock(&nf->lru_lock); +}  #endif diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h index 67a8fa098e3a..7b2ae9d37076 100644 --- a/include/net/inet_hashtables.h +++ b/include/net/inet_hashtables.h @@ -81,7 +81,9 @@ struct inet_bind_bucket {  	struct net		*ib_net;  #endif  	unsigned short		port; -	signed short		fastreuse; +	signed char		fastreuse; +	signed char		fastreuseport; +	kuid_t			fastuid;  	int			num_owners;  	struct hlist_node	node;  	struct hlist_head	owners; @@ -257,15 +259,19 @@ extern void inet_unhash(struct sock *sk);  extern struct sock *__inet_lookup_listener(struct net *net,  					   struct inet_hashinfo *hashinfo, +					   const __be32 saddr, +					   const __be16 sport,  					   const __be32 daddr,  					   const unsigned short hnum,  					   const int dif);  static inline struct sock *inet_lookup_listener(struct net *net,  		struct inet_hashinfo *hashinfo, +		__be32 saddr, __be16 sport,  		__be32 daddr, __be16 dport, int dif)  { -	return __inet_lookup_listener(net, hashinfo, daddr, ntohs(dport), dif); +	return __inet_lookup_listener(net, hashinfo, saddr, sport, +				      daddr, ntohs(dport), dif);  }  /* Socket demux engine toys. */ @@ -358,7 +364,8 @@ static inline struct sock *__inet_lookup(struct net *net,  	struct sock *sk = __inet_lookup_established(net, hashinfo,  				saddr, sport, daddr, hnum, dif); -	return sk ? : __inet_lookup_listener(net, hashinfo, daddr, hnum, dif); +	return sk ? : __inet_lookup_listener(net, hashinfo, saddr, sport, +					     daddr, hnum, dif);  }  static inline struct sock *inet_lookup(struct net *net, diff --git a/include/net/ip6_checksum.h b/include/net/ip6_checksum.h index 652d3d309357..7686e3f5033d 100644 --- a/include/net/ip6_checksum.h +++ b/include/net/ip6_checksum.h @@ -35,63 +35,10 @@  #include <linux/ipv6.h>  #ifndef _HAVE_ARCH_IPV6_CSUM - -static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr, -					  const struct in6_addr *daddr, -					  __u32 len, unsigned short proto, -					  __wsum csum) -{ - -	int carry; -	__u32 ulen; -	__u32 uproto; -	__u32 sum = (__force u32)csum; - -	sum += (__force u32)saddr->s6_addr32[0]; -	carry = (sum < (__force u32)saddr->s6_addr32[0]); -	sum += carry; - -	sum += (__force u32)saddr->s6_addr32[1]; -	carry = (sum < (__force u32)saddr->s6_addr32[1]); -	sum += carry; - -	sum += (__force u32)saddr->s6_addr32[2]; -	carry = (sum < (__force u32)saddr->s6_addr32[2]); -	sum += carry; - -	sum += (__force u32)saddr->s6_addr32[3]; -	carry = (sum < (__force u32)saddr->s6_addr32[3]); -	sum += carry; - -	sum += (__force u32)daddr->s6_addr32[0]; -	carry = (sum < (__force u32)daddr->s6_addr32[0]); -	sum += carry; - -	sum += (__force u32)daddr->s6_addr32[1]; -	carry = (sum < (__force u32)daddr->s6_addr32[1]); -	sum += carry; - -	sum += (__force u32)daddr->s6_addr32[2]; -	carry = (sum < (__force u32)daddr->s6_addr32[2]); -	sum += carry; - -	sum += (__force u32)daddr->s6_addr32[3]; -	carry = (sum < (__force u32)daddr->s6_addr32[3]); -	sum += carry; - -	ulen = (__force u32)htonl((__u32) len); -	sum += ulen; -	carry = (sum < ulen); -	sum += carry; - -	uproto = (__force u32)htonl(proto); -	sum += uproto; -	carry = (sum < uproto); -	sum += carry; - -	return csum_fold((__force __wsum)sum); -} - +__sum16 csum_ipv6_magic(const struct in6_addr *saddr, +			const struct in6_addr *daddr, +			__u32 len, unsigned short proto, +			__wsum csum);  #endif  static __inline__ __sum16 tcp_v6_check(int len, @@ -126,4 +73,5 @@ static inline void tcp_v6_send_check(struct sock *sk, struct sk_buff *skb)  	__tcp_v6_send_check(skb, &np->saddr, &np->daddr);  } +int udp6_csum_init(struct sk_buff *skb, struct udphdr *uh, int proto);  #endif diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h index fdc48a94a063..2a601e7da1bf 100644 --- a/include/net/ip6_fib.h +++ b/include/net/ip6_fib.h @@ -89,8 +89,6 @@ struct fib6_table;  struct rt6_info {  	struct dst_entry		dst; -	struct neighbour		*n; -  	/*  	 * Tail elements of dst_entry (__refcnt etc.)  	 * and these elements (rarely used in hot path) are in @@ -166,50 +164,35 @@ static inline struct inet6_dev *ip6_dst_idev(struct dst_entry *dst)  static inline void rt6_clean_expires(struct rt6_info *rt)  { -	if (!(rt->rt6i_flags & RTF_EXPIRES) && rt->dst.from) -		dst_release(rt->dst.from); -  	rt->rt6i_flags &= ~RTF_EXPIRES; -	rt->dst.from = NULL;  }  static inline void rt6_set_expires(struct rt6_info *rt, unsigned long expires)  { -	if (!(rt->rt6i_flags & RTF_EXPIRES) && rt->dst.from) -		dst_release(rt->dst.from); - -	rt->rt6i_flags |= RTF_EXPIRES;  	rt->dst.expires = expires; +	rt->rt6i_flags |= RTF_EXPIRES;  } -static inline void rt6_update_expires(struct rt6_info *rt, int timeout) +static inline void rt6_update_expires(struct rt6_info *rt0, int timeout)  { -	if (!(rt->rt6i_flags & RTF_EXPIRES)) { -		if (rt->dst.from) -			dst_release(rt->dst.from); -		/* dst_set_expires relies on expires == 0  -		 * if it has not been set previously. -		 */ -		rt->dst.expires = 0; -	} - -	dst_set_expires(&rt->dst, timeout); -	rt->rt6i_flags |= RTF_EXPIRES; +	struct rt6_info *rt; + +	for (rt = rt0; rt && !(rt->rt6i_flags & RTF_EXPIRES); +	     rt = (struct rt6_info *)rt->dst.from); +	if (rt && rt != rt0) +		rt0->dst.expires = rt->dst.expires; + +	dst_set_expires(&rt0->dst, timeout); +	rt0->rt6i_flags |= RTF_EXPIRES;  }  static inline void rt6_set_from(struct rt6_info *rt, struct rt6_info *from)  {  	struct dst_entry *new = (struct dst_entry *) from; -	if (!(rt->rt6i_flags & RTF_EXPIRES) && rt->dst.from) { -		if (new == rt->dst.from) -			return; -		dst_release(rt->dst.from); -	} -  	rt->rt6i_flags &= ~RTF_EXPIRES; -	rt->dst.from = new;  	dst_hold(new); +	rt->dst.from = new;  }  static inline void ip6_rt_put(struct rt6_info *rt) diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h index 27d83183e615..260f83f16bcf 100644 --- a/include/net/ip6_route.h +++ b/include/net/ip6_route.h @@ -23,6 +23,7 @@ struct route_info {  #include <net/sock.h>  #include <linux/ip.h>  #include <linux/ipv6.h> +#include <linux/route.h>  #define RT6_LOOKUP_F_IFACE		0x00000001  #define RT6_LOOKUP_F_REACHABLE		0x00000002 @@ -102,7 +103,6 @@ extern struct rt6_info		*rt6_lookup(struct net *net,  					    int oif, int flags);  extern struct dst_entry *icmp6_dst_alloc(struct net_device *dev, -					 struct neighbour *neigh,  					 struct flowi6 *fl6);  extern int icmp6_dst_gc(void); @@ -194,4 +194,11 @@ static inline int ip6_skb_dst_mtu(struct sk_buff *skb)  	       skb_dst(skb)->dev->mtu : dst_mtu(skb_dst(skb));  } +static inline struct in6_addr *rt6_nexthop(struct rt6_info *rt, struct in6_addr *dest) +{ +	if (rt->rt6i_flags & RTF_GATEWAY) +		return &rt->rt6i_gateway; +	return dest; +} +  #endif diff --git a/include/net/ipv6.h b/include/net/ipv6.h index 5af66b26ebdd..851d5412a299 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h @@ -222,6 +222,7 @@ struct ip6_flowlabel {  	struct in6_addr		dst;  	struct ipv6_txoptions	*opt;  	unsigned long		linger; +	struct rcu_head		rcu;  	u8			share;  	union {  		struct pid *pid; @@ -238,6 +239,7 @@ struct ip6_flowlabel {  struct ipv6_fl_socklist {  	struct ipv6_fl_socklist	*next;  	struct ip6_flowlabel	*fl; +	struct rcu_head		rcu;  };  extern struct ip6_flowlabel	*fl6_sock_lookup(struct sock *sk, __be32 label); @@ -288,12 +290,12 @@ static inline int ip6_frag_nqueues(struct net *net)  static inline int ip6_frag_mem(struct net *net)  { -	return atomic_read(&net->ipv6.frags.mem); +	return sum_frag_mem_limit(&net->ipv6.frags);  }  #endif -#define IPV6_FRAG_HIGH_THRESH	(256 * 1024)	/* 262144 */ -#define IPV6_FRAG_LOW_THRESH	(192 * 1024)	/* 196608 */ +#define IPV6_FRAG_HIGH_THRESH	(4 * 1024*1024)	/* 4194304 */ +#define IPV6_FRAG_LOW_THRESH	(3 * 1024*1024)	/* 3145728 */  #define IPV6_FRAG_TIMEOUT	(60 * HZ)	/* 60 seconds */  extern int __ipv6_addr_type(const struct in6_addr *addr); @@ -355,14 +357,32 @@ static inline void ipv6_addr_prefix(struct in6_addr *pfx,  		pfx->s6_addr[o] = addr->s6_addr[o] & (0xff00 >> b);  } +static inline void __ipv6_addr_set_half(__be32 *addr, +					__be32 wh, __be32 wl) +{ +#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64 +#if defined(__BIG_ENDIAN) +	if (__builtin_constant_p(wh) && __builtin_constant_p(wl)) { +		*(__force u64 *)addr = ((__force u64)(wh) << 32 | (__force u64)(wl)); +		return; +	} +#elif defined(__LITTLE_ENDIAN) +	if (__builtin_constant_p(wl) && __builtin_constant_p(wh)) { +		*(__force u64 *)addr = ((__force u64)(wl) << 32 | (__force u64)(wh)); +		return; +	} +#endif +#endif +	addr[0] = wh; +	addr[1] = wl; +} +  static inline void ipv6_addr_set(struct in6_addr *addr,   				     __be32 w1, __be32 w2,  				     __be32 w3, __be32 w4)  { -	addr->s6_addr32[0] = w1; -	addr->s6_addr32[1] = w2; -	addr->s6_addr32[2] = w3; -	addr->s6_addr32[3] = w4; +	__ipv6_addr_set_half(&addr->s6_addr32[0], w1, w2); +	__ipv6_addr_set_half(&addr->s6_addr32[2], w3, w4);  }  static inline bool ipv6_addr_equal(const struct in6_addr *a1, @@ -381,9 +401,37 @@ static inline bool ipv6_addr_equal(const struct in6_addr *a1,  #endif  } -static inline bool __ipv6_prefix_equal(const __be32 *a1, const __be32 *a2, -				       unsigned int prefixlen) +#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64 +static inline bool __ipv6_prefix_equal64_half(const __be64 *a1, +					      const __be64 *a2, +					      unsigned int len) +{ +	if (len && ((*a1 ^ *a2) & cpu_to_be64((~0UL) << (64 - len)))) +		return false; +	return true; +} + +static inline bool ipv6_prefix_equal(const struct in6_addr *addr1, +				     const struct in6_addr *addr2, +				     unsigned int prefixlen) +{ +	const __be64 *a1 = (const __be64 *)addr1; +	const __be64 *a2 = (const __be64 *)addr2; + +	if (prefixlen >= 64) { +		if (a1[0] ^ a2[0]) +			return false; +		return __ipv6_prefix_equal64_half(a1 + 1, a2 + 1, prefixlen - 64); +	} +	return __ipv6_prefix_equal64_half(a1, a2, prefixlen); +} +#else +static inline bool ipv6_prefix_equal(const struct in6_addr *addr1, +				     const struct in6_addr *addr2, +				     unsigned int prefixlen)  { +	const __be32 *a1 = addr1->s6_addr32; +	const __be32 *a2 = addr2->s6_addr32;  	unsigned int pdw, pbi;  	/* check complete u32 in prefix */ @@ -398,14 +446,7 @@ static inline bool __ipv6_prefix_equal(const __be32 *a1, const __be32 *a2,  	return true;  } - -static inline bool ipv6_prefix_equal(const struct in6_addr *a1, -				     const struct in6_addr *a2, -				     unsigned int prefixlen) -{ -	return __ipv6_prefix_equal(a1->s6_addr32, a2->s6_addr32, -				   prefixlen); -} +#endif  struct inet_frag_queue; @@ -475,14 +516,25 @@ static inline u32 ipv6_addr_hash(const struct in6_addr *a)  static inline bool ipv6_addr_loopback(const struct in6_addr *a)  { +#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64 +	const unsigned long *ul = (const unsigned long *)a; + +	return (ul[0] | (ul[1] ^ cpu_to_be64(1))) == 0UL; +#else  	return (a->s6_addr32[0] | a->s6_addr32[1] |  		a->s6_addr32[2] | (a->s6_addr32[3] ^ htonl(1))) == 0; +#endif  }  static inline bool ipv6_addr_v4mapped(const struct in6_addr *a)  { -	return (a->s6_addr32[0] | a->s6_addr32[1] | -		 (a->s6_addr32[2] ^ htonl(0x0000ffff))) == 0; +	return ( +#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64 +		*(__be64 *)a | +#else +		(a->s6_addr32[0] | a->s6_addr32[1]) | +#endif +		(a->s6_addr32[2] ^ htonl(0x0000ffff))) == 0UL;  }  /* @@ -507,7 +559,7 @@ static inline void ipv6_addr_set_v4mapped(const __be32 addr,   * find the first different bit between two addresses   * length of address must be a multiple of 32bits   */ -static inline int __ipv6_addr_diff(const void *token1, const void *token2, int addrlen) +static inline int __ipv6_addr_diff32(const void *token1, const void *token2, int addrlen)  {  	const __be32 *a1 = token1, *a2 = token2;  	int i; @@ -539,6 +591,33 @@ static inline int __ipv6_addr_diff(const void *token1, const void *token2, int a  	return addrlen << 5;  } +#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64 +static inline int __ipv6_addr_diff64(const void *token1, const void *token2, int addrlen) +{ +	const __be64 *a1 = token1, *a2 = token2; +	int i; + +	addrlen >>= 3; + +	for (i = 0; i < addrlen; i++) { +		__be64 xb = a1[i] ^ a2[i]; +		if (xb) +			return i * 64 + 63 - __fls(be64_to_cpu(xb)); +	} + +	return addrlen << 6; +} +#endif + +static inline int __ipv6_addr_diff(const void *token1, const void *token2, int addrlen) +{ +#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64 +	if (__builtin_constant_p(addrlen) && !(addrlen & 7)) +		return __ipv6_addr_diff64(token1, token2, addrlen); +#endif +	return __ipv6_addr_diff32(token1, token2, addrlen); +} +  static inline int ipv6_addr_diff(const struct in6_addr *a1, const struct in6_addr *a2)  {  	return __ipv6_addr_diff(a1, a2, sizeof(struct in6_addr)); @@ -547,6 +626,20 @@ static inline int ipv6_addr_diff(const struct in6_addr *a1, const struct in6_add  extern void ipv6_select_ident(struct frag_hdr *fhdr, struct rt6_info *rt);  /* + *	Header manipulation + */ +static inline void ip6_flow_hdr(struct ipv6hdr *hdr, unsigned int tclass, +				__be32 flowlabel) +{ +	*(__be32 *)hdr = htonl(0x60000000 | (tclass << 20)) | flowlabel; +} + +static inline __be32 ip6_flowinfo(const struct ipv6hdr *hdr) +{ +	return *(__be32 *)hdr & IPV6_FLOWINFO_MASK; +} + +/*   *	Prototypes exported by ipv6   */ @@ -570,13 +663,6 @@ extern int			ip6_xmit(struct sock *sk,  					 struct ipv6_txoptions *opt,  					 int tclass); -extern int			ip6_nd_hdr(struct sock *sk, -					   struct sk_buff *skb, -					   struct net_device *dev, -					   const struct in6_addr *saddr, -					   const struct in6_addr *daddr, -					   int proto, int len); -  extern int			ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr);  extern int			ip6_append_data(struct sock *sk, diff --git a/include/net/irda/irlmp.h b/include/net/irda/irlmp.h index 591f78631f13..f74109144d3f 100644 --- a/include/net/irda/irlmp.h +++ b/include/net/irda/irlmp.h @@ -278,7 +278,7 @@ static inline int irlmp_lap_tx_queue_full(struct lsap_cb *self)  }  /* After doing a irlmp_dup(), this get one of the two socket back into - * a state where it's waiting incomming connections. + * a state where it's waiting incoming connections.   * Note : this can be used *only* if the socket is not yet connected   * (i.e. NO irlmp_connect_response() done on this socket).   * - Jean II */ diff --git a/include/net/irda/irttp.h b/include/net/irda/irttp.h index af4b87721d13..98682d4bae8f 100644 --- a/include/net/irda/irttp.h +++ b/include/net/irda/irttp.h @@ -185,7 +185,7 @@ static inline __u32 irttp_get_max_seg_size(struct tsap_cb *self)  }  /* After doing a irttp_dup(), this get one of the two socket back into - * a state where it's waiting incomming connections. + * a state where it's waiting incoming connections.   * Note : this can be used *only* if the socket is not yet connected   * (i.e. NO irttp_connect_response() done on this socket).   * - Jean II */ diff --git a/include/net/mac80211.h b/include/net/mac80211.h index ee50c5eba50c..f7eba1300d82 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -147,10 +147,12 @@ struct ieee80211_low_level_stats {   * enum ieee80211_chanctx_change - change flag for channel context   * @IEEE80211_CHANCTX_CHANGE_WIDTH: The channel width changed   * @IEEE80211_CHANCTX_CHANGE_RX_CHAINS: The number of RX chains changed + * @IEEE80211_CHANCTX_CHANGE_RADAR: radar detection flag changed   */  enum ieee80211_chanctx_change {  	IEEE80211_CHANCTX_CHANGE_WIDTH		= BIT(0),  	IEEE80211_CHANCTX_CHANGE_RX_CHAINS	= BIT(1), +	IEEE80211_CHANCTX_CHANGE_RADAR		= BIT(2),  };  /** @@ -165,6 +167,7 @@ enum ieee80211_chanctx_change {   * @rx_chains_dynamic: The number of RX chains that must be enabled   *	after RTS/CTS handshake to receive SMPS MIMO transmissions;   *	this will always be >= @rx_chains_static. + * @radar_enabled: whether radar detection is enabled on this channel.   * @drv_priv: data area for driver use, will always be aligned to   *	sizeof(void *), size is determined in hw information.   */ @@ -173,7 +176,9 @@ struct ieee80211_chanctx_conf {  	u8 rx_chains_static, rx_chains_dynamic; -	u8 drv_priv[0] __attribute__((__aligned__(sizeof(void *)))); +	bool radar_enabled; + +	u8 drv_priv[0] __aligned(sizeof(void *));  };  /** @@ -208,6 +213,11 @@ struct ieee80211_chanctx_conf {   * @BSS_CHANGED_TXPOWER: TX power setting changed for this interface   * @BSS_CHANGED_P2P_PS: P2P powersave settings (CTWindow, opportunistic PS)   *	changed (currently only in P2P client mode, GO mode will be later) + * @BSS_CHANGED_DTIM_PERIOD: the DTIM period value was changed (set when + *	it becomes valid, managed mode only) + * @BSS_CHANGED_BANDWIDTH: The bandwidth used by this interface changed, + *	note that this is only called when it changes after the channel + *	context had been assigned.   */  enum ieee80211_bss_change {  	BSS_CHANGED_ASSOC		= 1<<0, @@ -230,6 +240,8 @@ enum ieee80211_bss_change {  	BSS_CHANGED_PS			= 1<<17,  	BSS_CHANGED_TXPOWER		= 1<<18,  	BSS_CHANGED_P2P_PS		= 1<<19, +	BSS_CHANGED_DTIM_PERIOD		= 1<<20, +	BSS_CHANGED_BANDWIDTH		= 1<<21,  	/* when adding here, make sure to change ieee80211_reconfig */  }; @@ -271,13 +283,19 @@ enum ieee80211_rssi_event {   *	if the hardware cannot handle this it must set the   *	IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE hardware flag   * @dtim_period: num of beacons before the next DTIM, for beaconing, - *	valid in station mode only while @assoc is true and if also - *	requested by %IEEE80211_HW_NEED_DTIM_PERIOD (cf. also hw conf - *	@ps_dtim_period) + *	valid in station mode only if after the driver was notified + *	with the %BSS_CHANGED_DTIM_PERIOD flag, will be non-zero then.   * @sync_tsf: last beacon's/probe response's TSF timestamp (could be old - *	as it may have been received during scanning long ago) + *	as it may have been received during scanning long ago). If the + *	HW flag %IEEE80211_HW_TIMING_BEACON_ONLY is set, then this can + *	only come from a beacon, but might not become valid until after + *	association when a beacon is received (which is notified with the + *	%BSS_CHANGED_DTIM flag.)   * @sync_device_ts: the device timestamp corresponding to the sync_tsf,   *	the driver/device can use this to calculate synchronisation + *	(see @sync_tsf) + * @sync_dtim_count: Only valid when %IEEE80211_HW_TIMING_BEACON_ONLY + *	is requested, see @sync_tsf/@sync_device_ts.   * @beacon_int: beacon interval   * @assoc_capability: capabilities taken from assoc resp   * @basic_rates: bitmap of basic rates, each bit stands for an @@ -297,11 +315,9 @@ enum ieee80211_rssi_event {   *	may filter ARP queries targeted for other addresses than listed here.   *	The driver must allow ARP queries targeted for all address listed here   *	to pass through. An empty list implies no ARP queries need to pass. - * @arp_addr_cnt: Number of addresses currently on the list. - * @arp_filter_enabled: Enable ARP filtering - if enabled, the hardware may - *	filter ARP queries based on the @arp_addr_list, if disabled, the - *	hardware must not perform any ARP filtering. Note, that the filter will - *	be enabled also in promiscuous mode. + * @arp_addr_cnt: Number of addresses currently on the list. Note that this + *	may be larger than %IEEE80211_BSS_ARP_ADDR_LIST_LEN (the arp_addr_list + *	array size), it's up to the driver what to do in that case.   * @qos: This is a QoS-enabled BSS.   * @idle: This interface is idle. There's also a global idle flag in the   *	hardware config which may be more appropriate depending on what @@ -331,6 +347,7 @@ struct ieee80211_bss_conf {  	u16 assoc_capability;  	u64 sync_tsf;  	u32 sync_device_ts; +	u8 sync_dtim_count;  	u32 basic_rates;  	int mcast_rate[IEEE80211_NUM_BANDS];  	u16 ht_operation_mode; @@ -338,8 +355,7 @@ struct ieee80211_bss_conf {  	u32 cqm_rssi_hyst;  	struct cfg80211_chan_def chandef;  	__be32 arp_addr_list[IEEE80211_BSS_ARP_ADDR_LIST_LEN]; -	u8 arp_addr_cnt; -	bool arp_filter_enabled; +	int arp_addr_cnt;  	bool qos;  	bool idle;  	bool ps; @@ -392,6 +408,9 @@ struct ieee80211_bss_conf {   * @IEEE80211_TX_CTL_RATE_CTRL_PROBE: internal to mac80211, can be   *	set by rate control algorithms to indicate probe rate, will   *	be cleared for fragmented frames (except on the last fragment) + * @IEEE80211_TX_INTFL_OFFCHAN_TX_OK: Internal to mac80211. Used to indicate + *	that a frame can be transmitted while the queues are stopped for + *	off-channel operation.   * @IEEE80211_TX_INTFL_NEED_TXPROCESSING: completely internal to mac80211,   *	used to indicate that a pending frame requires TX processing before   *	it can be sent out. @@ -409,6 +428,9 @@ struct ieee80211_bss_conf {   * @IEEE80211_TX_INTFL_RETRANSMISSION: This frame is being retransmitted   *	after TX status because the destination was asleep, it must not   *	be modified again (no seqno assignment, crypto, etc.) + * @IEEE80211_TX_INTFL_MLME_CONN_TX: This frame was transmitted by the MLME + *	code for connection establishment, this indicates that its status + *	should kick the MLME state machine.   * @IEEE80211_TX_INTFL_NL80211_FRAME_TX: Frame was requested through nl80211   *	MLME command (internal to mac80211 to figure out whether to send TX   *	status to user space) @@ -454,13 +476,14 @@ enum mac80211_tx_control_flags {  	IEEE80211_TX_STAT_AMPDU			= BIT(10),  	IEEE80211_TX_STAT_AMPDU_NO_BACK		= BIT(11),  	IEEE80211_TX_CTL_RATE_CTRL_PROBE	= BIT(12), +	IEEE80211_TX_INTFL_OFFCHAN_TX_OK	= BIT(13),  	IEEE80211_TX_INTFL_NEED_TXPROCESSING	= BIT(14),  	IEEE80211_TX_INTFL_RETRIED		= BIT(15),  	IEEE80211_TX_INTFL_DONT_ENCRYPT		= BIT(16),  	IEEE80211_TX_CTL_NO_PS_BUFFER		= BIT(17),  	IEEE80211_TX_CTL_MORE_FRAMES		= BIT(18),  	IEEE80211_TX_INTFL_RETRANSMISSION	= BIT(19), -	/* hole at 20, use later */ +	IEEE80211_TX_INTFL_MLME_CONN_TX		= BIT(20),  	IEEE80211_TX_INTFL_NL80211_FRAME_TX	= BIT(21),  	IEEE80211_TX_CTL_LDPC			= BIT(22),  	IEEE80211_TX_CTL_STBC			= BIT(23) | BIT(24), @@ -953,6 +976,7 @@ enum ieee80211_smps_mode {   *   * @channel: the channel to tune to   * @channel_type: the channel (HT) type + * @radar_enabled: whether radar detection is enabled   *   * @long_frame_max_tx_count: Maximum number of transmissions for a "long" frame   *    (a frame not RTS protected), called "dot11LongRetryLimit" in 802.11, @@ -979,6 +1003,7 @@ struct ieee80211_conf {  	struct ieee80211_channel *channel;  	enum nl80211_channel_type channel_type; +	bool radar_enabled;  	enum ieee80211_smps_mode smps_mode;  }; @@ -1059,7 +1084,7 @@ struct ieee80211_vif {  	u32 driver_flags;  	/* must be last */ -	u8 drv_priv[0] __attribute__((__aligned__(sizeof(void *)))); +	u8 drv_priv[0] __aligned(sizeof(void *));  };  static inline bool ieee80211_vif_is_mesh(struct ieee80211_vif *vif) @@ -1176,6 +1201,24 @@ enum ieee80211_sta_state {  };  /** + * enum ieee80211_sta_rx_bandwidth - station RX bandwidth + * @IEEE80211_STA_RX_BW_20: station can only receive 20 MHz + * @IEEE80211_STA_RX_BW_40: station can receive up to 40 MHz + * @IEEE80211_STA_RX_BW_80: station can receive up to 80 MHz + * @IEEE80211_STA_RX_BW_160: station can receive up to 160 MHz + *	(including 80+80 MHz) + * + * Implementation note: 20 must be zero to be initialized + *	correctly, the values must be sorted. + */ +enum ieee80211_sta_rx_bandwidth { +	IEEE80211_STA_RX_BW_20 = 0, +	IEEE80211_STA_RX_BW_40, +	IEEE80211_STA_RX_BW_80, +	IEEE80211_STA_RX_BW_160, +}; + +/**   * struct ieee80211_sta - station table entry   *   * A station table entry represents a station we are possibly @@ -1197,6 +1240,12 @@ enum ieee80211_sta_state {   * @uapsd_queues: bitmap of queues configured for uapsd. Only valid   *	if wme is supported.   * @max_sp: max Service Period. Only valid if wme is supported. + * @bandwidth: current bandwidth the station can receive with + * @rx_nss: in HT/VHT, the maximum number of spatial streams the + *	station can receive at the moment, changed by operating mode + *	notifications and capabilities. The value is only valid after + *	the station moves to associated state. + * @smps_mode: current SMPS mode (off, static or dynamic)   */  struct ieee80211_sta {  	u32 supp_rates[IEEE80211_NUM_BANDS]; @@ -1207,9 +1256,12 @@ struct ieee80211_sta {  	bool wme;  	u8 uapsd_queues;  	u8 max_sp; +	u8 rx_nss; +	enum ieee80211_sta_rx_bandwidth bandwidth; +	enum ieee80211_smps_mode smps_mode;  	/* must be last */ -	u8 drv_priv[0] __attribute__((__aligned__(sizeof(void *)))); +	u8 drv_priv[0] __aligned(sizeof(void *));  };  /** @@ -1331,9 +1383,9 @@ struct ieee80211_tx_control {   *      When this flag is set, signaling beacon-loss will cause an immediate   *      change to disassociated state.   * - * @IEEE80211_HW_NEED_DTIM_PERIOD: - *	This device needs to know the DTIM period for the BSS before - *	associating. + * @IEEE80211_HW_NEED_DTIM_BEFORE_ASSOC: + *	This device needs to get data from beacon before association (i.e. + *	dtim_period).   *   * @IEEE80211_HW_SUPPORTS_PER_STA_GTK: The device's crypto engine supports   *	per-station GTKs as used by IBSS RSN or during fast transition. If @@ -1353,10 +1405,6 @@ struct ieee80211_tx_control {   *	setup strictly in HW. mac80211 should not attempt to do this in   *	software.   * - * @IEEE80211_HW_SCAN_WHILE_IDLE: The device can do hw scan while - *	being idle (i.e. mac80211 doesn't have to go idle-off during the - *	the scan). - *   * @IEEE80211_HW_WANT_MONITOR_VIF: The driver would like to be informed of   *	a virtual monitor interface when monitor interfaces are the only   *	active interfaces. @@ -1370,9 +1418,8 @@ struct ieee80211_tx_control {   *	P2P Interface. This will be honoured even if more than one interface   *	is supported.   * - * @IEEE80211_HW_TEARDOWN_AGGR_ON_BAR_FAIL: On this hardware TX BA session - *	should be tear down once BAR frame will not be acked. - * + * @IEEE80211_HW_TIMING_BEACON_ONLY: Use sync timing from beacon frames + *	only, to allow getting TBTT of a DTIM beacon.   */  enum ieee80211_hw_flags {  	IEEE80211_HW_HAS_RATE_CONTROL			= 1<<0, @@ -1382,7 +1429,7 @@ enum ieee80211_hw_flags {  	IEEE80211_HW_2GHZ_SHORT_PREAMBLE_INCAPABLE	= 1<<4,  	IEEE80211_HW_SIGNAL_UNSPEC			= 1<<5,  	IEEE80211_HW_SIGNAL_DBM				= 1<<6, -	IEEE80211_HW_NEED_DTIM_PERIOD			= 1<<7, +	IEEE80211_HW_NEED_DTIM_BEFORE_ASSOC		= 1<<7,  	IEEE80211_HW_SPECTRUM_MGMT			= 1<<8,  	IEEE80211_HW_AMPDU_AGGREGATION			= 1<<9,  	IEEE80211_HW_SUPPORTS_PS			= 1<<10, @@ -1399,9 +1446,8 @@ enum ieee80211_hw_flags {  	IEEE80211_HW_SUPPORTS_PER_STA_GTK		= 1<<21,  	IEEE80211_HW_AP_LINK_PS				= 1<<22,  	IEEE80211_HW_TX_AMPDU_SETUP_IN_HW		= 1<<23, -	IEEE80211_HW_SCAN_WHILE_IDLE			= 1<<24,  	IEEE80211_HW_P2P_DEV_ADDR_FOR_INTF		= 1<<25, -	IEEE80211_HW_TEARDOWN_AGGR_ON_BAR_FAIL		= 1<<26, +	IEEE80211_HW_TIMING_BEACON_ONLY			= 1<<26,  };  /** @@ -1522,6 +1568,8 @@ struct ieee80211_hw {   * structure can then access it via hw->priv. Note that mac802111 drivers should   * not use wiphy_priv() to try to get their private driver structure as this   * is already used internally by mac80211. + * + * Return: The mac80211 driver hw struct of @wiphy.   */  struct ieee80211_hw *wiphy_to_ieee80211_hw(struct wiphy *wiphy); @@ -1628,6 +1676,10 @@ void ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb);   * rekeying), it will not include a valid phase 1 key. The valid phase 1 key is   * provided by update_tkip_key only. The trigger that makes mac80211 call this   * handler is software decryption with wrap around of iv16. + * + * The set_default_unicast_key() call updates the default WEP key index + * configured to the hardware for WEP encryption type. This is required + * for devices that support offload of data packets (e.g. ARP responses).   */  /** @@ -1680,15 +1732,6 @@ void ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb);   * dynamic PS feature in stack and will just keep %IEEE80211_CONF_PS   * enabled whenever user has enabled powersave.   * - * Some hardware need to toggle a single shared antenna between WLAN and - * Bluetooth to facilitate co-existence. These types of hardware set - * limitations on the use of host controlled dynamic powersave whenever there - * is simultaneous WLAN and Bluetooth traffic. For these types of hardware, the - * driver may request temporarily going into full power save, in order to - * enable toggling the antenna between BT and WLAN. If the driver requests - * disabling dynamic powersave, the @dynamic_ps_timeout value will be - * temporarily set to zero until the driver re-enables dynamic powersave. - *   * Driver informs U-APSD client support by enabling   * %IEEE80211_HW_SUPPORTS_UAPSD flag. The mode is configured through the   * uapsd paramater in conf_tx() operation. Hardware needs to send the QoS @@ -2033,17 +2076,29 @@ enum ieee80211_filter_flags {   * calling ieee80211_start_tx_ba_cb_irqsafe, because the peer   * might receive the addBA frame and send a delBA right away!   * - * @IEEE80211_AMPDU_RX_START: start Rx aggregation - * @IEEE80211_AMPDU_RX_STOP: stop Rx aggregation - * @IEEE80211_AMPDU_TX_START: start Tx aggregation - * @IEEE80211_AMPDU_TX_STOP: stop Tx aggregation + * @IEEE80211_AMPDU_RX_START: start RX aggregation + * @IEEE80211_AMPDU_RX_STOP: stop RX aggregation + * @IEEE80211_AMPDU_TX_START: start TX aggregation   * @IEEE80211_AMPDU_TX_OPERATIONAL: TX aggregation has become operational + * @IEEE80211_AMPDU_TX_STOP_CONT: stop TX aggregation but continue transmitting + *	queued packets, now unaggregated. After all packets are transmitted the + *	driver has to call ieee80211_stop_tx_ba_cb_irqsafe(). + * @IEEE80211_AMPDU_TX_STOP_FLUSH: stop TX aggregation and flush all packets, + *	called when the station is removed. There's no need or reason to call + *	ieee80211_stop_tx_ba_cb_irqsafe() in this case as mac80211 assumes the + *	session is gone and removes the station. + * @IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: called when TX aggregation is stopped + *	but the driver hasn't called ieee80211_stop_tx_ba_cb_irqsafe() yet and + *	now the connection is dropped and the station will be removed. Drivers + *	should clean up and drop remaining packets when this is called.   */  enum ieee80211_ampdu_mlme_action {  	IEEE80211_AMPDU_RX_START,  	IEEE80211_AMPDU_RX_STOP,  	IEEE80211_AMPDU_TX_START, -	IEEE80211_AMPDU_TX_STOP, +	IEEE80211_AMPDU_TX_STOP_CONT, +	IEEE80211_AMPDU_TX_STOP_FLUSH, +	IEEE80211_AMPDU_TX_STOP_FLUSH_CONT,  	IEEE80211_AMPDU_TX_OPERATIONAL,  }; @@ -2062,16 +2117,21 @@ enum ieee80211_frame_release_type {   * enum ieee80211_rate_control_changed - flags to indicate what changed   *   * @IEEE80211_RC_BW_CHANGED: The bandwidth that can be used to transmit - *	to this station changed. + *	to this station changed. The actual bandwidth is in the station + *	information -- for HT20/40 the IEEE80211_HT_CAP_SUP_WIDTH_20_40 + *	flag changes, for HT and VHT the bandwidth field changes.   * @IEEE80211_RC_SMPS_CHANGED: The SMPS state of the station changed.   * @IEEE80211_RC_SUPP_RATES_CHANGED: The supported rate set of this peer   *	changed (in IBSS mode) due to discovering more information about   *	the peer. + * @IEEE80211_RC_NSS_CHANGED: N_SS (number of spatial streams) was changed + *	by the peer   */  enum ieee80211_rate_control_changed {  	IEEE80211_RC_BW_CHANGED		= BIT(0),  	IEEE80211_RC_SMPS_CHANGED	= BIT(1),  	IEEE80211_RC_SUPP_RATES_CHANGED	= BIT(2), +	IEEE80211_RC_NSS_CHANGED	= BIT(3),  };  /** @@ -2152,6 +2212,18 @@ enum ieee80211_rate_control_changed {   *	MAC address of the device going away.   *	Hence, this callback must be implemented. It can sleep.   * + * @add_interface_debugfs: Drivers can use this callback to add debugfs files + *	when a vif is added to mac80211. This callback and + *	@remove_interface_debugfs should be within a CONFIG_MAC80211_DEBUGFS + *	conditional. @remove_interface_debugfs must be provided for cleanup. + *	This callback can sleep. + * + * @remove_interface_debugfs: Remove the debugfs files which were added using + *	@add_interface_debugfs. This callback must remove all debugfs entries + *	that were added because mac80211 only removes interface debugfs when the + *	interface is destroyed, not when it is removed from the driver. + *	This callback can sleep. + *   * @config: Handler for configuration requests. IEEE 802.11 code calls this   *	function to change hardware configuration, e.g., channel.   *	This function should never fail but returns a negative error code @@ -2194,6 +2266,10 @@ enum ieee80211_rate_control_changed {   *	After rekeying was done it should (for example during resume) notify   *	userspace of the new replay counter using ieee80211_gtk_rekey_notify().   * + * @set_default_unicast_key: Set the default (unicast) key index, useful for + *	WEP when the device sends data packets autonomously, e.g. for ARP + *	offloading. The index can be 0-3, or -1 for unsetting it. + *   * @hw_scan: Ask the hardware to service the scan request, no need to start   *	the scan state machine in stack. The scan must honour the channel   *	configuration done by the regulatory agent in the wiphy's @@ -2474,7 +2550,13 @@ enum ieee80211_rate_control_changed {   *   * @restart_complete: Called after a call to ieee80211_restart_hw(), when the   *	reconfiguration has completed. This can help the driver implement the - *	reconfiguration step. This callback may sleep. + *	reconfiguration step. Also called when reconfiguring because the + *	driver's resume function returned 1, as this is just like an "inline" + *	hardware restart. This callback may sleep. + * + * @ipv6_addr_change: IPv6 address assignment on the given interface changed. + *	Currently, this is only called for managed or P2P client interfaces. + *	This callback is optional; it must not sleep.   */  struct ieee80211_ops {  	void (*tx)(struct ieee80211_hw *hw, @@ -2522,6 +2604,8 @@ struct ieee80211_ops {  	void (*set_rekey_data)(struct ieee80211_hw *hw,  			       struct ieee80211_vif *vif,  			       struct cfg80211_gtk_rekey_data *data); +	void (*set_default_unicast_key)(struct ieee80211_hw *hw, +					struct ieee80211_vif *vif, int idx);  	int (*hw_scan)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,  		       struct cfg80211_scan_request *req);  	void (*cancel_hw_scan)(struct ieee80211_hw *hw, @@ -2553,6 +2637,12 @@ struct ieee80211_ops {  				   struct ieee80211_vif *vif,  				   struct ieee80211_sta *sta,  				   struct dentry *dir); +	void (*add_interface_debugfs)(struct ieee80211_hw *hw, +				      struct ieee80211_vif *vif, +				      struct dentry *dir); +	void (*remove_interface_debugfs)(struct ieee80211_hw *hw, +					 struct ieee80211_vif *vif, +					 struct dentry *dir);  #endif  	void (*sta_notify)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,  			enum sta_notify_cmd, struct ieee80211_sta *sta); @@ -2606,6 +2696,7 @@ struct ieee80211_ops {  	int (*set_bitrate_mask)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,  				const struct cfg80211_bitrate_mask *mask);  	void (*rssi_callback)(struct ieee80211_hw *hw, +			      struct ieee80211_vif *vif,  			      enum ieee80211_rssi_event rssi_event);  	void (*allow_buffered_frames)(struct ieee80211_hw *hw, @@ -2648,6 +2739,12 @@ struct ieee80211_ops {  				     struct ieee80211_chanctx_conf *ctx);  	void (*restart_complete)(struct ieee80211_hw *hw); + +#if IS_ENABLED(CONFIG_IPV6) +	void (*ipv6_addr_change)(struct ieee80211_hw *hw, +				 struct ieee80211_vif *vif, +				 struct inet6_dev *idev); +#endif  };  /** @@ -2661,6 +2758,8 @@ struct ieee80211_ops {   *   * @priv_data_len: length of private data   * @ops: callbacks for this device + * + * Return: A pointer to the new hardware device, or %NULL on error.   */  struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,  					const struct ieee80211_ops *ops); @@ -2673,6 +2772,8 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,   * need to fill the contained wiphy's information.   *   * @hw: the device to register as returned by ieee80211_alloc_hw() + * + * Return: 0 on success. An error code otherwise.   */  int ieee80211_register_hw(struct ieee80211_hw *hw); @@ -2719,6 +2820,8 @@ extern char *__ieee80211_create_tpt_led_trigger(   * of the trigger so you can automatically link the LED device.   *   * @hw: the hardware to get the LED trigger name for + * + * Return: The name of the LED trigger. %NULL if not configured for LEDs.   */  static inline char *ieee80211_get_tx_led_name(struct ieee80211_hw *hw)  { @@ -2738,6 +2841,8 @@ static inline char *ieee80211_get_tx_led_name(struct ieee80211_hw *hw)   * of the trigger so you can automatically link the LED device.   *   * @hw: the hardware to get the LED trigger name for + * + * Return: The name of the LED trigger. %NULL if not configured for LEDs.   */  static inline char *ieee80211_get_rx_led_name(struct ieee80211_hw *hw)  { @@ -2757,6 +2862,8 @@ static inline char *ieee80211_get_rx_led_name(struct ieee80211_hw *hw)   * of the trigger so you can automatically link the LED device.   *   * @hw: the hardware to get the LED trigger name for + * + * Return: The name of the LED trigger. %NULL if not configured for LEDs.   */  static inline char *ieee80211_get_assoc_led_name(struct ieee80211_hw *hw)  { @@ -2776,6 +2883,8 @@ static inline char *ieee80211_get_assoc_led_name(struct ieee80211_hw *hw)   * of the trigger so you can automatically link the LED device.   *   * @hw: the hardware to get the LED trigger name for + * + * Return: The name of the LED trigger. %NULL if not configured for LEDs.   */  static inline char *ieee80211_get_radio_led_name(struct ieee80211_hw *hw)  { @@ -2793,9 +2902,10 @@ static inline char *ieee80211_get_radio_led_name(struct ieee80211_hw *hw)   * @blink_table: the blink table -- needs to be ordered by throughput   * @blink_table_len: size of the blink table   * - * This function returns %NULL (in case of error, or if no LED - * triggers are configured) or the name of the new trigger. - * This function must be called before ieee80211_register_hw(). + * Return: %NULL (in case of error, or if no LED triggers are + * configured) or the name of the new trigger. + * + * Note: This function must be called before ieee80211_register_hw().   */  static inline char *  ieee80211_create_tpt_led_trigger(struct ieee80211_hw *hw, unsigned int flags, @@ -2928,10 +3038,10 @@ static inline void ieee80211_rx_ni(struct ieee80211_hw *hw,   * Calls to this function for a single hardware must be synchronized against   * each other.   * - * The function returns -EINVAL when the requested PS mode is already set. - *   * @sta: currently connected sta   * @start: start or stop PS + * + * Return: 0 on success. -EINVAL when the requested PS mode is already set.   */  int ieee80211_sta_ps_transition(struct ieee80211_sta *sta, bool start); @@ -2945,6 +3055,8 @@ int ieee80211_sta_ps_transition(struct ieee80211_sta *sta, bool start);   *   * @sta: currently connected sta   * @start: start or stop PS + * + * Return: Like ieee80211_sta_ps_transition().   */  static inline int ieee80211_sta_ps_transition_ni(struct ieee80211_sta *sta,  						  bool start) @@ -3082,6 +3194,8 @@ void ieee80211_report_low_ack(struct ieee80211_sta *sta, u32 num_packets);   * according to the current DTIM parameters/TIM bitmap.   *   * The driver is responsible for freeing the returned skb. + * + * Return: The beacon template. %NULL on error.   */  struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,  					 struct ieee80211_vif *vif, @@ -3093,6 +3207,8 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,   * @vif: &struct ieee80211_vif pointer from the add_interface callback.   *   * See ieee80211_beacon_get_tim(). + * + * Return: See ieee80211_beacon_get_tim().   */  static inline struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,  						   struct ieee80211_vif *vif) @@ -3109,6 +3225,8 @@ static inline struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,   * hardware. The destination address should be set by the caller.   *   * Can only be called in AP mode. + * + * Return: The Probe Response template. %NULL on error.   */  struct sk_buff *ieee80211_proberesp_get(struct ieee80211_hw *hw,  					struct ieee80211_vif *vif); @@ -3124,6 +3242,8 @@ struct sk_buff *ieee80211_proberesp_get(struct ieee80211_hw *hw,   *   * Note: Caller (or hardware) is responsible for setting the   * &IEEE80211_FCTL_PM bit. + * + * Return: The PS Poll template. %NULL on error.   */  struct sk_buff *ieee80211_pspoll_get(struct ieee80211_hw *hw,  				     struct ieee80211_vif *vif); @@ -3139,6 +3259,8 @@ struct sk_buff *ieee80211_pspoll_get(struct ieee80211_hw *hw,   *   * Note: Caller (or hardware) is responsible for setting the   * &IEEE80211_FCTL_PM bit as well as Duration and Sequence Control fields. + * + * Return: The nullfunc template. %NULL on error.   */  struct sk_buff *ieee80211_nullfunc_get(struct ieee80211_hw *hw,  				       struct ieee80211_vif *vif); @@ -3153,6 +3275,8 @@ struct sk_buff *ieee80211_nullfunc_get(struct ieee80211_hw *hw,   *   * Creates a Probe Request template which can, for example, be uploaded to   * hardware. + * + * Return: The Probe Request template. %NULL on error.   */  struct sk_buff *ieee80211_probereq_get(struct ieee80211_hw *hw,  				       struct ieee80211_vif *vif, @@ -3188,6 +3312,8 @@ void ieee80211_rts_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif,   * If the RTS is generated in firmware, but the host system must provide   * the duration field, the low-level driver uses this function to receive   * the duration field value in little-endian byteorder. + * + * Return: The duration.   */  __le16 ieee80211_rts_duration(struct ieee80211_hw *hw,  			      struct ieee80211_vif *vif, size_t frame_len, @@ -3223,6 +3349,8 @@ void ieee80211_ctstoself_get(struct ieee80211_hw *hw,   * If the CTS-to-self is generated in firmware, but the host system must provide   * the duration field, the low-level driver uses this function to receive   * the duration field value in little-endian byteorder. + * + * Return: The duration.   */  __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw,  				    struct ieee80211_vif *vif, @@ -3239,6 +3367,8 @@ __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw,   *   * Calculate the duration field of some generic frame, given its   * length and transmission rate (in 100kbps). + * + * Return: The duration.   */  __le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw,  					struct ieee80211_vif *vif, @@ -3255,9 +3385,10 @@ __le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw,   * hardware/firmware does not implement buffering of broadcast/multicast   * frames when power saving is used, 802.11 code buffers them in the host   * memory. The low-level driver uses this function to fetch next buffered - * frame. In most cases, this is used when generating beacon frame. This - * function returns a pointer to the next buffered skb or NULL if no more - * buffered frames are available. + * frame. In most cases, this is used when generating beacon frame. + * + * Return: A pointer to the next buffered skb or NULL if no more buffered + * frames are available.   *   * Note: buffered frames are returned only after DTIM beacon frame was   * generated with ieee80211_beacon_get() and the low-level driver must thus @@ -3437,6 +3568,8 @@ void ieee80211_stop_queue(struct ieee80211_hw *hw, int queue);   * @queue: queue number (counted from zero).   *   * Drivers should use this function instead of netif_stop_queue. + * + * Return: %true if the queue is stopped. %false otherwise.   */  int ieee80211_queue_stopped(struct ieee80211_hw *hw, int queue); @@ -3634,7 +3767,9 @@ void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_vif *vif, const u8 *ra,   * @vif: virtual interface to look for station on   * @addr: station's address   * - * This function must be called under RCU lock and the + * Return: The station, if found. %NULL otherwise. + * + * Note: This function must be called under RCU lock and the   * resulting pointer is only valid under RCU lock as well.   */  struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_vif *vif, @@ -3647,7 +3782,9 @@ struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_vif *vif,   * @addr: remote station's address   * @localaddr: local address (vif->sdata->vif.addr). Use NULL for 'any'.   * - * This function must be called under RCU lock and the + * Return: The station, if found. %NULL otherwise. + * + * Note: This function must be called under RCU lock and the   * resulting pointer is only valid under RCU lock as well.   *   * NOTE: You may pass NULL for localaddr, but then you will just get @@ -3754,6 +3891,11 @@ void ieee80211_iter_keys(struct ieee80211_hw *hw,   * The iterator will not find a context that's being added (during   * the driver callback to add it) but will find it while it's being   * removed. + * + * Note that during hardware restart, all contexts that existed + * before the restart are considered already present so will be + * found while iterating, whether they've been re-added already + * or not.   */  void ieee80211_iter_chan_contexts_atomic(  	struct ieee80211_hw *hw, @@ -3772,7 +3914,9 @@ void ieee80211_iter_chan_contexts_atomic(   * information. This function must only be called from within the   * .bss_info_changed callback function and only in managed mode. The function   * is only useful when the interface is associated, otherwise it will return - * NULL. + * %NULL. + * + * Return: The Probe Request template. %NULL on error.   */  struct sk_buff *ieee80211_ap_probereq_get(struct ieee80211_hw *hw,  					  struct ieee80211_vif *vif); @@ -3796,6 +3940,8 @@ void ieee80211_beacon_loss(struct ieee80211_vif *vif);   * When beacon filtering is enabled with %IEEE80211_VIF_BEACON_FILTER, and   * %IEEE80211_CONF_PS and %IEEE80211_HW_CONNECTION_MONITOR are set, the driver   * needs to inform if the connection to the AP has been lost. + * The function may also be called if the connection needs to be terminated + * for some other reason, even if %IEEE80211_HW_CONNECTION_MONITOR isn't set.   *   * This function will cause immediate change to disassociated state,   * without connection recovery attempts. @@ -3826,36 +3972,6 @@ void ieee80211_connection_loss(struct ieee80211_vif *vif);  void ieee80211_resume_disconnect(struct ieee80211_vif *vif);  /** - * ieee80211_disable_dyn_ps - force mac80211 to temporarily disable dynamic psm - * - * @vif: &struct ieee80211_vif pointer from the add_interface callback. - * - * Some hardware require full power save to manage simultaneous BT traffic - * on the WLAN frequency. Full PSM is required periodically, whenever there are - * burst of BT traffic. The hardware gets information of BT traffic via - * hardware co-existence lines, and consequentially requests mac80211 to - * (temporarily) enter full psm. - * This function will only temporarily disable dynamic PS, not enable PSM if - * it was not already enabled. - * The driver must make sure to re-enable dynamic PS using - * ieee80211_enable_dyn_ps() if the driver has disabled it. - * - */ -void ieee80211_disable_dyn_ps(struct ieee80211_vif *vif); - -/** - * ieee80211_enable_dyn_ps - restore dynamic psm after being disabled - * - * @vif: &struct ieee80211_vif pointer from the add_interface callback. - * - * This function restores dynamic PS after being temporarily disabled via - * ieee80211_disable_dyn_ps(). Each ieee80211_disable_dyn_ps() call must - * be coupled with an eventual call to this function. - * - */ -void ieee80211_enable_dyn_ps(struct ieee80211_vif *vif); - -/**   * ieee80211_cqm_rssi_notify - inform a configured connection quality monitoring   *	rssi threshold triggered   * @@ -3872,6 +3988,13 @@ void ieee80211_cqm_rssi_notify(struct ieee80211_vif *vif,  			       gfp_t gfp);  /** + * ieee80211_radar_detected - inform that a radar was detected + * + * @hw: pointer as obtained from ieee80211_alloc_hw() + */ +void ieee80211_radar_detected(struct ieee80211_hw *hw); + +/**   * ieee80211_chswitch_done - Complete channel switch process   * @vif: &struct ieee80211_vif pointer from the add_interface callback.   * @success: make the channel switch successful or not @@ -4119,13 +4242,27 @@ void ieee80211_enable_rssi_reports(struct ieee80211_vif *vif,  void ieee80211_disable_rssi_reports(struct ieee80211_vif *vif);  /** - * ieee80211_ave_rssi - report the average rssi for the specified interface + * ieee80211_ave_rssi - report the average RSSI for the specified interface   *   * @vif: the specified virtual interface   * - * This function return the average rssi value for the requested interface. - * It assumes that the given vif is valid. + * Note: This function assumes that the given vif is valid. + * + * Return: The average RSSI value for the requested interface, or 0 if not + * applicable.   */  int ieee80211_ave_rssi(struct ieee80211_vif *vif); +/** + * ieee80211_report_wowlan_wakeup - report WoWLAN wakeup + * @vif: virtual interface + * @wakeup: wakeup reason(s) + * @gfp: allocation flags + * + * See cfg80211_report_wowlan_wakeup(). + */ +void ieee80211_report_wowlan_wakeup(struct ieee80211_vif *vif, +				    struct cfg80211_wowlan_wakeup *wakeup, +				    gfp_t gfp); +  #endif /* MAC80211_H */ diff --git a/include/net/mrp.h b/include/net/mrp.h new file mode 100644 index 000000000000..4fbf02aa2ec1 --- /dev/null +++ b/include/net/mrp.h @@ -0,0 +1,143 @@ +#ifndef _NET_MRP_H +#define _NET_MRP_H + +#define MRP_END_MARK		0x0 + +struct mrp_pdu_hdr { +	u8	version; +}; + +struct mrp_msg_hdr { +	u8	attrtype; +	u8	attrlen; +}; + +struct mrp_vecattr_hdr { +	__be16	lenflags; +	unsigned char	firstattrvalue[]; +#define MRP_VECATTR_HDR_LEN_MASK cpu_to_be16(0x1FFF) +#define MRP_VECATTR_HDR_FLAG_LA cpu_to_be16(0x2000) +}; + +enum mrp_vecattr_event { +	MRP_VECATTR_EVENT_NEW, +	MRP_VECATTR_EVENT_JOIN_IN, +	MRP_VECATTR_EVENT_IN, +	MRP_VECATTR_EVENT_JOIN_MT, +	MRP_VECATTR_EVENT_MT, +	MRP_VECATTR_EVENT_LV, +	__MRP_VECATTR_EVENT_MAX +}; + +struct mrp_skb_cb { +	struct mrp_msg_hdr	*mh; +	struct mrp_vecattr_hdr	*vah; +	unsigned char		attrvalue[]; +}; + +static inline struct mrp_skb_cb *mrp_cb(struct sk_buff *skb) +{ +	BUILD_BUG_ON(sizeof(struct mrp_skb_cb) > +		     FIELD_SIZEOF(struct sk_buff, cb)); +	return (struct mrp_skb_cb *)skb->cb; +} + +enum mrp_applicant_state { +	MRP_APPLICANT_INVALID, +	MRP_APPLICANT_VO, +	MRP_APPLICANT_VP, +	MRP_APPLICANT_VN, +	MRP_APPLICANT_AN, +	MRP_APPLICANT_AA, +	MRP_APPLICANT_QA, +	MRP_APPLICANT_LA, +	MRP_APPLICANT_AO, +	MRP_APPLICANT_QO, +	MRP_APPLICANT_AP, +	MRP_APPLICANT_QP, +	__MRP_APPLICANT_MAX +}; +#define MRP_APPLICANT_MAX	(__MRP_APPLICANT_MAX - 1) + +enum mrp_event { +	MRP_EVENT_NEW, +	MRP_EVENT_JOIN, +	MRP_EVENT_LV, +	MRP_EVENT_TX, +	MRP_EVENT_R_NEW, +	MRP_EVENT_R_JOIN_IN, +	MRP_EVENT_R_IN, +	MRP_EVENT_R_JOIN_MT, +	MRP_EVENT_R_MT, +	MRP_EVENT_R_LV, +	MRP_EVENT_R_LA, +	MRP_EVENT_REDECLARE, +	MRP_EVENT_PERIODIC, +	__MRP_EVENT_MAX +}; +#define MRP_EVENT_MAX		(__MRP_EVENT_MAX - 1) + +enum mrp_tx_action { +	MRP_TX_ACTION_NONE, +	MRP_TX_ACTION_S_NEW, +	MRP_TX_ACTION_S_JOIN_IN, +	MRP_TX_ACTION_S_JOIN_IN_OPTIONAL, +	MRP_TX_ACTION_S_IN_OPTIONAL, +	MRP_TX_ACTION_S_LV, +}; + +struct mrp_attr { +	struct rb_node			node; +	enum mrp_applicant_state	state; +	u8				type; +	u8				len; +	unsigned char			value[]; +}; + +enum mrp_applications { +	MRP_APPLICATION_MVRP, +	__MRP_APPLICATION_MAX +}; +#define MRP_APPLICATION_MAX	(__MRP_APPLICATION_MAX - 1) + +struct mrp_application { +	enum mrp_applications	type; +	unsigned int		maxattr; +	struct packet_type	pkttype; +	unsigned char		group_address[ETH_ALEN]; +	u8			version; +}; + +struct mrp_applicant { +	struct mrp_application	*app; +	struct net_device	*dev; +	struct timer_list	join_timer; + +	spinlock_t		lock; +	struct sk_buff_head	queue; +	struct sk_buff		*pdu; +	struct rb_root		mad; +	struct rcu_head		rcu; +}; + +struct mrp_port { +	struct mrp_applicant __rcu	*applicants[MRP_APPLICATION_MAX + 1]; +	struct rcu_head			rcu; +}; + +extern int	mrp_register_application(struct mrp_application *app); +extern void	mrp_unregister_application(struct mrp_application *app); + +extern int	mrp_init_applicant(struct net_device *dev, +				    struct mrp_application *app); +extern void	mrp_uninit_applicant(struct net_device *dev, +				      struct mrp_application *app); + +extern int	mrp_request_join(const struct net_device *dev, +				  const struct mrp_application *app, +				  const void *value, u8 len, u8 type); +extern void	mrp_request_leave(const struct net_device *dev, +				   const struct mrp_application *app, +				   const void *value, u8 len, u8 type); + +#endif /* _NET_MRP_H */ diff --git a/include/net/ndisc.h b/include/net/ndisc.h index 23b3a7c58783..745bf741e029 100644 --- a/include/net/ndisc.h +++ b/include/net/ndisc.h @@ -127,13 +127,19 @@ static int ndisc_addr_option_pad(unsigned short type)  	}  } +static inline int ndisc_opt_addr_space(struct net_device *dev) +{ +	return NDISC_OPT_SPACE(dev->addr_len + +			       ndisc_addr_option_pad(dev->type)); +} +  static inline u8 *ndisc_opt_addr_data(struct nd_opt_hdr *p,  				      struct net_device *dev)  {  	u8 *lladdr = (u8 *)(p + 1);  	int lladdrlen = p->nd_opt_len << 3;  	int prepad = ndisc_addr_option_pad(dev->type); -	if (lladdrlen != NDISC_OPT_SPACE(dev->addr_len + prepad)) +	if (lladdrlen != ndisc_opt_addr_space(dev))  		return NULL;  	return lladdr + prepad;  } @@ -148,15 +154,14 @@ static inline u32 ndisc_hashfn(const void *pkey, const struct net_device *dev, _  		(p32[3] * hash_rnd[3]));  } -static inline struct neighbour *__ipv6_neigh_lookup(struct neigh_table *tbl, struct net_device *dev, const void *pkey) +static inline struct neighbour *__ipv6_neigh_lookup_noref(struct net_device *dev, const void *pkey)  {  	struct neigh_hash_table *nht;  	const u32 *p32 = pkey;  	struct neighbour *n;  	u32 hash_val; -	rcu_read_lock_bh(); -	nht = rcu_dereference_bh(tbl->nht); +	nht = rcu_dereference_bh(nd_tbl.nht);  	hash_val = ndisc_hashfn(pkey, dev, nht->hash_rnd) >> (32 - nht->hash_shift);  	for (n = rcu_dereference_bh(nht->hash_buckets[hash_val]);  	     n != NULL; @@ -164,12 +169,21 @@ static inline struct neighbour *__ipv6_neigh_lookup(struct neigh_table *tbl, str  		u32 *n32 = (u32 *) n->primary_key;  		if (n->dev == dev &&  		    ((n32[0] ^ p32[0]) | (n32[1] ^ p32[1]) | -		     (n32[2] ^ p32[2]) | (n32[3] ^ p32[3])) == 0) { -			if (!atomic_inc_not_zero(&n->refcnt)) -				n = NULL; -			break; -		} +		     (n32[2] ^ p32[2]) | (n32[3] ^ p32[3])) == 0) +			return n;  	} + +	return NULL; +} + +static inline struct neighbour *__ipv6_neigh_lookup(struct net_device *dev, const void *pkey) +{ +	struct neighbour *n; + +	rcu_read_lock_bh(); +	n = __ipv6_neigh_lookup_noref(dev, pkey); +	if (n && !atomic_inc_not_zero(&n->refcnt)) +		n = NULL;  	rcu_read_unlock_bh();  	return n; diff --git a/include/net/neighbour.h b/include/net/neighbour.h index 0dab173e27da..7e748ad8b50c 100644 --- a/include/net/neighbour.h +++ b/include/net/neighbour.h @@ -181,10 +181,11 @@ struct neigh_table {  };  #define NEIGH_PRIV_ALIGN	sizeof(long long) +#define NEIGH_ENTRY_SIZE(size)	ALIGN((size), NEIGH_PRIV_ALIGN)  static inline void *neighbour_priv(const struct neighbour *n)  { -	return (char *)n + ALIGN(sizeof(*n) + n->tbl->key_len, NEIGH_PRIV_ALIGN); +	return (char *)n + n->tbl->entry_size;  }  /* flags for neigh_update() */ diff --git a/include/net/netevent.h b/include/net/netevent.h index 3ce4988c9c08..fe630dde35c3 100644 --- a/include/net/netevent.h +++ b/include/net/netevent.h @@ -16,9 +16,8 @@ struct neighbour;  struct netevent_redirect {  	struct dst_entry *old; -	struct neighbour *old_neigh;  	struct dst_entry *new; -	struct neighbour *new_neigh; +	struct neighbour *neigh;  	const void *daddr;  }; diff --git a/include/net/netfilter/nf_conntrack_acct.h b/include/net/netfilter/nf_conntrack_acct.h index 463ae8e16696..2bdb7a15fe06 100644 --- a/include/net/netfilter/nf_conntrack_acct.h +++ b/include/net/netfilter/nf_conntrack_acct.h @@ -57,7 +57,9 @@ static inline void nf_ct_set_acct(struct net *net, bool enable)  	net->ct.sysctl_acct = enable;  } -extern int nf_conntrack_acct_init(struct net *net); -extern void nf_conntrack_acct_fini(struct net *net); +extern int nf_conntrack_acct_pernet_init(struct net *net); +extern void nf_conntrack_acct_pernet_fini(struct net *net); +extern int nf_conntrack_acct_init(void); +extern void nf_conntrack_acct_fini(void);  #endif /* _NF_CONNTRACK_ACCT_H */ diff --git a/include/net/netfilter/nf_conntrack_core.h b/include/net/netfilter/nf_conntrack_core.h index e98aeb3da033..930275fa2ea6 100644 --- a/include/net/netfilter/nf_conntrack_core.h +++ b/include/net/netfilter/nf_conntrack_core.h @@ -25,12 +25,19 @@ extern unsigned int nf_conntrack_in(struct net *net,  				    unsigned int hooknum,  				    struct sk_buff *skb); -extern int nf_conntrack_init(struct net *net); -extern void nf_conntrack_cleanup(struct net *net); +extern int nf_conntrack_init_net(struct net *net); +extern void nf_conntrack_cleanup_net(struct net *net); -extern int nf_conntrack_proto_init(struct net *net); -extern void nf_conntrack_proto_fini(struct net *net); +extern int nf_conntrack_proto_pernet_init(struct net *net); +extern void nf_conntrack_proto_pernet_fini(struct net *net); +extern int nf_conntrack_proto_init(void); +extern void nf_conntrack_proto_fini(void); + +extern int nf_conntrack_init_start(void); +extern void nf_conntrack_cleanup_start(void); + +extern void nf_conntrack_init_end(void);  extern void nf_conntrack_cleanup_end(void);  extern bool diff --git a/include/net/netfilter/nf_conntrack_ecache.h b/include/net/netfilter/nf_conntrack_ecache.h index 5654d292efd4..092dc651689f 100644 --- a/include/net/netfilter/nf_conntrack_ecache.h +++ b/include/net/netfilter/nf_conntrack_ecache.h @@ -207,9 +207,11 @@ nf_ct_expect_event(enum ip_conntrack_expect_events event,  	nf_ct_expect_event_report(event, exp, 0, 0);  } -extern int nf_conntrack_ecache_init(struct net *net); -extern void nf_conntrack_ecache_fini(struct net *net); +extern int nf_conntrack_ecache_pernet_init(struct net *net); +extern void nf_conntrack_ecache_pernet_fini(struct net *net); +extern int nf_conntrack_ecache_init(void); +extern void nf_conntrack_ecache_fini(void);  #else /* CONFIG_NF_CONNTRACK_EVENTS */  static inline void nf_conntrack_event_cache(enum ip_conntrack_events event, @@ -232,12 +234,21 @@ static inline void nf_ct_expect_event_report(enum ip_conntrack_expect_events e,   					     u32 portid,   					     int report) {} -static inline int nf_conntrack_ecache_init(struct net *net) +static inline int nf_conntrack_ecache_pernet_init(struct net *net)  {  	return 0;  } -static inline void nf_conntrack_ecache_fini(struct net *net) +static inline void nf_conntrack_ecache_pernet_fini(struct net *net) +{ +} + +static inline int nf_conntrack_ecache_init(void) +{ +	return 0; +} + +static inline void nf_conntrack_ecache_fini(void)  {  }  #endif /* CONFIG_NF_CONNTRACK_EVENTS */ diff --git a/include/net/netfilter/nf_conntrack_expect.h b/include/net/netfilter/nf_conntrack_expect.h index cc13f377a705..cbbae7621e22 100644 --- a/include/net/netfilter/nf_conntrack_expect.h +++ b/include/net/netfilter/nf_conntrack_expect.h @@ -69,8 +69,11 @@ struct nf_conntrack_expect_policy {  #define NF_CT_EXPECT_CLASS_DEFAULT	0 -int nf_conntrack_expect_init(struct net *net); -void nf_conntrack_expect_fini(struct net *net); +int nf_conntrack_expect_pernet_init(struct net *net); +void nf_conntrack_expect_pernet_fini(struct net *net); + +int nf_conntrack_expect_init(void); +void nf_conntrack_expect_fini(void);  struct nf_conntrack_expect *  __nf_ct_expect_find(struct net *net, u16 zone, diff --git a/include/net/netfilter/nf_conntrack_extend.h b/include/net/netfilter/nf_conntrack_extend.h index 8b4d1fc29096..977bc8a46444 100644 --- a/include/net/netfilter/nf_conntrack_extend.h +++ b/include/net/netfilter/nf_conntrack_extend.h @@ -23,6 +23,9 @@ enum nf_ct_ext_id {  #ifdef CONFIG_NF_CONNTRACK_TIMEOUT  	NF_CT_EXT_TIMEOUT,  #endif +#ifdef CONFIG_NF_CONNTRACK_LABELS +	NF_CT_EXT_LABELS, +#endif  	NF_CT_EXT_NUM,  }; @@ -33,6 +36,7 @@ enum nf_ct_ext_id {  #define NF_CT_EXT_ZONE_TYPE struct nf_conntrack_zone  #define NF_CT_EXT_TSTAMP_TYPE struct nf_conn_tstamp  #define NF_CT_EXT_TIMEOUT_TYPE struct nf_conn_timeout +#define NF_CT_EXT_LABELS_TYPE struct nf_conn_labels  /* Extensions: optional stuff which isn't permanently in struct. */  struct nf_ct_ext { diff --git a/include/net/netfilter/nf_conntrack_helper.h b/include/net/netfilter/nf_conntrack_helper.h index 9aad956d1008..26c4ae5bfbb8 100644 --- a/include/net/netfilter/nf_conntrack_helper.h +++ b/include/net/netfilter/nf_conntrack_helper.h @@ -82,8 +82,11 @@ static inline void *nfct_help_data(const struct nf_conn *ct)  	return (void *)help->data;  } -extern int nf_conntrack_helper_init(struct net *net); -extern void nf_conntrack_helper_fini(struct net *net); +extern int nf_conntrack_helper_pernet_init(struct net *net); +extern void nf_conntrack_helper_pernet_fini(struct net *net); + +extern int nf_conntrack_helper_init(void); +extern void nf_conntrack_helper_fini(void);  extern int nf_conntrack_broadcast_help(struct sk_buff *skb,  				       unsigned int protoff, @@ -97,6 +100,10 @@ struct nf_ct_helper_expectfn {  	void (*expectfn)(struct nf_conn *ct, struct nf_conntrack_expect *exp);  }; +__printf(3,4) +void nf_ct_helper_log(struct sk_buff *skb, const struct nf_conn *ct, +		      const char *fmt, ...); +  void nf_ct_helper_expectfn_register(struct nf_ct_helper_expectfn *n);  void nf_ct_helper_expectfn_unregister(struct nf_ct_helper_expectfn *n);  struct nf_ct_helper_expectfn * diff --git a/include/net/netfilter/nf_conntrack_l3proto.h b/include/net/netfilter/nf_conntrack_l3proto.h index 6f7c13f4ac03..3bb89eac3fa1 100644 --- a/include/net/netfilter/nf_conntrack_l3proto.h +++ b/include/net/netfilter/nf_conntrack_l3proto.h @@ -76,11 +76,16 @@ struct nf_conntrack_l3proto {  extern struct nf_conntrack_l3proto __rcu *nf_ct_l3protos[AF_MAX]; -/* Protocol registration. */ -extern int nf_conntrack_l3proto_register(struct net *net, +/* Protocol pernet registration. */ +extern int nf_ct_l3proto_pernet_register(struct net *net,  					 struct nf_conntrack_l3proto *proto); -extern void nf_conntrack_l3proto_unregister(struct net *net, +extern void nf_ct_l3proto_pernet_unregister(struct net *net,  					    struct nf_conntrack_l3proto *proto); + +/* Protocol global registration. */ +extern int nf_ct_l3proto_register(struct nf_conntrack_l3proto *proto); +extern void nf_ct_l3proto_unregister(struct nf_conntrack_l3proto *proto); +  extern struct nf_conntrack_l3proto *nf_ct_l3proto_find_get(u_int16_t l3proto);  extern void nf_ct_l3proto_put(struct nf_conntrack_l3proto *p); diff --git a/include/net/netfilter/nf_conntrack_l4proto.h b/include/net/netfilter/nf_conntrack_l4proto.h index c3be4aef6bf7..914d8d900798 100644 --- a/include/net/netfilter/nf_conntrack_l4proto.h +++ b/include/net/netfilter/nf_conntrack_l4proto.h @@ -121,12 +121,16 @@ extern struct nf_conntrack_l4proto *  nf_ct_l4proto_find_get(u_int16_t l3proto, u_int8_t l4proto);  extern void nf_ct_l4proto_put(struct nf_conntrack_l4proto *p); -/* Protocol registration. */ -extern int nf_conntrack_l4proto_register(struct net *net, +/* Protocol pernet registration. */ +extern int nf_ct_l4proto_pernet_register(struct net *net,  					 struct nf_conntrack_l4proto *proto); -extern void nf_conntrack_l4proto_unregister(struct net *net, +extern void nf_ct_l4proto_pernet_unregister(struct net *net,  					    struct nf_conntrack_l4proto *proto); +/* Protocol global registration. */ +extern int nf_ct_l4proto_register(struct nf_conntrack_l4proto *proto); +extern void nf_ct_l4proto_unregister(struct nf_conntrack_l4proto *proto); +  static inline void nf_ct_kfree_compat_sysctl_table(struct nf_proto_net *pn)  {  #if defined(CONFIG_SYSCTL) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT) diff --git a/include/net/netfilter/nf_conntrack_labels.h b/include/net/netfilter/nf_conntrack_labels.h new file mode 100644 index 000000000000..c985695283b3 --- /dev/null +++ b/include/net/netfilter/nf_conntrack_labels.h @@ -0,0 +1,58 @@ +#include <linux/types.h> +#include <net/net_namespace.h> +#include <linux/netfilter/nf_conntrack_common.h> +#include <linux/netfilter/nf_conntrack_tuple_common.h> +#include <net/netfilter/nf_conntrack.h> +#include <net/netfilter/nf_conntrack_extend.h> + +#include <uapi/linux/netfilter/xt_connlabel.h> + +struct nf_conn_labels { +	u8 words; +	unsigned long bits[]; +}; + +static inline struct nf_conn_labels *nf_ct_labels_find(const struct nf_conn *ct) +{ +#ifdef CONFIG_NF_CONNTRACK_LABELS +	return nf_ct_ext_find(ct, NF_CT_EXT_LABELS); +#else +	return NULL; +#endif +} + +static inline struct nf_conn_labels *nf_ct_labels_ext_add(struct nf_conn *ct) +{ +#ifdef CONFIG_NF_CONNTRACK_LABELS +	struct nf_conn_labels *cl_ext; +	struct net *net = nf_ct_net(ct); +	u8 words; + +	words = ACCESS_ONCE(net->ct.label_words); +	if (words == 0 || WARN_ON_ONCE(words > 8)) +		return NULL; + +	cl_ext = nf_ct_ext_add_length(ct, NF_CT_EXT_LABELS, +				      words * sizeof(long), GFP_ATOMIC); +	if (cl_ext != NULL) +		cl_ext->words = words; + +	return cl_ext; +#else +	return NULL; +#endif +} + +bool nf_connlabel_match(const struct nf_conn *ct, u16 bit); +int nf_connlabel_set(struct nf_conn *ct, u16 bit); + +int nf_connlabels_replace(struct nf_conn *ct, +			  const u32 *data, const u32 *mask, unsigned int words); + +#ifdef CONFIG_NF_CONNTRACK_LABELS +int nf_conntrack_labels_init(void); +void nf_conntrack_labels_fini(void); +#else +static inline int nf_conntrack_labels_init(void) { return 0; } +static inline void nf_conntrack_labels_fini(void) {} +#endif diff --git a/include/net/netfilter/nf_conntrack_timeout.h b/include/net/netfilter/nf_conntrack_timeout.h index e41e472d08f2..d23aceb16d94 100644 --- a/include/net/netfilter/nf_conntrack_timeout.h +++ b/include/net/netfilter/nf_conntrack_timeout.h @@ -76,15 +76,15 @@ nf_ct_timeout_lookup(struct net *net, struct nf_conn *ct,  }  #ifdef CONFIG_NF_CONNTRACK_TIMEOUT -extern int nf_conntrack_timeout_init(struct net *net); -extern void nf_conntrack_timeout_fini(struct net *net); +extern int nf_conntrack_timeout_init(void); +extern void nf_conntrack_timeout_fini(void);  #else -static inline int nf_conntrack_timeout_init(struct net *net) +static inline int nf_conntrack_timeout_init(void)  {          return 0;  } -static inline void nf_conntrack_timeout_fini(struct net *net) +static inline void nf_conntrack_timeout_fini(void)  {          return;  } diff --git a/include/net/netfilter/nf_conntrack_timestamp.h b/include/net/netfilter/nf_conntrack_timestamp.h index fc9c82b1f06b..b00461413efd 100644 --- a/include/net/netfilter/nf_conntrack_timestamp.h +++ b/include/net/netfilter/nf_conntrack_timestamp.h @@ -48,15 +48,28 @@ static inline void nf_ct_set_tstamp(struct net *net, bool enable)  }  #ifdef CONFIG_NF_CONNTRACK_TIMESTAMP -extern int nf_conntrack_tstamp_init(struct net *net); -extern void nf_conntrack_tstamp_fini(struct net *net); +extern int nf_conntrack_tstamp_pernet_init(struct net *net); +extern void nf_conntrack_tstamp_pernet_fini(struct net *net); + +extern int nf_conntrack_tstamp_init(void); +extern void nf_conntrack_tstamp_fini(void);  #else -static inline int nf_conntrack_tstamp_init(struct net *net) +static inline int nf_conntrack_tstamp_pernet_init(struct net *net) +{ +	return 0; +} + +static inline void nf_conntrack_tstamp_pernet_fini(struct net *net) +{ +	return; +} + +static inline int nf_conntrack_tstamp_init(void)  {  	return 0;  } -static inline void nf_conntrack_tstamp_fini(struct net *net) +static inline void nf_conntrack_tstamp_fini(void)  {  	return;  } diff --git a/include/net/netfilter/nf_tproxy_core.h b/include/net/netfilter/nf_tproxy_core.h index 75ca9291cf2c..36d9379d4c4b 100644 --- a/include/net/netfilter/nf_tproxy_core.h +++ b/include/net/netfilter/nf_tproxy_core.h @@ -82,6 +82,7 @@ nf_tproxy_get_sock_v4(struct net *net, const u8 protocol,  			break;  		case NFT_LOOKUP_LISTENER:  			sk = inet_lookup_listener(net, &tcp_hashinfo, +						    saddr, sport,  						    daddr, dport,  						    in->ifindex); @@ -151,6 +152,7 @@ nf_tproxy_get_sock_v6(struct net *net, const u8 protocol,  			break;  		case NFT_LOOKUP_LISTENER:  			sk = inet6_lookup_listener(net, &tcp_hashinfo, +						   saddr, sport,  						   daddr, ntohs(dport),  						   in->ifindex); diff --git a/include/net/netns/conntrack.h b/include/net/netns/conntrack.h index 923cb20051ed..c9c0c538b68b 100644 --- a/include/net/netns/conntrack.h +++ b/include/net/netns/conntrack.h @@ -84,6 +84,10 @@ struct netns_ct {  	int			sysctl_auto_assign_helper;  	bool			auto_assign_helper_warned;  	struct nf_ip_net	nf_ct_proto; +#if defined(CONFIG_NF_CONNTRACK_LABELS) +	unsigned int		labels_used; +	u8			label_words; +#endif  #ifdef CONFIG_NF_NAT_NEEDED  	struct hlist_head	*nat_bysource;  	unsigned int		nat_htable_size; diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h index 2ae2b8372cfd..2ba9de89e8ec 100644 --- a/include/net/netns/ipv4.h +++ b/include/net/netns/ipv4.h @@ -22,6 +22,7 @@ struct netns_ipv4 {  	struct ctl_table_header	*frags_hdr;  	struct ctl_table_header	*ipv4_hdr;  	struct ctl_table_header *route_hdr; +	struct ctl_table_header *xfrm4_hdr;  #endif  	struct ipv4_devconf	*devconf_all;  	struct ipv4_devconf	*devconf_dflt; @@ -61,6 +62,8 @@ struct netns_ipv4 {  	int sysctl_icmp_ratemask;  	int sysctl_icmp_errors_use_inbound_ifaddr; +	int sysctl_tcp_ecn; +  	kgid_t sysctl_ping_group_range[2];  	long sysctl_tcp_mem[3]; diff --git a/include/net/netns/ipv6.h b/include/net/netns/ipv6.h index 214cb0a53359..1242f371718b 100644 --- a/include/net/netns/ipv6.h +++ b/include/net/netns/ipv6.h @@ -16,6 +16,7 @@ struct netns_sysctl_ipv6 {  	struct ctl_table_header *route_hdr;  	struct ctl_table_header *icmp_hdr;  	struct ctl_table_header *frags_hdr; +	struct ctl_table_header *xfrm6_hdr;  #endif  	int bindv6only;  	int flush_delay; diff --git a/include/net/nfc/hci.h b/include/net/nfc/hci.h index 671953e11575..b87a1692b086 100644 --- a/include/net/nfc/hci.h +++ b/include/net/nfc/hci.h @@ -57,8 +57,10 @@ struct nfc_hci_ops {  	int (*tm_send)(struct nfc_hci_dev *hdev, struct sk_buff *skb);  	int (*check_presence)(struct nfc_hci_dev *hdev,  			      struct nfc_target *target); -	void (*event_received)(struct nfc_hci_dev *hdev, u8 gate, u8 event, -				struct sk_buff *skb); +	int (*event_received)(struct nfc_hci_dev *hdev, u8 gate, u8 event, +			      struct sk_buff *skb); +	int (*enable_se)(struct nfc_dev *dev, u32 secure_element); +	int (*disable_se)(struct nfc_dev *dev, u32 secure_element);  };  /* Pipes */ @@ -82,11 +84,23 @@ typedef int (*xmit) (struct sk_buff *skb, void *cb_data);  #define NFC_HCI_MAX_GATES		256 +/* + * These values can be specified by a driver to indicate it requires some + * adaptation of the HCI standard. + * + * NFC_HCI_QUIRK_SHORT_CLEAR - send HCI_ADM_CLEAR_ALL_PIPE cmd with no params + */ +enum { +	NFC_HCI_QUIRK_SHORT_CLEAR	= 0, +}; +  struct nfc_hci_dev {  	struct nfc_dev *ndev;  	u32 max_data_link_payload; +	bool shutting_down; +  	struct mutex msg_tx_mutex;  	struct list_head msg_tx_queue; @@ -129,12 +143,16 @@ struct nfc_hci_dev {  	u8 *gb;  	size_t gb_len; + +	unsigned long quirks;  };  /* hci device allocation */  struct nfc_hci_dev *nfc_hci_allocate_device(struct nfc_hci_ops *ops,  					    struct nfc_hci_init_data *init_data, +					    unsigned long quirks,  					    u32 protocols, +					    u32 supported_se,  					    const char *llc_name,  					    int tx_headroom,  					    int tx_tailroom, diff --git a/include/net/nfc/nci_core.h b/include/net/nfc/nci_core.h index d705d8674949..5bc0c460edc0 100644 --- a/include/net/nfc/nci_core.h +++ b/include/net/nfc/nci_core.h @@ -147,6 +147,7 @@ struct nci_dev {  /* ----- NCI Devices ----- */  struct nci_dev *nci_allocate_device(struct nci_ops *ops,  				    __u32 supported_protocols, +				    __u32 supported_se,  				    int tx_headroom,  				    int tx_tailroom);  void nci_free_device(struct nci_dev *ndev); diff --git a/include/net/nfc/nfc.h b/include/net/nfc/nfc.h index fce80b2f9be7..87a6417fc934 100644 --- a/include/net/nfc/nfc.h +++ b/include/net/nfc/nfc.h @@ -68,6 +68,8 @@ struct nfc_ops {  			     void *cb_context);  	int (*tm_send)(struct nfc_dev *dev, struct sk_buff *skb);  	int (*check_presence)(struct nfc_dev *dev, struct nfc_target *target); +	int (*enable_se)(struct nfc_dev *dev, u32 secure_element); +	int (*disable_se)(struct nfc_dev *dev, u32 secure_element);  };  #define NFC_TARGET_IDX_ANY -1 @@ -109,12 +111,17 @@ struct nfc_dev {  	struct nfc_genl_data genl_data;  	u32 supported_protocols; +	u32 supported_se; +	u32 active_se; +  	int tx_headroom;  	int tx_tailroom;  	struct timer_list check_pres_timer;  	struct work_struct check_pres_work; +	bool shutting_down; +  	struct nfc_ops *ops;  };  #define to_nfc_dev(_dev) container_of(_dev, struct nfc_dev, dev) @@ -123,6 +130,7 @@ extern struct class nfc_class;  struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops,  				    u32 supported_protocols, +				    u32 supported_se,  				    int tx_headroom,  				    int tx_tailroom); diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h index 9fcc680ab6b9..13174509cdfd 100644 --- a/include/net/pkt_cls.h +++ b/include/net/pkt_cls.h @@ -126,9 +126,10 @@ tcf_exts_exec(struct sk_buff *skb, struct tcf_exts *exts,  	return 0;  } -extern int tcf_exts_validate(struct tcf_proto *tp, struct nlattr **tb, -	                     struct nlattr *rate_tlv, struct tcf_exts *exts, -	                     const struct tcf_ext_map *map); +extern int tcf_exts_validate(struct net *net, struct tcf_proto *tp, +			     struct nlattr **tb, struct nlattr *rate_tlv, +			     struct tcf_exts *exts, +			     const struct tcf_ext_map *map);  extern void tcf_exts_destroy(struct tcf_proto *tp, struct tcf_exts *exts);  extern void tcf_exts_change(struct tcf_proto *tp, struct tcf_exts *dst,  	                     struct tcf_exts *src); diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h index 66f5ac370f92..388bf8b6d060 100644 --- a/include/net/pkt_sched.h +++ b/include/net/pkt_sched.h @@ -65,8 +65,14 @@ struct qdisc_watchdog {  };  extern void qdisc_watchdog_init(struct qdisc_watchdog *wd, struct Qdisc *qdisc); -extern void qdisc_watchdog_schedule(struct qdisc_watchdog *wd, -				    psched_time_t expires); +extern void qdisc_watchdog_schedule_ns(struct qdisc_watchdog *wd, u64 expires); + +static inline void qdisc_watchdog_schedule(struct qdisc_watchdog *wd, +					   psched_time_t expires) +{ +	qdisc_watchdog_schedule_ns(wd, PSCHED_TICKS2NS(expires)); +} +  extern void qdisc_watchdog_cancel(struct qdisc_watchdog *wd);  extern struct Qdisc_ops pfifo_qdisc_ops; diff --git a/include/net/regulatory.h b/include/net/regulatory.h index 7dcaa2794fde..f17ed590d64a 100644 --- a/include/net/regulatory.h +++ b/include/net/regulatory.h @@ -18,6 +18,7 @@   * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.   */ +#include <linux/rcupdate.h>  /**   * enum environment_cap - Environment parsed from country IE @@ -35,6 +36,7 @@ enum environment_cap {  /**   * struct regulatory_request - used to keep track of regulatory requests   * + * @rcu_head: RCU head struct used to free the request   * @wiphy_idx: this is set if this request's initiator is   * 	%REGDOM_SET_BY_COUNTRY_IE or %REGDOM_SET_BY_DRIVER. This   * 	can be used by the wireless core to deal with conflicts @@ -72,6 +74,7 @@ enum environment_cap {   * @list: used to insert into the reg_requests_list linked list   */  struct regulatory_request { +	struct rcu_head rcu_head;  	int wiphy_idx;  	enum nl80211_reg_initiator initiator;  	enum nl80211_user_reg_hint_type user_reg_hint_type; @@ -101,6 +104,7 @@ struct ieee80211_reg_rule {  };  struct ieee80211_regdomain { +	struct rcu_head rcu_head;  	u32 n_reg_rules;  	char alpha2[2];  	u8 dfs_region; diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index 1540f9c2fcf4..2761c905504e 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -195,7 +195,7 @@ struct tcf_proto_ops {  	unsigned long		(*get)(struct tcf_proto*, u32 handle);  	void			(*put)(struct tcf_proto*, unsigned long); -	int			(*change)(struct sk_buff *, +	int			(*change)(struct net *net, struct sk_buff *,  					struct tcf_proto*, unsigned long,  					u32 handle, struct nlattr **,  					unsigned long *); @@ -679,4 +679,23 @@ static inline struct sk_buff *skb_act_clone(struct sk_buff *skb, gfp_t gfp_mask,  }  #endif +struct psched_ratecfg { +	u64 rate_bps; +	u32 mult; +	u32 shift; +}; + +static inline u64 psched_l2t_ns(const struct psched_ratecfg *r, +				unsigned int len) +{ +	return ((u64)len * r->mult) >> r->shift; +} + +extern void psched_ratecfg_precompute(struct psched_ratecfg *r, u32 rate); + +static inline u32 psched_ratecfg_getrate(const struct psched_ratecfg *r) +{ +	return r->rate_bps >> 3; +} +  #endif diff --git a/include/net/sctp/constants.h b/include/net/sctp/constants.h index c29707d654c0..a7dd5c50df79 100644 --- a/include/net/sctp/constants.h +++ b/include/net/sctp/constants.h @@ -303,7 +303,7 @@ enum { SCTP_MAX_GABS = 16 };                                           * to which we will raise the P-MTU.  					 */  #define SCTP_DEFAULT_MINSEGMENT 512	/* MTU size ... if no mtu disc */ -#define SCTP_HOW_MANY_SECRETS 2		/* How many secrets I keep */ +  #define SCTP_SECRET_SIZE 32		/* Number of octets in a 256 bits. */  #define SCTP_SIGNATURE_SIZE 20	        /* size of a SLA-1 signature */ diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index fdeb85a970fc..0e0f9d2322e3 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -1236,10 +1236,7 @@ struct sctp_endpoint {  	 *	      Discussion in [RFC1750] can be helpful in  	 *	      selection of the key.  	 */ -	__u8 secret_key[SCTP_HOW_MANY_SECRETS][SCTP_SECRET_SIZE]; -	int current_key; -	int last_key; -	int key_changed_at; +	__u8 secret_key[SCTP_SECRET_SIZE];   	/* digest:  This is a digest of the sctp cookie.  This field is   	 * 	    only used on the receive path when we try to validate diff --git a/include/net/sock.h b/include/net/sock.h index 182ca99405ad..a66caa223d18 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -140,6 +140,7 @@ typedef __u64 __bitwise __addrpair;   *	@skc_family: network address family   *	@skc_state: Connection state   *	@skc_reuse: %SO_REUSEADDR setting + *	@skc_reuseport: %SO_REUSEPORT setting   *	@skc_bound_dev_if: bound device index if != 0   *	@skc_bind_node: bind hash linkage for various protocol lookup tables   *	@skc_portaddr_node: second hash linkage for UDP/UDP-Lite protocol @@ -179,7 +180,8 @@ struct sock_common {  	unsigned short		skc_family;  	volatile unsigned char	skc_state; -	unsigned char		skc_reuse; +	unsigned char		skc_reuse:4; +	unsigned char		skc_reuseport:4;  	int			skc_bound_dev_if;  	union {  		struct hlist_node	skc_bind_node; @@ -297,6 +299,7 @@ struct sock {  #define sk_family		__sk_common.skc_family  #define sk_state		__sk_common.skc_state  #define sk_reuse		__sk_common.skc_reuse +#define sk_reuseport		__sk_common.skc_reuseport  #define sk_bound_dev_if		__sk_common.skc_bound_dev_if  #define sk_bind_node		__sk_common.skc_bind_node  #define sk_prot			__sk_common.skc_prot @@ -337,7 +340,7 @@ struct sock {  #endif  	unsigned long 		sk_flags;  	struct dst_entry	*sk_rx_dst; -	struct dst_entry	*sk_dst_cache; +	struct dst_entry __rcu	*sk_dst_cache;  	spinlock_t		sk_dst_lock;  	atomic_t		sk_wmem_alloc;  	atomic_t		sk_omem_alloc; @@ -664,6 +667,7 @@ enum sock_flags {  		     * Will use last 4 bytes of packet sent from  		     * user-space instead.  		     */ +	SOCK_FILTER_LOCKED, /* Filter cannot be changed anymore */  };  static inline void sock_copy_flags(struct sock *nsk, struct sock *osk) @@ -1037,7 +1041,7 @@ static inline void sk_refcnt_debug_dec(struct sock *sk)  	       sk->sk_prot->name, sk, atomic_read(&sk->sk_prot->socks));  } -inline void sk_refcnt_debug_release(const struct sock *sk) +static inline void sk_refcnt_debug_release(const struct sock *sk)  {  	if (atomic_read(&sk->sk_refcnt) != 1)  		printk(KERN_DEBUG "Destruction of the %s socket %p delayed, refcnt=%d\n", diff --git a/include/net/tcp.h b/include/net/tcp.h index aed42c785153..23f2e98d4b65 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -266,7 +266,6 @@ extern int sysctl_tcp_abort_on_overflow;  extern int sysctl_tcp_max_orphans;  extern int sysctl_tcp_fack;  extern int sysctl_tcp_reordering; -extern int sysctl_tcp_ecn;  extern int sysctl_tcp_dsack;  extern int sysctl_tcp_wmem[3];  extern int sysctl_tcp_rmem[3]; @@ -280,7 +279,6 @@ extern int sysctl_tcp_dma_copybreak;  extern int sysctl_tcp_nometrics_save;  extern int sysctl_tcp_moderate_rcvbuf;  extern int sysctl_tcp_tso_win_divisor; -extern int sysctl_tcp_abc;  extern int sysctl_tcp_mtu_probing;  extern int sysctl_tcp_base_mss;  extern int sysctl_tcp_workaround_signed_windows; @@ -504,7 +502,8 @@ static inline __u32 cookie_v4_init_sequence(struct sock *sk,  #endif  extern __u32 cookie_init_timestamp(struct request_sock *req); -extern bool cookie_check_timestamp(struct tcp_options_received *opt, bool *); +extern bool cookie_check_timestamp(struct tcp_options_received *opt, +				struct net *net, bool *ecn_ok);  /* From net/ipv6/syncookies.c */  extern struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb); @@ -728,11 +727,12 @@ struct tcp_skb_cb {   * notifications, we disable TCP ECN negociation.   */  static inline void -TCP_ECN_create_request(struct request_sock *req, const struct sk_buff *skb) +TCP_ECN_create_request(struct request_sock *req, const struct sk_buff *skb, +		struct net *net)  {  	const struct tcphdr *th = tcp_hdr(skb); -	if (sysctl_tcp_ecn && th->ece && th->cwr && +	if (net->ipv4.sysctl_tcp_ecn && th->ece && th->cwr &&  	    INET_ECN_is_not_ect(TCP_SKB_CB(skb)->ip_dsfield))  		inet_rsk(req)->ecn_ok = 1;  } diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 63445ede48bb..24c8886fd969 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -501,6 +501,12 @@ struct xfrm_policy_walk {  	u32 seq;  }; +struct xfrm_policy_queue { +	struct sk_buff_head	hold_queue; +	struct timer_list	hold_timer; +	unsigned long		timeout; +}; +  struct xfrm_policy {  #ifdef CONFIG_NET_NS  	struct net		*xp_net; @@ -522,6 +528,7 @@ struct xfrm_policy {  	struct xfrm_lifetime_cfg lft;  	struct xfrm_lifetime_cur curlft;  	struct xfrm_policy_walk_entry walk; +	struct xfrm_policy_queue polq;  	u8			type;  	u8			action;  	u8			flags; @@ -557,10 +564,6 @@ struct xfrm_migrate {  };  #define XFRM_KM_TIMEOUT                30 -/* which seqno */ -#define XFRM_REPLAY_SEQ		1 -#define XFRM_REPLAY_OSEQ	2 -#define XFRM_REPLAY_SEQ_MASK	3  /* what happened */  #define XFRM_REPLAY_UPDATE	XFRM_AE_CR  #define XFRM_REPLAY_TIMEOUT	XFRM_AE_CE @@ -1036,7 +1039,7 @@ static inline int  __xfrm6_state_addr_cmp(const struct xfrm_tmpl *tmpl, const struct xfrm_state *x)  {  	return	(!ipv6_addr_any((struct in6_addr*)&tmpl->saddr) && -		 ipv6_addr_cmp((struct in6_addr *)&tmpl->saddr, (struct in6_addr*)&x->props.saddr)); +		 !ipv6_addr_equal((struct in6_addr *)&tmpl->saddr, (struct in6_addr*)&x->props.saddr));  }  static inline int @@ -1247,8 +1250,8 @@ static __inline__ int  __xfrm6_state_addr_check(const struct xfrm_state *x,  			 const xfrm_address_t *daddr, const xfrm_address_t *saddr)  { -	if (!ipv6_addr_cmp((struct in6_addr *)daddr, (struct in6_addr *)&x->id.daddr) && -	    (!ipv6_addr_cmp((struct in6_addr *)saddr, (struct in6_addr *)&x->props.saddr)||  +	if (ipv6_addr_equal((struct in6_addr *)daddr, (struct in6_addr *)&x->id.daddr) && +	    (ipv6_addr_equal((struct in6_addr *)saddr, (struct in6_addr *)&x->props.saddr) ||  	     ipv6_addr_any((struct in6_addr *)saddr) ||   	     ipv6_addr_any((struct in6_addr *)&x->props.saddr)))  		return 1; @@ -1324,6 +1327,7 @@ struct xfrm_algo_desc {  	char *name;  	char *compat;  	u8 available:1; +	u8 pfkey_supported:1;  	union {  		struct xfrm_algo_aead_info aead;  		struct xfrm_algo_auth_info auth; @@ -1565,8 +1569,8 @@ extern void xfrm_input_init(void);  extern int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq);  extern void xfrm_probe_algs(void); -extern int xfrm_count_auth_supported(void); -extern int xfrm_count_enc_supported(void); +extern int xfrm_count_pfkey_auth_supported(void); +extern int xfrm_count_pfkey_enc_supported(void);  extern struct xfrm_algo_desc *xfrm_aalg_get_byidx(unsigned int idx);  extern struct xfrm_algo_desc *xfrm_ealg_get_byidx(unsigned int idx);  extern struct xfrm_algo_desc *xfrm_aalg_get_byid(int alg_id); @@ -1578,17 +1582,23 @@ extern struct xfrm_algo_desc *xfrm_calg_get_byname(const char *name, int probe);  extern struct xfrm_algo_desc *xfrm_aead_get_byname(const char *name, int icv_len,  						   int probe); -static inline int xfrm_addr_cmp(const xfrm_address_t *a, -				const xfrm_address_t *b, -				int family) +static inline bool xfrm6_addr_equal(const xfrm_address_t *a, +				    const xfrm_address_t *b) +{ +	return ipv6_addr_equal((const struct in6_addr *)a, +			       (const struct in6_addr *)b); +} + +static inline bool xfrm_addr_equal(const xfrm_address_t *a, +				   const xfrm_address_t *b, +				   sa_family_t family)  {  	switch (family) {  	default:  	case AF_INET: -		return (__force u32)a->a4 - (__force u32)b->a4; +		return ((__force u32)a->a4 ^ (__force u32)b->a4) == 0;  	case AF_INET6: -		return ipv6_addr_cmp((const struct in6_addr *)a, -				     (const struct in6_addr *)b); +		return xfrm6_addr_equal(a, b);  	}  } |