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

Commit 962c382d authored by David S. Miller's avatar David S. Miller
Browse files

Merge tag 'mac80211-next-for-davem-2019-02-01' of...

Merge tag 'mac80211-next-for-davem-2019-02-01' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next



Johannes Berg says:

====================
New features for the wifi stack:
 * airtime fairness scheduling in mac80211, so we can share
 * more authentication offloads to userspace - this is for
   SAE which is part of WPA3 and is hard to do in firmware
 * documentation fixes
 * various mesh improvements
 * various other small improvements/cleanups

This also contains the NLA_POLICY_NESTED{,_ARRAY} change we
discussed, which affects everyone but there's no other user
yet.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 39ee6e82 7d419463
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -125,6 +125,9 @@ functions/definitions
.. kernel-doc:: include/net/mac80211.h
   :functions: ieee80211_rx_status

.. kernel-doc:: include/net/mac80211.h
   :functions: mac80211_rx_encoding_flags

.. kernel-doc:: include/net/mac80211.h
   :functions: mac80211_rx_flags

+0 −7
Original line number Diff line number Diff line
@@ -14,11 +14,6 @@
#include <linux/etherdevice.h>
#include <linux/module.h>

#include <net/cfg80211.h>
#include <net/rtnetlink.h>
#include <linux/etherdevice.h>
#include <linux/module.h>

static struct wiphy *common_wiphy;

