@@ -2424,6 +2424,125 @@ static int devlink_nl_cmd_linecard_set_doit(struct sk_buff *skb,
2424
2424
return 0 ;
2425
2425
}
2426
2426
2427
+ struct devlink_info_req {
2428
+ struct sk_buff * msg ;
2429
+ };
2430
+
2431
+ static int
2432
+ devlink_nl_linecard_info_fill (struct sk_buff * msg , struct devlink * devlink ,
2433
+ struct devlink_linecard * linecard ,
2434
+ enum devlink_command cmd , u32 portid ,
2435
+ u32 seq , int flags , struct netlink_ext_ack * extack )
2436
+ {
2437
+ struct devlink_info_req req ;
2438
+ void * hdr ;
2439
+ int err ;
2440
+
2441
+ hdr = genlmsg_put (msg , portid , seq , & devlink_nl_family , flags , cmd );
2442
+ if (!hdr )
2443
+ return - EMSGSIZE ;
2444
+
2445
+ err = - EMSGSIZE ;
2446
+ if (devlink_nl_put_handle (msg , devlink ))
2447
+ goto nla_put_failure ;
2448
+ if (nla_put_u32 (msg , DEVLINK_ATTR_LINECARD_INDEX , linecard -> index ))
2449
+ goto nla_put_failure ;
2450
+
2451
+ req .msg = msg ;
2452
+ err = linecard -> ops -> info_get (linecard , linecard -> priv , & req , extack );
2453
+ if (err )
2454
+ goto nla_put_failure ;
2455
+
2456
+ genlmsg_end (msg , hdr );
2457
+ return 0 ;
2458
+
2459
+ nla_put_failure :
2460
+ genlmsg_cancel (msg , hdr );
2461
+ return err ;
2462
+ }
2463
+
2464
+ static int devlink_nl_cmd_linecard_info_get_doit (struct sk_buff * skb ,
2465
+ struct genl_info * info )
2466
+ {
2467
+ struct devlink_linecard * linecard = info -> user_ptr [1 ];
2468
+ struct devlink * devlink = linecard -> devlink ;
2469
+ struct sk_buff * msg ;
2470
+ int err ;
2471
+
2472
+ if (!linecard -> ops -> info_get )
2473
+ return - EOPNOTSUPP ;
2474
+
2475
+ msg = nlmsg_new (NLMSG_DEFAULT_SIZE , GFP_KERNEL );
2476
+ if (!msg )
2477
+ return - ENOMEM ;
2478
+
2479
+ mutex_lock (& linecard -> state_lock );
2480
+ err = devlink_nl_linecard_info_fill (msg , devlink , linecard ,
2481
+ DEVLINK_CMD_LINECARD_INFO_GET ,
2482
+ info -> snd_portid , info -> snd_seq , 0 ,
2483
+ info -> extack );
2484
+ mutex_unlock (& linecard -> state_lock );
2485
+ if (err ) {
2486
+ nlmsg_free (msg );
2487
+ return err ;
2488
+ }
2489
+
2490
+ return genlmsg_reply (msg , info );
2491
+ }
2492
+
2493
+ static int devlink_nl_cmd_linecard_info_get_dumpit (struct sk_buff * msg ,
2494
+ struct netlink_callback * cb )
2495
+ {
2496
+ struct devlink_linecard * linecard ;
2497
+ struct devlink * devlink ;
2498
+ int start = cb -> args [0 ];
2499
+ unsigned long index ;
2500
+ int idx = 0 ;
2501
+ int err = 0 ;
2502
+
2503
+ mutex_lock (& devlink_mutex );
2504
+ xa_for_each_marked (& devlinks , index , devlink , DEVLINK_REGISTERED ) {
2505
+ if (!devlink_try_get (devlink ))
2506
+ continue ;
2507
+
2508
+ if (!net_eq (devlink_net (devlink ), sock_net (msg -> sk )))
2509
+ goto retry ;
2510
+
2511
+ mutex_lock (& devlink -> linecards_lock );
2512
+ list_for_each_entry (linecard , & devlink -> linecard_list , list ) {
2513
+ if (idx < start || !linecard -> ops -> info_get ) {
2514
+ idx ++ ;
2515
+ continue ;
2516
+ }
2517
+ mutex_lock (& linecard -> state_lock );
2518
+ err = devlink_nl_linecard_info_fill (msg , devlink , linecard ,
2519
+ DEVLINK_CMD_LINECARD_INFO_GET ,
2520
+ NETLINK_CB (cb -> skb ).portid ,
2521
+ cb -> nlh -> nlmsg_seq ,
2522
+ NLM_F_MULTI ,
2523
+ cb -> extack );
2524
+ mutex_unlock (& linecard -> state_lock );
2525
+ if (err ) {
2526
+ mutex_unlock (& devlink -> linecards_lock );
2527
+ devlink_put (devlink );
2528
+ goto out ;
2529
+ }
2530
+ idx ++ ;
2531
+ }
2532
+ mutex_unlock (& devlink -> linecards_lock );
2533
+ retry :
2534
+ devlink_put (devlink );
2535
+ }
2536
+ out :
2537
+ mutex_unlock (& devlink_mutex );
2538
+
2539
+ if (err != - EMSGSIZE )
2540
+ return err ;
2541
+
2542
+ cb -> args [0 ] = idx ;
2543
+ return msg -> len ;
2544
+ }
2545
+
2427
2546
static int devlink_nl_sb_fill (struct sk_buff * msg , struct devlink * devlink ,
2428
2547
struct devlink_sb * devlink_sb ,
2429
2548
enum devlink_command cmd , u32 portid ,
@@ -6416,10 +6535,6 @@ static int devlink_nl_cmd_region_read_dumpit(struct sk_buff *skb,
6416
6535
return err ;
6417
6536
}
6418
6537
6419
- struct devlink_info_req {
6420
- struct sk_buff * msg ;
6421
- };
6422
-
6423
6538
int devlink_info_driver_name_put (struct devlink_info_req * req , const char * name )
6424
6539
{
6425
6540
return nla_put_string (req -> msg , DEVLINK_ATTR_INFO_DRIVER_NAME , name );
@@ -9139,6 +9254,13 @@ static const struct genl_small_ops devlink_nl_ops[] = {
9139
9254
.flags = GENL_ADMIN_PERM ,
9140
9255
.internal_flags = DEVLINK_NL_FLAG_NEED_LINECARD ,
9141
9256
},
9257
+ {
9258
+ .cmd = DEVLINK_CMD_LINECARD_INFO_GET ,
9259
+ .doit = devlink_nl_cmd_linecard_info_get_doit ,
9260
+ .dumpit = devlink_nl_cmd_linecard_info_get_dumpit ,
9261
+ .internal_flags = DEVLINK_NL_FLAG_NEED_LINECARD ,
9262
+ /* can be retrieved by unprivileged users */
9263
+ },
9142
9264
{
9143
9265
.cmd = DEVLINK_CMD_SB_GET ,
9144
9266
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP ,
0 commit comments