// SPDX-License-Identifier: GPL-2.0-only

#include <linux/ethtool_netlink.h>
#include <linux/bitmap.h>

#include "bitset.h"
#include "netlink.h"

/* Some bitmaps are internally represented as an array of unsigned long, some
 * as an array of u32 (some even as single u32 for now). To avoid the need of
 * wrappers on caller side, we provide two set of functions: those with "32"
 * suffix in their names expect u32 based bitmaps, those without it expect
 * unsigned long bitmaps.
 */

static u32 ethnl_lower_bits(unsigned int n)
{
	return ~(u32)0 >> (32 - n % 32);
}

static u32 ethnl_upper_bits(unsigned int n)
{
	return ~(u32)0 << (n % 32);
}

/**
 * ethnl_bitmap32_clear() - Clear u32 based bitmap
 * @dst:   bitmap to clear
 * @start: beginning of the interval
 * @end:   end of the interval
 * @mod:   set if bitmap was modified
 *
 * Clear @nbits bits of a bitmap with indices @start <= i < @end
 */
static void ethnl_bitmap32_clear(u32 *dst, unsigned int start, unsigned int end,
				 bool *mod)
{
	unsigned int start_word = start / 32;
	unsigned int end_word = end / 32;
	unsigned int i;
	u32 mask;

	if (end <= start)
		return;

	if (start % 32) {
		mask = ethnl_upper_bits(start);
		if (end_word == start_word) {
			mask &= ethnl_lower_bits(end);
			if (dst[start_word] & mask) {
				dst[start_word] &= ~mask;
				*mod = true;
			}
			return;
		}
		if (dst[start_word] & mask) {
			dst[start_word] &= ~mask;
			*mod = true;
		}
		start_word++;
	}

	for (i = start_word; i < end_word; i++) {
		if (dst[i]) {
			dst[i] = 0;
			*mod = true;
		}
	}
	if (end % 32) {
		mask = ethnl_lower_bits(end);
		if (dst[end_word] & mask) {
			dst[end_word] &= ~mask;
			*mod = true;
		}
	}
}

/**
 * ethnl_bitmap32_not_zero() - Check if any bit is set in an interval
 * @map:   bitmap to test
 * @start: beginning of the interval
 * @end:   end of the interval
 *
 * Return: true if there is non-zero bit with  index @start <= i < @end,
 *         false if the whole interval is zero
 */
static bool ethnl_bitmap32_not_zero(const u32 *map, unsigned int start,
				    unsigned int end)
{
	unsigned int start_word = start / 32;
	unsigned int end_word = end / 32;
	u32 mask;

	if (end <= start)
		return true;

	if (start % 32) {
		mask = ethnl_upper_bits(start);
		if (end_word == start_word) {
			mask &= ethnl_lower_bits(end);
			return map[start_word] & mask;
		}
		if (map[start_word] & mask)
			return true;
		start_word++;
	}

	if (!memchr_inv(map + start_word, '\0',
			(end_word - start_word) * sizeof(u32)))
		return true;
	if (end % 32 == 0)
		return true;
	return map[end_word] & ethnl_lower_bits(end);
}

/**
 * ethnl_bitmap32_update() - Modify u32 based bitmap according to value/mask
 *			     pair
 * @dst:   bitmap to update
 * @nbits: bit size of the bitmap
 * @value: values to set
 * @mask:  mask of bits to set
 * @mod:   set to true if bitmap is modified, preserve if not
 *
 * Set bits in @dst bitmap which are set in @mask to values from @value, leave
 * the rest untouched. If destination bitmap was modified, set @mod to true,
 * leave as it is if not.
 */
static void ethnl_bitmap32_update(u32 *dst, unsigned int nbits,
				  const u32 *value, const u32 *mask, bool *mod)
{
	while (nbits > 0) {
		u32 real_mask = mask ? *mask : ~(u32)0;
		u32 new_value;

		if (nbits < 32)
			real_mask &= ethnl_lower_bits(nbits);
		new_value = (*dst & ~real_mask) | (*value & real_mask);
		if (new_value != *dst) {
			*dst = new_value;
			*mod = true;
		}

		if (nbits <= 32)
			break;
		dst++;
		nbits -= 32;
		value++;
		if (mask)
			mask++;
	}
}

