diff options
Diffstat (limited to 'include/net')
93 files changed, 1995 insertions, 1035 deletions
diff --git a/include/net/9p/client.h b/include/net/9p/client.h index e26812274b75..f076dfa75ae8 100644 --- a/include/net/9p/client.h +++ b/include/net/9p/client.h @@ -29,6 +29,19 @@ /* Number of requests per row */ #define P9_ROW_MAXTAG 255 +/** enum p9_proto_versions - 9P protocol versions + * @p9_proto_legacy: 9P Legacy mode, pre-9P2000.u + * @p9_proto_2000u: 9P2000.u extension + * @p9_proto_2000L: 9P2000.L extension + */ + +enum p9_proto_versions{ + p9_proto_legacy = 0, + p9_proto_2000u = 1, + p9_proto_2000L = 2, +}; + + /** * enum p9_trans_status - different states of underlying transports * @Connected: transport is connected and healthy @@ -111,6 +124,7 @@ struct p9_req_t { * @lock: protect @fidlist * @msize: maximum data size negotiated by protocol * @dotu: extension flags negotiated by protocol + * @proto_version: 9P protocol version to use * @trans_mod: module API instantiated with this client * @trans: tranport instance state and API * @conn: connection state information used by trans_fd @@ -137,7 +151,7 @@ struct p9_req_t { struct p9_client { spinlock_t lock; /* protect client structure */ int msize; - unsigned char dotu; + unsigned char proto_version; struct p9_trans_module *trans_mod; enum p9_trans_status status; void *trans; @@ -159,8 +173,7 @@ struct p9_client { * @qid: the &p9_qid server identifier this handle points to * @iounit: the server reported maximum transaction size for this file * @uid: the numeric uid of the local user who owns this handle - * @aux: transport specific information (unused?) - * @rdir_fpos: tracks offset of file position when reading directory contents + * @rdir: readdir accounting structure (allocated on demand) * @flist: per-client-instance fid tracking * @dlist: per-dentry fid tracking * @@ -174,9 +187,9 @@ struct p9_fid { struct p9_qid qid; u32 iounit; uid_t uid; - void *aux; - int rdir_fpos; + void *rdir; + struct list_head flist; struct list_head dlist; /* list of all fids attached to a dentry */ }; @@ -210,5 +223,7 @@ int p9_parse_header(struct p9_fcall *, int32_t *, int8_t *, int16_t *, int); int p9stat_read(char *, int, struct p9_wstat *, int); void p9stat_free(struct p9_wstat *); +int p9_is_proto_dotu(struct p9_client *clnt); +int p9_is_proto_dotl(struct p9_client *clnt); #endif /* NET_9P_CLIENT_H */ diff --git a/include/net/addrconf.h b/include/net/addrconf.h index 0f7c37825fc1..45375b41a2a0 100644 --- a/include/net/addrconf.h +++ b/include/net/addrconf.h @@ -177,7 +177,9 @@ extern int unregister_inet6addr_notifier(struct notifier_block *nb); static inline struct inet6_dev * __in6_dev_get(struct net_device *dev) { - return rcu_dereference(dev->ip6_ptr); + return rcu_dereference_check(dev->ip6_ptr, + rcu_read_lock_held() || + lockdep_rtnl_is_held()); } static inline struct inet6_dev * diff --git a/include/net/ah.h b/include/net/ah.h index ae1c322f4242..f0129f79a31a 100644 --- a/include/net/ah.h +++ b/include/net/ah.h @@ -1,43 +1,20 @@ #ifndef _NET_AH_H #define _NET_AH_H -#include <linux/crypto.h> -#include <net/xfrm.h> +#include <linux/skbuff.h> /* This is the maximum truncated ICV length that we know of. */ #define MAX_AH_AUTH_LEN 12 -struct ah_data -{ - u8 *work_icv; +struct crypto_ahash; + +struct ah_data { int icv_full_len; int icv_trunc_len; - struct crypto_hash *tfm; + struct crypto_ahash *ahash; }; -static inline int ah_mac_digest(struct ah_data *ahp, struct sk_buff *skb, - u8 *auth_data) -{ - struct hash_desc desc; - int err; - - desc.tfm = ahp->tfm; - desc.flags = 0; - - memset(auth_data, 0, ahp->icv_trunc_len); - err = crypto_hash_init(&desc); - if (unlikely(err)) - goto out; - err = skb_icv_walk(skb, &desc, 0, skb->len, crypto_hash_update); - if (unlikely(err)) - goto out; - err = crypto_hash_final(&desc, ahp->work_icv); - -out: - return err; -} - struct ip_auth_hdr; static inline struct ip_auth_hdr *ip_auth_hdr(const struct sk_buff *skb) diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h index 718394e2c01e..04a6908e38d2 100644 --- a/include/net/bluetooth/bluetooth.h +++ b/include/net/bluetooth/bluetooth.h @@ -121,7 +121,7 @@ struct bt_sock_list { rwlock_t lock; }; -int bt_sock_register(int proto, struct net_proto_family *ops); +int bt_sock_register(int proto, const struct net_proto_family *ops); int bt_sock_unregister(int proto); void bt_sock_link(struct bt_sock_list *l, struct sock *s); void bt_sock_unlink(struct bt_sock_list *l, struct sock *s); diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index ed3aea1605e8..fc0c502d9fd1 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -43,7 +43,7 @@ #define HCI_NOTIFY_CONN_DEL 2 #define HCI_NOTIFY_VOICE_SETTING 3 -/* HCI device types */ +/* HCI bus types */ #define HCI_VIRTUAL 0 #define HCI_USB 1 #define HCI_PCCARD 2 @@ -52,6 +52,10 @@ #define HCI_PCI 5 #define HCI_SDIO 6 +/* HCI controller types */ +#define HCI_BREDR 0x00 +#define HCI_80211 0x01 + /* HCI device quirks */ enum { HCI_QUIRK_NO_RESET, diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 7b640aeddb64..ce3c99e5fa25 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -70,7 +70,8 @@ struct hci_dev { char name[8]; unsigned long flags; __u16 id; - __u8 type; + __u8 bus; + __u8 dev_type; bdaddr_t bdaddr; __u8 dev_name[248]; __u8 dev_class[3]; @@ -134,6 +135,8 @@ struct hci_dev { atomic_t promisc; + struct dentry *debugfs; + struct device *parent; struct device dev; @@ -367,22 +370,6 @@ static inline void hci_conn_put(struct hci_conn *conn) } } -/* ----- HCI tasks ----- */ -static inline void hci_sched_cmd(struct hci_dev *hdev) -{ - tasklet_schedule(&hdev->cmd_task); -} - -static inline void hci_sched_rx(struct hci_dev *hdev) -{ - tasklet_schedule(&hdev->rx_task); -} - -static inline void hci_sched_tx(struct hci_dev *hdev) -{ - tasklet_schedule(&hdev->tx_task); -} - /* ----- HCI Devices ----- */ static inline void __hci_dev_put(struct hci_dev *d) { @@ -437,28 +424,7 @@ int hci_inquiry(void __user *arg); void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb); -/* Receive frame from HCI drivers */ -static inline int hci_recv_frame(struct sk_buff *skb) -{ - struct hci_dev *hdev = (struct hci_dev *) skb->dev; - if (!hdev || (!test_bit(HCI_UP, &hdev->flags) - && !test_bit(HCI_INIT, &hdev->flags))) { - kfree_skb(skb); - return -ENXIO; - } - - /* Incomming skb */ - bt_cb(skb)->incoming = 1; - - /* Time stamp */ - __net_timestamp(skb); - - /* Queue frame for rx task */ - skb_queue_tail(&hdev->rx_q, skb); - hci_sched_rx(hdev); - return 0; -} - +int hci_recv_frame(struct sk_buff *skb); int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count); int hci_register_sysfs(struct hci_dev *hdev); diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 9516f4b4a3c2..17a689f27a6a 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -324,7 +324,6 @@ struct l2cap_pinfo { __u8 next_tx_seq; __u8 expected_ack_seq; - __u8 req_seq; __u8 expected_tx_seq; __u8 buffer_seq; __u8 buffer_seq_srej; @@ -375,6 +374,7 @@ struct l2cap_pinfo { #define L2CAP_CONN_SEND_PBIT 0x10 #define L2CAP_CONN_REMOTE_BUSY 0x20 #define L2CAP_CONN_LOCAL_BUSY 0x40 +#define L2CAP_CONN_REJ_ACT 0x80 #define __mod_retrans_timer() mod_timer(&l2cap_pi(sk)->retrans_timer, \ jiffies + msecs_to_jiffies(L2CAP_DEFAULT_RETRANS_TO)); diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 3d874c620219..3d134a1fb96b 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -3,7 +3,7 @@ /* * 802.11 device and configuration interface * - * Copyright 2006-2009 Johannes Berg <johannes@sipsolutions.net> + * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -39,8 +39,8 @@ * @IEEE80211_BAND_5GHZ: around 5GHz band (4.9-5.7) */ enum ieee80211_band { - IEEE80211_BAND_2GHZ, - IEEE80211_BAND_5GHZ, + IEEE80211_BAND_2GHZ = NL80211_BAND_2GHZ, + IEEE80211_BAND_5GHZ = NL80211_BAND_5GHZ, /* keep last */ IEEE80211_NUM_BANDS @@ -206,10 +206,12 @@ struct ieee80211_supported_band { * struct vif_params - describes virtual interface parameters * @mesh_id: mesh ID to use * @mesh_id_len: length of the mesh ID + * @use_4addr: use 4-address frames */ struct vif_params { u8 *mesh_id; int mesh_id_len; + int use_4addr; }; /** @@ -233,6 +235,35 @@ struct key_params { }; /** + * enum survey_info_flags - survey information flags + * + * Used by the driver to indicate which info in &struct survey_info + * it has filled in during the get_survey(). + */ +enum survey_info_flags { + SURVEY_INFO_NOISE_DBM = 1<<0, +}; + +/** + * struct survey_info - channel survey response + * + * Used by dump_survey() to report back per-channel survey information. + * + * @channel: the channel this survey record reports, mandatory + * @filled: bitflag of flags from &enum survey_info_flags + * @noise: channel noise in dBm. This and all following fields are + * optional + * + * This structure can later be expanded with things like + * channel duty cycle etc. + */ +struct survey_info { + struct ieee80211_channel *channel; + u32 filled; + s8 noise; +}; + +/** * struct beacon_parameters - beacon parameters * * Used to configure the beacon for an interface. @@ -418,7 +449,7 @@ enum monitor_flags { * in during get_station() or dump_station(). * * MPATH_INFO_FRAME_QLEN: @frame_qlen filled - * MPATH_INFO_DSN: @dsn filled + * MPATH_INFO_SN: @sn filled * MPATH_INFO_METRIC: @metric filled * MPATH_INFO_EXPTIME: @exptime filled * MPATH_INFO_DISCOVERY_TIMEOUT: @discovery_timeout filled @@ -427,7 +458,7 @@ enum monitor_flags { */ enum mpath_info_flags { MPATH_INFO_FRAME_QLEN = BIT(0), - MPATH_INFO_DSN = BIT(1), + MPATH_INFO_SN = BIT(1), MPATH_INFO_METRIC = BIT(2), MPATH_INFO_EXPTIME = BIT(3), MPATH_INFO_DISCOVERY_TIMEOUT = BIT(4), @@ -442,7 +473,7 @@ enum mpath_info_flags { * * @filled: bitfield of flags from &enum mpath_info_flags * @frame_qlen: number of queued frames for this destination - * @dsn: destination sequence number + * @sn: target sequence number * @metric: metric (cost) of this mesh path * @exptime: expiration time for the mesh path from now, in msecs * @flags: mesh path flags @@ -456,7 +487,7 @@ enum mpath_info_flags { struct mpath_info { u32 filled; u32 frame_qlen; - u32 dsn; + u32 sn; u32 metric; u32 exptime; u32 discovery_timeout; @@ -506,6 +537,7 @@ struct mesh_config { u32 dot11MeshHWMPactivePathTimeout; u16 dot11MeshHWMPpreqMinInterval; u16 dot11MeshHWMPnetDiameterTraversalTime; + u8 dot11MeshHWMPRootMode; }; /** @@ -594,8 +626,14 @@ enum cfg80211_signal_type { * @beacon_interval: the beacon interval as from the frame * @capability: the capability field in host byte order * @information_elements: the information elements (Note that there - * is no guarantee that these are well-formed!) + * 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 * @len_information_elements: total length of the information elements + * @beacon_ies: the information elements from the last Beacon frame + * @len_beacon_ies: total length of the beacon_ies + * @proberesp_ies: the information elements from the last Probe Response frame + * @len_proberesp_ies: total length of the proberesp_ies * @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 @@ -609,6 +647,10 @@ struct cfg80211_bss { u16 capability; u8 *information_elements; size_t len_information_elements; + u8 *beacon_ies; + size_t len_beacon_ies; + u8 *proberesp_ies; + size_t len_proberesp_ies; s32 signal; @@ -805,6 +847,7 @@ enum wiphy_params_flags { WIPHY_PARAM_RETRY_LONG = 1 << 1, WIPHY_PARAM_FRAG_THRESHOLD = 1 << 2, WIPHY_PARAM_RTS_THRESHOLD = 1 << 3, + WIPHY_PARAM_COVERAGE_CLASS = 1 << 4, }; /** @@ -824,20 +867,24 @@ enum tx_power_setting { * cfg80211_bitrate_mask - masks for bitrate control */ struct cfg80211_bitrate_mask { -/* - * As discussed in Berlin, this struct really - * should look like this: - struct { u32 legacy; - u8 mcs[IEEE80211_HT_MCS_MASK_LEN]; + /* TODO: add support for masking MCS rates; e.g.: */ + /* u8 mcs[IEEE80211_HT_MCS_MASK_LEN]; */ } control[IEEE80211_NUM_BANDS]; - - * Since we can always fix in-kernel users, let's keep - * it simpler for now: +}; +/** + * struct cfg80211_pmksa - PMK Security Association + * + * This structure is passed to the set/del_pmksa() method for PMKSA + * caching. + * + * @bssid: The AP's BSSID. + * @pmkid: The PMK material itself. */ - u32 fixed; /* fixed bitrate, 0 == not fixed */ - u32 maxrate; /* in kbps, 0 == no limit */ +struct cfg80211_pmksa { + u8 *bssid; + u8 *pmkid; }; /** @@ -941,7 +988,26 @@ struct cfg80211_bitrate_mask { * @rfkill_poll: polls the hw rfkill line, use cfg80211 reporting * functions to adjust rfkill hw state * + * @dump_survey: get site survey information. + * + * @remain_on_channel: Request the driver to remain awake on the specified + * channel for the specified duration to complete an off-channel + * operation (e.g., public action frame exchange). When the driver is + * ready on the requested channel, it must indicate this with an event + * notification by calling cfg80211_ready_on_channel(). + * @cancel_remain_on_channel: Cancel an on-going remain-on-channel operation. + * This allows the operation to be terminated prior to timeout based on + * the duration value. + * @action: Transmit an action frame + * * @testmode_cmd: run a test mode command + * + * @set_pmksa: Cache a PMKID for a BSSID. This is mostly useful for fullmac + * devices running firmwares capable of generating the (re) association + * RSN IE. It allows for faster roaming between WPA2 BSSIDs. + * @del_pmksa: Delete a cached PMKID. + * @flush_pmksa: Flush all cached PMKIDs. + * */ struct cfg80211_ops { int (*suspend)(struct wiphy *wiphy); @@ -1060,7 +1126,30 @@ struct cfg80211_ops { const u8 *peer, const struct cfg80211_bitrate_mask *mask); - /* some temporary stuff to finish wext */ + int (*dump_survey)(struct wiphy *wiphy, struct net_device *netdev, + int idx, struct survey_info *info); + + int (*set_pmksa)(struct wiphy *wiphy, struct net_device *netdev, + struct cfg80211_pmksa *pmksa); + int (*del_pmksa)(struct wiphy *wiphy, struct net_device *netdev, + struct cfg80211_pmksa *pmksa); + int (*flush_pmksa)(struct wiphy *wiphy, struct net_device *netdev); + + int (*remain_on_channel)(struct wiphy *wiphy, + struct net_device *dev, + struct ieee80211_channel *chan, + enum nl80211_channel_type channel_type, + unsigned int duration, + u64 *cookie); + int (*cancel_remain_on_channel)(struct wiphy *wiphy, + struct net_device *dev, + u64 cookie); + + int (*action)(struct wiphy *wiphy, struct net_device *dev, + struct ieee80211_channel *chan, + enum nl80211_channel_type channel_type, + const u8 *buf, size_t len, u64 *cookie); + int (*set_power_mgmt)(struct wiphy *wiphy, struct net_device *dev, bool enabled, int timeout); }; @@ -1071,27 +1160,54 @@ struct cfg80211_ops { */ /** - * struct wiphy - wireless hardware description - * @idx: the wiphy index assigned to this item - * @class_dev: the class device representing /sys/class/ieee80211/<wiphy-name> - * @custom_regulatory: tells us the driver for this device + * enum wiphy_flags - wiphy capability flags + * + * @WIPHY_FLAG_CUSTOM_REGULATORY: tells us the driver for this device * has its own custom regulatory domain and cannot identify the * ISO / IEC 3166 alpha2 it belongs to. When this is enabled * we will disregard the first regulatory hint (when the * initiator is %REGDOM_SET_BY_CORE). - * @strict_regulatory: tells us the driver for this device will ignore - * regulatory domain settings until it gets its own regulatory domain - * via its regulatory_hint(). After its gets its own regulatory domain - * it will only allow further regulatory domain settings to further - * enhance compliance. For example if channel 13 and 14 are disabled - * by this regulatory domain no user regulatory domain can enable these - * channels at a later time. This can be used for devices which do not - * have calibration information gauranteed for frequencies or settings - * outside of its regulatory domain. - * @disable_beacon_hints: enable this if your driver needs to ensure that - * passive scan flags and beaconing flags may not be lifted by cfg80211 - * due to regulatory beacon hints. For more information on beacon + * @WIPHY_FLAG_STRICT_REGULATORY: tells us the driver for this device will + * ignore regulatory domain settings until it gets its own regulatory + * domain via its regulatory_hint(). After its gets its own regulatory + * domain it will only allow further regulatory domain settings to + * further enhance compliance. For example if channel 13 and 14 are + * disabled by this regulatory domain no user regulatory domain can + * enable these channels at a later time. This can be used for devices + * which do not have calibration information gauranteed for frequencies + * or settings outside of its regulatory domain. + * @WIPHY_FLAG_DISABLE_BEACON_HINTS: enable this if your driver needs to ensure + * that passive scan flags and beaconing flags may not be lifted by + * cfg80211 due to regulatory beacon hints. For more information on beacon * hints read the documenation for regulatory_hint_found_beacon() + * @WIPHY_FLAG_NETNS_OK: if not set, do not allow changing the netns of this + * wiphy at all + * @WIPHY_FLAG_PS_ON_BY_DEFAULT: if set to true, powersave will be enabled + * by default -- this flag will be set depending on the kernel's default + * on wiphy_new(), but can be changed by the driver if it has a good + * reason to override the default + * @WIPHY_FLAG_4ADDR_AP: supports 4addr mode even on AP (with a single station + * on a VLAN interface) + * @WIPHY_FLAG_4ADDR_STATION: supports 4addr mode even as a station + */ +enum wiphy_flags { + WIPHY_FLAG_CUSTOM_REGULATORY = BIT(0), + WIPHY_FLAG_STRICT_REGULATORY = BIT(1), + WIPHY_FLAG_DISABLE_BEACON_HINTS = BIT(2), + WIPHY_FLAG_NETNS_OK = BIT(3), + WIPHY_FLAG_PS_ON_BY_DEFAULT = BIT(4), + WIPHY_FLAG_4ADDR_AP = BIT(5), + WIPHY_FLAG_4ADDR_STATION = BIT(6), +}; + +struct mac_address { + u8 addr[ETH_ALEN]; +}; + +/** + * struct wiphy - wireless hardware description + * @idx: the wiphy index assigned to this item + * @class_dev: the class device representing /sys/class/ieee80211/<wiphy-name> * @reg_notifier: the driver's regulatory notification callback * @regd: the driver's regulatory domain, if one was requested via * the regulatory_hint() API. This can be used by the driver @@ -1106,27 +1222,33 @@ struct cfg80211_ops { * -1 = fragmentation disabled, only odd values >= 256 used * @rts_threshold: RTS threshold (dot11RTSThreshold); -1 = RTS/CTS disabled * @net: the network namespace this wiphy currently lives in - * @netnsok: if set to false, do not allow changing the netns of this - * wiphy at all - * @ps_default: default for powersave, will be set depending on the - * kernel's default on wiphy_new(), but can be changed by the - * driver if it has a good reason to override the default + * @perm_addr: permanent MAC address of this device + * @addr_mask: If the device supports multiple MAC addresses by masking, + * set this to a mask with variable bits set to 1, e.g. if the last + * four bits are variable then set it to 00:...:00:0f. The actual + * variable bits shall be determined by the interfaces added, with + * interfaces not matching the mask being rejected to be brought up. + * @n_addresses: number of addresses in @addresses. + * @addresses: If the device has more than one address, set this pointer + * to a list of addresses (6 bytes each). The first one will be used + * by default for perm_addr. In this case, the mask should be set to + * all-zeroes. In this case it is assumed that the device can handle + * the same number of arbitrary MAC addresses. */ struct wiphy { /* assign these fields before you register the wiphy */ - /* permanent MAC address */ + /* permanent MAC address(es) */ u8 perm_addr[ETH_ALEN]; + u8 addr_mask[ETH_ALEN]; + + u16 n_addresses; + struct mac_address *addresses; /* Supported interface modes, OR together BIT(NL80211_IFTYPE_...) */ u16 interface_modes; - bool custom_regulatory; - bool strict_regulatory; - bool disable_beacon_hints; - - bool netnsok; - bool ps_default; + u32 flags; enum cfg80211_signal_type signal_type; @@ -1141,6 +1263,12 @@ struct wiphy { u8 retry_long; u32 frag_threshold; u32 rts_threshold; + u8 coverage_class; + + char fw_version[ETHTOOL_BUSINFO_LEN]; + u32 hw_version; + + u8 max_num_pmkids; /* If multiple wiphys are registered and you're handed e.g. * a regular netdev with assigned ieee80211_ptr, you won't @@ -1171,6 +1299,10 @@ struct wiphy { struct net *_net; #endif +#ifdef CONFIG_CFG80211_WEXT + const struct iw_handler_def *wext; +#endif + char priv[0] __attribute__((__aligned__(NETDEV_ALIGN))); }; @@ -1314,6 +1446,12 @@ struct cfg80211_cached_keys; * @ssid_len: (private) Used by the internal configuration code * @wext: (private) Used by the internal wireless extensions compat code * @wext_bssid: (private) Used by the internal wireless extensions compat code + * @use_4addr: indicates 4addr mode is used on this interface, must be + * set by driver (if supported) on add_interface BEFORE registering the + * netdev and may otherwise be used by driver read-only, will be update + * by cfg80211 on change_interface + * @action_registrations: list of registrations for action frames + * @action_registrations_lock: lock for the list */ struct wireless_dev { struct wiphy *wiphy; @@ -1323,10 +1461,15 @@ struct wireless_dev { struct list_head list; struct net_device *netdev; + struct list_head action_registrations; + spinlock_t action_registrations_lock; + struct mutex mtx; struct work_struct cleanup_work; + bool use_4addr; + /* currently used for IBSS and SME - might be rearranged later */ u8 ssid[IEEE80211_MAX_SSID_LEN]; u8 ssid_len; @@ -1345,7 +1488,10 @@ struct wireless_dev { struct cfg80211_internal_bss *auth_bsses[MAX_AUTH_BSSES]; struct cfg80211_internal_bss *current_bss; /* associated / joined */ -#ifdef CONFIG_WIRELESS_EXT + bool ps; + int ps_timeout; + +#ifdef CONFIG_CFG80211_WEXT /* wext data */ struct { struct cfg80211_ibss_params ibss; @@ -1356,8 +1502,7 @@ struct wireless_dev { u8 bssid[ETH_ALEN], prev_bssid[ETH_ALEN]; u8 ssid[IEEE80211_MAX_SSID_LEN]; s8 default_key, default_mgmt_key; - bool ps, prev_bssid_valid; - int ps_timeout; + bool prev_bssid_valid; } wext; #endif }; @@ -1428,37 +1573,82 @@ ieee80211_get_response_rate(struct ieee80211_supported_band *sband, * Documentation in Documentation/networking/radiotap-headers.txt */ +struct radiotap_align_size { + uint8_t align:4, size:4; +}; + +struct ieee80211_radiotap_namespace { + const struct radiotap_align_size *align_size; + int n_bits; + uint32_t oui; + uint8_t subns; +}; + +struct ieee80211_radiotap_vendor_namespaces { + const struct ieee80211_radiotap_namespace *ns; + int n_ns; +}; + /** * struct ieee80211_radiotap_iterator - tracks walk thru present radiotap args - * @rtheader: pointer to the radiotap header we are walking through - * @max_length: length of radiotap header in cpu byte ordering - * @this_arg_index: IEEE80211_RADIOTAP_... index of current arg - * @this_arg: pointer to current radiotap arg - * @arg_index: internal next argument index - * @arg: internal next argument pointer - * @next_bitmap: internal pointer to next present u32 - * @bitmap_shifter: internal shifter for curr u32 bitmap, b0 set == arg present + * @this_arg_index: index of current arg, valid after each successful call + * to ieee80211_radiotap_iterator_next() + * @this_arg: pointer to current radiotap arg; it is valid after each + * call to ieee80211_radiotap_iterator_next() but also after + * ieee80211_radiotap_iterator_init() where it will point to + * the beginning of the actual data portion + * @this_arg_size: length of the current arg, for convenience + * @current_namespace: pointer to the current namespace definition + * (or internally %NULL if the current namespace is unknown) + * @is_radiotap_ns: indicates whether the current namespace is the default + * radiotap namespace or not + * + * @overrides: override standard radiotap fields + * @n_overrides: number of overrides + * + * @_rtheader: pointer to the radiotap header we are walking through + * @_max_length: length of radiotap header in cpu byte ordering + * @_arg_index: next argument index + * @_arg: next argument pointer + * @_next_bitmap: internal pointer to next present u32 + * @_bitmap_shifter: internal shifter for curr u32 bitmap, b0 set == arg present + * @_vns: vendor namespace definitions + * @_next_ns_data: beginning of the next namespace's data + * @_reset_on_ext: internal; reset the arg index to 0 when going to the + * next bitmap word + * + * Describes the radiotap parser state. Fields prefixed with an underscore + * must not be used by users of the parser, only by the parser internally. */ struct ieee80211_radiotap_iterator { - struct ieee80211_radiotap_header *rtheader; - int max_length; + struct ieee80211_radiotap_header *_rtheader; + const struct ieee80211_radiotap_vendor_namespaces *_vns; + const struct ieee80211_radiotap_namespace *current_namespace; + + unsigned char *_arg, *_next_ns_data; + uint32_t *_next_bitmap; + + unsigned char *this_arg; int this_arg_index; - u8 *this_arg; + int this_arg_size; - int arg_index; - u8 *arg; - __le32 *next_bitmap; - u32 bitmap_shifter; + int is_radiotap_ns; + + int _max_length; + int _arg_index; + uint32_t _bitmap_shifter; + int _reset_on_ext; }; extern int ieee80211_radiotap_iterator_init( - struct ieee80211_radiotap_iterator *iterator, - struct ieee80211_radiotap_header *radiotap_header, - int max_length); + struct ieee80211_radiotap_iterator *iterator, + struct ieee80211_radiotap_header *radiotap_header, + int max_length, const struct ieee80211_radiotap_vendor_namespaces *vns); extern int ieee80211_radiotap_iterator_next( - struct ieee80211_radiotap_iterator *iterator); + struct ieee80211_radiotap_iterator *iterator); + extern const unsigned char rfc1042_header[6]; extern const unsigned char bridge_tunnel_header[6]; @@ -1487,7 +1677,7 @@ unsigned int ieee80211_hdrlen(__le16 fc); * @addr: the device MAC address * @iftype: the virtual interface type */ -int ieee80211_data_to_8023(struct sk_buff *skb, u8 *addr, +int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, enum nl80211_iftype iftype); /** @@ -1498,15 +1688,49 @@ int ieee80211_data_to_8023(struct sk_buff *skb, u8 *addr, * @bssid: the network bssid (used only for iftype STATION and ADHOC) * @qos: build 802.11 QoS data frame */ -int ieee80211_data_from_8023(struct sk_buff *skb, u8 *addr, +int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr, enum nl80211_iftype iftype, u8 *bssid, bool qos); /** + * ieee80211_amsdu_to_8023s - decode an IEEE 802.11n A-MSDU frame + * + * Decode an IEEE 802.11n A-MSDU frame and convert it to a list of + * 802.3 frames. The @list will be empty if the decode fails. The + * @skb is consumed after the function returns. + * + * @skb: The input IEEE 802.11n A-MSDU frame. + * @list: The output list of 802.3 frames. It must be allocated and + * initialized by by the caller. + * @addr: The device MAC address. + * @iftype: The device interface type. + * @extra_headroom: The hardware extra headroom for SKBs in the @list. + */ +void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list, + const u8 *addr, enum nl80211_iftype iftype, + const unsigned int extra_headroom); + +/** * cfg80211_classify8021d - determine the 802.1p/1d tag for a data frame * @skb: the data frame */ unsigned int cfg80211_classify8021d(struct sk_buff *skb); +/** + * cfg80211_find_ie - find information element in data + * + * @eid: element ID + * @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. + */ +const u8 *cfg80211_find_ie(u8 eid, const u8 *ies, int len); + /* * Regulatory helper functions for wiphys */ @@ -1776,6 +2000,18 @@ void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len); void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr); /** + * __cfg80211_auth_canceled - notify cfg80211 that authentication was canceled + * @dev: network device + * @addr: The MAC address of the device with which the authentication timed out + * + * When a pending authentication had no action yet, the driver may decide + * to not send a deauth frame, but in that case must calls this function + * to tell cfg80211 about this decision. It is only valid to call this + * function within the deauth() callback. + */ +void __cfg80211_auth_canceled(struct net_device *dev, const u8 *addr); + +/** * cfg80211_send_rx_assoc - notification of processed association * @dev: network device * @buf: (re)association response frame (header + body) @@ -1802,30 +2038,45 @@ void cfg80211_send_assoc_timeout(struct net_device *dev, const u8 *addr); * @dev: network device * @buf: deauthentication frame (header + body) * @len: length of the frame data - * @cookie: cookie from ->deauth if called within that callback, - * %NULL otherwise * * This function is called whenever deauthentication has been processed in * station mode. This includes both received deauthentication frames and * locally generated ones. This function may sleep. */ -void cfg80211_send_deauth(struct net_device *dev, const u8 *buf, size_t len, - void *cookie); +void cfg80211_send_deauth(struct net_device *dev, const u8 *buf, size_t len); + +/** + * __cfg80211_send_deauth - notification of processed deauthentication + * @dev: network device + * @buf: deauthentication frame (header + body) + * @len: length of the frame data + * + * Like cfg80211_send_deauth(), but doesn't take the wdev lock. + */ +void __cfg80211_send_deauth(struct net_device *dev, const u8 *buf, size_t len); /** * cfg80211_send_disassoc - notification of processed disassociation * @dev: network device * @buf: disassociation response frame (header + body) * @len: length of the frame data - * @cookie: cookie from ->disassoc if called within that callback, - * %NULL otherwise * * This function is called whenever disassociation has been processed in * station mode. This includes both received disassociation frames and locally * generated ones. This function may sleep. */ -void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len, - void *cookie); +void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len); + +/** + * __cfg80211_send_disassoc - notification of processed disassociation + * @dev: network device + * @buf: disassociation response frame (header + body) + * @len: length of the frame data + * + * Like cfg80211_send_disassoc(), but doesn't take the wdev lock. + */ +void __cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, + size_t len); /** * cfg80211_michael_mic_failure - notification of Michael MIC failure (TKIP) @@ -2011,5 +2262,79 @@ void cfg80211_roamed(struct net_device *dev, const u8 *bssid, void cfg80211_disconnected(struct net_device *dev, u16 reason, u8 *ie, size_t ie_len, gfp_t gfp); +/** + * cfg80211_ready_on_channel - notification of remain_on_channel start + * @dev: network device + * @cookie: the request cookie + * @chan: The current channel (from remain_on_channel request) + * @channel_type: Channel type + * @duration: Duration in milliseconds that the driver intents to remain on the + * channel + * @gfp: allocation flags + */ +void cfg80211_ready_on_channel(struct net_device *dev, u64 cookie, + struct ieee80211_channel *chan, + enum nl80211_channel_type channel_type, + unsigned int duration, gfp_t gfp); + +/** + * cfg80211_remain_on_channel_expired - remain_on_channel duration expired + * @dev: network device + * @cookie: the request cookie + * @chan: The current channel (from remain_on_channel request) + * @channel_type: Channel type + * @gfp: allocation flags + */ +void cfg80211_remain_on_channel_expired(struct net_device *dev, + u64 cookie, + struct ieee80211_channel *chan, + enum nl80211_channel_type channel_type, + gfp_t gfp); + + +/** + * cfg80211_new_sta - notify userspace about station + * + * @dev: the netdev + * @mac_addr: the station's address + * @sinfo: the station information + * @gfp: allocation flags + */ +void cfg80211_new_sta(struct net_device *dev, const u8 *mac_addr, + struct station_info *sinfo, gfp_t gfp); + +/** + * cfg80211_rx_action - notification of received, unprocessed Action frame + * @dev: network device + * @freq: Frequency on which the frame was received in MHz + * @buf: Action frame (header + body) + * @len: length of the frame data + * @gfp: context flags + * Returns %true if a user space application is responsible for rejecting the + * unrecognized Action frame; %false if no such application is registered + * (i.e., the driver is responsible for rejecting the unrecognized Action + * 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_action(struct net_device *dev, int freq, const u8 *buf, + size_t len, gfp_t gfp); + +/** + * cfg80211_action_tx_status - notification of TX status for Action frame + * @dev: network device + * @cookie: Cookie returned by cfg80211_ops::action() + * @buf: Action frame (header + body) + * @len: length of the frame data + * @ack: Whether frame was acknowledged + * @gfp: context flags + * + * This function is called whenever an Action frame was requested to be + * transmitted with cfg80211_ops::action() to report the TX status of the + * transmission attempt. + */ +void cfg80211_action_tx_status(struct net_device *dev, u64 cookie, + const u8 *buf, size_t len, bool ack, gfp_t gfp); #endif /* __NET_CFG80211_H */ diff --git a/include/net/compat.h b/include/net/compat.h index 5bbf8bf9efea..28d5428ec6a2 100644 --- a/include/net/compat.h +++ b/include/net/compat.h @@ -18,6 +18,11 @@ struct compat_msghdr { compat_uint_t msg_flags; }; +struct compat_mmsghdr { + struct compat_msghdr msg_hdr; + compat_uint_t msg_len; +}; + struct compat_cmsghdr { compat_size_t cmsg_len; compat_int_t cmsg_level; @@ -28,20 +33,27 @@ extern int compat_sock_get_timestamp(struct sock *, struct timeval __user *); extern int compat_sock_get_timestampns(struct sock *, struct timespec __user *); #else /* defined(CONFIG_COMPAT) */ -#define compat_msghdr msghdr /* to avoid compiler warnings */ +/* + * To avoid compiler warnings: + */ +#define compat_msghdr msghdr +#define compat_mmsghdr mmsghdr #endif /* defined(CONFIG_COMPAT) */ extern int get_compat_msghdr(struct msghdr *, struct compat_msghdr __user *); extern int verify_compat_iovec(struct msghdr *, struct iovec *, struct sockaddr *, int); extern asmlinkage long compat_sys_sendmsg(int,struct compat_msghdr __user *,unsigned); extern asmlinkage long compat_sys_recvmsg(int,struct compat_msghdr __user *,unsigned); +extern asmlinkage long compat_sys_recvmmsg(int, struct compat_mmsghdr __user *, + unsigned, unsigned, + struct compat_timespec __user *); extern asmlinkage long compat_sys_getsockopt(int, int, int, char __user *, int __user *); extern int put_cmsg_compat(struct msghdr*, int, int, int, void *); extern int cmsghdr_from_user_compat_to_kern(struct msghdr *, struct sock *, unsigned char *, int); -extern int compat_mc_setsockopt(struct sock *, int, int, char __user *, int, - int (*)(struct sock *, int, int, char __user *, int)); +extern int compat_mc_setsockopt(struct sock *, int, int, char __user *, unsigned int, + int (*)(struct sock *, int, int, char __user *, unsigned int)); extern int compat_mc_getsockopt(struct sock *, int, int, char __user *, int __user *, int (*)(struct sock *, int, int, char __user *, int __user *)); diff --git a/include/net/dn_dev.h b/include/net/dn_dev.h index cee46821dc53..511a459ec10f 100644 --- a/include/net/dn_dev.h +++ b/include/net/dn_dev.h @@ -75,7 +75,6 @@ struct dn_dev_parms { unsigned long t3; /* Default value of t3 */ int priority; /* Priority to be a router */ char *name; /* Name for sysctl */ - int ctl_name; /* Index for sysctl */ int (*up)(struct net_device *); void (*down)(struct net_device *); void (*timer3)(struct net_device *, struct dn_ifaddr *ifa); @@ -97,16 +96,14 @@ struct dn_dev { unsigned long uptime; /* Time device went up in jiffies */ }; -struct dn_short_packet -{ +struct dn_short_packet { __u8 msgflg; __le16 dstnode; __le16 srcnode; __u8 forward; } __attribute__((packed)); -struct dn_long_packet -{ +struct dn_long_packet { __u8 msgflg; __u8 d_area; __u8 d_subarea; @@ -122,8 +119,7 @@ struct dn_long_packet /*------------------------- DRP - Routing messages ---------------------*/ -struct endnode_hello_message -{ +struct endnode_hello_message { __u8 msgflg; __u8 tiver[3]; __u8 id[6]; @@ -138,8 +134,7 @@ struct endnode_hello_message __u8 data[2]; } __attribute__((packed)); -struct rtnode_hello_message -{ +struct rtnode_hello_message { __u8 msgflg; __u8 tiver[3]; __u8 id[6]; diff --git a/include/net/dn_fib.h b/include/net/dn_fib.h index c378be7bf960..52da6c3dd50d 100644 --- a/include/net/dn_fib.h +++ b/include/net/dn_fib.h @@ -4,8 +4,7 @@ /* WARNING: The ordering of these elements must match ordering * of RTA_* rtnetlink attribute numbers. */ -struct dn_kern_rta -{ +struct dn_kern_rta { void *rta_dst; void *rta_src; int *rta_iif; diff --git a/include/net/dn_nsp.h b/include/net/dn_nsp.h index 96e816b6974d..17d43d2db5ec 100644 --- a/include/net/dn_nsp.h +++ b/include/net/dn_nsp.h @@ -70,30 +70,26 @@ extern struct sk_buff *dn_alloc_send_skb(struct sock *sk, size_t *size, int nobl /* Data Messages (data segment/interrupt/link service) */ -struct nsp_data_seg_msg -{ +struct nsp_data_seg_msg { __u8 msgflg; __le16 dstaddr; __le16 srcaddr; } __attribute__((packed)); -struct nsp_data_opt_msg -{ +struct nsp_data_opt_msg { __le16 acknum; __le16 segnum; __le16 lsflgs; } __attribute__((packed)); -struct nsp_data_opt_msg1 -{ +struct nsp_data_opt_msg1 { __le16 acknum; __le16 segnum; } __attribute__((packed)); /* Acknowledgment Message (data/other data) */ -struct nsp_data_ack_msg -{ +struct nsp_data_ack_msg { __u8 msgflg; __le16 dstaddr; __le16 srcaddr; @@ -101,16 +97,14 @@ struct nsp_data_ack_msg } __attribute__((packed)); /* Connect Acknowledgment Message */ -struct nsp_conn_ack_msg -{ +struct nsp_conn_ack_msg { __u8 msgflg; __le16 dstaddr; } __attribute__((packed)); /* Connect Initiate/Retransmit Initiate/Connect Confirm */ -struct nsp_conn_init_msg -{ +struct nsp_conn_init_msg { __u8 msgflg; #define NSP_CI 0x18 /* Connect Initiate */ #define NSP_RCI 0x68 /* Retrans. Conn Init */ @@ -126,8 +120,7 @@ struct nsp_conn_init_msg } __attribute__((packed)); /* Disconnect Initiate/Disconnect Confirm */ -struct nsp_disconn_init_msg -{ +struct nsp_disconn_init_msg { __u8 msgflg; __le16 dstaddr; __le16 srcaddr; @@ -136,8 +129,7 @@ struct nsp_disconn_init_msg -struct srcobj_fmt -{ +struct srcobj_fmt { __u8 format; __u8 task; __le16 grpcode; diff --git a/include/net/dst.h b/include/net/dst.h index 5a900ddcf10d..ce078cda6b74 100644 --- a/include/net/dst.h +++ b/include/net/dst.h @@ -36,8 +36,7 @@ struct sk_buff; -struct dst_entry -{ +struct dst_entry { struct rcu_head rcu_head; struct dst_entry *child; struct net_device *dev; @@ -84,8 +83,6 @@ struct dst_entry * (L1_CACHE_SIZE would be too much) */ #ifdef CONFIG_64BIT - long __pad_to_align_refcnt[2]; -#else long __pad_to_align_refcnt[1]; #endif /* @@ -111,6 +108,12 @@ dst_metric(const struct dst_entry *dst, int metric) return dst->metrics[metric-1]; } +static inline u32 +dst_feature(const struct dst_entry *dst, u32 feature) +{ + return dst_metric(dst, RTAX_FEATURES) & feature; +} + static inline u32 dst_mtu(const struct dst_entry *dst) { u32 mtu = dst_metric(dst, RTAX_MTU); @@ -136,7 +139,7 @@ static inline void set_dst_metric_rtt(struct dst_entry *dst, int metric, static inline u32 dst_allfrag(const struct dst_entry *dst) { - int ret = dst_metric(dst, RTAX_FEATURES) & RTAX_FEATURE_ALLFRAG; + int ret = dst_feature(dst, RTAX_FEATURE_ALLFRAG); /* Yes, _exactly_. This is paranoia. */ barrier(); return ret; @@ -222,11 +225,19 @@ static inline void dst_confirm(struct dst_entry *dst) neigh_confirm(dst->neighbour); } -static inline void dst_negative_advice(struct dst_entry **dst_p) +static inline void dst_negative_advice(struct dst_entry **dst_p, + struct sock *sk) { struct dst_entry * dst = *dst_p; - if (dst && dst->ops->negative_advice) + if (dst && dst->ops->negative_advice) { *dst_p = dst->ops->negative_advice(dst); + + if (dst != *dst_p) { + extern void sk_reset_txq(struct sock *sk); + + sk_reset_txq(sk); + } + } } static inline void dst_link_failure(struct sk_buff *skb) diff --git a/include/net/fib_rules.h b/include/net/fib_rules.h index ca4b2e840078..c07ac9650ebc 100644 --- a/include/net/fib_rules.h +++ b/include/net/fib_rules.h @@ -7,12 +7,11 @@ #include <net/flow.h> #include <net/rtnetlink.h> -struct fib_rule -{ +struct fib_rule { struct list_head list; atomic_t refcnt; - int ifindex; - char ifname[IFNAMSIZ]; + int iifindex; + int oifindex; u32 mark; u32 mark_mask; u32 pref; @@ -21,19 +20,19 @@ struct fib_rule u8 action; u32 target; struct fib_rule * ctarget; + char iifname[IFNAMSIZ]; + char oifname[IFNAMSIZ]; struct rcu_head rcu; struct net * fr_net; }; -struct fib_lookup_arg -{ +struct fib_lookup_arg { void *lookup_ptr; void *result; struct fib_rule *rule; }; -struct fib_rules_ops -{ +struct fib_rules_ops { int family; struct list_head list; int rule_size; @@ -67,10 +66,12 @@ struct fib_rules_ops struct list_head rules_list; struct module *owner; struct net *fro_net; + struct rcu_head rcu; }; #define FRA_GENERIC_POLICY \ - [FRA_IFNAME] = { .type = NLA_STRING, .len = IFNAMSIZ - 1 }, \ + [FRA_IIFNAME] = { .type = NLA_STRING, .len = IFNAMSIZ - 1 }, \ + [FRA_OIFNAME] = { .type = NLA_STRING, .len = IFNAMSIZ - 1 }, \ [FRA_PRIORITY] = { .type = NLA_U32 }, \ [FRA_FWMARK] = { .type = NLA_U32 }, \ [FRA_FWMASK] = { .type = NLA_U32 }, \ @@ -102,7 +103,7 @@ static inline u32 frh_get_table(struct fib_rule_hdr *frh, struct nlattr **nla) return frh->table; } -extern int fib_rules_register(struct fib_rules_ops *); +extern struct fib_rules_ops *fib_rules_register(struct fib_rules_ops *, struct net *); extern void fib_rules_unregister(struct fib_rules_ops *); extern void fib_rules_cleanup_ops(struct fib_rules_ops *); diff --git a/include/net/gen_stats.h b/include/net/gen_stats.h index c1488553e349..fa157712e982 100644 --- a/include/net/gen_stats.h +++ b/include/net/gen_stats.h @@ -6,8 +6,7 @@ #include <linux/rtnetlink.h> #include <linux/pkt_sched.h> -struct gnet_dump -{ +struct gnet_dump { spinlock_t * lock; struct sk_buff * skb; struct nlattr * tail; @@ -30,6 +29,7 @@ extern int gnet_stats_start_copy_compat(struct sk_buff *skb, int type, extern int gnet_stats_copy_basic(struct gnet_dump *d, struct gnet_stats_basic_packed *b); extern int gnet_stats_copy_rate_est(struct gnet_dump *d, + const struct gnet_stats_basic_packed *b, struct gnet_stats_rate_est *r); extern int gnet_stats_copy_queue(struct gnet_dump *d, struct gnet_stats_queue *q); diff --git a/include/net/genetlink.h b/include/net/genetlink.h index 2a1c06874c42..eb551baafc04 100644 --- a/include/net/genetlink.h +++ b/include/net/genetlink.h @@ -13,8 +13,7 @@ * @list: list entry for linking * @family: pointer to family, need not be set before registering */ -struct genl_multicast_group -{ +struct genl_multicast_group { struct genl_family *family; /* private */ struct list_head list; /* private */ char name[GENL_NAMSIZ]; @@ -35,8 +34,7 @@ struct genl_multicast_group * @family_list: family list * @mcast_groups: multicast groups list */ -struct genl_family -{ +struct genl_family { unsigned int id; unsigned int hdrsize; char name[GENL_NAMSIZ]; @@ -58,8 +56,7 @@ struct genl_family * @userhdr: user specific header * @attrs: netlink attributes */ -struct genl_info -{ +struct genl_info { u32 snd_seq; u32 snd_pid; struct nlmsghdr * nlhdr; @@ -102,8 +99,7 @@ static inline void genl_info_net_set(struct genl_info *info, struct net *net) * @done: completion callback for dumps * @ops_list: operations list */ -struct genl_ops -{ +struct genl_ops { u8 cmd; unsigned int flags; const struct nla_policy *policy; diff --git a/include/net/icmp.h b/include/net/icmp.h index dfa72d4e8907..15b3dfe9fce8 100644 --- a/include/net/icmp.h +++ b/include/net/icmp.h @@ -28,7 +28,7 @@ struct icmp_err { unsigned fatal:1; }; -extern struct icmp_err icmp_err_convert[]; +extern const struct icmp_err icmp_err_convert[]; #define ICMP_INC_STATS(net, field) SNMP_INC_STATS((net)->mib.icmp_statistics, field) #define ICMP_INC_STATS_BH(net, field) SNMP_INC_STATS_BH((net)->mib.icmp_statistics, field) #define ICMPMSGOUT_INC_STATS(net, field) SNMP_INC_STATS((net)->mib.icmpmsg_statistics, field+256) diff --git a/include/net/ieee80211_radiotap.h b/include/net/ieee80211_radiotap.h index 23c3f3d97779..af49f8ab7f81 100644 --- a/include/net/ieee80211_radiotap.h +++ b/include/net/ieee80211_radiotap.h @@ -80,7 +80,7 @@ struct ieee80211_radiotap_header { * Additional extensions are made * by setting bit 31. */ -}; +} __packed; /* Name Data type Units * ---- --------- ----- @@ -198,6 +198,10 @@ enum ieee80211_radiotap_type { IEEE80211_RADIOTAP_TX_FLAGS = 15, IEEE80211_RADIOTAP_RTS_RETRIES = 16, IEEE80211_RADIOTAP_DATA_RETRIES = 17, + + /* valid in every it_present bitmap, even vendor namespaces */ + IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE = 29, + IEEE80211_RADIOTAP_VENDOR_NAMESPACE = 30, IEEE80211_RADIOTAP_EXT = 31 }; diff --git a/include/net/ieee802154_netdev.h b/include/net/ieee802154_netdev.h index 5dc6a61952de..57430555487a 100644 --- a/include/net/ieee802154_netdev.h +++ b/include/net/ieee802154_netdev.h @@ -74,8 +74,12 @@ static inline int mac_cb_type(struct sk_buff *skb) #define IEEE802154_MAC_SCAN_PASSIVE 2 #define IEEE802154_MAC_SCAN_ORPHAN 3 +struct wpan_phy; /* * This should be located at net_device->ml_priv + * + * get_phy should increment the reference counting on returned phy. + * Use wpan_wpy_put to put that reference. */ struct ieee802154_mlme_ops { int (*assoc_req)(struct net_device *dev, @@ -94,18 +98,20 @@ struct ieee802154_mlme_ops { int (*scan_req)(struct net_device *dev, u8 type, u32 channels, u8 page, u8 duration); + struct wpan_phy *(*get_phy)(const struct net_device *dev); + /* * FIXME: these should become the part of PIB/MIB interface. * However we still don't have IB interface of any kind */ - u16 (*get_pan_id)(struct net_device *dev); - u16 (*get_short_addr)(struct net_device *dev); - u8 (*get_dsn)(struct net_device *dev); - u8 (*get_bsn)(struct net_device *dev); + u16 (*get_pan_id)(const struct net_device *dev); + u16 (*get_short_addr)(const struct net_device *dev); + u8 (*get_dsn)(const struct net_device *dev); + u8 (*get_bsn)(const struct net_device *dev); }; static inline struct ieee802154_mlme_ops *ieee802154_mlme_ops( - struct net_device *dev) + const struct net_device *dev) { return dev->ml_priv; } diff --git a/include/net/if_inet6.h b/include/net/if_inet6.h index 38b78132019b..545d8b059bef 100644 --- a/include/net/if_inet6.h +++ b/include/net/if_inet6.h @@ -32,8 +32,7 @@ #ifdef __KERNEL__ -struct inet6_ifaddr -{ +struct inet6_ifaddr { struct in6_addr addr; __u32 prefix_len; @@ -67,8 +66,7 @@ struct inet6_ifaddr int dead; }; -struct ip6_sf_socklist -{ +struct ip6_sf_socklist { unsigned int sl_max; unsigned int sl_count; struct in6_addr sl_addr[0]; @@ -79,8 +77,7 @@ struct ip6_sf_socklist #define IP6_SFBLOCK 10 /* allocate this many at once */ -struct ipv6_mc_socklist -{ +struct ipv6_mc_socklist { struct in6_addr addr; int ifindex; struct ipv6_mc_socklist *next; @@ -89,8 +86,7 @@ struct ipv6_mc_socklist struct ip6_sf_socklist *sflist; }; -struct ip6_sf_list -{ +struct ip6_sf_list { struct ip6_sf_list *sf_next; struct in6_addr sf_addr; unsigned long sf_count[2]; /* include/exclude counts */ @@ -105,8 +101,7 @@ struct ip6_sf_list #define MAF_NOREPORT 0x08 #define MAF_GSQUERY 0x10 -struct ifmcaddr6 -{ +struct ifmcaddr6 { struct in6_addr mca_addr; struct inet6_dev *idev; struct ifmcaddr6 *next; @@ -126,15 +121,13 @@ struct ifmcaddr6 /* Anycast stuff */ -struct ipv6_ac_socklist -{ +struct ipv6_ac_socklist { struct in6_addr acl_addr; int acl_ifindex; struct ipv6_ac_socklist *acl_next; }; -struct ifacaddr6 -{ +struct ifacaddr6 { struct in6_addr aca_addr; struct inet6_dev *aca_idev; struct rt6_info *aca_rt; @@ -157,15 +150,14 @@ struct ipv6_devstat { DEFINE_SNMP_STAT(struct icmpv6msg_mib, icmpv6msg); }; -struct inet6_dev -{ +struct inet6_dev { struct net_device *dev; struct inet6_ifaddr *addr_list; struct ifmcaddr6 *mc_list; struct ifmcaddr6 *mc_tomb; - rwlock_t mc_lock; + spinlock_t mc_lock; unsigned char mc_qrv; unsigned char mc_gq_running; unsigned char mc_ifc_count; diff --git a/include/net/inet6_hashtables.h b/include/net/inet6_hashtables.h index 22c73a77cd99..e46674d5daea 100644 --- a/include/net/inet6_hashtables.h +++ b/include/net/inet6_hashtables.h @@ -46,14 +46,14 @@ static inline int inet6_sk_ehashfn(const struct sock *sk) const struct ipv6_pinfo *np = inet6_sk(sk); const struct in6_addr *laddr = &np->rcv_saddr; const struct in6_addr *faddr = &np->daddr; - const __u16 lport = inet->num; - const __be16 fport = inet->dport; + const __u16 lport = inet->inet_num; + const __be16 fport = inet->inet_dport; struct net *net = sock_net(sk); return inet6_ehashfn(net, laddr, lport, faddr, fport); } -extern void __inet6_hash(struct sock *sk); +extern int __inet6_hash(struct sock *sk, struct inet_timewait_sock *twp); /* * Sockets in TCP_CLOSE state are _always_ taken out of the hash, so diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h index 03cffd9f64e3..696d6e4ce68a 100644 --- a/include/net/inet_connection_sock.h +++ b/include/net/inet_connection_sock.h @@ -48,13 +48,13 @@ struct inet_connection_sock_af_ops { u16 net_header_len; u16 sockaddr_len; int (*setsockopt)(struct sock *sk, int level, int optname, - char __user *optval, int optlen); + char __user *optval, unsigned int optlen); int (*getsockopt)(struct sock *sk, int level, int optname, char __user *optval, int __user *optlen); #ifdef CONFIG_COMPAT int (*compat_setsockopt)(struct sock *sk, int level, int optname, - char __user *optval, int optlen); + char __user *optval, unsigned int optlen); int (*compat_getsockopt)(struct sock *sk, int level, int optname, char __user *optval, int __user *optlen); @@ -332,5 +332,5 @@ extern void inet_csk_addr2sockaddr(struct sock *sk, struct sockaddr *uaddr); extern int inet_csk_compat_getsockopt(struct sock *sk, int level, int optname, char __user *optval, int __user *optlen); extern int inet_csk_compat_setsockopt(struct sock *sk, int level, int optname, - char __user *optval, int optlen); + char __user *optval, unsigned int optlen); #endif /* _INET_CONNECTION_SOCK_H */ diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h index d522dcf3031a..74358d1b3f43 100644 --- a/include/net/inet_hashtables.h +++ b/include/net/inet_hashtables.h @@ -92,8 +92,8 @@ static inline struct net *ib_net(struct inet_bind_bucket *ib) return read_pnet(&ib->ib_net); } -#define inet_bind_bucket_for_each(tb, node, head) \ - hlist_for_each_entry(tb, node, head, node) +#define inet_bind_bucket_for_each(tb, pos, head) \ + hlist_for_each_entry(tb, pos, head, node) struct inet_bind_hashbucket { spinlock_t lock; @@ -125,7 +125,7 @@ struct inet_hashinfo { */ struct inet_ehash_bucket *ehash; spinlock_t *ehash_locks; - unsigned int ehash_size; + unsigned int ehash_mask; unsigned int ehash_locks_mask; /* Ok, let's try this, I give up, we do need a local binding @@ -158,7 +158,7 @@ static inline struct inet_ehash_bucket *inet_ehash_bucket( struct inet_hashinfo *hashinfo, unsigned int hash) { - return &hashinfo->ehash[hash & (hashinfo->ehash_size - 1)]; + return &hashinfo->ehash[hash & hashinfo->ehash_mask]; } static inline spinlock_t *inet_ehash_lockp( @@ -241,7 +241,7 @@ static inline int inet_lhashfn(struct net *net, const unsigned short num) static inline int inet_sk_listen_hashfn(const struct sock *sk) { - return inet_lhashfn(sock_net(sk), inet_sk(sk)->num); + return inet_lhashfn(sock_net(sk), inet_sk(sk)->inet_num); } /* Caller must disable local BH processing. */ @@ -251,7 +251,7 @@ extern void inet_put_port(struct sock *sk); void inet_hashinfo_init(struct inet_hashinfo *h); -extern void __inet_hash_nolisten(struct sock *sk); +extern int __inet_hash_nolisten(struct sock *sk, struct inet_timewait_sock *tw); extern void inet_hash(struct sock *sk); extern void inet_unhash(struct sock *sk); @@ -301,8 +301,8 @@ typedef __u64 __bitwise __addrpair; #endif /* __BIG_ENDIAN */ #define INET_MATCH(__sk, __net, __hash, __cookie, __saddr, __daddr, __ports, __dif)\ (((__sk)->sk_hash == (__hash)) && net_eq(sock_net(__sk), (__net)) && \ - ((*((__addrpair *)&(inet_sk(__sk)->daddr))) == (__cookie)) && \ - ((*((__portpair *)&(inet_sk(__sk)->dport))) == (__ports)) && \ + ((*((__addrpair *)&(inet_sk(__sk)->inet_daddr))) == (__cookie)) && \ + ((*((__portpair *)&(inet_sk(__sk)->inet_dport))) == (__ports)) && \ (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif)))) #define INET_TW_MATCH(__sk, __net, __hash, __cookie, __saddr, __daddr, __ports, __dif)\ (((__sk)->sk_hash == (__hash)) && net_eq(sock_net(__sk), (__net)) && \ @@ -313,9 +313,9 @@ typedef __u64 __bitwise __addrpair; #define INET_ADDR_COOKIE(__name, __saddr, __daddr) #define INET_MATCH(__sk, __net, __hash, __cookie, __saddr, __daddr, __ports, __dif) \ (((__sk)->sk_hash == (__hash)) && net_eq(sock_net(__sk), (__net)) && \ - (inet_sk(__sk)->daddr == (__saddr)) && \ - (inet_sk(__sk)->rcv_saddr == (__daddr)) && \ - ((*((__portpair *)&(inet_sk(__sk)->dport))) == (__ports)) && \ + (inet_sk(__sk)->inet_daddr == (__saddr)) && \ + (inet_sk(__sk)->inet_rcv_saddr == (__daddr)) && \ + ((*((__portpair *)&(inet_sk(__sk)->inet_dport))) == (__ports)) && \ (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif)))) #define INET_TW_MATCH(__sk, __net, __hash,__cookie, __saddr, __daddr, __ports, __dif) \ (((__sk)->sk_hash == (__hash)) && net_eq(sock_net(__sk), (__net)) && \ @@ -391,10 +391,12 @@ static inline struct sock *__inet_lookup_skb(struct inet_hashinfo *hashinfo, } extern int __inet_hash_connect(struct inet_timewait_death_row *death_row, - struct sock *sk, u32 port_offset, + struct sock *sk, + u32 port_offset, int (*check_established)(struct inet_timewait_death_row *, struct sock *, __u16, struct inet_timewait_sock **), - void (*hash)(struct sock *sk)); + int (*hash)(struct sock *sk, struct inet_timewait_sock *twp)); + extern int inet_hash_connect(struct inet_timewait_death_row *death_row, struct sock *sk); #endif /* _INET_HASHTABLES_H */ diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h index 47004f35cc7e..83fd34437cf1 100644 --- a/include/net/inet_sock.h +++ b/include/net/inet_sock.h @@ -93,14 +93,14 @@ struct rtable; * * @sk - ancestor class * @pinet6 - pointer to IPv6 control block - * @daddr - Foreign IPv4 addr - * @rcv_saddr - Bound local IPv4 addr - * @dport - Destination port - * @num - Local port - * @saddr - Sending source + * @inet_daddr - Foreign IPv4 addr + * @inet_rcv_saddr - Bound local IPv4 addr + * @inet_dport - Destination port + * @inet_num - Local port + * @inet_saddr - Sending source * @uc_ttl - Unicast TTL - * @sport - Source port - * @id - ID counter for DF pkts + * @inet_sport - Source port + * @inet_id - ID counter for DF pkts * @tos - TOS * @mc_ttl - Multicasting TTL * @is_icsk - is this an inet_connection_sock? @@ -115,17 +115,19 @@ struct inet_sock { struct ipv6_pinfo *pinet6; #endif /* Socket demultiplex comparisons on incoming packets. */ - __be32 daddr; - __be32 rcv_saddr; - __be16 dport; - __u16 num; - __be32 saddr; + __be32 inet_daddr; + __be32 inet_rcv_saddr; + __be16 inet_dport; + __u16 inet_num; + __be32 inet_saddr; __s16 uc_ttl; __u16 cmsg_flags; + __be16 inet_sport; + __u16 inet_id; + struct ip_options *opt; - __be16 sport; - __u16 id; __u8 tos; + __u8 min_ttl; __u8 mc_ttl; __u8 pmtudisc; __u8 recverr:1, @@ -190,10 +192,10 @@ static inline unsigned int inet_ehashfn(struct net *net, static inline int inet_sk_ehashfn(const struct sock *sk) { const struct inet_sock *inet = inet_sk(sk); - const __be32 laddr = inet->rcv_saddr; - const __u16 lport = inet->num; - const __be32 faddr = inet->daddr; - const __be16 fport = inet->dport; + const __be32 laddr = inet->inet_rcv_saddr; + const __u16 lport = inet->inet_num; + const __be32 faddr = inet->inet_daddr; + const __be16 fport = inet->inet_dport; struct net *net = sock_net(sk); return inet_ehashfn(net, laddr, lport, faddr, fport); diff --git a/include/net/inet_timewait_sock.h b/include/net/inet_timewait_sock.h index b63b80fac567..79f67eae8a7e 100644 --- a/include/net/inet_timewait_sock.h +++ b/include/net/inet_timewait_sock.h @@ -130,11 +130,11 @@ struct inet_timewait_sock { __u16 tw_num; kmemcheck_bitfield_begin(flags); /* And these are ours. */ - __u8 tw_ipv6only:1, - tw_transparent:1; - /* 14 bits hole, try to pack */ + unsigned int tw_ipv6only : 1, + tw_transparent : 1, + tw_pad : 14, /* 14 bits hole */ + tw_ipv6_offset : 16; kmemcheck_bitfield_end(flags); - __u16 tw_ipv6_offset; unsigned long tw_ttd; struct inet_bind_bucket *tw_tb; struct hlist_node tw_death_node; @@ -194,11 +194,16 @@ static inline struct inet_timewait_sock *inet_twsk(const struct sock *sk) static inline __be32 inet_rcv_saddr(const struct sock *sk) { return likely(sk->sk_state != TCP_TIME_WAIT) ? - inet_sk(sk)->rcv_saddr : inet_twsk(sk)->tw_rcv_saddr; + inet_sk(sk)->inet_rcv_saddr : inet_twsk(sk)->tw_rcv_saddr; } extern void inet_twsk_put(struct inet_timewait_sock *tw); +extern int inet_twsk_unhash(struct inet_timewait_sock *tw); + +extern int inet_twsk_bind_unhash(struct inet_timewait_sock *tw, + struct inet_hashinfo *hashinfo); + extern struct inet_timewait_sock *inet_twsk_alloc(const struct sock *sk, const int state); @@ -212,14 +217,14 @@ extern void inet_twsk_schedule(struct inet_timewait_sock *tw, extern void inet_twsk_deschedule(struct inet_timewait_sock *tw, struct inet_timewait_death_row *twdr); -extern void inet_twsk_purge(struct net *net, struct inet_hashinfo *hashinfo, +extern void inet_twsk_purge(struct inet_hashinfo *hashinfo, struct inet_timewait_death_row *twdr, int family); static inline struct net *twsk_net(const struct inet_timewait_sock *twsk) { #ifdef CONFIG_NET_NS - return twsk->tw_net; + return rcu_dereference(twsk->tw_net); #else return &init_net; #endif @@ -229,7 +234,7 @@ static inline void twsk_net_set(struct inet_timewait_sock *twsk, struct net *net) { #ifdef CONFIG_NET_NS - twsk->tw_net = net; + rcu_assign_pointer(twsk->tw_net, net); #endif } #endif /* _INET_TIMEWAIT_SOCK_ */ diff --git a/include/net/inetpeer.h b/include/net/inetpeer.h index 15e1f8fe4c1f..87b1df0d4d8c 100644 --- a/include/net/inetpeer.h +++ b/include/net/inetpeer.h @@ -13,20 +13,19 @@ #include <linux/spinlock.h> #include <asm/atomic.h> -struct inet_peer -{ +struct inet_peer { /* group together avl_left,avl_right,v4daddr to speedup lookups */ struct inet_peer *avl_left, *avl_right; __be32 v4daddr; /* peer's address */ - __u16 avl_height; - __u16 ip_id_count; /* IP ID for the next packet */ + __u32 avl_height; struct list_head unused; __u32 dtime; /* the time of last use of not * referenced entries */ atomic_t refcnt; atomic_t rid; /* Frag reception counter */ + atomic_t ip_id_count; /* IP ID for the next packet */ __u32 tcp_ts; - unsigned long tcp_ts_stamp; + __u32 tcp_ts_stamp; }; void inet_initpeers(void) __init; @@ -37,17 +36,11 @@ struct inet_peer *inet_getpeer(__be32 daddr, int create); /* can be called from BH context or outside */ extern void inet_putpeer(struct inet_peer *p); -extern spinlock_t inet_peer_idlock; /* can be called with or without local BH being disabled */ static inline __u16 inet_getid(struct inet_peer *p, int more) { - __u16 id; - - spin_lock_bh(&inet_peer_idlock); - id = p->ip_id_count; - p->ip_id_count += 1 + more; - spin_unlock_bh(&inet_peer_idlock); - return id; + more++; + return atomic_add_return(more, &p->ip_id_count) - more; } #endif /* _NET_INETPEER_H */ diff --git a/include/net/ip.h b/include/net/ip.h index 5b26a0bd178e..503994a38ed1 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -33,8 +33,7 @@ struct sock; -struct inet_skb_parm -{ +struct inet_skb_parm { struct ip_options opt; /* Compiled IP options */ unsigned char flags; @@ -50,8 +49,7 @@ static inline unsigned int ip_hdrlen(const struct sk_buff *skb) return ip_hdr(skb)->ihl * 4; } -struct ipcm_cookie -{ +struct ipcm_cookie { __be32 addr; int oif; struct ip_options *opt; @@ -60,8 +58,7 @@ struct ipcm_cookie #define IPCB(skb) ((struct inet_skb_parm*)((skb)->cb)) -struct ip_ra_chain -{ +struct ip_ra_chain { struct ip_ra_chain *next; struct sock *sk; void (*destructor)(struct sock *); @@ -159,8 +156,7 @@ static inline __u8 ip_reply_arg_flowi_flags(const struct ip_reply_arg *arg) void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *arg, unsigned int len); -struct ipv4_config -{ +struct ipv4_config { int log_martians; int no_pmtu_disc; }; @@ -178,9 +174,9 @@ extern struct ipv4_config ipv4_config; #define NET_ADD_STATS_BH(net, field, adnd) SNMP_ADD_STATS_BH((net)->mib.net_statistics, field, adnd) #define NET_ADD_STATS_USER(net, field, adnd) SNMP_ADD_STATS_USER((net)->mib.net_statistics, field, adnd) -extern unsigned long snmp_fold_field(void *mib[], int offt); -extern int snmp_mib_init(void *ptr[2], size_t mibsize); -extern void snmp_mib_free(void *ptr[2]); +extern unsigned long snmp_fold_field(void __percpu *mib[], int offt); +extern int snmp_mib_init(void __percpu *ptr[2], size_t mibsize); +extern void snmp_mib_free(void __percpu *ptr[2]); extern struct local_ports { seqlock_t lock; @@ -240,8 +236,8 @@ static inline void ip_select_ident(struct iphdr *iph, struct dst_entry *dst, str * does not change, they drop every other packet in * a TCP stream using header compression. */ - iph->id = (sk && inet_sk(sk)->daddr) ? - htons(inet_sk(sk)->id++) : 0; + iph->id = (sk && inet_sk(sk)->inet_daddr) ? + htons(inet_sk(sk)->inet_id++) : 0; } else __ip_select_ident(iph, dst, 0); } @@ -249,9 +245,9 @@ static inline void ip_select_ident(struct iphdr *iph, struct dst_entry *dst, str static inline void ip_select_ident_more(struct iphdr *iph, struct dst_entry *dst, struct sock *sk, int more) { if (iph->frag_off & htons(IP_DF)) { - if (sk && inet_sk(sk)->daddr) { - iph->id = htons(inet_sk(sk)->id); - inet_sk(sk)->id += 1 + more; + if (sk && inet_sk(sk)->inet_daddr) { + iph->id = htons(inet_sk(sk)->inet_id); + inet_sk(sk)->inet_id += 1 + more; } else iph->id = 0; } else @@ -317,7 +313,7 @@ static inline void ip_ib_mc_map(__be32 naddr, const unsigned char *broadcast, ch static __inline__ void inet_reset_saddr(struct sock *sk) { - inet_sk(sk)->rcv_saddr = inet_sk(sk)->saddr = 0; + inet_sk(sk)->inet_rcv_saddr = inet_sk(sk)->inet_saddr = 0; #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) if (sk->sk_family == PF_INET6) { struct ipv6_pinfo *np = inet6_sk(sk); @@ -330,18 +326,37 @@ static __inline__ void inet_reset_saddr(struct sock *sk) #endif +static inline int sk_mc_loop(struct sock *sk) +{ + if (!sk) + return 1; + switch (sk->sk_family) { + case AF_INET: + return inet_sk(sk)->mc_loop; +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + case AF_INET6: + return inet6_sk(sk)->mc_loop; +#endif + } + WARN_ON(1); + return 1; +} + extern int ip_call_ra_chain(struct sk_buff *skb); /* * Functions provided by ip_fragment.c */ -enum ip_defrag_users -{ +enum ip_defrag_users { IP_DEFRAG_LOCAL_DELIVER, IP_DEFRAG_CALL_RA_CHAIN, IP_DEFRAG_CONNTRACK_IN, + __IP_DEFRAG_CONNTRACK_IN_END = IP_DEFRAG_CONNTRACK_IN + USHORT_MAX, IP_DEFRAG_CONNTRACK_OUT, + __IP_DEFRAG_CONNTRACK_OUT_END = IP_DEFRAG_CONNTRACK_OUT + USHORT_MAX, + IP_DEFRAG_CONNTRACK_BRIDGE_IN, + __IP_DEFRAG_CONNTRACK_BRIDGE_IN = IP_DEFRAG_CONNTRACK_BRIDGE_IN + USHORT_MAX, IP_DEFRAG_VS_IN, IP_DEFRAG_VS_OUT, IP_DEFRAG_VS_FWD @@ -381,10 +396,10 @@ extern int ip_options_rcv_srr(struct sk_buff *skb); extern void ip_cmsg_recv(struct msghdr *msg, struct sk_buff *skb); extern int ip_cmsg_send(struct net *net, struct msghdr *msg, struct ipcm_cookie *ipc); -extern int ip_setsockopt(struct sock *sk, int level, int optname, char __user *optval, int optlen); +extern int ip_setsockopt(struct sock *sk, int level, int optname, char __user *optval, unsigned int optlen); extern int ip_getsockopt(struct sock *sk, int level, int optname, char __user *optval, int __user *optlen); extern int compat_ip_setsockopt(struct sock *sk, int level, - int optname, char __user *optval, int optlen); + int optname, char __user *optval, unsigned int optlen); extern int compat_ip_getsockopt(struct sock *sk, int level, int optname, char __user *optval, int __user *optlen); extern int ip_ra_control(struct sock *sk, unsigned char on, void (*destructor)(struct sock *)); diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h index 15b492a9aa79..86f46c49e318 100644 --- a/include/net/ip6_fib.h +++ b/include/net/ip6_fib.h @@ -30,8 +30,7 @@ struct rt6_info; -struct fib6_config -{ +struct fib6_config { u32 fc_table; u32 fc_metric; int fc_dst_len; @@ -51,8 +50,7 @@ struct fib6_config struct nl_info fc_nlinfo; }; -struct fib6_node -{ +struct fib6_node { struct fib6_node *parent; struct fib6_node *left; struct fib6_node *right; @@ -78,16 +76,14 @@ struct fib6_node * */ -struct rt6key -{ +struct rt6key { struct in6_addr addr; int plen; }; struct fib6_table; -struct rt6_info -{ +struct rt6_info { union { struct dst_entry dst; } u; @@ -127,13 +123,14 @@ static inline struct inet6_dev *ip6_dst_idev(struct dst_entry *dst) return ((struct rt6_info *)dst)->rt6i_idev; } -struct fib6_walker_t -{ - struct fib6_walker_t *prev, *next; +struct fib6_walker_t { + struct list_head lh; struct fib6_node *root, *node; struct rt6_info *leaf; unsigned char state; unsigned char prune; + unsigned int skip; + unsigned int count; int (*func)(struct fib6_walker_t *); void *args; }; diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h index 0e1b8aebaff8..68f67836e146 100644 --- a/include/net/ip6_route.h +++ b/include/net/ip6_route.h @@ -37,6 +37,24 @@ struct route_info { #define RT6_LOOKUP_F_SRCPREF_PUBLIC 0x00000010 #define RT6_LOOKUP_F_SRCPREF_COA 0x00000020 +/* + * rt6_srcprefs2flags() and rt6_flags2srcprefs() translate + * between IPV6_ADDR_PREFERENCES socket option values + * IPV6_PREFER_SRC_TMP = 0x1 + * IPV6_PREFER_SRC_PUBLIC = 0x2 + * IPV6_PREFER_SRC_COA = 0x4 + * and above RT6_LOOKUP_F_SRCPREF_xxx flags. + */ +static inline int rt6_srcprefs2flags(unsigned int srcprefs) +{ + /* No need to bitmask because srcprefs have only 3 bits. */ + return srcprefs << 3; +} + +static inline unsigned int rt6_flags2srcprefs(int flags) +{ + return (flags >> 3) & 7; +} extern void ip6_route_input(struct sk_buff *skb); @@ -103,8 +121,7 @@ extern void rt6_pmtu_discovery(struct in6_addr *daddr, struct netlink_callback; -struct rt6_rtnl_dump_arg -{ +struct rt6_rtnl_dump_arg { struct sk_buff *skb; struct netlink_callback *cb; struct net *net; diff --git a/include/net/ip6_tunnel.h b/include/net/ip6_tunnel.h index 83b4e008b16d..fbf9d1cda27b 100644 --- a/include/net/ip6_tunnel.h +++ b/include/net/ip6_tunnel.h @@ -15,7 +15,6 @@ struct ip6_tnl { struct ip6_tnl *next; /* next tunnel in list */ struct net_device *dev; /* virtual device associated with tunnel */ - int recursion; /* depth of hard_start_xmit recursion */ struct ip6_tnl_parm parms; /* tunnel configuration parameters */ struct flowi fl; /* flowi template for xmit */ struct dst_entry *dst_cache; /* cached dst */ diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h index ef91fe924ba4..c93f94edc610 100644 --- a/include/net/ip_fib.h +++ b/include/net/ip_fib.h @@ -144,18 +144,21 @@ struct fib_table { struct hlist_node tb_hlist; u32 tb_id; int tb_default; - int (*tb_lookup)(struct fib_table *tb, const struct flowi *flp, struct fib_result *res); - int (*tb_insert)(struct fib_table *, struct fib_config *); - int (*tb_delete)(struct fib_table *, struct fib_config *); - int (*tb_dump)(struct fib_table *table, struct sk_buff *skb, - struct netlink_callback *cb); - int (*tb_flush)(struct fib_table *table); - void (*tb_select_default)(struct fib_table *table, - const struct flowi *flp, struct fib_result *res); - unsigned char tb_data[0]; }; +extern int fib_table_lookup(struct fib_table *tb, const struct flowi *flp, + struct fib_result *res); +extern int fib_table_insert(struct fib_table *, struct fib_config *); +extern int fib_table_delete(struct fib_table *, struct fib_config *); +extern int fib_table_dump(struct fib_table *table, struct sk_buff *skb, + struct netlink_callback *cb); +extern int fib_table_flush(struct fib_table *table); +extern void fib_table_select_default(struct fib_table *table, + const struct flowi *flp, + struct fib_result *res); + + #ifndef CONFIG_IP_MULTIPLE_TABLES #define TABLE_LOCAL_INDEX 0 @@ -182,11 +185,11 @@ static inline int fib_lookup(struct net *net, const struct flowi *flp, struct fib_table *table; table = fib_get_table(net, RT_TABLE_LOCAL); - if (!table->tb_lookup(table, flp, res)) + if (!fib_table_lookup(table, flp, res)) return 0; table = fib_get_table(net, RT_TABLE_MAIN); - if (!table->tb_lookup(table, flp, res)) + if (!fib_table_lookup(table, flp, res)) return 0; return -ENETUNREACH; } @@ -210,7 +213,8 @@ extern struct fib_table *fib_get_table(struct net *net, u32 id); extern const struct nla_policy rtm_ipv4_policy[]; extern void ip_fib_init(void); extern int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif, - struct net_device *dev, __be32 *spec_dst, u32 *itag); + struct net_device *dev, __be32 *spec_dst, + u32 *itag, u32 mark); extern void fib_select_default(struct net *net, const struct flowi *flp, struct fib_result *res); diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h index 98978e73f666..fe82b1e10a29 100644 --- a/include/net/ip_vs.h +++ b/include/net/ip_vs.h @@ -26,6 +26,11 @@ #include <linux/ipv6.h> /* for struct ipv6hdr */ #include <net/ipv6.h> /* for ipv6_addr_copy */ + +/* Connections' size value needed by ip_vs_ctl.c */ +extern int ip_vs_conn_tab_size; + + struct ip_vs_iphdr { int len; __u8 protocol; @@ -220,6 +225,26 @@ enum { }; /* + * SCTP State Values + */ +enum ip_vs_sctp_states { + IP_VS_SCTP_S_NONE, + IP_VS_SCTP_S_INIT_CLI, + IP_VS_SCTP_S_INIT_SER, + IP_VS_SCTP_S_INIT_ACK_CLI, + IP_VS_SCTP_S_INIT_ACK_SER, + IP_VS_SCTP_S_ECHO_CLI, + IP_VS_SCTP_S_ECHO_SER, + IP_VS_SCTP_S_ESTABLISHED, + IP_VS_SCTP_S_SHUT_CLI, + IP_VS_SCTP_S_SHUT_SER, + IP_VS_SCTP_S_SHUT_ACK_CLI, + IP_VS_SCTP_S_SHUT_ACK_SER, + IP_VS_SCTP_S_CLOSED, + IP_VS_SCTP_S_LAST +}; + +/* * Delta sequence info structure * Each ip_vs_conn has 2 (output AND input seq. changes). * Only used in the VS/NAT. @@ -251,8 +276,7 @@ struct ip_vs_estimator { u32 outbps; }; -struct ip_vs_stats -{ +struct ip_vs_stats { struct ip_vs_stats_user ustats; /* statistics */ struct ip_vs_estimator est; /* estimator */ @@ -518,8 +542,7 @@ struct ip_vs_scheduler { /* * The application module object (a.k.a. app incarnation) */ -struct ip_vs_app -{ +struct ip_vs_app { struct list_head a_list; /* member in app list */ int type; /* IP_VS_APP_TYPE_xxx */ char *name; /* application module name */ @@ -594,17 +617,6 @@ extern void ip_vs_init_hash_table(struct list_head *table, int rows); * (from ip_vs_conn.c) */ -/* - * IPVS connection entry hash table - */ -#ifndef CONFIG_IP_VS_TAB_BITS -#define CONFIG_IP_VS_TAB_BITS 12 -#endif - -#define IP_VS_CONN_TAB_BITS CONFIG_IP_VS_TAB_BITS -#define IP_VS_CONN_TAB_SIZE (1 << IP_VS_CONN_TAB_BITS) -#define IP_VS_CONN_TAB_MASK (IP_VS_CONN_TAB_SIZE - 1) - enum { IP_VS_DIR_INPUT = 0, IP_VS_DIR_OUTPUT, @@ -749,7 +761,7 @@ extern struct ip_vs_protocol ip_vs_protocol_udp; extern struct ip_vs_protocol ip_vs_protocol_icmp; extern struct ip_vs_protocol ip_vs_protocol_esp; extern struct ip_vs_protocol ip_vs_protocol_ah; - +extern struct ip_vs_protocol ip_vs_protocol_sctp; /* * Registering/unregistering scheduler functions diff --git a/include/net/ipcomp.h b/include/net/ipcomp.h index 2a1092abaa07..cc4f30cd7315 100644 --- a/include/net/ipcomp.h +++ b/include/net/ipcomp.h @@ -9,7 +9,7 @@ struct crypto_comp; struct ipcomp_data { u16 threshold; - struct crypto_comp **tfms; + struct crypto_comp * __percpu *tfms; }; struct ip_comp_hdr; diff --git a/include/net/ipip.h b/include/net/ipip.h index 76e3ea6e2fe5..11e8513d2d07 100644 --- a/include/net/ipip.h +++ b/include/net/ipip.h @@ -7,8 +7,15 @@ /* Keep error state on tunnel for 30 sec */ #define IPTUNNEL_ERR_TIMEO (30*HZ) -struct ip_tunnel -{ +/* 6rd prefix/relay information */ +struct ip_tunnel_6rd_parm { + struct in6_addr prefix; + __be32 relay_prefix; + u16 prefixlen; + u16 relay_prefixlen; +}; + +struct ip_tunnel { struct ip_tunnel *next; struct net_device *dev; @@ -23,22 +30,19 @@ struct ip_tunnel struct ip_tunnel_parm parms; + /* for SIT */ +#ifdef CONFIG_IPV6_SIT_6RD + struct ip_tunnel_6rd_parm ip6rd; +#endif struct ip_tunnel_prl_entry *prl; /* potential router list */ unsigned int prl_count; /* # of entries in PRL */ }; -/* ISATAP: default interval between RS in secondy */ -#define IPTUNNEL_RS_DEFAULT_DELAY (900) - -struct ip_tunnel_prl_entry -{ +struct ip_tunnel_prl_entry { struct ip_tunnel_prl_entry *next; __be32 addr; u16 flags; - unsigned long rs_delay; - struct timer_list rs_timer; - struct ip_tunnel *tunnel; - spinlock_t lock; + struct rcu_head rcu_head; }; #define IPTUNNEL_XMIT() do { \ @@ -49,9 +53,9 @@ struct ip_tunnel_prl_entry ip_select_ident(iph, &rt->u.dst, NULL); \ \ err = ip_local_out(skb); \ - if (net_xmit_eval(err) == 0) { \ - stats->tx_bytes += pkt_len; \ - stats->tx_packets++; \ + if (likely(net_xmit_eval(err) == 0)) { \ + txq->tx_bytes += pkt_len; \ + txq->tx_packets++; \ } else { \ stats->tx_errors++; \ stats->tx_aborted_errors++; \ diff --git a/include/net/ipv6.h b/include/net/ipv6.h index ad9a51130254..e72fb10ce573 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h @@ -73,7 +73,6 @@ #define IPV6_ADDR_SCOPE_MASK 0x00f0U #define IPV6_ADDR_MAPPED 0x1000U -#define IPV6_ADDR_RESERVED 0x2000U /* reserved address space */ /* * Addr scopes @@ -160,8 +159,7 @@ extern struct ctl_path net_ipv6_ctl_path[]; #define ICMP6MSGIN_INC_STATS_BH(net, idev, field) \ _DEVINC(net, icmpv6msg, _BH, idev, field) -struct ip6_ra_chain -{ +struct ip6_ra_chain { struct ip6_ra_chain *next; struct sock *sk; int sel; @@ -176,8 +174,7 @@ extern rwlock_t ip6_ra_lock; ancillary data and passed to IPv6. */ -struct ipv6_txoptions -{ +struct ipv6_txoptions { /* Length of this structure */ int tot_len; @@ -194,8 +191,7 @@ struct ipv6_txoptions /* Option buffer, as read by IPV6_PKTOPTIONS, starts here. */ }; -struct ip6_flowlabel -{ +struct ip6_flowlabel { struct ip6_flowlabel *next; __be32 label; atomic_t users; @@ -212,8 +208,7 @@ struct ip6_flowlabel #define IPV6_FLOWINFO_MASK cpu_to_be32(0x0FFFFFFF) #define IPV6_FLOWLABEL_MASK cpu_to_be32(0x000FFFFF) -struct ipv6_fl_socklist -{ +struct ipv6_fl_socklist { struct ipv6_fl_socklist *next; struct ip6_flowlabel *fl; }; @@ -250,7 +245,9 @@ extern int ipv6_opt_accepted(struct sock *sk, struct sk_buff *skb); int ip6_frag_nqueues(struct net *net); int ip6_frag_mem(struct net *net); -#define IPV6_FRAG_TIMEOUT (60*HZ) /* 60 seconds */ +#define IPV6_FRAG_HIGH_THRESH (256 * 1024) /* 262144 */ +#define IPV6_FRAG_LOW_THRESH (192 * 1024) /* 196608 */ +#define IPV6_FRAG_TIMEOUT (60 * HZ) /* 60 seconds */ extern int __ipv6_addr_type(const struct in6_addr *addr); static inline int ipv6_addr_type(const struct in6_addr *addr) @@ -354,8 +351,19 @@ static inline int ipv6_prefix_equal(const struct in6_addr *a1, struct inet_frag_queue; +enum ip6_defrag_users { + IP6_DEFRAG_LOCAL_DELIVER, + IP6_DEFRAG_CONNTRACK_IN, + __IP6_DEFRAG_CONNTRACK_IN = IP6_DEFRAG_CONNTRACK_IN + USHORT_MAX, + IP6_DEFRAG_CONNTRACK_OUT, + __IP6_DEFRAG_CONNTRACK_OUT = IP6_DEFRAG_CONNTRACK_OUT + USHORT_MAX, + IP6_DEFRAG_CONNTRACK_BRIDGE_IN, + __IP6_DEFRAG_CONNTRACK_BRIDGE_IN = IP6_DEFRAG_CONNTRACK_BRIDGE_IN + USHORT_MAX, +}; + struct ip6_create_arg { __be32 id; + u32 user; struct in6_addr *src; struct in6_addr *dst; }; @@ -550,7 +558,7 @@ extern int ipv6_find_tlv(struct sk_buff *skb, int offset, int type); extern int ipv6_setsockopt(struct sock *sk, int level, int optname, char __user *optval, - int optlen); + unsigned int optlen); extern int ipv6_getsockopt(struct sock *sk, int level, int optname, char __user *optval, @@ -559,7 +567,7 @@ extern int compat_ipv6_setsockopt(struct sock *sk, int level, int optname, char __user *optval, - int optlen); + unsigned int optlen); extern int compat_ipv6_getsockopt(struct sock *sk, int level, int optname, diff --git a/include/net/irda/irttp.h b/include/net/irda/irttp.h index 0788c23d2828..11aee7a2972a 100644 --- a/include/net/irda/irttp.h +++ b/include/net/irda/irttp.h @@ -97,7 +97,7 @@ #define TTP_MAX_SDU_SIZE 0x01 /* - * This structure contains all data assosiated with one instance of a TTP + * This structure contains all data associated with one instance of a TTP * connection. */ struct tsap_cb { diff --git a/include/net/iw_handler.h b/include/net/iw_handler.h index e9054a283fde..b2b98f3fa265 100644 --- a/include/net/iw_handler.h +++ b/include/net/iw_handler.h @@ -300,8 +300,7 @@ * This struct is also my long term insurance. I can add new fields here * without breaking the prototype of iw_handler... */ -struct iw_request_info -{ +struct iw_request_info { __u16 cmd; /* Wireless Extension command */ __u16 flags; /* More to come ;-) */ }; @@ -321,20 +320,20 @@ typedef int (*iw_handler)(struct net_device *dev, struct iw_request_info *info, * shared by all driver instances... Same for the members... * This will be linked from net_device in <linux/netdevice.h> */ -struct iw_handler_def -{ - /* Number of handlers defined (more precisely, index of the - * last defined handler + 1) */ - __u16 num_standard; - __u16 num_private; - /* Number of private arg description */ - __u16 num_private_args; +struct iw_handler_def { /* Array of handlers for standard ioctls * We will call dev->wireless_handlers->standard[ioctl - SIOCSIWCOMMIT] */ const iw_handler * standard; + /* Number of handlers defined (more precisely, index of the + * last defined handler + 1) */ + __u16 num_standard; +#ifdef CONFIG_WEXT_PRIV + __u16 num_private; + /* Number of private arg description */ + __u16 num_private_args; /* Array of handlers for private ioctls * Will call dev->wireless_handlers->private[ioctl - SIOCIWFIRSTPRIV] */ @@ -344,6 +343,7 @@ struct iw_handler_def * can put it in any order you want and should not leave holes... * We will automatically export that to user space... */ const struct iw_priv_args * private_args; +#endif /* New location of get_wireless_stats, to de-bloat struct net_device. * The old pointer in struct net_device will be gradually phased @@ -370,8 +370,7 @@ struct iw_handler_def /* * Describe how a standard IOCTL looks like. */ -struct iw_ioctl_description -{ +struct iw_ioctl_description { __u8 header_type; /* NULL, iw_point or other */ __u8 token_type; /* Future */ __u16 token_size; /* Granularity of payload */ @@ -393,8 +392,7 @@ struct iw_ioctl_description /* * Instance specific spy data, i.e. addresses spied and quality for them. */ -struct iw_spy_data -{ +struct iw_spy_data { /* --- Standard spy support --- */ int spy_number; u_char spy_address[IW_MAX_SPY][ETH_ALEN]; diff --git a/include/net/llc.h b/include/net/llc.h index 7940da1606e7..5503b74ab170 100644 --- a/include/net/llc.h +++ b/include/net/llc.h @@ -16,6 +16,9 @@ #include <linux/if_ether.h> #include <linux/list.h> #include <linux/spinlock.h> +#include <linux/rculist_nulls.h> +#include <linux/hash.h> +#include <linux/jhash.h> #include <asm/atomic.h> @@ -31,6 +34,12 @@ struct llc_addr { #define LLC_SAP_STATE_INACTIVE 1 #define LLC_SAP_STATE_ACTIVE 2 +#define LLC_SK_DEV_HASH_BITS 6 +#define LLC_SK_DEV_HASH_ENTRIES (1<<LLC_SK_DEV_HASH_BITS) + +#define LLC_SK_LADDR_HASH_BITS 6 +#define LLC_SK_LADDR_HASH_ENTRIES (1<<LLC_SK_LADDR_HASH_BITS) + /** * struct llc_sap - Defines the SAP component * @@ -53,18 +62,38 @@ struct llc_sap { struct net_device *orig_dev); struct llc_addr laddr; struct list_head node; - struct { - rwlock_t lock; - struct hlist_head list; - } sk_list; + spinlock_t sk_lock; + int sk_count; + struct hlist_nulls_head sk_laddr_hash[LLC_SK_LADDR_HASH_ENTRIES]; + struct hlist_head sk_dev_hash[LLC_SK_DEV_HASH_ENTRIES]; }; +static inline +struct hlist_head *llc_sk_dev_hash(struct llc_sap *sap, int ifindex) +{ + return &sap->sk_dev_hash[ifindex % LLC_SK_DEV_HASH_ENTRIES]; +} + +static inline +u32 llc_sk_laddr_hashfn(struct llc_sap *sap, const struct llc_addr *laddr) +{ + return hash_32(jhash(laddr->mac, sizeof(laddr->mac), 0), + LLC_SK_LADDR_HASH_BITS); +} + +static inline +struct hlist_nulls_head *llc_sk_laddr_hash(struct llc_sap *sap, + const struct llc_addr *laddr) +{ + return &sap->sk_laddr_hash[llc_sk_laddr_hashfn(sap, laddr)]; +} + #define LLC_DEST_INVALID 0 /* Invalid LLC PDU type */ #define LLC_DEST_SAP 1 /* Type 1 goes here */ #define LLC_DEST_CONN 2 /* Type 2 goes here */ extern struct list_head llc_sap_list; -extern rwlock_t llc_sap_list_lock; +extern spinlock_t llc_sap_list_lock; extern int llc_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev); diff --git a/include/net/llc_conn.h b/include/net/llc_conn.h index e2374e34989f..2f97d8ddce92 100644 --- a/include/net/llc_conn.h +++ b/include/net/llc_conn.h @@ -76,6 +76,8 @@ struct llc_sock { u32 rx_pdu_hdr; /* used for saving header of last pdu received and caused sending FRMR. Used for resending FRMR */ + u32 cmsg_flags; + struct hlist_node dev_hash_node; }; static inline struct llc_sock *llc_sk(const struct sock *sk) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 466859b285e1..45d7d44d7cbe 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -3,7 +3,7 @@ * * Copyright 2002-2005, Devicescape Software, Inc. * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> - * Copyright 2007-2008 Johannes Berg <johannes@sipsolutions.net> + * Copyright 2007-2010 Johannes Berg <johannes@sipsolutions.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -107,25 +107,14 @@ enum ieee80211_max_queues { * 2^n-1 in the range 1..32767] * @cw_max: maximum contention window [like @cw_min] * @txop: maximum burst time in units of 32 usecs, 0 meaning disabled + * @uapsd: is U-APSD mode enabled for the queue */ struct ieee80211_tx_queue_params { u16 txop; u16 cw_min; u16 cw_max; u8 aifs; -}; - -/** - * struct ieee80211_tx_queue_stats - transmit queue statistics - * - * @len: number of packets in queue - * @limit: queue length limit - * @count: number of frames sent - */ -struct ieee80211_tx_queue_stats { - unsigned int len; - unsigned int limit; - unsigned int count; + bool uapsd; }; struct ieee80211_low_level_stats { @@ -184,7 +173,8 @@ enum ieee80211_bss_change { * @use_short_slot: use short slot time (only relevant for ERP); * 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 PSM + * @dtim_period: num of beacons before the next DTIM, for beaconing, + * not valid in station mode (cf. hw conf ps_dtim_period) * @timestamp: beacon timestamp * @beacon_int: beacon interval * @assoc_capability: capabilities taken from assoc resp @@ -219,7 +209,7 @@ struct ieee80211_bss_conf { * * These flags are used with the @flags member of &ieee80211_tx_info. * - * @IEEE80211_TX_CTL_REQ_TX_STATUS: request TX status callback for this frame. + * @IEEE80211_TX_CTL_REQ_TX_STATUS: require TX status callback for this frame. * @IEEE80211_TX_CTL_ASSIGN_SEQ: The driver has to assign a sequence * number to this frame, taking care of not overwriting the fragment * number and increasing the sequence number only when the @@ -255,9 +245,6 @@ 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_RCALGO: mac80211 internal flag, do not test or - * set this flag in the driver; indicates that the rate control - * algorithm was used and should be notified of TX status * @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. @@ -272,6 +259,14 @@ struct ieee80211_bss_conf { * transmit function after the current frame, this can be used * by drivers to kick the DMA queue only if unset or when the * queue gets full. + * @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_HAS_RADIOTAP: This frame was injected and still + * has a radiotap header at skb->data. + * @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) */ enum mac80211_tx_control_flags { IEEE80211_TX_CTL_REQ_TX_STATUS = BIT(0), @@ -287,12 +282,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_RCALGO = 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_PSPOLL_RESPONSE = BIT(17), IEEE80211_TX_CTL_MORE_FRAMES = BIT(18), + IEEE80211_TX_INTFL_RETRANSMISSION = BIT(19), + IEEE80211_TX_INTFL_HAS_RADIOTAP = BIT(20), + IEEE80211_TX_INTFL_NL80211_FRAME_TX = BIT(21), }; /** @@ -390,10 +387,12 @@ struct ieee80211_tx_rate { * @control: union for control data * @status: union for status data * @driver_data: array of driver_data pointers - * @ampdu_ack_len: number of aggregated frames. + * @ampdu_ack_len: number of acked aggregated frames. * relevant only if IEEE80211_TX_STATUS_AMPDU was set. * @ampdu_ack_map: block ack bit map for the aggregation. * relevant only if IEEE80211_TX_STATUS_AMPDU was set. + * @ampdu_len: number of aggregated frames. + * relevant only if IEEE80211_TX_STATUS_AMPDU was set. * @ack_signal: signal strength of the ACK frame */ struct ieee80211_tx_info { @@ -428,7 +427,8 @@ struct ieee80211_tx_info { u8 ampdu_ack_len; u64 ampdu_ack_map; int ack_signal; - /* 8 bytes free */ + u8 ampdu_len; + /* 7 bytes free */ } status; struct { struct ieee80211_tx_rate driver_rates[ @@ -494,7 +494,6 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info) * @RX_FLAG_MMIC_ERROR: Michael MIC error was reported on this frame. * Use together with %RX_FLAG_MMIC_STRIPPED. * @RX_FLAG_DECRYPTED: This frame was decrypted in hardware. - * @RX_FLAG_RADIOTAP: This frame starts with a radiotap header. * @RX_FLAG_MMIC_STRIPPED: the Michael MIC is stripped off this frame, * verification has been done by the hardware. * @RX_FLAG_IV_STRIPPED: The IV/ICV are stripped from this frame. @@ -511,11 +510,13 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info) * @RX_FLAG_HT: HT MCS was used and rate_idx is MCS index * @RX_FLAG_40MHZ: HT40 (40 MHz) was used * @RX_FLAG_SHORT_GI: Short guard interval was used + * @RX_FLAG_INTERNAL_CMTR: set internally after frame was reported + * on cooked monitor to avoid double-reporting it for multiple + * virtual interfaces */ enum mac80211_rx_flags { RX_FLAG_MMIC_ERROR = 1<<0, RX_FLAG_DECRYPTED = 1<<1, - RX_FLAG_RADIOTAP = 1<<2, RX_FLAG_MMIC_STRIPPED = 1<<3, RX_FLAG_IV_STRIPPED = 1<<4, RX_FLAG_FAILED_FCS_CRC = 1<<5, @@ -525,6 +526,7 @@ enum mac80211_rx_flags { RX_FLAG_HT = 1<<9, RX_FLAG_40MHZ = 1<<10, RX_FLAG_SHORT_GI = 1<<11, + RX_FLAG_INTERNAL_CMTR = 1<<12, }; /** @@ -542,7 +544,6 @@ enum mac80211_rx_flags { * unspecified depending on the hardware capabilities flags * @IEEE80211_HW_SIGNAL_* * @noise: noise when receiving this frame, in dBm. - * @qual: overall signal quality indication, in percent (0-100). * @antenna: antenna used * @rate_idx: index of data rate into band's supported rates or MCS index if * HT rates are use (RX_FLAG_HT) @@ -554,7 +555,6 @@ struct ieee80211_rx_status { int freq; int signal; int noise; - int qual; int antenna; int rate_idx; int flag; @@ -565,8 +565,16 @@ struct ieee80211_rx_status { * * Flags to define PHY configuration options * - * @IEEE80211_CONF_RADIOTAP: add radiotap header at receive time (if supported) - * @IEEE80211_CONF_PS: Enable 802.11 power save mode (managed mode only) + * @IEEE80211_CONF_MONITOR: there's a monitor interface present -- use this + * to determine for example whether to calculate timestamps for packets + * or not, do not use instead of filter flags! + * @IEEE80211_CONF_PS: Enable 802.11 power save mode (managed mode only). + * This is the power save mode defined by IEEE 802.11-2007 section 11.2, + * meaning that the hardware still wakes up for beacons, is able to + * transmit frames and receive the possible acknowledgment frames. + * Not to be confused with hardware specific wakeup/sleep states, + * driver is responsible for that. See the section "Powersave support" + * for more. * @IEEE80211_CONF_IDLE: The device is running, but idle; if the flag is set * the driver should be prepared to handle configuration requests but * may turn the device off as much as possible. Typically, this flag will @@ -574,7 +582,7 @@ struct ieee80211_rx_status { * it can also be unset in that case when monitor interfaces are active. */ enum ieee80211_conf_flags { - IEEE80211_CONF_RADIOTAP = (1<<0), + IEEE80211_CONF_MONITOR = (1<<0), IEEE80211_CONF_PS = (1<<1), IEEE80211_CONF_IDLE = (1<<2), }; @@ -584,16 +592,18 @@ enum ieee80211_conf_flags { * enum ieee80211_conf_changed - denotes which configuration changed * * @IEEE80211_CONF_CHANGE_LISTEN_INTERVAL: the listen interval changed - * @IEEE80211_CONF_CHANGE_RADIOTAP: the radiotap flag changed + * @IEEE80211_CONF_CHANGE_MONITOR: the monitor flag changed * @IEEE80211_CONF_CHANGE_PS: the PS flag or dynamic PS timeout changed * @IEEE80211_CONF_CHANGE_POWER: the TX power changed * @IEEE80211_CONF_CHANGE_CHANNEL: the channel/channel_type changed * @IEEE80211_CONF_CHANGE_RETRY_LIMITS: retry limits changed * @IEEE80211_CONF_CHANGE_IDLE: Idle flag changed + * @IEEE80211_CONF_CHANGE_SMPS: Spatial multiplexing powersave mode changed */ enum ieee80211_conf_changed { + IEEE80211_CONF_CHANGE_SMPS = BIT(1), IEEE80211_CONF_CHANGE_LISTEN_INTERVAL = BIT(2), - IEEE80211_CONF_CHANGE_RADIOTAP = BIT(3), + IEEE80211_CONF_CHANGE_MONITOR = BIT(3), IEEE80211_CONF_CHANGE_PS = BIT(4), IEEE80211_CONF_CHANGE_POWER = BIT(5), IEEE80211_CONF_CHANGE_CHANNEL = BIT(6), @@ -602,6 +612,25 @@ enum ieee80211_conf_changed { }; /** + * enum ieee80211_smps_mode - spatial multiplexing power save mode + * + * @IEEE80211_SMPS_AUTOMATIC: automatic + * @IEEE80211_SMPS_OFF: off + * @IEEE80211_SMPS_STATIC: static + * @IEEE80211_SMPS_DYNAMIC: dynamic + * @IEEE80211_SMPS_NUM_MODES: internal, don't use + */ +enum ieee80211_smps_mode { + IEEE80211_SMPS_AUTOMATIC, + IEEE80211_SMPS_OFF, + IEEE80211_SMPS_STATIC, + IEEE80211_SMPS_DYNAMIC, + + /* keep last */ + IEEE80211_SMPS_NUM_MODES, +}; + +/** * struct ieee80211_conf - configuration of the device * * This struct indicates how the driver shall configure the hardware. @@ -614,6 +643,9 @@ enum ieee80211_conf_changed { * value will be only achievable between DTIM frames, the hardware * needs to check for the multicast traffic bit in DTIM beacons. * This variable is valid only when the CONF_PS flag is set. + * @ps_dtim_period: The DTIM period of the AP we're connected to, for use + * in power saving. Power saving will not be enabled until a beacon + * has been received and the DTIM period is known. * @dynamic_ps_timeout: The dynamic powersave timeout (in ms), see the * powersave documentation below. This variable is valid only when * the CONF_PS flag is set. @@ -629,6 +661,10 @@ enum ieee80211_conf_changed { * @short_frame_max_tx_count: Maximum number of transmissions for a "short" * frame, called "dot11ShortRetryLimit" in 802.11, but actually means the * number of transmissions not the number of retries + * + * @smps_mode: spatial multiplexing powersave mode; note that + * %IEEE80211_SMPS_STATIC is used when the device is not + * configured for an HT channel */ struct ieee80211_conf { u32 flags; @@ -636,11 +672,13 @@ struct ieee80211_conf { int max_sleep_period; u16 listen_interval; + u8 ps_dtim_period; u8 long_frame_max_tx_count, short_frame_max_tx_count; struct ieee80211_channel *channel; enum nl80211_channel_type channel_type; + enum ieee80211_smps_mode smps_mode; }; /** @@ -652,12 +690,14 @@ struct ieee80211_conf { * @type: type of this virtual interface * @bss_conf: BSS configuration for this interface, either our own * or the BSS we're associated to + * @addr: address of this interface * @drv_priv: data area for driver use, will always be aligned to * sizeof(void *). */ struct ieee80211_vif { enum nl80211_iftype type; struct ieee80211_bss_conf bss_conf; + u8 addr[ETH_ALEN]; /* must be last */ u8 drv_priv[0] __attribute__((__aligned__(sizeof(void *)))); }; @@ -671,33 +711,6 @@ static inline bool ieee80211_vif_is_mesh(struct ieee80211_vif *vif) } /** - * struct ieee80211_if_init_conf - initial configuration of an interface - * - * @vif: pointer to a driver-use per-interface structure. The pointer - * itself is also used for various functions including - * ieee80211_beacon_get() and ieee80211_get_buffered_bc(). - * @type: one of &enum nl80211_iftype constants. Determines the type of - * added/removed interface. - * @mac_addr: pointer to MAC address of the interface. This pointer is valid - * until the interface is removed (i.e. it cannot be used after - * remove_interface() callback was called for this interface). - * - * This structure is used in add_interface() and remove_interface() - * callbacks of &struct ieee80211_hw. - * - * When you allow multiple interfaces to be added to your PHY, take care - * that the hardware can actually handle multiple MAC addresses. However, - * also take care that when there's no interface left with mac_addr != %NULL - * you remove the MAC address from the device to avoid acknowledging packets - * in pure monitor mode. - */ -struct ieee80211_if_init_conf { - enum nl80211_iftype type; - struct ieee80211_vif *vif; - void *mac_addr; -}; - -/** * enum ieee80211_key_alg - key algorithm * @ALG_WEP: WEP40 or WEP104 * @ALG_TKIP: TKIP @@ -792,7 +805,7 @@ enum set_key_cmd { * mac80211, any ieee80211_sta pointer you get access to must * either be protected by rcu_read_lock() explicitly or implicitly, * or you must take good care to not use such a pointer after a - * call to your sta_notify callback that removed it. + * call to your sta_remove callback that removed it. * * @addr: MAC address * @aid: AID we assigned to the station if we're an AP @@ -818,8 +831,8 @@ struct ieee80211_sta { * indicates addition and removal of a station to station table, * or if a associated station made a power state transition. * - * @STA_NOTIFY_ADD: a station was added to the station table - * @STA_NOTIFY_REMOVE: a station being removed from the station table + * @STA_NOTIFY_ADD: (DEPRECATED) a station was added to the station table + * @STA_NOTIFY_REMOVE: (DEPRECATED) a station being removed from the station table * @STA_NOTIFY_SLEEP: a station is now sleeping * @STA_NOTIFY_AWAKE: a sleeping station woke up */ @@ -852,6 +865,19 @@ enum ieee80211_tkip_key_type { * any particular flags. There are some exceptions to this rule, * however, so you are advised to review these flags carefully. * + * @IEEE80211_HW_HAS_RATE_CONTROL: + * The hardware or firmware includes rate control, and cannot be + * controlled by the stack. As such, no rate control algorithm + * should be instantiated, and the TX rate reported to userspace + * will be taken from the TX status instead of the rate control + * algorithm. + * Note that this requires that the driver implement a number of + * callbacks so it has the correct information, it needs to have + * the @set_rts_threshold callback and must look at the BSS config + * @use_cts_prot for G/N protection, @use_short_slot for slot + * timing in 2.4 GHz and @use_short_preamble for preambles for + * CCK frames. + * * @IEEE80211_HW_RX_INCLUDES_FCS: * Indicates that received frames passed to the stack include * the FCS at the end. @@ -908,8 +934,29 @@ enum ieee80211_tkip_key_type { * @IEEE80211_HW_BEACON_FILTER: * Hardware supports dropping of irrelevant beacon frames to * avoid waking up cpu. + * + * @IEEE80211_HW_SUPPORTS_STATIC_SMPS: + * Hardware supports static spatial multiplexing powersave, + * ie. can turn off all but one chain even on HT connections + * that should be using more chains. + * + * @IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS: + * Hardware supports dynamic spatial multiplexing powersave, + * ie. can turn off all but one chain and then wake the rest + * up as required after, for example, rts/cts handshake. + * + * @IEEE80211_HW_SUPPORTS_UAPSD: + * Hardware supports Unscheduled Automatic Power Save Delivery + * (U-APSD) in managed mode. The mode is configured with + * conf_tx() operation. + * + * @IEEE80211_HW_REPORTS_TX_ACK_STATUS: + * Hardware can provide ack status reports of Tx frames to + * the stack. + * */ enum ieee80211_hw_flags { + IEEE80211_HW_HAS_RATE_CONTROL = 1<<0, IEEE80211_HW_RX_INCLUDES_FCS = 1<<1, IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING = 1<<2, IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE = 1<<3, @@ -924,6 +971,10 @@ enum ieee80211_hw_flags { IEEE80211_HW_SUPPORTS_DYNAMIC_PS = 1<<12, IEEE80211_HW_MFP_CAPABLE = 1<<13, IEEE80211_HW_BEACON_FILTER = 1<<14, + IEEE80211_HW_SUPPORTS_STATIC_SMPS = 1<<15, + IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS = 1<<16, + IEEE80211_HW_SUPPORTS_UAPSD = 1<<17, + IEEE80211_HW_REPORTS_TX_ACK_STATUS = 1<<18, }; /** @@ -1102,18 +1153,24 @@ ieee80211_get_alt_retry_rate(const struct ieee80211_hw *hw, * * mac80211 has support for various powersave implementations. * - * First, it can support hardware that handles all powersaving by - * itself, such hardware should simply set the %IEEE80211_HW_SUPPORTS_PS - * hardware flag. In that case, it will be told about the desired - * powersave mode depending on the association status, and the driver - * must take care of sending nullfunc frames when necessary, i.e. when - * entering and leaving powersave mode. The driver is required to look at - * the AID in beacons and signal to the AP that it woke up when it finds - * traffic directed to it. This mode supports dynamic PS by simply - * enabling/disabling PS. - * - * Additionally, such hardware may set the %IEEE80211_HW_SUPPORTS_DYNAMIC_PS - * flag to indicate that it can support dynamic PS mode itself (see below). + * First, it can support hardware that handles all powersaving by itself, + * such hardware should simply set the %IEEE80211_HW_SUPPORTS_PS hardware + * flag. In that case, it will be told about the desired powersave mode + * with the %IEEE80211_CONF_PS flag depending on the association status. + * The hardware must take care of sending nullfunc frames when necessary, + * i.e. when entering and leaving powersave mode. The hardware is required + * to look at the AID in beacons and signal to the AP that it woke up when + * it finds traffic directed to it. + * + * %IEEE80211_CONF_PS flag enabled means that the powersave mode defined in + * IEEE 802.11-2007 section 11.2 is enabled. This is not to be confused + * with hardware wakeup and sleep states. Driver is responsible for waking + * up the hardware before issueing commands to the hardware and putting it + * back to sleep at approriate times. + * + * When PS is enabled, hardware needs to wakeup for beacons and receive the + * buffered multicast/broadcast frames after the beacon. Also it must be + * possible to send frames and receive the acknowledment frame. * * Other hardware designs cannot send nullfunc frames by themselves and also * need software support for parsing the TIM bitmap. This is also supported @@ -1121,14 +1178,35 @@ ieee80211_get_alt_retry_rate(const struct ieee80211_hw *hw, * %IEEE80211_HW_PS_NULLFUNC_STACK flags. The hardware is of course still * required to pass up beacons. The hardware is still required to handle * waking up for multicast traffic; if it cannot the driver must handle that - * as best as it can, mac80211 is too slow. - * - * Dynamic powersave mode is an extension to normal powersave mode in which - * the hardware stays awake for a user-specified period of time after sending - * a frame so that reply frames need not be buffered and therefore delayed - * to the next wakeup. This can either be supported by hardware, in which case - * the driver needs to look at the @dynamic_ps_timeout hardware configuration - * value, or by the stack if all nullfunc handling is in the stack. + * as best as it can, mac80211 is too slow to do that. + * + * Dynamic powersave is an extension to normal powersave in which the + * hardware stays awake for a user-specified period of time after sending a + * frame so that reply frames need not be buffered and therefore delayed to + * the next wakeup. It's compromise of getting good enough latency when + * there's data traffic and still saving significantly power in idle + * periods. + * + * Dynamic powersave is supported by simply mac80211 enabling and disabling + * PS based on traffic. Driver needs to only set %IEEE80211_HW_SUPPORTS_PS + * flag and mac80211 will handle everything automatically. Additionally, + * hardware having support for the dynamic PS feature may set the + * %IEEE80211_HW_SUPPORTS_DYNAMIC_PS flag to indicate that it can support + * dynamic PS mode itself. The driver needs to look at the + * @dynamic_ps_timeout hardware configuration value and use it that value + * whenever %IEEE80211_CONF_PS is set. In this case mac80211 will disable + * dynamic PS feature in stack and will just keep %IEEE80211_CONF_PS + * enabled whenever user has enabled 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 + * Nullfunc frames and stay awake until the service period has ended. To + * utilize U-APSD, dynamic powersave is disabled for voip AC and all frames + * from that AC are transmitted with powersave enabled. + * + * Note: U-APSD client mode is not yet supported with + * %IEEE80211_HW_PS_NULLFUNC_STACK. */ /** @@ -1192,6 +1270,31 @@ ieee80211_get_alt_retry_rate(const struct ieee80211_hw *hw, */ /** + * DOC: Spatial multiplexing power save + * + * SMPS (Spatial multiplexing power save) is a mechanism to conserve + * power in an 802.11n implementation. For details on the mechanism + * and rationale, please refer to 802.11 (as amended by 802.11n-2009) + * "11.2.3 SM power save". + * + * The mac80211 implementation is capable of sending action frames + * to update the AP about the station's SMPS mode, and will instruct + * the driver to enter the specific mode. It will also announce the + * requested SMPS mode during the association handshake. Hardware + * support for this feature is required, and can be indicated by + * hardware flags. + * + * The default mode will be "automatic", which nl80211/cfg80211 + * defines to be dynamic SMPS in (regular) powersave, and SMPS + * turned off otherwise. + * + * To support this feature, the driver must set the appropriate + * hardware support flags, and handle the SMPS flag to the config() + * operation. It will then with this mechanism be instructed to + * enter the requested SMPS mode while associated to an HT AP. + */ + +/** * DOC: Frame filtering * * mac80211 requires to see many management frames for proper @@ -1283,6 +1386,12 @@ enum ieee80211_filter_flags { * * These flags are used with the ampdu_action() callback in * &struct ieee80211_ops to indicate which action is needed. + * + * Note that drivers MUST be able to deal with a TX aggregation + * session being stopped even before they OK'ed starting it by + * 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 @@ -1322,7 +1431,7 @@ enum ieee80211_ampdu_mlme_action { * When the device is started it should not have a MAC address * to avoid acknowledging frames before a non-monitor device * is added. - * Must be implemented. + * Must be implemented and can sleep. * * @stop: Called after last netdevice attached to the hardware * is disabled. This should turn off the hardware (at least @@ -1330,7 +1439,7 @@ enum ieee80211_ampdu_mlme_action { * May be called right after add_interface if that rejects * an interface. If you added any work onto the mac80211 workqueue * you should ensure to cancel it on this callback. - * Must be implemented. + * Must be implemented and can sleep. * * @add_interface: Called when a netdevice attached to the hardware is * enabled. Because it is not called for monitor mode devices, @start @@ -1340,7 +1449,7 @@ enum ieee80211_ampdu_mlme_action { * interface is given in the conf parameter. * The callback may refuse to add an interface by returning a * negative error code (which will be seen in userspace.) - * Must be implemented. + * Must be implemented and can sleep. * * @remove_interface: Notifies a driver that an interface is going down. * The @stop callback is called after this if it is the last interface @@ -1349,19 +1458,20 @@ enum ieee80211_ampdu_mlme_action { * must be cleared so the device no longer acknowledges packets, * the mac_addr member of the conf structure is, however, set to the * MAC address of the device going away. - * Hence, this callback must be implemented. + * Hence, this callback must be implemented. It 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 - * if it does. + * if it does. The callback can sleep. * * @bss_info_changed: Handler for configuration requests related to BSS * parameters that may vary during BSS's lifespan, and may affect low * level driver (e.g. assoc/disassoc status, erp parameters). * This function should not be used if no BSS has been set, unless * for association indication. The @changed parameter indicates which - * of the bss parameters has changed when a call is made. + * of the bss parameters has changed when a call is made. The callback + * can sleep. * * @prepare_multicast: Prepare for multicast filter configuration. * This callback is optional, and its return value is passed @@ -1369,20 +1479,22 @@ enum ieee80211_ampdu_mlme_action { * * @configure_filter: Configure the device's RX filter. * See the section "Frame filtering" for more information. - * This callback must be implemented. + * This callback must be implemented and can sleep. * * @set_tim: Set TIM bit. mac80211 calls this function when a TIM bit * must be set or cleared for a given STA. Must be atomic. * * @set_key: See the section "Hardware crypto acceleration" - * This callback can sleep, and is only called between add_interface - * and remove_interface calls, i.e. while the given virtual interface + * This callback is only called between add_interface and + * remove_interface calls, i.e. while the given virtual interface * is enabled. * Returns a negative error code if the key can't be added. + * The callback can sleep. * * @update_tkip_key: See the section "Hardware crypto acceleration" * This callback will be called in the context of Rx. Called for drivers * which set IEEE80211_KEY_FLAG_TKIP_REQ_RX_P1_KEY. + * The callback must be atomic. * * @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 @@ -1396,53 +1508,64 @@ enum ieee80211_ampdu_mlme_action { * When the scan finishes, ieee80211_scan_completed() must be called; * note that it also must be called when the scan cannot finish due to * any error unless this callback returned a negative error code. + * The callback can sleep. * * @sw_scan_start: Notifier function that is called just before a software scan * is started. Can be NULL, if the driver doesn't need this notification. + * The callback can sleep. * - * @sw_scan_complete: Notifier function that is called just after a software scan - * finished. Can be NULL, if the driver doesn't need this notification. + * @sw_scan_complete: Notifier function that is called just after a + * software scan finished. Can be NULL, if the driver doesn't need + * this notification. + * The callback can sleep. * * @get_stats: Return low-level statistics. * Returns zero if statistics are available. + * The callback can sleep. * * @get_tkip_seq: If your device implements TKIP encryption in hardware this * callback should be provided to read the TKIP transmit IVs (both IV32 * and IV16) for the given key from hardware. + * The callback must be atomic. * * @set_rts_threshold: Configuration of RTS threshold (if device needs it) + * The callback can sleep. + * + * @sta_add: Notifies low level driver about addition of an associated station, + * AP, IBSS/WDS/mesh peer etc. This callback can sleep. + * + * @sta_remove: Notifies low level driver about removal of an associated + * station, AP, IBSS/WDS/mesh peer etc. This callback can sleep. * - * @sta_notify: Notifies low level driver about addition, removal or power - * state transition of an associated station, AP, IBSS/WDS/mesh peer etc. - * Must be atomic. + * @sta_notify: Notifies low level driver about power state transition of an + * associated station, AP, IBSS/WDS/mesh peer etc. Must be atomic. * * @conf_tx: Configure TX queue parameters (EDCF (aifs, cw_min, cw_max), * bursting) for a hardware TX queue. * Returns a negative error code on failure. - * - * @get_tx_stats: Get statistics of the current TX queue status. This is used - * to get number of currently queued packets (queue length), maximum queue - * size (limit), and total number of packets sent using each TX queue - * (count). The 'stats' pointer points to an array that has hw->queues - * items. + * The callback can sleep. * * @get_tsf: Get the current TSF timer value from firmware/hardware. Currently, * this is only used for IBSS mode BSSID merging and debugging. Is not a * required function. + * The callback can sleep. * * @set_tsf: Set the TSF timer to the specified value in the firmware/hardware. * Currently, this is only used for IBSS mode debugging. Is not a * required function. + * The callback can sleep. * * @reset_tsf: Reset the TSF timer and allow firmware/hardware to synchronize * with other STAs in the IBSS. This is only used in IBSS mode. This * function is optional if the firmware/hardware takes full care of * TSF synchronization. + * The callback can sleep. * * @tx_last_beacon: Determine whether the last IBSS beacon was sent by us. * This is needed only for IBSS mode and the result of this function is * used to determine whether to reply to Probe Requests. * Returns non-zero if this device sent the last beacon. + * The callback can sleep. * * @ampdu_action: Perform a certain A-MPDU action * The RA/TID combination determines the destination and TID we want @@ -1451,21 +1574,32 @@ enum ieee80211_ampdu_mlme_action { * is the first frame we expect to perform the action on. Notice * that TX/RX_STOP can pass NULL for this parameter. * Returns a negative error code on failure. + * The callback must be atomic. * * @rfkill_poll: Poll rfkill hardware state. If you need this, you also * need to set wiphy->rfkill_poll to %true before registration, * and need to call wiphy_rfkill_set_hw_state() in the callback. + * The callback can sleep. + * + * @set_coverage_class: Set slot time for given coverage class as specified + * in IEEE 802.11-2007 section 17.3.8.6 and modify ACK timeout + * accordingly. This callback is not required and may sleep. * * @testmode_cmd: Implement a cfg80211 test mode command. + * The callback can sleep. + * + * @flush: Flush all pending frames from the hardware queue, making sure + * that the hardware queues are empty. If the parameter @drop is set + * to %true, pending frames may be dropped. The callback can sleep. */ struct ieee80211_ops { int (*tx)(struct ieee80211_hw *hw, struct sk_buff *skb); int (*start)(struct ieee80211_hw *hw); void (*stop)(struct ieee80211_hw *hw); int (*add_interface)(struct ieee80211_hw *hw, - struct ieee80211_if_init_conf *conf); + struct ieee80211_vif *vif); void (*remove_interface)(struct ieee80211_hw *hw, - struct ieee80211_if_init_conf *conf); + struct ieee80211_vif *vif); int (*config)(struct ieee80211_hw *hw, u32 changed); void (*bss_info_changed)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, @@ -1483,8 +1617,10 @@ struct ieee80211_ops { struct ieee80211_vif *vif, struct ieee80211_sta *sta, struct ieee80211_key_conf *key); void (*update_tkip_key)(struct ieee80211_hw *hw, - struct ieee80211_key_conf *conf, const u8 *address, - u32 iv32, u16 *phase1key); + struct ieee80211_vif *vif, + struct ieee80211_key_conf *conf, + struct ieee80211_sta *sta, + u32 iv32, u16 *phase1key); int (*hw_scan)(struct ieee80211_hw *hw, struct cfg80211_scan_request *req); void (*sw_scan_start)(struct ieee80211_hw *hw); @@ -1494,24 +1630,29 @@ struct ieee80211_ops { void (*get_tkip_seq)(struct ieee80211_hw *hw, u8 hw_key_idx, u32 *iv32, u16 *iv16); int (*set_rts_threshold)(struct ieee80211_hw *hw, u32 value); + int (*sta_add)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_sta *sta); + int (*sta_remove)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_sta *sta); void (*sta_notify)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, enum sta_notify_cmd, struct ieee80211_sta *sta); int (*conf_tx)(struct ieee80211_hw *hw, u16 queue, const struct ieee80211_tx_queue_params *params); - int (*get_tx_stats)(struct ieee80211_hw *hw, - struct ieee80211_tx_queue_stats *stats); u64 (*get_tsf)(struct ieee80211_hw *hw); void (*set_tsf)(struct ieee80211_hw *hw, u64 tsf); void (*reset_tsf)(struct ieee80211_hw *hw); int (*tx_last_beacon)(struct ieee80211_hw *hw); int (*ampdu_action)(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, enum ieee80211_ampdu_mlme_action action, struct ieee80211_sta *sta, u16 tid, u16 *ssn); void (*rfkill_poll)(struct ieee80211_hw *hw); + void (*set_coverage_class)(struct ieee80211_hw *hw, u8 coverage_class); #ifdef CONFIG_NL80211_TESTMODE int (*testmode_cmd)(struct ieee80211_hw *hw, void *data, int len); #endif + void (*flush)(struct ieee80211_hw *hw, bool drop); }; /** @@ -1661,13 +1802,14 @@ void ieee80211_restart_hw(struct ieee80211_hw *hw); * ieee80211_rx - receive frame * * Use this function to hand received frames to mac80211. The receive - * buffer in @skb must start with an IEEE 802.11 header or a radiotap - * header if %RX_FLAG_RADIOTAP is set in the @status flags. + * buffer in @skb must start with an IEEE 802.11 header. * * This function may not be called in IRQ context. Calls to this function - * for a single hardware must be synchronized against each other. Calls - * to this function and ieee80211_rx_irqsafe() may not be mixed for a - * single hardware. + * for a single hardware must be synchronized against each other. Calls to + * this function, ieee80211_rx_ni() and ieee80211_rx_irqsafe() may not be + * mixed for a single hardware. + * + * In process context use instead ieee80211_rx_ni(). * * @hw: the hardware this frame came in on * @skb: the buffer to receive, owned by mac80211 after this call @@ -1680,8 +1822,8 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb); * Like ieee80211_rx() but can be called in IRQ context * (internally defers to a tasklet.) * - * Calls to this function and ieee80211_rx() may not be mixed for a - * single hardware. + * Calls to this function, ieee80211_rx() or ieee80211_rx_ni() may not + * be mixed for a single hardware. * * @hw: the hardware this frame came in on * @skb: the buffer to receive, owned by mac80211 after this call @@ -1689,6 +1831,32 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb); void ieee80211_rx_irqsafe(struct ieee80211_hw *hw, struct sk_buff *skb); /** + * ieee80211_rx_ni - receive frame (in process context) + * + * Like ieee80211_rx() but can be called in process context + * (internally disables bottom halves). + * + * Calls to this function, ieee80211_rx() and ieee80211_rx_irqsafe() may + * not be mixed for a single hardware. + * + * @hw: the hardware this frame came in on + * @skb: the buffer to receive, owned by mac80211 after this call + */ +static inline void ieee80211_rx_ni(struct ieee80211_hw *hw, + struct sk_buff *skb) +{ + local_bh_disable(); + ieee80211_rx(hw, skb); + local_bh_enable(); +} + +/* + * The TX headroom reserved by mac80211 for its own tx_status functions. + * This is enough for the radiotap header. + */ +#define IEEE80211_TX_STATUS_HEADROOM 13 + +/** * ieee80211_tx_status - transmit status callback * * Call this function for all transmitted frames after they have been @@ -1722,24 +1890,97 @@ void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw, struct sk_buff *skb); /** - * ieee80211_beacon_get - beacon generation function + * ieee80211_beacon_get_tim - beacon generation function * @hw: pointer obtained from ieee80211_alloc_hw(). - * @vif: &struct ieee80211_vif pointer from &struct ieee80211_if_init_conf. + * @vif: &struct ieee80211_vif pointer from the add_interface callback. + * @tim_offset: pointer to variable that will receive the TIM IE offset. + * Set to 0 if invalid (in non-AP modes). + * @tim_length: pointer to variable that will receive the TIM IE length, + * (including the ID and length bytes!). + * Set to 0 if invalid (in non-AP modes). + * + * If the driver implements beaconing modes, it must use this function to + * obtain the beacon frame/template. * * If the beacon frames are generated by the host system (i.e., not in - * hardware/firmware), the low-level driver uses this function to receive - * the next beacon frame from the 802.11 code. The low-level is responsible - * for calling this function before beacon data is needed (e.g., based on - * hardware interrupt). Returned skb is used only once and low-level driver - * is responsible for freeing it. + * hardware/firmware), the driver uses this function to get each beacon + * frame from mac80211 -- it is responsible for calling this function + * before the beacon is needed (e.g. based on hardware interrupt). + * + * If the beacon frames are generated by the device, then the driver + * must use the returned beacon as the template and change the TIM IE + * according to the current DTIM parameters/TIM bitmap. + * + * The driver is responsible for freeing the returned skb. */ -struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, +struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + u16 *tim_offset, u16 *tim_length); + +/** + * ieee80211_beacon_get - beacon generation function + * @hw: pointer obtained from ieee80211_alloc_hw(). + * @vif: &struct ieee80211_vif pointer from the add_interface callback. + * + * See ieee80211_beacon_get_tim(). + */ +static inline struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + return ieee80211_beacon_get_tim(hw, vif, NULL, NULL); +} + +/** + * ieee80211_pspoll_get - retrieve a PS Poll template + * @hw: pointer obtained from ieee80211_alloc_hw(). + * @vif: &struct ieee80211_vif pointer from the add_interface callback. + * + * Creates a PS Poll a template which can, for example, uploaded to + * hardware. The template must be updated after association so that correct + * AID, BSSID and MAC address is used. + * + * Note: Caller (or hardware) is responsible for setting the + * &IEEE80211_FCTL_PM bit. + */ +struct sk_buff *ieee80211_pspoll_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif); /** + * ieee80211_nullfunc_get - retrieve a nullfunc template + * @hw: pointer obtained from ieee80211_alloc_hw(). + * @vif: &struct ieee80211_vif pointer from the add_interface callback. + * + * Creates a Nullfunc template which can, for example, uploaded to + * hardware. The template must be updated after association so that correct + * BSSID and address is used. + * + * Note: Caller (or hardware) is responsible for setting the + * &IEEE80211_FCTL_PM bit as well as Duration and Sequence Control fields. + */ +struct sk_buff *ieee80211_nullfunc_get(struct ieee80211_hw *hw, + struct ieee80211_vif *vif); + +/** + * ieee80211_probereq_get - retrieve a Probe Request template + * @hw: pointer obtained from ieee80211_alloc_hw(). + * @vif: &struct ieee80211_vif pointer from the add_interface callback. + * @ssid: SSID buffer + * @ssid_len: length of SSID + * @ie: buffer containing all IEs except SSID for the template + * @ie_len: length of the IE buffer + * + * Creates a Probe Request template which can, for example, be uploaded to + * hardware. + */ +struct sk_buff *ieee80211_probereq_get(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + const u8 *ssid, size_t ssid_len, + const u8 *ie, size_t ie_len); + +/** * ieee80211_rts_get - RTS frame generation function * @hw: pointer obtained from ieee80211_alloc_hw(). - * @vif: &struct ieee80211_vif pointer from &struct ieee80211_if_init_conf. + * @vif: &struct ieee80211_vif pointer from the add_interface callback. * @frame: pointer to the frame that is going to be protected by the RTS. * @frame_len: the frame length (in octets). * @frame_txctl: &struct ieee80211_tx_info of the frame. @@ -1758,7 +1999,7 @@ void ieee80211_rts_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif, /** * ieee80211_rts_duration - Get the duration field for an RTS frame * @hw: pointer obtained from ieee80211_alloc_hw(). - * @vif: &struct ieee80211_vif pointer from &struct ieee80211_if_init_conf. + * @vif: &struct ieee80211_vif pointer from the add_interface callback. * @frame_len: the length of the frame that is going to be protected by the RTS. * @frame_txctl: &struct ieee80211_tx_info of the frame. * @@ -1773,7 +2014,7 @@ __le16 ieee80211_rts_duration(struct ieee80211_hw *hw, /** * ieee80211_ctstoself_get - CTS-to-self frame generation function * @hw: pointer obtained from ieee80211_alloc_hw(). - * @vif: &struct ieee80211_vif pointer from &struct ieee80211_if_init_conf. + * @vif: &struct ieee80211_vif pointer from the add_interface callback. * @frame: pointer to the frame that is going to be protected by the CTS-to-self. * @frame_len: the frame length (in octets). * @frame_txctl: &struct ieee80211_tx_info of the frame. @@ -1793,7 +2034,7 @@ void ieee80211_ctstoself_get(struct ieee80211_hw *hw, /** * ieee80211_ctstoself_duration - Get the duration field for a CTS-to-self frame * @hw: pointer obtained from ieee80211_alloc_hw(). - * @vif: &struct ieee80211_vif pointer from &struct ieee80211_if_init_conf. + * @vif: &struct ieee80211_vif pointer from the add_interface callback. * @frame_len: the length of the frame that is going to be protected by the CTS-to-self. * @frame_txctl: &struct ieee80211_tx_info of the frame. * @@ -1809,7 +2050,7 @@ __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw, /** * ieee80211_generic_frame_duration - Calculate the duration field for a frame * @hw: pointer obtained from ieee80211_alloc_hw(). - * @vif: &struct ieee80211_vif pointer from &struct ieee80211_if_init_conf. + * @vif: &struct ieee80211_vif pointer from the add_interface callback. * @frame_len: the length of the frame. * @rate: the rate at which the frame is going to be transmitted. * @@ -1824,7 +2065,7 @@ __le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw, /** * ieee80211_get_buffered_bc - accessing buffered broadcast and multicast frames * @hw: pointer as obtained from ieee80211_alloc_hw(). - * @vif: &struct ieee80211_vif pointer from &struct ieee80211_if_init_conf. + * @vif: &struct ieee80211_vif pointer from the add_interface callback. * * Function for accessing buffered broadcast and multicast frames. If * hardware/firmware does not implement buffering of broadcast/multicast @@ -1979,8 +2220,7 @@ void ieee80211_queue_delayed_work(struct ieee80211_hw *hw, /** * ieee80211_start_tx_ba_session - Start a tx Block Ack session. - * @hw: pointer as obtained from ieee80211_alloc_hw(). - * @ra: receiver address of the BA session recipient + * @sta: the station for which to start a BA session * @tid: the TID to BA on. * * Return: success if addBA request was sent, failure otherwise @@ -1989,22 +2229,22 @@ void ieee80211_queue_delayed_work(struct ieee80211_hw *hw, * the need to start aggregation on a certain RA/TID, the session level * will be managed by the mac80211. */ -int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid); +int ieee80211_start_tx_ba_session(struct ieee80211_sta *sta, u16 tid); /** * ieee80211_start_tx_ba_cb - low level driver ready to aggregate. - * @hw: pointer as obtained from ieee80211_alloc_hw(). + * @vif: &struct ieee80211_vif pointer from the add_interface callback * @ra: receiver address of the BA session recipient. * @tid: the TID to BA on. * * This function must be called by low level driver once it has * finished with preparations for the BA session. */ -void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid); +void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid); /** * ieee80211_start_tx_ba_cb_irqsafe - low level driver ready to aggregate. - * @hw: pointer as obtained from ieee80211_alloc_hw(). + * @vif: &struct ieee80211_vif pointer from the add_interface callback * @ra: receiver address of the BA session recipient. * @tid: the TID to BA on. * @@ -2012,13 +2252,12 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid); * finished with preparations for the BA session. * This version of the function is IRQ-safe. */ -void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, const u8 *ra, +void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_vif *vif, const u8 *ra, u16 tid); /** * ieee80211_stop_tx_ba_session - Stop a Block Ack session. - * @hw: pointer as obtained from ieee80211_alloc_hw(). - * @ra: receiver address of the BA session recipient + * @sta: the station whose BA session to stop * @tid: the TID to stop BA. * @initiator: if indicates initiator DELBA frame will be sent. * @@ -2028,24 +2267,23 @@ void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, const u8 *ra, * the need to stop aggregation on a certain RA/TID, the session level * will be managed by the mac80211. */ -int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw, - u8 *ra, u16 tid, +int ieee80211_stop_tx_ba_session(struct ieee80211_sta *sta, u16 tid, enum ieee80211_back_parties initiator); /** * ieee80211_stop_tx_ba_cb - low level driver ready to stop aggregate. - * @hw: pointer as obtained from ieee80211_alloc_hw(). + * @vif: &struct ieee80211_vif pointer from the add_interface callback * @ra: receiver address of the BA session recipient. * @tid: the desired TID to BA on. * * This function must be called by low level driver once it has * finished with preparations for the BA session tear down. */ -void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid); +void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid); /** * ieee80211_stop_tx_ba_cb_irqsafe - low level driver ready to stop aggregate. - * @hw: pointer as obtained from ieee80211_alloc_hw(). + * @vif: &struct ieee80211_vif pointer from the add_interface callback * @ra: receiver address of the BA session recipient. * @tid: the desired TID to BA on. * @@ -2053,25 +2291,78 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid); * finished with preparations for the BA session tear down. * This version of the function is IRQ-safe. */ -void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, const u8 *ra, +void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_vif *vif, const u8 *ra, u16 tid); /** * ieee80211_find_sta - find a station * - * @hw: pointer as obtained from ieee80211_alloc_hw() + * @vif: virtual interface to look for station on * @addr: station's address * * 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_hw *hw, +struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_vif *vif, const u8 *addr); /** + * ieee80211_find_sta_by_hw - find a station on hardware + * + * @hw: pointer as obtained from ieee80211_alloc_hw() + * @addr: station's address + * + * This function must be called under RCU lock and the + * resulting pointer is only valid under RCU lock as well. + * + * NOTE: This function should not be used! When mac80211 is converted + * internally to properly keep track of stations on multiple + * virtual interfaces, it will not always know which station to + * return here since a single address might be used by multiple + * logical stations (e.g. consider a station connecting to another + * BSSID on the same AP hardware without disconnecting first). + * + * DO NOT USE THIS FUNCTION. + */ +struct ieee80211_sta *ieee80211_find_sta_by_hw(struct ieee80211_hw *hw, + const u8 *addr); + +/** + * ieee80211_sta_block_awake - block station from waking up + * @hw: the hardware + * @pubsta: the station + * @block: whether to block or unblock + * + * Some devices require that all frames that are on the queues + * for a specific station that went to sleep are flushed before + * a poll response or frames after the station woke up can be + * delivered to that it. Note that such frames must be rejected + * by the driver as filtered, with the appropriate status flag. + * + * This function allows implementing this mode in a race-free + * manner. + * + * To do this, a driver must keep track of the number of frames + * still enqueued for a specific station. If this number is not + * zero when the station goes to sleep, the driver must call + * this function to force mac80211 to consider the station to + * be asleep regardless of the station's actual state. Once the + * number of outstanding frames reaches zero, the driver must + * call this function again to unblock the station. That will + * cause mac80211 to be able to send ps-poll responses, and if + * the station queried in the meantime then frames will also + * be sent out as a result of this. Additionally, the driver + * will be notified that the station woke up some time after + * it is unblocked, regardless of whether the station actually + * woke up while blocked or not. + */ +void ieee80211_sta_block_awake(struct ieee80211_hw *hw, + struct ieee80211_sta *pubsta, bool block); + +/** * ieee80211_beacon_loss - inform hardware does not receive beacons * - * @vif: &struct ieee80211_vif pointer from &struct ieee80211_if_init_conf. + * @vif: &struct ieee80211_vif pointer from the add_interface callback. * * When beacon filtering is enabled with IEEE80211_HW_BEACON_FILTERING and * IEEE80211_CONF_PS is set, the driver needs to inform whenever the @@ -2105,8 +2396,12 @@ enum rate_control_changed { * @short_preamble: whether mac80211 will request short-preamble transmission * if the selected rate supports it * @max_rate_idx: user-requested maximum rate (not MCS for now) + * (deprecated; this will be removed once drivers get updated to use + * rate_idx_mask) + * @rate_idx_mask: user-requested rate mask (not MCS for now) * @skb: the skb that will be transmitted, the control information in it needs * to be filled in + * @ap: whether this frame is sent out in AP mode */ struct ieee80211_tx_rate_control { struct ieee80211_hw *hw; @@ -2116,6 +2411,8 @@ struct ieee80211_tx_rate_control { struct ieee80211_tx_rate reported_rate; bool rts, short_preamble; u8 max_rate_idx; + u32 rate_idx_mask; + bool ap; }; struct rate_control_ops { @@ -2129,7 +2426,8 @@ struct rate_control_ops { struct ieee80211_sta *sta, void *priv_sta); void (*rate_update)(void *priv, struct ieee80211_supported_band *sband, struct ieee80211_sta *sta, - void *priv_sta, u32 changed); + void *priv_sta, u32 changed, + enum nl80211_channel_type oper_chan_type); void (*free_sta)(void *priv, struct ieee80211_sta *sta, void *priv_sta); diff --git a/include/net/neighbour.h b/include/net/neighbour.h index 3817fda82a80..da1d58be31b7 100644 --- a/include/net/neighbour.h +++ b/include/net/neighbour.h @@ -37,8 +37,7 @@ struct neighbour; -struct neigh_parms -{ +struct neigh_parms { #ifdef CONFIG_NET_NS struct net *net; #endif @@ -70,8 +69,7 @@ struct neigh_parms int locktime; }; -struct neigh_statistics -{ +struct neigh_statistics { unsigned long allocs; /* number of allocated neighs */ unsigned long destroys; /* number of destroyed neighs */ unsigned long hash_grows; /* number of hash resizes */ @@ -90,15 +88,9 @@ struct neigh_statistics unsigned long unres_discards; /* number of unresolved drops */ }; -#define NEIGH_CACHE_STAT_INC(tbl, field) \ - do { \ - preempt_disable(); \ - (per_cpu_ptr((tbl)->stats, smp_processor_id())->field)++; \ - preempt_enable(); \ - } while (0) +#define NEIGH_CACHE_STAT_INC(tbl, field) this_cpu_inc((tbl)->stats->field) -struct neighbour -{ +struct neighbour { struct neighbour *next; struct neigh_table *tbl; struct neigh_parms *parms; @@ -122,8 +114,7 @@ struct neighbour u8 primary_key[0]; }; -struct neigh_ops -{ +struct neigh_ops { int family; void (*solicit)(struct neighbour *, struct sk_buff*); void (*error_report)(struct neighbour *, struct sk_buff*); @@ -133,8 +124,7 @@ struct neigh_ops int (*queue_xmit)(struct sk_buff*); }; -struct pneigh_entry -{ +struct pneigh_entry { struct pneigh_entry *next; #ifdef CONFIG_NET_NS struct net *net; @@ -149,8 +139,7 @@ struct pneigh_entry */ -struct neigh_table -{ +struct neigh_table { struct neigh_table *next; int family; int entry_size; @@ -175,7 +164,7 @@ struct neigh_table rwlock_t lock; unsigned long last_rand; struct kmem_cache *kmem_cachep; - struct neigh_statistics *stats; + struct neigh_statistics __percpu *stats; struct neighbour **hash_buckets; unsigned int hash_mask; __u32 hash_rnd; @@ -262,10 +251,8 @@ extern void neigh_seq_stop(struct seq_file *, void *); extern int neigh_sysctl_register(struct net_device *dev, struct neigh_parms *p, - int p_id, int pdev_id, char *p_name, - proc_handler *proc_handler, - ctl_handler *strategy); + proc_handler *proc_handler); extern void neigh_sysctl_unregister(struct neigh_parms *p); static inline void __neigh_parms_put(struct neigh_parms *parms) diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h index a1202841aadd..bd10a7908993 100644 --- a/include/net/net_namespace.h +++ b/include/net/net_namespace.h @@ -28,6 +28,10 @@ struct ctl_table_header; struct net_generic; struct sock; + +#define NETDEV_HASHBITS 8 +#define NETDEV_HASHENTRIES (1 << NETDEV_HASHBITS) + struct net { atomic_t count; /* To decided when the network * namespace should be freed. @@ -38,7 +42,8 @@ struct net { */ #endif struct list_head list; /* list of network namespaces */ - struct work_struct work; /* work struct for freeing */ + struct list_head cleanup_list; /* namespaces on death row */ + struct list_head exit_list; /* Use only net_mutex */ struct proc_dir_entry *proc_net; struct proc_dir_entry *proc_net_stat; @@ -76,11 +81,13 @@ struct net { #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) struct netns_ct ct; #endif + struct sock *nfnl; + struct sock *nfnl_stash; #endif #ifdef CONFIG_XFRM struct netns_xfrm xfrm; #endif -#ifdef CONFIG_WIRELESS_EXT +#ifdef CONFIG_WEXT_CORE struct sk_buff_head wext_nlevents; #endif struct net_generic *gen; @@ -93,14 +100,9 @@ struct net { extern struct net init_net; #ifdef CONFIG_NET -#define INIT_NET_NS(net_ns) .net_ns = &init_net, - extern struct net *copy_net_ns(unsigned long flags, struct net *net_ns); #else /* CONFIG_NET */ - -#define INIT_NET_NS(net_ns) - static inline struct net *copy_net_ns(unsigned long flags, struct net *net_ns) { /* There is nothing to copy so this is a noop */ @@ -232,6 +234,9 @@ struct pernet_operations { struct list_head list; int (*init)(struct net *net); void (*exit)(struct net *net); + void (*exit_batch)(struct list_head *net_exit_list); + int *id; + size_t size; }; /* @@ -255,12 +260,8 @@ struct pernet_operations { */ extern int register_pernet_subsys(struct pernet_operations *); extern void unregister_pernet_subsys(struct pernet_operations *); -extern int register_pernet_gen_subsys(int *id, struct pernet_operations *); -extern void unregister_pernet_gen_subsys(int id, struct pernet_operations *); extern int register_pernet_device(struct pernet_operations *); extern void unregister_pernet_device(struct pernet_operations *); -extern int register_pernet_gen_device(int *id, struct pernet_operations *); -extern void unregister_pernet_gen_device(int id, struct pernet_operations *); struct ctl_path; struct ctl_table; diff --git a/include/net/netfilter/ipv6/nf_conntrack_ipv6.h b/include/net/netfilter/ipv6/nf_conntrack_ipv6.h index abc55ad75c2b..1ee717eb5b09 100644 --- a/include/net/netfilter/ipv6/nf_conntrack_ipv6.h +++ b/include/net/netfilter/ipv6/nf_conntrack_ipv6.h @@ -9,7 +9,7 @@ extern struct nf_conntrack_l4proto nf_conntrack_l4proto_icmpv6; extern int nf_ct_frag6_init(void); extern void nf_ct_frag6_cleanup(void); -extern struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb); +extern struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb, u32 user); extern void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb, struct net_device *in, struct net_device *out, diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h index cbdd6284996d..bde095f7e845 100644 --- a/include/net/netfilter/nf_conntrack.h +++ b/include/net/netfilter/nf_conntrack.h @@ -70,7 +70,7 @@ union nf_conntrack_help { struct nf_conntrack_helper; /* Must be kept in sync with the classes defined by helpers */ -#define NF_CT_MAX_EXPECT_CLASSES 3 +#define NF_CT_MAX_EXPECT_CLASSES 4 /* nf_conn feature for connections that have a helper */ struct nf_conn_help { @@ -198,7 +198,8 @@ extern void *nf_ct_alloc_hashtable(unsigned int *sizep, int *vmalloced, int null extern void nf_ct_free_hashtable(void *hash, int vmalloced, unsigned int size); extern struct nf_conntrack_tuple_hash * -__nf_conntrack_find(struct net *net, const struct nf_conntrack_tuple *tuple); +__nf_conntrack_find(struct net *net, u16 zone, + const struct nf_conntrack_tuple *tuple); extern void nf_conntrack_hash_insert(struct nf_conn *ct); extern void nf_ct_delete_from_lists(struct nf_conn *ct); @@ -255,11 +256,9 @@ static inline bool nf_ct_kill(struct nf_conn *ct) } /* These are for NAT. Icky. */ -/* Update TCP window tracking data when NAT mangles the packet */ -extern void nf_conntrack_tcp_update(const struct sk_buff *skb, - unsigned int dataoff, - struct nf_conn *ct, int dir, - s16 offset); +extern s16 (*nf_ct_nat_offset)(const struct nf_conn *ct, + enum ip_conntrack_dir dir, + u32 seq); /* Fake conntrack entry for untracked connections */ extern struct nf_conn nf_conntrack_untracked; @@ -269,11 +268,16 @@ extern void nf_ct_iterate_cleanup(struct net *net, int (*iter)(struct nf_conn *i, void *data), void *data); extern void nf_conntrack_free(struct nf_conn *ct); extern struct nf_conn * -nf_conntrack_alloc(struct net *net, +nf_conntrack_alloc(struct net *net, u16 zone, const struct nf_conntrack_tuple *orig, const struct nf_conntrack_tuple *repl, gfp_t gfp); +static inline int nf_ct_is_template(const struct nf_conn *ct) +{ + return test_bit(IPS_TEMPLATE_BIT, &ct->status); +} + /* It's confirmed if it is, or has been in the hash table. */ static inline int nf_ct_is_confirmed(struct nf_conn *ct) { @@ -295,11 +299,11 @@ extern unsigned int nf_conntrack_htable_size; extern unsigned int nf_conntrack_max; #define NF_CT_STAT_INC(net, count) \ - (per_cpu_ptr((net)->ct.stat, raw_smp_processor_id())->count++) + __this_cpu_inc((net)->ct.stat->count) #define NF_CT_STAT_INC_ATOMIC(net, count) \ do { \ local_bh_disable(); \ - per_cpu_ptr((net)->ct.stat, raw_smp_processor_id())->count++; \ + __this_cpu_inc((net)->ct.stat->count); \ local_bh_enable(); \ } while (0) diff --git a/include/net/netfilter/nf_conntrack_core.h b/include/net/netfilter/nf_conntrack_core.h index 5a449b44ba33..dffde8e6920e 100644 --- a/include/net/netfilter/nf_conntrack_core.h +++ b/include/net/netfilter/nf_conntrack_core.h @@ -49,7 +49,8 @@ nf_ct_invert_tuple(struct nf_conntrack_tuple *inverse, /* Find a connection corresponding to a tuple. */ extern struct nf_conntrack_tuple_hash * -nf_conntrack_find_get(struct net *net, const struct nf_conntrack_tuple *tuple); +nf_conntrack_find_get(struct net *net, u16 zone, + const struct nf_conntrack_tuple *tuple); extern int __nf_conntrack_confirm(struct sk_buff *skb); diff --git a/include/net/netfilter/nf_conntrack_ecache.h b/include/net/netfilter/nf_conntrack_ecache.h index 4f20d58e2ab7..96ba5f7dcab6 100644 --- a/include/net/netfilter/nf_conntrack_ecache.h +++ b/include/net/netfilter/nf_conntrack_ecache.h @@ -12,28 +12,12 @@ #include <linux/netfilter/nf_conntrack_tuple_common.h> #include <net/netfilter/nf_conntrack_extend.h> -/* Connection tracking event types */ -enum ip_conntrack_events -{ - IPCT_NEW = 0, /* new conntrack */ - IPCT_RELATED = 1, /* related conntrack */ - IPCT_DESTROY = 2, /* destroyed conntrack */ - IPCT_STATUS = 3, /* status has changed */ - IPCT_PROTOINFO = 4, /* protocol information has changed */ - IPCT_HELPER = 5, /* new helper has been set */ - IPCT_MARK = 6, /* new mark has been set */ - IPCT_NATSEQADJ = 7, /* NAT is doing sequence adjustment */ - IPCT_SECMARK = 8, /* new security mark has been set */ -}; - -enum ip_conntrack_expect_events { - IPEXP_NEW = 0, /* new expectation */ -}; - struct nf_conntrack_ecache { - unsigned long cache; /* bitops want long */ - unsigned long missed; /* missed events */ - u32 pid; /* netlink pid of destroyer */ + unsigned long cache; /* bitops want long */ + unsigned long missed; /* missed events */ + u16 ctmask; /* bitmask of ct events to be delivered */ + u16 expmask; /* bitmask of expect events to be delivered */ + u32 pid; /* netlink pid of destroyer */ }; static inline struct nf_conntrack_ecache * @@ -43,14 +27,24 @@ nf_ct_ecache_find(const struct nf_conn *ct) } static inline struct nf_conntrack_ecache * -nf_ct_ecache_ext_add(struct nf_conn *ct, gfp_t gfp) +nf_ct_ecache_ext_add(struct nf_conn *ct, u16 ctmask, u16 expmask, gfp_t gfp) { struct net *net = nf_ct_net(ct); + struct nf_conntrack_ecache *e; - if (!net->ct.sysctl_events) + if (!ctmask && !expmask && net->ct.sysctl_events) { + ctmask = ~0; + expmask = ~0; + } + if (!ctmask && !expmask) return NULL; - return nf_ct_ext_add(ct, NF_CT_EXT_ECACHE, gfp); + e = nf_ct_ext_add(ct, NF_CT_EXT_ECACHE, gfp); + if (e) { + e->ctmask = ctmask; + e->expmask = expmask; + } + return e; }; #ifdef CONFIG_NF_CONNTRACK_EVENTS @@ -83,6 +77,9 @@ nf_conntrack_event_cache(enum ip_conntrack_events event, struct nf_conn *ct) if (e == NULL) return; + if (!(e->ctmask & (1 << event))) + return; + set_bit(event, &e->cache); } @@ -93,7 +90,6 @@ nf_conntrack_eventmask_report(unsigned int eventmask, int report) { int ret = 0; - struct net *net = nf_ct_net(ct); struct nf_ct_event_notifier *notify; struct nf_conntrack_ecache *e; @@ -102,9 +98,6 @@ nf_conntrack_eventmask_report(unsigned int eventmask, if (notify == NULL) goto out_unlock; - if (!net->ct.sysctl_events) - goto out_unlock; - e = nf_ct_ecache_find(ct); if (e == NULL) goto out_unlock; @@ -118,6 +111,9 @@ nf_conntrack_eventmask_report(unsigned int eventmask, /* This is a resent of a destroy event? If so, skip missed */ unsigned long missed = e->pid ? 0 : e->missed; + if (!((eventmask | missed) & e->ctmask)) + goto out_unlock; + ret = notify->fcn(eventmask | missed, &item); if (unlikely(ret < 0 || missed)) { spin_lock_bh(&ct->lock); @@ -173,18 +169,19 @@ nf_ct_expect_event_report(enum ip_conntrack_expect_events event, u32 pid, int report) { - struct net *net = nf_ct_exp_net(exp); struct nf_exp_event_notifier *notify; + struct nf_conntrack_ecache *e; rcu_read_lock(); notify = rcu_dereference(nf_expect_event_cb); if (notify == NULL) goto out_unlock; - if (!net->ct.sysctl_events) + e = nf_ct_ecache_find(exp->master); + if (e == NULL) goto out_unlock; - { + if (e->expmask & (1 << event)) { struct nf_exp_event item = { .exp = exp, .pid = pid, diff --git a/include/net/netfilter/nf_conntrack_expect.h b/include/net/netfilter/nf_conntrack_expect.h index a9652806d0df..11e815084fcf 100644 --- a/include/net/netfilter/nf_conntrack_expect.h +++ b/include/net/netfilter/nf_conntrack_expect.h @@ -9,8 +9,7 @@ extern unsigned int nf_ct_expect_hsize; extern unsigned int nf_ct_expect_max; -struct nf_conntrack_expect -{ +struct nf_conntrack_expect { /* Conntrack expectation list member */ struct hlist_node lnode; @@ -57,17 +56,13 @@ struct nf_conntrack_expect static inline struct net *nf_ct_exp_net(struct nf_conntrack_expect *exp) { -#ifdef CONFIG_NET_NS - return exp->master->ct_net; /* by definition */ -#else - return &init_net; -#endif + return nf_ct_net(exp->master); } -struct nf_conntrack_expect_policy -{ +struct nf_conntrack_expect_policy { unsigned int max_expected; unsigned int timeout; + const char *name; }; #define NF_CT_EXPECT_CLASS_DEFAULT 0 @@ -79,13 +74,16 @@ int nf_conntrack_expect_init(struct net *net); void nf_conntrack_expect_fini(struct net *net); struct nf_conntrack_expect * -__nf_ct_expect_find(struct net *net, const struct nf_conntrack_tuple *tuple); +__nf_ct_expect_find(struct net *net, u16 zone, + const struct nf_conntrack_tuple *tuple); struct nf_conntrack_expect * -nf_ct_expect_find_get(struct net *net, const struct nf_conntrack_tuple *tuple); +nf_ct_expect_find_get(struct net *net, u16 zone, + const struct nf_conntrack_tuple *tuple); struct nf_conntrack_expect * -nf_ct_find_expectation(struct net *net, const struct nf_conntrack_tuple *tuple); +nf_ct_find_expectation(struct net *net, u16 zone, + const struct nf_conntrack_tuple *tuple); void nf_ct_unlink_expect(struct nf_conntrack_expect *exp); void nf_ct_remove_expectations(struct nf_conn *ct); diff --git a/include/net/netfilter/nf_conntrack_extend.h b/include/net/netfilter/nf_conntrack_extend.h index 7f8fc5d123c5..2d2a1f9a61d8 100644 --- a/include/net/netfilter/nf_conntrack_extend.h +++ b/include/net/netfilter/nf_conntrack_extend.h @@ -3,12 +3,12 @@ #include <net/netfilter/nf_conntrack.h> -enum nf_ct_ext_id -{ +enum nf_ct_ext_id { NF_CT_EXT_HELPER, NF_CT_EXT_NAT, NF_CT_EXT_ACCT, NF_CT_EXT_ECACHE, + NF_CT_EXT_ZONE, NF_CT_EXT_NUM, }; @@ -16,6 +16,7 @@ enum nf_ct_ext_id #define NF_CT_EXT_NAT_TYPE struct nf_conn_nat #define NF_CT_EXT_ACCT_TYPE struct nf_conn_counter #define NF_CT_EXT_ECACHE_TYPE struct nf_conntrack_ecache +#define NF_CT_EXT_ZONE_TYPE struct nf_conntrack_zone /* Extensions: optional stuff which isn't permanently in struct. */ struct nf_ct_ext { @@ -65,8 +66,7 @@ __nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, gfp_t gfp); #define NF_CT_EXT_F_PREALLOC 0x0001 -struct nf_ct_ext_type -{ +struct nf_ct_ext_type { /* Destroys relationships (can be NULL). */ void (*destroy)(struct nf_conn *ct); /* Called when realloacted (can be NULL). diff --git a/include/net/netfilter/nf_conntrack_helper.h b/include/net/netfilter/nf_conntrack_helper.h index 1b7068000927..32c305dbdab6 100644 --- a/include/net/netfilter/nf_conntrack_helper.h +++ b/include/net/netfilter/nf_conntrack_helper.h @@ -16,8 +16,7 @@ struct module; #define NF_CT_HELPER_NAME_LEN 16 -struct nf_conntrack_helper -{ +struct nf_conntrack_helper { struct hlist_node hnode; /* Internal use. */ const char *name; /* name of the module */ @@ -41,14 +40,18 @@ struct nf_conntrack_helper }; extern struct nf_conntrack_helper * -__nf_conntrack_helper_find_byname(const char *name); +__nf_conntrack_helper_find(const char *name, u16 l3num, u8 protonum); + +extern struct nf_conntrack_helper * +nf_conntrack_helper_try_module_get(const char *name, u16 l3num, u8 protonum); extern int nf_conntrack_helper_register(struct nf_conntrack_helper *); extern void nf_conntrack_helper_unregister(struct nf_conntrack_helper *); extern struct nf_conn_help *nf_ct_helper_ext_add(struct nf_conn *ct, gfp_t gfp); -extern int __nf_ct_try_assign_helper(struct nf_conn *ct, gfp_t flags); +extern int __nf_ct_try_assign_helper(struct nf_conn *ct, struct nf_conn *tmpl, + gfp_t flags); extern void nf_ct_helper_destroy(struct nf_conn *ct); diff --git a/include/net/netfilter/nf_conntrack_l3proto.h b/include/net/netfilter/nf_conntrack_l3proto.h index 9f99d36d5de9..a7547611e8f1 100644 --- a/include/net/netfilter/nf_conntrack_l3proto.h +++ b/include/net/netfilter/nf_conntrack_l3proto.h @@ -16,8 +16,7 @@ #include <linux/seq_file.h> #include <net/netfilter/nf_conntrack.h> -struct nf_conntrack_l3proto -{ +struct nf_conntrack_l3proto { /* L3 Protocol Family number. ex) PF_INET */ u_int16_t l3proto; diff --git a/include/net/netfilter/nf_conntrack_l4proto.h b/include/net/netfilter/nf_conntrack_l4proto.h index 3767fb41e541..e3d3ee3c06a2 100644 --- a/include/net/netfilter/nf_conntrack_l4proto.h +++ b/include/net/netfilter/nf_conntrack_l4proto.h @@ -15,8 +15,7 @@ struct seq_file; -struct nf_conntrack_l4proto -{ +struct nf_conntrack_l4proto { /* L3 Protocol number. */ u_int16_t l3proto; @@ -50,8 +49,8 @@ struct nf_conntrack_l4proto /* Called when a conntrack entry is destroyed */ void (*destroy)(struct nf_conn *ct); - int (*error)(struct net *net, struct sk_buff *skb, unsigned int dataoff, - enum ip_conntrack_info *ctinfo, + int (*error)(struct net *net, struct nf_conn *tmpl, struct sk_buff *skb, + unsigned int dataoff, enum ip_conntrack_info *ctinfo, u_int8_t pf, unsigned int hooknum); /* Print out the per-protocol part of the tuple. Return like seq_* */ diff --git a/include/net/netfilter/nf_conntrack_tuple.h b/include/net/netfilter/nf_conntrack_tuple.h index 2628c154d40e..4ee44c84a304 100644 --- a/include/net/netfilter/nf_conntrack_tuple.h +++ b/include/net/netfilter/nf_conntrack_tuple.h @@ -26,8 +26,7 @@ /* The protocol-specific manipulable parts of the tuple: always in network order! */ -union nf_conntrack_man_proto -{ +union nf_conntrack_man_proto { /* Add other protocols here. */ __be16 all; @@ -52,8 +51,7 @@ union nf_conntrack_man_proto }; /* The manipulable part of the tuple. */ -struct nf_conntrack_man -{ +struct nf_conntrack_man { union nf_inet_addr u3; union nf_conntrack_man_proto u; /* Layer 3 protocol */ @@ -61,8 +59,7 @@ struct nf_conntrack_man }; /* This contains the information to distinguish a connection. */ -struct nf_conntrack_tuple -{ +struct nf_conntrack_tuple { struct nf_conntrack_man src; /* These are the parts of the tuple which are fixed. */ @@ -100,8 +97,7 @@ struct nf_conntrack_tuple } dst; }; -struct nf_conntrack_tuple_mask -{ +struct nf_conntrack_tuple_mask { struct { union nf_inet_addr u3; union nf_conntrack_man_proto u; diff --git a/include/net/netfilter/nf_conntrack_zones.h b/include/net/netfilter/nf_conntrack_zones.h new file mode 100644 index 000000000000..034efe8d45a5 --- /dev/null +++ b/include/net/netfilter/nf_conntrack_zones.h @@ -0,0 +1,25 @@ +#ifndef _NF_CONNTRACK_ZONES_H +#define _NF_CONNTRACK_ZONES_H + +#define NF_CT_DEFAULT_ZONE 0 + +#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) +#include <net/netfilter/nf_conntrack_extend.h> + +struct nf_conntrack_zone { + u16 id; +}; + +static inline u16 nf_ct_zone(const struct nf_conn *ct) +{ +#ifdef CONFIG_NF_CONNTRACK_ZONES + struct nf_conntrack_zone *nf_ct_zone; + nf_ct_zone = nf_ct_ext_find(ct, NF_CT_EXT_ZONE); + if (nf_ct_zone) + return nf_ct_zone->id; +#endif + return NF_CT_DEFAULT_ZONE; +} + +#endif /* CONFIG_NF_CONNTRACK || CONFIG_NF_CONNTRACK_MODULE */ +#endif /* _NF_CONNTRACK_ZONES_H */ diff --git a/include/net/netfilter/nf_nat.h b/include/net/netfilter/nf_nat.h index 8df0b7f7fc6e..f5f09f032a90 100644 --- a/include/net/netfilter/nf_nat.h +++ b/include/net/netfilter/nf_nat.h @@ -5,8 +5,7 @@ #define NF_NAT_MAPPING_TYPE_MAX_NAMELEN 16 -enum nf_nat_manip_type -{ +enum nf_nat_manip_type { IP_NAT_MANIP_SRC, IP_NAT_MANIP_DST }; @@ -30,8 +29,7 @@ struct nf_nat_seq { }; /* Single range specification. */ -struct nf_nat_range -{ +struct nf_nat_range { /* Set to OR of flags above. */ unsigned int flags; @@ -43,8 +41,7 @@ struct nf_nat_range }; /* For backwards compat: don't use in modern code. */ -struct nf_nat_multi_range_compat -{ +struct nf_nat_multi_range_compat { unsigned int rangesize; /* Must be 1. */ /* hangs off end. */ @@ -57,8 +54,7 @@ struct nf_nat_multi_range_compat #include <net/netfilter/nf_conntrack_extend.h> /* per conntrack: nat application helper private data */ -union nf_conntrack_nat_help -{ +union nf_conntrack_nat_help { /* insert nat helper private data here */ struct nf_nat_pptp nat_pptp_info; }; @@ -66,8 +62,7 @@ union nf_conntrack_nat_help struct nf_conn; /* The structure embedded in the conntrack structure. */ -struct nf_conn_nat -{ +struct nf_conn_nat { struct hlist_node bysource; struct nf_nat_seq seq[IP_CT_DIR_MAX]; struct nf_conn *ct; diff --git a/include/net/netfilter/nf_nat_helper.h b/include/net/netfilter/nf_nat_helper.h index 237a961f40e1..02bb6c29dc3d 100644 --- a/include/net/netfilter/nf_nat_helper.h +++ b/include/net/netfilter/nf_nat_helper.h @@ -7,13 +7,27 @@ struct sk_buff; /* These return true or false. */ -extern int nf_nat_mangle_tcp_packet(struct sk_buff *skb, - struct nf_conn *ct, - enum ip_conntrack_info ctinfo, - unsigned int match_offset, - unsigned int match_len, - const char *rep_buffer, - unsigned int rep_len); +extern int __nf_nat_mangle_tcp_packet(struct sk_buff *skb, + struct nf_conn *ct, + enum ip_conntrack_info ctinfo, + unsigned int match_offset, + unsigned int match_len, + const char *rep_buffer, + unsigned int rep_len, bool adjust); + +static inline int nf_nat_mangle_tcp_packet(struct sk_buff *skb, + struct nf_conn *ct, + enum ip_conntrack_info ctinfo, + unsigned int match_offset, + unsigned int match_len, + const char *rep_buffer, + unsigned int rep_len) +{ + return __nf_nat_mangle_tcp_packet(skb, ct, ctinfo, + match_offset, match_len, + rep_buffer, rep_len, true); +} + extern int nf_nat_mangle_udp_packet(struct sk_buff *skb, struct nf_conn *ct, enum ip_conntrack_info ctinfo, @@ -21,6 +35,10 @@ extern int nf_nat_mangle_udp_packet(struct sk_buff *skb, unsigned int match_len, const char *rep_buffer, unsigned int rep_len); + +extern void nf_nat_set_seq_adjust(struct nf_conn *ct, + enum ip_conntrack_info ctinfo, + __be32 seq, s16 off); extern int nf_nat_seq_adjust(struct sk_buff *skb, struct nf_conn *ct, enum ip_conntrack_info ctinfo); @@ -32,4 +50,8 @@ extern int (*nf_nat_seq_adjust_hook)(struct sk_buff *skb, * to port ct->master->saved_proto. */ extern void nf_nat_follow_master(struct nf_conn *ct, struct nf_conntrack_expect *this); + +extern s16 nf_nat_get_offset(const struct nf_conn *ct, + enum ip_conntrack_dir dir, + u32 seq); #endif diff --git a/include/net/netfilter/nf_nat_protocol.h b/include/net/netfilter/nf_nat_protocol.h index f3662c4394ef..c398017ccfa3 100644 --- a/include/net/netfilter/nf_nat_protocol.h +++ b/include/net/netfilter/nf_nat_protocol.h @@ -6,8 +6,7 @@ struct nf_nat_range; -struct nf_nat_protocol -{ +struct nf_nat_protocol { /* Protocol number. */ unsigned int protonum; diff --git a/include/net/netlink.h b/include/net/netlink.h index a63b2192ac1c..f82e463c875a 100644 --- a/include/net/netlink.h +++ b/include/net/netlink.h @@ -196,7 +196,7 @@ enum { * All other Exact length of attribute payload * * Example: - * static struct nla_policy my_policy[ATTR_MAX+1] __read_mostly = { + * static const struct nla_policy my_policy[ATTR_MAX+1] = { * [ATTR_FOO] = { .type = NLA_U16 }, * [ATTR_BAR] = { .type = NLA_STRING, .len = BARSIZ }, * [ATTR_BAZ] = { .len = sizeof(struct mystruct) }, diff --git a/include/net/netns/conntrack.h b/include/net/netns/conntrack.h index ba1ba0c5efd1..d4958d4c6574 100644 --- a/include/net/netns/conntrack.h +++ b/include/net/netns/conntrack.h @@ -11,11 +11,13 @@ struct nf_conntrack_ecache; struct netns_ct { atomic_t count; unsigned int expect_count; + unsigned int htable_size; + struct kmem_cache *nf_conntrack_cachep; struct hlist_nulls_head *hash; struct hlist_head *expect_hash; struct hlist_nulls_head unconfirmed; struct hlist_nulls_head dying; - struct ip_conntrack_stat *stat; + struct ip_conntrack_stat __percpu *stat; int sysctl_events; unsigned int sysctl_events_retry_timeout; int sysctl_acct; @@ -28,5 +30,6 @@ struct netns_ct { #endif int hash_vmalloc; int expect_vmalloc; + char *slabname; }; #endif diff --git a/include/net/netns/core.h b/include/net/netns/core.h index 24d4be76bbd1..78eb1ff75475 100644 --- a/include/net/netns/core.h +++ b/include/net/netns/core.h @@ -10,7 +10,7 @@ struct netns_core { int sysctl_somaxconn; - struct prot_inuse *inuse; + struct prot_inuse __percpu *inuse; }; #endif diff --git a/include/net/netns/generic.h b/include/net/netns/generic.h index 0c04fd2a700b..ff4982ab84b6 100644 --- a/include/net/netns/generic.h +++ b/include/net/netns/generic.h @@ -12,9 +12,11 @@ * stuff on the struct net without explicit struct net modification * * The rules are simple: - * 1. register the ops with register_pernet_gen_device to get the id - * of your private pointer; - * 2. call net_assign_generic() to put the private data on the struct + * 1. set pernet_operations->id. After register_pernet_device you + * will have the id of your private pointer. + * 2. Either set pernet_operations->size (to have the code allocate and + * free a private structure pointed to from struct net ) or + * call net_assign_generic() to put the private data on the struct * net (most preferably this should be done in the ->init callback * of the ops registered); * 3. do not change this pointer while the net is alive; diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h index 2eb3814d6258..2764994c9136 100644 --- a/include/net/netns/ipv4.h +++ b/include/net/netns/ipv4.h @@ -37,9 +37,12 @@ struct netns_ipv4 { struct xt_table *iptable_mangle; struct xt_table *iptable_raw; struct xt_table *arptable_filter; +#ifdef CONFIG_SECURITY struct xt_table *iptable_security; +#endif struct xt_table *nat_table; struct hlist_head *nat_bysource; + unsigned int nat_htable_size; int nat_vmalloced; #endif diff --git a/include/net/netns/ipv6.h b/include/net/netns/ipv6.h index dfeb2d7c425b..1f11ebc22151 100644 --- a/include/net/netns/ipv6.h +++ b/include/net/netns/ipv6.h @@ -36,8 +36,10 @@ struct netns_ipv6 { struct xt_table *ip6table_filter; struct xt_table *ip6table_mangle; struct xt_table *ip6table_raw; +#ifdef CONFIG_SECURITY struct xt_table *ip6table_security; #endif +#endif struct rt6_info *ip6_null_entry; struct rt6_statistics *rt6_stats; struct timer_list ip6_fib_timer; diff --git a/include/net/netns/packet.h b/include/net/netns/packet.h index 637daf698884..cb4e894c0f8d 100644 --- a/include/net/netns/packet.h +++ b/include/net/netns/packet.h @@ -4,11 +4,11 @@ #ifndef __NETNS_PACKET_H__ #define __NETNS_PACKET_H__ -#include <linux/list.h> +#include <linux/rculist.h> #include <linux/spinlock.h> struct netns_packet { - rwlock_t sklist_lock; + spinlock_t sklist_lock; struct hlist_head sklist; }; diff --git a/include/net/netns/xfrm.h b/include/net/netns/xfrm.h index 1ba912749caa..74f119a2829a 100644 --- a/include/net/netns/xfrm.h +++ b/include/net/netns/xfrm.h @@ -5,6 +5,7 @@ #include <linux/wait.h> #include <linux/workqueue.h> #include <linux/xfrm.h> +#include <net/dst_ops.h> struct ctl_table_header; @@ -42,7 +43,13 @@ struct netns_xfrm { unsigned int policy_count[XFRM_POLICY_MAX * 2]; struct work_struct policy_hash_work; + struct dst_ops xfrm4_dst_ops; +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + struct dst_ops xfrm6_dst_ops; +#endif + struct sock *nlsk; + struct sock *nlsk_stash; u32 sysctl_aevent_etime; u32 sysctl_aevent_rseqth; diff --git a/include/net/netrom.h b/include/net/netrom.h index 15696b1fd30f..ab170a60e7d3 100644 --- a/include/net/netrom.h +++ b/include/net/netrom.h @@ -132,6 +132,8 @@ static __inline__ void nr_node_put(struct nr_node *nr_node) static __inline__ void nr_neigh_put(struct nr_neigh *nr_neigh) { if (atomic_dec_and_test(&nr_neigh->refcount)) { + if (nr_neigh->ax25) + ax25_cb_put(nr_neigh->ax25); kfree(nr_neigh->digipeat); kfree(nr_neigh); } diff --git a/include/net/phonet/pep.h b/include/net/phonet/pep.h index 4c61cdce4e5f..35672b1cf44a 100644 --- a/include/net/phonet/pep.h +++ b/include/net/phonet/pep.h @@ -44,6 +44,7 @@ struct pep_sock { u8 rx_fc; /* RX flow control */ u8 tx_fc; /* TX flow control */ u8 init_enable; /* auto-enable at creation */ + u8 aligned; }; static inline struct pep_sock *pep_sk(struct sock *sk) @@ -77,6 +78,7 @@ static inline struct pnpipehdr *pnp_hdr(struct sk_buff *skb) enum { PNS_PIPE_DATA = 0x20, + PNS_PIPE_ALIGNED_DATA, PNS_PEP_CONNECT_REQ = 0x40, PNS_PEP_CONNECT_RESP, @@ -138,6 +140,7 @@ enum { PN_PIPE_SB_NEGOTIATED_FC, PN_PIPE_SB_REQUIRED_FC_TX, PN_PIPE_SB_PREFERRED_FC_RX, + PN_PIPE_SB_ALIGNED_DATA, }; /* Phonet pipe flow control models */ diff --git a/include/net/phonet/phonet.h b/include/net/phonet/phonet.h index d43f71b5ec00..7b114079a51b 100644 --- a/include/net/phonet/phonet.h +++ b/include/net/phonet/phonet.h @@ -46,7 +46,9 @@ static inline struct pn_sock *pn_sk(struct sock *sk) extern const struct proto_ops phonet_dgram_ops; +void pn_sock_init(void); struct sock *pn_find_sock_by_sa(struct net *net, const struct sockaddr_pn *sa); +void pn_deliver_sock_broadcast(struct net *net, struct sk_buff *skb); void phonet_get_local_port_range(int *min, int *max); void pn_sock_hash(struct sock *sk); void pn_sock_unhash(struct sock *sk); diff --git a/include/net/phonet/pn_dev.h b/include/net/phonet/pn_dev.h index 44c923c9e21d..d7b989ca3d63 100644 --- a/include/net/phonet/pn_dev.h +++ b/include/net/phonet/pn_dev.h @@ -25,7 +25,7 @@ struct phonet_device_list { struct list_head list; - spinlock_t lock; + struct mutex lock; }; struct phonet_device_list *phonet_device_list(struct net *net); @@ -47,6 +47,12 @@ u8 phonet_address_get(struct net_device *dev, u8 addr); int phonet_address_lookup(struct net *net, u8 addr); void phonet_address_notify(int event, struct net_device *dev, u8 addr); +int phonet_route_add(struct net_device *dev, u8 daddr); +int phonet_route_del(struct net_device *dev, u8 daddr); +void rtm_phonet_notify(int event, struct net_device *dev, u8 dst); +struct net_device *phonet_route_get(struct net *net, u8 daddr); +struct net_device *phonet_route_output(struct net *net, u8 daddr); + #define PN_NO_ADDR 0xff extern const struct file_operations pn_sock_seq_fops; diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h index d1ca31444644..dd3031aed9d5 100644 --- a/include/net/pkt_cls.h +++ b/include/net/pkt_cls.h @@ -7,8 +7,7 @@ /* Basic packet classifier frontend definitions. */ -struct tcf_walker -{ +struct tcf_walker { int stop; int skip; int count; @@ -61,8 +60,7 @@ tcf_unbind_filter(struct tcf_proto *tp, struct tcf_result *r) tp->q->ops->cl_ops->unbind_tcf(tp->q, cl); } -struct tcf_exts -{ +struct tcf_exts { #ifdef CONFIG_NET_CLS_ACT struct tc_action *action; #endif @@ -71,8 +69,7 @@ struct tcf_exts /* Map to export classifier specific extension TLV types to the * generic extensions API. Unsupported extensions must be set to 0. */ -struct tcf_ext_map -{ +struct tcf_ext_map { int action; int police; }; @@ -143,8 +140,7 @@ extern int tcf_exts_dump_stats(struct sk_buff *skb, struct tcf_exts *exts, /** * struct tcf_pkt_info - packet information */ -struct tcf_pkt_info -{ +struct tcf_pkt_info { unsigned char * ptr; int nexthdr; }; @@ -162,8 +158,7 @@ struct tcf_ematch_ops; * @datalen: length of the ematch specific configuration data * @data: ematch specific data */ -struct tcf_ematch -{ +struct tcf_ematch { struct tcf_ematch_ops * ops; unsigned long data; unsigned int datalen; @@ -211,8 +206,7 @@ static inline int tcf_em_early_end(struct tcf_ematch *em, int result) * @hdr: ematch tree header supplied by userspace * @matches: array of ematches */ -struct tcf_ematch_tree -{ +struct tcf_ematch_tree { struct tcf_ematch_tree_hdr hdr; struct tcf_ematch * matches; @@ -230,8 +224,7 @@ struct tcf_ematch_tree * @owner: owner, must be set to THIS_MODULE * @link: link to previous/next ematch module (internal use) */ -struct tcf_ematch_ops -{ +struct tcf_ematch_ops { int kind; int datalen; int (*change)(struct tcf_proto *, void *, @@ -302,8 +295,7 @@ static inline int tcf_em_tree_match(struct sk_buff *skb, #else /* CONFIG_NET_EMATCH */ -struct tcf_ematch_tree -{ +struct tcf_ematch_tree { }; #define tcf_em_tree_validate(tp, tb, t) ((void)(t), 0) @@ -351,9 +343,9 @@ tcf_match_indev(struct sk_buff *skb, char *indev) struct net_device *dev; if (indev[0]) { - if (!skb->iif) + if (!skb->skb_iif) return 0; - dev = __dev_get_by_index(dev_net(skb->dev), skb->iif); + dev = __dev_get_by_index(dev_net(skb->dev), skb->skb_iif); if (!dev || strcmp(indev, dev->name)) return 0; } diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h index f911ec7598ef..b6cdc33b39c1 100644 --- a/include/net/pkt_sched.h +++ b/include/net/pkt_sched.h @@ -5,8 +5,7 @@ #include <linux/ktime.h> #include <net/sch_generic.h> -struct qdisc_walker -{ +struct qdisc_walker { int stop; int skip; int count; @@ -72,6 +71,7 @@ extern void qdisc_watchdog_cancel(struct qdisc_watchdog *wd); extern struct Qdisc_ops pfifo_qdisc_ops; extern struct Qdisc_ops bfifo_qdisc_ops; +extern struct Qdisc_ops pfifo_head_drop_qdisc_ops; extern int fifo_set_limit(struct Qdisc *q, unsigned int limit); extern struct Qdisc *fifo_create_dflt(struct Qdisc *sch, struct Qdisc_ops *ops, diff --git a/include/net/protocol.h b/include/net/protocol.h index 60249e51b669..f1effdd3c265 100644 --- a/include/net/protocol.h +++ b/include/net/protocol.h @@ -47,8 +47,7 @@ struct net_protocol { }; #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) -struct inet6_protocol -{ +struct inet6_protocol { int (*handler)(struct sk_buff *skb); void (*err_handler)(struct sk_buff *skb, @@ -83,10 +82,6 @@ struct inet_protosw { struct proto *prot; const struct proto_ops *ops; - int capability; /* Which (if any) capability do - * we need to use this socket - * interface? - */ char no_check; /* checksum on rcv/xmit/none? */ unsigned char flags; /* See INET_PROTOSW_* below. */ }; diff --git a/include/net/red.h b/include/net/red.h index 3cf31d466a81..995108e54d9f 100644 --- a/include/net/red.h +++ b/include/net/red.h @@ -90,8 +90,7 @@ #define RED_STAB_SIZE 256 #define RED_STAB_MASK (RED_STAB_SIZE - 1) -struct red_stats -{ +struct red_stats { u32 prob_drop; /* Early probability drops */ u32 prob_mark; /* Early probability marks */ u32 forced_drop; /* Forced drops, qavg > max_thresh */ @@ -101,8 +100,7 @@ struct red_stats u32 backlog; }; -struct red_parms -{ +struct red_parms { /* Parameters */ u32 qth_min; /* Min avg length threshold: A scaled */ u32 qth_max; /* Max avg length threshold: A scaled */ diff --git a/include/net/regulatory.h b/include/net/regulatory.h index 47995b81c5d7..f873ee37f7e4 100644 --- a/include/net/regulatory.h +++ b/include/net/regulatory.h @@ -39,6 +39,7 @@ enum environment_cap { * 00 - World regulatory domain * 99 - built by driver but a specific alpha2 cannot be determined * 98 - result of an intersection between two regulatory domains + * 97 - regulatory domain has not yet been configured * @intersect: indicates whether the wireless core should intersect * the requested regulatory domain with the presently set regulatory * domain. diff --git a/include/net/request_sock.h b/include/net/request_sock.h index c7190846e128..99e6e19b57c2 100644 --- a/include/net/request_sock.h +++ b/include/net/request_sock.h @@ -27,18 +27,26 @@ struct sk_buff; struct dst_entry; struct proto; +/* empty to "strongly type" an otherwise void parameter. + */ +struct request_values { +}; + struct request_sock_ops { int family; int obj_size; struct kmem_cache *slab; char *slab_name; int (*rtx_syn_ack)(struct sock *sk, - struct request_sock *req); + struct request_sock *req, + struct request_values *rvp); void (*send_ack)(struct sock *sk, struct sk_buff *skb, struct request_sock *req); void (*send_reset)(struct sock *sk, struct sk_buff *skb); void (*destructor)(struct request_sock *req); + void (*syn_ack_timeout)(struct sock *sk, + struct request_sock *req); }; /* struct request_sock - mini sock to represent a connection request diff --git a/include/net/route.h b/include/net/route.h index 40f6346ef496..2c9fba7f7731 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -49,10 +49,8 @@ struct fib_nh; struct inet_peer; -struct rtable -{ - union - { +struct rtable { + union { struct dst_entry dst; } u; @@ -77,16 +75,14 @@ struct rtable struct inet_peer *peer; /* long-living peer info */ }; -struct ip_rt_acct -{ +struct ip_rt_acct { __u32 o_bytes; __u32 o_packets; __u32 i_bytes; __u32 i_packets; }; -struct rt_cache_stat -{ +struct rt_cache_stat { unsigned int in_hit; unsigned int in_slow_tot; unsigned int in_slow_mc; @@ -105,13 +101,14 @@ struct rt_cache_stat unsigned int out_hlist_search; }; -extern struct ip_rt_acct *ip_rt_acct; +extern struct ip_rt_acct __percpu *ip_rt_acct; struct in_device; extern int ip_rt_init(void); extern void ip_rt_redirect(__be32 old_gw, __be32 dst, __be32 new_gw, __be32 src, struct net_device *dev); extern void rt_cache_flush(struct net *net, int how); +extern void rt_cache_flush_batch(void); extern int __ip_route_output_key(struct net *, struct rtable **, const struct flowi *flp); extern int ip_route_output_key(struct net *, struct rtable **, struct flowi *flp); extern int ip_route_output_flow(struct net *, struct rtable **rp, struct flowi *flp, struct sock *sk, int flags); diff --git a/include/net/rtnetlink.h b/include/net/rtnetlink.h index c3aa044d3fc3..af60fd050844 100644 --- a/include/net/rtnetlink.h +++ b/include/net/rtnetlink.h @@ -55,13 +55,15 @@ struct rtnl_link_ops { int (*validate)(struct nlattr *tb[], struct nlattr *data[]); - int (*newlink)(struct net_device *dev, + int (*newlink)(struct net *src_net, + struct net_device *dev, struct nlattr *tb[], struct nlattr *data[]); int (*changelink)(struct net_device *dev, struct nlattr *tb[], struct nlattr *data[]); - void (*dellink)(struct net_device *dev); + void (*dellink)(struct net_device *dev, + struct list_head *head); size_t (*get_size)(const struct net_device *dev); int (*fill_info)(struct sk_buff *skb, @@ -82,8 +84,11 @@ extern void rtnl_kill_links(struct net *net, struct rtnl_link_ops *ops); extern int rtnl_link_register(struct rtnl_link_ops *ops); extern void rtnl_link_unregister(struct rtnl_link_ops *ops); -extern struct net_device *rtnl_create_link(struct net *net, char *ifname, - const struct rtnl_link_ops *ops, struct nlattr *tb[]); +extern struct net *rtnl_link_get_net(struct net *src_net, struct nlattr *tb[]); +extern struct net_device *rtnl_create_link(struct net *src_net, struct net *net, + char *ifname, const struct rtnl_link_ops *ops, struct nlattr *tb[]); +extern int rtnl_configure_link(struct net_device *dev, + const struct ifinfomsg *ifm); extern const struct nla_policy ifla_policy[IFLA_MAX+1]; #define MODULE_ALIAS_RTNL_LINK(kind) MODULE_ALIAS("rtnl-link-" kind) diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index c33180dd42b4..67dc08eaaa45 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -15,16 +15,14 @@ struct qdisc_walker; struct tcf_walker; struct module; -struct qdisc_rate_table -{ +struct qdisc_rate_table { struct tc_ratespec rate; u32 data[256]; struct qdisc_rate_table *next; int refcnt; }; -enum qdisc_state_t -{ +enum qdisc_state_t { __QDISC_STATE_RUNNING, __QDISC_STATE_SCHED, __QDISC_STATE_DEACTIVATED, @@ -37,8 +35,7 @@ struct qdisc_size_table { u16 data[]; }; -struct Qdisc -{ +struct Qdisc { int (*enqueue)(struct sk_buff *skb, struct Qdisc *dev); struct sk_buff * (*dequeue)(struct Qdisc *dev); unsigned flags; @@ -78,8 +75,7 @@ struct Qdisc struct gnet_stats_queue qstats; }; -struct Qdisc_class_ops -{ +struct Qdisc_class_ops { /* Child qdisc manipulation */ struct netdev_queue * (*select_queue)(struct Qdisc *, struct tcmsg *); int (*graft)(struct Qdisc *, unsigned long cl, @@ -108,8 +104,7 @@ struct Qdisc_class_ops struct gnet_dump *); }; -struct Qdisc_ops -{ +struct Qdisc_ops { struct Qdisc_ops *next; const struct Qdisc_class_ops *cl_ops; char id[IFNAMSIZ]; @@ -133,14 +128,12 @@ struct Qdisc_ops }; -struct tcf_result -{ +struct tcf_result { unsigned long class; u32 classid; }; -struct tcf_proto_ops -{ +struct tcf_proto_ops { struct tcf_proto_ops *next; char kind[IFNAMSIZ]; @@ -164,8 +157,7 @@ struct tcf_proto_ops struct module *owner; }; -struct tcf_proto -{ +struct tcf_proto { /* Fast access part */ struct tcf_proto *next; void *root; @@ -261,14 +253,12 @@ extern struct Qdisc_ops noop_qdisc_ops; extern struct Qdisc_ops pfifo_fast_ops; extern struct Qdisc_ops mq_qdisc_ops; -struct Qdisc_class_common -{ +struct Qdisc_class_common { u32 classid; struct hlist_node hnode; }; -struct Qdisc_class_hash -{ +struct Qdisc_class_hash { struct hlist_head *hash; unsigned int hashsize; unsigned int hashmask; @@ -437,6 +427,25 @@ static inline struct sk_buff *qdisc_dequeue_head(struct Qdisc *sch) return __qdisc_dequeue_head(sch, &sch->q); } +static inline unsigned int __qdisc_queue_drop_head(struct Qdisc *sch, + struct sk_buff_head *list) +{ + struct sk_buff *skb = __qdisc_dequeue_head(sch, list); + + if (likely(skb != NULL)) { + unsigned int len = qdisc_pkt_len(skb); + kfree_skb(skb); + return len; + } + + return 0; +} + +static inline unsigned int qdisc_queue_drop_head(struct Qdisc *sch) +{ + return __qdisc_queue_drop_head(sch, &sch->q); +} + static inline struct sk_buff *__qdisc_dequeue_tail(struct Qdisc *sch, struct sk_buff_head *list) { diff --git a/include/net/scm.h b/include/net/scm.h index cf48c800e926..8360e47aa7e3 100644 --- a/include/net/scm.h +++ b/include/net/scm.h @@ -12,15 +12,13 @@ */ #define SCM_MAX_FD 255 -struct scm_fp_list -{ +struct scm_fp_list { struct list_head list; int count; struct file *fp[SCM_MAX_FD]; }; -struct scm_cookie -{ +struct scm_cookie { struct ucred creds; /* Skb credentials */ struct scm_fp_list *fp; /* Passed files */ #ifdef CONFIG_SECURITY_NETWORK @@ -88,8 +86,7 @@ static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct sc static __inline__ void scm_recv(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm, int flags) { - if (!msg->msg_control) - { + if (!msg->msg_control) { if (test_bit(SOCK_PASSCRED, &sock->flags) || scm->fp) msg->msg_flags |= MSG_CTRUNC; scm_destroy(scm); diff --git a/include/net/sctp/constants.h b/include/net/sctp/constants.h index 58f714a3b670..63908840eef0 100644 --- a/include/net/sctp/constants.h +++ b/include/net/sctp/constants.h @@ -308,6 +308,10 @@ enum { SCTP_MAX_GABS = 16 }; #define SCTP_DEFAULT_MINWINDOW 1500 /* default minimum rwnd size */ #define SCTP_DEFAULT_MAXWINDOW 65535 /* default rwnd size */ +#define SCTP_DEFAULT_RWND_SHIFT 4 /* by default, update on 1/16 of + * rcvbuf, which is 1/8 of initial + * window + */ #define SCTP_DEFAULT_MAXSEGMENT 1500 /* MTU size, this is the limit * to which we will raise the P-MTU. */ diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h index 8a6d5297de16..78740ec57d5d 100644 --- a/include/net/sctp/sctp.h +++ b/include/net/sctp/sctp.h @@ -227,8 +227,7 @@ DECLARE_SNMP_STAT(struct sctp_mib, sctp_statistics); #endif /* !TEST_FRAME */ /* sctp mib definitions */ -enum -{ +enum { SCTP_MIB_NUM = 0, SCTP_MIB_CURRESTAB, /* CurrEstab */ SCTP_MIB_ACTIVEESTABS, /* ActiveEstabs */ diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h index c1dd89365833..851c813adb3a 100644 --- a/include/net/sctp/sm.h +++ b/include/net/sctp/sm.h @@ -243,7 +243,8 @@ struct sctp_chunk *sctp_make_op_error(const struct sctp_association *, const struct sctp_chunk *chunk, __be16 cause_code, const void *payload, - size_t paylen); + size_t paylen, + size_t reserve_tail); struct sctp_chunk *sctp_make_asconf_update_ip(struct sctp_association *, union sctp_addr *, diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index 42d00ced5eb8..ff3017744711 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -231,6 +231,11 @@ extern struct sctp_globals { /* Flag to indicate whether computing and verifying checksum * is disabled. */ int checksum_disable; + + /* Threshold for rwnd update SACKS. Receive buffer shifted this many + * bits is an indicator of when to send and window update SACK. + */ + int rwnd_update_shift; } sctp_globals; #define sctp_rto_initial (sctp_globals.rto_initial) @@ -267,6 +272,7 @@ extern struct sctp_globals { #define sctp_prsctp_enable (sctp_globals.prsctp_enable) #define sctp_auth_enable (sctp_globals.auth_enable) #define sctp_checksum_disable (sctp_globals.checksum_disable) +#define sctp_rwnd_upd_shift (sctp_globals.rwnd_update_shift) /* SCTP Socket type: UDP or TCP style. */ typedef enum { @@ -544,7 +550,7 @@ struct sctp_af { int level, int optname, char __user *optval, - int optlen); + unsigned int optlen); int (*getsockopt) (struct sock *sk, int level, int optname, @@ -554,7 +560,7 @@ struct sctp_af { int level, int optname, char __user *optval, - int optlen); + unsigned int optlen); int (*compat_getsockopt) (struct sock *sk, int level, int optname, @@ -893,7 +899,6 @@ struct sctp_transport { */ /* RTO : The current retransmission timeout value. */ unsigned long rto; - unsigned long last_rto; __u32 rtt; /* This is the most recent RTT. */ @@ -936,6 +941,8 @@ struct sctp_transport { /* Data that has been sent, but not acknowledged. */ __u32 flight_size; + __u32 burst_limited; /* Holds old cwnd when max.burst is applied */ + /* TSN marking the fast recovery exit point */ __u32 fast_recovery_exit; @@ -944,12 +951,6 @@ struct sctp_transport { /* Source address. */ union sctp_addr saddr; - /* When was the last time(in jiffies) that a data packet was sent on - * this transport? This is used to adjust the cwnd when the transport - * becomes inactive. - */ - unsigned long last_time_used; - /* Heartbeat interval: The endpoint sends out a Heartbeat chunk to * the destination address every heartbeat interval. */ @@ -988,7 +989,7 @@ struct sctp_transport { int init_sent_count; /* state : The current state of this destination, - * : i.e. SCTP_ACTIVE, SCTP_INACTIVE, SCTP_UNKOWN. + * : i.e. SCTP_ACTIVE, SCTP_INACTIVE, SCTP_UNKNOWN. */ int state; @@ -1070,6 +1071,8 @@ void sctp_transport_put(struct sctp_transport *); void sctp_transport_update_rto(struct sctp_transport *, __u32); void sctp_transport_raise_cwnd(struct sctp_transport *, __u32, __u32); void sctp_transport_lower_cwnd(struct sctp_transport *, sctp_lower_cwnd_t); +void sctp_transport_burst_limited(struct sctp_transport *); +void sctp_transport_burst_reset(struct sctp_transport *); unsigned long sctp_transport_timeout(struct sctp_transport *); void sctp_transport_reset(struct sctp_transport *); void sctp_transport_update_pmtu(struct sctp_transport *, u32); @@ -1980,7 +1983,7 @@ void sctp_assoc_set_primary(struct sctp_association *, void sctp_assoc_del_nonprimary_peers(struct sctp_association *, struct sctp_transport *); int sctp_assoc_set_bind_addr_from_ep(struct sctp_association *, - gfp_t); + sctp_scope_t, gfp_t); int sctp_assoc_set_bind_addr_from_cookie(struct sctp_association *, struct sctp_cookie*, gfp_t gfp); diff --git a/include/net/sctp/user.h b/include/net/sctp/user.h index be2334aaf52e..2b2769c5ca9f 100644 --- a/include/net/sctp/user.h +++ b/include/net/sctp/user.h @@ -60,96 +60,49 @@ typedef __s32 sctp_assoc_t; /* The following symbols come from the Sockets API Extensions for * SCTP <draft-ietf-tsvwg-sctpsocket-07.txt>. */ -enum sctp_optname { - SCTP_RTOINFO, -#define SCTP_RTOINFO SCTP_RTOINFO - SCTP_ASSOCINFO, -#define SCTP_ASSOCINFO SCTP_ASSOCINFO - SCTP_INITMSG, -#define SCTP_INITMSG SCTP_INITMSG - SCTP_NODELAY, /* Get/set nodelay option. */ -#define SCTP_NODELAY SCTP_NODELAY - SCTP_AUTOCLOSE, -#define SCTP_AUTOCLOSE SCTP_AUTOCLOSE - SCTP_SET_PEER_PRIMARY_ADDR, -#define SCTP_SET_PEER_PRIMARY_ADDR SCTP_SET_PEER_PRIMARY_ADDR - SCTP_PRIMARY_ADDR, -#define SCTP_PRIMARY_ADDR SCTP_PRIMARY_ADDR - SCTP_ADAPTATION_LAYER, -#define SCTP_ADAPTATION_LAYER SCTP_ADAPTATION_LAYER - SCTP_DISABLE_FRAGMENTS, -#define SCTP_DISABLE_FRAGMENTS SCTP_DISABLE_FRAGMENTS - SCTP_PEER_ADDR_PARAMS, -#define SCTP_PEER_ADDR_PARAMS SCTP_PEER_ADDR_PARAMS - SCTP_DEFAULT_SEND_PARAM, -#define SCTP_DEFAULT_SEND_PARAM SCTP_DEFAULT_SEND_PARAM - SCTP_EVENTS, -#define SCTP_EVENTS SCTP_EVENTS - SCTP_I_WANT_MAPPED_V4_ADDR, /* Turn on/off mapped v4 addresses */ -#define SCTP_I_WANT_MAPPED_V4_ADDR SCTP_I_WANT_MAPPED_V4_ADDR - SCTP_MAXSEG, /* Get/set maximum fragment. */ -#define SCTP_MAXSEG SCTP_MAXSEG - SCTP_STATUS, -#define SCTP_STATUS SCTP_STATUS - SCTP_GET_PEER_ADDR_INFO, -#define SCTP_GET_PEER_ADDR_INFO SCTP_GET_PEER_ADDR_INFO - SCTP_DELAYED_ACK, -#define SCTP_DELAYED_ACK_TIME SCTP_DELAYED_ACK -#define SCTP_DELAYED_ACK SCTP_DELAYED_ACK - SCTP_CONTEXT, /* Receive Context */ -#define SCTP_CONTEXT SCTP_CONTEXT - SCTP_FRAGMENT_INTERLEAVE, -#define SCTP_FRAGMENT_INTERLEAVE SCTP_FRAGMENT_INTERLEAVE - SCTP_PARTIAL_DELIVERY_POINT, /* Set/Get partial delivery point */ -#define SCTP_PARTIAL_DELIVERY_POINT SCTP_PARTIAL_DELIVERY_POINT - SCTP_MAX_BURST, /* Set/Get max burst */ -#define SCTP_MAX_BURST SCTP_MAX_BURST - SCTP_AUTH_CHUNK, /* Set only: add a chunk type to authenticat */ -#define SCTP_AUTH_CHUNK SCTP_AUTH_CHUNK - SCTP_HMAC_IDENT, -#define SCTP_HMAC_IDENT SCTP_HMAC_IDENT - SCTP_AUTH_KEY, -#define SCTP_AUTH_KEY SCTP_AUTH_KEY - SCTP_AUTH_ACTIVE_KEY, -#define SCTP_AUTH_ACTIVE_KEY SCTP_AUTH_ACTIVE_KEY - SCTP_AUTH_DELETE_KEY, -#define SCTP_AUTH_DELETE_KEY SCTP_AUTH_DELETE_KEY - SCTP_PEER_AUTH_CHUNKS, /* Read only */ -#define SCTP_PEER_AUTH_CHUNKS SCTP_PEER_AUTH_CHUNKS - SCTP_LOCAL_AUTH_CHUNKS, /* Read only */ -#define SCTP_LOCAL_AUTH_CHUNKS SCTP_LOCAL_AUTH_CHUNKS - SCTP_GET_ASSOC_NUMBER, /* Read only */ -#define SCTP_GET_ASSOC_NUMBER SCTP_GET_ASSOC_NUMBER - - - /* Internal Socket Options. Some of the sctp library functions are - * implemented using these socket options. - */ - SCTP_SOCKOPT_BINDX_ADD = 100,/* BINDX requests for adding addresses. */ -#define SCTP_SOCKOPT_BINDX_ADD SCTP_SOCKOPT_BINDX_ADD - SCTP_SOCKOPT_BINDX_REM, /* BINDX requests for removing addresses. */ -#define SCTP_SOCKOPT_BINDX_REM SCTP_SOCKOPT_BINDX_REM - SCTP_SOCKOPT_PEELOFF, /* peel off association. */ -#define SCTP_SOCKOPT_PEELOFF SCTP_SOCKOPT_PEELOFF - SCTP_GET_PEER_ADDRS_NUM_OLD, /* Get number of peer addresss. */ -#define SCTP_GET_PEER_ADDRS_NUM_OLD SCTP_GET_PEER_ADDRS_NUM_OLD - SCTP_GET_PEER_ADDRS_OLD, /* Get all peer addresss. */ -#define SCTP_GET_PEER_ADDRS_OLD SCTP_GET_PEER_ADDRS_OLD - SCTP_GET_LOCAL_ADDRS_NUM_OLD, /* Get number of local addresss. */ -#define SCTP_GET_LOCAL_ADDRS_NUM_OLD SCTP_GET_LOCAL_ADDRS_NUM_OLD - SCTP_GET_LOCAL_ADDRS_OLD, /* Get all local addresss. */ -#define SCTP_GET_LOCAL_ADDRS_OLD SCTP_GET_LOCAL_ADDRS_OLD - SCTP_SOCKOPT_CONNECTX_OLD, /* CONNECTX old requests. */ -#define SCTP_SOCKOPT_CONNECTX_OLD SCTP_SOCKOPT_CONNECTX_OLD - SCTP_GET_PEER_ADDRS, /* Get all peer addresss. */ -#define SCTP_GET_PEER_ADDRS SCTP_GET_PEER_ADDRS - SCTP_GET_LOCAL_ADDRS, /* Get all local addresss. */ -#define SCTP_GET_LOCAL_ADDRS SCTP_GET_LOCAL_ADDRS - SCTP_SOCKOPT_CONNECTX, /* CONNECTX requests. */ -#define SCTP_SOCKOPT_CONNECTX SCTP_SOCKOPT_CONNECTX - SCTP_SOCKOPT_CONNECTX3, /* CONNECTX requests. (new implementation) */ -#define SCTP_SOCKOPT_CONNECTX3 SCTP_SOCKOPT_CONNECTX3 -}; +#define SCTP_RTOINFO 0 +#define SCTP_ASSOCINFO 1 +#define SCTP_INITMSG 2 +#define SCTP_NODELAY 3 /* Get/set nodelay option. */ +#define SCTP_AUTOCLOSE 4 +#define SCTP_SET_PEER_PRIMARY_ADDR 5 +#define SCTP_PRIMARY_ADDR 6 +#define SCTP_ADAPTATION_LAYER 7 +#define SCTP_DISABLE_FRAGMENTS 8 +#define SCTP_PEER_ADDR_PARAMS 9 +#define SCTP_DEFAULT_SEND_PARAM 10 +#define SCTP_EVENTS 11 +#define SCTP_I_WANT_MAPPED_V4_ADDR 12 /* Turn on/off mapped v4 addresses */ +#define SCTP_MAXSEG 13 /* Get/set maximum fragment. */ +#define SCTP_STATUS 14 +#define SCTP_GET_PEER_ADDR_INFO 15 +#define SCTP_DELAYED_ACK_TIME 16 +#define SCTP_DELAYED_ACK SCTP_DELAYED_ACK_TIME +#define SCTP_CONTEXT 17 +#define SCTP_FRAGMENT_INTERLEAVE 18 +#define SCTP_PARTIAL_DELIVERY_POINT 19 /* Set/Get partial delivery point */ +#define SCTP_MAX_BURST 20 /* Set/Get max burst */ +#define SCTP_AUTH_CHUNK 21 /* Set only: add a chunk type to authenticate */ +#define SCTP_HMAC_IDENT 22 +#define SCTP_AUTH_KEY 23 +#define SCTP_AUTH_ACTIVE_KEY 24 +#define SCTP_AUTH_DELETE_KEY 25 +#define SCTP_PEER_AUTH_CHUNKS 26 /* Read only */ +#define SCTP_LOCAL_AUTH_CHUNKS 27 /* Read only */ +#define SCTP_GET_ASSOC_NUMBER 28 /* Read only */ + +/* Internal Socket Options. Some of the sctp library functions are + * implemented using these socket options. + */ +#define SCTP_SOCKOPT_BINDX_ADD 100 /* BINDX requests for adding addrs */ +#define SCTP_SOCKOPT_BINDX_REM 101 /* BINDX requests for removing addrs. */ +#define SCTP_SOCKOPT_PEELOFF 102 /* peel off association. */ +/* Options 104-106 are deprecated and removed. Do not use this space */ +#define SCTP_SOCKOPT_CONNECTX_OLD 107 /* CONNECTX old requests. */ +#define SCTP_GET_PEER_ADDRS 108 /* Get all peer addresss. */ +#define SCTP_GET_LOCAL_ADDRS 109 /* Get all local addresss. */ +#define SCTP_SOCKOPT_CONNECTX 110 /* CONNECTX requests. */ +#define SCTP_SOCKOPT_CONNECTX3 111 /* CONNECTX requests (updated) */ /* * 5.2.1 SCTP Initiation Structure (SCTP_INIT) @@ -206,6 +159,7 @@ enum sctp_sinfo_flags { SCTP_UNORDERED = 1, /* Send/receive message unordered. */ SCTP_ADDR_OVER = 2, /* Override the primary destination. */ SCTP_ABORT=4, /* Send an ABORT message to the peer. */ + SCTP_SACK_IMMEDIATELY = 8, /* SACK should be sent without delay */ SCTP_EOF=MSG_FIN, /* Initiate graceful shutdown process. */ }; diff --git a/include/net/snmp.h b/include/net/snmp.h index 8c842e06bec8..692ee0061dc4 100644 --- a/include/net/snmp.h +++ b/include/net/snmp.h @@ -32,7 +32,7 @@ * - name of entries. */ struct snmp_mib { - char *name; + const char *name; int entry; }; @@ -129,52 +129,42 @@ struct linux_xfrm_mib { * nonlocked_atomic_inc() primitives -AK */ #define DEFINE_SNMP_STAT(type, name) \ - __typeof__(type) *name[2] + __typeof__(type) __percpu *name[2] #define DECLARE_SNMP_STAT(type, name) \ - extern __typeof__(type) *name[2] + extern __typeof__(type) __percpu *name[2] #define SNMP_STAT_BHPTR(name) (name[0]) #define SNMP_STAT_USRPTR(name) (name[1]) -#define SNMP_INC_STATS_BH(mib, field) \ - (per_cpu_ptr(mib[0], raw_smp_processor_id())->mibs[field]++) -#define SNMP_INC_STATS_USER(mib, field) \ - do { \ - per_cpu_ptr(mib[1], get_cpu())->mibs[field]++; \ - put_cpu(); \ - } while (0) -#define SNMP_INC_STATS(mib, field) \ - do { \ - per_cpu_ptr(mib[!in_softirq()], get_cpu())->mibs[field]++; \ - put_cpu(); \ - } while (0) -#define SNMP_DEC_STATS(mib, field) \ - do { \ - per_cpu_ptr(mib[!in_softirq()], get_cpu())->mibs[field]--; \ - put_cpu(); \ - } while (0) -#define SNMP_ADD_STATS(mib, field, addend) \ - do { \ - per_cpu_ptr(mib[!in_softirq()], get_cpu())->mibs[field] += addend; \ - put_cpu(); \ - } while (0) -#define SNMP_ADD_STATS_BH(mib, field, addend) \ - (per_cpu_ptr(mib[0], raw_smp_processor_id())->mibs[field] += addend) -#define SNMP_ADD_STATS_USER(mib, field, addend) \ - do { \ - per_cpu_ptr(mib[1], get_cpu())->mibs[field] += addend; \ - put_cpu(); \ - } while (0) +#define SNMP_INC_STATS_BH(mib, field) \ + __this_cpu_inc(mib[0]->mibs[field]) +#define SNMP_INC_STATS_USER(mib, field) \ + this_cpu_inc(mib[1]->mibs[field]) +#define SNMP_INC_STATS(mib, field) \ + this_cpu_inc(mib[!in_softirq()]->mibs[field]) +#define SNMP_DEC_STATS(mib, field) \ + this_cpu_dec(mib[!in_softirq()]->mibs[field]) +#define SNMP_ADD_STATS_BH(mib, field, addend) \ + __this_cpu_add(mib[0]->mibs[field], addend) +#define SNMP_ADD_STATS_USER(mib, field, addend) \ + this_cpu_add(mib[1]->mibs[field], addend) +/* + * Use "__typeof__(*mib[0]) *ptr" instead of "__typeof__(mib[0]) ptr" + * to make @ptr a non-percpu pointer. + */ #define SNMP_UPD_PO_STATS(mib, basefield, addend) \ do { \ - __typeof__(mib[0]) ptr = per_cpu_ptr(mib[!in_softirq()], get_cpu());\ + __typeof__(*mib[0]) *ptr; \ + preempt_disable(); \ + ptr = this_cpu_ptr((mib)[!in_softirq()]); \ ptr->mibs[basefield##PKTS]++; \ ptr->mibs[basefield##OCTETS] += addend;\ - put_cpu(); \ + preempt_enable(); \ } while (0) #define SNMP_UPD_PO_STATS_BH(mib, basefield, addend) \ do { \ - __typeof__(mib[0]) ptr = per_cpu_ptr(mib[!in_softirq()], raw_smp_processor_id());\ + __typeof__(*mib[0]) *ptr = \ + __this_cpu_ptr((mib)[!in_softirq()]); \ ptr->mibs[basefield##PKTS]++; \ ptr->mibs[basefield##OCTETS] += addend;\ } while (0) diff --git a/include/net/sock.h b/include/net/sock.h index 950409dcec3d..092b0551e77f 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -105,14 +105,17 @@ struct net; /** * struct sock_common - minimal network layer representation of sockets * @skc_node: main hash linkage for various protocol lookup tables - * @skc_nulls_node: main hash linkage for UDP/UDP-Lite protocol + * @skc_nulls_node: main hash linkage for TCP/UDP/UDP-Lite protocol * @skc_refcnt: reference count + * @skc_tx_queue_mapping: tx queue number for this connection * @skc_hash: hash value used with various protocol lookup tables + * @skc_u16hashes: two u16 hash values used by UDP lookup tables * @skc_family: network address family * @skc_state: Connection state * @skc_reuse: %SO_REUSEADDR setting * @skc_bound_dev_if: bound device index if != 0 * @skc_bind_node: bind hash linkage for various protocol lookup tables + * @skc_portaddr_node: second hash linkage for UDP/UDP-Lite protocol * @skc_prot: protocol handlers inside a network family * @skc_net: reference to the network namespace of this socket * @@ -128,13 +131,20 @@ struct sock_common { struct hlist_nulls_node skc_nulls_node; }; atomic_t skc_refcnt; + int skc_tx_queue_mapping; - unsigned int skc_hash; + union { + unsigned int skc_hash; + __u16 skc_u16hashes[2]; + }; unsigned short skc_family; volatile unsigned char skc_state; unsigned char skc_reuse; int skc_bound_dev_if; - struct hlist_node skc_bind_node; + union { + struct hlist_node skc_bind_node; + struct hlist_nulls_node skc_portaddr_node; + }; struct proto *skc_prot; #ifdef CONFIG_NET_NS struct net *skc_net; @@ -215,6 +225,7 @@ struct sock { #define sk_node __sk_common.skc_node #define sk_nulls_node __sk_common.skc_nulls_node #define sk_refcnt __sk_common.skc_refcnt +#define sk_tx_queue_mapping __sk_common.skc_tx_queue_mapping #define sk_copy_start __sk_common.skc_hash #define sk_hash __sk_common.skc_hash @@ -226,12 +237,12 @@ struct sock { #define sk_prot __sk_common.skc_prot #define sk_net __sk_common.skc_net kmemcheck_bitfield_begin(flags); - unsigned char sk_shutdown : 2, - sk_no_check : 2, - sk_userlocks : 4; + unsigned int sk_shutdown : 2, + sk_no_check : 2, + sk_userlocks : 4, + sk_protocol : 8, + sk_type : 16; kmemcheck_bitfield_end(flags); - unsigned char sk_protocol; - unsigned short sk_type; int sk_rcvbuf; socket_lock_t sk_lock; /* @@ -242,6 +253,8 @@ struct sock { struct { struct sk_buff *head; struct sk_buff *tail; + int len; + int limit; } sk_backlog; wait_queue_head_t *sk_sleep; struct dst_entry *sk_dst_cache; @@ -306,6 +319,11 @@ struct sock { /* * Hashed lists helper routines */ +static inline struct sock *sk_entry(const struct hlist_node *node) +{ + return hlist_entry(node, struct sock, sk_node); +} + static inline struct sock *__sk_head(const struct hlist_head *head) { return hlist_entry(head->first, struct sock, sk_node); @@ -365,6 +383,7 @@ static __inline__ void __sk_del_node(struct sock *sk) __hlist_del(&sk->sk_node); } +/* NB: equivalent to hlist_del_init_rcu */ static __inline__ int __sk_del_node_init(struct sock *sk) { if (sk_hashed(sk)) { @@ -405,6 +424,7 @@ static __inline__ int sk_del_node_init(struct sock *sk) } return rc; } +#define sk_del_node_init_rcu(sk) sk_del_node_init(sk) static __inline__ int __sk_nulls_del_node_init_rcu(struct sock *sk) { @@ -438,6 +458,12 @@ static __inline__ void sk_add_node(struct sock *sk, struct hlist_head *list) __sk_add_node(sk, list); } +static __inline__ void sk_add_node_rcu(struct sock *sk, struct hlist_head *list) +{ + sock_hold(sk); + hlist_add_head_rcu(&sk->sk_node, list); +} + static __inline__ void __sk_nulls_add_node_rcu(struct sock *sk, struct hlist_nulls_head *list) { hlist_nulls_add_head_rcu(&sk->sk_nulls_node, list); @@ -462,6 +488,8 @@ static __inline__ void sk_add_bind_node(struct sock *sk, #define sk_for_each(__sk, node, list) \ hlist_for_each_entry(__sk, node, list, sk_node) +#define sk_for_each_rcu(__sk, node, list) \ + hlist_for_each_entry_rcu(__sk, node, list, sk_node) #define sk_nulls_for_each(__sk, node, list) \ hlist_nulls_for_each_entry(__sk, node, list, sk_nulls_node) #define sk_nulls_for_each_rcu(__sk, node, list) \ @@ -504,6 +532,8 @@ enum sock_flags { SOCK_TIMESTAMPING_SOFTWARE, /* %SOF_TIMESTAMPING_SOFTWARE */ SOCK_TIMESTAMPING_RAW_HARDWARE, /* %SOF_TIMESTAMPING_RAW_HARDWARE */ SOCK_TIMESTAMPING_SYS_HARDWARE, /* %SOF_TIMESTAMPING_SYS_HARDWARE */ + SOCK_FASYNC, /* fasync() active */ + SOCK_RXQ_OVFL, }; static inline void sock_copy_flags(struct sock *nsk, struct sock *osk) @@ -561,8 +591,8 @@ static inline int sk_stream_memory_free(struct sock *sk) return sk->sk_wmem_queued < sk->sk_sndbuf; } -/* The per-socket spinlock must be held here. */ -static inline void sk_add_backlog(struct sock *sk, struct sk_buff *skb) +/* OOB backlog add */ +static inline void __sk_add_backlog(struct sock *sk, struct sk_buff *skb) { if (!sk->sk_backlog.tail) { sk->sk_backlog.head = sk->sk_backlog.tail = skb; @@ -573,6 +603,17 @@ static inline void sk_add_backlog(struct sock *sk, struct sk_buff *skb) skb->next = NULL; } +/* The per-socket spinlock must be held here. */ +static inline __must_check int sk_add_backlog(struct sock *sk, struct sk_buff *skb) +{ + if (sk->sk_backlog.len >= max(sk->sk_backlog.limit, sk->sk_rcvbuf << 1)) + return -ENOBUFS; + + __sk_add_backlog(sk, skb); + sk->sk_backlog.len += skb->truesize; + return 0; +} + static inline int sk_backlog_rcv(struct sock *sk, struct sk_buff *skb) { return sk->sk_backlog_rcv(sk, skb); @@ -624,7 +665,7 @@ struct proto { void (*shutdown)(struct sock *sk, int how); int (*setsockopt)(struct sock *sk, int level, int optname, char __user *optval, - int optlen); + unsigned int optlen); int (*getsockopt)(struct sock *sk, int level, int optname, char __user *optval, int __user *option); @@ -632,7 +673,7 @@ struct proto { int (*compat_setsockopt)(struct sock *sk, int level, int optname, char __user *optval, - int optlen); + unsigned int optlen); int (*compat_getsockopt)(struct sock *sk, int level, int optname, char __user *optval, @@ -951,7 +992,7 @@ extern void sock_rfree(struct sk_buff *skb); extern int sock_setsockopt(struct socket *sock, int level, int op, char __user *optval, - int optlen); + unsigned int optlen); extern int sock_getsockopt(struct socket *sock, int level, int op, char __user *optval, @@ -993,7 +1034,7 @@ extern int sock_no_shutdown(struct socket *, int); extern int sock_no_getsockopt(struct socket *, int , int, char __user *, int __user *); extern int sock_no_setsockopt(struct socket *, int, int, - char __user *, int); + char __user *, unsigned int); extern int sock_no_sendmsg(struct kiocb *, struct socket *, struct msghdr *, size_t); extern int sock_no_recvmsg(struct kiocb *, struct socket *, @@ -1015,11 +1056,11 @@ extern int sock_common_getsockopt(struct socket *sock, int level, int optname, extern int sock_common_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t size, int flags); extern int sock_common_setsockopt(struct socket *sock, int level, int optname, - char __user *optval, int optlen); + char __user *optval, unsigned int optlen); extern int compat_sock_common_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen); extern int compat_sock_common_setsockopt(struct socket *sock, int level, - int optname, char __user *optval, int optlen); + int optname, char __user *optval, unsigned int optlen); extern void sk_common_release(struct sock *sk); @@ -1031,7 +1072,7 @@ extern void sk_common_release(struct sock *sk); extern void sock_init_data(struct socket *sock, struct sock *sk); /** - * sk_filter_release: Release a socket filter + * sk_filter_release - release a socket filter * @fp: filter to remove * * Remove a filter from a socket and release its resources. @@ -1092,8 +1133,29 @@ static inline void sock_put(struct sock *sk) extern int sk_receive_skb(struct sock *sk, struct sk_buff *skb, const int nested); +static inline void sk_tx_queue_set(struct sock *sk, int tx_queue) +{ + sk->sk_tx_queue_mapping = tx_queue; +} + +static inline void sk_tx_queue_clear(struct sock *sk) +{ + sk->sk_tx_queue_mapping = -1; +} + +static inline int sk_tx_queue_get(const struct sock *sk) +{ + return sk->sk_tx_queue_mapping; +} + +static inline bool sk_tx_queue_recorded(const struct sock *sk) +{ + return (sk && sk->sk_tx_queue_mapping >= 0); +} + static inline void sk_set_socket(struct sock *sk, struct socket *sock) { + sk_tx_queue_clear(sk); sk->sk_socket = sock; } @@ -1150,6 +1212,7 @@ __sk_dst_set(struct sock *sk, struct dst_entry *dst) { struct dst_entry *old_dst; + sk_tx_queue_clear(sk); old_dst = sk->sk_dst_cache; sk->sk_dst_cache = dst; dst_release(old_dst); @@ -1168,6 +1231,7 @@ __sk_dst_reset(struct sock *sk) { struct dst_entry *old_dst; + sk_tx_queue_clear(sk); old_dst = sk->sk_dst_cache; sk->sk_dst_cache = NULL; dst_release(old_dst); @@ -1396,7 +1460,7 @@ static inline unsigned long sock_wspace(struct sock *sk) static inline void sk_wake_async(struct sock *sk, int how, int band) { - if (sk->sk_socket && sk->sk_socket->fasync_list) + if (sock_flag(sk, SOCK_FASYNC)) sock_wake_async(sk->sk_socket, how, band); } @@ -1492,6 +1556,8 @@ sock_recv_timestamp(struct msghdr *msg, struct sock *sk, struct sk_buff *skb) sk->sk_stamp = kt; } +extern void sock_recv_ts_and_drops(struct msghdr *msg, struct sock *sk, struct sk_buff *skb); + /** * sock_tx_timestamp - checks whether the outgoing packet is to be time stamped * @msg: outgoing packet diff --git a/include/net/tc_act/tc_skbedit.h b/include/net/tc_act/tc_skbedit.h index 6abb3ed3ebf7..e103fe02f375 100644 --- a/include/net/tc_act/tc_skbedit.h +++ b/include/net/tc_act/tc_skbedit.h @@ -26,7 +26,9 @@ struct tcf_skbedit { struct tcf_common common; u32 flags; u32 priority; + u32 mark; u16 queue_mapping; + /* XXX: 16-bit pad here? */ }; #define to_skbedit(pc) \ container_of(pc, struct tcf_skbedit, common) diff --git a/include/net/tcp.h b/include/net/tcp.h index 56b76027b85e..75be5a28815d 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -30,6 +30,7 @@ #include <linux/dmaengine.h> #include <linux/crypto.h> #include <linux/cryptohash.h> +#include <linux/kref.h> #include <net/inet_connection_sock.h> #include <net/inet_timewait_sock.h> @@ -62,9 +63,6 @@ extern void tcp_time_wait(struct sock *sk, int state, int timeo); /* Minimal accepted MSS. It is (60+60+8) - (20+20). */ #define TCP_MIN_MSS 88U -/* Minimal RCV_MSS. */ -#define TCP_MIN_RCVMSS 536U - /* The least MTU to use for probing */ #define TCP_BASE_MSS 512 @@ -167,6 +165,7 @@ extern void tcp_time_wait(struct sock *sk, int state, int timeo); #define TCPOPT_SACK 5 /* SACK Block */ #define TCPOPT_TIMESTAMP 8 /* Better RTT estimations/PAWS */ #define TCPOPT_MD5SIG 19 /* MD5 Signature (RFC2385) */ +#define TCPOPT_COOKIE 253 /* Cookie extension (experimental) */ /* * TCP option lengths @@ -177,6 +176,10 @@ extern void tcp_time_wait(struct sock *sk, int state, int timeo); #define TCPOLEN_SACK_PERM 2 #define TCPOLEN_TIMESTAMP 10 #define TCPOLEN_MD5SIG 18 +#define TCPOLEN_COOKIE_BASE 2 /* Cookie-less header extension */ +#define TCPOLEN_COOKIE_PAIR 3 /* Cookie pair header extension */ +#define TCPOLEN_COOKIE_MIN (TCPOLEN_COOKIE_BASE+TCP_COOKIE_MIN) +#define TCPOLEN_COOKIE_MAX (TCPOLEN_COOKIE_BASE+TCP_COOKIE_MAX) /* But this is what stacks really send out. */ #define TCPOLEN_TSTAMP_ALIGNED 12 @@ -193,6 +196,9 @@ extern void tcp_time_wait(struct sock *sk, int state, int timeo); #define TCP_NAGLE_CORK 2 /* Socket is corked */ #define TCP_NAGLE_PUSH 4 /* Cork is overridden for already queued data */ +/* TCP thin-stream limits */ +#define TCP_THIN_LINEAR_RETRIES 6 /* After 6 linear retries, do exp. backoff */ + extern struct inet_timewait_death_row tcp_death_row; /* sysctl variables for tcp */ @@ -237,6 +243,9 @@ extern int sysctl_tcp_base_mss; extern int sysctl_tcp_workaround_signed_windows; extern int sysctl_tcp_slow_start_after_idle; extern int sysctl_tcp_max_ssthresh; +extern int sysctl_tcp_cookie_size; +extern int sysctl_tcp_thin_linear_timeouts; +extern int sysctl_tcp_thin_dupack; extern atomic_t tcp_memory_allocated; extern struct percpu_counter tcp_sockets_allocated; @@ -343,11 +352,6 @@ static inline void tcp_dec_quickack_mode(struct sock *sk, extern void tcp_enter_quickack_mode(struct sock *sk); -static inline void tcp_clear_options(struct tcp_options_received *rx_opt) -{ - rx_opt->tstamp_ok = rx_opt->sack_ok = rx_opt->wscale_ok = rx_opt->snd_wscale = 0; -} - #define TCP_ECN_OK 1 #define TCP_ECN_QUEUE_CWR 2 #define TCP_ECN_DEMAND_CWR 4 @@ -359,8 +363,7 @@ TCP_ECN_create_request(struct request_sock *req, struct tcphdr *th) inet_rsk(req)->ecn_ok = 1; } -enum tcp_tw_status -{ +enum tcp_tw_status { TCP_TW_SUCCESS = 0, TCP_TW_RST = 1, TCP_TW_ACK = 2, @@ -394,14 +397,16 @@ extern int tcp_getsockopt(struct sock *sk, int level, int __user *optlen); extern int tcp_setsockopt(struct sock *sk, int level, int optname, char __user *optval, - int optlen); + unsigned int optlen); extern int compat_tcp_getsockopt(struct sock *sk, int level, int optname, char __user *optval, int __user *optlen); extern int compat_tcp_setsockopt(struct sock *sk, int level, int optname, - char __user *optval, int optlen); + char __user *optval, unsigned int optlen); extern void tcp_set_keepalive(struct sock *sk, int val); +extern void tcp_syn_ack_timeout(struct sock *sk, + struct request_sock *req); extern int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, size_t len, int nonblock, @@ -409,6 +414,7 @@ extern int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, extern void tcp_parse_options(struct sk_buff *skb, struct tcp_options_received *opt_rx, + u8 **hvpp, int estab); extern u8 *tcp_parse_md5sig_option(struct tcphdr *th); @@ -443,7 +449,8 @@ extern int tcp_connect(struct sock *sk); extern struct sk_buff * tcp_make_synack(struct sock *sk, struct dst_entry *dst, - struct request_sock *req); + struct request_sock *req, + struct request_values *rvp); extern int tcp_disconnect(struct sock *sk, int flags); @@ -856,13 +863,6 @@ static inline void tcp_check_probe_timer(struct sock *sk) icsk->icsk_rto, TCP_RTO_MAX); } -static inline void tcp_push_pending_frames(struct sock *sk) -{ - struct tcp_sock *tp = tcp_sk(sk); - - __tcp_push_pending_frames(sk, tcp_current_mss(sk), tp->nonagle); -} - static inline void tcp_init_wl(struct tcp_sock *tp, u32 seq) { tp->snd_wl1 = seq; @@ -939,7 +939,7 @@ static inline int tcp_prequeue(struct sock *sk, struct sk_buff *skb) tp->ucopy.memory = 0; } else if (skb_queue_len(&tp->ucopy.prequeue) == 1) { - wake_up_interruptible_poll(sk->sk_sleep, + wake_up_interruptible_sync_poll(sk->sk_sleep, POLLIN | POLLRDNORM | POLLRDBAND); if (!inet_csk_ack_scheduled(sk)) inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK, @@ -972,7 +972,8 @@ static inline void tcp_sack_reset(struct tcp_options_received *rx_opt) /* Determine a window scaling and initial window to offer. */ extern void tcp_select_initial_window(int __space, __u32 mss, __u32 *rcv_wnd, __u32 *window_clamp, - int wscale_ok, __u8 *rcv_wscale); + int wscale_ok, __u8 *rcv_wscale, + __u32 init_rcv_wnd); static inline int tcp_win_from_space(int space) { @@ -1193,7 +1194,7 @@ extern int tcp_v4_md5_do_del(struct sock *sk, #define tcp_twsk_md5_key(twsk) NULL #endif -extern struct tcp_md5sig_pool **tcp_alloc_md5sig_pool(struct sock *); +extern struct tcp_md5sig_pool * __percpu *tcp_alloc_md5sig_pool(struct sock *); extern void tcp_free_md5sig_pool(void); extern struct tcp_md5sig_pool *__tcp_get_md5sig_pool(int cpu); @@ -1228,6 +1229,7 @@ static inline void tcp_write_queue_purge(struct sock *sk) while ((skb = __skb_dequeue(&sk->sk_write_queue)) != NULL) sk_wmem_free_skb(sk, skb); sk_mem_reclaim(sk); + tcp_clear_all_retrans_hints(tcp_sk(sk)); } static inline struct sk_buff *tcp_write_queue_head(struct sock *sk) @@ -1259,29 +1261,6 @@ static inline struct sk_buff *tcp_write_queue_prev(struct sock *sk, struct sk_bu #define tcp_for_write_queue_from_safe(skb, tmp, sk) \ skb_queue_walk_from_safe(&(sk)->sk_write_queue, skb, tmp) -/* This function calculates a "timeout" which is equivalent to the timeout of a - * TCP connection after "boundary" unsucessful, exponentially backed-off - * retransmissions with an initial RTO of TCP_RTO_MIN. - */ -static inline bool retransmits_timed_out(const struct sock *sk, - unsigned int boundary) -{ - unsigned int timeout, linear_backoff_thresh; - - if (!inet_csk(sk)->icsk_retransmits) - return false; - - linear_backoff_thresh = ilog2(TCP_RTO_MAX/TCP_RTO_MIN); - - if (boundary <= linear_backoff_thresh) - timeout = ((2 << boundary) - 1) * TCP_RTO_MIN; - else - timeout = ((2 << linear_backoff_thresh) - 1) * TCP_RTO_MIN + - (boundary - linear_backoff_thresh) * TCP_RTO_MAX; - - return (tcp_time_stamp - tcp_sk(sk)->retrans_stamp) >= timeout; -} - static inline struct sk_buff *tcp_send_head(struct sock *sk) { return sk->sk_send_head; @@ -1364,6 +1343,15 @@ static inline int tcp_write_queue_empty(struct sock *sk) return skb_queue_empty(&sk->sk_write_queue); } +static inline void tcp_push_pending_frames(struct sock *sk) +{ + if (tcp_send_head(sk)) { + struct tcp_sock *tp = tcp_sk(sk); + + __tcp_push_pending_frames(sk, tcp_current_mss(sk), tp->nonagle); + } +} + /* Start sequence of the highest skb with SACKed bit, valid only if * sacked > 0 or when the caller has ensured validity by itself. */ @@ -1403,6 +1391,14 @@ static inline void tcp_highest_sack_combine(struct sock *sk, tcp_sk(sk)->highest_sack = new; } +/* Determines whether this is a thin stream (which may suffer from + * increased latency). Used to trigger latency-reducing mechanisms. + */ +static inline unsigned int tcp_stream_is_thin(struct tcp_sock *tp) +{ + return tp->packets_out < 4 && !tcp_in_initial_slowstart(tp); +} + /* /proc */ enum tcp_seq_states { TCP_SEQ_STATE_LISTENING, @@ -1480,6 +1476,91 @@ struct tcp_request_sock_ops { #endif }; +/* Using SHA1 for now, define some constants. + */ +#define COOKIE_DIGEST_WORDS (SHA_DIGEST_WORDS) +#define COOKIE_MESSAGE_WORDS (SHA_MESSAGE_BYTES / 4) +#define COOKIE_WORKSPACE_WORDS (COOKIE_DIGEST_WORDS + COOKIE_MESSAGE_WORDS) + +extern int tcp_cookie_generator(u32 *bakery); + +/** + * struct tcp_cookie_values - each socket needs extra space for the + * cookies, together with (optional) space for any SYN data. + * + * A tcp_sock contains a pointer to the current value, and this is + * cloned to the tcp_timewait_sock. + * + * @cookie_pair: variable data from the option exchange. + * + * @cookie_desired: user specified tcpct_cookie_desired. Zero + * indicates default (sysctl_tcp_cookie_size). + * After cookie sent, remembers size of cookie. + * Range 0, TCP_COOKIE_MIN to TCP_COOKIE_MAX. + * + * @s_data_desired: user specified tcpct_s_data_desired. When the + * constant payload is specified (@s_data_constant), + * holds its length instead. + * Range 0 to TCP_MSS_DESIRED. + * + * @s_data_payload: constant data that is to be included in the + * payload of SYN or SYNACK segments when the + * cookie option is present. + */ +struct tcp_cookie_values { + struct kref kref; + u8 cookie_pair[TCP_COOKIE_PAIR_SIZE]; + u8 cookie_pair_size; + u8 cookie_desired; + u16 s_data_desired:11, + s_data_constant:1, + s_data_in:1, + s_data_out:1, + s_data_unused:2; + u8 s_data_payload[0]; +}; + +static inline void tcp_cookie_values_release(struct kref *kref) +{ + kfree(container_of(kref, struct tcp_cookie_values, kref)); +} + +/* The length of constant payload data. Note that s_data_desired is + * overloaded, depending on s_data_constant: either the length of constant + * data (returned here) or the limit on variable data. + */ +static inline int tcp_s_data_size(const struct tcp_sock *tp) +{ + return (tp->cookie_values != NULL && tp->cookie_values->s_data_constant) + ? tp->cookie_values->s_data_desired + : 0; +} + +/** + * struct tcp_extend_values - tcp_ipv?.c to tcp_output.c workspace. + * + * As tcp_request_sock has already been extended in other places, the + * only remaining method is to pass stack values along as function + * parameters. These parameters are not needed after sending SYNACK. + * + * @cookie_bakery: cryptographic secret and message workspace. + * + * @cookie_plus: bytes in authenticator/cookie option, copied from + * struct tcp_options_received (above). + */ +struct tcp_extend_values { + struct request_values rv; + u32 cookie_bakery[COOKIE_WORKSPACE_WORDS]; + u8 cookie_plus:6, + cookie_out_never:1, + cookie_in_always:1; +}; + +static inline struct tcp_extend_values *tcp_xv(struct request_values *rvp) +{ + return (struct tcp_extend_values *)rvp; +} + extern void tcp_v4_init(void); extern void tcp_init(void); diff --git a/include/net/udp.h b/include/net/udp.h index 5fb029f817a3..5348d80b25bb 100644 --- a/include/net/udp.h +++ b/include/net/udp.h @@ -50,16 +50,49 @@ struct udp_skb_cb { }; #define UDP_SKB_CB(__skb) ((struct udp_skb_cb *)((__skb)->cb)) +/** + * struct udp_hslot - UDP hash slot + * + * @head: head of list of sockets + * @count: number of sockets in 'head' list + * @lock: spinlock protecting changes to head/count + */ struct udp_hslot { struct hlist_nulls_head head; + int count; spinlock_t lock; } __attribute__((aligned(2 * sizeof(long)))); + +/** + * struct udp_table - UDP table + * + * @hash: hash table, sockets are hashed on (local port) + * @hash2: hash table, sockets are hashed on (local port, local address) + * @mask: number of slots in hash tables, minus 1 + * @log: log2(number of slots in hash table) + */ struct udp_table { - struct udp_hslot hash[UDP_HTABLE_SIZE]; + struct udp_hslot *hash; + struct udp_hslot *hash2; + unsigned int mask; + unsigned int log; }; extern struct udp_table udp_table; -extern void udp_table_init(struct udp_table *); - +extern void udp_table_init(struct udp_table *, const char *); +static inline struct udp_hslot *udp_hashslot(struct udp_table *table, + struct net *net, unsigned num) +{ + return &table->hash[udp_hashfn(net, num, table->mask)]; +} +/* + * For secondary hash, net_hash_mix() is performed before calling + * udp_hashslot2(), this explains difference with udp_hashslot() + */ +static inline struct udp_hslot *udp_hashslot2(struct udp_table *table, + unsigned int hash) +{ + return &table->hash2[hash & table->mask]; +} /* Note: this must match 'valbool' in sock_setsockopt */ #define UDP_CSUM_NOXMIT 1 @@ -125,7 +158,8 @@ static inline void udp_lib_close(struct sock *sk, long timeout) } extern int udp_lib_get_port(struct sock *sk, unsigned short snum, - int (*)(const struct sock*,const struct sock*)); + int (*)(const struct sock *,const struct sock *), + unsigned int hash2_nulladdr); /* net/ipv4/udp.c */ extern int udp_get_port(struct sock *sk, unsigned short snum, @@ -144,7 +178,7 @@ extern unsigned int udp_poll(struct file *file, struct socket *sock, extern int udp_lib_getsockopt(struct sock *sk, int level, int optname, char __user *optval, int __user *optlen); extern int udp_lib_setsockopt(struct sock *sk, int level, int optname, - char __user *optval, int optlen, + char __user *optval, unsigned int optlen, int (*push_pending_frames)(struct sock *)); extern struct sock *udp4_lib_lookup(struct net *net, __be32 saddr, __be16 sport, diff --git a/include/net/wext.h b/include/net/wext.h index 6d76a39a9c5b..4f6e7423174c 100644 --- a/include/net/wext.h +++ b/include/net/wext.h @@ -1,28 +1,19 @@ #ifndef __NET_WEXT_H #define __NET_WEXT_H -/* - * wireless extensions interface to the core code - */ +#include <net/iw_handler.h> struct net; -#ifdef CONFIG_WIRELESS_EXT -extern int wext_proc_init(struct net *net); -extern void wext_proc_exit(struct net *net); +#ifdef CONFIG_WEXT_CORE extern int wext_handle_ioctl(struct net *net, struct ifreq *ifr, unsigned int cmd, void __user *arg); extern int compat_wext_handle_ioctl(struct net *net, unsigned int cmd, unsigned long arg); + +extern struct iw_statistics *get_wireless_stats(struct net_device *dev); +extern int call_commit_handler(struct net_device *dev); #else -static inline int wext_proc_init(struct net *net) -{ - return 0; -} -static inline void wext_proc_exit(struct net *net) -{ - return; -} static inline int wext_handle_ioctl(struct net *net, struct ifreq *ifr, unsigned int cmd, void __user *arg) { @@ -35,4 +26,35 @@ static inline int compat_wext_handle_ioctl(struct net *net, unsigned int cmd, } #endif +#ifdef CONFIG_WEXT_PROC +extern int wext_proc_init(struct net *net); +extern void wext_proc_exit(struct net *net); +#else +static inline int wext_proc_init(struct net *net) +{ + return 0; +} +static inline void wext_proc_exit(struct net *net) +{ + return; +} +#endif + +#ifdef CONFIG_WEXT_PRIV +int ioctl_private_call(struct net_device *dev, struct iwreq *iwr, + unsigned int cmd, struct iw_request_info *info, + iw_handler handler); +int compat_private_call(struct net_device *dev, struct iwreq *iwr, + unsigned int cmd, struct iw_request_info *info, + iw_handler handler); +int iw_handler_get_private(struct net_device * dev, + struct iw_request_info * info, + union iwreq_data * wrqu, + char * extra); +#else +#define ioctl_private_call NULL +#define compat_private_call NULL +#endif + + #endif /* __NET_WEXT_H */ diff --git a/include/net/wimax.h b/include/net/wimax.h index 2af7bf839f23..3461aa1df1e0 100644 --- a/include/net/wimax.h +++ b/include/net/wimax.h @@ -79,7 +79,7 @@ * drivers have to only report state changes due to external * conditions. * - * All API operations are 'atomic', serialized thorough a mutex in the + * All API operations are 'atomic', serialized through a mutex in the * `struct wimax_dev`. * * EXPORTING TO USER SPACE THROUGH GENERIC NETLINK @@ -195,6 +195,12 @@ * defining the `struct nla_policy` for each message, it has to have * an array size of WIMAX_GNL_ATTR_MAX+1. * + * The op_*() function pointers will not be called if the wimax_dev is + * in a state <= %WIMAX_ST_UNINITIALIZED. The exception is: + * + * - op_reset: can be called at any time after wimax_dev_add() has + * been called. + * * THE PIPE INTERFACE: * * This interface is kept intentionally simple. The driver can send diff --git a/include/net/wpan-phy.h b/include/net/wpan-phy.h index 547b1e271ac9..85926231c07a 100644 --- a/include/net/wpan-phy.h +++ b/include/net/wpan-phy.h @@ -34,20 +34,32 @@ struct wpan_phy { */ u8 current_channel; u8 current_page; - u32 channels_supported; + u32 channels_supported[32]; u8 transmit_power; u8 cca_mode; struct device dev; int idx; + struct net_device *(*add_iface)(struct wpan_phy *phy, + const char *name); + void (*del_iface)(struct wpan_phy *phy, struct net_device *dev); + char priv[0] __attribute__((__aligned__(NETDEV_ALIGN))); }; +#define to_phy(_dev) container_of(_dev, struct wpan_phy, dev) + struct wpan_phy *wpan_phy_alloc(size_t priv_size); -int wpan_phy_register(struct device *parent, struct wpan_phy *phy); +static inline void wpan_phy_set_dev(struct wpan_phy *phy, struct device *dev) +{ + phy->dev.parent = dev; +} +int wpan_phy_register(struct wpan_phy *phy); void wpan_phy_unregister(struct wpan_phy *phy); void wpan_phy_free(struct wpan_phy *phy); +/* Same semantics as for class_for_each_device */ +int wpan_phy_for_each(int (*fn)(struct wpan_phy *phy, void *data), void *data); static inline void *wpan_phy_priv(struct wpan_phy *phy) { @@ -56,6 +68,12 @@ static inline void *wpan_phy_priv(struct wpan_phy *phy) } struct wpan_phy *wpan_phy_find(const char *str); + +static inline void wpan_phy_put(struct wpan_phy *phy) +{ + put_device(&phy->dev); +} + static inline const char *wpan_phy_name(struct wpan_phy *phy) { return dev_name(&phy->dev); diff --git a/include/net/x25.h b/include/net/x25.h index 2cda04011568..9baa07dc7d17 100644 --- a/include/net/x25.h +++ b/include/net/x25.h @@ -287,8 +287,14 @@ extern unsigned long x25_display_timer(struct sock *); extern void x25_check_rbuf(struct sock *); /* sysctl_net_x25.c */ +#ifdef CONFIG_SYSCTL extern void x25_register_sysctl(void); extern void x25_unregister_sysctl(void); +#else +static inline void x25_register_sysctl(void) {}; +static inline void x25_unregister_sysctl(void) {}; +#endif /* CONFIG_SYSCTL */ + struct x25_skb_cb { unsigned flags; }; diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 223e90a44824..d74e080ba6c9 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -19,6 +19,9 @@ #include <net/route.h> #include <net/ipv6.h> #include <net/ip6_fib.h> + +#include <linux/interrupt.h> + #ifdef CONFIG_XFRM_STATISTICS #include <net/snmp.h> #endif @@ -121,8 +124,7 @@ struct xfrm_state_walk { }; /* Full description of state of transformer. */ -struct xfrm_state -{ +struct xfrm_state { #ifdef CONFIG_NET_NS struct net *xs_net; #endif @@ -138,6 +140,7 @@ struct xfrm_state struct xfrm_id id; struct xfrm_selector sel; + struct xfrm_mark mark; u32 genid; @@ -160,7 +163,7 @@ struct xfrm_state struct xfrm_lifetime_cfg lft; /* Data for transformer */ - struct xfrm_algo *aalg; + struct xfrm_algo_auth *aalg; struct xfrm_algo *ealg; struct xfrm_algo *calg; struct xfrm_algo_aead *aead; @@ -199,7 +202,7 @@ struct xfrm_state struct xfrm_stats stats; struct xfrm_lifetime_cur curlft; - struct timer_list timer; + struct tasklet_hrtimer mtimer; /* Last used time */ unsigned long lastused; @@ -237,8 +240,7 @@ enum { }; /* callback structure passed from either netlink or pfkey */ -struct km_event -{ +struct km_event { union { u32 hard; u32 proto; @@ -273,7 +275,8 @@ struct xfrm_policy_afinfo { struct dst_entry *dst, int nfheader_len); int (*fill_dst)(struct xfrm_dst *xdst, - struct net_device *dev); + struct net_device *dev, + struct flowi *fl); }; extern int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo); @@ -313,12 +316,11 @@ extern int xfrm_state_unregister_afinfo(struct xfrm_state_afinfo *afinfo); extern void xfrm_state_delete_tunnel(struct xfrm_state *x); -struct xfrm_type -{ +struct xfrm_type { char *description; struct module *owner; - __u8 proto; - __u8 flags; + u8 proto; + u8 flags; #define XFRM_TYPE_NON_FRAGMENT 1 #define XFRM_TYPE_REPLAY_PROT 2 #define XFRM_TYPE_LOCAL_COADDR 4 @@ -420,8 +422,7 @@ static inline struct xfrm_mode *xfrm_ip2inner_mode(struct xfrm_state *x, int ipp return x->inner_mode_iaf; } -struct xfrm_tmpl -{ +struct xfrm_tmpl { /* id in template is interpreted as: * daddr - destination of tunnel, may be zero for transport mode. * spi - zero to acquire spi. Not zero if spi is static, then @@ -435,24 +436,24 @@ struct xfrm_tmpl unsigned short encap_family; - __u32 reqid; + u32 reqid; /* Mode: transport, tunnel etc. */ - __u8 mode; + u8 mode; /* Sharing mode: unique, this session only, this user only etc. */ - __u8 share; + u8 share; /* May skip this transfomration if no SA is found */ - __u8 optional; + u8 optional; /* Skip aalgos/ealgos/calgos checks. */ - __u8 allalgs; + u8 allalgs; /* Bit mask of algos allowed for acquisition */ - __u32 aalgos; - __u32 ealgos; - __u32 calgos; + u32 aalgos; + u32 ealgos; + u32 calgos; }; #define XFRM_MAX_DEPTH 6 @@ -468,8 +469,7 @@ struct xfrm_policy_walk { u32 seq; }; -struct xfrm_policy -{ +struct xfrm_policy { #ifdef CONFIG_NET_NS struct net *xp_net; #endif @@ -483,6 +483,7 @@ struct xfrm_policy u32 priority; u32 index; + struct xfrm_mark mark; struct xfrm_selector selector; struct xfrm_lifetime_cfg lft; struct xfrm_lifetime_cur curlft; @@ -538,8 +539,7 @@ struct xfrm_migrate { /* default seq threshold size */ #define XFRM_AE_SEQT_SIZE 2 -struct xfrm_mgr -{ +struct xfrm_mgr { struct list_head list; char *id; int (*notify)(struct xfrm_state *x, struct km_event *c); @@ -626,8 +626,7 @@ struct xfrm_spi_skb_cb { #define XFRM_SPI_SKB_CB(__skb) ((struct xfrm_spi_skb_cb *)&((__skb)->cb[0])) /* Audit Information */ -struct xfrm_audit -{ +struct xfrm_audit { u32 secid; uid_t loginuid; u32 sessionid; @@ -774,7 +773,7 @@ static __inline__ int addr_match(void *token1, void *token2, int prefixlen) int pdw; int pbi; - pdw = prefixlen >> 5; /* num of whole __u32 in prefix */ + pdw = prefixlen >> 5; /* num of whole u32 in prefix */ pbi = prefixlen & 0x1f; /* num of bits in incomplete u32 in prefix */ if (pdw) @@ -871,8 +870,7 @@ static inline int xfrm_sec_ctx_match(struct xfrm_sec_ctx *s1, struct xfrm_sec_ct * bundles differing by session id. All the bundles grow from a parent * policy rule. */ -struct xfrm_dst -{ +struct xfrm_dst { union { struct dst_entry dst; struct rtable rt; @@ -907,8 +905,7 @@ static inline void xfrm_dst_destroy(struct xfrm_dst *xdst) extern void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev); -struct sec_path -{ +struct sec_path { atomic_t refcnt; int len; struct xfrm_state *xvec[XFRM_MAX_DEPTH]; @@ -1265,7 +1262,7 @@ struct xfrm_algo_desc { /* XFRM tunnel handlers. */ struct xfrm_tunnel { int (*handler)(struct sk_buff *skb); - int (*err_handler)(struct sk_buff *skb, __u32 info); + int (*err_handler)(struct sk_buff *skb, u32 info); struct xfrm_tunnel *next; int priority; @@ -1323,7 +1320,7 @@ extern struct xfrm_state *xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t struct flowi *fl, struct xfrm_tmpl *tmpl, struct xfrm_policy *pol, int *err, unsigned short family); -extern struct xfrm_state * xfrm_stateonly_find(struct net *net, +extern struct xfrm_state *xfrm_stateonly_find(struct net *net, u32 mark, xfrm_address_t *daddr, xfrm_address_t *saddr, unsigned short family, @@ -1332,8 +1329,14 @@ extern int xfrm_state_check_expire(struct xfrm_state *x); extern void xfrm_state_insert(struct xfrm_state *x); extern int xfrm_state_add(struct xfrm_state *x); extern int xfrm_state_update(struct xfrm_state *x); -extern struct xfrm_state *xfrm_state_lookup(struct net *net, xfrm_address_t *daddr, __be32 spi, u8 proto, unsigned short family); -extern struct xfrm_state *xfrm_state_lookup_byaddr(struct net *net, xfrm_address_t *daddr, xfrm_address_t *saddr, u8 proto, unsigned short family); +extern struct xfrm_state *xfrm_state_lookup(struct net *net, u32 mark, + xfrm_address_t *daddr, __be32 spi, + u8 proto, unsigned short family); +extern struct xfrm_state *xfrm_state_lookup_byaddr(struct net *net, u32 mark, + xfrm_address_t *daddr, + xfrm_address_t *saddr, + u8 proto, + unsigned short family); #ifdef CONFIG_XFRM_SUB_POLICY extern int xfrm_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n, unsigned short family); @@ -1370,11 +1373,12 @@ struct xfrmk_spdinfo { u32 spdhmcnt; }; -extern struct xfrm_state *xfrm_find_acq_byseq(struct net *net, u32 seq); +extern struct xfrm_state *xfrm_find_acq_byseq(struct net *net, u32 mark, + u32 seq); extern int xfrm_state_delete(struct xfrm_state *x); extern int xfrm_state_flush(struct net *net, u8 proto, struct xfrm_audit *audit_info); -extern void xfrm_sad_getinfo(struct xfrmk_sadinfo *si); -extern void xfrm_spd_getinfo(struct xfrmk_spdinfo *si); +extern void xfrm_sad_getinfo(struct net *net, struct xfrmk_sadinfo *si); +extern void xfrm_spd_getinfo(struct net *net, struct xfrmk_spdinfo *si); extern int xfrm_replay_check(struct xfrm_state *x, struct sk_buff *skb, __be32 seq); extern void xfrm_replay_advance(struct xfrm_state *x, __be32 seq); @@ -1414,9 +1418,9 @@ extern int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr, xfrm_address_t *saddr, u8 proto); extern int xfrm6_tunnel_register(struct xfrm6_tunnel *handler, unsigned short family); extern int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler, unsigned short family); -extern __be32 xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr); -extern void xfrm6_tunnel_free_spi(xfrm_address_t *saddr); -extern __be32 xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr); +extern __be32 xfrm6_tunnel_alloc_spi(struct net *net, xfrm_address_t *saddr); +extern void xfrm6_tunnel_free_spi(struct net *net, xfrm_address_t *saddr); +extern __be32 xfrm6_tunnel_spi_lookup(struct net *net, xfrm_address_t *saddr); extern int xfrm6_extract_output(struct xfrm_state *x, struct sk_buff *skb); extern int xfrm6_prepare_output(struct xfrm_state *x, struct sk_buff *skb); extern int xfrm6_output(struct sk_buff *skb); @@ -1447,17 +1451,20 @@ extern int xfrm_policy_walk(struct net *net, struct xfrm_policy_walk *walk, int (*func)(struct xfrm_policy *, int, int, void*), void *); extern void xfrm_policy_walk_done(struct xfrm_policy_walk *walk); int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl); -struct xfrm_policy *xfrm_policy_bysel_ctx(struct net *net, u8 type, int dir, +struct xfrm_policy *xfrm_policy_bysel_ctx(struct net *net, u32 mark, + u8 type, int dir, struct xfrm_selector *sel, struct xfrm_sec_ctx *ctx, int delete, int *err); -struct xfrm_policy *xfrm_policy_byid(struct net *net, u8, int dir, u32 id, int delete, int *err); +struct xfrm_policy *xfrm_policy_byid(struct net *net, u32 mark, u8, int dir, u32 id, int delete, int *err); int xfrm_policy_flush(struct net *net, u8 type, struct xfrm_audit *audit_info); u32 xfrm_get_acqseq(void); extern int xfrm_alloc_spi(struct xfrm_state *x, u32 minspi, u32 maxspi); -struct xfrm_state * xfrm_find_acq(struct net *net, u8 mode, u32 reqid, u8 proto, - xfrm_address_t *daddr, xfrm_address_t *saddr, - int create, unsigned short family); +struct xfrm_state *xfrm_find_acq(struct net *net, struct xfrm_mark *mark, + u8 mode, u32 reqid, u8 proto, + xfrm_address_t *daddr, + xfrm_address_t *saddr, int create, + unsigned short family); extern int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol); extern int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *xdst, struct flowi *fl, int family, int strict); @@ -1500,16 +1507,13 @@ struct scatterlist; typedef int (icv_update_fn_t)(struct hash_desc *, struct scatterlist *, unsigned int); -extern int skb_icv_walk(const struct sk_buff *skb, struct hash_desc *tfm, - int offset, int len, icv_update_fn_t icv_update); - static inline int xfrm_addr_cmp(xfrm_address_t *a, xfrm_address_t *b, int 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; case AF_INET6: return ipv6_addr_cmp((struct in6_addr *)a, (struct in6_addr *)b); @@ -1541,12 +1545,22 @@ static inline int xfrm_alg_len(struct xfrm_algo *alg) return sizeof(*alg) + ((alg->alg_key_len + 7) / 8); } +static inline int xfrm_alg_auth_len(struct xfrm_algo_auth *alg) +{ + return sizeof(*alg) + ((alg->alg_key_len + 7) / 8); +} + #ifdef CONFIG_XFRM_MIGRATE static inline struct xfrm_algo *xfrm_algo_clone(struct xfrm_algo *orig) { return kmemdup(orig, xfrm_alg_len(orig), GFP_KERNEL); } +static inline struct xfrm_algo_auth *xfrm_algo_auth_clone(struct xfrm_algo_auth *orig) +{ + return kmemdup(orig, xfrm_alg_auth_len(orig), GFP_KERNEL); +} + static inline void xfrm_states_put(struct xfrm_state **states, int n) { int i; @@ -1569,4 +1583,24 @@ static inline struct xfrm_state *xfrm_input_state(struct sk_buff *skb) } #endif +static inline int xfrm_mark_get(struct nlattr **attrs, struct xfrm_mark *m) +{ + if (attrs[XFRMA_MARK]) + memcpy(m, nla_data(attrs[XFRMA_MARK]), sizeof(m)); + else + m->v = m->m = 0; + + return m->v & m->m; +} + +static inline int xfrm_mark_put(struct sk_buff *skb, struct xfrm_mark *m) +{ + if (m->m | m->v) + NLA_PUT(skb, XFRMA_MARK, sizeof(struct xfrm_mark), m); + return 0; + +nla_put_failure: + return -1; +} + #endif /* _NET_XFRM_H */ |