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

Merge branch 'devlink-introduce-selective-dumps'

Jiri Pirko says:

====================
devlink: introduce selective dumps

Motivation:

For SFs, one devlink instance per SF is created. There might be
thousands of these on a single host. When a user needs to know port
handle for specific SF, he needs to dump all devlink ports on the host
which does not scale good.

Solution:

Allow user to pass devlink handle (and possibly other attributes)
alongside the dump command and dump only objects which are matching
the selection.

Use split ops to generate policies for dump callbacks acccording to
the attributes used for selection.

The userspace can use ctrl genetlink GET_POLICY command to find out if
the selective dumps are supported by kernel for particular command.

Example:
$ devlink port show
auxiliary/mlx5_core.eth.0/65535: type eth netdev eth2 flavour physical port 0 splittable false
auxiliary/mlx5_core.eth.1/131071: type eth netdev eth3 flavour physical port 1 splittable false

$ devlink port show auxiliary/mlx5_core.eth.0
auxiliary/mlx5_core.eth.0/65535: type eth netdev eth2 flavour physical port 0 splittable false

$ devlink port show auxiliary/mlx5_core.eth.1
auxiliary/mlx5_core.eth.1/131071: type eth netdev eth3 flavour physical port 1 splittable false

Extension:

patches #12 and #13 extends selection attributes by port index
for health reporter dumping.
====================

