1 // SPDX-License-Identifier: GPL-2.0-only 2 3 #include <linux/ethtool_netlink.h> 4 #include <linux/bitmap.h> 5 6 #include "bitset.h" 7 #include "netlink.h" 8 9 /* Some bitmaps are internally represented as an array of unsigned long, some 10 * as an array of u32 (some even as single u32 for now). To avoid the need of 11 * wrappers on caller side, we provide two set of functions: those with "32" 12 * suffix in their names expect u32 based bitmaps, those without it expect 13 * unsigned long bitmaps. 14 */ 15 16 static u32 ethnl_lower_bits(unsigned int n) 17 { 18 return ~(u32)0 >> (32 - n % 32); 19 } 20 21 static u32 ethnl_upper_bits(unsigned int n) 22 { 23 return ~(u32)0 << (n % 32); 24 } 25 26 /** 27 * ethnl_bitmap32_clear() - Clear u32 based bitmap 28 * @dst: bitmap to clear 29 * @start: beginning of the interval 30 * @end: end of the interval 31 * @mod: set if bitmap was modified 32 * 33 * Clear @nbits bits of a bitmap with indices @start <= i < @end 34 */ 35 static void ethnl_bitmap32_clear(u32 *dst, unsigned int start, unsigned int end, 36 bool *mod) 37 { 38 unsigned int start_word = start / 32; 39 unsigned int end_word = end / 32; 40 unsigned int i; 41 u32 mask; 42 43 if (end <= start) 44 return; 45 46 if (start % 32) { 47 mask = ethnl_upper_bits(start); 48 if (end_word == start_word) { 49 mask &= ethnl_lower_bits(end); 50 if (dst[start_word] & mask) { 51 dst[start_word] &= ~mask; 52 *mod = true; 53 } 54 return; 55 } 56 if (dst[start_word] & mask) { 57 dst[start_word] &= ~mask; 58 *mod = true; 59 } 60 start_word++; 61 } 62 63 for (i = start_word; i < end_word; i++) { 64 if (dst[i]) { 65 dst[i] = 0; 66 *mod = true; 67 } 68 } 69 if (end % 32) { 70 mask = ethnl_lower_bits(end); 71 if (dst[end_word] & mask) { 72 dst[end_word] &= ~mask; 73 *mod = true; 74 } 75 } 76 } 77 78 /** 79 * ethnl_bitmap32_not_zero() - Check if any bit is set in an interval 80 * @map: bitmap to test 81 * @start: beginning of the interval 82 * @end: end of the interval 83 * 84 * Return: true if there is non-zero bit with index @start <= i < @end, 85 * false if the whole interval is zero 86 */ 87 static bool ethnl_bitmap32_not_zero(const u32 *map, unsigned int start, 88 unsigned int end) 89 { 90 unsigned int start_word = start / 32; 91 unsigned int end_word = end / 32; 92 u32 mask; 93 94 if (end <= start) 95 return true; 96 97 if (start % 32) { 98 mask = ethnl_upper_bits(start); 99 if (end_word == start_word) { 100 mask &= ethnl_lower_bits(end); 101 return map[start_word] & mask; 102 } 103 if (map[start_word] & mask) 104 return true; 105 start_word++; 106 } 107 108 if (!memchr_inv(map + start_word, '\0', 109 (end_word - start_word) * sizeof(u32))) 110 return true; 111 if (end % 32 == 0) 112 return true; 113 return map[end_word] & ethnl_lower_bits(end); 114 } 115 116 /** 117 * ethnl_bitmap32_update() - Modify u32 based bitmap according to value/mask 118 * pair 119 * @dst: bitmap to update 120 * @nbits: bit size of the bitmap 121 * @value: values to set 122 * @mask: mask of bits to set 123 * @mod: set to true if bitmap is modified, preserve if not 124 * 125 * Set bits in @dst bitmap which are set in @mask to values from @value, leave 126 * the rest untouched. If destination bitmap was modified, set @mod to true, 127 * leave as it is if not. 128 */ 129 static void ethnl_bitmap32_update(u32 *dst, unsigned int nbits, 130 const u32 *value, const u32 *mask, bool *mod) 131 { 132 while (nbits > 0) { 133 u32 real_mask = mask ? *mask : ~(u32)0; 134 u32 new_value; 135 136 if (nbits < 32) 137 real_mask &= ethnl_lower_bits(nbits); 138 new_value = (*dst & ~real_mask) | (*value & real_mask); 139 if (new_value != *dst) { 140 *dst = new_value; 141 *mod = true; 142 } 143 144 if (nbits <= 32) 145 break; 146 dst++; 147 nbits -= 32; 148 value++; 149 if (mask) 150 mask++; 151 } 152 } 153 154 static bool ethnl_bitmap32_test_bit(const u32 *map, unsigned int index) 155 { 156 return map[index / 32] & (1U << (index % 32)); 157 } 158 159 /** 160 * ethnl_bitset32_size() - Calculate size of bitset nested attribute 161 * @val: value bitmap (u32 based) 162 * @mask: mask bitmap (u32 based, optional) 163 * @nbits: bit length of the bitset 164 * @names: array of bit names (optional) 165 * @compact: assume compact format for output 166 * 167 * Estimate length of netlink attribute composed by a later call to 168 * ethnl_put_bitset32() call with the same arguments. 169 * 170 * Return: negative error code or attribute length estimate 171 */ 172 int ethnl_bitset32_size(const u32 *val, const u32 *mask, unsigned int nbits, 173 ethnl_string_array_t names, bool compact) 174 { 175 unsigned int len = 0; 176 177 /* list flag */ 178 if (!mask) 179 len += nla_total_size(sizeof(u32)); 180 /* size */ 181 len += nla_total_size(sizeof(u32)); 182 183 if (compact) { 184 unsigned int nwords = DIV_ROUND_UP(nbits, 32); 185 186 /* value, mask */ 187 len += (mask ? 2 : 1) * nla_total_size(nwords * sizeof(u32)); 188 } else { 189 unsigned int bits_len = 0; 190 unsigned int bit_len, i; 191 192 for (i = 0; i < nbits; i++) { 193 const char *name = names ? names[i] : NULL; 194 195 if (!ethnl_bitmap32_test_bit(mask ?: val, i)) 196 continue; 197 /* index */ 198 bit_len = nla_total_size(sizeof(u32)); 199 /* name */ 200 if (name) 201 bit_len += ethnl_strz_size(name); 202 /* value */ 203 if (mask && ethnl_bitmap32_test_bit(val, i)) 204 bit_len += nla_total_size(0); 205 206 /* bit nest */ 207 bits_len += nla_total_size(bit_len); 208 } 209 /* bits nest */ 210 len += nla_total_size(bits_len); 211 } 212 213 /* outermost nest */ 214 return nla_total_size(len); 215 } 216 217 /** 218 * ethnl_put_bitset32() - Put a bitset nest into a message 219 * @skb: skb with the message 220 * @attrtype: attribute type for the bitset nest 221 * @val: value bitmap (u32 based) 222 * @mask: mask bitmap (u32 based, optional) 223 * @nbits: bit length of the bitset 224 * @names: array of bit names (optional) 225 * @compact: use compact format for the output 226 * 227 * Compose a nested attribute representing a bitset. If @mask is null, simple 228 * bitmap (bit list) is created, if @mask is provided, represent a value/mask 229 * pair. Bit names are only used in verbose mode and when provided by calller. 230 * 231 * Return: 0 on success, negative error value on error 232 */ 233 int ethnl_put_bitset32(struct sk_buff *skb, int attrtype, const u32 *val, 234 const u32 *mask, unsigned int nbits, 235 ethnl_string_array_t names, bool compact) 236 { 237 struct nlattr *nest; 238 struct nlattr *attr; 239 240 nest = nla_nest_start(skb, attrtype); 241 if (!nest) 242 return -EMSGSIZE; 243 244 if (!mask && nla_put_flag(skb, ETHTOOL_A_BITSET_NOMASK)) 245 goto nla_put_failure; 246 if (nla_put_u32(skb, ETHTOOL_A_BITSET_SIZE, nbits)) 247 goto nla_put_failure; 248 if (compact) { 249 unsigned int nwords = DIV_ROUND_UP(nbits, 32); 250 unsigned int nbytes = nwords * sizeof(u32); 251 u32 *dst; 252 253 attr = nla_reserve(skb, ETHTOOL_A_BITSET_VALUE, nbytes); 254 if (!attr) 255 goto nla_put_failure; 256 dst = nla_data(attr); 257 memcpy(dst, val, nbytes); 258 if (nbits % 32) 259 dst[nwords - 1] &= ethnl_lower_bits(nbits); 260 261 if (mask) { 262 attr = nla_reserve(skb, ETHTOOL_A_BITSET_MASK, nbytes); 263 if (!attr) 264 goto nla_put_failure; 265 dst = nla_data(attr); 266 memcpy(dst, mask, nbytes); 267 if (nbits % 32) 268 dst[nwords - 1] &= ethnl_lower_bits(nbits); 269 } 270 } else { 271 struct nlattr *bits; 272 unsigned int i; 273 274 bits = nla_nest_start(skb, ETHTOOL_A_BITSET_BITS); 275 if (!bits) 276 goto nla_put_failure; 277 for (i = 0; i < nbits; i++) { 278 const char *name = names ? names[i] : NULL; 279 280 if (!ethnl_bitmap32_test_bit(mask ?: val, i)) 281 continue; 282 attr = nla_nest_start(skb, ETHTOOL_A_BITSET_BITS_BIT); 283 if (!attr) 284 goto nla_put_failure; 285 if (nla_put_u32(skb, ETHTOOL_A_BITSET_BIT_INDEX, i)) 286 goto nla_put_failure; 287 if (name && 288 ethnl_put_strz(skb, ETHTOOL_A_BITSET_BIT_NAME, name)) 289 goto nla_put_failure; 290 if (mask && ethnl_bitmap32_test_bit(val, i) && 291 nla_put_flag(skb, ETHTOOL_A_BITSET_BIT_VALUE)) 292 goto nla_put_failure; 293 nla_nest_end(skb, attr); 294 } 295 nla_nest_end(skb, bits); 296 } 297 298 nla_nest_end(skb, nest); 299 return 0; 300 301 nla_put_failure: 302 nla_nest_cancel(skb, nest); 303 return -EMSGSIZE; 304 } 305 306 static const struct nla_policy bitset_policy[] = { 307 [ETHTOOL_A_BITSET_NOMASK] = { .type = NLA_FLAG }, 308 [ETHTOOL_A_BITSET_SIZE] = NLA_POLICY_MAX(NLA_U32, 309 ETHNL_MAX_BITSET_SIZE), 310 [ETHTOOL_A_BITSET_BITS] = { .type = NLA_NESTED }, 311 [ETHTOOL_A_BITSET_VALUE] = { .type = NLA_BINARY }, 312 [ETHTOOL_A_BITSET_MASK] = { .type = NLA_BINARY }, 313 }; 314 315 static const struct nla_policy bit_policy[] = { 316 [ETHTOOL_A_BITSET_BIT_INDEX] = { .type = NLA_U32 }, 317 [ETHTOOL_A_BITSET_BIT_NAME] = { .type = NLA_NUL_STRING }, 318 [ETHTOOL_A_BITSET_BIT_VALUE] = { .type = NLA_FLAG }, 319 }; 320 321 /** 322 * ethnl_bitset_is_compact() - check if bitset attribute represents a compact 323 * bitset 324 * @bitset: nested attribute representing a bitset 325 * @compact: pointer for return value 326 * 327 * Return: 0 on success, negative error code on failure 328 */ 329 int ethnl_bitset_is_compact(const struct nlattr *bitset, bool *compact) 330 { 331 struct nlattr *tb[ARRAY_SIZE(bitset_policy)]; 332 int ret; 333 334 ret = nla_parse_nested(tb, ARRAY_SIZE(bitset_policy) - 1, bitset, 335 bitset_policy, NULL); 336 if (ret < 0) 337 return ret; 338 339 if (tb[ETHTOOL_A_BITSET_BITS]) { 340 if (tb[ETHTOOL_A_BITSET_VALUE] || tb[ETHTOOL_A_BITSET_MASK]) 341 return -EINVAL; 342 *compact = false; 343 return 0; 344 } 345 if (!tb[ETHTOOL_A_BITSET_SIZE] || !tb[ETHTOOL_A_BITSET_VALUE]) 346 return -EINVAL; 347 348 *compact = true; 349 return 0; 350 } 351 352 /** 353 * ethnl_name_to_idx() - look up string index for a name 354 * @names: array of ETH_GSTRING_LEN sized strings 355 * @n_names: number of strings in the array 356 * @name: name to look up 357 * 358 * Return: index of the string if found, -ENOENT if not found 359 */ 360 static int ethnl_name_to_idx(ethnl_string_array_t names, unsigned int n_names, 361 const char *name) 362 { 363 unsigned int i; 364 365 if (!names) 366 return -ENOENT; 367 368 for (i = 0; i < n_names; i++) { 369 /* names[i] may not be null terminated */ 370 if (!strncmp(names[i], name, ETH_GSTRING_LEN) && 371 strlen(name) <= ETH_GSTRING_LEN) 372 return i; 373 } 374 375 return -ENOENT; 376 } 377 378 static int ethnl_parse_bit(unsigned int *index, bool *val, unsigned int nbits, 379 const struct nlattr *bit_attr, bool no_mask, 380 ethnl_string_array_t names, 381 struct netlink_ext_ack *extack) 382 { 383 struct nlattr *tb[ARRAY_SIZE(bit_policy)]; 384 int ret, idx; 385 386 ret = nla_parse_nested(tb, ARRAY_SIZE(bit_policy) - 1, bit_attr, 387 bit_policy, extack); 388 if (ret < 0) 389 return ret; 390 391 if (tb[ETHTOOL_A_BITSET_BIT_INDEX]) { 392 const char *name; 393 394 idx = nla_get_u32(tb[ETHTOOL_A_BITSET_BIT_INDEX]); 395 if (idx >= nbits) { 396 NL_SET_ERR_MSG_ATTR(extack, 397 tb[ETHTOOL_A_BITSET_BIT_INDEX], 398 "bit index too high"); 399 return -EOPNOTSUPP; 400 } 401 name = names ? names[idx] : NULL; 402 if (tb[ETHTOOL_A_BITSET_BIT_NAME] && name && 403 strncmp(nla_data(tb[ETHTOOL_A_BITSET_BIT_NAME]), name, 404 nla_len(tb[ETHTOOL_A_BITSET_BIT_NAME]))) { 405 NL_SET_ERR_MSG_ATTR(extack, bit_attr, 406 "bit index and name mismatch"); 407 return -EINVAL; 408 } 409 } else if (tb[ETHTOOL_A_BITSET_BIT_NAME]) { 410 idx = ethnl_name_to_idx(names, nbits, 411 nla_data(tb[ETHTOOL_A_BITSET_BIT_NAME])); 412 if (idx < 0) { 413 NL_SET_ERR_MSG_ATTR(extack, 414 tb[ETHTOOL_A_BITSET_BIT_NAME], 415 "bit name not found"); 416 return -EOPNOTSUPP; 417 } 418 } else { 419 NL_SET_ERR_MSG_ATTR(extack, bit_attr, 420 "neither bit index nor name specified"); 421 return -EINVAL; 422 } 423 424 *index = idx; 425 *val = no_mask || tb[ETHTOOL_A_BITSET_BIT_VALUE]; 426 return 0; 427 } 428 429 /** 430 * ethnl_bitmap32_equal() - Compare two bitmaps 431 * @map1: first bitmap 432 * @map2: second bitmap 433 * @nbits: bit size to compare 434 * 435 * Return: true if first @nbits are equal, false if not 436 */ 437 static bool ethnl_bitmap32_equal(const u32 *map1, const u32 *map2, 438 unsigned int nbits) 439 { 440 if (memcmp(map1, map2, nbits / 32 * sizeof(u32))) 441 return false; 442 if (nbits % 32 == 0) 443 return true; 444 return !((map1[nbits / 32] ^ map2[nbits / 32]) & 445 ethnl_lower_bits(nbits % 32)); 446 } 447 448 static int 449 ethnl_update_bitset32_verbose(u32 *bitmap, unsigned int nbits, 450 const struct nlattr *attr, struct nlattr **tb, 451 ethnl_string_array_t names, 452 struct netlink_ext_ack *extack, bool *mod) 453 { 454 u32 *saved_bitmap = NULL; 455 struct nlattr *bit_attr; 456 bool no_mask; 457 int rem; 458 int ret; 459 460 if (tb[ETHTOOL_A_BITSET_VALUE]) { 461 NL_SET_ERR_MSG_ATTR(extack, tb[ETHTOOL_A_BITSET_VALUE], 462 "value only allowed in compact bitset"); 463 return -EINVAL; 464 } 465 if (tb[ETHTOOL_A_BITSET_MASK]) { 466 NL_SET_ERR_MSG_ATTR(extack, tb[ETHTOOL_A_BITSET_MASK], 467 "mask only allowed in compact bitset"); 468 return -EINVAL; 469 } 470 471 no_mask = tb[ETHTOOL_A_BITSET_NOMASK]; 472 if (no_mask) { 473 unsigned int nwords = DIV_ROUND_UP(nbits, 32); 474 unsigned int nbytes = nwords * sizeof(u32); 475 bool dummy; 476 477 /* The bitmap size is only the size of the map part without 478 * its mask part. 479 */ 480 saved_bitmap = kcalloc(nwords, sizeof(u32), GFP_KERNEL); 481 if (!saved_bitmap) 482 return -ENOMEM; 483 memcpy(saved_bitmap, bitmap, nbytes); 484 ethnl_bitmap32_clear(bitmap, 0, nbits, &dummy); 485 } 486 487 nla_for_each_nested(bit_attr, tb[ETHTOOL_A_BITSET_BITS], rem) { 488 bool old_val, new_val; 489 unsigned int idx; 490 491 if (nla_type(bit_attr) != ETHTOOL_A_BITSET_BITS_BIT) { 492 NL_SET_ERR_MSG_ATTR(extack, bit_attr, 493 "only ETHTOOL_A_BITSET_BITS_BIT allowed in ETHTOOL_A_BITSET_BITS"); 494 kfree(saved_bitmap); 495 return -EINVAL; 496 } 497 ret = ethnl_parse_bit(&idx, &new_val, nbits, bit_attr, no_mask, 498 names, extack); 499 if (ret < 0) { 500 kfree(saved_bitmap); 501 return ret; 502 } 503 old_val = bitmap[idx / 32] & ((u32)1 << (idx % 32)); 504 if (new_val != old_val) { 505 if (new_val) 506 bitmap[idx / 32] |= ((u32)1 << (idx % 32)); 507 else 508 bitmap[idx / 32] &= ~((u32)1 << (idx % 32)); 509 if (!no_mask) 510 *mod = true; 511 } 512 } 513 514 if (no_mask && !ethnl_bitmap32_equal(saved_bitmap, bitmap, nbits)) 515 *mod = true; 516 517 kfree(saved_bitmap); 518 return 0; 519 } 520 521 static int ethnl_compact_sanity_checks(unsigned int nbits, 522 const struct nlattr *nest, 523 struct nlattr **tb, 524 struct netlink_ext_ack *extack) 525 { 526 bool no_mask = tb[ETHTOOL_A_BITSET_NOMASK]; 527 unsigned int attr_nbits, attr_nwords; 528 const struct nlattr *test_attr; 529 530 if (no_mask && tb[ETHTOOL_A_BITSET_MASK]) { 531 NL_SET_ERR_MSG_ATTR(extack, tb[ETHTOOL_A_BITSET_MASK], 532 "mask not allowed in list bitset"); 533 return -EINVAL; 534 } 535 if (!tb[ETHTOOL_A_BITSET_SIZE]) { 536 NL_SET_ERR_MSG_ATTR(extack, nest, 537 "missing size in compact bitset"); 538 return -EINVAL; 539 } 540 if (!tb[ETHTOOL_A_BITSET_VALUE]) { 541 NL_SET_ERR_MSG_ATTR(extack, nest, 542 "missing value in compact bitset"); 543 return -EINVAL; 544 } 545 if (!no_mask && !tb[ETHTOOL_A_BITSET_MASK]) { 546 NL_SET_ERR_MSG_ATTR(extack, nest, 547 "missing mask in compact nonlist bitset"); 548 return -EINVAL; 549 } 550 551 attr_nbits = nla_get_u32(tb[ETHTOOL_A_BITSET_SIZE]); 552 attr_nwords = DIV_ROUND_UP(attr_nbits, 32); 553 if (nla_len(tb[ETHTOOL_A_BITSET_VALUE]) != attr_nwords * sizeof(u32)) { 554 NL_SET_ERR_MSG_ATTR(extack, tb[ETHTOOL_A_BITSET_VALUE], 555 "bitset value length does not match size"); 556 return -EINVAL; 557 } 558 if (tb[ETHTOOL_A_BITSET_MASK] && 559 nla_len(tb[ETHTOOL_A_BITSET_MASK]) != attr_nwords * sizeof(u32)) { 560 NL_SET_ERR_MSG_ATTR(extack, tb[ETHTOOL_A_BITSET_MASK], 561 "bitset mask length does not match size"); 562 return -EINVAL; 563 } 564 if (attr_nbits <= nbits) 565 return 0; 566 567 test_attr = no_mask ? tb[ETHTOOL_A_BITSET_VALUE] : 568 tb[ETHTOOL_A_BITSET_MASK]; 569 if (ethnl_bitmap32_not_zero(nla_data(test_attr), nbits, attr_nbits)) { 570 NL_SET_ERR_MSG_ATTR(extack, test_attr, 571 "cannot modify bits past kernel bitset size"); 572 return -EINVAL; 573 } 574 return 0; 575 } 576 577 /** 578 * ethnl_update_bitset32() - Apply a bitset nest to a u32 based bitmap 579 * @bitmap: bitmap to update 580 * @nbits: size of the updated bitmap in bits 581 * @attr: nest attribute to parse and apply 582 * @names: array of bit names; may be null for compact format 583 * @extack: extack for error reporting 584 * @mod: set this to true if bitmap is modified, leave as it is if not 585 * 586 * Apply bitset netsted attribute to a bitmap. If the attribute represents 587 * a bit list, @bitmap is set to its contents; otherwise, bits in mask are 588 * set to values from value. Bitmaps in the attribute may be longer than 589 * @nbits but the message must not request modifying any bits past @nbits. 590 * 591 * Return: negative error code on failure, 0 on success 592 */ 593 int ethnl_update_bitset32(u32 *bitmap, unsigned int nbits, 594 const struct nlattr *attr, ethnl_string_array_t names, 595 struct netlink_ext_ack *extack, bool *mod) 596 { 597 struct nlattr *tb[ARRAY_SIZE(bitset_policy)]; 598 unsigned int change_bits; 599 bool no_mask; 600 int ret; 601 602 if (!attr) 603 return 0; 604 ret = nla_parse_nested(tb, ARRAY_SIZE(bitset_policy) - 1, attr, 605 bitset_policy, extack); 606 if (ret < 0) 607 return ret; 608 609 if (tb[ETHTOOL_A_BITSET_BITS]) 610 return ethnl_update_bitset32_verbose(bitmap, nbits, attr, tb, 611 names, extack, mod); 612 ret = ethnl_compact_sanity_checks(nbits, attr, tb, extack); 613 if (ret < 0) 614 return ret; 615 616 no_mask = tb[ETHTOOL_A_BITSET_NOMASK]; 617 change_bits = min_t(unsigned int, 618 nla_get_u32(tb[ETHTOOL_A_BITSET_SIZE]), nbits); 619 ethnl_bitmap32_update(bitmap, change_bits, 620 nla_data(tb[ETHTOOL_A_BITSET_VALUE]), 621 no_mask ? NULL : 622 nla_data(tb[ETHTOOL_A_BITSET_MASK]), 623 mod); 624 if (no_mask && change_bits < nbits) 625 ethnl_bitmap32_clear(bitmap, change_bits, nbits, mod); 626 627 return 0; 628 } 629 630 /** 631 * ethnl_parse_bitset() - Compute effective value and mask from bitset nest 632 * @val: unsigned long based bitmap to put value into 633 * @mask: unsigned long based bitmap to put mask into 634 * @nbits: size of @val and @mask bitmaps 635 * @attr: nest attribute to parse and apply 636 * @names: array of bit names; may be null for compact format 637 * @extack: extack for error reporting 638 * 639 * Provide @nbits size long bitmaps for value and mask so that 640 * x = (val & mask) | (x & ~mask) would modify any @nbits sized bitmap x 641 * the same way ethnl_update_bitset() with the same bitset attribute would. 642 * 643 * Return: negative error code on failure, 0 on success 644 */ 645 int ethnl_parse_bitset(unsigned long *val, unsigned long *mask, 646 unsigned int nbits, const struct nlattr *attr, 647 ethnl_string_array_t names, 648 struct netlink_ext_ack *extack) 649 { 650 struct nlattr *tb[ARRAY_SIZE(bitset_policy)]; 651 const struct nlattr *bit_attr; 652 bool no_mask; 653 int rem; 654 int ret; 655 656 if (!attr) 657 return 0; 658 ret = nla_parse_nested(tb, ARRAY_SIZE(bitset_policy) - 1, attr, 659 bitset_policy, extack); 660 if (ret < 0) 661 return ret; 662 no_mask = tb[ETHTOOL_A_BITSET_NOMASK]; 663 664 if (!tb[ETHTOOL_A_BITSET_BITS]) { 665 unsigned int change_bits; 666 667 ret = ethnl_compact_sanity_checks(nbits, attr, tb, extack); 668 if (ret < 0) 669 return ret; 670 671 change_bits = nla_get_u32(tb[ETHTOOL_A_BITSET_SIZE]); 672 if (change_bits > nbits) 673 change_bits = nbits; 674 bitmap_from_arr32(val, nla_data(tb[ETHTOOL_A_BITSET_VALUE]), 675 change_bits); 676 if (change_bits < nbits) 677 bitmap_clear(val, change_bits, nbits - change_bits); 678 if (no_mask) { 679 bitmap_fill(mask, nbits); 680 } else { 681 bitmap_from_arr32(mask, 682 nla_data(tb[ETHTOOL_A_BITSET_MASK]), 683 change_bits); 684 if (change_bits < nbits) 685 bitmap_clear(mask, change_bits, 686 nbits - change_bits); 687 } 688 689 return 0; 690 } 691 692 if (tb[ETHTOOL_A_BITSET_VALUE]) { 693 NL_SET_ERR_MSG_ATTR(extack, tb[ETHTOOL_A_BITSET_VALUE], 694 "value only allowed in compact bitset"); 695 return -EINVAL; 696 } 697 if (tb[ETHTOOL_A_BITSET_MASK]) { 698 NL_SET_ERR_MSG_ATTR(extack, tb[ETHTOOL_A_BITSET_MASK], 699 "mask only allowed in compact bitset"); 700 return -EINVAL; 701 } 702 703 bitmap_zero(val, nbits); 704 if (no_mask) 705 bitmap_fill(mask, nbits); 706 else 707 bitmap_zero(mask, nbits); 708 709 nla_for_each_nested(bit_attr, tb[ETHTOOL_A_BITSET_BITS], rem) { 710 unsigned int idx; 711 bool bit_val; 712 713 ret = ethnl_parse_bit(&idx, &bit_val, nbits, bit_attr, no_mask, 714 names, extack); 715 if (ret < 0) 716 return ret; 717 if (bit_val) 718 __set_bit(idx, val); 719 if (!no_mask) 720 __set_bit(idx, mask); 721 } 722 723 return 0; 724 } 725 726 #if BITS_PER_LONG == 64 && defined(__BIG_ENDIAN) 727 728 /* 64-bit big endian architectures are the only case when u32 based bitmaps 729 * and unsigned long based bitmaps have different memory layout so that we 730 * cannot simply cast the latter to the former and need actual wrappers 731 * converting the latter to the former. 732 * 733 * To reduce the number of slab allocations, the wrappers use fixed size local 734 * variables for bitmaps up to ETHNL_SMALL_BITMAP_BITS bits which is the 735 * majority of bitmaps used by ethtool. 736 */ 737 #define ETHNL_SMALL_BITMAP_BITS 128 738 #define ETHNL_SMALL_BITMAP_WORDS DIV_ROUND_UP(ETHNL_SMALL_BITMAP_BITS, 32) 739 740 int ethnl_bitset_size(const unsigned long *val, const unsigned long *mask, 741 unsigned int nbits, ethnl_string_array_t names, 742 bool compact) 743 { 744 u32 small_mask32[ETHNL_SMALL_BITMAP_WORDS]; 745 u32 small_val32[ETHNL_SMALL_BITMAP_WORDS]; 746 u32 *mask32; 747 u32 *val32; 748 int ret; 749 750 if (nbits > ETHNL_SMALL_BITMAP_BITS) { 751 unsigned int nwords = DIV_ROUND_UP(nbits, 32); 752 753 val32 = kmalloc_array(2 * nwords, sizeof(u32), GFP_KERNEL); 754 if (!val32) 755 return -ENOMEM; 756 mask32 = val32 + nwords; 757 } else { 758 val32 = small_val32; 759 mask32 = small_mask32; 760 } 761 762 bitmap_to_arr32(val32, val, nbits); 763 if (mask) 764 bitmap_to_arr32(mask32, mask, nbits); 765 else 766 mask32 = NULL; 767 ret = ethnl_bitset32_size(val32, mask32, nbits, names, compact); 768 769 if (nbits > ETHNL_SMALL_BITMAP_BITS) 770 kfree(val32); 771 772 return ret; 773 } 774 775 int ethnl_put_bitset(struct sk_buff *skb, int attrtype, 776 const unsigned long *val, const unsigned long *mask, 777 unsigned int nbits, ethnl_string_array_t names, 778 bool compact) 779 { 780 u32 small_mask32[ETHNL_SMALL_BITMAP_WORDS]; 781 u32 small_val32[ETHNL_SMALL_BITMAP_WORDS]; 782 u32 *mask32; 783 u32 *val32; 784 int ret; 785 786 if (nbits > ETHNL_SMALL_BITMAP_BITS) { 787 unsigned int nwords = DIV_ROUND_UP(nbits, 32); 788 789 val32 = kmalloc_array(2 * nwords, sizeof(u32), GFP_KERNEL); 790 if (!val32) 791 return -ENOMEM; 792 mask32 = val32 + nwords; 793 } else { 794 val32 = small_val32; 795 mask32 = small_mask32; 796 } 797 798 bitmap_to_arr32(val32, val, nbits); 799 if (mask) 800 bitmap_to_arr32(mask32, mask, nbits); 801 else 802 mask32 = NULL; 803 ret = ethnl_put_bitset32(skb, attrtype, val32, mask32, nbits, names, 804 compact); 805 806 if (nbits > ETHNL_SMALL_BITMAP_BITS) 807 kfree(val32); 808 809 return ret; 810 } 811 812 int ethnl_update_bitset(unsigned long *bitmap, unsigned int nbits, 813 const struct nlattr *attr, ethnl_string_array_t names, 814 struct netlink_ext_ack *extack, bool *mod) 815 { 816 u32 small_bitmap32[ETHNL_SMALL_BITMAP_WORDS]; 817 u32 *bitmap32 = small_bitmap32; 818 bool u32_mod = false; 819 int ret; 820 821 if (nbits > ETHNL_SMALL_BITMAP_BITS) { 822 unsigned int dst_words = DIV_ROUND_UP(nbits, 32); 823 824 bitmap32 = kmalloc_array(dst_words, sizeof(u32), GFP_KERNEL); 825 if (!bitmap32) 826 return -ENOMEM; 827 } 828 829 bitmap_to_arr32(bitmap32, bitmap, nbits); 830 ret = ethnl_update_bitset32(bitmap32, nbits, attr, names, extack, 831 &u32_mod); 832 if (u32_mod) { 833 bitmap_from_arr32(bitmap, bitmap32, nbits); 834 *mod = true; 835 } 836 837 if (nbits > ETHNL_SMALL_BITMAP_BITS) 838 kfree(bitmap32); 839 840 return ret; 841 } 842 843 #else 844 845 /* On little endian 64-bit and all 32-bit architectures, an unsigned long 846 * based bitmap can be interpreted as u32 based one using a simple cast. 847 */ 848 849 int ethnl_bitset_size(const unsigned long *val, const unsigned long *mask, 850 unsigned int nbits, ethnl_string_array_t names, 851 bool compact) 852 { 853 return ethnl_bitset32_size((const u32 *)val, (const u32 *)mask, nbits, 854 names, compact); 855 } 856 857 int ethnl_put_bitset(struct sk_buff *skb, int attrtype, 858 const unsigned long *val, const unsigned long *mask, 859 unsigned int nbits, ethnl_string_array_t names, 860 bool compact) 861 { 862 return ethnl_put_bitset32(skb, attrtype, (const u32 *)val, 863 (const u32 *)mask, nbits, names, compact); 864 } 865 866 int ethnl_update_bitset(unsigned long *bitmap, unsigned int nbits, 867 const struct nlattr *attr, ethnl_string_array_t names, 868 struct netlink_ext_ack *extack, bool *mod) 869 { 870 return ethnl_update_bitset32((u32 *)bitmap, nbits, attr, names, extack, 871 mod); 872 } 873 874 #endif /* BITS_PER_LONG == 64 && defined(__BIG_ENDIAN) */ 875