static bool ethnl_bitmap32_test_bit(const u32 *map, unsigned int index)
{
	return map[index / 32] & (1U << (index % 32));
}

/**
 * ethnl_bitset32_size() - Calculate size of bitset nested attribute
 * @val:     value bitmap (u32 based)
 * @mask:    mask bitmap (u32 based, optional)
 * @nbits:   bit length of the bitset
 * @names:   array of bit names (optional)
 * @compact: assume compact format for output
 *
 * Estimate length of netlink attribute composed by a later call to
 * ethnl_put_bitset32() call with the same arguments.
 *
 * Return: negative error code or attribute length estimate
 */
int ethnl_bitset32_size(const u32 *val, const u32 *mask, unsigned int nbits,
			ethnl_string_array_t names, bool compact)
{
	unsigned int len = 0;

	/* list flag */
	if (!mask)
		len += nla_total_size(sizeof(u32));
	/* size */
	len += nla_total_size(sizeof(u32));

	if (compact) {
		unsigned int nwords = DIV_ROUND_UP(nbits, 32);

		/* value, mask */
		len += (mask ? 2 : 1) * nla_total_size(nwords * sizeof(u32));
	} else {
		unsigned int bits_len = 0;
		unsigned int bit_len, i;

		for (i = 0; i < nbits; i++) {
			const char *name = names ? names[i] : NULL;

			if (!ethnl_bitmap32_test_bit(mask ?: val, i))
				continue;
			/* index */
			bit_len = nla_total_size(sizeof(u32));
			/* name */
			if (name)
				bit_len += ethnl_strz_size(name);
			/* value */
			if (mask && ethnl_bitmap32_test_bit(val, i))
				bit_len += nla_total_size(0);

			/* bit nest */
			bits_len += nla_total_size(bit_len);
		}
		/* bits nest */
		len += nla_total_size(bits_len);
	}

	/* outermost nest */
	return nla_total_size(len);
}

/**
 * ethnl_put_bitset32() - Put a bitset nest into a message
 * @skb:      skb with the message
 * @attrtype: attribute type for the bitset nest
 * @val:      value bitmap (u32 based)
 * @mask:     mask bitmap (u32 based, optional)
 * @nbits:    bit length of the bitset
 * @names:    array of bit names (optional)
 * @compact:  use compact format for the output
 *
 * Compose a nested attribute representing a bitset. If @mask is null, simple
 * bitmap (bit list) is created, if @mask is provided, represent a value/mask
 * pair. Bit names are only used in verbose mode and when provided by calller.
 *
 * Return: 0 on success, negative error value on error
 */
