@@ -1112,7 +1112,10 @@ static int genl_ctrl_event(int event, const struct genl_family *family,
1112
1112
1113
1113
struct ctrl_dump_policy_ctx {
1114
1114
struct netlink_policy_dump_state * state ;
1115
+ const struct genl_family * rt ;
1116
+ unsigned int opidx ;
1115
1117
u16 fam_id ;
1118
+ u8 policies :1 ;
1116
1119
};
1117
1120
1118
1121
static const struct nla_policy ctrl_policy_policy [] = {
@@ -1127,6 +1130,8 @@ static int ctrl_dumppolicy_start(struct netlink_callback *cb)
1127
1130
struct ctrl_dump_policy_ctx * ctx = (void * )cb -> ctx ;
1128
1131
struct nlattr * * tb = info -> attrs ;
1129
1132
const struct genl_family * rt ;
1133
+ struct genl_ops op ;
1134
+ int err , i ;
1130
1135
1131
1136
BUILD_BUG_ON (sizeof (* ctx ) > sizeof (cb -> ctx ));
1132
1137
@@ -1147,11 +1152,23 @@ static int ctrl_dumppolicy_start(struct netlink_callback *cb)
1147
1152
if (!rt )
1148
1153
return - ENOENT ;
1149
1154
1150
- if (!rt -> policy )
1151
- return - ENODATA ;
1155
+ ctx -> rt = rt ;
1156
+
1157
+ for (i = 0 ; i < genl_get_cmd_cnt (rt ); i ++ ) {
1158
+ genl_get_cmd_by_index (i , rt , & op );
1159
+
1160
+ if (op .policy ) {
1161
+ err = netlink_policy_dump_add_policy (& ctx -> state ,
1162
+ op .policy ,
1163
+ op .maxattr );
1164
+ if (err )
1165
+ return err ;
1166
+ }
1167
+ }
1152
1168
1153
- return netlink_policy_dump_add_policy (& ctx -> state , rt -> policy ,
1154
- rt -> maxattr );
1169
+ if (!ctx -> state )
1170
+ return - ENODATA ;
1171
+ return 0 ;
1155
1172
}
1156
1173
1157
1174
static void * ctrl_dumppolicy_prep (struct sk_buff * skb ,
@@ -1172,12 +1189,78 @@ static void *ctrl_dumppolicy_prep(struct sk_buff *skb,
1172
1189
return hdr ;
1173
1190
}
1174
1191
1192
+ static int ctrl_dumppolicy_put_op (struct sk_buff * skb ,
1193
+ struct netlink_callback * cb ,
1194
+ struct genl_ops * op )
1195
+ {
1196
+ struct ctrl_dump_policy_ctx * ctx = (void * )cb -> ctx ;
1197
+ struct nlattr * nest_pol , * nest_op ;
1198
+ void * hdr ;
1199
+ int idx ;
1200
+
1201
+ /* skip if we have nothing to show */
1202
+ if (!op -> policy )
1203
+ return 0 ;
1204
+ if (!op -> doit &&
1205
+ (!op -> dumpit || op -> validate & GENL_DONT_VALIDATE_DUMP ))
1206
+ return 0 ;
1207
+
1208
+ hdr = ctrl_dumppolicy_prep (skb , cb );
1209
+ if (!hdr )
1210
+ return - ENOBUFS ;
1211
+
1212
+ nest_pol = nla_nest_start (skb , CTRL_ATTR_OP_POLICY );
1213
+ if (!nest_pol )
1214
+ goto err ;
1215
+
1216
+ nest_op = nla_nest_start (skb , op -> cmd );
1217
+ if (!nest_op )
1218
+ goto err ;
1219
+
1220
+ /* for now both do/dump are always the same */
1221
+ idx = netlink_policy_dump_get_policy_idx (ctx -> state ,
1222
+ op -> policy ,
1223
+ op -> maxattr );
1224
+
1225
+ if (op -> doit && nla_put_u32 (skb , CTRL_ATTR_POLICY_DO , idx ))
1226
+ goto err ;
1227
+
1228
+ if (op -> dumpit && !(op -> validate & GENL_DONT_VALIDATE_DUMP ) &&
1229
+ nla_put_u32 (skb , CTRL_ATTR_POLICY_DUMP , idx ))
1230
+ goto err ;
1231
+
1232
+ nla_nest_end (skb , nest_op );
1233
+ nla_nest_end (skb , nest_pol );
1234
+ genlmsg_end (skb , hdr );
1235
+
1236
+ return 0 ;
1237
+ err :
1238
+ genlmsg_cancel (skb , hdr );
1239
+ return - ENOBUFS ;
1240
+ }
1241
+
1175
1242
static int ctrl_dumppolicy (struct sk_buff * skb , struct netlink_callback * cb )
1176
1243
{
1177
1244
struct ctrl_dump_policy_ctx * ctx = (void * )cb -> ctx ;
1245
+ void * hdr ;
1246
+
1247
+ if (!ctx -> policies ) {
1248
+ while (ctx -> opidx < genl_get_cmd_cnt (ctx -> rt )) {
1249
+ struct genl_ops op ;
1250
+
1251
+ genl_get_cmd_by_index (ctx -> opidx , ctx -> rt , & op );
1252
+
1253
+ if (ctrl_dumppolicy_put_op (skb , cb , & op ))
1254
+ return skb -> len ;
1255
+
1256
+ ctx -> opidx ++ ;
1257
+ }
1258
+
1259
+ /* completed with the per-op policy index list */
1260
+ ctx -> policies = true;
1261
+ }
1178
1262
1179
1263
while (netlink_policy_dump_loop (ctx -> state )) {
1180
- void * hdr ;
1181
1264
struct nlattr * nest ;
1182
1265
1183
1266
hdr = ctrl_dumppolicy_prep (skb , cb );
@@ -1194,14 +1277,13 @@ static int ctrl_dumppolicy(struct sk_buff *skb, struct netlink_callback *cb)
1194
1277
nla_nest_end (skb , nest );
1195
1278
1196
1279
genlmsg_end (skb , hdr );
1197
- continue ;
1198
-
1199
- nla_put_failure :
1200
- genlmsg_cancel (skb , hdr );
1201
- break ;
1202
1280
}
1203
1281
1204
1282
return skb -> len ;
1283
+
1284
+ nla_put_failure :
1285
+ genlmsg_cancel (skb , hdr );
1286
+ return skb -> len ;
1205
1287
}
1206
1288
1207
1289
static int ctrl_dumppolicy_done (struct netlink_callback * cb )
0 commit comments