Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: sysfs: Implement is_visible for phys_(port_id, port_name, switch_id)

phys_port_id_show, phys_port_name_show and phys_switch_id_show would
return -EOPNOTSUPP if the netdev didn't implement the corresponding
method.

There is no point in creating these files if they are unsupported.

Put these attributes in netdev_phys_group and implement the is_visible
method. make phys_(port_id, port_name, switch_id) invisible if the netdev
dosen't implement the corresponding method.

Signed-off-by: Yajun Deng <yajun.deng@linux.dev>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20250612142707.4644-1-yajun.deng@linux.dev
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Yajun Deng and committed by
Jakub Kicinski
0c17270f ffe8a490

+36 -25
+1 -1
include/linux/netdevice.h
··· 2388 2388 struct dm_hw_stat_delta __rcu *dm_private; 2389 2389 #endif 2390 2390 struct device dev; 2391 - const struct attribute_group *sysfs_groups[4]; 2391 + const struct attribute_group *sysfs_groups[5]; 2392 2392 const struct attribute_group *sysfs_rx_queue_group; 2393 2393 2394 2394 const struct rtnl_link_ops *rtnl_link_ops;
+35 -24
net/core/net-sysfs.c
··· 641 641 struct netdev_phys_item_id ppid; 642 642 ssize_t ret; 643 643 644 - /* The check is also done in dev_get_phys_port_id; this helps returning 645 - * early without hitting the locking section below. 646 - */ 647 - if (!netdev->netdev_ops->ndo_get_phys_port_id) 648 - return -EOPNOTSUPP; 649 - 650 644 ret = sysfs_rtnl_lock(&dev->kobj, &attr->attr, netdev); 651 645 if (ret) 652 646 return ret; ··· 661 667 struct net_device *netdev = to_net_dev(dev); 662 668 char name[IFNAMSIZ]; 663 669 ssize_t ret; 664 - 665 - /* The checks are also done in dev_get_phys_port_name; this helps 666 - * returning early without hitting the locking section below. 667 - */ 668 - if (!netdev->netdev_ops->ndo_get_phys_port_name && 669 - !netdev->devlink_port) 670 - return -EOPNOTSUPP; 671 670 672 671 ret = sysfs_rtnl_lock(&dev->kobj, &attr->attr, netdev); 673 672 if (ret) ··· 683 696 struct netdev_phys_item_id ppid = { }; 684 697 ssize_t ret; 685 698 686 - /* The checks are also done in dev_get_phys_port_name; this helps 687 - * returning early without hitting the locking section below. This works 688 - * because recurse is false when calling dev_get_port_parent_id. 689 - */ 690 - if (!netdev->netdev_ops->ndo_get_port_parent_id && 691 - !netdev->devlink_port) 692 - return -EOPNOTSUPP; 693 - 694 699 ret = sysfs_rtnl_lock(&dev->kobj, &attr->attr, netdev); 695 700 if (ret) 696 701 return ret; ··· 696 717 return ret; 697 718 } 698 719 static DEVICE_ATTR_RO(phys_switch_id); 720 + 721 + static struct attribute *netdev_phys_attrs[] __ro_after_init = { 722 + &dev_attr_phys_port_id.attr, 723 + &dev_attr_phys_port_name.attr, 724 + &dev_attr_phys_switch_id.attr, 725 + NULL, 726 + }; 727 + 728 + static umode_t netdev_phys_is_visible(struct kobject *kobj, 729 + struct attribute *attr, int index) 730 + { 731 + struct device *dev = kobj_to_dev(kobj); 732 + struct net_device *netdev = to_net_dev(dev); 733 + 734 + if (attr == &dev_attr_phys_port_id.attr) { 735 + if (!netdev->netdev_ops->ndo_get_phys_port_id) 736 + return 0; 737 + } else if (attr == &dev_attr_phys_port_name.attr) { 738 + if (!netdev->netdev_ops->ndo_get_phys_port_name && 739 + !netdev->devlink_port) 740 + return 0; 741 + } else if (attr == &dev_attr_phys_switch_id.attr) { 742 + if (!netdev->netdev_ops->ndo_get_port_parent_id && 743 + !netdev->devlink_port) 744 + return 0; 745 + } 746 + 747 + return attr->mode; 748 + } 749 + 750 + static const struct attribute_group netdev_phys_group = { 751 + .attrs = netdev_phys_attrs, 752 + .is_visible = netdev_phys_is_visible, 753 + }; 699 754 700 755 static ssize_t threaded_show(struct device *dev, 701 756 struct device_attribute *attr, char *buf) ··· 796 783 &dev_attr_tx_queue_len.attr, 797 784 &dev_attr_gro_flush_timeout.attr, 798 785 &dev_attr_napi_defer_hard_irqs.attr, 799 - &dev_attr_phys_port_id.attr, 800 - &dev_attr_phys_port_name.attr, 801 - &dev_attr_phys_switch_id.attr, 802 786 &dev_attr_proto_down.attr, 803 787 &dev_attr_carrier_up_count.attr, 804 788 &dev_attr_carrier_down_count.attr, ··· 2338 2328 groups++; 2339 2329 2340 2330 *groups++ = &netstat_group; 2331 + *groups++ = &netdev_phys_group; 2341 2332 2342 2333 if (wireless_group_needed(ndev)) 2343 2334 *groups++ = &wireless_group;