int ethnl_put_bitset32(struct sk_buff *skb, int attrtype, const u32 *val,
		       const u32 *mask, unsigned int nbits,
		       ethnl_string_array_t names, bool compact)
{
	struct nlattr *nest;
	struct nlattr *attr;

	nest = nla_nest_start(skb, attrtype);
	if (!nest)
		return -EMSGSIZE;

	if (!mask && nla_put_flag(skb, ETHTOOL_A_BITSET_NOMASK))
		goto nla_put_failure;
	if (nla_put_u32(skb, ETHTOOL_A_BITSET_SIZE, nbits))
		goto nla_put_failure;
	if (compact) {
		unsigned int nwords = DIV_ROUND_UP(nbits, 32);
		unsigned int nbytes = nwords * sizeof(u32);
		u32 *dst;

		attr = nla_reserve(skb, ETHTOOL_A_BITSET_VALUE, nbytes);
		if (!attr)
			goto nla_put_failure;
		dst = nla_data(attr);
		memcpy(dst, val, nbytes);
		if (nbits % 32)
			dst[nwords - 1] &= ethnl_lower_bits(nbits);

		if (mask) {
			attr = nla_reserve(skb, ETHTOOL_A_BITSET_MASK, nbytes);
			if (!attr)
				goto nla_put_failure;
			dst = nla_data(attr);
			memcpy(dst, mask, nbytes);
			if (nbits % 32)
				dst[nwords - 1] &= ethnl_lower_bits(nbits);
		}
	} else {
		struct nlattr *bits;
		unsigned int i;

		bits = nla_nest_start(skb, ETHTOOL_A_BITSET_BITS);
		if (!bits)
			goto nla_put_failure;
		for (i = 0; i < nbits; i++) {
			const char *name = names ? names[i] : NULL;

			if (!ethnl_bitmap32_test_bit(mask ?: val, i))
				continue;
			attr = nla_nest_start(skb, ETHTOOL_A_BITSET_BITS_BIT);
			if (!attr)
				goto nla_put_failure;
			if (nla_put_u32(skb, ETHTOOL_A_BITSET_BIT_INDEX, i))
				goto nla_put_failure;
			if (name &&
			    ethnl_put_strz(skb, ETHTOOL_A_BITSET_BIT_NAME, name))
				goto nla_put_failure;
			if (mask && ethnl_bitmap32_test_bit(val, i) &&
			    nla_put_flag(skb, ETHTOOL_A_BITSET_BIT_VALUE))
				goto nla_put_failure;
			nla_nest_end(skb, attr);
		}
		nla_nest_end(skb, bits);
	}

	nla_nest_end(skb, nest);
	return 0;

nla_put_failure:
	nla_nest_cancel(skb, nest);
	return -EMSGSIZE;
}

static const struct nla_policy bitset_policy[] = {
	[ETHTOOL_A_BITSET_NOMASK]	= { .type = NLA_FLAG },
	[ETHTOOL_A_BITSET_SIZE]		= NLA_POLICY_MAX(NLA_U32,
							 ETHNL_MAX_BITSET_SIZE),
	[ETHTOOL_A_BITSET_BITS]		= { .type = NLA_NESTED },
	[ETHTOOL_A_BITSET_VALUE]	= { .type = NLA_BINARY },
	[ETHTOOL_A_BITSET_MASK]		= { .type = NLA_BINARY },
};

static const struct nla_policy bit_policy[] = {
	[ETHTOOL_A_BITSET_BIT_INDEX]	= { .type = NLA_U32 },
	[ETHTOOL_A_BITSET_BIT_NAME]	= { .type = NLA_NUL_STRING },
	[ETHTOOL_A_BITSET_BIT_VALUE]	= { .type = NLA_FLAG },
};

/**
 * ethnl_bitset_is_compact() - check if bitset attribute represents a compact
 *			       bitset
 * @bitset:  nested attribute representing a bitset
 * @compact: pointer for return value
 *
 * Return: 0 on success, negative error code on failure
 */
int ethnl_bitset_is_compact(const struct nlattr *bitset, bool *compact)
{
	struct nlattr *tb[ARRAY_SIZE(bitset_policy)];
	int ret;

	ret = nla_parse_nested(tb, ARRAY_SIZE(bitset_policy) - 1, bitset,
			       bitset_policy, NULL);
	if (ret < 0)
		return ret;

	if (tb[ETHTOOL_A_BITSET_BITS]) {
		if (tb[ETHTOOL_A_BITSET_VALUE] || tb[ETHTOOL_A_BITSET_MASK])
			return -EINVAL;
		*compact = false;
		return 0;
	}
	if (!tb[ETHTOOL_A_BITSET_SIZE] || !tb[ETHTOOL_A_BITSET_VALUE])
		return -EINVAL;

	*compact = true;
	return 0;
}

/**
 * ethnl_name_to_idx() - look up string index for a name
 * @names:   array of ETH_GSTRING_LEN sized strings
 * @n_names: number of strings in the array
 * @name:    name to look up
 *
 * Return: index of the string if found, -ENOENT if not found
 */
