@@ -2283,3 +2283,167 @@ int batadv_bla_backbone_table_seq_print_text(struct seq_file *seq, void *offset)
2283
2283
batadv_hardif_put (primary_if );
2284
2284
return 0 ;
2285
2285
}
2286
+
2287
+ /**
2288
+ * batadv_bla_backbone_dump_entry - dump one entry of the backbone table
2289
+ * to a netlink socket
2290
+ * @msg: buffer for the message
2291
+ * @portid: netlink port
2292
+ * @seq: Sequence number of netlink message
2293
+ * @primary_if: primary interface
2294
+ * @backbone_gw: entry to dump
2295
+ *
2296
+ * Return: 0 or error code.
2297
+ */
2298
+ static int
2299
+ batadv_bla_backbone_dump_entry (struct sk_buff * msg , u32 portid , u32 seq ,
2300
+ struct batadv_hard_iface * primary_if ,
2301
+ struct batadv_bla_backbone_gw * backbone_gw )
2302
+ {
2303
+ u8 * primary_addr = primary_if -> net_dev -> dev_addr ;
2304
+ u16 backbone_crc ;
2305
+ bool is_own ;
2306
+ int msecs ;
2307
+ void * hdr ;
2308
+ int ret = - EINVAL ;
2309
+
2310
+ hdr = genlmsg_put (msg , portid , seq , & batadv_netlink_family ,
2311
+ NLM_F_MULTI , BATADV_CMD_GET_BLA_BACKBONE );
2312
+ if (!hdr ) {
2313
+ ret = - ENOBUFS ;
2314
+ goto out ;
2315
+ }
2316
+
2317
+ is_own = batadv_compare_eth (backbone_gw -> orig , primary_addr );
2318
+
2319
+ spin_lock_bh (& backbone_gw -> crc_lock );
2320
+ backbone_crc = backbone_gw -> crc ;
2321
+ spin_unlock_bh (& backbone_gw -> crc_lock );
2322
+
2323
+ msecs = jiffies_to_msecs (jiffies - backbone_gw -> lasttime );
2324
+
2325
+ if (is_own )
2326
+ if (nla_put_flag (msg , BATADV_ATTR_BLA_OWN )) {
2327
+ genlmsg_cancel (msg , hdr );
2328
+ goto out ;
2329
+ }
2330
+
2331
+ if (nla_put (msg , BATADV_ATTR_BLA_BACKBONE , ETH_ALEN ,
2332
+ backbone_gw -> orig ) ||
2333
+ nla_put_u16 (msg , BATADV_ATTR_BLA_VID , backbone_gw -> vid ) ||
2334
+ nla_put_u16 (msg , BATADV_ATTR_BLA_CRC ,
2335
+ backbone_crc ) ||
2336
+ nla_put_u32 (msg , BATADV_ATTR_LAST_SEEN_MSECS , msecs )) {
2337
+ genlmsg_cancel (msg , hdr );
2338
+ goto out ;
2339
+ }
2340
+
2341
+ genlmsg_end (msg , hdr );
2342
+ ret = 0 ;
2343
+
2344
+ out :
2345
+ return ret ;
2346
+ }
2347
+
2348
+ /**
2349
+ * batadv_bla_backbone_dump_bucket - dump one bucket of the backbone table
2350
+ * to a netlink socket
2351
+ * @msg: buffer for the message
2352
+ * @portid: netlink port
2353
+ * @seq: Sequence number of netlink message
2354
+ * @primary_if: primary interface
2355
+ * @head: bucket to dump
2356
+ * @idx_skip: How many entries to skip
2357
+ *
2358
+ * Return: always 0.
2359
+ */
2360
+ static int
2361
+ batadv_bla_backbone_dump_bucket (struct sk_buff * msg , u32 portid , u32 seq ,
2362
+ struct batadv_hard_iface * primary_if ,
2363
+ struct hlist_head * head , int * idx_skip )
2364
+ {
2365
+ struct batadv_bla_backbone_gw * backbone_gw ;
2366
+ int idx = 0 ;
2367
+
2368
+ rcu_read_lock ();
2369
+ hlist_for_each_entry_rcu (backbone_gw , head , hash_entry ) {
2370
+ if (idx ++ < * idx_skip )
2371
+ continue ;
2372
+ if (batadv_bla_backbone_dump_entry (msg , portid , seq ,
2373
+ primary_if , backbone_gw )) {
2374
+ * idx_skip = idx - 1 ;
2375
+ goto unlock ;
2376
+ }
2377
+ }
2378
+
2379
+ * idx_skip = idx ;
2380
+ unlock :
2381
+ rcu_read_unlock ();
2382
+ return 0 ;
2383
+ }
2384
+
2385
+ /**
2386
+ * batadv_bla_backbone_dump - dump backbone table to a netlink socket
2387
+ * @msg: buffer for the message
2388
+ * @cb: callback structure containing arguments
2389
+ *
2390
+ * Return: message length.
2391
+ */
2392
+ int batadv_bla_backbone_dump (struct sk_buff * msg , struct netlink_callback * cb )
2393
+ {
2394
+ struct batadv_hard_iface * primary_if = NULL ;
2395
+ int portid = NETLINK_CB (cb -> skb ).portid ;
2396
+ struct net * net = sock_net (cb -> skb -> sk );
2397
+ struct net_device * soft_iface ;
2398
+ struct batadv_hashtable * hash ;
2399
+ struct batadv_priv * bat_priv ;
2400
+ int bucket = cb -> args [0 ];
2401
+ struct hlist_head * head ;
2402
+ int idx = cb -> args [1 ];
2403
+ int ifindex ;
2404
+ int ret = 0 ;
2405
+
2406
+ ifindex = batadv_netlink_get_ifindex (cb -> nlh ,
2407
+ BATADV_ATTR_MESH_IFINDEX );
2408
+ if (!ifindex )
2409
+ return - EINVAL ;
2410
+
2411
+ soft_iface = dev_get_by_index (net , ifindex );
2412
+ if (!soft_iface || !batadv_softif_is_valid (soft_iface )) {
2413
+ ret = - ENODEV ;
2414
+ goto out ;
2415
+ }
2416
+
2417
+ bat_priv = netdev_priv (soft_iface );
2418
+ hash = bat_priv -> bla .backbone_hash ;
2419
+
2420
+ primary_if = batadv_primary_if_get_selected (bat_priv );
2421
+ if (!primary_if || primary_if -> if_status != BATADV_IF_ACTIVE ) {
2422
+ ret = - ENOENT ;
2423
+ goto out ;
2424
+ }
2425
+
2426
+ while (bucket < hash -> size ) {
2427
+ head = & hash -> table [bucket ];
2428
+
2429
+ if (batadv_bla_backbone_dump_bucket (msg , portid ,
2430
+ cb -> nlh -> nlmsg_seq ,
2431
+ primary_if , head , & idx ))
2432
+ break ;
2433
+ bucket ++ ;
2434
+ }
2435
+
2436
+ cb -> args [0 ] = bucket ;
2437
+ cb -> args [1 ] = idx ;
2438
+
2439
+ ret = msg -> len ;
2440
+
2441
+ out :
2442
+ if (primary_if )
2443
+ batadv_hardif_put (primary_if );
2444
+
2445
+ if (soft_iface )
2446
+ dev_put (soft_iface );
2447
+
2448
+ return ret ;
2449
+ }
0 commit comments