@@ -2681,6 +2681,110 @@ static void batadv_iv_gw_print(struct batadv_priv *bat_priv,
2681
2681
seq_puts (seq , "No gateways in range ...\n" );
2682
2682
}
2683
2683
2684
+ /**
2685
+ * batadv_iv_gw_dump_entry - Dump a gateway into a message
2686
+ * @msg: Netlink message to dump into
2687
+ * @portid: Port making netlink request
2688
+ * @seq: Sequence number of netlink message
2689
+ * @bat_priv: The bat priv with all the soft interface information
2690
+ * @gw_node: Gateway to be dumped
2691
+ *
2692
+ * Return: Error code, or 0 on success
2693
+ */
2694
+ static int batadv_iv_gw_dump_entry (struct sk_buff * msg , u32 portid , u32 seq ,
2695
+ struct batadv_priv * bat_priv ,
2696
+ struct batadv_gw_node * gw_node )
2697
+ {
2698
+ struct batadv_neigh_ifinfo * router_ifinfo = NULL ;
2699
+ struct batadv_neigh_node * router ;
2700
+ struct batadv_gw_node * curr_gw ;
2701
+ int ret = - EINVAL ;
2702
+ void * hdr ;
2703
+
2704
+ router = batadv_orig_router_get (gw_node -> orig_node , BATADV_IF_DEFAULT );
2705
+ if (!router )
2706
+ goto out ;
2707
+
2708
+ router_ifinfo = batadv_neigh_ifinfo_get (router , BATADV_IF_DEFAULT );
2709
+ if (!router_ifinfo )
2710
+ goto out ;
2711
+
2712
+ curr_gw = batadv_gw_get_selected_gw_node (bat_priv );
2713
+
2714
+ hdr = genlmsg_put (msg , portid , seq , & batadv_netlink_family ,
2715
+ NLM_F_MULTI , BATADV_CMD_GET_GATEWAYS );
2716
+ if (!hdr ) {
2717
+ ret = - ENOBUFS ;
2718
+ goto out ;
2719
+ }
2720
+
2721
+ ret = - EMSGSIZE ;
2722
+
2723
+ if (curr_gw == gw_node )
2724
+ if (nla_put_flag (msg , BATADV_ATTR_FLAG_BEST )) {
2725
+ genlmsg_cancel (msg , hdr );
2726
+ goto out ;
2727
+ }
2728
+
2729
+ if (nla_put (msg , BATADV_ATTR_ORIG_ADDRESS , ETH_ALEN ,
2730
+ gw_node -> orig_node -> orig ) ||
2731
+ nla_put_u8 (msg , BATADV_ATTR_TQ , router_ifinfo -> bat_iv .tq_avg ) ||
2732
+ nla_put (msg , BATADV_ATTR_ROUTER , ETH_ALEN ,
2733
+ router -> addr ) ||
2734
+ nla_put_string (msg , BATADV_ATTR_HARD_IFNAME ,
2735
+ router -> if_incoming -> net_dev -> name ) ||
2736
+ nla_put_u32 (msg , BATADV_ATTR_BANDWIDTH_DOWN ,
2737
+ gw_node -> bandwidth_down ) ||
2738
+ nla_put_u32 (msg , BATADV_ATTR_BANDWIDTH_UP ,
2739
+ gw_node -> bandwidth_up )) {
2740
+ genlmsg_cancel (msg , hdr );
2741
+ goto out ;
2742
+ }
2743
+
2744
+ genlmsg_end (msg , hdr );
2745
+ ret = 0 ;
2746
+
2747
+ out :
2748
+ if (router_ifinfo )
2749
+ batadv_neigh_ifinfo_put (router_ifinfo );
2750
+ if (router )
2751
+ batadv_neigh_node_put (router );
2752
+ return ret ;
2753
+ }
2754
+
2755
+ /**
2756
+ * batadv_iv_gw_dump - Dump gateways into a message
2757
+ * @msg: Netlink message to dump into
2758
+ * @cb: Control block containing additional options
2759
+ * @bat_priv: The bat priv with all the soft interface information
2760
+ */
2761
+ static void batadv_iv_gw_dump (struct sk_buff * msg , struct netlink_callback * cb ,
2762
+ struct batadv_priv * bat_priv )
2763
+ {
2764
+ int portid = NETLINK_CB (cb -> skb ).portid ;
2765
+ struct batadv_gw_node * gw_node ;
2766
+ int idx_skip = cb -> args [0 ];
2767
+ int idx = 0 ;
2768
+
2769
+ rcu_read_lock ();
2770
+ hlist_for_each_entry_rcu (gw_node , & bat_priv -> gw .list , list ) {
2771
+ if (idx ++ < idx_skip )
2772
+ continue ;
2773
+
2774
+ if (batadv_iv_gw_dump_entry (msg , portid , cb -> nlh -> nlmsg_seq ,
2775
+ bat_priv , gw_node )) {
2776
+ idx_skip = idx - 1 ;
2777
+ goto unlock ;
2778
+ }
2779
+ }
2780
+
2781
+ idx_skip = idx ;
2782
+ unlock :
2783
+ rcu_read_unlock ();
2784
+
2785
+ cb -> args [0 ] = idx_skip ;
2786
+ }
2787
+
2684
2788
static struct batadv_algo_ops batadv_batman_iv __read_mostly = {
2685
2789
.name = "BATMAN_IV" ,
2686
2790
.iface = {
@@ -2707,6 +2811,7 @@ static struct batadv_algo_ops batadv_batman_iv __read_mostly = {
2707
2811
.get_best_gw_node = batadv_iv_gw_get_best_gw_node ,
2708
2812
.is_eligible = batadv_iv_gw_is_eligible ,
2709
2813
.print = batadv_iv_gw_print ,
2814
+ .dump = batadv_iv_gw_dump ,
2710
2815
},
2711
2816
};
2712
2817
0 commit comments