static int ethnl_name_to_idx(ethnl_string_array_t names, unsigned int n_names,
			     const char *name)
{
	unsigned int i;

	if (!names)
		return -ENOENT;

	for (i = 0; i < n_names; i++) {
		/* names[i] may not be null terminated */
		if (!strncmp(names[i], name, ETH_GSTRING_LEN) &&
		    strlen(name) <= ETH_GSTRING_LEN)
			return i;
	}

	return -ENOENT;
}

static int ethnl_parse_bit(unsigned int *index, bool *val, unsigned int nbits,
			   const struct nlattr *bit_attr, bool no_mask,
			   ethnl_string_array_t names,
			   struct netlink_ext_ack *extack)
{
	struct nlattr *tb[ARRAY_SIZE(bit_policy)];
	int ret, idx;

	ret = nla_parse_nested(tb, ARRAY_SIZE(bit_policy) - 1, bit_attr,
			       bit_policy, extack);
	if (ret < 0)
		return ret;

	if (tb[ETHTOOL_A_BITSET_BIT_INDEX]) {
		const char *name;

		idx = nla_get_u32(tb[ETHTOOL_A_BITSET_BIT_INDEX]);
		if (idx >= nbits) {
			NL_SET_ERR_MSG_ATTR(extack,
					    tb[ETHTOOL_A_BITSET_BIT_INDEX],
					    "bit index too high");
			return -EOPNOTSUPP;
		}
		name = names ? names[idx] : NULL;
		if (tb[ETHTOOL_A_BITSET_BIT_NAME] && name &&
		    strncmp(nla_data(tb[ETHTOOL_A_BITSET_BIT_NAME]), name,
			    nla_len(tb[ETHTOOL_A_BITSET_BIT_NAME]))) {
			NL_SET_ERR_MSG_ATTR(extack, bit_attr,
					    "bit index and name mismatch");
			return -EINVAL;
		}
	} else if (tb[ETHTOOL_A_BITSET_BIT_NAME]) {
		idx = ethnl_name_to_idx(names, nbits,
					nla_data(tb[ETHTOOL_A_BITSET_BIT_NAME]));
		if (idx < 0) {
			NL_SET_ERR_MSG_ATTR(extack,
					    tb[ETHTOOL_A_BITSET_BIT_NAME],
					    "bit name not found");
			return -EOPNOTSUPP;
		}
	} else {
		NL_SET_ERR_MSG_ATTR(extack, bit_attr,
				    "neither bit index nor name specified");
		return -EINVAL;
	}

	*index = idx;
	*val = no_mask || tb[ETHTOOL_A_BITSET_BIT_VALUE];
	return 0;
}

/**
 * ethnl_bitmap32_equal() - Compare two bitmaps
 * @map1:  first bitmap
 * @map2:  second bitmap
 * @nbits: bit size to compare
 *
 * Return: true if first @nbits are equal, false if not
 */
static bool ethnl_bitmap32_equal(const u32 *map1, const u32 *map2,
				 unsigned int nbits)
{
	if (memcmp(map1, map2, nbits / 32 * sizeof(u32)))
		return false;
	if (nbits % 32 == 0)
		return true;
	return !((map1[nbits / 32] ^ map2[nbits / 32]) &
		 ethnl_lower_bits(nbits % 32));
}

static int
ethnl_update_bitset32_verbose(u32 *bitmap, unsigned int nbits,
			      const struct nlattr *attr, struct nlattr **tb,
			      ethnl_string_array_t names,
			      struct netlink_ext_ack *extack, bool *mod)
{
	u32 *saved_bitmap = NULL;
	struct nlattr *bit_attr;
	bool no_mask;
	int rem;
	int ret;

	if (tb[ETHTOOL_A_BITSET_VALUE]) {
		NL_SET_ERR_MSG_ATTR(extack, tb[ETHTOOL_A_BITSET_VALUE],
				    "value only allowed in compact bitset");
		return -EINVAL;
	}
	if (tb[ETHTOOL_A_BITSET_MASK]) {
		NL_SET_ERR_MSG_ATTR(extack, tb[ETHTOOL_A_BITSET_MASK],
				    "mask only allowed in compact bitset");
		return -EINVAL;
	}

