@@ -268,6 +268,55 @@ int mr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
268
268
}
269
269
EXPORT_SYMBOL (mr_fill_mroute );
270
270
271
+ int mr_table_dump (struct mr_table * mrt , struct sk_buff * skb ,
272
+ struct netlink_callback * cb ,
273
+ int (* fill )(struct mr_table * mrt , struct sk_buff * skb ,
274
+ u32 portid , u32 seq , struct mr_mfc * c ,
275
+ int cmd , int flags ),
276
+ spinlock_t * lock )
277
+ {
278
+ unsigned int e = 0 , s_e = cb -> args [1 ];
279
+ unsigned int flags = NLM_F_MULTI ;
280
+ struct mr_mfc * mfc ;
281
+ int err ;
282
+
283
+ list_for_each_entry_rcu (mfc , & mrt -> mfc_cache_list , list ) {
284
+ if (e < s_e )
285
+ goto next_entry ;
286
+
287
+ err = fill (mrt , skb , NETLINK_CB (cb -> skb ).portid ,
288
+ cb -> nlh -> nlmsg_seq , mfc , RTM_NEWROUTE , flags );
289
+ if (err < 0 )
290
+ goto out ;
291
+ next_entry :
292
+ e ++ ;
293
+ }
294
+ e = 0 ;
295
+ s_e = 0 ;
296
+
297
+ spin_lock_bh (lock );
298
+ list_for_each_entry (mfc , & mrt -> mfc_unres_queue , list ) {
299
+ if (e < s_e )
300
+ goto next_entry2 ;
301
+
302
+ err = fill (mrt , skb , NETLINK_CB (cb -> skb ).portid ,
303
+ cb -> nlh -> nlmsg_seq , mfc , RTM_NEWROUTE , flags );
304
+ if (err < 0 ) {
305
+ spin_unlock_bh (lock );
306
+ goto out ;
307
+ }
308
+ next_entry2 :
309
+ e ++ ;
310
+ }
311
+ spin_unlock_bh (lock );
312
+ err = 0 ;
313
+ e = 0 ;
314
+
315
+ out :
316
+ cb -> args [1 ] = e ;
317
+ return err ;
318
+ }
319
+
271
320
int mr_rtm_dumproute (struct sk_buff * skb , struct netlink_callback * cb ,
272
321
struct mr_table * (* iter )(struct net * net ,
273
322
struct mr_table * mrt ),
@@ -277,51 +326,24 @@ int mr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb,
277
326
int cmd , int flags ),
278
327
spinlock_t * lock )
279
328
{
280
- unsigned int t = 0 , e = 0 , s_t = cb -> args [0 ], s_e = cb -> args [ 1 ];
329
+ unsigned int t = 0 , s_t = cb -> args [0 ];
281
330
struct net * net = sock_net (skb -> sk );
282
331
struct mr_table * mrt ;
283
- struct mr_mfc * mfc ;
332
+ int err ;
284
333
285
334
rcu_read_lock ();
286
335
for (mrt = iter (net , NULL ); mrt ; mrt = iter (net , mrt )) {
287
336
if (t < s_t )
288
337
goto next_table ;
289
- list_for_each_entry_rcu (mfc , & mrt -> mfc_cache_list , list ) {
290
- if (e < s_e )
291
- goto next_entry ;
292
- if (fill (mrt , skb , NETLINK_CB (cb -> skb ).portid ,
293
- cb -> nlh -> nlmsg_seq , mfc ,
294
- RTM_NEWROUTE , NLM_F_MULTI ) < 0 )
295
- goto done ;
296
- next_entry :
297
- e ++ ;
298
- }
299
- e = 0 ;
300
- s_e = 0 ;
301
-
302
- spin_lock_bh (lock );
303
- list_for_each_entry (mfc , & mrt -> mfc_unres_queue , list ) {
304
- if (e < s_e )
305
- goto next_entry2 ;
306
- if (fill (mrt , skb , NETLINK_CB (cb -> skb ).portid ,
307
- cb -> nlh -> nlmsg_seq , mfc ,
308
- RTM_NEWROUTE , NLM_F_MULTI ) < 0 ) {
309
- spin_unlock_bh (lock );
310
- goto done ;
311
- }
312
- next_entry2 :
313
- e ++ ;
314
- }
315
- spin_unlock_bh (lock );
316
- e = 0 ;
317
- s_e = 0 ;
338
+
339
+ err = mr_table_dump (mrt , skb , cb , fill , lock );
340
+ if (err < 0 )
341
+ break ;
318
342
next_table :
319
343
t ++ ;
320
344
}
321
- done :
322
345
rcu_read_unlock ();
323
346
324
- cb -> args [1 ] = e ;
325
347
cb -> args [0 ] = t ;
326
348
327
349
return skb -> len ;
0 commit comments