^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) 2007-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) * Marek Lindner, Simon Wunderlich
^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_iv_ogm.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/bitmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/bug.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/byteorder/generic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/cache.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/etherdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/gfp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/if_ether.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/jiffies.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/kref.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/lockdep.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/netlink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/pkt_sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/prandom.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/printk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/random.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/rculist.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/rcupdate.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/seq_file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <linux/skbuff.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <linux/stddef.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include <linux/workqueue.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include <net/genetlink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include <net/netlink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include <uapi/linux/batadv_packet.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #include <uapi/linux/batman_adv.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #include "bat_algo.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #include "bitarray.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #include "gateway_client.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #include "hard-interface.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #include "hash.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #include "log.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #include "netlink.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #include "network-coding.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #include "originator.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #include "routing.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #include "send.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #include "translation-table.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #include "tvlv.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) static void batadv_iv_send_outstanding_bat_ogm_packet(struct work_struct *work);
^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) * enum batadv_dup_status - duplicate status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) enum batadv_dup_status {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) /** @BATADV_NO_DUP: the packet is no duplicate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) BATADV_NO_DUP = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) * @BATADV_ORIG_DUP: OGM is a duplicate in the originator (but not for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) * the neighbor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) BATADV_ORIG_DUP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) /** @BATADV_NEIGH_DUP: OGM is a duplicate for the neighbor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) BATADV_NEIGH_DUP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * @BATADV_PROTECTED: originator is currently protected (after reboot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) BATADV_PROTECTED,
^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) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * batadv_ring_buffer_set() - update the ring buffer with the given value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * @lq_recv: pointer to the ring buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * @lq_index: index to store the value at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * @value: value to store in the ring buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) static void batadv_ring_buffer_set(u8 lq_recv[], u8 *lq_index, u8 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) lq_recv[*lq_index] = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) *lq_index = (*lq_index + 1) % BATADV_TQ_GLOBAL_WINDOW_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * batadv_ring_buffer_avg() - compute the average of all non-zero values stored
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * in the given ring buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) * @lq_recv: pointer to the ring buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * Return: computed average value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) static u8 batadv_ring_buffer_avg(const u8 lq_recv[])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) const u8 *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) u16 count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) u16 i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) u16 sum = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) ptr = lq_recv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) while (i < BATADV_TQ_GLOBAL_WINDOW_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) if (*ptr != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) sum += *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) ptr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) if (count == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) return (u8)(sum / count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * batadv_iv_ogm_orig_get() - retrieve or create (if does not exist) an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) * originator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * @addr: mac address of the originator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) * Return: the originator object corresponding to the passed mac address or NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) * on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) * If the object does not exist, it is created and initialised.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) static struct batadv_orig_node *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) batadv_iv_ogm_orig_get(struct batadv_priv *bat_priv, const u8 *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) struct batadv_orig_node *orig_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) int hash_added;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) orig_node = batadv_orig_hash_find(bat_priv, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) if (orig_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) return orig_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) orig_node = batadv_orig_node_new(bat_priv, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) if (!orig_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) spin_lock_init(&orig_node->bat_iv.ogm_cnt_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) kref_get(&orig_node->refcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) hash_added = batadv_hash_add(bat_priv->orig_hash, batadv_compare_orig,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) batadv_choose_orig, orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) &orig_node->hash_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) if (hash_added != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) goto free_orig_node_hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) return orig_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) free_orig_node_hash:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) /* reference for batadv_hash_add */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) batadv_orig_node_put(orig_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) /* reference from batadv_orig_node_new */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) batadv_orig_node_put(orig_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) return NULL;
^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) static struct batadv_neigh_node *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) batadv_iv_ogm_neigh_new(struct batadv_hard_iface *hard_iface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) const u8 *neigh_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) struct batadv_orig_node *orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) struct batadv_orig_node *orig_neigh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) struct batadv_neigh_node *neigh_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) neigh_node = batadv_neigh_node_get_or_create(orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) hard_iface, neigh_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) if (!neigh_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) neigh_node->orig_node = orig_neigh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) return neigh_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) static int batadv_iv_ogm_iface_enable(struct batadv_hard_iface *hard_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) struct batadv_ogm_packet *batadv_ogm_packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) unsigned char *ogm_buff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) u32 random_seqno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) /* randomize initial seqno to avoid collision */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) get_random_bytes(&random_seqno, sizeof(random_seqno));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) atomic_set(&hard_iface->bat_iv.ogm_seqno, random_seqno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) hard_iface->bat_iv.ogm_buff_len = BATADV_OGM_HLEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) ogm_buff = kmalloc(hard_iface->bat_iv.ogm_buff_len, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) if (!ogm_buff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) hard_iface->bat_iv.ogm_buff = ogm_buff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) batadv_ogm_packet->packet_type = BATADV_IV_OGM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) batadv_ogm_packet->version = BATADV_COMPAT_VERSION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) batadv_ogm_packet->ttl = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) batadv_ogm_packet->flags = BATADV_NO_FLAGS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) batadv_ogm_packet->reserved = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) batadv_ogm_packet->tq = BATADV_TQ_MAX_VALUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) static void batadv_iv_ogm_iface_disable(struct batadv_hard_iface *hard_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) kfree(hard_iface->bat_iv.ogm_buff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) hard_iface->bat_iv.ogm_buff = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) static void batadv_iv_ogm_iface_update_mac(struct batadv_hard_iface *hard_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) struct batadv_ogm_packet *batadv_ogm_packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) void *ogm_buff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) ogm_buff = hard_iface->bat_iv.ogm_buff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) if (!ogm_buff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) batadv_ogm_packet = ogm_buff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) ether_addr_copy(batadv_ogm_packet->orig,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) hard_iface->net_dev->dev_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) ether_addr_copy(batadv_ogm_packet->prev_sender,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) hard_iface->net_dev->dev_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) batadv_iv_ogm_primary_iface_set(struct batadv_hard_iface *hard_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) struct batadv_ogm_packet *batadv_ogm_packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) void *ogm_buff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) ogm_buff = hard_iface->bat_iv.ogm_buff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) if (!ogm_buff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) batadv_ogm_packet = ogm_buff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) batadv_ogm_packet->ttl = BATADV_TTL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) /* when do we schedule our own ogm to be sent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) static unsigned long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) batadv_iv_ogm_emit_send_time(const struct batadv_priv *bat_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) unsigned int msecs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) msecs = atomic_read(&bat_priv->orig_interval) - BATADV_JITTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) msecs += prandom_u32_max(2 * BATADV_JITTER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) return jiffies + msecs_to_jiffies(msecs);
^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) /* when do we schedule a ogm packet to be sent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) static unsigned long batadv_iv_ogm_fwd_send_time(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) return jiffies + msecs_to_jiffies(prandom_u32_max(BATADV_JITTER / 2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) /* apply hop penalty for a normal link */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) static u8 batadv_hop_penalty(u8 tq, const struct batadv_priv *bat_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) int hop_penalty = atomic_read(&bat_priv->hop_penalty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) int new_tq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) new_tq = tq * (BATADV_TQ_MAX_VALUE - hop_penalty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) new_tq /= BATADV_TQ_MAX_VALUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) return new_tq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) * batadv_iv_ogm_aggr_packet() - checks if there is another OGM attached
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) * @buff_pos: current position in the skb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) * @packet_len: total length of the skb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) * @ogm_packet: potential OGM in buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) * Return: true if there is enough space for another OGM, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) static bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) batadv_iv_ogm_aggr_packet(int buff_pos, int packet_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) const struct batadv_ogm_packet *ogm_packet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) int next_buff_pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) /* check if there is enough space for the header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) next_buff_pos += buff_pos + sizeof(*ogm_packet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) if (next_buff_pos > packet_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) /* check if there is enough space for the optional TVLV */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) next_buff_pos += ntohs(ogm_packet->tvlv_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) return (next_buff_pos <= packet_len) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) (next_buff_pos <= BATADV_MAX_AGGREGATION_BYTES);
^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) /* send a batman ogm to a given interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) static void batadv_iv_ogm_send_to_if(struct batadv_forw_packet *forw_packet,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) struct batadv_hard_iface *hard_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) const char *fwd_str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) u8 packet_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) s16 buff_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) struct batadv_ogm_packet *batadv_ogm_packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) u8 *packet_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) if (hard_iface->if_status != BATADV_IF_ACTIVE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) packet_num = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) buff_pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) packet_pos = forw_packet->skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) batadv_ogm_packet = (struct batadv_ogm_packet *)packet_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) /* adjust all flags and log packets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) while (batadv_iv_ogm_aggr_packet(buff_pos, forw_packet->packet_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) batadv_ogm_packet)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) /* we might have aggregated direct link packets with an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) * ordinary base packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) if (forw_packet->direct_link_flags & BIT(packet_num) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) forw_packet->if_incoming == hard_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) batadv_ogm_packet->flags |= BATADV_DIRECTLINK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) batadv_ogm_packet->flags &= ~BATADV_DIRECTLINK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) if (packet_num > 0 || !forw_packet->own)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) fwd_str = "Forwarding";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) fwd_str = "Sending own";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) "%s %spacket (originator %pM, seqno %u, TQ %d, TTL %d, IDF %s) on interface %s [%pM]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) fwd_str, (packet_num > 0 ? "aggregated " : ""),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) batadv_ogm_packet->orig,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) ntohl(batadv_ogm_packet->seqno),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) batadv_ogm_packet->tq, batadv_ogm_packet->ttl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) ((batadv_ogm_packet->flags & BATADV_DIRECTLINK) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) "on" : "off"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) hard_iface->net_dev->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) hard_iface->net_dev->dev_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) buff_pos += BATADV_OGM_HLEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) buff_pos += ntohs(batadv_ogm_packet->tvlv_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) packet_num++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) packet_pos = forw_packet->skb->data + buff_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) batadv_ogm_packet = (struct batadv_ogm_packet *)packet_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) /* create clone because function is called more than once */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) skb = skb_clone(forw_packet->skb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) if (skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) batadv_inc_counter(bat_priv, BATADV_CNT_MGMT_TX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) batadv_add_counter(bat_priv, BATADV_CNT_MGMT_TX_BYTES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) skb->len + ETH_HLEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) batadv_send_broadcast_skb(skb, hard_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) /* send a batman ogm packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) static void batadv_iv_ogm_emit(struct batadv_forw_packet *forw_packet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) struct net_device *soft_iface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) if (!forw_packet->if_incoming) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) pr_err("Error - can't forward packet: incoming iface not specified\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) soft_iface = forw_packet->if_incoming->soft_iface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) if (WARN_ON(!forw_packet->if_outgoing))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) if (forw_packet->if_outgoing->soft_iface != soft_iface) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) pr_warn("%s: soft interface switch for queued OGM\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) if (forw_packet->if_incoming->if_status != BATADV_IF_ACTIVE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) /* only for one specific outgoing interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) batadv_iv_ogm_send_to_if(forw_packet, forw_packet->if_outgoing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) * batadv_iv_ogm_can_aggregate() - find out if an OGM can be aggregated on an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) * existing forward packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) * @new_bat_ogm_packet: OGM packet to be aggregated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) * @packet_len: (total) length of the OGM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) * @send_time: timestamp (jiffies) when the packet is to be sent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) * @directlink: true if this is a direct link packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) * @if_incoming: interface where the packet was received
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) * @if_outgoing: interface for which the retransmission should be considered
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) * @forw_packet: the forwarded packet which should be checked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) * Return: true if new_packet can be aggregated with forw_packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) static bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) batadv_iv_ogm_can_aggregate(const struct batadv_ogm_packet *new_bat_ogm_packet,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) int packet_len, unsigned long send_time,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) bool directlink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) const struct batadv_hard_iface *if_incoming,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) const struct batadv_hard_iface *if_outgoing,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) const struct batadv_forw_packet *forw_packet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) struct batadv_ogm_packet *batadv_ogm_packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) int aggregated_bytes = forw_packet->packet_len + packet_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) struct batadv_hard_iface *primary_if = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) bool res = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) unsigned long aggregation_end_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) batadv_ogm_packet = (struct batadv_ogm_packet *)forw_packet->skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) aggregation_end_time = send_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) aggregation_end_time += msecs_to_jiffies(BATADV_MAX_AGGREGATION_MS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) /* we can aggregate the current packet to this aggregated packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) * if:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) * - the send time is within our MAX_AGGREGATION_MS time
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) * - the resulting packet wont be bigger than
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) * MAX_AGGREGATION_BYTES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) * otherwise aggregation is not possible
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) if (!time_before(send_time, forw_packet->send_time) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) !time_after_eq(aggregation_end_time, forw_packet->send_time))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) if (aggregated_bytes > BATADV_MAX_AGGREGATION_BYTES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) /* packet is not leaving on the same interface. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) if (forw_packet->if_outgoing != if_outgoing)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) /* check aggregation compatibility
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) * -> direct link packets are broadcasted on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) * their interface only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) * -> aggregate packet if the current packet is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) * a "global" packet as well as the base
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) * packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) primary_if = batadv_primary_if_get_selected(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) if (!primary_if)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) /* packets without direct link flag and high TTL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) * are flooded through the net
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) if (!directlink &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) !(batadv_ogm_packet->flags & BATADV_DIRECTLINK) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) batadv_ogm_packet->ttl != 1 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) /* own packets originating non-primary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) * interfaces leave only that interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) (!forw_packet->own ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) forw_packet->if_incoming == primary_if)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) res = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) /* if the incoming packet is sent via this one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) * interface only - we still can aggregate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) if (directlink &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) new_bat_ogm_packet->ttl == 1 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) forw_packet->if_incoming == if_incoming &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) /* packets from direct neighbors or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) * own secondary interface packets
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) * (= secondary interface packets in general)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) (batadv_ogm_packet->flags & BATADV_DIRECTLINK ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) (forw_packet->own &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) forw_packet->if_incoming != primary_if))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) res = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) if (primary_if)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) batadv_hardif_put(primary_if);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) return res;
^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_iv_ogm_aggregate_new() - create a new aggregated packet and add this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) * packet to it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) * @packet_buff: pointer to the OGM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) * @packet_len: (total) length of the OGM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) * @send_time: timestamp (jiffies) when the packet is to be sent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) * @direct_link: whether this OGM has direct link status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) * @if_incoming: interface where the packet was received
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) * @if_outgoing: interface for which the retransmission should be considered
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) * @own_packet: true if it is a self-generated ogm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) static void batadv_iv_ogm_aggregate_new(const unsigned char *packet_buff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) int packet_len, unsigned long send_time,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) bool direct_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) struct batadv_hard_iface *if_incoming,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) struct batadv_hard_iface *if_outgoing,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) int own_packet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) struct batadv_forw_packet *forw_packet_aggr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) unsigned char *skb_buff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) unsigned int skb_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) atomic_t *queue_left = own_packet ? NULL : &bat_priv->batman_queue_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) if (atomic_read(&bat_priv->aggregated_ogms) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) packet_len < BATADV_MAX_AGGREGATION_BYTES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) skb_size = BATADV_MAX_AGGREGATION_BYTES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) skb_size = packet_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) skb_size += ETH_HLEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) skb = netdev_alloc_skb_ip_align(NULL, skb_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) forw_packet_aggr = batadv_forw_packet_alloc(if_incoming, if_outgoing,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) queue_left, bat_priv, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) if (!forw_packet_aggr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) forw_packet_aggr->skb->priority = TC_PRIO_CONTROL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) skb_reserve(forw_packet_aggr->skb, ETH_HLEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) skb_buff = skb_put(forw_packet_aggr->skb, packet_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) forw_packet_aggr->packet_len = packet_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) memcpy(skb_buff, packet_buff, packet_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) forw_packet_aggr->own = own_packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) forw_packet_aggr->direct_link_flags = BATADV_NO_FLAGS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) forw_packet_aggr->send_time = send_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) /* save packet direct link flag status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) if (direct_link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) forw_packet_aggr->direct_link_flags |= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) INIT_DELAYED_WORK(&forw_packet_aggr->delayed_work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) batadv_iv_send_outstanding_bat_ogm_packet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) batadv_forw_packet_ogmv1_queue(bat_priv, forw_packet_aggr, send_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) /* aggregate a new packet into the existing ogm packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) static void batadv_iv_ogm_aggregate(struct batadv_forw_packet *forw_packet_aggr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) const unsigned char *packet_buff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) int packet_len, bool direct_link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) unsigned long new_direct_link_flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) skb_put_data(forw_packet_aggr->skb, packet_buff, packet_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) forw_packet_aggr->packet_len += packet_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) forw_packet_aggr->num_packets++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) /* save packet direct link flag status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) if (direct_link) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) new_direct_link_flag = BIT(forw_packet_aggr->num_packets);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) forw_packet_aggr->direct_link_flags |= new_direct_link_flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) * batadv_iv_ogm_queue_add() - queue up an OGM for transmission
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) * @packet_buff: pointer to the OGM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) * @packet_len: (total) length of the OGM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) * @if_incoming: interface where the packet was received
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) * @if_outgoing: interface for which the retransmission should be considered
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) * @own_packet: true if it is a self-generated ogm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) * @send_time: timestamp (jiffies) when the packet is to be sent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) static void batadv_iv_ogm_queue_add(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) unsigned char *packet_buff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) int packet_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) struct batadv_hard_iface *if_incoming,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) struct batadv_hard_iface *if_outgoing,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) int own_packet, unsigned long send_time)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) /* _aggr -> pointer to the packet we want to aggregate with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) * _pos -> pointer to the position in the queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) struct batadv_forw_packet *forw_packet_aggr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) struct batadv_forw_packet *forw_packet_pos = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) struct batadv_ogm_packet *batadv_ogm_packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) bool direct_link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) unsigned long max_aggregation_jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) batadv_ogm_packet = (struct batadv_ogm_packet *)packet_buff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) direct_link = !!(batadv_ogm_packet->flags & BATADV_DIRECTLINK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) max_aggregation_jiffies = msecs_to_jiffies(BATADV_MAX_AGGREGATION_MS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) /* find position for the packet in the forward queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) spin_lock_bh(&bat_priv->forw_bat_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) /* own packets are not to be aggregated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) if (atomic_read(&bat_priv->aggregated_ogms) && !own_packet) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) hlist_for_each_entry(forw_packet_pos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) &bat_priv->forw_bat_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) if (batadv_iv_ogm_can_aggregate(batadv_ogm_packet,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) bat_priv, packet_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) send_time, direct_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) if_incoming,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) if_outgoing,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) forw_packet_pos)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) forw_packet_aggr = forw_packet_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) }
^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) /* nothing to aggregate with - either aggregation disabled or no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) * suitable aggregation packet found
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) if (!forw_packet_aggr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) /* the following section can run without the lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) spin_unlock_bh(&bat_priv->forw_bat_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) /* if we could not aggregate this packet with one of the others
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) * we hold it back for a while, so that it might be aggregated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) * later on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) if (!own_packet && atomic_read(&bat_priv->aggregated_ogms))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) send_time += max_aggregation_jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) batadv_iv_ogm_aggregate_new(packet_buff, packet_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) send_time, direct_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) if_incoming, if_outgoing,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) own_packet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) batadv_iv_ogm_aggregate(forw_packet_aggr, packet_buff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) packet_len, direct_link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) spin_unlock_bh(&bat_priv->forw_bat_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) static void batadv_iv_ogm_forward(struct batadv_orig_node *orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) const struct ethhdr *ethhdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) struct batadv_ogm_packet *batadv_ogm_packet,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) bool is_single_hop_neigh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) bool is_from_best_next_hop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) struct batadv_hard_iface *if_incoming,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) struct batadv_hard_iface *if_outgoing)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) u16 tvlv_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) if (batadv_ogm_packet->ttl <= 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) batadv_dbg(BATADV_DBG_BATMAN, bat_priv, "ttl exceeded\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) if (!is_from_best_next_hop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) /* Mark the forwarded packet when it is not coming from our
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) * best next hop. We still need to forward the packet for our
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) * neighbor link quality detection to work in case the packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) * originated from a single hop neighbor. Otherwise we can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) * simply drop the ogm.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) if (is_single_hop_neigh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) batadv_ogm_packet->flags |= BATADV_NOT_BEST_NEXT_HOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) tvlv_len = ntohs(batadv_ogm_packet->tvlv_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) batadv_ogm_packet->ttl--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) ether_addr_copy(batadv_ogm_packet->prev_sender, ethhdr->h_source);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) /* apply hop penalty */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) batadv_ogm_packet->tq = batadv_hop_penalty(batadv_ogm_packet->tq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) "Forwarding packet: tq: %i, ttl: %i\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) batadv_ogm_packet->tq, batadv_ogm_packet->ttl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) if (is_single_hop_neigh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) batadv_ogm_packet->flags |= BATADV_DIRECTLINK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) batadv_ogm_packet->flags &= ~BATADV_DIRECTLINK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) batadv_iv_ogm_queue_add(bat_priv, (unsigned char *)batadv_ogm_packet,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) BATADV_OGM_HLEN + tvlv_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) if_incoming, if_outgoing, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) batadv_iv_ogm_fwd_send_time());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) }
^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) * batadv_iv_ogm_slide_own_bcast_window() - bitshift own OGM broadcast windows
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) * for the given interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) * @hard_iface: the interface for which the windows have to be shifted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) batadv_iv_ogm_slide_own_bcast_window(struct batadv_hard_iface *hard_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) struct batadv_hashtable *hash = bat_priv->orig_hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) struct hlist_head *head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) struct batadv_orig_node *orig_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) struct batadv_orig_ifinfo *orig_ifinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) unsigned long *word;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) u32 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) u8 *w;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) for (i = 0; i < hash->size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) head = &hash->table[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) hlist_for_each_entry_rcu(orig_ifinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) &orig_node->ifinfo_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) if (orig_ifinfo->if_outgoing != hard_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) word = orig_ifinfo->bat_iv.bcast_own;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) batadv_bit_get_packet(bat_priv, word, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) w = &orig_ifinfo->bat_iv.bcast_own_sum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) *w = bitmap_weight(word,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) BATADV_TQ_LOCAL_WINDOW_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) spin_unlock_bh(&orig_node->bat_iv.ogm_cnt_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) rcu_read_unlock();
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) * batadv_iv_ogm_schedule_buff() - schedule submission of hardif ogm buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) * @hard_iface: interface whose ogm buffer should be transmitted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) static void batadv_iv_ogm_schedule_buff(struct batadv_hard_iface *hard_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) unsigned char **ogm_buff = &hard_iface->bat_iv.ogm_buff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) struct batadv_ogm_packet *batadv_ogm_packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) struct batadv_hard_iface *primary_if, *tmp_hard_iface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) int *ogm_buff_len = &hard_iface->bat_iv.ogm_buff_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) u32 seqno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) u16 tvlv_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) unsigned long send_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) lockdep_assert_held(&hard_iface->bat_iv.ogm_buff_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) /* interface already disabled by batadv_iv_ogm_iface_disable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) if (!*ogm_buff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) /* the interface gets activated here to avoid race conditions between
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) * the moment of activating the interface in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) * hardif_activate_interface() where the originator mac is set and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) * outdated packets (especially uninitialized mac addresses) in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) * packet queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) if (hard_iface->if_status == BATADV_IF_TO_BE_ACTIVATED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) hard_iface->if_status = BATADV_IF_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) primary_if = batadv_primary_if_get_selected(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) if (hard_iface == primary_if) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) /* tt changes have to be committed before the tvlv data is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) * appended as it may alter the tt tvlv container
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) batadv_tt_local_commit_changes(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) tvlv_len = batadv_tvlv_container_ogm_append(bat_priv, ogm_buff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) ogm_buff_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) BATADV_OGM_HLEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) batadv_ogm_packet = (struct batadv_ogm_packet *)(*ogm_buff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) batadv_ogm_packet->tvlv_len = htons(tvlv_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) /* change sequence number to network order */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) seqno = (u32)atomic_read(&hard_iface->bat_iv.ogm_seqno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) batadv_ogm_packet->seqno = htonl(seqno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) atomic_inc(&hard_iface->bat_iv.ogm_seqno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) batadv_iv_ogm_slide_own_bcast_window(hard_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) send_time = batadv_iv_ogm_emit_send_time(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) if (hard_iface != primary_if) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) /* OGMs from secondary interfaces are only scheduled on their
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) * respective interfaces.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) batadv_iv_ogm_queue_add(bat_priv, *ogm_buff, *ogm_buff_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) hard_iface, hard_iface, 1, send_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) /* OGMs from primary interfaces are scheduled on all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) * interfaces.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) list_for_each_entry_rcu(tmp_hard_iface, &batadv_hardif_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) if (tmp_hard_iface->soft_iface != hard_iface->soft_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) if (!kref_get_unless_zero(&tmp_hard_iface->refcount))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) batadv_iv_ogm_queue_add(bat_priv, *ogm_buff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) *ogm_buff_len, hard_iface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) tmp_hard_iface, 1, send_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) batadv_hardif_put(tmp_hard_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) if (primary_if)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) batadv_hardif_put(primary_if);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) if (hard_iface->if_status == BATADV_IF_NOT_IN_USE ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) hard_iface->if_status == BATADV_IF_TO_BE_REMOVED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) batadv_iv_ogm_schedule_buff(hard_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
^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) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) * batadv_iv_orig_ifinfo_sum() - Get bcast_own sum for originator over interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) * @orig_node: originator which reproadcasted the OGMs directly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) * @if_outgoing: interface which transmitted the original OGM and received the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) * direct rebroadcast
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) * Return: Number of replied (rebroadcasted) OGMs which were transmitted by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) * an originator and directly (without intermediate hop) received by a specific
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) * interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) static u8 batadv_iv_orig_ifinfo_sum(struct batadv_orig_node *orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) struct batadv_hard_iface *if_outgoing)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) struct batadv_orig_ifinfo *orig_ifinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) u8 sum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) orig_ifinfo = batadv_orig_ifinfo_get(orig_node, if_outgoing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) if (!orig_ifinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) sum = orig_ifinfo->bat_iv.bcast_own_sum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) spin_unlock_bh(&orig_node->bat_iv.ogm_cnt_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) batadv_orig_ifinfo_put(orig_ifinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) return sum;
^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) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) * batadv_iv_ogm_orig_update() - use OGM to update corresponding data in an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) * originator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) * @orig_node: the orig node who originally emitted the ogm packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) * @orig_ifinfo: ifinfo for the outgoing interface of the orig_node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) * @ethhdr: Ethernet header of the OGM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) * @batadv_ogm_packet: the ogm packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) * @if_incoming: interface where the packet was received
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) * @if_outgoing: interface for which the retransmission should be considered
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) * @dup_status: the duplicate status of this ogm packet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) struct batadv_orig_node *orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) struct batadv_orig_ifinfo *orig_ifinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) const struct ethhdr *ethhdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) const struct batadv_ogm_packet *batadv_ogm_packet,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) struct batadv_hard_iface *if_incoming,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) struct batadv_hard_iface *if_outgoing,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) enum batadv_dup_status dup_status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) struct batadv_neigh_ifinfo *neigh_ifinfo = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) struct batadv_neigh_ifinfo *router_ifinfo = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) struct batadv_neigh_node *neigh_node = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) struct batadv_neigh_node *tmp_neigh_node = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) struct batadv_neigh_node *router = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) u8 sum_orig, sum_neigh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) u8 *neigh_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) u8 tq_avg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) "%s(): Searching and updating originator entry of received packet\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) hlist_for_each_entry_rcu(tmp_neigh_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) &orig_node->neigh_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) neigh_addr = tmp_neigh_node->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) if (batadv_compare_eth(neigh_addr, ethhdr->h_source) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) tmp_neigh_node->if_incoming == if_incoming &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) kref_get_unless_zero(&tmp_neigh_node->refcount)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) if (WARN(neigh_node, "too many matching neigh_nodes"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) batadv_neigh_node_put(neigh_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) neigh_node = tmp_neigh_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) continue;
^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) if (dup_status != BATADV_NO_DUP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) /* only update the entry for this outgoing interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) neigh_ifinfo = batadv_neigh_ifinfo_get(tmp_neigh_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) if_outgoing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) if (!neigh_ifinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) spin_lock_bh(&tmp_neigh_node->ifinfo_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) batadv_ring_buffer_set(neigh_ifinfo->bat_iv.tq_recv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) &neigh_ifinfo->bat_iv.tq_index, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) tq_avg = batadv_ring_buffer_avg(neigh_ifinfo->bat_iv.tq_recv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) neigh_ifinfo->bat_iv.tq_avg = tq_avg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) spin_unlock_bh(&tmp_neigh_node->ifinfo_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) batadv_neigh_ifinfo_put(neigh_ifinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) neigh_ifinfo = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) if (!neigh_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) struct batadv_orig_node *orig_tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) orig_tmp = batadv_iv_ogm_orig_get(bat_priv, ethhdr->h_source);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) if (!orig_tmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) neigh_node = batadv_iv_ogm_neigh_new(if_incoming,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) ethhdr->h_source,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) orig_node, orig_tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) batadv_orig_node_put(orig_tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) if (!neigh_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) "Updating existing last-hop neighbor of originator\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) neigh_ifinfo = batadv_neigh_ifinfo_new(neigh_node, if_outgoing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) if (!neigh_ifinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) neigh_node->last_seen = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) spin_lock_bh(&neigh_node->ifinfo_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) batadv_ring_buffer_set(neigh_ifinfo->bat_iv.tq_recv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) &neigh_ifinfo->bat_iv.tq_index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) batadv_ogm_packet->tq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) tq_avg = batadv_ring_buffer_avg(neigh_ifinfo->bat_iv.tq_recv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) neigh_ifinfo->bat_iv.tq_avg = tq_avg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) spin_unlock_bh(&neigh_node->ifinfo_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) if (dup_status == BATADV_NO_DUP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) orig_ifinfo->last_ttl = batadv_ogm_packet->ttl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) neigh_ifinfo->last_ttl = batadv_ogm_packet->ttl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) /* if this neighbor already is our next hop there is nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) * to change
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) router = batadv_orig_router_get(orig_node, if_outgoing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) if (router == neigh_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) if (router) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) router_ifinfo = batadv_neigh_ifinfo_get(router, if_outgoing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) if (!router_ifinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) /* if this neighbor does not offer a better TQ we won't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) * consider it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) if (router_ifinfo->bat_iv.tq_avg > neigh_ifinfo->bat_iv.tq_avg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) /* if the TQ is the same and the link not more symmetric we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) * won't consider it either
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) if (router_ifinfo &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) neigh_ifinfo->bat_iv.tq_avg == router_ifinfo->bat_iv.tq_avg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) sum_orig = batadv_iv_orig_ifinfo_sum(router->orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) router->if_incoming);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) sum_neigh = batadv_iv_orig_ifinfo_sum(neigh_node->orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) neigh_node->if_incoming);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) if (sum_orig >= sum_neigh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) batadv_update_route(bat_priv, orig_node, if_outgoing, neigh_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) if (neigh_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) batadv_neigh_node_put(neigh_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) if (router)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) batadv_neigh_node_put(router);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) if (neigh_ifinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) batadv_neigh_ifinfo_put(neigh_ifinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) if (router_ifinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) batadv_neigh_ifinfo_put(router_ifinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) * batadv_iv_ogm_calc_tq() - calculate tq for current received ogm packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) * @orig_node: the orig node who originally emitted the ogm packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) * @orig_neigh_node: the orig node struct of the neighbor who sent the packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) * @batadv_ogm_packet: the ogm packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) * @if_incoming: interface where the packet was received
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) * @if_outgoing: interface for which the retransmission should be considered
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) * Return: true if the link can be considered bidirectional, false otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) static bool batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) struct batadv_orig_node *orig_neigh_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) struct batadv_ogm_packet *batadv_ogm_packet,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) struct batadv_hard_iface *if_incoming,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) struct batadv_hard_iface *if_outgoing)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) struct batadv_neigh_node *neigh_node = NULL, *tmp_neigh_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) struct batadv_neigh_ifinfo *neigh_ifinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) u8 total_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) u8 orig_eq_count, neigh_rq_count, neigh_rq_inv, tq_own;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) unsigned int tq_iface_hop_penalty = BATADV_TQ_MAX_VALUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) unsigned int neigh_rq_inv_cube, neigh_rq_max_cube;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) unsigned int tq_asym_penalty, inv_asym_penalty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) unsigned int combined_tq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) bool ret = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) /* find corresponding one hop neighbor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) hlist_for_each_entry_rcu(tmp_neigh_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) &orig_neigh_node->neigh_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) if (!batadv_compare_eth(tmp_neigh_node->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) orig_neigh_node->orig))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) if (tmp_neigh_node->if_incoming != if_incoming)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) if (!kref_get_unless_zero(&tmp_neigh_node->refcount))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) neigh_node = tmp_neigh_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) if (!neigh_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) neigh_node = batadv_iv_ogm_neigh_new(if_incoming,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) orig_neigh_node->orig,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) orig_neigh_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) orig_neigh_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) if (!neigh_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) /* if orig_node is direct neighbor update neigh_node last_seen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) if (orig_node == orig_neigh_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) neigh_node->last_seen = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) orig_node->last_seen = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) /* find packet count of corresponding one hop neighbor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) orig_eq_count = batadv_iv_orig_ifinfo_sum(orig_neigh_node, if_incoming);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) neigh_ifinfo = batadv_neigh_ifinfo_new(neigh_node, if_outgoing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) if (neigh_ifinfo) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) neigh_rq_count = neigh_ifinfo->bat_iv.real_packet_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) batadv_neigh_ifinfo_put(neigh_ifinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) neigh_rq_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) /* pay attention to not get a value bigger than 100 % */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) if (orig_eq_count > neigh_rq_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) total_count = neigh_rq_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) total_count = orig_eq_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) /* if we have too few packets (too less data) we set tq_own to zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) * if we receive too few packets it is not considered bidirectional
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) if (total_count < BATADV_TQ_LOCAL_BIDRECT_SEND_MINIMUM ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) neigh_rq_count < BATADV_TQ_LOCAL_BIDRECT_RECV_MINIMUM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) tq_own = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) /* neigh_node->real_packet_count is never zero as we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) * only purge old information when getting new
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) * information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) tq_own = (BATADV_TQ_MAX_VALUE * total_count) / neigh_rq_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) /* 1 - ((1-x) ** 3), normalized to TQ_MAX_VALUE this does
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) * affect the nearly-symmetric links only a little, but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) * punishes asymmetric links more. This will give a value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) * between 0 and TQ_MAX_VALUE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) neigh_rq_inv = BATADV_TQ_LOCAL_WINDOW_SIZE - neigh_rq_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) neigh_rq_inv_cube = neigh_rq_inv * neigh_rq_inv * neigh_rq_inv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) neigh_rq_max_cube = BATADV_TQ_LOCAL_WINDOW_SIZE *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) BATADV_TQ_LOCAL_WINDOW_SIZE *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) BATADV_TQ_LOCAL_WINDOW_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) inv_asym_penalty = BATADV_TQ_MAX_VALUE * neigh_rq_inv_cube;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) inv_asym_penalty /= neigh_rq_max_cube;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) tq_asym_penalty = BATADV_TQ_MAX_VALUE - inv_asym_penalty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) tq_iface_hop_penalty -= atomic_read(&if_incoming->hop_penalty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) /* penalize if the OGM is forwarded on the same interface. WiFi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) * interfaces and other half duplex devices suffer from throughput
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) * drops as they can't send and receive at the same time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) if (if_outgoing && if_incoming == if_outgoing &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) batadv_is_wifi_hardif(if_outgoing))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) tq_iface_hop_penalty = batadv_hop_penalty(tq_iface_hop_penalty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) combined_tq = batadv_ogm_packet->tq *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) tq_own *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) tq_asym_penalty *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) tq_iface_hop_penalty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) combined_tq /= BATADV_TQ_MAX_VALUE *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) BATADV_TQ_MAX_VALUE *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) BATADV_TQ_MAX_VALUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) batadv_ogm_packet->tq = combined_tq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) "bidirectional: orig = %pM neigh = %pM => own_bcast = %2i, real recv = %2i, local tq: %3i, asym_penalty: %3i, iface_hop_penalty: %3i, total tq: %3i, if_incoming = %s, if_outgoing = %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) orig_node->orig, orig_neigh_node->orig, total_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) neigh_rq_count, tq_own, tq_asym_penalty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) tq_iface_hop_penalty, batadv_ogm_packet->tq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) if_incoming->net_dev->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) if_outgoing ? if_outgoing->net_dev->name : "DEFAULT");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) /* if link has the minimum required transmission quality
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) * consider it bidirectional
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) if (batadv_ogm_packet->tq >= BATADV_TQ_TOTAL_BIDRECT_LIMIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) ret = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) if (neigh_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) batadv_neigh_node_put(neigh_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) * batadv_iv_ogm_update_seqnos() - process a batman packet for all interfaces,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) * adjust the sequence number and find out whether it is a duplicate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) * @ethhdr: ethernet header of the packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) * @batadv_ogm_packet: OGM packet to be considered
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) * @if_incoming: interface on which the OGM packet was received
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) * @if_outgoing: interface for which the retransmission should be considered
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) * Return: duplicate status as enum batadv_dup_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) static enum batadv_dup_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) const struct batadv_ogm_packet *batadv_ogm_packet,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) const struct batadv_hard_iface *if_incoming,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) struct batadv_hard_iface *if_outgoing)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) struct batadv_orig_node *orig_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) struct batadv_orig_ifinfo *orig_ifinfo = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) struct batadv_neigh_node *neigh_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) struct batadv_neigh_ifinfo *neigh_ifinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) bool is_dup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) s32 seq_diff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) bool need_update = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) int set_mark;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) enum batadv_dup_status ret = BATADV_NO_DUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) u32 seqno = ntohl(batadv_ogm_packet->seqno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) u8 *neigh_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) u8 packet_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) unsigned long *bitmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) orig_node = batadv_iv_ogm_orig_get(bat_priv, batadv_ogm_packet->orig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) if (!orig_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) return BATADV_NO_DUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) orig_ifinfo = batadv_orig_ifinfo_new(orig_node, if_outgoing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) if (WARN_ON(!orig_ifinfo)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) batadv_orig_node_put(orig_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) seq_diff = seqno - orig_ifinfo->last_real_seqno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) /* signalize caller that the packet is to be dropped. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) if (!hlist_empty(&orig_node->neigh_list) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) batadv_window_protected(bat_priv, seq_diff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) BATADV_TQ_LOCAL_WINDOW_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) &orig_ifinfo->batman_seqno_reset, NULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) ret = BATADV_PROTECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) hlist_for_each_entry_rcu(neigh_node, &orig_node->neigh_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) neigh_ifinfo = batadv_neigh_ifinfo_new(neigh_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) if_outgoing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) if (!neigh_ifinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) neigh_addr = neigh_node->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) is_dup = batadv_test_bit(neigh_ifinfo->bat_iv.real_bits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) orig_ifinfo->last_real_seqno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) seqno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) if (batadv_compare_eth(neigh_addr, ethhdr->h_source) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) neigh_node->if_incoming == if_incoming) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) set_mark = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) if (is_dup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) ret = BATADV_NEIGH_DUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) set_mark = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) if (is_dup && ret != BATADV_NEIGH_DUP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) ret = BATADV_ORIG_DUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) /* if the window moved, set the update flag. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) bitmap = neigh_ifinfo->bat_iv.real_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) need_update |= batadv_bit_get_packet(bat_priv, bitmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) seq_diff, set_mark);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) packet_count = bitmap_weight(bitmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) BATADV_TQ_LOCAL_WINDOW_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) neigh_ifinfo->bat_iv.real_packet_count = packet_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) batadv_neigh_ifinfo_put(neigh_ifinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) if (need_update) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) "%s updating last_seqno: old %u, new %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) if_outgoing ? if_outgoing->net_dev->name : "DEFAULT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) orig_ifinfo->last_real_seqno, seqno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) orig_ifinfo->last_real_seqno = seqno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) spin_unlock_bh(&orig_node->bat_iv.ogm_cnt_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) batadv_orig_node_put(orig_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) batadv_orig_ifinfo_put(orig_ifinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) * batadv_iv_ogm_process_per_outif() - process a batman iv OGM for an outgoing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) * interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) * @skb: the skb containing the OGM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) * @ogm_offset: offset from skb->data to start of ogm header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) * @orig_node: the (cached) orig node for the originator of this OGM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) * @if_incoming: the interface where this packet was received
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) * @if_outgoing: the interface for which the packet should be considered
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) batadv_iv_ogm_process_per_outif(const struct sk_buff *skb, int ogm_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) struct batadv_orig_node *orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) struct batadv_hard_iface *if_incoming,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) struct batadv_hard_iface *if_outgoing)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) struct batadv_hardif_neigh_node *hardif_neigh = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) struct batadv_neigh_node *router = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) struct batadv_neigh_node *router_router = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) struct batadv_orig_node *orig_neigh_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) struct batadv_orig_ifinfo *orig_ifinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) struct batadv_neigh_node *orig_neigh_router = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) struct batadv_neigh_ifinfo *router_ifinfo = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) struct batadv_ogm_packet *ogm_packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) enum batadv_dup_status dup_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) bool is_from_best_next_hop = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) bool is_single_hop_neigh = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) bool sameseq, similar_ttl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) struct sk_buff *skb_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) struct ethhdr *ethhdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) u8 *prev_sender;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) bool is_bidirect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) /* create a private copy of the skb, as some functions change tq value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) * and/or flags.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) skb_priv = skb_copy(skb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) if (!skb_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) ethhdr = eth_hdr(skb_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) ogm_packet = (struct batadv_ogm_packet *)(skb_priv->data + ogm_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) dup_status = batadv_iv_ogm_update_seqnos(ethhdr, ogm_packet,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) if_incoming, if_outgoing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) if (batadv_compare_eth(ethhdr->h_source, ogm_packet->orig))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) is_single_hop_neigh = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) if (dup_status == BATADV_PROTECTED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) "Drop packet: packet within seqno protection time (sender: %pM)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) ethhdr->h_source);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) if (ogm_packet->tq == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) "Drop packet: originator packet with tq equal 0\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) if (is_single_hop_neigh) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) hardif_neigh = batadv_hardif_neigh_get(if_incoming,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) ethhdr->h_source);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) if (hardif_neigh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) hardif_neigh->last_seen = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) router = batadv_orig_router_get(orig_node, if_outgoing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) if (router) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) router_router = batadv_orig_router_get(router->orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) if_outgoing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) router_ifinfo = batadv_neigh_ifinfo_get(router, if_outgoing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) if ((router_ifinfo && router_ifinfo->bat_iv.tq_avg != 0) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) (batadv_compare_eth(router->addr, ethhdr->h_source)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) is_from_best_next_hop = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) prev_sender = ogm_packet->prev_sender;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) /* avoid temporary routing loops */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) if (router && router_router &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) (batadv_compare_eth(router->addr, prev_sender)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) !(batadv_compare_eth(ogm_packet->orig, prev_sender)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) (batadv_compare_eth(router->addr, router_router->addr))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) "Drop packet: ignoring all rebroadcast packets that may make me loop (sender: %pM)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) ethhdr->h_source);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) if (if_outgoing == BATADV_IF_DEFAULT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) batadv_tvlv_ogm_receive(bat_priv, ogm_packet, orig_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) /* if sender is a direct neighbor the sender mac equals
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) * originator mac
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) if (is_single_hop_neigh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) orig_neigh_node = orig_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) orig_neigh_node = batadv_iv_ogm_orig_get(bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) ethhdr->h_source);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) if (!orig_neigh_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) /* Update nc_nodes of the originator */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) batadv_nc_update_nc_node(bat_priv, orig_node, orig_neigh_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) ogm_packet, is_single_hop_neigh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) orig_neigh_router = batadv_orig_router_get(orig_neigh_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) if_outgoing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) /* drop packet if sender is not a direct neighbor and if we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) * don't route towards it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) if (!is_single_hop_neigh && !orig_neigh_router) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) "Drop packet: OGM via unknown neighbor!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) goto out_neigh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) is_bidirect = batadv_iv_ogm_calc_tq(orig_node, orig_neigh_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) ogm_packet, if_incoming,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) if_outgoing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) /* update ranking if it is not a duplicate or has the same
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) * seqno and similar ttl as the non-duplicate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) orig_ifinfo = batadv_orig_ifinfo_new(orig_node, if_outgoing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) if (!orig_ifinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) goto out_neigh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) sameseq = orig_ifinfo->last_real_seqno == ntohl(ogm_packet->seqno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) similar_ttl = (orig_ifinfo->last_ttl - 3) <= ogm_packet->ttl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) if (is_bidirect && (dup_status == BATADV_NO_DUP ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) (sameseq && similar_ttl))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) batadv_iv_ogm_orig_update(bat_priv, orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) orig_ifinfo, ethhdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) ogm_packet, if_incoming,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) if_outgoing, dup_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) batadv_orig_ifinfo_put(orig_ifinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) /* only forward for specific interface, not for the default one. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) if (if_outgoing == BATADV_IF_DEFAULT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) goto out_neigh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) /* is single hop (direct) neighbor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) if (is_single_hop_neigh) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) /* OGMs from secondary interfaces should only scheduled once
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) * per interface where it has been received, not multiple times
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) if (ogm_packet->ttl <= 2 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) if_incoming != if_outgoing) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) "Drop packet: OGM from secondary interface and wrong outgoing interface\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) goto out_neigh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) /* mark direct link on incoming interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) batadv_iv_ogm_forward(orig_node, ethhdr, ogm_packet,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) is_single_hop_neigh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) is_from_best_next_hop, if_incoming,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) if_outgoing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) "Forwarding packet: rebroadcast neighbor packet with direct link flag\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) goto out_neigh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) /* multihop originator */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) if (!is_bidirect) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) "Drop packet: not received via bidirectional link\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) goto out_neigh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) if (dup_status == BATADV_NEIGH_DUP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) "Drop packet: duplicate packet received\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) goto out_neigh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) "Forwarding packet: rebroadcast originator packet\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) batadv_iv_ogm_forward(orig_node, ethhdr, ogm_packet,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) is_single_hop_neigh, is_from_best_next_hop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) if_incoming, if_outgoing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) out_neigh:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) if (orig_neigh_node && !is_single_hop_neigh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) batadv_orig_node_put(orig_neigh_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) if (router_ifinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) batadv_neigh_ifinfo_put(router_ifinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) if (router)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) batadv_neigh_node_put(router);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) if (router_router)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) batadv_neigh_node_put(router_router);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) if (orig_neigh_router)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) batadv_neigh_node_put(orig_neigh_router);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) if (hardif_neigh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) batadv_hardif_neigh_put(hardif_neigh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) consume_skb(skb_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) * batadv_iv_ogm_process_reply() - Check OGM for direct reply and process it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) * @ogm_packet: rebroadcast OGM packet to process
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) * @if_incoming: the interface where this packet was received
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) * @orig_node: originator which reproadcasted the OGMs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) * @if_incoming_seqno: OGM sequence number when rebroadcast was received
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) static void batadv_iv_ogm_process_reply(struct batadv_ogm_packet *ogm_packet,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) struct batadv_hard_iface *if_incoming,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) struct batadv_orig_node *orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) u32 if_incoming_seqno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) struct batadv_orig_ifinfo *orig_ifinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) s32 bit_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) u8 *weight;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) /* neighbor has to indicate direct link and it has to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) * come via the corresponding interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) if (!(ogm_packet->flags & BATADV_DIRECTLINK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) if (!batadv_compare_eth(if_incoming->net_dev->dev_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) ogm_packet->orig))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) orig_ifinfo = batadv_orig_ifinfo_get(orig_node, if_incoming);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) if (!orig_ifinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) /* save packet seqno for bidirectional check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) bit_pos = if_incoming_seqno - 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) bit_pos -= ntohl(ogm_packet->seqno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) batadv_set_bit(orig_ifinfo->bat_iv.bcast_own, bit_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) weight = &orig_ifinfo->bat_iv.bcast_own_sum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) *weight = bitmap_weight(orig_ifinfo->bat_iv.bcast_own,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) BATADV_TQ_LOCAL_WINDOW_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) spin_unlock_bh(&orig_node->bat_iv.ogm_cnt_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) batadv_orig_ifinfo_put(orig_ifinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) * batadv_iv_ogm_process() - process an incoming batman iv OGM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) * @skb: the skb containing the OGM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) * @ogm_offset: offset to the OGM which should be processed (for aggregates)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) * @if_incoming: the interface where this packet was received
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) static void batadv_iv_ogm_process(const struct sk_buff *skb, int ogm_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) struct batadv_hard_iface *if_incoming)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) struct batadv_orig_node *orig_neigh_node, *orig_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) struct batadv_hard_iface *hard_iface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) struct batadv_ogm_packet *ogm_packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) u32 if_incoming_seqno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) bool has_directlink_flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) struct ethhdr *ethhdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) bool is_my_oldorig = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) bool is_my_addr = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) bool is_my_orig = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) ogm_packet = (struct batadv_ogm_packet *)(skb->data + ogm_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) ethhdr = eth_hdr(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) /* Silently drop when the batman packet is actually not a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) * correct packet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) * This might happen if a packet is padded (e.g. Ethernet has a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) * minimum frame length of 64 byte) and the aggregation interprets
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) * it as an additional length.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) * TODO: A more sane solution would be to have a bit in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) * batadv_ogm_packet to detect whether the packet is the last
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) * packet in an aggregation. Here we expect that the padding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) * is always zero (or not 0x01)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) if (ogm_packet->packet_type != BATADV_IV_OGM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) /* could be changed by schedule_own_packet() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) if_incoming_seqno = atomic_read(&if_incoming->bat_iv.ogm_seqno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) if (ogm_packet->flags & BATADV_DIRECTLINK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) has_directlink_flag = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) has_directlink_flag = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) "Received BATMAN packet via NB: %pM, IF: %s [%pM] (from OG: %pM, via prev OG: %pM, seqno %u, tq %d, TTL %d, V %d, IDF %d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) ethhdr->h_source, if_incoming->net_dev->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) if_incoming->net_dev->dev_addr, ogm_packet->orig,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) ogm_packet->prev_sender, ntohl(ogm_packet->seqno),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) ogm_packet->tq, ogm_packet->ttl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) ogm_packet->version, has_directlink_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) if (hard_iface->if_status != BATADV_IF_ACTIVE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) if (hard_iface->soft_iface != if_incoming->soft_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) if (batadv_compare_eth(ethhdr->h_source,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) hard_iface->net_dev->dev_addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) is_my_addr = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) if (batadv_compare_eth(ogm_packet->orig,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) hard_iface->net_dev->dev_addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) is_my_orig = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) if (batadv_compare_eth(ogm_packet->prev_sender,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) hard_iface->net_dev->dev_addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) is_my_oldorig = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) if (is_my_addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) "Drop packet: received my own broadcast (sender: %pM)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) ethhdr->h_source);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) if (is_my_orig) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) orig_neigh_node = batadv_iv_ogm_orig_get(bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) ethhdr->h_source);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) if (!orig_neigh_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) batadv_iv_ogm_process_reply(ogm_packet, if_incoming,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) orig_neigh_node, if_incoming_seqno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) "Drop packet: originator packet from myself (via neighbor)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) batadv_orig_node_put(orig_neigh_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) if (is_my_oldorig) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) "Drop packet: ignoring all rebroadcast echos (sender: %pM)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) ethhdr->h_source);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) if (ogm_packet->flags & BATADV_NOT_BEST_NEXT_HOP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) "Drop packet: ignoring all packets not forwarded from the best next hop (sender: %pM)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) ethhdr->h_source);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) orig_node = batadv_iv_ogm_orig_get(bat_priv, ogm_packet->orig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) if (!orig_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) batadv_iv_ogm_process_per_outif(skb, ogm_offset, orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) if_incoming, BATADV_IF_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) if (hard_iface->if_status != BATADV_IF_ACTIVE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) if (hard_iface->soft_iface != bat_priv->soft_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) if (!kref_get_unless_zero(&hard_iface->refcount))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) batadv_iv_ogm_process_per_outif(skb, ogm_offset, orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) if_incoming, hard_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) batadv_hardif_put(hard_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) batadv_orig_node_put(orig_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) static void batadv_iv_send_outstanding_bat_ogm_packet(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) struct delayed_work *delayed_work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) struct batadv_forw_packet *forw_packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) struct batadv_priv *bat_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) bool dropped = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) delayed_work = to_delayed_work(work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) forw_packet = container_of(delayed_work, struct batadv_forw_packet,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) delayed_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) bat_priv = netdev_priv(forw_packet->if_incoming->soft_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) dropped = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) batadv_iv_ogm_emit(forw_packet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) /* we have to have at least one packet in the queue to determine the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) * queues wake up time unless we are shutting down.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) * only re-schedule if this is the "original" copy, e.g. the OGM of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) * primary interface should only be rescheduled once per period, but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) * this function will be called for the forw_packet instances of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) * other secondary interfaces as well.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) if (forw_packet->own &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) forw_packet->if_incoming == forw_packet->if_outgoing)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) batadv_iv_ogm_schedule(forw_packet->if_incoming);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) /* do we get something for free()? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) if (batadv_forw_packet_steal(forw_packet,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) &bat_priv->forw_bat_list_lock))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) batadv_forw_packet_free(forw_packet, dropped);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) static int batadv_iv_ogm_receive(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) struct batadv_hard_iface *if_incoming)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) struct batadv_ogm_packet *ogm_packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) u8 *packet_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) int ogm_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) bool res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) int ret = NET_RX_DROP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) res = batadv_check_management_packet(skb, if_incoming, BATADV_OGM_HLEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) if (!res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) goto free_skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) /* did we receive a B.A.T.M.A.N. IV OGM packet on an interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) * that does not have B.A.T.M.A.N. IV enabled ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) if (bat_priv->algo_ops->iface.enable != batadv_iv_ogm_iface_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) goto free_skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) batadv_inc_counter(bat_priv, BATADV_CNT_MGMT_RX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) batadv_add_counter(bat_priv, BATADV_CNT_MGMT_RX_BYTES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) skb->len + ETH_HLEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) ogm_offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) ogm_packet = (struct batadv_ogm_packet *)skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) /* unpack the aggregated packets and process them one by one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) while (batadv_iv_ogm_aggr_packet(ogm_offset, skb_headlen(skb),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) ogm_packet)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) batadv_iv_ogm_process(skb, ogm_offset, if_incoming);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) ogm_offset += BATADV_OGM_HLEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) ogm_offset += ntohs(ogm_packet->tvlv_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) packet_pos = skb->data + ogm_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) ogm_packet = (struct batadv_ogm_packet *)packet_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) ret = NET_RX_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) free_skb:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) if (ret == NET_RX_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) consume_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) #ifdef CONFIG_BATMAN_ADV_DEBUGFS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) * batadv_iv_ogm_orig_print_neigh() - print neighbors for the originator table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) * @orig_node: the orig_node for which the neighbors are printed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) * @if_outgoing: outgoing interface for these entries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) * @seq: debugfs table seq_file struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) * Must be called while holding an rcu lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) batadv_iv_ogm_orig_print_neigh(struct batadv_orig_node *orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) struct batadv_hard_iface *if_outgoing,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) struct seq_file *seq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) struct batadv_neigh_node *neigh_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) struct batadv_neigh_ifinfo *n_ifinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) hlist_for_each_entry_rcu(neigh_node, &orig_node->neigh_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) n_ifinfo = batadv_neigh_ifinfo_get(neigh_node, if_outgoing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) if (!n_ifinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) seq_printf(seq, " %pM (%3i)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) neigh_node->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) n_ifinfo->bat_iv.tq_avg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) batadv_neigh_ifinfo_put(n_ifinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) * batadv_iv_ogm_orig_print() - print the originator table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) * @seq: debugfs table seq_file struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) * @if_outgoing: the outgoing interface for which this should be printed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) static void batadv_iv_ogm_orig_print(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) struct seq_file *seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) struct batadv_hard_iface *if_outgoing)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) struct batadv_neigh_node *neigh_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) struct batadv_hashtable *hash = bat_priv->orig_hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) int last_seen_msecs, last_seen_secs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) struct batadv_orig_node *orig_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) struct batadv_neigh_ifinfo *n_ifinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) unsigned long last_seen_jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) struct hlist_head *head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) int batman_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) u32 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) seq_puts(seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) " Originator last-seen (#/255) Nexthop [outgoingIF]: Potential nexthops ...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) for (i = 0; i < hash->size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) head = &hash->table[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) neigh_node = batadv_orig_router_get(orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) if_outgoing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) if (!neigh_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) n_ifinfo = batadv_neigh_ifinfo_get(neigh_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) if_outgoing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) if (!n_ifinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) goto next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) if (n_ifinfo->bat_iv.tq_avg == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) goto next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) last_seen_jiffies = jiffies - orig_node->last_seen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) last_seen_msecs = jiffies_to_msecs(last_seen_jiffies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) last_seen_secs = last_seen_msecs / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) last_seen_msecs = last_seen_msecs % 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) seq_printf(seq, "%pM %4i.%03is (%3i) %pM [%10s]:",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) orig_node->orig, last_seen_secs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) last_seen_msecs, n_ifinfo->bat_iv.tq_avg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) neigh_node->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) neigh_node->if_incoming->net_dev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) batadv_iv_ogm_orig_print_neigh(orig_node, if_outgoing,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) seq_putc(seq, '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) batman_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) next:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) batadv_neigh_node_put(neigh_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) if (n_ifinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) batadv_neigh_ifinfo_put(n_ifinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) if (batman_count == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) seq_puts(seq, "No batman nodes in range ...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) * batadv_iv_ogm_neigh_get_tq_avg() - Get the TQ average for a neighbour on a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) * given outgoing interface.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) * @neigh_node: Neighbour of interest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) * @if_outgoing: Outgoing interface of interest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) * @tq_avg: Pointer of where to store the TQ average
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) * Return: False if no average TQ available, otherwise true.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) static bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) batadv_iv_ogm_neigh_get_tq_avg(struct batadv_neigh_node *neigh_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) struct batadv_hard_iface *if_outgoing,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) u8 *tq_avg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) struct batadv_neigh_ifinfo *n_ifinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) n_ifinfo = batadv_neigh_ifinfo_get(neigh_node, if_outgoing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) if (!n_ifinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) *tq_avg = n_ifinfo->bat_iv.tq_avg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) batadv_neigh_ifinfo_put(n_ifinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) * batadv_iv_ogm_orig_dump_subentry() - Dump an originator subentry into a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) * message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) * @msg: Netlink message to dump into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) * @portid: Port making netlink request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) * @seq: Sequence number of netlink message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) * @bat_priv: The bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) * @if_outgoing: Limit dump to entries with this outgoing interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) * @orig_node: Originator to dump
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) * @neigh_node: Single hops neighbour
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) * @best: Is the best originator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) * Return: Error code, or 0 on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) batadv_iv_ogm_orig_dump_subentry(struct sk_buff *msg, u32 portid, u32 seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) struct batadv_hard_iface *if_outgoing,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) struct batadv_orig_node *orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) struct batadv_neigh_node *neigh_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) bool best)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) u8 tq_avg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) unsigned int last_seen_msecs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) last_seen_msecs = jiffies_to_msecs(jiffies - orig_node->last_seen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) if (!batadv_iv_ogm_neigh_get_tq_avg(neigh_node, if_outgoing, &tq_avg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) if (if_outgoing != BATADV_IF_DEFAULT &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) if_outgoing != neigh_node->if_incoming)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) hdr = genlmsg_put(msg, portid, seq, &batadv_netlink_family,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) NLM_F_MULTI, BATADV_CMD_GET_ORIGINATORS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) if (nla_put(msg, BATADV_ATTR_ORIG_ADDRESS, ETH_ALEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) orig_node->orig) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) nla_put(msg, BATADV_ATTR_NEIGH_ADDRESS, ETH_ALEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) neigh_node->addr) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) nla_put_u32(msg, BATADV_ATTR_HARD_IFINDEX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) neigh_node->if_incoming->net_dev->ifindex) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) nla_put_u8(msg, BATADV_ATTR_TQ, tq_avg) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) nla_put_u32(msg, BATADV_ATTR_LAST_SEEN_MSECS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) last_seen_msecs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) if (best && nla_put_flag(msg, BATADV_ATTR_FLAG_BEST))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) genlmsg_cancel(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) * batadv_iv_ogm_orig_dump_entry() - Dump an originator entry into a message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) * @msg: Netlink message to dump into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) * @portid: Port making netlink request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) * @seq: Sequence number of netlink message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) * @bat_priv: The bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) * @if_outgoing: Limit dump to entries with this outgoing interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) * @orig_node: Originator to dump
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) * @sub_s: Number of sub entries to skip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) * This function assumes the caller holds rcu_read_lock().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) * Return: Error code, or 0 on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) batadv_iv_ogm_orig_dump_entry(struct sk_buff *msg, u32 portid, u32 seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) struct batadv_hard_iface *if_outgoing,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) struct batadv_orig_node *orig_node, int *sub_s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) struct batadv_neigh_node *neigh_node_best;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) struct batadv_neigh_node *neigh_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) int sub = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) bool best;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) u8 tq_avg_best;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) neigh_node_best = batadv_orig_router_get(orig_node, if_outgoing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) if (!neigh_node_best)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) if (!batadv_iv_ogm_neigh_get_tq_avg(neigh_node_best, if_outgoing,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) &tq_avg_best))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) if (tq_avg_best == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) hlist_for_each_entry_rcu(neigh_node, &orig_node->neigh_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) if (sub++ < *sub_s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) best = (neigh_node == neigh_node_best);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) if (batadv_iv_ogm_orig_dump_subentry(msg, portid, seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) bat_priv, if_outgoing,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) orig_node, neigh_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) best)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) batadv_neigh_node_put(neigh_node_best);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) *sub_s = sub - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) if (neigh_node_best)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) batadv_neigh_node_put(neigh_node_best);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) *sub_s = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) * batadv_iv_ogm_orig_dump_bucket() - Dump an originator bucket into a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) * message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) * @msg: Netlink message to dump into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) * @portid: Port making netlink request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) * @seq: Sequence number of netlink message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) * @bat_priv: The bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) * @if_outgoing: Limit dump to entries with this outgoing interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) * @head: Bucket to be dumped
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) * @idx_s: Number of entries to be skipped
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) * @sub: Number of sub entries to be skipped
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) * Return: Error code, or 0 on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) batadv_iv_ogm_orig_dump_bucket(struct sk_buff *msg, u32 portid, u32 seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) struct batadv_hard_iface *if_outgoing,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) struct hlist_head *head, int *idx_s, int *sub)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) struct batadv_orig_node *orig_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) int idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) if (idx++ < *idx_s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) if (batadv_iv_ogm_orig_dump_entry(msg, portid, seq, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) if_outgoing, orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) sub)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) *idx_s = idx - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) *idx_s = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) *sub = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) * batadv_iv_ogm_orig_dump() - Dump the originators into a message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) * @msg: Netlink message to dump into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) * @cb: Control block containing additional options
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) * @bat_priv: The bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) * @if_outgoing: Limit dump to entries with this outgoing interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) batadv_iv_ogm_orig_dump(struct sk_buff *msg, struct netlink_callback *cb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) struct batadv_hard_iface *if_outgoing)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) struct batadv_hashtable *hash = bat_priv->orig_hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) struct hlist_head *head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) int bucket = cb->args[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) int idx = cb->args[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) int sub = cb->args[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) int portid = NETLINK_CB(cb->skb).portid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) while (bucket < hash->size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) head = &hash->table[bucket];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) if (batadv_iv_ogm_orig_dump_bucket(msg, portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) cb->nlh->nlmsg_seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) bat_priv, if_outgoing, head,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) &idx, &sub))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) bucket++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) cb->args[0] = bucket;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) cb->args[1] = idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) cb->args[2] = sub;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) #ifdef CONFIG_BATMAN_ADV_DEBUGFS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) * batadv_iv_hardif_neigh_print() - print a single hop neighbour node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) * @seq: neighbour table seq_file struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) * @hardif_neigh: hardif neighbour information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) batadv_iv_hardif_neigh_print(struct seq_file *seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) struct batadv_hardif_neigh_node *hardif_neigh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) int last_secs, last_msecs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) last_secs = jiffies_to_msecs(jiffies - hardif_neigh->last_seen) / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) last_msecs = jiffies_to_msecs(jiffies - hardif_neigh->last_seen) % 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) seq_printf(seq, " %10s %pM %4i.%03is\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) hardif_neigh->if_incoming->net_dev->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) hardif_neigh->addr, last_secs, last_msecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) * batadv_iv_ogm_neigh_print() - print the single hop neighbour list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) * @seq: neighbour table seq_file struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) static void batadv_iv_neigh_print(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) struct seq_file *seq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) struct net_device *net_dev = (struct net_device *)seq->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) struct batadv_hardif_neigh_node *hardif_neigh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) struct batadv_hard_iface *hard_iface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) int batman_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) seq_puts(seq, " IF Neighbor last-seen\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) if (hard_iface->soft_iface != net_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) hlist_for_each_entry_rcu(hardif_neigh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) &hard_iface->neigh_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) batadv_iv_hardif_neigh_print(seq, hardif_neigh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) batman_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) if (batman_count == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) seq_puts(seq, "No batman nodes in range ...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) * batadv_iv_ogm_neigh_diff() - calculate tq difference of two neighbors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) * @neigh1: the first neighbor object of the comparison
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) * @if_outgoing1: outgoing interface for the first neighbor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) * @neigh2: the second neighbor object of the comparison
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) * @if_outgoing2: outgoing interface for the second neighbor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) * @diff: pointer to integer receiving the calculated difference
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) * The content of *@diff is only valid when this function returns true.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) * It is less, equal to or greater than 0 if the metric via neigh1 is lower,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) * the same as or higher than the metric via neigh2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) * Return: true when the difference could be calculated, false otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) static bool batadv_iv_ogm_neigh_diff(struct batadv_neigh_node *neigh1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) struct batadv_hard_iface *if_outgoing1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) struct batadv_neigh_node *neigh2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) struct batadv_hard_iface *if_outgoing2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) int *diff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) struct batadv_neigh_ifinfo *neigh1_ifinfo, *neigh2_ifinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) u8 tq1, tq2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) bool ret = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) neigh1_ifinfo = batadv_neigh_ifinfo_get(neigh1, if_outgoing1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) neigh2_ifinfo = batadv_neigh_ifinfo_get(neigh2, if_outgoing2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) if (!neigh1_ifinfo || !neigh2_ifinfo) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) ret = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) tq1 = neigh1_ifinfo->bat_iv.tq_avg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) tq2 = neigh2_ifinfo->bat_iv.tq_avg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) *diff = (int)tq1 - (int)tq2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) if (neigh1_ifinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) batadv_neigh_ifinfo_put(neigh1_ifinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) if (neigh2_ifinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) batadv_neigh_ifinfo_put(neigh2_ifinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) * batadv_iv_ogm_neigh_dump_neigh() - Dump a neighbour into a netlink message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) * @msg: Netlink message to dump into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) * @portid: Port making netlink request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) * @seq: Sequence number of netlink message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) * @hardif_neigh: Neighbour to be dumped
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) * Return: Error code, or 0 on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) batadv_iv_ogm_neigh_dump_neigh(struct sk_buff *msg, u32 portid, u32 seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) struct batadv_hardif_neigh_node *hardif_neigh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) unsigned int last_seen_msecs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) last_seen_msecs = jiffies_to_msecs(jiffies - hardif_neigh->last_seen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) hdr = genlmsg_put(msg, portid, seq, &batadv_netlink_family,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) NLM_F_MULTI, BATADV_CMD_GET_NEIGHBORS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) if (nla_put(msg, BATADV_ATTR_NEIGH_ADDRESS, ETH_ALEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) hardif_neigh->addr) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) nla_put_u32(msg, BATADV_ATTR_HARD_IFINDEX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) hardif_neigh->if_incoming->net_dev->ifindex) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) nla_put_u32(msg, BATADV_ATTR_LAST_SEEN_MSECS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) last_seen_msecs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) genlmsg_cancel(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) * batadv_iv_ogm_neigh_dump_hardif() - Dump the neighbours of a hard interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) * into a message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) * @msg: Netlink message to dump into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) * @portid: Port making netlink request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) * @seq: Sequence number of netlink message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) * @bat_priv: The bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) * @hard_iface: Hard interface to dump the neighbours for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) * @idx_s: Number of entries to skip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) * This function assumes the caller holds rcu_read_lock().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) * Return: Error code, or 0 on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) batadv_iv_ogm_neigh_dump_hardif(struct sk_buff *msg, u32 portid, u32 seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) struct batadv_hard_iface *hard_iface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) int *idx_s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) struct batadv_hardif_neigh_node *hardif_neigh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) int idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) hlist_for_each_entry_rcu(hardif_neigh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) &hard_iface->neigh_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) if (idx++ < *idx_s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) if (batadv_iv_ogm_neigh_dump_neigh(msg, portid, seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) hardif_neigh)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) *idx_s = idx - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) *idx_s = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) * batadv_iv_ogm_neigh_dump() - Dump the neighbours into a message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) * @msg: Netlink message to dump into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) * @cb: Control block containing additional options
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) * @bat_priv: The bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) * @single_hardif: Limit dump to this hard interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) batadv_iv_ogm_neigh_dump(struct sk_buff *msg, struct netlink_callback *cb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) struct batadv_hard_iface *single_hardif)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) struct batadv_hard_iface *hard_iface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) int i_hardif = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) int i_hardif_s = cb->args[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) int idx = cb->args[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) int portid = NETLINK_CB(cb->skb).portid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) if (single_hardif) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) if (i_hardif_s == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) if (batadv_iv_ogm_neigh_dump_hardif(msg, portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) cb->nlh->nlmsg_seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) single_hardif,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) &idx) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) i_hardif++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) list_for_each_entry_rcu(hard_iface, &batadv_hardif_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) if (hard_iface->soft_iface != bat_priv->soft_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) if (i_hardif++ < i_hardif_s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) if (batadv_iv_ogm_neigh_dump_hardif(msg, portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) cb->nlh->nlmsg_seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) hard_iface, &idx)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) i_hardif--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) cb->args[0] = i_hardif;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) cb->args[1] = idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) * batadv_iv_ogm_neigh_cmp() - compare the metrics of two neighbors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) * @neigh1: the first neighbor object of the comparison
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) * @if_outgoing1: outgoing interface for the first neighbor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) * @neigh2: the second neighbor object of the comparison
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) * @if_outgoing2: outgoing interface for the second neighbor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) * Return: a value less, equal to or greater than 0 if the metric via neigh1 is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) * lower, the same as or higher than the metric via neigh2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) static int batadv_iv_ogm_neigh_cmp(struct batadv_neigh_node *neigh1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) struct batadv_hard_iface *if_outgoing1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) struct batadv_neigh_node *neigh2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) struct batadv_hard_iface *if_outgoing2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) bool ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) int diff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) ret = batadv_iv_ogm_neigh_diff(neigh1, if_outgoing1, neigh2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) if_outgoing2, &diff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) return diff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) * batadv_iv_ogm_neigh_is_sob() - check if neigh1 is similarly good or better
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) * than neigh2 from the metric prospective
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) * @neigh1: the first neighbor object of the comparison
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) * @if_outgoing1: outgoing interface for the first neighbor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) * @neigh2: the second neighbor object of the comparison
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) * @if_outgoing2: outgoing interface for the second neighbor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) * Return: true if the metric via neigh1 is equally good or better than
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) * the metric via neigh2, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) static bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) batadv_iv_ogm_neigh_is_sob(struct batadv_neigh_node *neigh1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) struct batadv_hard_iface *if_outgoing1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) struct batadv_neigh_node *neigh2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) struct batadv_hard_iface *if_outgoing2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) bool ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) int diff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) ret = batadv_iv_ogm_neigh_diff(neigh1, if_outgoing1, neigh2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) if_outgoing2, &diff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) ret = diff > -BATADV_TQ_SIMILARITY_THRESHOLD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) static void batadv_iv_iface_enabled(struct batadv_hard_iface *hard_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) /* begin scheduling originator messages on that interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) batadv_iv_ogm_schedule(hard_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) * batadv_iv_init_sel_class() - initialize GW selection class
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) static void batadv_iv_init_sel_class(struct batadv_priv *bat_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) /* set default TQ difference threshold to 20 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) atomic_set(&bat_priv->gw.sel_class, 20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) static struct batadv_gw_node *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) batadv_iv_gw_get_best_gw_node(struct batadv_priv *bat_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) struct batadv_neigh_node *router;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) struct batadv_neigh_ifinfo *router_ifinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) struct batadv_gw_node *gw_node, *curr_gw = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) u64 max_gw_factor = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) u64 tmp_gw_factor = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) u8 max_tq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) u8 tq_avg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) struct batadv_orig_node *orig_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) hlist_for_each_entry_rcu(gw_node, &bat_priv->gw.gateway_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) orig_node = gw_node->orig_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) router = batadv_orig_router_get(orig_node, BATADV_IF_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) if (!router)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) router_ifinfo = batadv_neigh_ifinfo_get(router,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) BATADV_IF_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) if (!router_ifinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) goto next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) if (!kref_get_unless_zero(&gw_node->refcount))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) goto next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) tq_avg = router_ifinfo->bat_iv.tq_avg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) switch (atomic_read(&bat_priv->gw.sel_class)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) case 1: /* fast connection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) tmp_gw_factor = tq_avg * tq_avg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) tmp_gw_factor *= gw_node->bandwidth_down;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) tmp_gw_factor *= 100 * 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) tmp_gw_factor >>= 18;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) if (tmp_gw_factor > max_gw_factor ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) (tmp_gw_factor == max_gw_factor &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) tq_avg > max_tq)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) if (curr_gw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) batadv_gw_node_put(curr_gw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) curr_gw = gw_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) kref_get(&curr_gw->refcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) default: /* 2: stable connection (use best statistic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) * 3: fast-switch (use best statistic but change as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) * soon as a better gateway appears)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) * XX: late-switch (use best statistic but change as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) * soon as a better gateway appears which has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) * $routing_class more tq points)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) if (tq_avg > max_tq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) if (curr_gw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) batadv_gw_node_put(curr_gw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) curr_gw = gw_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) kref_get(&curr_gw->refcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) if (tq_avg > max_tq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) max_tq = tq_avg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) if (tmp_gw_factor > max_gw_factor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) max_gw_factor = tmp_gw_factor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) batadv_gw_node_put(gw_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) next:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) batadv_neigh_node_put(router);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) if (router_ifinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) batadv_neigh_ifinfo_put(router_ifinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) return curr_gw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) static bool batadv_iv_gw_is_eligible(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) struct batadv_orig_node *curr_gw_orig,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) struct batadv_orig_node *orig_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) struct batadv_neigh_ifinfo *router_orig_ifinfo = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) struct batadv_neigh_ifinfo *router_gw_ifinfo = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) struct batadv_neigh_node *router_gw = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) struct batadv_neigh_node *router_orig = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) u8 gw_tq_avg, orig_tq_avg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) bool ret = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) /* dynamic re-election is performed only on fast or late switch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) if (atomic_read(&bat_priv->gw.sel_class) <= 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) router_gw = batadv_orig_router_get(curr_gw_orig, BATADV_IF_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) if (!router_gw) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) ret = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) router_gw_ifinfo = batadv_neigh_ifinfo_get(router_gw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) BATADV_IF_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) if (!router_gw_ifinfo) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) ret = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) router_orig = batadv_orig_router_get(orig_node, BATADV_IF_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) if (!router_orig)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) router_orig_ifinfo = batadv_neigh_ifinfo_get(router_orig,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) BATADV_IF_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) if (!router_orig_ifinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) gw_tq_avg = router_gw_ifinfo->bat_iv.tq_avg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) orig_tq_avg = router_orig_ifinfo->bat_iv.tq_avg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) /* the TQ value has to be better */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) if (orig_tq_avg < gw_tq_avg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) /* if the routing class is greater than 3 the value tells us how much
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) * greater the TQ value of the new gateway must be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) if ((atomic_read(&bat_priv->gw.sel_class) > 3) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) (orig_tq_avg - gw_tq_avg < atomic_read(&bat_priv->gw.sel_class)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) "Restarting gateway selection: better gateway found (tq curr: %i, tq new: %i)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) gw_tq_avg, orig_tq_avg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) ret = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) if (router_gw_ifinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) batadv_neigh_ifinfo_put(router_gw_ifinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) if (router_orig_ifinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) batadv_neigh_ifinfo_put(router_orig_ifinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) if (router_gw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) batadv_neigh_node_put(router_gw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) if (router_orig)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) batadv_neigh_node_put(router_orig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) #ifdef CONFIG_BATMAN_ADV_DEBUGFS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) /* fails if orig_node has no router */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) static int batadv_iv_gw_write_buffer_text(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) struct seq_file *seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) const struct batadv_gw_node *gw_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) struct batadv_gw_node *curr_gw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) struct batadv_neigh_node *router;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) struct batadv_neigh_ifinfo *router_ifinfo = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) int ret = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) router = batadv_orig_router_get(gw_node->orig_node, BATADV_IF_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) if (!router)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) router_ifinfo = batadv_neigh_ifinfo_get(router, BATADV_IF_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) if (!router_ifinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) curr_gw = batadv_gw_get_selected_gw_node(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) seq_printf(seq, "%s %pM (%3i) %pM [%10s]: %u.%u/%u.%u MBit\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) (curr_gw == gw_node ? "=>" : " "),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) gw_node->orig_node->orig,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) router_ifinfo->bat_iv.tq_avg, router->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) router->if_incoming->net_dev->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) gw_node->bandwidth_down / 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) gw_node->bandwidth_down % 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) gw_node->bandwidth_up / 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) gw_node->bandwidth_up % 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) ret = seq_has_overflowed(seq) ? -1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) if (curr_gw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) batadv_gw_node_put(curr_gw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) if (router_ifinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) batadv_neigh_ifinfo_put(router_ifinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) if (router)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) batadv_neigh_node_put(router);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) static void batadv_iv_gw_print(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) struct seq_file *seq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) struct batadv_gw_node *gw_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) int gw_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) seq_puts(seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) " Gateway (#/255) Nexthop [outgoingIF]: advertised uplink bandwidth\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) hlist_for_each_entry_rcu(gw_node, &bat_priv->gw.gateway_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) /* fails if orig_node has no router */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) if (batadv_iv_gw_write_buffer_text(bat_priv, seq, gw_node) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) gw_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) if (gw_count == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) seq_puts(seq, "No gateways in range ...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) * batadv_iv_gw_dump_entry() - Dump a gateway into a message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) * @msg: Netlink message to dump into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) * @portid: Port making netlink request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) * @cb: Control block containing additional options
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) * @bat_priv: The bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) * @gw_node: Gateway to be dumped
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) * Return: Error code, or 0 on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) static int batadv_iv_gw_dump_entry(struct sk_buff *msg, u32 portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) struct netlink_callback *cb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) struct batadv_gw_node *gw_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) struct batadv_neigh_ifinfo *router_ifinfo = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) struct batadv_neigh_node *router;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) struct batadv_gw_node *curr_gw = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) router = batadv_orig_router_get(gw_node->orig_node, BATADV_IF_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) if (!router)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) router_ifinfo = batadv_neigh_ifinfo_get(router, BATADV_IF_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) if (!router_ifinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) curr_gw = batadv_gw_get_selected_gw_node(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) hdr = genlmsg_put(msg, portid, cb->nlh->nlmsg_seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) &batadv_netlink_family, NLM_F_MULTI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) BATADV_CMD_GET_GATEWAYS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) if (!hdr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) ret = -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) genl_dump_check_consistent(cb, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) ret = -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) if (curr_gw == gw_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) if (nla_put_flag(msg, BATADV_ATTR_FLAG_BEST)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) genlmsg_cancel(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) if (nla_put(msg, BATADV_ATTR_ORIG_ADDRESS, ETH_ALEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) gw_node->orig_node->orig) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) nla_put_u8(msg, BATADV_ATTR_TQ, router_ifinfo->bat_iv.tq_avg) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) nla_put(msg, BATADV_ATTR_ROUTER, ETH_ALEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) router->addr) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) nla_put_string(msg, BATADV_ATTR_HARD_IFNAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) router->if_incoming->net_dev->name) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) nla_put_u32(msg, BATADV_ATTR_BANDWIDTH_DOWN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) gw_node->bandwidth_down) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) nla_put_u32(msg, BATADV_ATTR_BANDWIDTH_UP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) gw_node->bandwidth_up)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) genlmsg_cancel(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) if (curr_gw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) batadv_gw_node_put(curr_gw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) if (router_ifinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) batadv_neigh_ifinfo_put(router_ifinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) if (router)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) batadv_neigh_node_put(router);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) * batadv_iv_gw_dump() - Dump gateways into a message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) * @msg: Netlink message to dump into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) * @cb: Control block containing additional options
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) * @bat_priv: The bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) static void batadv_iv_gw_dump(struct sk_buff *msg, struct netlink_callback *cb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) struct batadv_priv *bat_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) int portid = NETLINK_CB(cb->skb).portid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) struct batadv_gw_node *gw_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) int idx_skip = cb->args[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) int idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) spin_lock_bh(&bat_priv->gw.list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) cb->seq = bat_priv->gw.generation << 1 | 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) hlist_for_each_entry(gw_node, &bat_priv->gw.gateway_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) if (idx++ < idx_skip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) if (batadv_iv_gw_dump_entry(msg, portid, cb, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) gw_node)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) idx_skip = idx - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) idx_skip = idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) spin_unlock_bh(&bat_priv->gw.list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) cb->args[0] = idx_skip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) static struct batadv_algo_ops batadv_batman_iv __read_mostly = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) .name = "BATMAN_IV",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) .iface = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) .enable = batadv_iv_ogm_iface_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) .enabled = batadv_iv_iface_enabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) .disable = batadv_iv_ogm_iface_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) .update_mac = batadv_iv_ogm_iface_update_mac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) .primary_set = batadv_iv_ogm_primary_iface_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) .neigh = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) .cmp = batadv_iv_ogm_neigh_cmp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) .is_similar_or_better = batadv_iv_ogm_neigh_is_sob,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) #ifdef CONFIG_BATMAN_ADV_DEBUGFS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) .print = batadv_iv_neigh_print,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) .dump = batadv_iv_ogm_neigh_dump,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) .orig = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) #ifdef CONFIG_BATMAN_ADV_DEBUGFS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) .print = batadv_iv_ogm_orig_print,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) .dump = batadv_iv_ogm_orig_dump,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) .gw = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) .init_sel_class = batadv_iv_init_sel_class,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) .get_best_gw_node = batadv_iv_gw_get_best_gw_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) .is_eligible = batadv_iv_gw_is_eligible,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) #ifdef CONFIG_BATMAN_ADV_DEBUGFS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) .print = batadv_iv_gw_print,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) .dump = batadv_iv_gw_dump,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) * batadv_iv_init() - B.A.T.M.A.N. IV initialization function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) * Return: 0 on success or negative error number in case of failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) int __init batadv_iv_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) /* batman originator packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) ret = batadv_recv_handler_register(BATADV_IV_OGM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) batadv_iv_ogm_receive);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) ret = batadv_algo_register(&batadv_batman_iv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) goto handler_unregister;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) handler_unregister:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) batadv_recv_handler_unregister(BATADV_IV_OGM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) }