^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /* Copyright (C) 2013-2020 B.A.T.M.A.N. contributors:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Linus Lüssing, Marek Lindner
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include "bat_v.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include "main.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/atomic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/cache.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/if_ether.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/jiffies.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/kref.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/netlink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/rculist.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/rcupdate.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/seq_file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/skbuff.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/stddef.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/workqueue.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <net/genetlink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <net/netlink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <uapi/linux/batadv_packet.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <uapi/linux/batman_adv.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include "bat_algo.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include "bat_v_elp.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include "bat_v_ogm.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include "gateway_client.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include "gateway_common.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include "hard-interface.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include "hash.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include "log.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include "netlink.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include "originator.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) static void batadv_v_iface_activate(struct batadv_hard_iface *hard_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) struct batadv_hard_iface *primary_if;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) primary_if = batadv_primary_if_get_selected(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) if (primary_if) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) batadv_v_elp_iface_activate(primary_if, hard_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) batadv_hardif_put(primary_if);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) /* B.A.T.M.A.N. V does not use any queuing mechanism, therefore it can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * set the interface as ACTIVE right away, without any risk of race
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * condition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) if (hard_iface->if_status == BATADV_IF_TO_BE_ACTIVATED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) hard_iface->if_status = BATADV_IF_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) static int batadv_v_iface_enable(struct batadv_hard_iface *hard_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) ret = batadv_v_elp_iface_enable(hard_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) ret = batadv_v_ogm_iface_enable(hard_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) batadv_v_elp_iface_disable(hard_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) static void batadv_v_iface_disable(struct batadv_hard_iface *hard_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) batadv_v_ogm_iface_disable(hard_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) batadv_v_elp_iface_disable(hard_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) static void batadv_v_primary_iface_set(struct batadv_hard_iface *hard_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) batadv_v_elp_primary_iface_set(hard_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) batadv_v_ogm_primary_iface_set(hard_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) * batadv_v_iface_update_mac() - react to hard-interface MAC address change
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) * @hard_iface: the modified interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) * If the modified interface is the primary one, update the originator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) * address in the ELP and OGM messages to reflect the new MAC address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) static void batadv_v_iface_update_mac(struct batadv_hard_iface *hard_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) struct batadv_hard_iface *primary_if;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) primary_if = batadv_primary_if_get_selected(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) if (primary_if != hard_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) batadv_v_primary_iface_set(hard_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) if (primary_if)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) batadv_hardif_put(primary_if);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) batadv_v_hardif_neigh_init(struct batadv_hardif_neigh_node *hardif_neigh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) ewma_throughput_init(&hardif_neigh->bat_v.throughput);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) INIT_WORK(&hardif_neigh->bat_v.metric_work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) batadv_v_elp_throughput_metric_update);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) #ifdef CONFIG_BATMAN_ADV_DEBUGFS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) * batadv_v_orig_print_neigh() - print neighbors for the originator table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) * @orig_node: the orig_node for which the neighbors are printed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) * @if_outgoing: outgoing interface for these entries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) * @seq: debugfs table seq_file struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) * Must be called while holding an rcu lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) batadv_v_orig_print_neigh(struct batadv_orig_node *orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) struct batadv_hard_iface *if_outgoing,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) struct seq_file *seq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) struct batadv_neigh_node *neigh_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) struct batadv_neigh_ifinfo *n_ifinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) hlist_for_each_entry_rcu(neigh_node, &orig_node->neigh_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) n_ifinfo = batadv_neigh_ifinfo_get(neigh_node, if_outgoing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) if (!n_ifinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) seq_printf(seq, " %pM (%9u.%1u)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) neigh_node->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) n_ifinfo->bat_v.throughput / 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) n_ifinfo->bat_v.throughput % 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) batadv_neigh_ifinfo_put(n_ifinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) * batadv_v_hardif_neigh_print() - print a single ELP neighbour node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) * @seq: neighbour table seq_file struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) * @hardif_neigh: hardif neighbour information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) batadv_v_hardif_neigh_print(struct seq_file *seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) struct batadv_hardif_neigh_node *hardif_neigh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) int last_secs, last_msecs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) u32 throughput;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) last_secs = jiffies_to_msecs(jiffies - hardif_neigh->last_seen) / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) last_msecs = jiffies_to_msecs(jiffies - hardif_neigh->last_seen) % 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) throughput = ewma_throughput_read(&hardif_neigh->bat_v.throughput);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) seq_printf(seq, "%pM %4i.%03is (%9u.%1u) [%10s]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) hardif_neigh->addr, last_secs, last_msecs, throughput / 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) throughput % 10, hardif_neigh->if_incoming->net_dev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) * batadv_v_neigh_print() - print the single hop neighbour list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) * @seq: neighbour table seq_file struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) static void batadv_v_neigh_print(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) struct seq_file *seq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) struct net_device *net_dev = (struct net_device *)seq->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) struct batadv_hardif_neigh_node *hardif_neigh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) struct batadv_hard_iface *hard_iface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) int batman_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) seq_puts(seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) " Neighbor last-seen ( throughput) [ IF]\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) if (hard_iface->soft_iface != net_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) hlist_for_each_entry_rcu(hardif_neigh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) &hard_iface->neigh_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) batadv_v_hardif_neigh_print(seq, hardif_neigh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) batman_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) if (batman_count == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) seq_puts(seq, "No batman nodes in range ...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) * batadv_v_neigh_dump_neigh() - Dump a neighbour into a message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) * @msg: Netlink message to dump into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) * @portid: Port making netlink request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) * @seq: Sequence number of netlink message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) * @hardif_neigh: Neighbour to dump
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) * Return: Error code, or 0 on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) batadv_v_neigh_dump_neigh(struct sk_buff *msg, u32 portid, u32 seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) struct batadv_hardif_neigh_node *hardif_neigh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) unsigned int last_seen_msecs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) u32 throughput;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) last_seen_msecs = jiffies_to_msecs(jiffies - hardif_neigh->last_seen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) throughput = ewma_throughput_read(&hardif_neigh->bat_v.throughput);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) throughput = throughput * 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) hdr = genlmsg_put(msg, portid, seq, &batadv_netlink_family, NLM_F_MULTI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) BATADV_CMD_GET_NEIGHBORS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) if (nla_put(msg, BATADV_ATTR_NEIGH_ADDRESS, ETH_ALEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) hardif_neigh->addr) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) nla_put_u32(msg, BATADV_ATTR_HARD_IFINDEX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) hardif_neigh->if_incoming->net_dev->ifindex) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) nla_put_u32(msg, BATADV_ATTR_LAST_SEEN_MSECS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) last_seen_msecs) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) nla_put_u32(msg, BATADV_ATTR_THROUGHPUT, throughput))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) genlmsg_cancel(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) * batadv_v_neigh_dump_hardif() - Dump the neighbours of a hard interface into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) * a message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) * @msg: Netlink message to dump into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) * @portid: Port making netlink request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) * @seq: Sequence number of netlink message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) * @bat_priv: The bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) * @hard_iface: The hard interface to be dumped
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) * @idx_s: Entries to be skipped
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) * This function assumes the caller holds rcu_read_lock().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) * Return: Error code, or 0 on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) batadv_v_neigh_dump_hardif(struct sk_buff *msg, u32 portid, u32 seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) struct batadv_hard_iface *hard_iface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) int *idx_s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) struct batadv_hardif_neigh_node *hardif_neigh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) int idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) hlist_for_each_entry_rcu(hardif_neigh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) &hard_iface->neigh_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) if (idx++ < *idx_s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) if (batadv_v_neigh_dump_neigh(msg, portid, seq, hardif_neigh)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) *idx_s = idx - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) *idx_s = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) * batadv_v_neigh_dump() - Dump the neighbours of a hard interface into a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) * message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) * @msg: Netlink message to dump into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) * @cb: Control block containing additional options
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) * @bat_priv: The bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) * @single_hardif: Limit dumping to this hard interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) batadv_v_neigh_dump(struct sk_buff *msg, struct netlink_callback *cb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) struct batadv_hard_iface *single_hardif)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) struct batadv_hard_iface *hard_iface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) int i_hardif = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) int i_hardif_s = cb->args[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) int idx = cb->args[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) int portid = NETLINK_CB(cb->skb).portid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) if (single_hardif) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) if (i_hardif_s == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) if (batadv_v_neigh_dump_hardif(msg, portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) cb->nlh->nlmsg_seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) bat_priv, single_hardif,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) &idx) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) i_hardif++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) if (hard_iface->soft_iface != bat_priv->soft_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) if (i_hardif++ < i_hardif_s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) if (batadv_v_neigh_dump_hardif(msg, portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) cb->nlh->nlmsg_seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) bat_priv, hard_iface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) &idx)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) i_hardif--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) cb->args[0] = i_hardif;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) cb->args[1] = idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) #ifdef CONFIG_BATMAN_ADV_DEBUGFS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) * batadv_v_orig_print() - print the originator table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) * @seq: debugfs table seq_file struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) * @if_outgoing: the outgoing interface for which this should be printed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) static void batadv_v_orig_print(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) struct seq_file *seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) struct batadv_hard_iface *if_outgoing)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) struct batadv_neigh_node *neigh_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) struct batadv_hashtable *hash = bat_priv->orig_hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) int last_seen_msecs, last_seen_secs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) struct batadv_orig_node *orig_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) struct batadv_neigh_ifinfo *n_ifinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) unsigned long last_seen_jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) struct hlist_head *head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) int batman_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) u32 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) seq_puts(seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) " Originator last-seen ( throughput) Nexthop [outgoingIF]: Potential nexthops ...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) for (i = 0; i < hash->size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) head = &hash->table[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) neigh_node = batadv_orig_router_get(orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) if_outgoing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) if (!neigh_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) n_ifinfo = batadv_neigh_ifinfo_get(neigh_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) if_outgoing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) if (!n_ifinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) goto next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) last_seen_jiffies = jiffies - orig_node->last_seen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) last_seen_msecs = jiffies_to_msecs(last_seen_jiffies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) last_seen_secs = last_seen_msecs / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) last_seen_msecs = last_seen_msecs % 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) seq_printf(seq, "%pM %4i.%03is (%9u.%1u) %pM [%10s]:",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) orig_node->orig, last_seen_secs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) last_seen_msecs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) n_ifinfo->bat_v.throughput / 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) n_ifinfo->bat_v.throughput % 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) neigh_node->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) neigh_node->if_incoming->net_dev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) batadv_v_orig_print_neigh(orig_node, if_outgoing, seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) seq_putc(seq, '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) batman_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) next:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) batadv_neigh_node_put(neigh_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) if (n_ifinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) batadv_neigh_ifinfo_put(n_ifinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) if (batman_count == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) seq_puts(seq, "No batman nodes in range ...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) * batadv_v_orig_dump_subentry() - Dump an originator subentry into a message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) * @msg: Netlink message to dump into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) * @portid: Port making netlink request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) * @seq: Sequence number of netlink message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) * @bat_priv: The bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) * @if_outgoing: Limit dump to entries with this outgoing interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) * @orig_node: Originator to dump
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) * @neigh_node: Single hops neighbour
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) * @best: Is the best originator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) * Return: Error code, or 0 on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) batadv_v_orig_dump_subentry(struct sk_buff *msg, u32 portid, u32 seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) struct batadv_hard_iface *if_outgoing,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) struct batadv_orig_node *orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) struct batadv_neigh_node *neigh_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) bool best)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) struct batadv_neigh_ifinfo *n_ifinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) unsigned int last_seen_msecs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) u32 throughput;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) n_ifinfo = batadv_neigh_ifinfo_get(neigh_node, if_outgoing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) if (!n_ifinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) throughput = n_ifinfo->bat_v.throughput * 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) batadv_neigh_ifinfo_put(n_ifinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) last_seen_msecs = jiffies_to_msecs(jiffies - orig_node->last_seen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) if (if_outgoing != BATADV_IF_DEFAULT &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) if_outgoing != neigh_node->if_incoming)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) hdr = genlmsg_put(msg, portid, seq, &batadv_netlink_family, NLM_F_MULTI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) BATADV_CMD_GET_ORIGINATORS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) if (nla_put(msg, BATADV_ATTR_ORIG_ADDRESS, ETH_ALEN, orig_node->orig) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) nla_put(msg, BATADV_ATTR_NEIGH_ADDRESS, ETH_ALEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) neigh_node->addr) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) nla_put_u32(msg, BATADV_ATTR_HARD_IFINDEX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) neigh_node->if_incoming->net_dev->ifindex) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) nla_put_u32(msg, BATADV_ATTR_THROUGHPUT, throughput) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) nla_put_u32(msg, BATADV_ATTR_LAST_SEEN_MSECS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) last_seen_msecs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) if (best && nla_put_flag(msg, BATADV_ATTR_FLAG_BEST))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) genlmsg_cancel(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) * batadv_v_orig_dump_entry() - Dump an originator entry into a message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) * @msg: Netlink message to dump into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) * @portid: Port making netlink request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) * @seq: Sequence number of netlink message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) * @bat_priv: The bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) * @if_outgoing: Limit dump to entries with this outgoing interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) * @orig_node: Originator to dump
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) * @sub_s: Number of sub entries to skip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) * This function assumes the caller holds rcu_read_lock().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) * Return: Error code, or 0 on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) batadv_v_orig_dump_entry(struct sk_buff *msg, u32 portid, u32 seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) struct batadv_hard_iface *if_outgoing,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) struct batadv_orig_node *orig_node, int *sub_s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) struct batadv_neigh_node *neigh_node_best;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) struct batadv_neigh_node *neigh_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) int sub = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) bool best;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) neigh_node_best = batadv_orig_router_get(orig_node, if_outgoing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) if (!neigh_node_best)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) hlist_for_each_entry_rcu(neigh_node, &orig_node->neigh_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) if (sub++ < *sub_s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) best = (neigh_node == neigh_node_best);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) if (batadv_v_orig_dump_subentry(msg, portid, seq, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) if_outgoing, orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) neigh_node, best)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) batadv_neigh_node_put(neigh_node_best);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) *sub_s = sub - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) if (neigh_node_best)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) batadv_neigh_node_put(neigh_node_best);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) *sub_s = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) * batadv_v_orig_dump_bucket() - Dump an originator bucket into a message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) * @msg: Netlink message to dump into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) * @portid: Port making netlink request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) * @seq: Sequence number of netlink message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) * @bat_priv: The bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) * @if_outgoing: Limit dump to entries with this outgoing interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) * @head: Bucket to be dumped
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) * @idx_s: Number of entries to be skipped
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) * @sub: Number of sub entries to be skipped
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) * Return: Error code, or 0 on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) batadv_v_orig_dump_bucket(struct sk_buff *msg, u32 portid, u32 seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) struct batadv_hard_iface *if_outgoing,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) struct hlist_head *head, int *idx_s, int *sub)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) struct batadv_orig_node *orig_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) int idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) if (idx++ < *idx_s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) if (batadv_v_orig_dump_entry(msg, portid, seq, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) if_outgoing, orig_node, sub)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) *idx_s = idx - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) *idx_s = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) *sub = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) * batadv_v_orig_dump() - Dump the originators into a message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) * @msg: Netlink message to dump into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) * @cb: Control block containing additional options
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) * @bat_priv: The bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) * @if_outgoing: Limit dump to entries with this outgoing interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) batadv_v_orig_dump(struct sk_buff *msg, struct netlink_callback *cb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) struct batadv_hard_iface *if_outgoing)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) struct batadv_hashtable *hash = bat_priv->orig_hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) struct hlist_head *head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) int bucket = cb->args[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) int idx = cb->args[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) int sub = cb->args[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) int portid = NETLINK_CB(cb->skb).portid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) while (bucket < hash->size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) head = &hash->table[bucket];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) if (batadv_v_orig_dump_bucket(msg, portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) cb->nlh->nlmsg_seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) bat_priv, if_outgoing, head, &idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) &sub))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) bucket++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) cb->args[0] = bucket;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) cb->args[1] = idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) cb->args[2] = sub;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) static int batadv_v_neigh_cmp(struct batadv_neigh_node *neigh1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) struct batadv_hard_iface *if_outgoing1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) struct batadv_neigh_node *neigh2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) struct batadv_hard_iface *if_outgoing2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) struct batadv_neigh_ifinfo *ifinfo1, *ifinfo2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) ifinfo1 = batadv_neigh_ifinfo_get(neigh1, if_outgoing1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) if (!ifinfo1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) goto err_ifinfo1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) ifinfo2 = batadv_neigh_ifinfo_get(neigh2, if_outgoing2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) if (!ifinfo2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) goto err_ifinfo2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) ret = ifinfo1->bat_v.throughput - ifinfo2->bat_v.throughput;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) batadv_neigh_ifinfo_put(ifinfo2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) err_ifinfo2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) batadv_neigh_ifinfo_put(ifinfo1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) err_ifinfo1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) static bool batadv_v_neigh_is_sob(struct batadv_neigh_node *neigh1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) struct batadv_hard_iface *if_outgoing1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) struct batadv_neigh_node *neigh2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) struct batadv_hard_iface *if_outgoing2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) struct batadv_neigh_ifinfo *ifinfo1, *ifinfo2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) u32 threshold;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) bool ret = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) ifinfo1 = batadv_neigh_ifinfo_get(neigh1, if_outgoing1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) if (!ifinfo1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) goto err_ifinfo1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) ifinfo2 = batadv_neigh_ifinfo_get(neigh2, if_outgoing2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) if (!ifinfo2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) goto err_ifinfo2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) threshold = ifinfo1->bat_v.throughput / 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) threshold = ifinfo1->bat_v.throughput - threshold;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) ret = ifinfo2->bat_v.throughput > threshold;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) batadv_neigh_ifinfo_put(ifinfo2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) err_ifinfo2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) batadv_neigh_ifinfo_put(ifinfo1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) err_ifinfo1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) * batadv_v_init_sel_class() - initialize GW selection class
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) static void batadv_v_init_sel_class(struct batadv_priv *bat_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) /* set default throughput difference threshold to 5Mbps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) atomic_set(&bat_priv->gw.sel_class, 50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) static ssize_t batadv_v_store_sel_class(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) char *buff, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) u32 old_class, class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) if (!batadv_parse_throughput(bat_priv->soft_iface, buff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) "B.A.T.M.A.N. V GW selection class",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) &class))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) old_class = atomic_read(&bat_priv->gw.sel_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) atomic_set(&bat_priv->gw.sel_class, class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) if (old_class != class)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) batadv_gw_reselect(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) static ssize_t batadv_v_show_sel_class(struct batadv_priv *bat_priv, char *buff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) u32 class = atomic_read(&bat_priv->gw.sel_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) return sprintf(buff, "%u.%u MBit\n", class / 10, class % 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) * batadv_v_gw_throughput_get() - retrieve the GW-bandwidth for a given GW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) * @gw_node: the GW to retrieve the metric for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) * @bw: the pointer where the metric will be stored. The metric is computed as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) * the minimum between the GW advertised throughput and the path throughput to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) * it in the mesh
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) * Return: 0 on success, -1 on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) static int batadv_v_gw_throughput_get(struct batadv_gw_node *gw_node, u32 *bw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) struct batadv_neigh_ifinfo *router_ifinfo = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) struct batadv_orig_node *orig_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) struct batadv_neigh_node *router;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) int ret = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) orig_node = gw_node->orig_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) router = batadv_orig_router_get(orig_node, BATADV_IF_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) if (!router)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) router_ifinfo = batadv_neigh_ifinfo_get(router, BATADV_IF_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) if (!router_ifinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) /* the GW metric is computed as the minimum between the path throughput
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) * to reach the GW itself and the advertised bandwidth.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) * This gives us an approximation of the effective throughput that the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) * client can expect via this particular GW node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) *bw = router_ifinfo->bat_v.throughput;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) *bw = min_t(u32, *bw, gw_node->bandwidth_down);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) if (router)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) batadv_neigh_node_put(router);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) if (router_ifinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) batadv_neigh_ifinfo_put(router_ifinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) * batadv_v_gw_get_best_gw_node() - retrieve the best GW node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) * Return: the GW node having the best GW-metric, NULL if no GW is known
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) static struct batadv_gw_node *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) batadv_v_gw_get_best_gw_node(struct batadv_priv *bat_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) struct batadv_gw_node *gw_node, *curr_gw = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) u32 max_bw = 0, bw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) hlist_for_each_entry_rcu(gw_node, &bat_priv->gw.gateway_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) if (!kref_get_unless_zero(&gw_node->refcount))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) if (batadv_v_gw_throughput_get(gw_node, &bw) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) goto next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) if (curr_gw && bw <= max_bw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) goto next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) if (curr_gw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) batadv_gw_node_put(curr_gw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) curr_gw = gw_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) kref_get(&curr_gw->refcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) max_bw = bw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) next:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) batadv_gw_node_put(gw_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) return curr_gw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) * batadv_v_gw_is_eligible() - check if a originator would be selected as GW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) * @curr_gw_orig: originator representing the currently selected GW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) * @orig_node: the originator representing the new candidate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) * Return: true if orig_node can be selected as current GW, false otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) static bool batadv_v_gw_is_eligible(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) struct batadv_orig_node *curr_gw_orig,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) struct batadv_orig_node *orig_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) struct batadv_gw_node *curr_gw, *orig_gw = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) u32 gw_throughput, orig_throughput, threshold;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) bool ret = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) threshold = atomic_read(&bat_priv->gw.sel_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) curr_gw = batadv_gw_node_get(bat_priv, curr_gw_orig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) if (!curr_gw) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) ret = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) if (batadv_v_gw_throughput_get(curr_gw, &gw_throughput) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) ret = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) orig_gw = batadv_gw_node_get(bat_priv, orig_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) if (!orig_gw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) if (batadv_v_gw_throughput_get(orig_gw, &orig_throughput) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) if (orig_throughput < gw_throughput)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) if ((orig_throughput - gw_throughput) < threshold)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) "Restarting gateway selection: better gateway found (throughput curr: %u, throughput new: %u)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) gw_throughput, orig_throughput);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) ret = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) if (curr_gw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) batadv_gw_node_put(curr_gw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) if (orig_gw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) batadv_gw_node_put(orig_gw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) #ifdef CONFIG_BATMAN_ADV_DEBUGFS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) /* fails if orig_node has no router */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) static int batadv_v_gw_write_buffer_text(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) struct seq_file *seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) const struct batadv_gw_node *gw_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) struct batadv_gw_node *curr_gw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) struct batadv_neigh_node *router;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) struct batadv_neigh_ifinfo *router_ifinfo = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) int ret = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) router = batadv_orig_router_get(gw_node->orig_node, BATADV_IF_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) if (!router)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) router_ifinfo = batadv_neigh_ifinfo_get(router, BATADV_IF_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) if (!router_ifinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) curr_gw = batadv_gw_get_selected_gw_node(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) seq_printf(seq, "%s %pM (%9u.%1u) %pM [%10s]: %u.%u/%u.%u MBit\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) (curr_gw == gw_node ? "=>" : " "),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) gw_node->orig_node->orig,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) router_ifinfo->bat_v.throughput / 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) router_ifinfo->bat_v.throughput % 10, router->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) router->if_incoming->net_dev->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) gw_node->bandwidth_down / 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) gw_node->bandwidth_down % 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) gw_node->bandwidth_up / 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) gw_node->bandwidth_up % 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) ret = seq_has_overflowed(seq) ? -1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) if (curr_gw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) batadv_gw_node_put(curr_gw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) if (router_ifinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) batadv_neigh_ifinfo_put(router_ifinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) if (router)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) batadv_neigh_node_put(router);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) * batadv_v_gw_print() - print the gateway list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) * @seq: gateway table seq_file struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) static void batadv_v_gw_print(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) struct seq_file *seq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) struct batadv_gw_node *gw_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) int gw_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) seq_puts(seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) " Gateway ( throughput) Nexthop [outgoingIF]: advertised uplink bandwidth\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) hlist_for_each_entry_rcu(gw_node, &bat_priv->gw.gateway_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) /* fails if orig_node has no router */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) if (batadv_v_gw_write_buffer_text(bat_priv, seq, gw_node) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) gw_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) if (gw_count == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) seq_puts(seq, "No gateways in range ...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) * batadv_v_gw_dump_entry() - Dump a gateway into a message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) * @msg: Netlink message to dump into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) * @portid: Port making netlink request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) * @cb: Control block containing additional options
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) * @bat_priv: The bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) * @gw_node: Gateway to be dumped
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) * Return: Error code, or 0 on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) static int batadv_v_gw_dump_entry(struct sk_buff *msg, u32 portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) struct netlink_callback *cb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) struct batadv_gw_node *gw_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) struct batadv_neigh_ifinfo *router_ifinfo = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) struct batadv_neigh_node *router;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) struct batadv_gw_node *curr_gw = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) router = batadv_orig_router_get(gw_node->orig_node, BATADV_IF_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) if (!router)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) router_ifinfo = batadv_neigh_ifinfo_get(router, BATADV_IF_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) if (!router_ifinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) curr_gw = batadv_gw_get_selected_gw_node(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) hdr = genlmsg_put(msg, portid, cb->nlh->nlmsg_seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) &batadv_netlink_family, NLM_F_MULTI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) BATADV_CMD_GET_GATEWAYS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) if (!hdr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) ret = -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) genl_dump_check_consistent(cb, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) ret = -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) if (curr_gw == gw_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) if (nla_put_flag(msg, BATADV_ATTR_FLAG_BEST)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) genlmsg_cancel(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) if (nla_put(msg, BATADV_ATTR_ORIG_ADDRESS, ETH_ALEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) gw_node->orig_node->orig)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) genlmsg_cancel(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) if (nla_put_u32(msg, BATADV_ATTR_THROUGHPUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) router_ifinfo->bat_v.throughput)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) genlmsg_cancel(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) if (nla_put(msg, BATADV_ATTR_ROUTER, ETH_ALEN, router->addr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) genlmsg_cancel(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) if (nla_put_string(msg, BATADV_ATTR_HARD_IFNAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) router->if_incoming->net_dev->name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) genlmsg_cancel(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) if (nla_put_u32(msg, BATADV_ATTR_BANDWIDTH_DOWN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) gw_node->bandwidth_down)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) genlmsg_cancel(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) if (nla_put_u32(msg, BATADV_ATTR_BANDWIDTH_UP, gw_node->bandwidth_up)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) genlmsg_cancel(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) if (curr_gw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) batadv_gw_node_put(curr_gw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) if (router_ifinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) batadv_neigh_ifinfo_put(router_ifinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) if (router)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) batadv_neigh_node_put(router);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) * batadv_v_gw_dump() - Dump gateways into a message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) * @msg: Netlink message to dump into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) * @cb: Control block containing additional options
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) * @bat_priv: The bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) static void batadv_v_gw_dump(struct sk_buff *msg, struct netlink_callback *cb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) struct batadv_priv *bat_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) int portid = NETLINK_CB(cb->skb).portid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) struct batadv_gw_node *gw_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) int idx_skip = cb->args[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) int idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) spin_lock_bh(&bat_priv->gw.list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) cb->seq = bat_priv->gw.generation << 1 | 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) hlist_for_each_entry(gw_node, &bat_priv->gw.gateway_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) if (idx++ < idx_skip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) if (batadv_v_gw_dump_entry(msg, portid, cb, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) gw_node)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) idx_skip = idx - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) idx_skip = idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) spin_unlock_bh(&bat_priv->gw.list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) cb->args[0] = idx_skip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) static struct batadv_algo_ops batadv_batman_v __read_mostly = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) .name = "BATMAN_V",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) .iface = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) .activate = batadv_v_iface_activate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) .enable = batadv_v_iface_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) .disable = batadv_v_iface_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) .update_mac = batadv_v_iface_update_mac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) .primary_set = batadv_v_primary_iface_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) .neigh = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) .hardif_init = batadv_v_hardif_neigh_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) .cmp = batadv_v_neigh_cmp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) .is_similar_or_better = batadv_v_neigh_is_sob,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) #ifdef CONFIG_BATMAN_ADV_DEBUGFS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) .print = batadv_v_neigh_print,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) .dump = batadv_v_neigh_dump,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) .orig = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) #ifdef CONFIG_BATMAN_ADV_DEBUGFS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) .print = batadv_v_orig_print,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) .dump = batadv_v_orig_dump,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) .gw = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) .init_sel_class = batadv_v_init_sel_class,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) .store_sel_class = batadv_v_store_sel_class,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) .show_sel_class = batadv_v_show_sel_class,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) .get_best_gw_node = batadv_v_gw_get_best_gw_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) .is_eligible = batadv_v_gw_is_eligible,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) #ifdef CONFIG_BATMAN_ADV_DEBUGFS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) .print = batadv_v_gw_print,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) .dump = batadv_v_gw_dump,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) * batadv_v_hardif_init() - initialize the algorithm specific fields in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) * hard-interface object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) * @hard_iface: the hard-interface to initialize
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) void batadv_v_hardif_init(struct batadv_hard_iface *hard_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) /* enable link throughput auto-detection by setting the throughput
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) * override to zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) atomic_set(&hard_iface->bat_v.throughput_override, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) atomic_set(&hard_iface->bat_v.elp_interval, 500);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) hard_iface->bat_v.aggr_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) skb_queue_head_init(&hard_iface->bat_v.aggr_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) INIT_DELAYED_WORK(&hard_iface->bat_v.aggr_wq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) batadv_v_ogm_aggr_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) * batadv_v_mesh_init() - initialize the B.A.T.M.A.N. V private resources for a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) * mesh
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) * @bat_priv: the object representing the mesh interface to initialise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) * Return: 0 on success or a negative error code otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) int batadv_v_mesh_init(struct batadv_priv *bat_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) ret = batadv_v_ogm_init(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) * batadv_v_mesh_free() - free the B.A.T.M.A.N. V private resources for a mesh
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) * @bat_priv: the object representing the mesh interface to free
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) void batadv_v_mesh_free(struct batadv_priv *bat_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) batadv_v_ogm_free(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) * batadv_v_init() - B.A.T.M.A.N. V initialization function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) * Description: Takes care of initializing all the subcomponents.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) * It is invoked upon module load only.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) * Return: 0 on success or a negative error code otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) int __init batadv_v_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) /* B.A.T.M.A.N. V echo location protocol packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) ret = batadv_recv_handler_register(BATADV_ELP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) batadv_v_elp_packet_recv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) ret = batadv_recv_handler_register(BATADV_OGM2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) batadv_v_ogm_packet_recv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) goto elp_unregister;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) ret = batadv_algo_register(&batadv_batman_v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) goto ogm_unregister;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) ogm_unregister:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) batadv_recv_handler_unregister(BATADV_OGM2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) elp_unregister:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) batadv_recv_handler_unregister(BATADV_ELP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) }