	no_mask = tb[ETHTOOL_A_BITSET_NOMASK];
	if (no_mask) {
		unsigned int nwords = DIV_ROUND_UP(nbits, 32);
		unsigned int nbytes = nwords * sizeof(u32);
		bool dummy;

		/* The bitmap size is only the size of the map part without
		 * its mask part.
		 */
		saved_bitmap = kcalloc(nwords, sizeof(u32), GFP_KERNEL);
		if (!saved_bitmap)
			return -ENOMEM;
		memcpy(saved_bitmap, bitmap, nbytes);
		ethnl_bitmap32_clear(bitmap, 0, nbits, &dummy);
	}

	nla_for_each_nested(bit_attr, tb[ETHTOOL_A_BITSET_BITS], rem) {
		bool old_val, new_val;
		unsigned int idx;

		if (nla_type(bit_attr) != ETHTOOL_A_BITSET_BITS_BIT) {
			NL_SET_ERR_MSG_ATTR(extack, bit_attr,
					    "only ETHTOOL_A_BITSET_BITS_BIT allowed in ETHTOOL_A_BITSET_BITS");
			kfree(saved_bitmap);
			return -EINVAL;
		}
		ret = ethnl_parse_bit(&idx, &new_val, nbits, bit_attr, no_mask,
				      names, extack);
		if (ret < 0) {
			kfree(saved_bitmap);
			return ret;
		}
		old_val = bitmap[idx / 32] & ((u32)1 << (idx % 32));
		if (new_val != old_val) {
			if (new_val)
				bitmap[idx / 32] |= ((u32)1 << (idx % 32));
			else
				bitmap[idx / 32] &= ~((u32)1 << (idx % 32));
			if (!no_mask)
				*mod = true;
		}
	}

	if (no_mask && !ethnl_bitmap32_equal(saved_bitmap, bitmap, nbits))
		*mod = true;

	kfree(saved_bitmap);
	return 0;
}

static int ethnl_compact_sanity_checks(unsigned int nbits,
				       const struct nlattr *nest,
				       struct nlattr **tb,
				       struct netlink_ext_ack *extack)
{
	bool no_mask = tb[ETHTOOL_A_BITSET_NOMASK];
	unsigned int attr_nbits, attr_nwords;
	const struct nlattr *test_attr;

	if (no_mask && tb[ETHTOOL_A_BITSET_MASK]) {
		NL_SET_ERR_MSG_ATTR(extack, tb[ETHTOOL_A_BITSET_MASK],
				    "mask not allowed in list bitset");
		return -EINVAL;
	}
	if (!tb[ETHTOOL_A_BITSET_SIZE]) {
		NL_SET_ERR_MSG_ATTR(extack, nest,
				    "missing size in compact bitset");
		return -EINVAL;
	}
	if (!tb[ETHTOOL_A_BITSET_VALUE]) {
		NL_SET_ERR_MSG_ATTR(extack, nest,
				    "missing value in compact bitset");
		return -EINVAL;
	}
	if (!no_mask && !tb[ETHTOOL_A_BITSET_MASK]) {
		NL_SET_ERR_MSG_ATTR(extack, nest,
				    "missing mask in compact nonlist bitset");
		return -EINVAL;
	}

	attr_nbits = nla_get_u32(tb[ETHTOOL_A_BITSET_SIZE]);
	attr_nwords = DIV_ROUND_UP(attr_nbits, 32);
	if (nla_len(tb[ETHTOOL_A_BITSET_VALUE]) != attr_nwords * sizeof(u32)) {
		NL_SET_ERR_MSG_ATTR(extack, tb[ETHTOOL_A_BITSET_VALUE],
				    "bitset value length does not match size");
		return -EINVAL;
	}
	if (tb[ETHTOOL_A_BITSET_MASK] &&
	    nla_len(tb[ETHTOOL_A_BITSET_MASK]) != attr_nwords * sizeof(u32)) {
		NL_SET_ERR_MSG_ATTR(extack, tb[ETHTOOL_A_BITSET_MASK],
				    "bitset mask length does not match size");
		return -EINVAL;
	}
	if (attr_nbits <= nbits)
		return 0;

