@@ -23,6 +23,7 @@ static const char * const netdev_op_strmap[] = {
2323 [NETDEV_CMD_PAGE_POOL_DEL_NTF ] = "page-pool-del-ntf" ,
2424 [NETDEV_CMD_PAGE_POOL_CHANGE_NTF ] = "page-pool-change-ntf" ,
2525 [NETDEV_CMD_PAGE_POOL_STATS_GET ] = "page-pool-stats-get" ,
26+ [NETDEV_CMD_QUEUE_GET ] = "queue-get" ,
2627};
2728
2829const char * netdev_op_str (int op )
@@ -76,6 +77,18 @@ const char *netdev_xsk_flags_str(enum netdev_xsk_flags value)
7677 return netdev_xsk_flags_strmap [value ];
7778}
7879
80+ static const char * const netdev_queue_type_strmap [] = {
81+ [0 ] = "rx" ,
82+ [1 ] = "tx" ,
83+ };
84+
85+ const char * netdev_queue_type_str (enum netdev_queue_type value )
86+ {
87+ if (value < 0 || value >= (int )MNL_ARRAY_SIZE (netdev_queue_type_strmap ))
88+ return NULL ;
89+ return netdev_queue_type_strmap [value ];
90+ }
91+
7992/* Policies */
8093struct ynl_policy_attr netdev_page_pool_info_policy [NETDEV_A_PAGE_POOL_MAX + 1 ] = {
8194 [NETDEV_A_PAGE_POOL_ID ] = { .name = "id" , .type = YNL_PT_UINT , },
@@ -135,6 +148,18 @@ struct ynl_policy_nest netdev_page_pool_stats_nest = {
135148 .table = netdev_page_pool_stats_policy ,
136149};
137150
151+ struct ynl_policy_attr netdev_queue_policy [NETDEV_A_QUEUE_MAX + 1 ] = {
152+ [NETDEV_A_QUEUE_ID ] = { .name = "id" , .type = YNL_PT_U32 , },
153+ [NETDEV_A_QUEUE_IFINDEX ] = { .name = "ifindex" , .type = YNL_PT_U32 , },
154+ [NETDEV_A_QUEUE_TYPE ] = { .name = "type" , .type = YNL_PT_U32 , },
155+ [NETDEV_A_QUEUE_NAPI_ID ] = { .name = "napi-id" , .type = YNL_PT_U32 , },
156+ };
157+
158+ struct ynl_policy_nest netdev_queue_nest = {
159+ .max_attr = NETDEV_A_QUEUE_MAX ,
160+ .table = netdev_queue_policy ,
161+ };
162+
138163/* Common nested types */
139164void netdev_page_pool_info_free (struct netdev_page_pool_info * obj )
140165{
@@ -617,6 +642,134 @@ netdev_page_pool_stats_get_dump(struct ynl_sock *ys)
617642 return NULL ;
618643}
619644
645+ /* ============== NETDEV_CMD_QUEUE_GET ============== */
646+ /* NETDEV_CMD_QUEUE_GET - do */
647+ void netdev_queue_get_req_free (struct netdev_queue_get_req * req )
648+ {
649+ free (req );
650+ }
651+
652+ void netdev_queue_get_rsp_free (struct netdev_queue_get_rsp * rsp )
653+ {
654+ free (rsp );
655+ }
656+
657+ int netdev_queue_get_rsp_parse (const struct nlmsghdr * nlh , void * data )
658+ {
659+ struct ynl_parse_arg * yarg = data ;
660+ struct netdev_queue_get_rsp * dst ;
661+ const struct nlattr * attr ;
662+
663+ dst = yarg -> data ;
664+
665+ mnl_attr_for_each (attr , nlh , sizeof (struct genlmsghdr )) {
666+ unsigned int type = mnl_attr_get_type (attr );
667+
668+ if (type == NETDEV_A_QUEUE_ID ) {
669+ if (ynl_attr_validate (yarg , attr ))
670+ return MNL_CB_ERROR ;
671+ dst -> _present .id = 1 ;
672+ dst -> id = mnl_attr_get_u32 (attr );
673+ } else if (type == NETDEV_A_QUEUE_TYPE ) {
674+ if (ynl_attr_validate (yarg , attr ))
675+ return MNL_CB_ERROR ;
676+ dst -> _present .type = 1 ;
677+ dst -> type = mnl_attr_get_u32 (attr );
678+ } else if (type == NETDEV_A_QUEUE_NAPI_ID ) {
679+ if (ynl_attr_validate (yarg , attr ))
680+ return MNL_CB_ERROR ;
681+ dst -> _present .napi_id = 1 ;
682+ dst -> napi_id = mnl_attr_get_u32 (attr );
683+ } else if (type == NETDEV_A_QUEUE_IFINDEX ) {
684+ if (ynl_attr_validate (yarg , attr ))
685+ return MNL_CB_ERROR ;
686+ dst -> _present .ifindex = 1 ;
687+ dst -> ifindex = mnl_attr_get_u32 (attr );
688+ }
689+ }
690+
691+ return MNL_CB_OK ;
692+ }
693+
694+ struct netdev_queue_get_rsp *
695+ netdev_queue_get (struct ynl_sock * ys , struct netdev_queue_get_req * req )
696+ {
697+ struct ynl_req_state yrs = { .yarg = { .ys = ys , }, };
698+ struct netdev_queue_get_rsp * rsp ;
699+ struct nlmsghdr * nlh ;
700+ int err ;
701+
702+ nlh = ynl_gemsg_start_req (ys , ys -> family_id , NETDEV_CMD_QUEUE_GET , 1 );
703+ ys -> req_policy = & netdev_queue_nest ;
704+ yrs .yarg .rsp_policy = & netdev_queue_nest ;
705+
706+ if (req -> _present .ifindex )
707+ mnl_attr_put_u32 (nlh , NETDEV_A_QUEUE_IFINDEX , req -> ifindex );
708+ if (req -> _present .type )
709+ mnl_attr_put_u32 (nlh , NETDEV_A_QUEUE_TYPE , req -> type );
710+ if (req -> _present .id )
711+ mnl_attr_put_u32 (nlh , NETDEV_A_QUEUE_ID , req -> id );
712+
713+ rsp = calloc (1 , sizeof (* rsp ));
714+ yrs .yarg .data = rsp ;
715+ yrs .cb = netdev_queue_get_rsp_parse ;
716+ yrs .rsp_cmd = NETDEV_CMD_QUEUE_GET ;
717+
718+ err = ynl_exec (ys , nlh , & yrs );
719+ if (err < 0 )
720+ goto err_free ;
721+
722+ return rsp ;
723+
724+ err_free :
725+ netdev_queue_get_rsp_free (rsp );
726+ return NULL ;
727+ }
728+
729+ /* NETDEV_CMD_QUEUE_GET - dump */
730+ void netdev_queue_get_list_free (struct netdev_queue_get_list * rsp )
731+ {
732+ struct netdev_queue_get_list * next = rsp ;
733+
734+ while ((void * )next != YNL_LIST_END ) {
735+ rsp = next ;
736+ next = rsp -> next ;
737+
738+ free (rsp );
739+ }
740+ }
741+
742+ struct netdev_queue_get_list *
743+ netdev_queue_get_dump (struct ynl_sock * ys ,
744+ struct netdev_queue_get_req_dump * req )
745+ {
746+ struct ynl_dump_state yds = {};
747+ struct nlmsghdr * nlh ;
748+ int err ;
749+
750+ yds .ys = ys ;
751+ yds .alloc_sz = sizeof (struct netdev_queue_get_list );
752+ yds .cb = netdev_queue_get_rsp_parse ;
753+ yds .rsp_cmd = NETDEV_CMD_QUEUE_GET ;
754+ yds .rsp_policy = & netdev_queue_nest ;
755+
756+ nlh = ynl_gemsg_start_dump (ys , ys -> family_id , NETDEV_CMD_QUEUE_GET , 1 );
757+ ys -> req_policy = & netdev_queue_nest ;
758+
759+ if (req -> _present .ifindex )
760+ mnl_attr_put_u32 (nlh , NETDEV_A_QUEUE_IFINDEX , req -> ifindex );
761+
762+ err = ynl_exec_dump (ys , nlh , & yds );
763+ if (err < 0 )
764+ goto free_list ;
765+
766+ return yds .first ;
767+
768+ free_list :
769+ netdev_queue_get_list_free (yds .first );
770+ return NULL ;
771+ }
772+
620773static const struct ynl_ntf_info netdev_ntf_info [] = {
621774 [NETDEV_CMD_DEV_ADD_NTF ] = {
622775 .alloc_sz = sizeof (struct netdev_dev_get_ntf ),
0 commit comments