Link: https://lore.kernel.org/r/20230811155714.1736405-1-jiri@resnulli.us
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+5189 -368
+456 -1
Documentation/netlink/specs/devlink.yaml
··· 6 6 7 7 doc: Partial family for Devlink. 8 8 9 + definitions: 10 + - 11 + type: enum 12 + name: sb-pool-type 13 + entries: 14 + - 15 + name: ingress 16 + - 17 + name: egress 18 + 9 19 attribute-sets: 10 20 - 11 21 name: devlink ··· 31 21 - 32 22 name: port-index 33 23 type: u32 24 + 25 + # TODO: fill in the attributes in between 26 + 27 + - 28 + name: sb-index 29 + type: u32 30 + value: 11 31 + 32 + # TODO: fill in the attributes in between 33 + 34 + - 35 + name: sb-pool-index 36 + type: u16 37 + value: 17 38 + 39 + - 40 + name: sb-pool-type 41 + type: u8 42 + enum: sb-pool-type 43 + 44 + # TODO: fill in the attributes in between 45 + 46 + - 47 + name: sb-tc-index 48 + type: u16 49 + value: 22 50 + 51 + # TODO: fill in the attributes in between 52 + 53 + - 54 + name: param-name 55 + type: string 56 + value: 81 57 + 58 + # TODO: fill in the attributes in between 59 + 60 + - 61 + name: region-name 62 + type: string 63 + value: 88 34 64 35 65 # TODO: fill in the attributes in between 36 66 ··· 106 56 # TODO: fill in the attributes in between 107 57 108 58 - 59 + name: health-reporter-name 60 + type: string 61 + value: 115 62 + 63 + # TODO: fill in the attributes in between 64 + 65 + - 66 + name: trap-name 67 + type: string 68 + value: 130 69 + 70 + # TODO: fill in the attributes in between 71 + 72 + - 73 + name: trap-group-name 74 + type: string 75 + value: 135 76 + 77 + - 109 78 name: reload-failed 110 79 type: u8 111 - value: 136 80 + 81 + # TODO: fill in the attributes in between 82 + 83 + - 84 + name: trap-policer-id 85 + type: u32 86 + value: 142 112 87 113 88 # TODO: fill in the attributes in between 114 89 ··· 178 103 type: nest 179 104 multi-attr: true 180 105 nested-attributes: dl-reload-act-stats 106 + 107 + # TODO: fill in the attributes in between 108 + 109 + - 110 + name: rate-node-name 111 + type: string 112 + value: 168 113 + 114 + # TODO: fill in the attributes in between 115 + 116 + - 117 + name: linecard-index 118 + type: u32 119 + value: 171 120 + 181 121 - 182 122 name: dl-dev-stats 183 123 subset-of: devlink ··· 278 188 dump: 279 189 reply: *get-reply 280 190 191 + - 192 + name: port-get 193 + doc: Get devlink port instances. 194 + attribute-set: devlink 195 + dont-validate: 196 + - strict 197 + 198 + do: 199 + pre: devlink-nl-pre-doit-port 200 + post: devlink-nl-post-doit 201 + request: 202 + value: 5 203 + attributes: &port-id-attrs 204 + - bus-name 205 + - dev-name 206 + - port-index 207 + reply: 208 + value: 7 209 + attributes: *port-id-attrs 210 + dump: 211 + request: 212 + attributes: *dev-id-attrs 213 + reply: 214 + value: 3 # due to a bug, port dump returns DEVLINK_CMD_NEW 215 + attributes: *port-id-attrs 216 + 217 + # TODO: fill in the operations in between 218 + 219 + - 220 + name: sb-get 221 + doc: Get shared buffer instances. 222 + attribute-set: devlink 223 + dont-validate: 224 + - strict 225 + 226 + do: 227 + pre: devlink-nl-pre-doit 228 + post: devlink-nl-post-doit 229 + request: 230 + value: 11 231 + attributes: &sb-id-attrs 232 + - bus-name 233 + - dev-name 234 + - sb-index 235 + reply: &sb-get-reply 236 + value: 11 237 + attributes: *sb-id-attrs 238 + dump: 239 + request: 240 + attributes: *dev-id-attrs 241 + reply: *sb-get-reply 242 + 243 + # TODO: fill in the operations in between 244 + 245 + - 246 + name: sb-pool-get 247 + doc: Get shared buffer pool instances. 248 + attribute-set: devlink 249 + dont-validate: 250 + - strict 251 + 252 + do: 253 + pre: devlink-nl-pre-doit 254 + post: devlink-nl-post-doit 255 + request: 256 + value: 15 257 + attributes: &sb-pool-id-attrs 258 + - bus-name 259 + - dev-name 260 + - sb-index 261 + - sb-pool-index 262 + reply: &sb-pool-get-reply 263 + value: 15 264 + attributes: *sb-pool-id-attrs 265 + dump: 266 + request: 267 + attributes: *dev-id-attrs 268 + reply: *sb-pool-get-reply 269 + 270 + # TODO: fill in the operations in between 271 + 272 + - 273 + name: sb-port-pool-get 274 + doc: Get shared buffer port-pool combinations and threshold. 275 + attribute-set: devlink 276 + dont-validate: 277 + - strict 278 + 279 + do: 280 + pre: devlink-nl-pre-doit-port 281 + post: devlink-nl-post-doit 282 + request: 283 + value: 19 284 + attributes: &sb-port-pool-id-attrs 285 + - bus-name 286 + - dev-name 287 + - port-index 288 + - sb-index 289 + - sb-pool-index 290 + reply: &sb-port-pool-get-reply 291 + value: 19 292 + attributes: *sb-port-pool-id-attrs 293 + dump: 294 + request: 295 + attributes: *dev-id-attrs 296 + reply: *sb-port-pool-get-reply 297 + 298 + # TODO: fill in the operations in between 299 + 300 + - 301 + name: sb-tc-pool-bind-get 302 + doc: Get shared buffer port-TC to pool bindings and threshold. 303 + attribute-set: devlink 304 + dont-validate: 305 + - strict 306 + 307 + do: 308 + pre: devlink-nl-pre-doit-port 309 + post: devlink-nl-post-doit 310 + request: 311 + value: 23 312 + attributes: &sb-tc-pool-bind-id-attrs 313 + - bus-name 314 + - dev-name 315 + - port-index 316 + - sb-index 317 + - sb-pool-type 318 + - sb-tc-index 319 + reply: &sb-tc-pool-bind-get-reply 320 + value: 23 321 + attributes: *sb-tc-pool-bind-id-attrs 322 + dump: 323 + request: 324 + attributes: *dev-id-attrs 325 + reply: *sb-tc-pool-bind-get-reply 326 + 327 + # TODO: fill in the operations in between 328 + 329 + - 330 + name: param-get 331 + doc: Get param instances. 332 + attribute-set: devlink 333 + dont-validate: 334 + - strict 335 + 336 + do: 337 + pre: devlink-nl-pre-doit 338 + post: devlink-nl-post-doit 339 + request: 340 + value: 38 341 + attributes: &param-id-attrs 342 + - bus-name 343 + - dev-name 344 + - param-name 345 + reply: &param-get-reply 346 + value: 38 347 + attributes: *param-id-attrs 348 + dump: 349 + request: 350 + attributes: *dev-id-attrs 351 + reply: *param-get-reply 352 + 353 + # TODO: fill in the operations in between 354 + 355 + - 356 + name: region-get 357 + doc: Get region instances. 358 + attribute-set: devlink 359 + dont-validate: 360 + - strict 361 + 362 + do: 363 + pre: devlink-nl-pre-doit-port-optional 364 + post: devlink-nl-post-doit 365 + request: 366 + value: 42 367 + attributes: &region-id-attrs 368 + - bus-name 369 + - dev-name 370 + - port-index 371 + - region-name 372 + reply: &region-get-reply 373 + value: 42 374 + attributes: *region-id-attrs 375 + dump: 376 + request: 377 + attributes: *dev-id-attrs 378 + reply: *region-get-reply 379 + 281 380 # TODO: fill in the operations in between 282 381 283 382 - ··· 495 216 - info-version-stored 496 217 dump: 497 218 reply: *info-get-reply 219 + 220 + - 221 + name: health-reporter-get 222 + doc: Get health reporter instances. 223 + attribute-set: devlink 224 + dont-validate: 225 + - strict 226 + 227 + do: 228 + pre: devlink-nl-pre-doit-port-optional 229 + post: devlink-nl-post-doit 230 + request: 231 + attributes: &health-reporter-id-attrs 232 + - bus-name 233 + - dev-name 234 + - port-index 235 + - health-reporter-name 236 + reply: &health-reporter-get-reply 237 + attributes: *health-reporter-id-attrs 238 + dump: 239 + request: 240 + attributes: *port-id-attrs 241 + reply: *health-reporter-get-reply 242 + 243 + # TODO: fill in the operations in between 244 + 245 + - 246 + name: trap-get 247 + doc: Get trap instances. 248 + attribute-set: devlink 249 + dont-validate: 250 + - strict 251 + 252 + do: 253 + pre: devlink-nl-pre-doit 254 + post: devlink-nl-post-doit 255 + request: 256 + value: 61 257 + attributes: &trap-id-attrs 258 + - bus-name 259 + - dev-name 260 + - trap-name 261 + reply: &trap-get-reply 262 + value: 61 263 + attributes: *trap-id-attrs 264 + dump: 265 + request: 266 + attributes: *dev-id-attrs 267 + reply: *trap-get-reply 268 + 269 + # TODO: fill in the operations in between 270 + 271 + - 272 + name: trap-group-get 273 + doc: Get trap group instances. 274 + attribute-set: devlink 275 + dont-validate: 276 + - strict 277 + 278 + do: 279 + pre: devlink-nl-pre-doit 280 + post: devlink-nl-post-doit 281 + request: 282 + value: 65 283 + attributes: &trap-group-id-attrs 284 + - bus-name 285 + - dev-name 286 + - trap-group-name 287 + reply: &trap-group-get-reply 288 + value: 65 289 + attributes: *trap-group-id-attrs 290 + dump: 291 + request: 292 + attributes: *dev-id-attrs 293 + reply: *trap-group-get-reply 294 + 295 + # TODO: fill in the operations in between 296 + 297 + - 298 + name: trap-policer-get 299 + doc: Get trap policer instances. 300 + attribute-set: devlink 301 + dont-validate: 302 + - strict 303 + 304 + do: 305 + pre: devlink-nl-pre-doit 306 + post: devlink-nl-post-doit 307 + request: 308 + value: 69 309 + attributes: &trap-policer-id-attrs 310 + - bus-name 311 + - dev-name 312 + - trap-policer-id 313 + reply: &trap-policer-get-reply 314 + value: 69 315 + attributes: *trap-policer-id-attrs 316 + dump: 317 + request: 318 + attributes: *dev-id-attrs 319 + reply: *trap-policer-get-reply 320 + 321 + # TODO: fill in the operations in between 322 + 323 + - 324 + name: rate-get 325 + doc: Get rate instances. 326 + attribute-set: devlink 327 + dont-validate: 328 + - strict 329 + 330 + do: 331 + pre: devlink-nl-pre-doit 332 + post: devlink-nl-post-doit 333 + request: 334 + value: 74 335 + attributes: &rate-id-attrs 336 + - bus-name 337 + - dev-name 338 + - port-index 339 + - rate-node-name 340 + reply: &rate-get-reply 341 + value: 74 342 + attributes: *rate-id-attrs 343 + dump: 344 + request: 345 + attributes: *dev-id-attrs 346 + reply: *rate-get-reply 347 + 348 + # TODO: fill in the operations in between 349 + 350 + - 351 + name: linecard-get 352 + doc: Get line card instances. 353 + attribute-set: devlink 354 + dont-validate: 355 + - strict 356 + 357 + do: 358 + pre: devlink-nl-pre-doit 359 + post: devlink-nl-post-doit 360 + request: 361 + value: 78 362 + attributes: &linecard-id-attrs 363 + - bus-name 364 + - dev-name 365 + - linecard-index 366 + reply: &linecard-get-reply 367 + value: 78 368 + attributes: *linecard-id-attrs 369 + dump: 370 + request: 371 + attributes: *dev-id-attrs 372 + reply: *linecard-get-reply 373 + 374 + # TODO: fill in the operations in between 375 + 376 + - 377 + name: selftests-get 378 + doc: Get device selftest instances. 379 + attribute-set: devlink 380 + dont-validate: 381 + - strict 382 + - dump 383 + 384 + do: 385 + pre: devlink-nl-pre-doit 386 + post: devlink-nl-post-doit 387 + request: 388 + value: 82 389 + attributes: *dev-id-attrs 390 + reply: &selftests-get-reply 391 + value: 82 392 + attributes: *dev-id-attrs 393 + dump: 394 + reply: *selftests-get-reply
+15 -14
net/devlink/dev.c
··· 218 218 219 219 static int 220 220 devlink_nl_get_dump_one(struct sk_buff *msg, struct devlink *devlink, 221 - struct netlink_callback *cb) 221 + struct netlink_callback *cb, int flags) 222 222 { 223 223 return devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW, 224 224 NETLINK_CB(cb->skb).portid, 225 - cb->nlh->nlmsg_seq, NLM_F_MULTI); 225 + cb->nlh->nlmsg_seq, flags); 226 226 } 227 227 228 228 int devlink_nl_get_dumpit(struct sk_buff *msg, struct netlink_callback *cb) ··· 828 828 829 829 static int 830 830 devlink_nl_info_get_dump_one(struct sk_buff *msg, struct devlink *devlink, 831 - struct netlink_callback *cb) 831 + struct netlink_callback *cb, int flags) 832 832 { 833 833 int err; 834 834 835 835 err = devlink_nl_info_fill(msg, devlink, DEVLINK_CMD_INFO_GET, 836 836 NETLINK_CB(cb->skb).portid, 837 - cb->nlh->nlmsg_seq, NLM_F_MULTI, 837 + cb->nlh->nlmsg_seq, flags, 838 838 cb->extack); 839 839 if (err == -EOPNOTSUPP) 840 840 err = 0; ··· 1206 1206 return err; 1207 1207 } 1208 1208 1209 - int devlink_nl_cmd_selftests_get_doit(struct sk_buff *skb, 1210 - struct genl_info *info) 1209 + int devlink_nl_selftests_get_doit(struct sk_buff *skb, struct genl_info *info) 1211 1210 { 1212 1211 struct devlink *devlink = info->user_ptr[0]; 1213 1212 struct sk_buff *msg; ··· 1229 1230 return genlmsg_reply(msg, info); 1230 1231 } 1231 1232 1232 - static int 1233 - devlink_nl_cmd_selftests_get_dump_one(struct sk_buff *msg, 1234 - struct devlink *devlink, 1235 - struct netlink_callback *cb) 1233 + static int devlink_nl_selftests_get_dump_one(struct sk_buff *msg, 1234 + struct devlink *devlink, 1235 + struct netlink_callback *cb, 1236 + int flags) 1236 1237 { 1237 1238 if (!devlink->ops->selftest_check) 1238 1239 return 0; 1239 1240 1240 1241 return devlink_nl_selftests_fill(msg, devlink, 1241 1242 NETLINK_CB(cb->skb).portid, 1242 - cb->nlh->nlmsg_seq, NLM_F_MULTI, 1243 + cb->nlh->nlmsg_seq, flags, 1243 1244 cb->extack); 1244 1245 } 1245 1246 1246 - const struct devlink_cmd devl_cmd_selftests_get = { 1247 - .dump_one = devlink_nl_cmd_selftests_get_dump_one, 1248 - }; 1247 + int devlink_nl_selftests_get_dumpit(struct sk_buff *skb, 1248 + struct netlink_callback *cb) 1249 + { 1250 + return devlink_nl_dumpit(skb, cb, devlink_nl_selftests_get_dump_one); 1251 + } 1249 1252 1250 1253 static int devlink_selftest_result_put(struct sk_buff *skb, unsigned int id, 1251 1254 enum devlink_selftest_status test_status)
+4 -40
net/devlink/devl_internal.h
··· 92 92 /* Netlink */ 93 93 #define DEVLINK_NL_FLAG_NEED_PORT BIT(0) 94 94 #define DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT BIT(1) 95 - #define DEVLINK_NL_FLAG_NEED_RATE BIT(2) 96 - #define DEVLINK_NL_FLAG_NEED_RATE_NODE BIT(3) 97 - #define DEVLINK_NL_FLAG_NEED_LINECARD BIT(4) 98 95 99 96 enum devlink_multicast_groups { 100 97 DEVLINK_MCGRP_CONFIG, ··· 115 118 116 119 typedef int devlink_nl_dump_one_func_t(struct sk_buff *msg, 117 120 struct devlink *devlink, 118 - struct netlink_callback *cb); 121 + struct netlink_callback *cb, 122 + int flags); 119 123 120 - struct devlink_cmd { 121 - devlink_nl_dump_one_func_t *dump_one; 122 - }; 123 - 124 - extern const struct genl_small_ops devlink_nl_small_ops[54]; 124 + extern const struct genl_small_ops devlink_nl_small_ops[40]; 125 125 126 126 struct devlink * 127 127 devlink_get_from_attrs_lock(struct net *net, struct nlattr **attrs); ··· 128 134 129 135 int devlink_nl_dumpit(struct sk_buff *msg, struct netlink_callback *cb, 130 136 devlink_nl_dump_one_func_t *dump_one); 131 - int devlink_nl_instance_iter_dumpit(struct sk_buff *msg, struct netlink_callback *cb); 132 137 133 138 static inline struct devlink_nl_dump_state * 134 139 devlink_dump_state(struct netlink_callback *cb) ··· 146 153 return -EMSGSIZE; 147 154 return 0; 148 155 } 149 - 150 - /* Commands */ 151 - extern const struct devlink_cmd devl_cmd_port_get; 152 - extern const struct devlink_cmd devl_cmd_sb_get; 153 - extern const struct devlink_cmd devl_cmd_sb_pool_get; 154 - extern const struct devlink_cmd devl_cmd_sb_port_pool_get; 155 - extern const struct devlink_cmd devl_cmd_sb_tc_pool_bind_get; 156 - extern const struct devlink_cmd devl_cmd_param_get; 157 - extern const struct devlink_cmd devl_cmd_region_get; 158 - extern const struct devlink_cmd devl_cmd_health_reporter_get; 159 - extern const struct devlink_cmd devl_cmd_trap_get; 160 - extern const struct devlink_cmd devl_cmd_trap_group_get; 161 - extern const struct devlink_cmd devl_cmd_trap_policer_get; 162 - extern const struct devlink_cmd devl_cmd_rate_get; 163 - extern const struct devlink_cmd devl_cmd_linecard_get; 164 - extern const struct devlink_cmd devl_cmd_selftests_get; 165 156 166 157 /* Notify */ 167 158 void devlink_notify(struct devlink *devlink, enum devlink_command cmd); ··· 180 203 struct devlink_resource *resource, 181 204 struct genl_info *info); 182 205 183 - /* Line cards */ 184 - struct devlink_linecard; 185 - 186 - struct devlink_linecard * 187 - devlink_linecard_get_from_info(struct devlink *devlink, struct genl_info *info); 188 - 189 206 /* Rates */ 190 207 int devlink_rate_nodes_check(struct devlink *devlink, u16 mode, 191 208 struct netlink_ext_ack *extack); 192 - struct devlink_rate * 193 - devlink_rate_get_from_info(struct devlink *devlink, struct genl_info *info); 194 - struct devlink_rate * 195 - devlink_rate_node_get_from_info(struct devlink *devlink, 196 - struct genl_info *info); 209 + 197 210 /* Devlink nl cmds */ 198 211 int devlink_nl_cmd_reload(struct sk_buff *skb, struct genl_info *info); 199 212 int devlink_nl_cmd_eswitch_get_doit(struct sk_buff *skb, struct genl_info *info); 200 213 int devlink_nl_cmd_eswitch_set_doit(struct sk_buff *skb, struct genl_info *info); 201 214 int devlink_nl_cmd_flash_update(struct sk_buff *skb, struct genl_info *info); 202 - int devlink_nl_cmd_selftests_get_doit(struct sk_buff *skb, struct genl_info *info); 203 215 int devlink_nl_cmd_selftests_run(struct sk_buff *skb, struct genl_info *info); 204 - int devlink_nl_cmd_health_reporter_get_doit(struct sk_buff *skb, 205 - struct genl_info *info); 206 216 int devlink_nl_cmd_health_reporter_set_doit(struct sk_buff *skb, 207 217 struct genl_info *info); 208 218 int devlink_nl_cmd_health_reporter_recover_doit(struct sk_buff *skb,
+28 -12
net/devlink/health.c
··· 356 356 return devlink_health_reporter_get_from_attrs(devlink, info->attrs); 357 357 } 358 358 359 - int devlink_nl_cmd_health_reporter_get_doit(struct sk_buff *skb, 360 - struct genl_info *info) 359 + int devlink_nl_health_reporter_get_doit(struct sk_buff *skb, 360 + struct genl_info *info) 361 361 { 362 362 struct devlink *devlink = info->user_ptr[0]; 363 363 struct devlink_health_reporter *reporter; ··· 384 384 return genlmsg_reply(msg, info); 385 385 } 386 386 387 - static int 388 - devlink_nl_cmd_health_reporter_get_dump_one(struct sk_buff *msg, 389 - struct devlink *devlink, 390 - struct netlink_callback *cb) 387 + static int devlink_nl_health_reporter_get_dump_one(struct sk_buff *msg, 388 + struct devlink *devlink, 389 + struct netlink_callback *cb, 390 + int flags) 391 391 { 392 392 struct devlink_nl_dump_state *state = devlink_dump_state(cb); 393 + const struct genl_dumpit_info *info = genl_dumpit_info(cb); 393 394 struct devlink_health_reporter *reporter; 395 + unsigned long port_index_end = ULONG_MAX; 396 + struct nlattr **attrs = info->attrs; 397 + unsigned long port_index_start = 0; 394 398 struct devlink_port *port; 395 399 unsigned long port_index; 396 400 int idx = 0; 397 401 int err; 402 + 403 + if (attrs && attrs[DEVLINK_ATTR_PORT_INDEX]) { 404 + port_index_start = nla_get_u32(attrs[DEVLINK_ATTR_PORT_INDEX]); 405 + port_index_end = port_index_start; 406 + flags |= NLM_F_DUMP_FILTERED; 407 + goto per_port_dump; 408 + } 398 409 399 410 list_for_each_entry(reporter, &devlink->reporter_list, list) { 400 411 if (idx < state->idx) { ··· 416 405 DEVLINK_CMD_HEALTH_REPORTER_GET, 417 406 NETLINK_CB(cb->skb).portid, 418 407 cb->nlh->nlmsg_seq, 419 - NLM_F_MULTI); 408 + flags); 420 409 if (err) { 421 410 state->idx = idx; 422 411 return err; 423 412 } 424 413 idx++; 425 414 } 426 - xa_for_each(&devlink->ports, port_index, port) { 415 + per_port_dump: 416 + xa_for_each_range(&devlink->ports, port_index, port, 417 + port_index_start, port_index_end) { 427 418 list_for_each_entry(reporter, &port->reporter_list, list) { 428 419 if (idx < state->idx) { 429 420 idx++; ··· 435 422 DEVLINK_CMD_HEALTH_REPORTER_GET, 436 423 NETLINK_CB(cb->skb).portid, 437 424 cb->nlh->nlmsg_seq, 438 - NLM_F_MULTI); 425 + flags); 439 426 if (err) { 440 427 state->idx = idx; 441 428 return err; ··· 447 434 return 0; 448 435 } 449 436 450 - const struct devlink_cmd devl_cmd_health_reporter_get = { 451 - .dump_one = devlink_nl_cmd_health_reporter_get_dump_one, 452 - }; 437 + int devlink_nl_health_reporter_get_dumpit(struct sk_buff *skb, 438 + struct netlink_callback *cb) 439 + { 440 + return devlink_nl_dumpit(skb, cb, 441 + devlink_nl_health_reporter_get_dump_one); 442 + } 453 443 454 444 int devlink_nl_cmd_health_reporter_set_doit(struct sk_buff *skb, 455 445 struct genl_info *info)
+175 -246
net/devlink/leftover.c
··· 232 232 return devlink_rate_node_get_by_name(devlink, rate_node_name); 233 233 } 234 234 235 - struct devlink_rate * 235 + static struct devlink_rate * 236 236 devlink_rate_node_get_from_info(struct devlink *devlink, struct genl_info *info) 237 237 { 238 238 return devlink_rate_node_get_from_attrs(devlink, info->attrs); 239 239 } 240 240 241 - struct devlink_rate * 241 + static struct devlink_rate * 242 242 devlink_rate_get_from_info(struct devlink *devlink, struct genl_info *info) 243 243 { 244 244 struct nlattr **attrs = info->attrs; ··· 285 285 return ERR_PTR(-EINVAL); 286 286 } 287 287 288 - struct devlink_linecard * 288 + static struct devlink_linecard * 289 289 devlink_linecard_get_from_info(struct devlink *devlink, struct genl_info *info) 290 290 { 291 291 return devlink_linecard_get_from_attrs(devlink, info->attrs); ··· 1005 1005 } 1006 1006 1007 1007 static int 1008 - devlink_nl_cmd_rate_get_dump_one(struct sk_buff *msg, struct devlink *devlink, 1009 - struct netlink_callback *cb) 1008 + devlink_nl_rate_get_dump_one(struct sk_buff *msg, struct devlink *devlink, 1009 + struct netlink_callback *cb, int flags) 1010 1010 { 1011 1011 struct devlink_nl_dump_state *state = devlink_dump_state(cb); 1012 1012 struct devlink_rate *devlink_rate; ··· 1022 1022 continue; 1023 1023 } 1024 1024 err = devlink_nl_rate_fill(msg, devlink_rate, cmd, id, 1025 - cb->nlh->nlmsg_seq, 1026 - NLM_F_MULTI, NULL); 1025 + cb->nlh->nlmsg_seq, flags, NULL); 1027 1026 if (err) { 1028 1027 state->idx = idx; 1029 1028 break; ··· 1033 1034 return err; 1034 1035 } 1035 1036 1036 - const struct devlink_cmd devl_cmd_rate_get = { 1037 - .dump_one = devlink_nl_cmd_rate_get_dump_one, 1038 - }; 1039 - 1040 - static int devlink_nl_cmd_rate_get_doit(struct sk_buff *skb, 1041 - struct genl_info *info) 1037 + int devlink_nl_rate_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb) 1042 1038 { 1043 - struct devlink_rate *devlink_rate = info->user_ptr[1]; 1039 + return devlink_nl_dumpit(skb, cb, devlink_nl_rate_get_dump_one); 1040 + } 1041 + 1042 + int devlink_nl_rate_get_doit(struct sk_buff *skb, struct genl_info *info) 1043 + { 1044 + struct devlink *devlink = info->user_ptr[0]; 1045 + struct devlink_rate *devlink_rate; 1044 1046 struct sk_buff *msg; 1045 1047 int err; 1048 + 1049 + devlink_rate = devlink_rate_get_from_info(devlink, info); 1050 + if (IS_ERR(devlink_rate)) 1051 + return PTR_ERR(devlink_rate); 1046 1052 1047 1053 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1048 1054 if (!msg) ··· 1076 1072 return false; 1077 1073 } 1078 1074 1079 - static int devlink_nl_cmd_port_get_doit(struct sk_buff *skb, 1080 - struct genl_info *info) 1075 + int devlink_nl_port_get_doit(struct sk_buff *skb, struct genl_info *info) 1081 1076 { 1082 1077 struct devlink_port *devlink_port = info->user_ptr[1]; 1083 1078 struct sk_buff *msg; ··· 1098 1095 } 1099 1096 1100 1097 static int 1101 - devlink_nl_cmd_port_get_dump_one(struct sk_buff *msg, struct devlink *devlink, 1102 - struct netlink_callback *cb) 1098 + devlink_nl_port_get_dump_one(struct sk_buff *msg, struct devlink *devlink, 1099 + struct netlink_callback *cb, int flags) 1103 1100 { 1104 1101 struct devlink_nl_dump_state *state = devlink_dump_state(cb); 1105 1102 struct devlink_port *devlink_port; ··· 1110 1107 err = devlink_nl_port_fill(msg, devlink_port, 1111 1108 DEVLINK_CMD_NEW, 1112 1109 NETLINK_CB(cb->skb).portid, 1113 - cb->nlh->nlmsg_seq, 1114 - NLM_F_MULTI, cb->extack); 1110 + cb->nlh->nlmsg_seq, flags, 1111 + cb->extack); 1115 1112 if (err) { 1116 1113 state->idx = port_index; 1117 1114 break; ··· 1121 1118 return err; 1122 1119 } 1123 1120 1124 - const struct devlink_cmd devl_cmd_port_get = { 1125 - .dump_one = devlink_nl_cmd_port_get_dump_one, 1126 - }; 1121 + int devlink_nl_port_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb) 1122 + { 1123 + return devlink_nl_dumpit(skb, cb, devlink_nl_port_get_dump_one); 1124 + } 1127 1125 1128 1126 static int devlink_port_type_set(struct devlink_port *devlink_port, 1129 1127 enum devlink_port_type port_type) ··· 1633 1629 static int devlink_nl_cmd_rate_set_doit(struct sk_buff *skb, 1634 1630 struct genl_info *info) 1635 1631 { 1636 - struct devlink_rate *devlink_rate = info->user_ptr[1]; 1637 - struct devlink *devlink = devlink_rate->devlink; 1638 - const struct devlink_ops *ops = devlink->ops; 1632 + struct devlink *devlink = info->user_ptr[0]; 1633 + struct devlink_rate *devlink_rate; 1634 + const struct devlink_ops *ops; 1639 1635 int err; 1640 1636 1637 + devlink_rate = devlink_rate_get_from_info(devlink, info); 1638 + if (IS_ERR(devlink_rate)) 1639 + return PTR_ERR(devlink_rate); 1640 + 1641 + ops = devlink->ops; 1641 1642 if (!ops || !devlink_rate_set_ops_supported(ops, info, devlink_rate->type)) 1642 1643 return -EOPNOTSUPP; 1643 1644 ··· 1713 1704 static int devlink_nl_cmd_rate_del_doit(struct sk_buff *skb, 1714 1705 struct genl_info *info) 1715 1706 { 1716 - struct devlink_rate *rate_node = info->user_ptr[1]; 1717 - struct devlink *devlink = rate_node->devlink; 1718 - const struct devlink_ops *ops = devlink->ops; 1707 + struct devlink *devlink = info->user_ptr[0]; 1708 + struct devlink_rate *rate_node; 1719 1709 int err; 1710 + 1711 + rate_node = devlink_rate_node_get_from_info(devlink, info); 1712 + if (IS_ERR(rate_node)) 1713 + return PTR_ERR(rate_node); 1720 1714 1721 1715 if (refcount_read(&rate_node->refcnt) > 1) { 1722 1716 NL_SET_ERR_MSG(info->extack, "Node has children. Cannot delete node."); ··· 1727 1715 } 1728 1716 1729 1717 devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_DEL); 1730 - err = ops->rate_node_del(rate_node, rate_node->priv, info->extack); 1718 + err = devlink->ops->rate_node_del(rate_node, rate_node->priv, 1719 + info->extack); 1731 1720 if (rate_node->parent) 1732 1721 refcount_dec(&rate_node->parent->refcnt); 1733 1722 list_del(&rate_node->list); ··· 1824 1811 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); 1825 1812 } 1826 1813 1827 - static int devlink_nl_cmd_linecard_get_doit(struct sk_buff *skb, 1828 - struct genl_info *info) 1814 + int devlink_nl_linecard_get_doit(struct sk_buff *skb, struct genl_info *info) 1829 1815 { 1830 - struct devlink_linecard *linecard = info->user_ptr[1]; 1831 - struct devlink *devlink = linecard->devlink; 1816 + struct devlink *devlink = info->user_ptr[0]; 1817 + struct devlink_linecard *linecard; 1832 1818 struct sk_buff *msg; 1833 1819 int err; 1820 + 1821 + linecard = devlink_linecard_get_from_info(devlink, info); 1822 + if (IS_ERR(linecard)) 1823 + return PTR_ERR(linecard); 1834 1824 1835 1825 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1836 1826 if (!msg) ··· 1853 1837 return genlmsg_reply(msg, info); 1854 1838 } 1855 1839 1856 - static int devlink_nl_cmd_linecard_get_dump_one(struct sk_buff *msg, 1857 - struct devlink *devlink, 1858 - struct netlink_callback *cb) 1840 + static int devlink_nl_linecard_get_dump_one(struct sk_buff *msg, 1841 + struct devlink *devlink, 1842 + struct netlink_callback *cb, 1843 + int flags) 1859 1844 { 1860 1845 struct devlink_nl_dump_state *state = devlink_dump_state(cb); 1861 1846 struct devlink_linecard *linecard; ··· 1872 1855 err = devlink_nl_linecard_fill(msg, devlink, linecard, 1873 1856 DEVLINK_CMD_LINECARD_NEW, 1874 1857 NETLINK_CB(cb->skb).portid, 1875 - cb->nlh->nlmsg_seq, 1876 - NLM_F_MULTI, 1858 + cb->nlh->nlmsg_seq, flags, 1877 1859 cb->extack); 1878 1860 mutex_unlock(&linecard->state_lock); 1879 1861 if (err) { ··· 1885 1869 return err; 1886 1870 } 1887 1871 1888 - const struct devlink_cmd devl_cmd_linecard_get = { 1889 - .dump_one = devlink_nl_cmd_linecard_get_dump_one, 1890 - }; 1872 + int devlink_nl_linecard_get_dumpit(struct sk_buff *skb, 1873 + struct netlink_callback *cb) 1874 + { 1875 + return devlink_nl_dumpit(skb, cb, devlink_nl_linecard_get_dump_one); 1876 + } 1891 1877 1892 1878 static struct devlink_linecard_type * 1893 1879 devlink_linecard_type_lookup(struct devlink_linecard *linecard, ··· 2026 2008 static int devlink_nl_cmd_linecard_set_doit(struct sk_buff *skb, 2027 2009 struct genl_info *info) 2028 2010 { 2029 - struct devlink_linecard *linecard = info->user_ptr[1]; 2030 2011 struct netlink_ext_ack *extack = info->extack; 2012 + struct devlink *devlink = info->user_ptr[0]; 2013 + struct devlink_linecard *linecard; 2031 2014 int err; 2015 + 2016 + linecard = devlink_linecard_get_from_info(devlink, info); 2017 + if (IS_ERR(linecard)) 2018 + return PTR_ERR(linecard); 2032 2019 2033 2020 if (info->attrs[DEVLINK_ATTR_LINECARD_TYPE]) { 2034 2021 const char *type; ··· 2091 2068 return -EMSGSIZE; 2092 2069 } 2093 2070 2094 - static int devlink_nl_cmd_sb_get_doit(struct sk_buff *skb, 2095 - struct genl_info *info) 2071 + int devlink_nl_sb_get_doit(struct sk_buff *skb, struct genl_info *info) 2096 2072 { 2097 2073 struct devlink *devlink = info->user_ptr[0]; 2098 2074 struct devlink_sb *devlink_sb; ··· 2118 2096 } 2119 2097 2120 2098 static int 2121 - devlink_nl_cmd_sb_get_dump_one(struct sk_buff *msg, struct devlink *devlink, 2122 - struct netlink_callback *cb) 2099 + devlink_nl_sb_get_dump_one(struct sk_buff *msg, struct devlink *devlink, 2100 + struct netlink_callback *cb, int flags) 2123 2101 { 2124 2102 struct devlink_nl_dump_state *state = devlink_dump_state(cb); 2125 2103 struct devlink_sb *devlink_sb; ··· 2134 2112 err = devlink_nl_sb_fill(msg, devlink, devlink_sb, 2135 2113 DEVLINK_CMD_SB_NEW, 2136 2114 NETLINK_CB(cb->skb).portid, 2137 - cb->nlh->nlmsg_seq, 2138 - NLM_F_MULTI); 2115 + cb->nlh->nlmsg_seq, flags); 2139 2116 if (err) { 2140 2117 state->idx = idx; 2141 2118 break; ··· 2145 2124 return err; 2146 2125 } 2147 2126 2148 - const struct devlink_cmd devl_cmd_sb_get = { 2149 - .dump_one = devlink_nl_cmd_sb_get_dump_one, 2150 - }; 2127 + int devlink_nl_sb_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb) 2128 + { 2129 + return devlink_nl_dumpit(skb, cb, devlink_nl_sb_get_dump_one); 2130 + } 2151 2131 2152 2132 static int devlink_nl_sb_pool_fill(struct sk_buff *msg, struct devlink *devlink, 2153 2133 struct devlink_sb *devlink_sb, ··· 2193 2171 return -EMSGSIZE; 2194 2172 } 2195 2173 2196 - static int devlink_nl_cmd_sb_pool_get_doit(struct sk_buff *skb, 2197 - struct genl_info *info) 2174 + int devlink_nl_sb_pool_get_doit(struct sk_buff *skb, struct genl_info *info) 2198 2175 { 2199 2176 struct devlink *devlink = info->user_ptr[0]; 2200 2177 struct devlink_sb *devlink_sb; ··· 2231 2210 static int __sb_pool_get_dumpit(struct sk_buff *msg, int start, int *p_idx, 2232 2211 struct devlink *devlink, 2233 2212 struct devlink_sb *devlink_sb, 2234 - u32 portid, u32 seq) 2213 + u32 portid, u32 seq, int flags) 2235 2214 { 2236 2215 u16 pool_count = devlink_sb_pool_count(devlink_sb); 2237 2216 u16 pool_index; ··· 2246 2225 devlink_sb, 2247 2226 pool_index, 2248 2227 DEVLINK_CMD_SB_POOL_NEW, 2249 - portid, seq, NLM_F_MULTI); 2228 + portid, seq, flags); 2250 2229 if (err) 2251 2230 return err; 2252 2231 (*p_idx)++; ··· 2255 2234 } 2256 2235 2257 2236 static int 2258 - devlink_nl_cmd_sb_pool_get_dump_one(struct sk_buff *msg, 2259 - struct devlink *devlink, 2260 - struct netlink_callback *cb) 2237 + devlink_nl_sb_pool_get_dump_one(struct sk_buff *msg, struct devlink *devlink, 2238 + struct netlink_callback *cb, int flags) 2261 2239 { 2262 2240 struct devlink_nl_dump_state *state = devlink_dump_state(cb); 2263 2241 struct devlink_sb *devlink_sb; ··· 2270 2250 err = __sb_pool_get_dumpit(msg, state->idx, &idx, 2271 2251 devlink, devlink_sb, 2272 2252 NETLINK_CB(cb->skb).portid, 2273 - cb->nlh->nlmsg_seq); 2253 + cb->nlh->nlmsg_seq, flags); 2274 2254 if (err == -EOPNOTSUPP) { 2275 2255 err = 0; 2276 2256 } else if (err) { ··· 2282 2262 return err; 2283 2263 } 2284 2264 2285 - const struct devlink_cmd devl_cmd_sb_pool_get = { 2286 - .dump_one = devlink_nl_cmd_sb_pool_get_dump_one, 2287 - }; 2265 + int devlink_nl_sb_pool_get_dumpit(struct sk_buff *skb, 2266 + struct netlink_callback *cb) 2267 + { 2268 + return devlink_nl_dumpit(skb, cb, devlink_nl_sb_pool_get_dump_one); 2269 + } 2288 2270 2289 2271 static int devlink_sb_pool_set(struct devlink *devlink, unsigned int sb_index, 2290 2272 u16 pool_index, u32 size, ··· 2393 2371 return err; 2394 2372 } 2395 2373 2396 - static int devlink_nl_cmd_sb_port_pool_get_doit(struct sk_buff *skb, 2397 - struct genl_info *info) 2374 + int devlink_nl_sb_port_pool_get_doit(struct sk_buff *skb, 2375 + struct genl_info *info) 2398 2376 { 2399 2377 struct devlink_port *devlink_port = info->user_ptr[1]; 2400 2378 struct devlink *devlink = devlink_port->devlink; ··· 2434 2412 static int __sb_port_pool_get_dumpit(struct sk_buff *msg, int start, int *p_idx, 2435 2413 struct devlink *devlink, 2436 2414 struct devlink_sb *devlink_sb, 2437 - u32 portid, u32 seq) 2415 + u32 portid, u32 seq, int flags) 2438 2416 { 2439 2417 struct devlink_port *devlink_port; 2440 2418 u16 pool_count = devlink_sb_pool_count(devlink_sb); ··· 2453 2431 devlink_sb, 2454 2432 pool_index, 2455 2433 DEVLINK_CMD_SB_PORT_POOL_NEW, 2456 - portid, seq, 2457 - NLM_F_MULTI); 2434 + portid, seq, flags); 2458 2435 if (err) 2459 2436 return err; 2460 2437 (*p_idx)++; ··· 2463 2442 } 2464 2443 2465 2444 static int 2466 - devlink_nl_cmd_sb_port_pool_get_dump_one(struct sk_buff *msg, 2467 - struct devlink *devlink, 2468 - struct netlink_callback *cb) 2445 + devlink_nl_sb_port_pool_get_dump_one(struct sk_buff *msg, 2446 + struct devlink *devlink, 2447 + struct netlink_callback *cb, int flags) 2469 2448 { 2470 2449 struct devlink_nl_dump_state *state = devlink_dump_state(cb); 2471 2450 struct devlink_sb *devlink_sb; ··· 2479 2458 err = __sb_port_pool_get_dumpit(msg, state->idx, &idx, 2480 2459 devlink, devlink_sb, 2481 2460 NETLINK_CB(cb->skb).portid, 2482 - cb->nlh->nlmsg_seq); 2461 + cb->nlh->nlmsg_seq, flags); 2483 2462 if (err == -EOPNOTSUPP) { 2484 2463 err = 0; 2485 2464 } else if (err) { ··· 2491 2470 return err; 2492 2471 } 2493 2472 2494 - const struct devlink_cmd devl_cmd_sb_port_pool_get = { 2495 - .dump_one = devlink_nl_cmd_sb_port_pool_get_dump_one, 2496 - }; 2473 + int devlink_nl_sb_port_pool_get_dumpit(struct sk_buff *skb, 2474 + struct netlink_callback *cb) 2475 + { 2476 + return devlink_nl_dumpit(skb, cb, devlink_nl_sb_port_pool_get_dump_one); 2477 + } 2497 2478 2498 2479 static int devlink_sb_port_pool_set(struct devlink_port *devlink_port, 2499 2480 unsigned int sb_index, u16 pool_index, ··· 2603 2580 return -EMSGSIZE; 2604 2581 } 2605 2582 2606 - static int devlink_nl_cmd_sb_tc_pool_bind_get_doit(struct sk_buff *skb, 2607 - struct genl_info *info) 2583 + int devlink_nl_sb_tc_pool_bind_get_doit(struct sk_buff *skb, 2584 + struct genl_info *info) 2608 2585 { 2609 2586 struct devlink_port *devlink_port = info->user_ptr[1]; 2610 2587 struct devlink *devlink = devlink_port->devlink; ··· 2651 2628 int start, int *p_idx, 2652 2629 struct devlink *devlink, 2653 2630 struct devlink_sb *devlink_sb, 2654 - u32 portid, u32 seq) 2631 + u32 portid, u32 seq, int flags) 2655 2632 { 2656 2633 struct devlink_port *devlink_port; 2657 2634 unsigned long port_index; ··· 2672 2649 DEVLINK_SB_POOL_TYPE_INGRESS, 2673 2650 DEVLINK_CMD_SB_TC_POOL_BIND_NEW, 2674 2651 portid, seq, 2675 - NLM_F_MULTI); 2652 + flags); 2676 2653 if (err) 2677 2654 return err; 2678 2655 (*p_idx)++; ··· 2690 2667 DEVLINK_SB_POOL_TYPE_EGRESS, 2691 2668 DEVLINK_CMD_SB_TC_POOL_BIND_NEW, 2692 2669 portid, seq, 2693 - NLM_F_MULTI); 2670 + flags); 2694 2671 if (err) 2695 2672 return err; 2696 2673 (*p_idx)++; ··· 2699 2676 return 0; 2700 2677 } 2701 2678 2702 - static int 2703 - devlink_nl_cmd_sb_tc_pool_bind_get_dump_one(struct sk_buff *msg, 2704 - struct devlink *devlink, 2705 - struct netlink_callback *cb) 2679 + static int devlink_nl_sb_tc_pool_bind_get_dump_one(struct sk_buff *msg, 2680 + struct devlink *devlink, 2681 + struct netlink_callback *cb, 2682 + int flags) 2706 2683 { 2707 2684 struct devlink_nl_dump_state *state = devlink_dump_state(cb); 2708 2685 struct devlink_sb *devlink_sb; ··· 2716 2693 err = __sb_tc_pool_bind_get_dumpit(msg, state->idx, &idx, 2717 2694 devlink, devlink_sb, 2718 2695 NETLINK_CB(cb->skb).portid, 2719 - cb->nlh->nlmsg_seq); 2696 + cb->nlh->nlmsg_seq, flags); 2720 2697 if (err == -EOPNOTSUPP) { 2721 2698 err = 0; 2722 2699 } else if (err) { ··· 2728 2705 return err; 2729 2706 } 2730 2707 2731 - const struct devlink_cmd devl_cmd_sb_tc_pool_bind_get = { 2732 - .dump_one = devlink_nl_cmd_sb_tc_pool_bind_get_dump_one, 2733 - }; 2708 + int devlink_nl_sb_tc_pool_bind_get_dumpit(struct sk_buff *skb, 2709 + struct netlink_callback *cb) 2710 + { 2711 + return devlink_nl_dumpit(skb, cb, 2712 + devlink_nl_sb_tc_pool_bind_get_dump_one); 2713 + } 2734 2714 2735 2715 static int devlink_sb_tc_pool_bind_set(struct devlink_port *devlink_port, 2736 2716 unsigned int sb_index, u16 tc_index, ··· 4181 4155 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); 4182 4156 } 4183 4157 4184 - static int 4185 - devlink_nl_cmd_param_get_dump_one(struct sk_buff *msg, struct devlink *devlink, 4186 - struct netlink_callback *cb) 4158 + static int devlink_nl_param_get_dump_one(struct sk_buff *msg, 4159 + struct devlink *devlink, 4160 + struct netlink_callback *cb, 4161 + int flags) 4187 4162 { 4188 4163 struct devlink_nl_dump_state *state = devlink_dump_state(cb); 4189 4164 struct devlink_param_item *param_item; ··· 4195 4168 err = devlink_nl_param_fill(msg, devlink, 0, param_item, 4196 4169 DEVLINK_CMD_PARAM_GET, 4197 4170 NETLINK_CB(cb->skb).portid, 4198 - cb->nlh->nlmsg_seq, 4199 - NLM_F_MULTI); 4171 + cb->nlh->nlmsg_seq, flags); 4200 4172 if (err == -EOPNOTSUPP) { 4201 4173 err = 0; 4202 4174 } else if (err) { ··· 4207 4181 return err; 4208 4182 } 4209 4183 4210 - const struct devlink_cmd devl_cmd_param_get = { 4211 - .dump_one = devlink_nl_cmd_param_get_dump_one, 4212 - }; 4184 + int devlink_nl_param_get_dumpit(struct sk_buff *skb, 4185 + struct netlink_callback *cb) 4186 + { 4187 + return devlink_nl_dumpit(skb, cb, devlink_nl_param_get_dump_one); 4188 + } 4213 4189 4214 4190 static int 4215 4191 devlink_param_type_get_from_info(struct genl_info *info, ··· 4300 4272 return devlink_param_find_by_name(params, param_name); 4301 4273 } 4302 4274 4303 - static int devlink_nl_cmd_param_get_doit(struct sk_buff *skb, 4304 - struct genl_info *info) 4275 + int devlink_nl_param_get_doit(struct sk_buff *skb, 4276 + struct genl_info *info) 4305 4277 { 4306 4278 struct devlink *devlink = info->user_ptr[0]; 4307 4279 struct devlink_param_item *param_item; ··· 4798 4770 kfree(snapshot); 4799 4771 } 4800 4772 4801 - static int devlink_nl_cmd_region_get_doit(struct sk_buff *skb, 4802 - struct genl_info *info) 4773 + int devlink_nl_region_get_doit(struct sk_buff *skb, struct genl_info *info) 4803 4774 { 4804 4775 struct devlink *devlink = info->user_ptr[0]; 4805 4776 struct devlink_port *port = NULL; ··· 4846 4819 static int devlink_nl_cmd_region_get_port_dumpit(struct sk_buff *msg, 4847 4820 struct netlink_callback *cb, 4848 4821 struct devlink_port *port, 4849 - int *idx, 4850 - int start) 4822 + int *idx, int start, int flags) 4851 4823 { 4852 4824 struct devlink_region *region; 4853 4825 int err = 0; ··· 4860 4834 DEVLINK_CMD_REGION_GET, 4861 4835 NETLINK_CB(cb->skb).portid, 4862 4836 cb->nlh->nlmsg_seq, 4863 - NLM_F_MULTI, region); 4837 + flags, region); 4864 4838 if (err) 4865 4839 goto out; 4866 4840 (*idx)++; ··· 4870 4844 return err; 4871 4845 } 4872 4846 4873 - static int 4874 - devlink_nl_cmd_region_get_dump_one(struct sk_buff *msg, struct devlink *devlink, 4875 - struct netlink_callback *cb) 4847 + static int devlink_nl_region_get_dump_one(struct sk_buff *msg, 4848 + struct devlink *devlink, 4849 + struct netlink_callback *cb, 4850 + int flags) 4876 4851 { 4877 4852 struct devlink_nl_dump_state *state = devlink_dump_state(cb); 4878 4853 struct devlink_region *region; ··· 4890 4863 err = devlink_nl_region_fill(msg, devlink, 4891 4864 DEVLINK_CMD_REGION_GET, 4892 4865 NETLINK_CB(cb->skb).portid, 4893 - cb->nlh->nlmsg_seq, 4894 - NLM_F_MULTI, region); 4866 + cb->nlh->nlmsg_seq, flags, 4867 + region); 4895 4868 if (err) { 4896 4869 state->idx = idx; 4897 4870 return err; ··· 4901 4874 4902 4875 xa_for_each(&devlink->ports, port_index, port) { 4903 4876 err = devlink_nl_cmd_region_get_port_dumpit(msg, cb, port, &idx, 4904 - state->idx); 4877 + state->idx, flags); 4905 4878 if (err) { 4906 4879 state->idx = idx; 4907 4880 return err; ··· 4911 4884 return 0; 4912 4885 } 4913 4886 4914 - const struct devlink_cmd devl_cmd_region_get = { 4915 - .dump_one = devlink_nl_cmd_region_get_dump_one, 4916 - }; 4887 + int devlink_nl_region_get_dumpit(struct sk_buff *skb, 4888 + struct netlink_callback *cb) 4889 + { 4890 + return devlink_nl_dumpit(skb, cb, devlink_nl_region_get_dump_one); 4891 + } 4917 4892 4918 4893 static int devlink_nl_cmd_region_del(struct sk_buff *skb, 4919 4894 struct genl_info *info) ··· 5661 5632 return -EMSGSIZE; 5662 5633 } 5663 5634 5664 - static int devlink_nl_cmd_trap_get_doit(struct sk_buff *skb, 5665 - struct genl_info *info) 5635 + int devlink_nl_trap_get_doit(struct sk_buff *skb, struct genl_info *info) 5666 5636 { 5667 5637 struct netlink_ext_ack *extack = info->extack; 5668 5638 struct devlink *devlink = info->user_ptr[0]; ··· 5695 5667 return err; 5696 5668 } 5697 5669 5698 - static int 5699 - devlink_nl_cmd_trap_get_dump_one(struct sk_buff *msg, struct devlink *devlink, 5700 - struct netlink_callback *cb) 5670 + static int devlink_nl_trap_get_dump_one(struct sk_buff *msg, 5671 + struct devlink *devlink, 5672 + struct netlink_callback *cb, int flags) 5701 5673 { 5702 5674 struct devlink_nl_dump_state *state = devlink_dump_state(cb); 5703 5675 struct devlink_trap_item *trap_item; ··· 5712 5684 err = devlink_nl_trap_fill(msg, devlink, trap_item, 5713 5685 DEVLINK_CMD_TRAP_NEW, 5714 5686 NETLINK_CB(cb->skb).portid, 5715 - cb->nlh->nlmsg_seq, 5716 - NLM_F_MULTI); 5687 + cb->nlh->nlmsg_seq, flags); 5717 5688 if (err) { 5718 5689 state->idx = idx; 5719 5690 break; ··· 5723 5696 return err; 5724 5697 } 5725 5698 5726 - const struct devlink_cmd devl_cmd_trap_get = { 5727 - .dump_one = devlink_nl_cmd_trap_get_dump_one, 5728 - }; 5699 + int devlink_nl_trap_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb) 5700 + { 5701 + return devlink_nl_dumpit(skb, cb, devlink_nl_trap_get_dump_one); 5702 + } 5729 5703 5730 5704 static int __devlink_trap_action_set(struct devlink *devlink, 5731 5705 struct devlink_trap_item *trap_item, ··· 5871 5843 return -EMSGSIZE; 5872 5844 } 5873 5845 5874 - static int devlink_nl_cmd_trap_group_get_doit(struct sk_buff *skb, 5875 - struct genl_info *info) 5846 + int devlink_nl_trap_group_get_doit(struct sk_buff *skb, struct genl_info *info) 5876 5847 { 5877 5848 struct netlink_ext_ack *extack = info->extack; 5878 5849 struct devlink *devlink = info->user_ptr[0]; ··· 5905 5878 return err; 5906 5879 } 5907 5880 5908 - static int 5909 - devlink_nl_cmd_trap_group_get_dump_one(struct sk_buff *msg, 5910 - struct devlink *devlink, 5911 - struct netlink_callback *cb) 5881 + static int devlink_nl_trap_group_get_dump_one(struct sk_buff *msg, 5882 + struct devlink *devlink, 5883 + struct netlink_callback *cb, 5884 + int flags) 5912 5885 { 5913 5886 struct devlink_nl_dump_state *state = devlink_dump_state(cb); 5914 5887 struct devlink_trap_group_item *group_item; ··· 5924 5897 err = devlink_nl_trap_group_fill(msg, devlink, group_item, 5925 5898 DEVLINK_CMD_TRAP_GROUP_NEW, 5926 5899 NETLINK_CB(cb->skb).portid, 5927 - cb->nlh->nlmsg_seq, 5928 - NLM_F_MULTI); 5900 + cb->nlh->nlmsg_seq, flags); 5929 5901 if (err) { 5930 5902 state->idx = idx; 5931 5903 break; ··· 5935 5909 return err; 5936 5910 } 5937 5911 5938 - const struct devlink_cmd devl_cmd_trap_group_get = { 5939 - .dump_one = devlink_nl_cmd_trap_group_get_dump_one, 5940 - }; 5912 + int devlink_nl_trap_group_get_dumpit(struct sk_buff *skb, 5913 + struct netlink_callback *cb) 5914 + { 5915 + return devlink_nl_dumpit(skb, cb, devlink_nl_trap_group_get_dump_one); 5916 + } 5941 5917 5942 5918 static int 5943 5919 __devlink_trap_group_action_set(struct devlink *devlink, ··· 6165 6137 return -EMSGSIZE; 6166 6138 } 6167 6139 6168 - static int devlink_nl_cmd_trap_policer_get_doit(struct sk_buff *skb, 6169 - struct genl_info *info) 6140 + int devlink_nl_trap_policer_get_doit(struct sk_buff *skb, 6141 + struct genl_info *info) 6170 6142 { 6171 6143 struct devlink_trap_policer_item *policer_item; 6172 6144 struct netlink_ext_ack *extack = info->extack; ··· 6200 6172 return err; 6201 6173 } 6202 6174 6203 - static int 6204 - devlink_nl_cmd_trap_policer_get_dump_one(struct sk_buff *msg, 6205 - struct devlink *devlink, 6206 - struct netlink_callback *cb) 6175 + static int devlink_nl_trap_policer_get_dump_one(struct sk_buff *msg, 6176 + struct devlink *devlink, 6177 + struct netlink_callback *cb, 6178 + int flags) 6207 6179 { 6208 6180 struct devlink_nl_dump_state *state = devlink_dump_state(cb); 6209 6181 struct devlink_trap_policer_item *policer_item; ··· 6218 6190 err = devlink_nl_trap_policer_fill(msg, devlink, policer_item, 6219 6191 DEVLINK_CMD_TRAP_POLICER_NEW, 6220 6192 NETLINK_CB(cb->skb).portid, 6221 - cb->nlh->nlmsg_seq, 6222 - NLM_F_MULTI); 6193 + cb->nlh->nlmsg_seq, flags); 6223 6194 if (err) { 6224 6195 state->idx = idx; 6225 6196 break; ··· 6229 6202 return err; 6230 6203 } 6231 6204 6232 - const struct devlink_cmd devl_cmd_trap_policer_get = { 6233 - .dump_one = devlink_nl_cmd_trap_policer_get_dump_one, 6234 - }; 6205 + int devlink_nl_trap_policer_get_dumpit(struct sk_buff *skb, 6206 + struct netlink_callback *cb) 6207 + { 6208 + return devlink_nl_dumpit(skb, cb, devlink_nl_trap_policer_get_dump_one); 6209 + } 6235 6210 6236 6211 static int 6237 6212 devlink_trap_policer_set(struct devlink *devlink, ··· 6307 6278 return devlink_trap_policer_set(devlink, policer_item, info); 6308 6279 } 6309 6280 6310 - const struct genl_small_ops devlink_nl_small_ops[54] = { 6311 - { 6312 - .cmd = DEVLINK_CMD_PORT_GET, 6313 - .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 6314 - .doit = devlink_nl_cmd_port_get_doit, 6315 - .dumpit = devlink_nl_instance_iter_dumpit, 6316 - .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, 6317 - /* can be retrieved by unprivileged users */ 6318 - }, 6281 + const struct genl_small_ops devlink_nl_small_ops[40] = { 6319 6282 { 6320 6283 .cmd = DEVLINK_CMD_PORT_SET, 6321 6284 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, ··· 6316 6295 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, 6317 6296 }, 6318 6297 { 6319 - .cmd = DEVLINK_CMD_RATE_GET, 6320 - .doit = devlink_nl_cmd_rate_get_doit, 6321 - .dumpit = devlink_nl_instance_iter_dumpit, 6322 - .internal_flags = DEVLINK_NL_FLAG_NEED_RATE, 6323 - /* can be retrieved by unprivileged users */ 6324 - }, 6325 - { 6326 6298 .cmd = DEVLINK_CMD_RATE_SET, 6327 6299 .doit = devlink_nl_cmd_rate_set_doit, 6328 6300 .flags = GENL_ADMIN_PERM, 6329 - .internal_flags = DEVLINK_NL_FLAG_NEED_RATE, 6330 6301 }, 6331 6302 { 6332 6303 .cmd = DEVLINK_CMD_RATE_NEW, ··· 6329 6316 .cmd = DEVLINK_CMD_RATE_DEL, 6330 6317 .doit = devlink_nl_cmd_rate_del_doit, 6331 6318 .flags = GENL_ADMIN_PERM, 6332 - .internal_flags = DEVLINK_NL_FLAG_NEED_RATE_NODE, 6333 6319 }, 6334 6320 { 6335 6321 .cmd = DEVLINK_CMD_PORT_SPLIT, ··· 6355 6343 .flags = GENL_ADMIN_PERM, 6356 6344 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, 6357 6345 }, 6358 - { 6359 - .cmd = DEVLINK_CMD_LINECARD_GET, 6360 - .doit = devlink_nl_cmd_linecard_get_doit, 6361 - .dumpit = devlink_nl_instance_iter_dumpit, 6362 - .internal_flags = DEVLINK_NL_FLAG_NEED_LINECARD, 6363 - /* can be retrieved by unprivileged users */ 6364 - }, 6346 + 6365 6347 { 6366 6348 .cmd = DEVLINK_CMD_LINECARD_SET, 6367 6349 .doit = devlink_nl_cmd_linecard_set_doit, 6368 6350 .flags = GENL_ADMIN_PERM, 6369 - .internal_flags = DEVLINK_NL_FLAG_NEED_LINECARD, 6370 - }, 6371 - { 6372 - .cmd = DEVLINK_CMD_SB_GET, 6373 - .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 6374 - .doit = devlink_nl_cmd_sb_get_doit, 6375 - .dumpit = devlink_nl_instance_iter_dumpit, 6376 - /* can be retrieved by unprivileged users */ 6377 - }, 6378 - { 6379 - .cmd = DEVLINK_CMD_SB_POOL_GET, 6380 - .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 6381 - .doit = devlink_nl_cmd_sb_pool_get_doit, 6382 - .dumpit = devlink_nl_instance_iter_dumpit, 6383 - /* can be retrieved by unprivileged users */ 6384 6351 }, 6385 6352 { 6386 6353 .cmd = DEVLINK_CMD_SB_POOL_SET, ··· 6368 6377 .flags = GENL_ADMIN_PERM, 6369 6378 }, 6370 6379 { 6371 - .cmd = DEVLINK_CMD_SB_PORT_POOL_GET, 6372 - .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 6373 - .doit = devlink_nl_cmd_sb_port_pool_get_doit, 6374 - .dumpit = devlink_nl_instance_iter_dumpit, 6375 - .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, 6376 - /* can be retrieved by unprivileged users */ 6377 - }, 6378 - { 6379 6380 .cmd = DEVLINK_CMD_SB_PORT_POOL_SET, 6380 6381 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 6381 6382 .doit = devlink_nl_cmd_sb_port_pool_set_doit, 6382 6383 .flags = GENL_ADMIN_PERM, 6383 6384 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, 6384 - }, 6385 - { 6386 - .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_GET, 6387 - .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 6388 - .doit = devlink_nl_cmd_sb_tc_pool_bind_get_doit, 6389 - .dumpit = devlink_nl_instance_iter_dumpit, 6390 - .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, 6391 - /* can be retrieved by unprivileged users */ 6392 6385 }, 6393 6386 { 6394 6387 .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_SET, ··· 6448 6473 .flags = GENL_ADMIN_PERM, 6449 6474 }, 6450 6475 { 6451 - .cmd = DEVLINK_CMD_PARAM_GET, 6452 - .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 6453 - .doit = devlink_nl_cmd_param_get_doit, 6454 - .dumpit = devlink_nl_instance_iter_dumpit, 6455 - /* can be retrieved by unprivileged users */ 6456 - }, 6457 - { 6458 6476 .cmd = DEVLINK_CMD_PARAM_SET, 6459 6477 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 6460 6478 .doit = devlink_nl_cmd_param_set_doit, ··· 6469 6501 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, 6470 6502 }, 6471 6503 { 6472 - .cmd = DEVLINK_CMD_REGION_GET, 6473 - .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 6474 - .doit = devlink_nl_cmd_region_get_doit, 6475 - .dumpit = devlink_nl_instance_iter_dumpit, 6476 - .flags = GENL_ADMIN_PERM, 6477 - }, 6478 - { 6479 6504 .cmd = DEVLINK_CMD_REGION_NEW, 6480 6505 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 6481 6506 .doit = devlink_nl_cmd_region_new, ··· 6486 6525 GENL_DONT_VALIDATE_DUMP_STRICT, 6487 6526 .dumpit = devlink_nl_cmd_region_read_dumpit, 6488 6527 .flags = GENL_ADMIN_PERM, 6489 - }, 6490 - { 6491 - .cmd = DEVLINK_CMD_HEALTH_REPORTER_GET, 6492 - .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 6493 - .doit = devlink_nl_cmd_health_reporter_get_doit, 6494 - .dumpit = devlink_nl_instance_iter_dumpit, 6495 - .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT, 6496 - /* can be retrieved by unprivileged users */ 6497 6528 }, 6498 6529 { 6499 6530 .cmd = DEVLINK_CMD_HEALTH_REPORTER_SET, ··· 6536 6583 .flags = GENL_ADMIN_PERM, 6537 6584 }, 6538 6585 { 6539 - .cmd = DEVLINK_CMD_TRAP_GET, 6540 - .doit = devlink_nl_cmd_trap_get_doit, 6541 - .dumpit = devlink_nl_instance_iter_dumpit, 6542 - /* can be retrieved by unprivileged users */ 6543 - }, 6544 - { 6545 6586 .cmd = DEVLINK_CMD_TRAP_SET, 6546 6587 .doit = devlink_nl_cmd_trap_set_doit, 6547 6588 .flags = GENL_ADMIN_PERM, 6548 - }, 6549 - { 6550 - .cmd = DEVLINK_CMD_TRAP_GROUP_GET, 6551 - .doit = devlink_nl_cmd_trap_group_get_doit, 6552 - .dumpit = devlink_nl_instance_iter_dumpit, 6553 - /* can be retrieved by unprivileged users */ 6554 6589 }, 6555 6590 { 6556 6591 .cmd = DEVLINK_CMD_TRAP_GROUP_SET, ··· 6546 6605 .flags = GENL_ADMIN_PERM, 6547 6606 }, 6548 6607 { 6549 - .cmd = DEVLINK_CMD_TRAP_POLICER_GET, 6550 - .doit = devlink_nl_cmd_trap_policer_get_doit, 6551 - .dumpit = devlink_nl_instance_iter_dumpit, 6552 - /* can be retrieved by unprivileged users */ 6553 - }, 6554 - { 6555 6608 .cmd = DEVLINK_CMD_TRAP_POLICER_SET, 6556 6609 .doit = devlink_nl_cmd_trap_policer_set_doit, 6557 6610 .flags = GENL_ADMIN_PERM, 6558 - }, 6559 - { 6560 - .cmd = DEVLINK_CMD_SELFTESTS_GET, 6561 - .doit = devlink_nl_cmd_selftests_get_doit, 6562 - .dumpit = devlink_nl_instance_iter_dumpit, 6563 - /* can be retrieved by unprivileged users */ 6564 6611 }, 6565 6612 { 6566 6613 .cmd = DEVLINK_CMD_SELFTESTS_RUN,
+57 -53
net/devlink/netlink.c
··· 109 109 return ERR_PTR(-ENODEV); 110 110 } 111 111 112 - int devlink_nl_pre_doit(const struct genl_split_ops *ops, 113 - struct sk_buff *skb, struct genl_info *info) 112 + static int __devlink_nl_pre_doit(struct sk_buff *skb, struct genl_info *info, 113 + u8 flags) 114 114 { 115 - struct devlink_linecard *linecard; 116 115 struct devlink_port *devlink_port; 117 116 struct devlink *devlink; 118 117 int err; ··· 121 122 return PTR_ERR(devlink); 122 123 123 124 info->user_ptr[0] = devlink; 124 - if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_PORT) { 125 + if (flags & DEVLINK_NL_FLAG_NEED_PORT) { 125 126 devlink_port = devlink_port_get_from_info(devlink, info); 126 127 if (IS_ERR(devlink_port)) { 127 128 err = PTR_ERR(devlink_port); 128 129 goto unlock; 129 130 } 130 131 info->user_ptr[1] = devlink_port; 131 - } else if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT) { 132 + } else if (flags & DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT) { 132 133 devlink_port = devlink_port_get_from_info(devlink, info); 133 134 if (!IS_ERR(devlink_port)) 134 135 info->user_ptr[1] = devlink_port; 135 - } else if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_RATE) { 136 - struct devlink_rate *devlink_rate; 137 - 138 - devlink_rate = devlink_rate_get_from_info(devlink, info); 139 - if (IS_ERR(devlink_rate)) { 140 - err = PTR_ERR(devlink_rate); 141 - goto unlock; 142 - } 143 - info->user_ptr[1] = devlink_rate; 144 - } else if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_RATE_NODE) { 145 - struct devlink_rate *rate_node; 146 - 147 - rate_node = devlink_rate_node_get_from_info(devlink, info); 148 - if (IS_ERR(rate_node)) { 149 - err = PTR_ERR(rate_node); 150 - goto unlock; 151 - } 152 - info->user_ptr[1] = rate_node; 153 - } else if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_LINECARD) { 154 - linecard = devlink_linecard_get_from_info(devlink, info); 155 - if (IS_ERR(linecard)) { 156 - err = PTR_ERR(linecard); 157 - goto unlock; 158 - } 159 - info->user_ptr[1] = linecard; 160 136 } 161 137 return 0; 162 138 ··· 139 165 devl_unlock(devlink); 140 166 devlink_put(devlink); 141 167 return err; 168 + } 169 + 170 + int devlink_nl_pre_doit(const struct genl_split_ops *ops, 171 + struct sk_buff *skb, struct genl_info *info) 172 + { 173 + return __devlink_nl_pre_doit(skb, info, ops->internal_flags); 174 + } 175 + 176 + int devlink_nl_pre_doit_port(const struct genl_split_ops *ops, 177 + struct sk_buff *skb, struct genl_info *info) 178 + { 179 + return __devlink_nl_pre_doit(skb, info, DEVLINK_NL_FLAG_NEED_PORT); 180 + } 181 + 182 + int devlink_nl_pre_doit_port_optional(const struct genl_split_ops *ops, 183 + struct sk_buff *skb, 184 + struct genl_info *info) 185 + { 186 + return __devlink_nl_pre_doit(skb, info, DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT); 142 187 } 143 188 144 189 void devlink_nl_post_doit(const struct genl_split_ops *ops, ··· 170 177 devlink_put(devlink); 171 178 } 172 179 173 - static const struct devlink_cmd *devl_cmds[] = { 174 - [DEVLINK_CMD_PORT_GET] = &devl_cmd_port_get, 175 - [DEVLINK_CMD_SB_GET] = &devl_cmd_sb_get, 176 - [DEVLINK_CMD_SB_POOL_GET] = &devl_cmd_sb_pool_get, 177 - [DEVLINK_CMD_SB_PORT_POOL_GET] = &devl_cmd_sb_port_pool_get, 178 - [DEVLINK_CMD_SB_TC_POOL_BIND_GET] = &devl_cmd_sb_tc_pool_bind_get, 179 - [DEVLINK_CMD_PARAM_GET] = &devl_cmd_param_get, 180 - [DEVLINK_CMD_REGION_GET] = &devl_cmd_region_get, 181 - [DEVLINK_CMD_HEALTH_REPORTER_GET] = &devl_cmd_health_reporter_get, 182 - [DEVLINK_CMD_TRAP_GET] = &devl_cmd_trap_get, 183 - [DEVLINK_CMD_TRAP_GROUP_GET] = &devl_cmd_trap_group_get, 184 - [DEVLINK_CMD_TRAP_POLICER_GET] = &devl_cmd_trap_policer_get, 185 - [DEVLINK_CMD_RATE_GET] = &devl_cmd_rate_get, 186 - [DEVLINK_CMD_LINECARD_GET] = &devl_cmd_linecard_get, 187 - [DEVLINK_CMD_SELFTESTS_GET] = &devl_cmd_selftests_get, 188 - }; 180 + static int devlink_nl_inst_single_dumpit(struct sk_buff *msg, 181 + struct netlink_callback *cb, int flags, 182 + devlink_nl_dump_one_func_t *dump_one, 183 + struct nlattr **attrs) 184 + { 185 + struct devlink *devlink; 186 + int err; 189 187 190 - int devlink_nl_dumpit(struct sk_buff *msg, struct netlink_callback *cb, 191 - devlink_nl_dump_one_func_t *dump_one) 188 + devlink = devlink_get_from_attrs_lock(sock_net(msg->sk), attrs); 189 + if (IS_ERR(devlink)) 190 + return PTR_ERR(devlink); 191 + err = dump_one(msg, devlink, cb, flags | NLM_F_DUMP_FILTERED); 192 + 193 + devl_unlock(devlink); 194 + devlink_put(devlink); 195 + 196 + if (err != -EMSGSIZE) 197 + return err; 198 + return msg->len; 199 + } 200 + 201 + static int devlink_nl_inst_iter_dumpit(struct sk_buff *msg, 202 + struct netlink_callback *cb, int flags, 203 + devlink_nl_dump_one_func_t *dump_one) 192 204 { 193 205 struct devlink_nl_dump_state *state = devlink_dump_state(cb); 194 206 struct devlink *devlink; ··· 204 206 devl_lock(devlink); 205 207 206 208 if (devl_is_registered(devlink)) 207 - err = dump_one(msg, devlink, cb); 209 + err = dump_one(msg, devlink, cb, flags); 208 210 else 209 211 err = 0; 210 212 ··· 225 227 return msg->len; 226 228 } 227 229 228 - int devlink_nl_instance_iter_dumpit(struct sk_buff *msg, 229 - struct netlink_callback *cb) 230 + int devlink_nl_dumpit(struct sk_buff *msg, struct netlink_callback *cb, 231 + devlink_nl_dump_one_func_t *dump_one) 230 232 { 231 233 const struct genl_dumpit_info *info = genl_dumpit_info(cb); 232 - const struct devlink_cmd *cmd = devl_cmds[info->op.cmd]; 234 + struct nlattr **attrs = info->attrs; 235 + int flags = NLM_F_MULTI; 233 236 234 - return devlink_nl_dumpit(msg, cb, cmd->dump_one); 237 + if (attrs && 238 + (attrs[DEVLINK_ATTR_BUS_NAME] || attrs[DEVLINK_ATTR_DEV_NAME])) 239 + return devlink_nl_inst_single_dumpit(msg, cb, flags, dump_one, 240 + attrs); 241 + else 242 + return devlink_nl_inst_iter_dumpit(msg, cb, flags, dump_one); 235 243 } 236 244 237 245 struct genl_family devlink_nl_family __ro_after_init = {