	test_attr = no_mask ? tb[ETHTOOL_A_BITSET_VALUE] :
			      tb[ETHTOOL_A_BITSET_MASK];
	if (ethnl_bitmap32_not_zero(nla_data(test_attr), nbits, attr_nbits)) {
		NL_SET_ERR_MSG_ATTR(extack, test_attr,
				    "cannot modify bits past kernel bitset size");
		return -EINVAL;
	}
	return 0;
}

/**
 * ethnl_update_bitset32() - Apply a bitset nest to a u32 based bitmap
 * @bitmap:  bitmap to update
 * @nbits:   size of the updated bitmap in bits
 * @attr:    nest attribute to parse and apply
 * @names:   array of bit names; may be null for compact format
 * @extack:  extack for error reporting
 * @mod:     set this to true if bitmap is modified, leave as it is if not
 *
 * Apply bitset netsted attribute to a bitmap. If the attribute represents
 * a bit list, @bitmap is set to its contents; otherwise, bits in mask are
 * set to values from value. Bitmaps in the attribute may be longer than
 * @nbits but the message must not request modifying any bits past @nbits.
 *
 * Return: negative error code on failure, 0 on success
 */
int ethnl_update_bitset32(u32 *bitmap, unsigned int nbits,
			  const struct nlattr *attr, ethnl_string_array_t names,
			  struct netlink_ext_ack *extack, bool *mod)
{
	struct nlattr *tb[ARRAY_SIZE(bitset_policy)];
	unsigned int change_bits;
	bool no_mask;
	int ret;

	if (!attr)
		return 0;
	ret = nla_parse_nested(tb, ARRAY_SIZE(bitset_policy) - 1, attr,
			       bitset_policy, extack);
	if (ret < 0)
		return ret;

	if (tb[ETHTOOL_A_BITSET_BITS])
		return ethnl_update_bitset32_verbose(bitmap, nbits, attr, tb,
						     names, extack, mod);
	ret = ethnl_compact_sanity_checks(nbits, attr, tb, extack);
	if (ret < 0)
		return ret;

	no_mask = tb[ETHTOOL_A_BITSET_NOMASK];
	change_bits = min_t(unsigned int,
			    nla_get_u32(tb[ETHTOOL_A_BITSET_SIZE]), nbits);
	ethnl_bitmap32_update(bitmap, change_bits,
			      nla_data(tb[ETHTOOL_A_BITSET_VALUE]),
			      no_mask ? NULL :
					nla_data(tb[ETHTOOL_A_BITSET_MASK]),
			      mod);
	if (no_mask && change_bits < nbits)
		ethnl_bitmap32_clear(bitmap, change_bits, nbits, mod);

	return 0;
}

/**
 * ethnl_parse_bitset() - Compute effective value and mask from bitset nest
 * @val:     unsigned long based bitmap to put value into
 * @mask:    unsigned long based bitmap to put mask into
 * @nbits:   size of @val and @mask bitmaps
 * @attr:    nest attribute to parse and apply
 * @names:   array of bit names; may be null for compact format
 * @extack:  extack for error reporting
 *
 * Provide @nbits size long bitmaps for value and mask so that
 * x = (val & mask) | (x & ~mask) would modify any @nbits sized bitmap x
 * the same way ethnl_update_bitset() with the same bitset attribute would.
 *
 * Return:   negative error code on failure, 0 on success
 */
int ethnl_parse_bitset(unsigned long *val, unsigned long *mask,
		       unsigned int nbits, const struct nlattr *attr,
		       ethnl_string_array_t names,
		       struct netlink_ext_ack *extack)
{
	struct nlattr *tb[ARRAY_SIZE(bitset_policy)];
	const struct nlattr *bit_attr;
	bool no_mask;
	int rem;
	int ret;

