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

netlink: spec: add shaper introspection support

Allow the user-space to fine-grain query the shaping features
supported by the NIC on each domain.

Reviewed-by: Jiri Pirko <jiri@nvidia.com>
Reviewed-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Link: https://patch.msgid.link/3ddd10e450e3fe7d4b944c0d0b886d4483529ee6.1728460186.git.pabeni@redhat.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Paolo Abeni and committed by
Jakub Kicinski
14bba928 ff7d4deb

+176
+88
Documentation/netlink/specs/net_shaper.yaml
··· 26 26 27 27 The user can query the running configuration via the @get operation. 28 28 29 + Different devices can provide different feature sets, e.g. with no 30 + support for complex scheduling hierarchy, or for some shaping 31 + parameters. The user can introspect the HW capabilities via the 32 + @cap-get operation. 33 + 29 34 definitions: 30 35 - 31 36 type: enum ··· 153 148 name: priority 154 149 - 155 150 name: weight 151 + - 152 + name: caps 153 + attributes: 154 + - 155 + name: ifindex 156 + type: u32 157 + doc: Interface index queried for shapers capabilities. 158 + - 159 + name: scope 160 + type: u32 161 + enum: scope 162 + doc: The scope to which the queried capabilities apply. 163 + - 164 + name: support-metric-bps 165 + type: flag 166 + doc: The device accepts 'bps' metric for bw-min, bw-max and burst. 167 + - 168 + name: support-metric-pps 169 + type: flag 170 + doc: The device accepts 'pps' metric for bw-min, bw-max and burst. 171 + - 172 + name: support-nesting 173 + type: flag 174 + doc: | 175 + The device supports nesting shaper belonging to this scope 176 + below 'node' scoped shapers. Only 'queue' and 'node' 177 + scope can have flag 'support-nesting'. 178 + - 179 + name: support-bw-min 180 + type: flag 181 + doc: The device supports a minimum guaranteed B/W. 182 + - 183 + name: support-bw-max 184 + type: flag 185 + doc: The device supports maximum B/W shaping. 186 + - 187 + name: support-burst 188 + type: flag 189 + doc: The device supports a maximum burst size. 190 + - 191 + name: support-priority 192 + type: flag 193 + doc: The device supports priority scheduling. 194 + - 195 + name: support-weight 196 + type: flag 197 + doc: The device supports weighted round robin scheduling. 156 198 157 199 operations: 158 200 list: ··· 324 272 - leaves 325 273 reply: 326 274 attributes: *ns-binding 275 + 276 + - 277 + name: cap-get 278 + doc: | 279 + Get the shaper capabilities supported by the given device 280 + for the specified scope. 281 + attribute-set: caps 282 + 283 + do: 284 + pre: net-shaper-nl-cap-pre-doit 285 + post: net-shaper-nl-cap-post-doit 286 + request: 287 + attributes: 288 + - ifindex 289 + - scope 290 + reply: 291 + attributes: &cap-attrs 292 + - ifindex 293 + - scope 294 + - support-metric-bps 295 + - support-metric-pps 296 + - support-nesting 297 + - support-bw-min 298 + - support-bw-max 299 + - support-burst 300 + - support-priority 301 + - support-weight 302 + 303 + dump: 304 + pre: net-shaper-nl-cap-pre-dumpit 305 + post: net-shaper-nl-cap-post-dumpit 306 + request: 307 + attributes: 308 + - ifindex 309 + reply: 310 + attributes: *cap-attrs
+17
include/uapi/linux/net_shaper.h
··· 66 66 }; 67 67 68 68 enum { 69 + NET_SHAPER_A_CAPS_IFINDEX = 1, 70 + NET_SHAPER_A_CAPS_SCOPE, 71 + NET_SHAPER_A_CAPS_SUPPORT_METRIC_BPS, 72 + NET_SHAPER_A_CAPS_SUPPORT_METRIC_PPS, 73 + NET_SHAPER_A_CAPS_SUPPORT_NESTING, 74 + NET_SHAPER_A_CAPS_SUPPORT_BW_MIN, 75 + NET_SHAPER_A_CAPS_SUPPORT_BW_MAX, 76 + NET_SHAPER_A_CAPS_SUPPORT_BURST, 77 + NET_SHAPER_A_CAPS_SUPPORT_PRIORITY, 78 + NET_SHAPER_A_CAPS_SUPPORT_WEIGHT, 79 + 80 + __NET_SHAPER_A_CAPS_MAX, 81 + NET_SHAPER_A_CAPS_MAX = (__NET_SHAPER_A_CAPS_MAX - 1) 82 + }; 83 + 84 + enum { 69 85 NET_SHAPER_CMD_GET = 1, 70 86 NET_SHAPER_CMD_SET, 71 87 NET_SHAPER_CMD_DELETE, 72 88 NET_SHAPER_CMD_GROUP, 89 + NET_SHAPER_CMD_CAP_GET, 73 90 74 91 __NET_SHAPER_CMD_MAX, 75 92 NET_SHAPER_CMD_MAX = (__NET_SHAPER_CMD_MAX - 1)
+32
net/shaper/shaper.c
··· 598 598 return 0; 599 599 } 600 600 601 + int net_shaper_nl_cap_pre_doit(const struct genl_split_ops *ops, 602 + struct sk_buff *skb, struct genl_info *info) 603 + { 604 + return -EOPNOTSUPP; 605 + } 606 + 607 + void net_shaper_nl_cap_post_doit(const struct genl_split_ops *ops, 608 + struct sk_buff *skb, struct genl_info *info) 609 + { 610 + } 611 + 612 + int net_shaper_nl_cap_pre_dumpit(struct netlink_callback *cb) 613 + { 614 + return -EOPNOTSUPP; 615 + } 616 + 617 + int net_shaper_nl_cap_post_dumpit(struct netlink_callback *cb) 618 + { 619 + return -EOPNOTSUPP; 620 + } 621 + 601 622 int net_shaper_nl_get_doit(struct sk_buff *skb, struct genl_info *info) 602 623 { 603 624 struct net_shaper_binding *binding; ··· 1145 1124 free_msg: 1146 1125 kfree_skb(msg); 1147 1126 goto free_leaves; 1127 + } 1128 + 1129 + int net_shaper_nl_cap_get_doit(struct sk_buff *skb, struct genl_info *info) 1130 + { 1131 + return 0; 1132 + } 1133 + 1134 + int net_shaper_nl_cap_get_dumpit(struct sk_buff *skb, 1135 + struct netlink_callback *cb) 1136 + { 1137 + return 0; 1148 1138 } 1149 1139 1150 1140 static void net_shaper_flush(struct net_shaper_binding *binding)
+29
net/shaper/shaper_nl_gen.c
··· 65 65 [NET_SHAPER_A_LEAVES] = NLA_POLICY_NESTED(net_shaper_leaf_info_nl_policy), 66 66 }; 67 67 68 + /* NET_SHAPER_CMD_CAP_GET - do */ 69 + static const struct nla_policy net_shaper_cap_get_do_nl_policy[NET_SHAPER_A_CAPS_SCOPE + 1] = { 70 + [NET_SHAPER_A_CAPS_IFINDEX] = { .type = NLA_U32, }, 71 + [NET_SHAPER_A_CAPS_SCOPE] = NLA_POLICY_MAX(NLA_U32, 3), 72 + }; 73 + 74 + /* NET_SHAPER_CMD_CAP_GET - dump */ 75 + static const struct nla_policy net_shaper_cap_get_dump_nl_policy[NET_SHAPER_A_CAPS_IFINDEX + 1] = { 76 + [NET_SHAPER_A_CAPS_IFINDEX] = { .type = NLA_U32, }, 77 + }; 78 + 68 79 /* Ops table for net_shaper */ 69 80 static const struct genl_split_ops net_shaper_nl_ops[] = { 70 81 { ··· 122 111 .policy = net_shaper_group_nl_policy, 123 112 .maxattr = NET_SHAPER_A_LEAVES, 124 113 .flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO, 114 + }, 115 + { 116 + .cmd = NET_SHAPER_CMD_CAP_GET, 117 + .pre_doit = net_shaper_nl_cap_pre_doit, 118 + .doit = net_shaper_nl_cap_get_doit, 119 + .post_doit = net_shaper_nl_cap_post_doit, 120 + .policy = net_shaper_cap_get_do_nl_policy, 121 + .maxattr = NET_SHAPER_A_CAPS_SCOPE, 122 + .flags = GENL_CMD_CAP_DO, 123 + }, 124 + { 125 + .cmd = NET_SHAPER_CMD_CAP_GET, 126 + .start = net_shaper_nl_cap_pre_dumpit, 127 + .dumpit = net_shaper_nl_cap_get_dumpit, 128 + .done = net_shaper_nl_cap_post_dumpit, 129 + .policy = net_shaper_cap_get_dump_nl_policy, 130 + .maxattr = NET_SHAPER_A_CAPS_IFINDEX, 131 + .flags = GENL_CMD_CAP_DUMP, 125 132 }, 126 133 }; 127 134
+10
net/shaper/shaper_nl_gen.h
··· 17 17 18 18 int net_shaper_nl_pre_doit(const struct genl_split_ops *ops, 19 19 struct sk_buff *skb, struct genl_info *info); 20 + int net_shaper_nl_cap_pre_doit(const struct genl_split_ops *ops, 21 + struct sk_buff *skb, struct genl_info *info); 20 22 void 21 23 net_shaper_nl_post_doit(const struct genl_split_ops *ops, struct sk_buff *skb, 22 24 struct genl_info *info); 25 + void 26 + net_shaper_nl_cap_post_doit(const struct genl_split_ops *ops, 27 + struct sk_buff *skb, struct genl_info *info); 23 28 int net_shaper_nl_pre_dumpit(struct netlink_callback *cb); 29 + int net_shaper_nl_cap_pre_dumpit(struct netlink_callback *cb); 24 30 int net_shaper_nl_post_dumpit(struct netlink_callback *cb); 31 + int net_shaper_nl_cap_post_dumpit(struct netlink_callback *cb); 25 32 26 33 int net_shaper_nl_get_doit(struct sk_buff *skb, struct genl_info *info); 27 34 int net_shaper_nl_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb); 28 35 int net_shaper_nl_set_doit(struct sk_buff *skb, struct genl_info *info); 29 36 int net_shaper_nl_delete_doit(struct sk_buff *skb, struct genl_info *info); 30 37 int net_shaper_nl_group_doit(struct sk_buff *skb, struct genl_info *info); 38 + int net_shaper_nl_cap_get_doit(struct sk_buff *skb, struct genl_info *info); 39 + int net_shaper_nl_cap_get_dumpit(struct sk_buff *skb, 40 + struct netlink_callback *cb); 31 41 32 42 extern struct genl_family net_shaper_nl_family; 33 43