History

net: rtnetlink: add linkxstats callbacks and attribute

Add callbacks to calculate the size and fill link extended statistics which can be split into multiple messages and are dumped via the new rtnl stats API (RTM_GETSTATS) with the IFLA_STATS_LINK_XSTATS attribute. Also add that attribute to the idx mask check since it is expected to be able to save state and resume dumping (e.g. future bridge per-vlan stats will be dumped via this attribute and callbacks). Each link type should nest its private attributes under the per-link type attribute. This allows to have any number of separated private attributes and to avoid one call to get the dev link type.

Nikolay Aleksandrov committed 10 years ago

Commit 97a47fa1 parent e8872a23 files · +49 −0Browse files

Unified · Split

3 files
  1. include/net/rtnetlink.h +7 −0
  2. include/uapi/linux/if_link.h +12 −0
  3. net/core/rtnetlink.c +30 −0
include/net/rtnetlink.h+7−0
@@ -47,6 +47,9 @@ static inline int rtnl_msg_family(const struct nlmsghdr *nlh) · 46 unmodified lines
4747 * @get_num_rx_queues: Function to determine number of receive queues
4848 * to create when creating a new device.
4949 * @get_link_net: Function to get the i/o netns of the device
50+ * @get_linkxstats_size: Function to calculate the required room for
51+ * dumping device-specific extended link stats
52+ * @fill_linkxstats: Function to dump device-specific extended link stats
5053 */
5154 struct rtnl_link_ops {
5255 struct list_head list;
@@ -95,6 +98,10 @@ struct rtnl_link_ops { · 42 unmodified lines
9598 const struct net_device *dev,
9699 const struct net_device *slave_dev);
97100 struct net *(*get_link_net)(const struct net_device *dev);
101+ size_t (*get_linkxstats_size)(const struct net_device *dev);
102+ int (*fill_linkxstats)(struct sk_buff *skb,
103+ const struct net_device *dev,
104+ int *prividx);
98105 };
99106
100107 int __rtnl_link_register(struct rtnl_link_ops *ops);
include/uapi/linux/if_link.h+12−0
@@ -810,6 +810,7 @@ struct if_stats_msg { · 809 unmodified lines
810810 enum {
811811 IFLA_STATS_UNSPEC, /* also used as 64bit pad attribute */
812812 IFLA_STATS_LINK_64,
813+ IFLA_STATS_LINK_XSTATS,
813814 __IFLA_STATS_MAX,
814815 };
815816
@@ -817,4 +818,15 @@ enum { · 1 unmodified line
817818
818819 #define IFLA_STATS_FILTER_BIT(ATTR) (1 << (ATTR - 1))
819820
821+/* These are embedded into IFLA_STATS_LINK_XSTATS:
822+ * [IFLA_STATS_LINK_XSTATS]
823+ * -> [LINK_XSTATS_TYPE_xxx]
824+ * -> [rtnl link type specific attributes]
825+ */
826+enum {
827+ LINK_XSTATS_TYPE_UNSPEC,
828+ __LINK_XSTATS_TYPE_MAX
829+};
830+#define LINK_XSTATS_TYPE_MAX (__LINK_XSTATS_TYPE_MAX - 1)
831+
820832 #endif /* _UAPI_LINUX_IF_LINK_H */
net/core/rtnetlink.c+30−0
@@ -3483,6 +3483,26 @@ static int rtnl_fill_statsinfo(struct sk_buff *skb, struct net_device *dev, · 3482 unmodified lines
34833483 dev_get_stats(dev, sp);
34843484 }
34853485
3486+ if (stats_attr_valid(filter_mask, IFLA_STATS_LINK_XSTATS, *idxattr)) {
3487+ const struct rtnl_link_ops *ops = dev->rtnl_link_ops;
3488+
3489+ if (ops && ops->fill_linkxstats) {
3490+ int err;
3491+
3492+ *idxattr = IFLA_STATS_LINK_XSTATS;
3493+ attr = nla_nest_start(skb,
3494+ IFLA_STATS_LINK_XSTATS);
3495+ if (!attr)
3496+ goto nla_put_failure;
3497+
3498+ err = ops->fill_linkxstats(skb, dev, prividx);
3499+ nla_nest_end(skb, attr);
3500+ if (err)
3501+ goto nla_put_failure;
3502+ *idxattr = 0;
3503+ }
3504+ }
3505+
34863506 nlmsg_end(skb, nlh);
34873507
34883508 return 0;
@@ -3509,6 +3529,16 @@ static size_t if_nlmsg_stats_size(const struct net_device *dev, · 20 unmodified lines
35093529 if (stats_attr_valid(filter_mask, IFLA_STATS_LINK_64, 0))
35103530 size += nla_total_size_64bit(sizeof(struct rtnl_link_stats64));
35113531
3532+ if (stats_attr_valid(filter_mask, IFLA_STATS_LINK_XSTATS, 0)) {
3533+ const struct rtnl_link_ops *ops = dev->rtnl_link_ops;
3534+
3535+ if (ops && ops->get_linkxstats_size) {
3536+ size += nla_total_size(ops->get_linkxstats_size(dev));
3537+ /* for IFLA_STATS_LINK_XSTATS */
3538+ size += nla_total_size(0);
3539+ }
3540+ }
3541+
35123542 return size;
35133543 }
35143544