	if (!attr)
		return 0;
	ret = nla_parse_nested(tb, ARRAY_SIZE(bitset_policy) - 1, attr,
			       bitset_policy, extack);
	if (ret < 0)
		return ret;
	no_mask = tb[ETHTOOL_A_BITSET_NOMASK];

	if (!tb[ETHTOOL_A_BITSET_BITS]) {
		unsigned int change_bits;

		ret = ethnl_compact_sanity_checks(nbits, attr, tb, extack);
		if (ret < 0)
			return ret;

		change_bits = nla_get_u32(tb[ETHTOOL_A_BITSET_SIZE]);
		if (change_bits > nbits)
			change_bits = nbits;
		bitmap_from_arr32(val, nla_data(tb[ETHTOOL_A_BITSET_VALUE]),
				  change_bits);
		if (change_bits < nbits)
			bitmap_clear(val, change_bits, nbits - change_bits);
		if (no_mask) {
			bitmap_fill(mask, nbits);
		} else {
			bitmap_from_arr32(mask,
					  nla_data(tb[ETHTOOL_A_BITSET_MASK]),
					  change_bits);
			if (change_bits < nbits)
				bitmap_clear(mask, change_bits,
					     nbits - change_bits);
		}

		return 0;
	}

	if (tb[ETHTOOL_A_BITSET_VALUE]) {
		NL_SET_ERR_MSG_ATTR(extack, tb[ETHTOOL_A_BITSET_VALUE],
				    "value only allowed in compact bitset");
		return -EINVAL;
	}
	if (tb[ETHTOOL_A_BITSET_MASK]) {
		NL_SET_ERR_MSG_ATTR(extack, tb[ETHTOOL_A_BITSET_MASK],
				    "mask only allowed in compact bitset");
		return -EINVAL;
	}

	bitmap_zero(val, nbits);
	if (no_mask)
		bitmap_fill(mask, nbits);
	else
		bitmap_zero(mask, nbits);

	nla_for_each_nested(bit_attr, tb[ETHTOOL_A_BITSET_BITS], rem) {
		unsigned int idx;
		bool bit_val;

		ret = ethnl_parse_bit(&idx, &bit_val, nbits, bit_attr, no_mask,
				      names, extack);
		if (ret < 0)
			return ret;
		if (bit_val)
			__set_bit(idx, val);
		if (!no_mask)
			__set_bit(idx, mask);
	}

	return 0;
}

#if BITS_PER_LONG == 64 && defined(__BIG_ENDIAN)

/* 64-bit big endian architectures are the only case when u32 based bitmaps
 * and unsigned long based bitmaps have different memory layout so that we
 * cannot simply cast the latter to the former and need actual wrappers
 * converting the latter to the former.
 *
 * To reduce the number of slab allocations, the wrappers use fixed size local
 * variables for bitmaps up to ETHNL_SMALL_BITMAP_BITS bits which is the
 * majority of bitmaps used by ethtool.
 */
#define ETHNL_SMALL_BITMAP_BITS 128
#define ETHNL_SMALL_BITMAP_WORDS DIV_ROUND_UP(ETHNL_SMALL_BITMAP_BITS, 32)

int ethnl_bitset_size(const unsigned long *val, const unsigned long *mask,
		      unsigned int nbits, ethnl_string_array_t names,
		      bool compact)
{
	u32 small_mask32[ETHNL_SMALL_BITMAP_WORDS];
	u32 small_val32[ETHNL_SMALL_BITMAP_WORDS];
	u32 *mask32;
	u32 *val32;
	int ret;

	if (nbits > ETHNL_SMALL_BITMAP_BITS) {
		unsigned int nwords = DIV_ROUND_UP(nbits, 32);

		val32 = kmalloc_array(2 * nwords, sizeof(u32), GFP_KERNEL);
		if (!val32)
			return -ENOMEM;
		mask32 = val32 + nwords;
	} else {
		val32 = small_val32;
		mask32 = small_mask32;
	}

	bitmap_to_arr32(val32, val, nbits);
	if (mask)
		bitmap_to_arr32(mask32, mask, nbits);
	else
		mask32 = NULL;
	ret = ethnl_bitset32_size(val32, mask32, nbits, names, compact);

	if (nbits > ETHNL_SMALL_BITMAP_BITS)
		kfree(val32);

	return ret;
}

