@@ -601,22 +601,29 @@ int net_shaper_nl_post_dumpit(struct netlink_callback *cb)
601601int net_shaper_nl_cap_pre_doit (const struct genl_split_ops * ops ,
602602 struct sk_buff * skb , struct genl_info * info )
603603{
604- return - EOPNOTSUPP ;
604+ return net_shaper_generic_pre ( info , NET_SHAPER_A_CAPS_IFINDEX ) ;
605605}
606606
607607void net_shaper_nl_cap_post_doit (const struct genl_split_ops * ops ,
608608 struct sk_buff * skb , struct genl_info * info )
609609{
610+ net_shaper_generic_post (info );
610611}
611612
612613int net_shaper_nl_cap_pre_dumpit (struct netlink_callback * cb )
613614{
614- return - EOPNOTSUPP ;
615+ struct net_shaper_nl_ctx * ctx = (struct net_shaper_nl_ctx * )cb -> ctx ;
616+
617+ return net_shaper_ctx_setup (genl_info_dump (cb ),
618+ NET_SHAPER_A_CAPS_IFINDEX , ctx );
615619}
616620
617621int net_shaper_nl_cap_post_dumpit (struct netlink_callback * cb )
618622{
619- return - EOPNOTSUPP ;
623+ struct net_shaper_nl_ctx * ctx = (struct net_shaper_nl_ctx * )cb -> ctx ;
624+
625+ net_shaper_ctx_cleanup (ctx );
626+ return 0 ;
620627}
621628
622629int net_shaper_nl_get_doit (struct sk_buff * skb , struct genl_info * info )
@@ -1147,14 +1154,99 @@ int net_shaper_nl_group_doit(struct sk_buff *skb, struct genl_info *info)
11471154 goto free_leaves ;
11481155}
11491156
1157+ static int
1158+ net_shaper_cap_fill_one (struct sk_buff * msg ,
1159+ struct net_shaper_binding * binding ,
1160+ enum net_shaper_scope scope , unsigned long flags ,
1161+ const struct genl_info * info )
1162+ {
1163+ unsigned long cur ;
1164+ void * hdr ;
1165+
1166+ hdr = genlmsg_iput (msg , info );
1167+ if (!hdr )
1168+ return - EMSGSIZE ;
1169+
1170+ if (net_shaper_fill_binding (msg , binding , NET_SHAPER_A_CAPS_IFINDEX ) ||
1171+ nla_put_u32 (msg , NET_SHAPER_A_CAPS_SCOPE , scope ))
1172+ goto nla_put_failure ;
1173+
1174+ for (cur = NET_SHAPER_A_CAPS_SUPPORT_METRIC_BPS ;
1175+ cur <= NET_SHAPER_A_CAPS_MAX ; ++ cur ) {
1176+ if (flags & BIT (cur ) && nla_put_flag (msg , cur ))
1177+ goto nla_put_failure ;
1178+ }
1179+
1180+ genlmsg_end (msg , hdr );
1181+
1182+ return 0 ;
1183+
1184+ nla_put_failure :
1185+ genlmsg_cancel (msg , hdr );
1186+ return - EMSGSIZE ;
1187+ }
1188+
11501189int net_shaper_nl_cap_get_doit (struct sk_buff * skb , struct genl_info * info )
11511190{
1191+ struct net_shaper_binding * binding ;
1192+ const struct net_shaper_ops * ops ;
1193+ enum net_shaper_scope scope ;
1194+ unsigned long flags = 0 ;
1195+ struct sk_buff * msg ;
1196+ int ret ;
1197+
1198+ if (GENL_REQ_ATTR_CHECK (info , NET_SHAPER_A_CAPS_SCOPE ))
1199+ return - EINVAL ;
1200+
1201+ binding = net_shaper_binding_from_ctx (info -> ctx );
1202+ scope = nla_get_u32 (info -> attrs [NET_SHAPER_A_CAPS_SCOPE ]);
1203+ ops = net_shaper_ops (binding );
1204+ ops -> capabilities (binding , scope , & flags );
1205+ if (!flags )
1206+ return - EOPNOTSUPP ;
1207+
1208+ msg = genlmsg_new (NLMSG_DEFAULT_SIZE , GFP_KERNEL );
1209+ if (!msg )
1210+ return - ENOMEM ;
1211+
1212+ ret = net_shaper_cap_fill_one (msg , binding , scope , flags , info );
1213+ if (ret )
1214+ goto free_msg ;
1215+
1216+ ret = genlmsg_reply (msg , info );
1217+ if (ret )
1218+ goto free_msg ;
11521219 return 0 ;
1220+
1221+ free_msg :
1222+ nlmsg_free (msg );
1223+ return ret ;
11531224}
11541225
11551226int net_shaper_nl_cap_get_dumpit (struct sk_buff * skb ,
11561227 struct netlink_callback * cb )
11571228{
1229+ const struct genl_info * info = genl_info_dump (cb );
1230+ struct net_shaper_binding * binding ;
1231+ const struct net_shaper_ops * ops ;
1232+ enum net_shaper_scope scope ;
1233+ int ret ;
1234+
1235+ binding = net_shaper_binding_from_ctx (cb -> ctx );
1236+ ops = net_shaper_ops (binding );
1237+ for (scope = 0 ; scope <= NET_SHAPER_SCOPE_MAX ; ++ scope ) {
1238+ unsigned long flags = 0 ;
1239+
1240+ ops -> capabilities (binding , scope , & flags );
1241+ if (!flags )
1242+ continue ;
1243+
1244+ ret = net_shaper_cap_fill_one (skb , binding , scope , flags ,
1245+ info );
1246+ if (ret )
1247+ return ret ;
1248+ }
1249+
11581250 return 0 ;
11591251}
11601252
0 commit comments