@@ -196,49 +196,33 @@ bool netlink_policy_dump_loop(struct netlink_policy_dump_state *state)
196
196
return !netlink_policy_dump_finished (state );
197
197
}
198
198
199
- /**
200
- * netlink_policy_dump_write - write current policy dump attributes
201
- * @skb: the message skb to write to
202
- * @state: the policy dump state
203
- *
204
- * Returns: 0 on success, an error code otherwise
205
- */
206
- int netlink_policy_dump_write (struct sk_buff * skb ,
207
- struct netlink_policy_dump_state * state )
199
+ static int
200
+ __netlink_policy_dump_write_attr (struct netlink_policy_dump_state * state ,
201
+ struct sk_buff * skb ,
202
+ const struct nla_policy * pt ,
203
+ int nestattr )
208
204
{
209
- const struct nla_policy * pt ;
210
- struct nlattr * policy , * attr ;
211
205
enum netlink_attribute_type type ;
212
- bool again ;
213
-
214
- send_attribute :
215
- again = false;
216
-
217
- pt = & state -> policies [state -> policy_idx ].policy [state -> attr_idx ];
206
+ struct nlattr * attr ;
218
207
219
- policy = nla_nest_start (skb , state -> policy_idx );
220
- if (!policy )
221
- return - ENOBUFS ;
222
-
223
- attr = nla_nest_start (skb , state -> attr_idx );
208
+ attr = nla_nest_start (skb , nestattr );
224
209
if (!attr )
225
- goto nla_put_failure ;
210
+ return - ENOBUFS ;
226
211
227
212
switch (pt -> type ) {
228
213
default :
229
214
case NLA_UNSPEC :
230
215
case NLA_REJECT :
231
216
/* skip - use NLA_MIN_LEN to advertise such */
232
- nla_nest_cancel (skb , policy );
233
- again = true;
234
- goto next ;
217
+ nla_nest_cancel (skb , attr );
218
+ return - ENODATA ;
235
219
case NLA_NESTED :
236
220
type = NL_ATTR_TYPE_NESTED ;
237
221
fallthrough ;
238
222
case NLA_NESTED_ARRAY :
239
223
if (pt -> type == NLA_NESTED_ARRAY )
240
224
type = NL_ATTR_TYPE_NESTED_ARRAY ;
241
- if (pt -> nested_policy && pt -> len &&
225
+ if (state && pt -> nested_policy && pt -> len &&
242
226
(nla_put_u32 (skb , NL_POLICY_TYPE_ATTR_POLICY_IDX ,
243
227
netlink_policy_dump_get_policy_idx (state ,
244
228
pt -> nested_policy ,
@@ -349,8 +333,47 @@ int netlink_policy_dump_write(struct sk_buff *skb,
349
333
if (nla_put_u32 (skb , NL_POLICY_TYPE_ATTR_TYPE , type ))
350
334
goto nla_put_failure ;
351
335
352
- /* finish and move state to next attribute */
353
336
nla_nest_end (skb , attr );
337
+ return 0 ;
338
+ nla_put_failure :
339
+ nla_nest_cancel (skb , attr );
340
+ return - ENOBUFS ;
341
+ }
342
+
343
+ /**
344
+ * netlink_policy_dump_write - write current policy dump attributes
345
+ * @skb: the message skb to write to
346
+ * @state: the policy dump state
347
+ *
348
+ * Returns: 0 on success, an error code otherwise
349
+ */
350
+ int netlink_policy_dump_write (struct sk_buff * skb ,
351
+ struct netlink_policy_dump_state * state )
352
+ {
353
+ const struct nla_policy * pt ;
354
+ struct nlattr * policy ;
355
+ bool again ;
356
+ int err ;
357
+
358
+ send_attribute :
359
+ again = false;
360
+
361
+ pt = & state -> policies [state -> policy_idx ].policy [state -> attr_idx ];
362
+
363
+ policy = nla_nest_start (skb , state -> policy_idx );
364
+ if (!policy )
365
+ return - ENOBUFS ;
366
+
367
+ err = __netlink_policy_dump_write_attr (state , skb , pt , state -> attr_idx );
368
+ if (err == - ENODATA ) {
369
+ nla_nest_cancel (skb , policy );
370
+ again = true;
371
+ goto next ;
372
+ } else if (err ) {
373
+ goto nla_put_failure ;
374
+ }
375
+
376
+ /* finish and move state to next attribute */
354
377
nla_nest_end (skb , policy );
355
378
356
379
next :
0 commit comments