struct virt_wifi_wiphy_priv {
@@ -429,13 +424,11 @@ static int virt_wifi_net_device_open(struct net_device *dev)
static int virt_wifi_net_device_stop(struct net_device *dev)
{
	struct virt_wifi_netdev_priv *n_priv = netdev_priv(dev);
	struct virt_wifi_wiphy_priv *w_priv;

	n_priv->is_up = false;

	if (!dev->ieee80211_ptr)
		return 0;
	w_priv = wiphy_priv(dev->ieee80211_ptr->wiphy);

	virt_wifi_cancel_scan(dev->ieee80211_ptr->wiphy);
	virt_wifi_cancel_connect(dev);
+52 −3
Original line number Diff line number Diff line
@@ -835,6 +835,17 @@ struct cfg80211_bitrate_mask {
	} control[NUM_NL80211_BANDS];
};

/**
 * enum cfg80211_ap_settings_flags - AP settings flags
 *
 * Used by cfg80211_ap_settings
 *
 * @AP_SETTINGS_EXTERNAL_AUTH_SUPPORT: AP supports external authentication
 */
enum cfg80211_ap_settings_flags {
	AP_SETTINGS_EXTERNAL_AUTH_SUPPORT = BIT(0),
};

/**
 * struct cfg80211_ap_settings - AP configuration
 *
@@ -865,6 +876,7 @@ struct cfg80211_bitrate_mask {
 * @he_cap: HE capabilities (or %NULL if HE isn't enabled)
 * @ht_required: stations must support HT
 * @vht_required: stations must support VHT
 * @flags: flags, as defined in enum cfg80211_ap_settings_flags
 */
struct cfg80211_ap_settings {
	struct cfg80211_chan_def chandef;
@@ -890,6 +902,7 @@ struct cfg80211_ap_settings {
	const struct ieee80211_vht_cap *vht_cap;
	const struct ieee80211_he_cap_elem *he_cap;
	bool ht_required, vht_required;
	u32 flags;
};

/**
@@ -1003,6 +1016,7 @@ enum station_parameters_apply_mask {
 * @support_p2p_ps: information if station supports P2P PS mechanism
 * @he_capa: HE capabilities of station
 * @he_capa_len: the length of the HE capabilities
 * @airtime_weight: airtime scheduler weight for this station
 */
struct station_parameters {
	const u8 *supported_rates;
@@ -1032,6 +1046,7 @@ struct station_parameters {
	int support_p2p_ps;
	const struct ieee80211_he_cap_elem *he_capa;
	u8 he_capa_len;
	u16 airtime_weight;
};

/**
@@ -1300,6 +1315,8 @@ struct cfg80211_tid_stats {
 *	from this peer
 * @connected_to_gate: true if mesh STA has a path to mesh gate
 * @rx_duration: aggregate PPDU duration(usecs) for all the frames from a peer
 * @tx_duration: aggregate PPDU duration(usecs) for all the frames to a peer
 * @airtime_weight: current airtime scheduling weight
 * @pertid: per-TID statistics, see &struct cfg80211_tid_stats, using the last
 *	(IEEE80211_NUM_TIDS) index for MSDUs not encapsulated in QoS-MPDUs.
 *	Note that this doesn't use the @filled bit, but is used if non-NULL.
@@ -1350,8 +1367,9 @@ struct station_info {

	u32 expected_throughput;

	u64 rx_beacon;
	u64 tx_duration;
	u64 rx_duration;
	u64 rx_beacon;
	u8 rx_beacon_signal_avg;
	u8 connected_to_gate;

@@ -1359,6 +1377,8 @@ struct station_info {
	s8 ack_signal;
	s8 avg_ack_signal;

	u16 airtime_weight;

	u32 rx_mpdu_count;
	u32 fcs_err_count;
};
@@ -1422,6 +1442,8 @@ enum monitor_flags {
 * @MPATH_INFO_DISCOVERY_TIMEOUT: @discovery_timeout filled
 * @MPATH_INFO_DISCOVERY_RETRIES: @discovery_retries filled
 * @MPATH_INFO_FLAGS: @flags filled
 * @MPATH_INFO_HOP_COUNT: @hop_count filled
 * @MPATH_INFO_PATH_CHANGE: @path_change_count filled
 */
enum mpath_info_flags {
	MPATH_INFO_FRAME_QLEN		= BIT(0),
@@ -1431,6 +1453,8 @@ enum mpath_info_flags {
	MPATH_INFO_DISCOVERY_TIMEOUT	= BIT(4),
	MPATH_INFO_DISCOVERY_RETRIES	= BIT(5),
	MPATH_INFO_FLAGS		= BIT(6),
	MPATH_INFO_HOP_COUNT		= BIT(7),
	MPATH_INFO_PATH_CHANGE		= BIT(8),
};

/**
@@ -1450,6 +1474,8 @@ enum mpath_info_flags {
 *	This number should increase every time the list of mesh paths
 *	changes, i.e. when a station is added or removed, so that
 *	userspace can tell whether it got a consistent snapshot.
 * @hop_count: hops to destination
 * @path_change_count: total number of path changes to destination
 */
struct mpath_info {
	u32 filled;
@@ -1460,6 +1486,8 @@ struct mpath_info {
	u32 discovery_timeout;
	u8 discovery_retries;
	u8 flags;
	u8 hop_count;
	u32 path_change_count;

	int generation;
};
@@ -2391,6 +2419,8 @@ enum wiphy_params_flags {
	WIPHY_PARAM_TXQ_QUANTUM		= 1 << 8,
};

#define IEEE80211_DEFAULT_AIRTIME_WEIGHT	256

/**
 * struct cfg80211_pmksa - PMK Security Association
 *
@@ -2815,6 +2845,7 @@ struct cfg80211_pmk_conf {
 *	use %WLAN_STATUS_UNSPECIFIED_FAILURE if user space cannot give you
 *	the real status code for failures. Used only for the authentication
 *	response command interface (user space to driver).
 * @pmkid: The identifier to refer a PMKSA.
 */
struct cfg80211_external_auth_params {
	enum nl80211_external_auth_action action;
@@ -2822,6 +2853,7 @@ struct cfg80211_external_auth_params {
	struct cfg80211_ssid ssid;
	unsigned int key_mgmt_suite;
	u16 status;
	const u8 *pmkid;
};

/**
@@ -4112,6 +4144,8 @@ struct cfg80211_pmsr_capabilities {
 * @signal_type: signal type reported in &struct cfg80211_bss.
 * @cipher_suites: supported cipher suites
 * @n_cipher_suites: number of supported cipher suites
 * @akm_suites: supported AKM suites
 * @n_akm_suites: number of supported AKM suites
 * @retry_short: Retry limit for short frames (dot11ShortRetryLimit)
 * @retry_long: Retry limit for long frames (dot11LongRetryLimit)
 * @frag_threshold: Fragmentation threshold (dot11FragmentationThreshold);
@@ -4310,6 +4344,9 @@ struct wiphy {
	int n_cipher_suites;
	const u32 *cipher_suites;

	int n_akm_suites;
	const u32 *akm_suites;

	u8 retry_short;
	u8 retry_long;
	u32 frag_threshold;
@@ -4573,6 +4610,17 @@ struct cfg80211_cqm_config;
 * @mesh_id_len: (private) Used by the internal configuration code
 * @mesh_id_up_len: (private) Used by the internal configuration code
 * @wext: (private) Used by the internal wireless extensions compat code
 * @wext.ibss: (private) IBSS data part of wext handling
 * @wext.connect: (private) connection handling data
 * @wext.keys: (private) (WEP) key data
 * @wext.ie: (private) extra elements for association
 * @wext.ie_len: (private) length of extra elements
 * @wext.bssid: (private) selected network BSSID
 * @wext.ssid: (private) selected network SSID
 * @wext.default_key: (private) selected default key index
 * @wext.default_mgmt_key: (private) selected default management key index
 * @wext.prev_bssid: (private) previous BSSID for reassociation
 * @wext.prev_bssid_valid: (private) previous BSSID validity
 * @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
@@ -4672,7 +4720,8 @@ struct wireless_dev {
		struct cfg80211_cached_keys *keys;
		const u8 *ie;
		size_t ie_len;
		u8 bssid[ETH_ALEN], prev_bssid[ETH_ALEN];
		u8 bssid[ETH_ALEN];
		u8 prev_bssid[ETH_ALEN];
		u8 ssid[IEEE80211_MAX_SSID_LEN];
		s8 default_key, default_mgmt_key;
		bool prev_bssid_valid;
@@ -5568,7 +5617,7 @@ void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid,
 * @dev: network device
 * @macaddr: the MAC address of the new candidate
 * @ie: information elements advertised by the peer candidate
 * @ie_len: lenght of the information elements buffer
 * @ie_len: length of the information elements buffer
 * @gfp: allocation flags
 *
 * This function notifies cfg80211 that the mesh peer candidate has been
+171 −12
Original line number Diff line number Diff line
@@ -108,9 +108,15 @@
 * The driver is expected to initialize its private per-queue data for stations
 * and interfaces in the .add_interface and .sta_add ops.
 *
 * The driver can't access the queue directly. To dequeue a frame, it calls
 * ieee80211_tx_dequeue(). Whenever mac80211 adds a new frame to a queue, it
 * calls the .wake_tx_queue driver op.
 * The driver can't access the queue directly. To dequeue a frame from a
 * txq, it calls ieee80211_tx_dequeue(). Whenever mac80211 adds a new frame to a
 * queue, it calls the .wake_tx_queue driver op.
 *
 * Drivers can optionally delegate responsibility for scheduling queues to
 * mac80211, to take advantage of airtime fairness accounting. In this case, to
 * obtain the next queue to pull frames from, the driver calls
 * ieee80211_next_txq(). The driver is then expected to return the txq using
 * ieee80211_return_txq().
 *
 * For AP powersave TIM handling, the driver only needs to indicate if it has
 * buffered packets in the driver specific data structures by calling
@@ -936,8 +942,32 @@ ieee80211_rate_get_vht_nss(const struct ieee80211_tx_rate *rate)
 * @band: the band to transmit on (use for checking for races)
 * @hw_queue: HW queue to put the frame on, skb_get_queue_mapping() gives the AC
 * @ack_frame_id: internal frame ID for TX status, used internally
 * @control: union for control data
 * @status: union for status data
 * @control: union part for control data
 * @control.rates: TX rates array to try
 * @control.rts_cts_rate_idx: rate for RTS or CTS
 * @control.use_rts: use RTS
 * @control.use_cts_prot: use RTS/CTS
 * @control.short_preamble: use short preamble (CCK only)
 * @control.skip_table: skip externally configured rate table
 * @control.jiffies: timestamp for expiry on powersave clients
 * @control.vif: virtual interface (may be NULL)
 * @control.hw_key: key to encrypt with (may be NULL)
 * @control.flags: control flags, see &enum mac80211_tx_control_flags
 * @control.enqueue_time: enqueue time (for iTXQs)
 * @driver_rates: alias to @control.rates to reserve space
 * @pad: padding
 * @rate_driver_data: driver use area if driver needs @control.rates
 * @status: union part for status data
 * @status.rates: attempted rates
 * @status.ack_signal: ACK signal
 * @status.ampdu_ack_len: AMPDU ack length
 * @status.ampdu_len: AMPDU length
 * @status.antenna: (legacy, kept only for iwlegacy)
 * @status.tx_time: airtime consumed for transmission
 * @status.is_valid_ack_signal: ACK signal is valid
 * @status.status_driver_data: driver use area
 * @ack: union part for pure ACK data
 * @ack.cookie: cookie for the ACK
 * @driver_data: array of driver_data pointers
 * @ampdu_ack_len: number of acked aggregated frames.
 * 	relevant only if IEEE80211_TX_STAT_AMPDU was set.
@@ -1157,6 +1187,7 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info)
 * @RX_FLAG_AMPDU_EOF_BIT_KNOWN: The EOF value is known
 * @RX_FLAG_RADIOTAP_HE: HE radiotap data is present
 *	(&struct ieee80211_radiotap_he, mac80211 will fill in
 *	
 *	 - DATA3_DATA_MCS
 *	 - DATA3_DATA_DCM
 *	 - DATA3_CODING
@@ -1164,6 +1195,7 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info)
 *	 - DATA5_DATA_BW_RU_ALLOC
 *	 - DATA6_NSTS
 *	 - DATA3_STBC
 *	
 *	from the RX info data, so leave those zeroed when building this data)
 * @RX_FLAG_RADIOTAP_HE_MU: HE MU radiotap data is present
 *	(&struct ieee80211_radiotap_he_mu)
@@ -1214,7 +1246,7 @@ enum mac80211_rx_flags {
 * @RX_ENC_FLAG_HT_GF: This frame was received in a HT-greenfield transmission,
 *	if the driver fills this value it should add
 *	%IEEE80211_RADIOTAP_MCS_HAVE_FMT
 *	to hw.radiotap_mcs_details to advertise that fact
 *	to @hw.radiotap_mcs_details to advertise that fact.
 * @RX_ENC_FLAG_LDPC: LDPC was used
 * @RX_ENC_FLAG_STBC_MASK: STBC 2 bit bitmask. 1 - Nss=1, 2 - Nss=2, 3 - Nss=3
 * @RX_ENC_FLAG_BF: packet was beamformed
@@ -2184,6 +2216,9 @@ struct ieee80211_txq {
 *	MMPDUs on station interfaces. This of course requires the driver to use
 *	TXQs to start with.
 *
 * @IEEE80211_HW_TX_STATUS_NO_AMPDU_LEN: Driver does not report accurate A-MPDU
 *	length in tx status information
 *
 * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays
 */
enum ieee80211_hw_flags {
@@ -2232,6 +2267,7 @@ enum ieee80211_hw_flags {
	IEEE80211_HW_BUFF_MMPDU_TXQ,
	IEEE80211_HW_SUPPORTS_VHT_EXT_NSS_BW,
	IEEE80211_HW_STA_MMPDU_TXQ,
	IEEE80211_HW_TX_STATUS_NO_AMPDU_LEN,

	/* keep last, obviously */
	NUM_IEEE80211_HW_FLAGS
@@ -2323,12 +2359,14 @@ enum ieee80211_hw_flags {
 * @radiotap_he: HE radiotap validity flags
 *
 * @radiotap_timestamp: Information for the radiotap timestamp field; if the
 *	'units_pos' member is set to a non-negative value it must be set to
 *	a combination of a IEEE80211_RADIOTAP_TIMESTAMP_UNIT_* and a
 *	IEEE80211_RADIOTAP_TIMESTAMP_SPOS_* value, and then the timestamp
 *	@units_pos member is set to a non-negative value then the timestamp
 *	field will be added and populated from the &struct ieee80211_rx_status
 *	device_timestamp. If the 'accuracy' member is non-negative, it's put
 *	into the accuracy radiotap field and the accuracy known flag is set.
 *	device_timestamp.
 * @radiotap_timestamp.units_pos: Must be set to a combination of a
 *	IEEE80211_RADIOTAP_TIMESTAMP_UNIT_* and a
 *	IEEE80211_RADIOTAP_TIMESTAMP_SPOS_* value.
 * @radiotap_timestamp.accuracy: If non-negative, fills the accuracy in the
 *	radiotap field and the accuracy known flag will be set.
 *
 * @netdev_features: netdev features to be set in each netdev created
 *	from this HW. Note that not all features are usable with mac80211,
@@ -2354,6 +2392,9 @@ enum ieee80211_hw_flags {
 * @tx_sk_pacing_shift: Pacing shift to set on TCP sockets when frames from
 *	them are encountered. The default should typically not be changed,
 *	unless the driver has good reasons for needing more buffers.
 *
 * @weight_multiplier: Driver specific airtime weight multiplier used while
 *	refilling deficit of each TXQ.
 */
struct ieee80211_hw {
	struct ieee80211_conf conf;
@@ -2390,6 +2431,7 @@ struct ieee80211_hw {
	const struct ieee80211_cipher_scheme *cipher_schemes;
	u8 max_nan_de_entries;
	u8 tx_sk_pacing_shift;
	u8 weight_multiplier;
};

static inline bool _ieee80211_hw_check(struct ieee80211_hw *hw,
@@ -5401,6 +5443,34 @@ void ieee80211_sta_eosp(struct ieee80211_sta *pubsta);
 */
void ieee80211_send_eosp_nullfunc(struct ieee80211_sta *pubsta, int tid);

/**
 * ieee80211_sta_register_airtime - register airtime usage for a sta/tid
 *
 * Register airtime usage for a given sta on a given tid. The driver can call
 * this function to notify mac80211 that a station used a certain amount of
 * airtime. This information will be used by the TXQ scheduler to schedule
 * stations in a way that ensures airtime fairness.
 *
 * The reported airtime should as a minimum include all time that is spent
 * transmitting to the remote station, including overhead and padding, but not
 * including time spent waiting for a TXOP. If the time is not reported by the
 * hardware it can in some cases be calculated from the rate and known frame
 * composition. When possible, the time should include any failed transmission
 * attempts.
 *
 * The driver can either call this function synchronously for every packet or
 * aggregate, or asynchronously as airtime usage information becomes available.
 * TX and RX airtime can be reported together, or separately by setting one of
 * them to 0.
 *
 * @pubsta: the station
 * @tid: the TID to register airtime for
 * @tx_airtime: airtime used during TX (in usec)
 * @rx_airtime: airtime used during RX (in usec)
 */
void ieee80211_sta_register_airtime(struct ieee80211_sta *pubsta, u8 tid,
				    u32 tx_airtime, u32 rx_airtime);

/**
 * ieee80211_iter_keys - iterate keys programmed into the device
 * @hw: pointer obtained from ieee80211_alloc_hw()
@@ -6103,7 +6173,8 @@ void ieee80211_unreserve_tid(struct ieee80211_sta *sta, u8 tid);
 * ieee80211_tx_dequeue - dequeue a packet from a software tx queue
 *
 * @hw: pointer as obtained from ieee80211_alloc_hw()
 * @txq: pointer obtained from station or virtual interface
 * @txq: pointer obtained from station or virtual interface, or from
 *	ieee80211_next_txq()
 *
 * Returns the skb if successful, %NULL if no frame was available.
 *
@@ -6118,6 +6189,94 @@ void ieee80211_unreserve_tid(struct ieee80211_sta *sta, u8 tid);
struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw,
				     struct ieee80211_txq *txq);

/**
 * ieee80211_next_txq - get next tx queue to pull packets from
 *
 * @hw: pointer as obtained from ieee80211_alloc_hw()
 * @ac: AC number to return packets from.
 *
 * Should only be called between calls to ieee80211_txq_schedule_start()
 * and ieee80211_txq_schedule_end().
 * Returns the next txq if successful, %NULL if no queue is eligible. If a txq
 * is returned, it should be returned with ieee80211_return_txq() after the
 * driver has finished scheduling it.
 */
struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw, u8 ac);

/**
 * ieee80211_return_txq - return a TXQ previously acquired by ieee80211_next_txq()
 *
 * @hw: pointer as obtained from ieee80211_alloc_hw()
 * @txq: pointer obtained from station or virtual interface
 *
 * Should only be called between calls to ieee80211_txq_schedule_start()
 * and ieee80211_txq_schedule_end().
 */
void ieee80211_return_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq);

/**
 * ieee80211_txq_schedule_start - acquire locks for safe scheduling of an AC
 *
 * @hw: pointer as obtained from ieee80211_alloc_hw()
 * @ac: AC number to acquire locks for
 *
 * Acquire locks needed to schedule TXQs from the given AC. Should be called
 * before ieee80211_next_txq() or ieee80211_return_txq().
 */
void ieee80211_txq_schedule_start(struct ieee80211_hw *hw, u8 ac)
	__acquires(txq_lock);

/**
 * ieee80211_txq_schedule_end - release locks for safe scheduling of an AC
 *
 * @hw: pointer as obtained from ieee80211_alloc_hw()
 * @ac: AC number to acquire locks for
 *
 * Release locks previously acquired by ieee80211_txq_schedule_end().
 */
void ieee80211_txq_schedule_end(struct ieee80211_hw *hw, u8 ac)
	__releases(txq_lock);

/**
 * ieee80211_schedule_txq - schedule a TXQ for transmission
 *
 * @hw: pointer as obtained from ieee80211_alloc_hw()
 * @txq: pointer obtained from station or virtual interface
 *
 * Schedules a TXQ for transmission if it is not already scheduled. Takes a
 * lock, which means it must *not* be called between
 * ieee80211_txq_schedule_start() and ieee80211_txq_schedule_end()
 */
void ieee80211_schedule_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq)
	__acquires(txq_lock) __releases(txq_lock);

/**
 * ieee80211_txq_may_transmit - check whether TXQ is allowed to transmit
 *
 * This function is used to check whether given txq is allowed to transmit by
 * the airtime scheduler, and can be used by drivers to access the airtime
 * fairness accounting without going using the scheduling order enfored by
 * next_txq().
 *
 * Returns %true if the airtime scheduler thinks the TXQ should be allowed to
 * transmit, and %false if it should be throttled. This function can also have
 * the side effect of rotating the TXQ in the scheduler rotation, which will
 * eventually bring the deficit to positive and allow the station to transmit
 * again.
 *
 * The API ieee80211_txq_may_transmit() also ensures that TXQ list will be
 * aligned aginst driver's own round-robin scheduler list. i.e it rotates
 * the TXQ list till it makes the requested node becomes the first entry
 * in TXQ list. Thus both the TXQ list and driver's list are in sync. If this
 * function returns %true, the driver is expected to schedule packets
 * for transmission, and then return the TXQ through ieee80211_return_txq().
 *
 * @hw: pointer as obtained from ieee80211_alloc_hw()
 * @txq: pointer obtained from station or virtual interface
 */
bool ieee80211_txq_may_transmit(struct ieee80211_hw *hw,
				struct ieee80211_txq *txq);

/**
 * ieee80211_txq_get_depth - get pending frame/byte count of given txq
 *
+6 −2
Original line number Diff line number Diff line
@@ -306,10 +306,14 @@ struct nla_policy {
#define NLA_POLICY_ETH_ADDR		NLA_POLICY_EXACT_LEN(ETH_ALEN)
#define NLA_POLICY_ETH_ADDR_COMPAT	NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN)

#define NLA_POLICY_NESTED(maxattr, policy) \
#define _NLA_POLICY_NESTED(maxattr, policy) \
	{ .type = NLA_NESTED, .validation_data = policy, .len = maxattr }
#define NLA_POLICY_NESTED_ARRAY(maxattr, policy) \
#define _NLA_POLICY_NESTED_ARRAY(maxattr, policy) \
	{ .type = NLA_NESTED_ARRAY, .validation_data = policy, .len = maxattr }
#define NLA_POLICY_NESTED(policy) \
	_NLA_POLICY_NESTED(ARRAY_SIZE(policy) - 1, policy)
#define NLA_POLICY_NESTED_ARRAY(policy) \
	_NLA_POLICY_NESTED_ARRAY(ARRAY_SIZE(policy) - 1, policy)

#define __NLA_ENSURE(condition) BUILD_BUG_ON_ZERO(!(condition))
#define NLA_ENSURE_INT_TYPE(tp)				\
Loading