| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Sysfs attributes of bridge |
|---|
| 3 | 4 | * Linux ethernet bridge |
|---|
| 4 | 5 | * |
|---|
| 5 | 6 | * Authors: |
|---|
| 6 | 7 | * Stephen Hemminger <shemminger@osdl.org> |
|---|
| 7 | | - * |
|---|
| 8 | | - * This program is free software; you can redistribute it and/or |
|---|
| 9 | | - * modify it under the terms of the GNU General Public License |
|---|
| 10 | | - * as published by the Free Software Foundation; either version |
|---|
| 11 | | - * 2 of the License, or (at your option) any later version. |
|---|
| 12 | 8 | */ |
|---|
| 13 | 9 | |
|---|
| 14 | 10 | #include <linux/capability.h> |
|---|
| .. | .. |
|---|
| 130 | 126 | |
|---|
| 131 | 127 | static int set_stp_state(struct net_bridge *br, unsigned long val) |
|---|
| 132 | 128 | { |
|---|
| 133 | | - br_stp_set_enabled(br, val); |
|---|
| 134 | | - |
|---|
| 135 | | - return 0; |
|---|
| 129 | + return br_stp_set_enabled(br, val, NULL); |
|---|
| 136 | 130 | } |
|---|
| 137 | 131 | |
|---|
| 138 | 132 | static ssize_t stp_state_store(struct device *d, |
|---|
| .. | .. |
|---|
| 303 | 297 | ether_addr_copy(br->group_addr, new_addr); |
|---|
| 304 | 298 | spin_unlock_bh(&br->lock); |
|---|
| 305 | 299 | |
|---|
| 306 | | - br->group_addr_set = true; |
|---|
| 300 | + br_opt_toggle(br, BROPT_GROUP_ADDR_SET, true); |
|---|
| 307 | 301 | br_recalculate_fwd_mask(br); |
|---|
| 308 | 302 | netdev_state_change(br->dev); |
|---|
| 309 | 303 | |
|---|
| .. | .. |
|---|
| 328 | 322 | } |
|---|
| 329 | 323 | static DEVICE_ATTR_WO(flush); |
|---|
| 330 | 324 | |
|---|
| 325 | +static ssize_t no_linklocal_learn_show(struct device *d, |
|---|
| 326 | + struct device_attribute *attr, |
|---|
| 327 | + char *buf) |
|---|
| 328 | +{ |
|---|
| 329 | + struct net_bridge *br = to_bridge(d); |
|---|
| 330 | + return sprintf(buf, "%d\n", br_boolopt_get(br, BR_BOOLOPT_NO_LL_LEARN)); |
|---|
| 331 | +} |
|---|
| 332 | + |
|---|
| 333 | +static int set_no_linklocal_learn(struct net_bridge *br, unsigned long val) |
|---|
| 334 | +{ |
|---|
| 335 | + return br_boolopt_toggle(br, BR_BOOLOPT_NO_LL_LEARN, !!val, NULL); |
|---|
| 336 | +} |
|---|
| 337 | + |
|---|
| 338 | +static ssize_t no_linklocal_learn_store(struct device *d, |
|---|
| 339 | + struct device_attribute *attr, |
|---|
| 340 | + const char *buf, size_t len) |
|---|
| 341 | +{ |
|---|
| 342 | + return store_bridge_parm(d, buf, len, set_no_linklocal_learn); |
|---|
| 343 | +} |
|---|
| 344 | +static DEVICE_ATTR_RW(no_linklocal_learn); |
|---|
| 345 | + |
|---|
| 331 | 346 | #ifdef CONFIG_BRIDGE_IGMP_SNOOPING |
|---|
| 332 | 347 | static ssize_t multicast_router_show(struct device *d, |
|---|
| 333 | 348 | struct device_attribute *attr, char *buf) |
|---|
| .. | .. |
|---|
| 349 | 364 | char *buf) |
|---|
| 350 | 365 | { |
|---|
| 351 | 366 | struct net_bridge *br = to_bridge(d); |
|---|
| 352 | | - return sprintf(buf, "%d\n", !br->multicast_disabled); |
|---|
| 367 | + return sprintf(buf, "%d\n", br_opt_get(br, BROPT_MULTICAST_ENABLED)); |
|---|
| 353 | 368 | } |
|---|
| 354 | 369 | |
|---|
| 355 | 370 | static ssize_t multicast_snooping_store(struct device *d, |
|---|
| .. | .. |
|---|
| 365 | 380 | char *buf) |
|---|
| 366 | 381 | { |
|---|
| 367 | 382 | struct net_bridge *br = to_bridge(d); |
|---|
| 368 | | - return sprintf(buf, "%d\n", br->multicast_query_use_ifaddr); |
|---|
| 383 | + return sprintf(buf, "%d\n", |
|---|
| 384 | + br_opt_get(br, BROPT_MULTICAST_QUERY_USE_IFADDR)); |
|---|
| 369 | 385 | } |
|---|
| 370 | 386 | |
|---|
| 371 | 387 | static int set_query_use_ifaddr(struct net_bridge *br, unsigned long val) |
|---|
| 372 | 388 | { |
|---|
| 373 | | - br->multicast_query_use_ifaddr = !!val; |
|---|
| 389 | + br_opt_toggle(br, BROPT_MULTICAST_QUERY_USE_IFADDR, !!val); |
|---|
| 374 | 390 | return 0; |
|---|
| 375 | 391 | } |
|---|
| 376 | 392 | |
|---|
| .. | .. |
|---|
| 388 | 404 | char *buf) |
|---|
| 389 | 405 | { |
|---|
| 390 | 406 | struct net_bridge *br = to_bridge(d); |
|---|
| 391 | | - return sprintf(buf, "%d\n", br->multicast_querier); |
|---|
| 407 | + return sprintf(buf, "%d\n", br_opt_get(br, BROPT_MULTICAST_QUERIER)); |
|---|
| 392 | 408 | } |
|---|
| 393 | 409 | |
|---|
| 394 | 410 | static ssize_t multicast_querier_store(struct device *d, |
|---|
| .. | .. |
|---|
| 402 | 418 | static ssize_t hash_elasticity_show(struct device *d, |
|---|
| 403 | 419 | struct device_attribute *attr, char *buf) |
|---|
| 404 | 420 | { |
|---|
| 405 | | - struct net_bridge *br = to_bridge(d); |
|---|
| 406 | | - return sprintf(buf, "%u\n", br->hash_elasticity); |
|---|
| 421 | + return sprintf(buf, "%u\n", RHT_ELASTICITY); |
|---|
| 407 | 422 | } |
|---|
| 408 | 423 | |
|---|
| 409 | 424 | static int set_elasticity(struct net_bridge *br, unsigned long val) |
|---|
| 410 | 425 | { |
|---|
| 411 | | - br->hash_elasticity = val; |
|---|
| 426 | + br_warn(br, "the hash_elasticity option has been deprecated and is always %u\n", |
|---|
| 427 | + RHT_ELASTICITY); |
|---|
| 412 | 428 | return 0; |
|---|
| 413 | 429 | } |
|---|
| 414 | 430 | |
|---|
| .. | .. |
|---|
| 427 | 443 | return sprintf(buf, "%u\n", br->hash_max); |
|---|
| 428 | 444 | } |
|---|
| 429 | 445 | |
|---|
| 446 | +static int set_hash_max(struct net_bridge *br, unsigned long val) |
|---|
| 447 | +{ |
|---|
| 448 | + br->hash_max = val; |
|---|
| 449 | + return 0; |
|---|
| 450 | +} |
|---|
| 451 | + |
|---|
| 430 | 452 | static ssize_t hash_max_store(struct device *d, struct device_attribute *attr, |
|---|
| 431 | 453 | const char *buf, size_t len) |
|---|
| 432 | 454 | { |
|---|
| 433 | | - return store_bridge_parm(d, buf, len, br_multicast_set_hash_max); |
|---|
| 455 | + return store_bridge_parm(d, buf, len, set_hash_max); |
|---|
| 434 | 456 | } |
|---|
| 435 | 457 | static DEVICE_ATTR_RW(hash_max); |
|---|
| 436 | 458 | |
|---|
| .. | .. |
|---|
| 636 | 658 | { |
|---|
| 637 | 659 | struct net_bridge *br = to_bridge(d); |
|---|
| 638 | 660 | |
|---|
| 639 | | - return sprintf(buf, "%u\n", br->multicast_stats_enabled); |
|---|
| 661 | + return sprintf(buf, "%d\n", |
|---|
| 662 | + br_opt_get(br, BROPT_MULTICAST_STATS_ENABLED)); |
|---|
| 640 | 663 | } |
|---|
| 641 | 664 | |
|---|
| 642 | 665 | static int set_stats_enabled(struct net_bridge *br, unsigned long val) |
|---|
| 643 | 666 | { |
|---|
| 644 | | - br->multicast_stats_enabled = !!val; |
|---|
| 667 | + br_opt_toggle(br, BROPT_MULTICAST_STATS_ENABLED, !!val); |
|---|
| 645 | 668 | return 0; |
|---|
| 646 | 669 | } |
|---|
| 647 | 670 | |
|---|
| .. | .. |
|---|
| 678 | 701 | struct device *d, struct device_attribute *attr, char *buf) |
|---|
| 679 | 702 | { |
|---|
| 680 | 703 | struct net_bridge *br = to_bridge(d); |
|---|
| 681 | | - return sprintf(buf, "%u\n", br->nf_call_iptables); |
|---|
| 704 | + return sprintf(buf, "%u\n", br_opt_get(br, BROPT_NF_CALL_IPTABLES)); |
|---|
| 682 | 705 | } |
|---|
| 683 | 706 | |
|---|
| 684 | 707 | static int set_nf_call_iptables(struct net_bridge *br, unsigned long val) |
|---|
| 685 | 708 | { |
|---|
| 686 | | - br->nf_call_iptables = val ? true : false; |
|---|
| 709 | + br_opt_toggle(br, BROPT_NF_CALL_IPTABLES, !!val); |
|---|
| 687 | 710 | return 0; |
|---|
| 688 | 711 | } |
|---|
| 689 | 712 | |
|---|
| .. | .. |
|---|
| 699 | 722 | struct device *d, struct device_attribute *attr, char *buf) |
|---|
| 700 | 723 | { |
|---|
| 701 | 724 | struct net_bridge *br = to_bridge(d); |
|---|
| 702 | | - return sprintf(buf, "%u\n", br->nf_call_ip6tables); |
|---|
| 725 | + return sprintf(buf, "%u\n", br_opt_get(br, BROPT_NF_CALL_IP6TABLES)); |
|---|
| 703 | 726 | } |
|---|
| 704 | 727 | |
|---|
| 705 | 728 | static int set_nf_call_ip6tables(struct net_bridge *br, unsigned long val) |
|---|
| 706 | 729 | { |
|---|
| 707 | | - br->nf_call_ip6tables = val ? true : false; |
|---|
| 730 | + br_opt_toggle(br, BROPT_NF_CALL_IP6TABLES, !!val); |
|---|
| 708 | 731 | return 0; |
|---|
| 709 | 732 | } |
|---|
| 710 | 733 | |
|---|
| .. | .. |
|---|
| 720 | 743 | struct device *d, struct device_attribute *attr, char *buf) |
|---|
| 721 | 744 | { |
|---|
| 722 | 745 | struct net_bridge *br = to_bridge(d); |
|---|
| 723 | | - return sprintf(buf, "%u\n", br->nf_call_arptables); |
|---|
| 746 | + return sprintf(buf, "%u\n", br_opt_get(br, BROPT_NF_CALL_ARPTABLES)); |
|---|
| 724 | 747 | } |
|---|
| 725 | 748 | |
|---|
| 726 | 749 | static int set_nf_call_arptables(struct net_bridge *br, unsigned long val) |
|---|
| 727 | 750 | { |
|---|
| 728 | | - br->nf_call_arptables = val ? true : false; |
|---|
| 751 | + br_opt_toggle(br, BROPT_NF_CALL_ARPTABLES, !!val); |
|---|
| 729 | 752 | return 0; |
|---|
| 730 | 753 | } |
|---|
| 731 | 754 | |
|---|
| .. | .. |
|---|
| 743 | 766 | char *buf) |
|---|
| 744 | 767 | { |
|---|
| 745 | 768 | struct net_bridge *br = to_bridge(d); |
|---|
| 746 | | - return sprintf(buf, "%d\n", br->vlan_enabled); |
|---|
| 769 | + return sprintf(buf, "%d\n", br_opt_get(br, BROPT_VLAN_ENABLED)); |
|---|
| 747 | 770 | } |
|---|
| 748 | 771 | |
|---|
| 749 | 772 | static ssize_t vlan_filtering_store(struct device *d, |
|---|
| .. | .. |
|---|
| 791 | 814 | char *buf) |
|---|
| 792 | 815 | { |
|---|
| 793 | 816 | struct net_bridge *br = to_bridge(d); |
|---|
| 794 | | - return sprintf(buf, "%u\n", br->vlan_stats_enabled); |
|---|
| 817 | + return sprintf(buf, "%u\n", br_opt_get(br, BROPT_VLAN_STATS_ENABLED)); |
|---|
| 795 | 818 | } |
|---|
| 796 | 819 | |
|---|
| 797 | 820 | static ssize_t vlan_stats_enabled_store(struct device *d, |
|---|
| .. | .. |
|---|
| 801 | 824 | return store_bridge_parm(d, buf, len, br_vlan_set_stats); |
|---|
| 802 | 825 | } |
|---|
| 803 | 826 | static DEVICE_ATTR_RW(vlan_stats_enabled); |
|---|
| 827 | + |
|---|
| 828 | +static ssize_t vlan_stats_per_port_show(struct device *d, |
|---|
| 829 | + struct device_attribute *attr, |
|---|
| 830 | + char *buf) |
|---|
| 831 | +{ |
|---|
| 832 | + struct net_bridge *br = to_bridge(d); |
|---|
| 833 | + return sprintf(buf, "%u\n", br_opt_get(br, BROPT_VLAN_STATS_PER_PORT)); |
|---|
| 834 | +} |
|---|
| 835 | + |
|---|
| 836 | +static ssize_t vlan_stats_per_port_store(struct device *d, |
|---|
| 837 | + struct device_attribute *attr, |
|---|
| 838 | + const char *buf, size_t len) |
|---|
| 839 | +{ |
|---|
| 840 | + return store_bridge_parm(d, buf, len, br_vlan_set_stats_per_port); |
|---|
| 841 | +} |
|---|
| 842 | +static DEVICE_ATTR_RW(vlan_stats_per_port); |
|---|
| 804 | 843 | #endif |
|---|
| 805 | 844 | |
|---|
| 806 | 845 | static struct attribute *bridge_attrs[] = { |
|---|
| .. | .. |
|---|
| 823 | 862 | &dev_attr_gc_timer.attr, |
|---|
| 824 | 863 | &dev_attr_group_addr.attr, |
|---|
| 825 | 864 | &dev_attr_flush.attr, |
|---|
| 865 | + &dev_attr_no_linklocal_learn.attr, |
|---|
| 826 | 866 | #ifdef CONFIG_BRIDGE_IGMP_SNOOPING |
|---|
| 827 | 867 | &dev_attr_multicast_router.attr, |
|---|
| 828 | 868 | &dev_attr_multicast_snooping.attr, |
|---|
| .. | .. |
|---|
| 854 | 894 | &dev_attr_vlan_protocol.attr, |
|---|
| 855 | 895 | &dev_attr_default_pvid.attr, |
|---|
| 856 | 896 | &dev_attr_vlan_stats_enabled.attr, |
|---|
| 897 | + &dev_attr_vlan_stats_per_port.attr, |
|---|
| 857 | 898 | #endif |
|---|
| 858 | 899 | NULL |
|---|
| 859 | 900 | }; |
|---|