int ethnl_put_bitset(struct sk_buff *skb, int attrtype,
		     const unsigned long *val, const unsigned long *mask,
		     unsigned int nbits, ethnl_string_array_t names,
		     bool compact)
{
	u32 small_mask32[ETHNL_SMALL_BITMAP_WORDS];
	u32 small_val32[ETHNL_SMALL_BITMAP_WORDS];
	u32 *mask32;
	u32 *val32;
	int ret;

	if (nbits > ETHNL_SMALL_BITMAP_BITS) {
		unsigned int nwords = DIV_ROUND_UP(nbits, 32);

		val32 = kmalloc_array(2 * nwords, sizeof(u32), GFP_KERNEL);
		if (!val32)
			return -ENOMEM;
		mask32 = val32 + nwords;
	} else {
		val32 = small_val32;
		mask32 = small_mask32;
	}

	bitmap_to_arr32(val32, val, nbits);
	if (mask)
		bitmap_to_arr32(mask32, mask, nbits);
	else
		mask32 = NULL;
	ret = ethnl_put_bitset32(skb, attrtype, val32, mask32, nbits, names,
				 compact);

	if (nbits > ETHNL_SMALL_BITMAP_BITS)
		kfree(val32);

	return ret;
}

int ethnl_update_bitset(unsigned long *bitmap, unsigned int nbits,
			const struct nlattr *attr, ethnl_string_array_t names,
			struct netlink_ext_ack *extack, bool *mod)
{
	u32 small_bitmap32[ETHNL_SMALL_BITMAP_WORDS];
	u32 *bitmap32 = small_bitmap32;
	bool u32_mod = false;
	int ret;

	if (nbits > ETHNL_SMALL_BITMAP_BITS) {
		unsigned int dst_words = DIV_ROUND_UP(nbits, 32);

		bitmap32 = kmalloc_array(dst_words, sizeof(u32), GFP_KERNEL);
		if (!bitmap32)
			return -ENOMEM;
	}

	bitmap_to_arr32(bitmap32, bitmap, nbits);
	ret = ethnl_update_bitset32(bitmap32, nbits, attr, names, extack,
				    &u32_mod);
	if (u32_mod) {
		bitmap_from_arr32(bitmap, bitmap32, nbits);
		*mod = true;
	}

	if (nbits > ETHNL_SMALL_BITMAP_BITS)
		kfree(bitmap32);

	return ret;
}

#else

/* On little endian 64-bit and all 32-bit architectures, an unsigned long
 * based bitmap can be interpreted as u32 based one using a simple cast.
 */

int ethnl_bitset_size(const unsigned long *val, const unsigned long *mask,
		      unsigned int nbits, ethnl_string_array_t names,
		      bool compact)
{
	return ethnl_bitset32_size((const u32 *)val, (const u32 *)mask, nbits,
				   names, compact);
}

int ethnl_put_bitset(struct sk_buff *skb, int attrtype,
		     const unsigned long *val, const unsigned long *mask,
		     unsigned int nbits, ethnl_string_array_t names,
		     bool compact)
{
	return ethnl_put_bitset32(skb, attrtype, (const u32 *)val,
				  (const u32 *)mask, nbits, names, compact);
}

int ethnl_update_bitset(unsigned long *bitmap, unsigned int nbits,
			const struct nlattr *attr, ethnl_string_array_t names,
			struct netlink_ext_ack *extack, bool *mod)
{
	return ethnl_update_bitset32((u32 *)bitmap, nbits, attr, names, extack,
				     mod);
}

#endif /* BITS_PER_LONG == 64 && defined(__BIG_ENDIAN) */
