@@ -167,6 +167,7 @@ static const struct nla_policy nldev_policy[RDMA_NLDEV_ATTR_MAX] = {
167
167
[RDMA_NLDEV_ATTR_STAT_HWCOUNTER_DYNAMIC ] = { .type = NLA_U8 },
168
168
[RDMA_NLDEV_SYS_ATTR_PRIVILEGED_QKEY_MODE ] = { .type = NLA_U8 },
169
169
[RDMA_NLDEV_ATTR_DRIVER_DETAILS ] = { .type = NLA_U8 },
170
+ [RDMA_NLDEV_ATTR_DEV_TYPE ] = { .type = NLA_U8 },
170
171
};
171
172
172
173
static int put_driver_name_print_type (struct sk_buff * msg , const char * name ,
@@ -2548,6 +2549,56 @@ static int nldev_stat_get_counter_status_doit(struct sk_buff *skb,
2548
2549
return ret ;
2549
2550
}
2550
2551
2552
+ static int nldev_newdev (struct sk_buff * skb , struct nlmsghdr * nlh ,
2553
+ struct netlink_ext_ack * extack )
2554
+ {
2555
+ struct nlattr * tb [RDMA_NLDEV_ATTR_MAX ];
2556
+ enum rdma_nl_dev_type type ;
2557
+ struct ib_device * parent ;
2558
+ char name [IFNAMSIZ ] = {};
2559
+ u32 parentid ;
2560
+ int ret ;
2561
+
2562
+ ret = nlmsg_parse (nlh , 0 , tb , RDMA_NLDEV_ATTR_MAX - 1 ,
2563
+ nldev_policy , extack );
2564
+ if (ret || !tb [RDMA_NLDEV_ATTR_DEV_INDEX ] ||
2565
+ !tb [RDMA_NLDEV_ATTR_DEV_NAME ] || !tb [RDMA_NLDEV_ATTR_DEV_TYPE ])
2566
+ return - EINVAL ;
2567
+
2568
+ nla_strscpy (name , tb [RDMA_NLDEV_ATTR_DEV_NAME ], sizeof (name ));
2569
+ type = nla_get_u8 (tb [RDMA_NLDEV_ATTR_DEV_TYPE ]);
2570
+ parentid = nla_get_u32 (tb [RDMA_NLDEV_ATTR_DEV_INDEX ]);
2571
+ parent = ib_device_get_by_index (sock_net (skb -> sk ), parentid );
2572
+ if (!parent )
2573
+ return - EINVAL ;
2574
+
2575
+ ret = ib_add_sub_device (parent , type , name );
2576
+ ib_device_put (parent );
2577
+
2578
+ return ret ;
2579
+ }
2580
+
2581
+ static int nldev_deldev (struct sk_buff * skb , struct nlmsghdr * nlh ,
2582
+ struct netlink_ext_ack * extack )
2583
+ {
2584
+ struct nlattr * tb [RDMA_NLDEV_ATTR_MAX ];
2585
+ struct ib_device * device ;
2586
+ u32 devid ;
2587
+ int ret ;
2588
+
2589
+ ret = nlmsg_parse (nlh , 0 , tb , RDMA_NLDEV_ATTR_MAX - 1 ,
2590
+ nldev_policy , extack );
2591
+ if (ret || !tb [RDMA_NLDEV_ATTR_DEV_INDEX ])
2592
+ return - EINVAL ;
2593
+
2594
+ devid = nla_get_u32 (tb [RDMA_NLDEV_ATTR_DEV_INDEX ]);
2595
+ device = ib_device_get_by_index (sock_net (skb -> sk ), devid );
2596
+ if (!device )
2597
+ return - EINVAL ;
2598
+
2599
+ return ib_del_sub_device_and_put (device );
2600
+ }
2601
+
2551
2602
static const struct rdma_nl_cbs nldev_cb_table [RDMA_NLDEV_NUM_OPS ] = {
2552
2603
[RDMA_NLDEV_CMD_GET ] = {
2553
2604
.doit = nldev_get_doit ,
@@ -2646,6 +2697,14 @@ static const struct rdma_nl_cbs nldev_cb_table[RDMA_NLDEV_NUM_OPS] = {
2646
2697
[RDMA_NLDEV_CMD_STAT_GET_STATUS ] = {
2647
2698
.doit = nldev_stat_get_counter_status_doit ,
2648
2699
},
2700
+ [RDMA_NLDEV_CMD_NEWDEV ] = {
2701
+ .doit = nldev_newdev ,
2702
+ .flags = RDMA_NL_ADMIN_PERM ,
2703
+ },
2704
+ [RDMA_NLDEV_CMD_DELDEV ] = {
2705
+ .doit = nldev_deldev ,
2706
+ .flags = RDMA_NL_ADMIN_PERM ,
2707
+ },
2649
2708
};
2650
2709
2651
2710
void __init nldev_init (void )
0 commit comments