^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /* Copyright (C) 2013-2020 B.A.T.M.A.N. contributors:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Antonio Quartulli
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include "bat_v_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/byteorder/generic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/etherdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/gfp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/if_ether.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/jiffies.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/kref.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/lockdep.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/prandom.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/random.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/rculist.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/rcupdate.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/skbuff.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/stddef.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/workqueue.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <uapi/linux/batadv_packet.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include "bat_algo.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include "hard-interface.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include "hash.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include "log.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include "originator.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include "routing.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include "send.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include "translation-table.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include "tvlv.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * batadv_v_ogm_orig_get() - retrieve and possibly create an originator node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * @addr: the address of the originator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * Return: the orig_node corresponding to the specified address. If such an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * object does not exist, it is allocated here. In case of allocation failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * returns NULL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) struct batadv_orig_node *batadv_v_ogm_orig_get(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) const u8 *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) struct batadv_orig_node *orig_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) int hash_added;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) orig_node = batadv_orig_hash_find(bat_priv, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) if (orig_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) return orig_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) orig_node = batadv_orig_node_new(bat_priv, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) if (!orig_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) kref_get(&orig_node->refcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) hash_added = batadv_hash_add(bat_priv->orig_hash, batadv_compare_orig,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) batadv_choose_orig, orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) &orig_node->hash_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) if (hash_added != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) /* remove refcnt for newly created orig_node and hash entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) batadv_orig_node_put(orig_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) batadv_orig_node_put(orig_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) orig_node = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) return orig_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * batadv_v_ogm_start_queue_timer() - restart the OGM aggregation timer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * @hard_iface: the interface to use to send the OGM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) static void batadv_v_ogm_start_queue_timer(struct batadv_hard_iface *hard_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) unsigned int msecs = BATADV_MAX_AGGREGATION_MS * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) /* msecs * [0.9, 1.1] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) msecs += prandom_u32_max(msecs / 5) - (msecs / 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) queue_delayed_work(batadv_event_workqueue, &hard_iface->bat_v.aggr_wq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) msecs_to_jiffies(msecs / 1000));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) }
^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) * batadv_v_ogm_start_timer() - restart the OGM sending timer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) static void batadv_v_ogm_start_timer(struct batadv_priv *bat_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) unsigned long msecs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) /* this function may be invoked in different contexts (ogm rescheduling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * or hard_iface activation), but the work timer should not be reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) if (delayed_work_pending(&bat_priv->bat_v.ogm_wq))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) msecs = atomic_read(&bat_priv->orig_interval) - BATADV_JITTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) msecs += prandom_u32_max(2 * BATADV_JITTER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) queue_delayed_work(batadv_event_workqueue, &bat_priv->bat_v.ogm_wq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) msecs_to_jiffies(msecs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) * batadv_v_ogm_send_to_if() - send a batman ogm using a given interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) * @skb: the OGM to send
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) * @hard_iface: the interface to use to send the OGM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) static void batadv_v_ogm_send_to_if(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) struct batadv_hard_iface *hard_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) if (hard_iface->if_status != BATADV_IF_ACTIVE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) batadv_inc_counter(bat_priv, BATADV_CNT_MGMT_TX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) batadv_add_counter(bat_priv, BATADV_CNT_MGMT_TX_BYTES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) skb->len + ETH_HLEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) batadv_send_broadcast_skb(skb, hard_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) * batadv_v_ogm_len() - OGMv2 packet length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) * @skb: the OGM to check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) * Return: Length of the given OGMv2 packet, including tvlv length, excluding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) * ethernet header length.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) static unsigned int batadv_v_ogm_len(struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) struct batadv_ogm2_packet *ogm_packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) ogm_packet = (struct batadv_ogm2_packet *)skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) return BATADV_OGM2_HLEN + ntohs(ogm_packet->tvlv_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) * batadv_v_ogm_queue_left() - check if given OGM still fits aggregation queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) * @skb: the OGM to check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) * @hard_iface: the interface to use to send the OGM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) * Caller needs to hold the hard_iface->bat_v.aggr_list.lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) * Return: True, if the given OGMv2 packet still fits, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) static bool batadv_v_ogm_queue_left(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) struct batadv_hard_iface *hard_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) unsigned int max = min_t(unsigned int, hard_iface->net_dev->mtu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) BATADV_MAX_AGGREGATION_BYTES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) unsigned int ogm_len = batadv_v_ogm_len(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) lockdep_assert_held(&hard_iface->bat_v.aggr_list.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) return hard_iface->bat_v.aggr_len + ogm_len <= max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) * batadv_v_ogm_aggr_list_free - free all elements in an aggregation queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) * @hard_iface: the interface holding the aggregation queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) * Empties the OGMv2 aggregation queue and frees all the skbs it contains.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) * Caller needs to hold the hard_iface->bat_v.aggr_list.lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) static void batadv_v_ogm_aggr_list_free(struct batadv_hard_iface *hard_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) lockdep_assert_held(&hard_iface->bat_v.aggr_list.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) __skb_queue_purge(&hard_iface->bat_v.aggr_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) hard_iface->bat_v.aggr_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) * batadv_v_ogm_aggr_send() - flush & send aggregation queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) * @hard_iface: the interface with the aggregation queue to flush
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) * Aggregates all OGMv2 packets currently in the aggregation queue into a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) * single OGMv2 packet and transmits this aggregate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * The aggregation queue is empty after this call.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) * Caller needs to hold the hard_iface->bat_v.aggr_list.lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) static void batadv_v_ogm_aggr_send(struct batadv_hard_iface *hard_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) unsigned int aggr_len = hard_iface->bat_v.aggr_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) struct sk_buff *skb_aggr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) unsigned int ogm_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) lockdep_assert_held(&hard_iface->bat_v.aggr_list.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) if (!aggr_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) skb_aggr = dev_alloc_skb(aggr_len + ETH_HLEN + NET_IP_ALIGN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) if (!skb_aggr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) batadv_v_ogm_aggr_list_free(hard_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) skb_reserve(skb_aggr, ETH_HLEN + NET_IP_ALIGN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) skb_reset_network_header(skb_aggr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) while ((skb = __skb_dequeue(&hard_iface->bat_v.aggr_list))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) hard_iface->bat_v.aggr_len -= batadv_v_ogm_len(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) ogm_len = batadv_v_ogm_len(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) skb_put_data(skb_aggr, skb->data, ogm_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) consume_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) batadv_v_ogm_send_to_if(skb_aggr, hard_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) * batadv_v_ogm_queue_on_if() - queue a batman ogm on a given interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) * @skb: the OGM to queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) * @hard_iface: the interface to queue the OGM on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) static void batadv_v_ogm_queue_on_if(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) struct batadv_hard_iface *hard_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) if (!atomic_read(&bat_priv->aggregated_ogms)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) batadv_v_ogm_send_to_if(skb, hard_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) spin_lock_bh(&hard_iface->bat_v.aggr_list.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) if (!batadv_v_ogm_queue_left(skb, hard_iface))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) batadv_v_ogm_aggr_send(hard_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) hard_iface->bat_v.aggr_len += batadv_v_ogm_len(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) __skb_queue_tail(&hard_iface->bat_v.aggr_list, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) spin_unlock_bh(&hard_iface->bat_v.aggr_list.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) * batadv_v_ogm_send_softif() - periodic worker broadcasting the own OGM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) static void batadv_v_ogm_send_softif(struct batadv_priv *bat_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) struct batadv_hard_iface *hard_iface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) struct batadv_ogm2_packet *ogm_packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) struct sk_buff *skb, *skb_tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) unsigned char *ogm_buff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) int ogm_buff_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) u16 tvlv_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) lockdep_assert_held(&bat_priv->bat_v.ogm_buff_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) ogm_buff = bat_priv->bat_v.ogm_buff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) ogm_buff_len = bat_priv->bat_v.ogm_buff_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) /* tt changes have to be committed before the tvlv data is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) * appended as it may alter the tt tvlv container
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) batadv_tt_local_commit_changes(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) tvlv_len = batadv_tvlv_container_ogm_append(bat_priv, &ogm_buff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) &ogm_buff_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) BATADV_OGM2_HLEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) bat_priv->bat_v.ogm_buff = ogm_buff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) bat_priv->bat_v.ogm_buff_len = ogm_buff_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) skb = netdev_alloc_skb_ip_align(NULL, ETH_HLEN + ogm_buff_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) goto reschedule;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) skb_reserve(skb, ETH_HLEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) skb_put_data(skb, ogm_buff, ogm_buff_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) ogm_packet = (struct batadv_ogm2_packet *)skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) ogm_packet->seqno = htonl(atomic_read(&bat_priv->bat_v.ogm_seqno));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) atomic_inc(&bat_priv->bat_v.ogm_seqno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) ogm_packet->tvlv_len = htons(tvlv_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) /* broadcast on every interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) if (hard_iface->soft_iface != bat_priv->soft_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) if (!kref_get_unless_zero(&hard_iface->refcount))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) ret = batadv_hardif_no_broadcast(hard_iface, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) char *type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) switch (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) case BATADV_HARDIF_BCAST_NORECIPIENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) type = "no neighbor";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) case BATADV_HARDIF_BCAST_DUPFWD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) type = "single neighbor is source";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) case BATADV_HARDIF_BCAST_DUPORIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) type = "single neighbor is originator";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) type = "unknown";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) batadv_dbg(BATADV_DBG_BATMAN, bat_priv, "OGM2 from ourselves on %s suppressed: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) hard_iface->net_dev->name, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) batadv_hardif_put(hard_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) "Sending own OGM2 packet (originator %pM, seqno %u, throughput %u, TTL %d) on interface %s [%pM]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) ogm_packet->orig, ntohl(ogm_packet->seqno),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) ntohl(ogm_packet->throughput), ogm_packet->ttl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) hard_iface->net_dev->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) hard_iface->net_dev->dev_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) /* this skb gets consumed by batadv_v_ogm_send_to_if() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) skb_tmp = skb_clone(skb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if (!skb_tmp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) batadv_hardif_put(hard_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) batadv_v_ogm_queue_on_if(skb_tmp, hard_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) batadv_hardif_put(hard_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) consume_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) reschedule:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) batadv_v_ogm_start_timer(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) * batadv_v_ogm_send() - periodic worker broadcasting the own OGM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) * @work: work queue item
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) static void batadv_v_ogm_send(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) struct batadv_priv_bat_v *bat_v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) struct batadv_priv *bat_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) bat_v = container_of(work, struct batadv_priv_bat_v, ogm_wq.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) bat_priv = container_of(bat_v, struct batadv_priv, bat_v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) mutex_lock(&bat_priv->bat_v.ogm_buff_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) batadv_v_ogm_send_softif(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) mutex_unlock(&bat_priv->bat_v.ogm_buff_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) * batadv_v_ogm_aggr_work() - OGM queue periodic task per interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) * @work: work queue item
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) * Emits aggregated OGM messages in regular intervals.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) void batadv_v_ogm_aggr_work(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) struct batadv_hard_iface_bat_v *batv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) struct batadv_hard_iface *hard_iface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) batv = container_of(work, struct batadv_hard_iface_bat_v, aggr_wq.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) hard_iface = container_of(batv, struct batadv_hard_iface, bat_v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) spin_lock_bh(&hard_iface->bat_v.aggr_list.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) batadv_v_ogm_aggr_send(hard_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) spin_unlock_bh(&hard_iface->bat_v.aggr_list.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) batadv_v_ogm_start_queue_timer(hard_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) * batadv_v_ogm_iface_enable() - prepare an interface for B.A.T.M.A.N. V
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) * @hard_iface: the interface to prepare
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) * Takes care of scheduling its own OGM sending routine for this interface.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) * Return: 0 on success or a negative error code otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) int batadv_v_ogm_iface_enable(struct batadv_hard_iface *hard_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) batadv_v_ogm_start_queue_timer(hard_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) batadv_v_ogm_start_timer(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) }
^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) * batadv_v_ogm_iface_disable() - release OGM interface private resources
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) * @hard_iface: interface for which the resources have to be released
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) void batadv_v_ogm_iface_disable(struct batadv_hard_iface *hard_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) cancel_delayed_work_sync(&hard_iface->bat_v.aggr_wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) spin_lock_bh(&hard_iface->bat_v.aggr_list.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) batadv_v_ogm_aggr_list_free(hard_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) spin_unlock_bh(&hard_iface->bat_v.aggr_list.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) * batadv_v_ogm_primary_iface_set() - set a new primary interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) * @primary_iface: the new primary interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) void batadv_v_ogm_primary_iface_set(struct batadv_hard_iface *primary_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) struct batadv_priv *bat_priv = netdev_priv(primary_iface->soft_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) struct batadv_ogm2_packet *ogm_packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) mutex_lock(&bat_priv->bat_v.ogm_buff_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) if (!bat_priv->bat_v.ogm_buff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) ogm_packet = (struct batadv_ogm2_packet *)bat_priv->bat_v.ogm_buff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) ether_addr_copy(ogm_packet->orig, primary_iface->net_dev->dev_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) mutex_unlock(&bat_priv->bat_v.ogm_buff_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) * batadv_v_forward_penalty() - apply a penalty to the throughput metric
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) * forwarded with B.A.T.M.A.N. V OGMs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) * @if_incoming: the interface where the OGM has been received
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) * @if_outgoing: the interface where the OGM has to be forwarded to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) * @throughput: the current throughput
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) * Apply a penalty on the current throughput metric value based on the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) * characteristic of the interface where the OGM has been received.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) * Initially the per hardif hop penalty is applied to the throughput. After
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) * that the return value is then computed as follows:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) * - throughput * 50% if the incoming and outgoing interface are the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) * same WiFi interface and the throughput is above
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) * 1MBit/s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) * - throughput if the outgoing interface is the default
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) * interface (i.e. this OGM is processed for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) * internal table and not forwarded)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) * - throughput * node hop penalty otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) * Return: the penalised throughput metric.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) static u32 batadv_v_forward_penalty(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) struct batadv_hard_iface *if_incoming,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) struct batadv_hard_iface *if_outgoing,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) u32 throughput)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) int if_hop_penalty = atomic_read(&if_incoming->hop_penalty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) int hop_penalty = atomic_read(&bat_priv->hop_penalty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) int hop_penalty_max = BATADV_TQ_MAX_VALUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) /* Apply per hardif hop penalty */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) throughput = throughput * (hop_penalty_max - if_hop_penalty) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) hop_penalty_max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) /* Don't apply hop penalty in default originator table. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) if (if_outgoing == BATADV_IF_DEFAULT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) return throughput;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) /* Forwarding on the same WiFi interface cuts the throughput in half
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) * due to the store & forward characteristics of WIFI.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) * Very low throughput values are the exception.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) if (throughput > 10 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) if_incoming == if_outgoing &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) !(if_incoming->bat_v.flags & BATADV_FULL_DUPLEX))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) return throughput / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) /* hop penalty of 255 equals 100% */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) return throughput * (hop_penalty_max - hop_penalty) / hop_penalty_max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) }
^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) * batadv_v_ogm_forward() - check conditions and forward an OGM to the given
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) * outgoing interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) * @ogm_received: previously received OGM to be forwarded
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) * @orig_node: the originator which has been updated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) * @neigh_node: the neigh_node through with the OGM has been received
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) * @if_incoming: the interface on which this OGM was received on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) * @if_outgoing: the interface to which the OGM has to be forwarded to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) * Forward an OGM to an interface after having altered the throughput metric and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) * the TTL value contained in it. The original OGM isn't modified.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) static void batadv_v_ogm_forward(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) const struct batadv_ogm2_packet *ogm_received,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) struct batadv_orig_node *orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) struct batadv_neigh_node *neigh_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) struct batadv_hard_iface *if_incoming,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) struct batadv_hard_iface *if_outgoing)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) struct batadv_neigh_ifinfo *neigh_ifinfo = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) struct batadv_orig_ifinfo *orig_ifinfo = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) struct batadv_neigh_node *router = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) struct batadv_ogm2_packet *ogm_forward;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) unsigned char *skb_buff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) size_t packet_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) u16 tvlv_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) /* only forward for specific interfaces, not for the default one. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) if (if_outgoing == BATADV_IF_DEFAULT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) orig_ifinfo = batadv_orig_ifinfo_new(orig_node, if_outgoing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) if (!orig_ifinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) /* acquire possibly updated router */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) router = batadv_orig_router_get(orig_node, if_outgoing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) /* strict rule: forward packets coming from the best next hop only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) if (neigh_node != router)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) /* don't forward the same seqno twice on one interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) if (orig_ifinfo->last_seqno_forwarded == ntohl(ogm_received->seqno))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) orig_ifinfo->last_seqno_forwarded = ntohl(ogm_received->seqno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) if (ogm_received->ttl <= 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) batadv_dbg(BATADV_DBG_BATMAN, bat_priv, "ttl exceeded\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) neigh_ifinfo = batadv_neigh_ifinfo_get(neigh_node, if_outgoing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) if (!neigh_ifinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) tvlv_len = ntohs(ogm_received->tvlv_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) packet_len = BATADV_OGM2_HLEN + tvlv_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) skb = netdev_alloc_skb_ip_align(if_outgoing->net_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) ETH_HLEN + packet_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) skb_reserve(skb, ETH_HLEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) skb_buff = skb_put_data(skb, ogm_received, packet_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) /* apply forward penalty */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) ogm_forward = (struct batadv_ogm2_packet *)skb_buff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) ogm_forward->throughput = htonl(neigh_ifinfo->bat_v.throughput);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) ogm_forward->ttl--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) "Forwarding OGM2 packet on %s: throughput %u, ttl %u, received via %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) if_outgoing->net_dev->name, ntohl(ogm_forward->throughput),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) ogm_forward->ttl, if_incoming->net_dev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) batadv_v_ogm_queue_on_if(skb, if_outgoing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) if (orig_ifinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) batadv_orig_ifinfo_put(orig_ifinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) if (router)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) batadv_neigh_node_put(router);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) if (neigh_ifinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) batadv_neigh_ifinfo_put(neigh_ifinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) * batadv_v_ogm_metric_update() - update route metric based on OGM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) * @ogm2: OGM2 structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) * @orig_node: Originator structure for which the OGM has been received
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) * @neigh_node: the neigh_node through with the OGM has been received
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) * @if_incoming: the interface where this packet was received
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) * @if_outgoing: the interface for which the packet should be considered
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) * Return:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) * 1 if the OGM is new,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) * 0 if it is not new but valid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) * <0 on error (e.g. old OGM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) static int batadv_v_ogm_metric_update(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) const struct batadv_ogm2_packet *ogm2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) struct batadv_orig_node *orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) struct batadv_neigh_node *neigh_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) struct batadv_hard_iface *if_incoming,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) struct batadv_hard_iface *if_outgoing)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) struct batadv_orig_ifinfo *orig_ifinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) struct batadv_neigh_ifinfo *neigh_ifinfo = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) bool protection_started = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) int ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) u32 path_throughput;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) s32 seq_diff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) orig_ifinfo = batadv_orig_ifinfo_new(orig_node, if_outgoing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) if (!orig_ifinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) seq_diff = ntohl(ogm2->seqno) - orig_ifinfo->last_real_seqno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) if (!hlist_empty(&orig_node->neigh_list) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) batadv_window_protected(bat_priv, seq_diff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) BATADV_OGM_MAX_AGE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) &orig_ifinfo->batman_seqno_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) &protection_started)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) "Drop packet: packet within window protection time from %pM\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) ogm2->orig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) "Last reset: %ld, %ld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) orig_ifinfo->batman_seqno_reset, jiffies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) /* drop packets with old seqnos, however accept the first packet after
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) * a host has been rebooted.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) if (seq_diff < 0 && !protection_started)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) neigh_node->last_seen = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) orig_node->last_seen = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) orig_ifinfo->last_real_seqno = ntohl(ogm2->seqno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) orig_ifinfo->last_ttl = ogm2->ttl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) neigh_ifinfo = batadv_neigh_ifinfo_new(neigh_node, if_outgoing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) if (!neigh_ifinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) path_throughput = batadv_v_forward_penalty(bat_priv, if_incoming,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) if_outgoing,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) ntohl(ogm2->throughput));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) neigh_ifinfo->bat_v.throughput = path_throughput;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) neigh_ifinfo->bat_v.last_seqno = ntohl(ogm2->seqno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) neigh_ifinfo->last_ttl = ogm2->ttl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) if (seq_diff > 0 || protection_started)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) ret = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) if (orig_ifinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) batadv_orig_ifinfo_put(orig_ifinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) if (neigh_ifinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) batadv_neigh_ifinfo_put(neigh_ifinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) * batadv_v_ogm_route_update() - update routes based on OGM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) * @ethhdr: the Ethernet header of the OGM2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) * @ogm2: OGM2 structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) * @orig_node: Originator structure for which the OGM has been received
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) * @neigh_node: the neigh_node through with the OGM has been received
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) * @if_incoming: the interface where this packet was received
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) * @if_outgoing: the interface for which the packet should be considered
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) * Return: true if the packet should be forwarded, false otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) static bool batadv_v_ogm_route_update(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) const struct ethhdr *ethhdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) const struct batadv_ogm2_packet *ogm2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) struct batadv_orig_node *orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) struct batadv_neigh_node *neigh_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) struct batadv_hard_iface *if_incoming,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) struct batadv_hard_iface *if_outgoing)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) struct batadv_neigh_node *router = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) struct batadv_orig_node *orig_neigh_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) struct batadv_neigh_node *orig_neigh_router = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) struct batadv_neigh_ifinfo *router_ifinfo = NULL, *neigh_ifinfo = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) u32 router_throughput, neigh_throughput;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) u32 router_last_seqno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) u32 neigh_last_seqno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) s32 neigh_seq_diff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) bool forward = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) orig_neigh_node = batadv_v_ogm_orig_get(bat_priv, ethhdr->h_source);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) if (!orig_neigh_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) orig_neigh_router = batadv_orig_router_get(orig_neigh_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) if_outgoing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) /* drop packet if sender is not a direct neighbor and if we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) * don't route towards it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) router = batadv_orig_router_get(orig_node, if_outgoing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) if (router && router->orig_node != orig_node && !orig_neigh_router) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) "Drop packet: OGM via unknown neighbor!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) /* Mark the OGM to be considered for forwarding, and update routes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) * if needed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) forward = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) "Searching and updating originator entry of received packet\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) /* if this neighbor already is our next hop there is nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) * to change
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) if (router == neigh_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) /* don't consider neighbours with worse throughput.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) * also switch route if this seqno is BATADV_V_MAX_ORIGDIFF newer than
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) * the last received seqno from our best next hop.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) if (router) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) router_ifinfo = batadv_neigh_ifinfo_get(router, if_outgoing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) neigh_ifinfo = batadv_neigh_ifinfo_get(neigh_node, if_outgoing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) /* if these are not allocated, something is wrong. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) if (!router_ifinfo || !neigh_ifinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) neigh_last_seqno = neigh_ifinfo->bat_v.last_seqno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) router_last_seqno = router_ifinfo->bat_v.last_seqno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) neigh_seq_diff = neigh_last_seqno - router_last_seqno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) router_throughput = router_ifinfo->bat_v.throughput;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) neigh_throughput = neigh_ifinfo->bat_v.throughput;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) if (neigh_seq_diff < BATADV_OGM_MAX_ORIGDIFF &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) router_throughput >= neigh_throughput)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) batadv_update_route(bat_priv, orig_node, if_outgoing, neigh_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) if (router)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) batadv_neigh_node_put(router);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) if (orig_neigh_router)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) batadv_neigh_node_put(orig_neigh_router);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) if (orig_neigh_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) batadv_orig_node_put(orig_neigh_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) if (router_ifinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) batadv_neigh_ifinfo_put(router_ifinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) if (neigh_ifinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) batadv_neigh_ifinfo_put(neigh_ifinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) return forward;
^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) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) * batadv_v_ogm_process_per_outif() - process a batman v OGM for an outgoing if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) * @ethhdr: the Ethernet header of the OGM2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) * @ogm2: OGM2 structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) * @orig_node: Originator structure for which the OGM has been received
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) * @neigh_node: the neigh_node through with the OGM has been received
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) * @if_incoming: the interface where this packet was received
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) * @if_outgoing: the interface for which the packet should be considered
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) batadv_v_ogm_process_per_outif(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) const struct ethhdr *ethhdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) const struct batadv_ogm2_packet *ogm2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) struct batadv_orig_node *orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) struct batadv_neigh_node *neigh_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) struct batadv_hard_iface *if_incoming,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) struct batadv_hard_iface *if_outgoing)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) int seqno_age;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) bool forward;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) /* first, update the metric with according sanity checks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) seqno_age = batadv_v_ogm_metric_update(bat_priv, ogm2, orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) neigh_node, if_incoming,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) if_outgoing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) /* outdated sequence numbers are to be discarded */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) if (seqno_age < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) /* only unknown & newer OGMs contain TVLVs we are interested in */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) if (seqno_age > 0 && if_outgoing == BATADV_IF_DEFAULT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) batadv_tvlv_containers_process(bat_priv, true, orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) NULL, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) (unsigned char *)(ogm2 + 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) ntohs(ogm2->tvlv_len));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) /* if the metric update went through, update routes if needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) forward = batadv_v_ogm_route_update(bat_priv, ethhdr, ogm2, orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) neigh_node, if_incoming,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) if_outgoing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) /* if the routes have been processed correctly, check and forward */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) if (forward)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) batadv_v_ogm_forward(bat_priv, ogm2, orig_node, neigh_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) if_incoming, if_outgoing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) * batadv_v_ogm_aggr_packet() - checks if there is another OGM aggregated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) * @buff_pos: current position in the skb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) * @packet_len: total length of the skb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) * @ogm2_packet: potential OGM2 in buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) * Return: true if there is enough space for another OGM, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) static bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) batadv_v_ogm_aggr_packet(int buff_pos, int packet_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) const struct batadv_ogm2_packet *ogm2_packet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) int next_buff_pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) /* check if there is enough space for the header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) next_buff_pos += buff_pos + sizeof(*ogm2_packet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) if (next_buff_pos > packet_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) /* check if there is enough space for the optional TVLV */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) next_buff_pos += ntohs(ogm2_packet->tvlv_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) return (next_buff_pos <= packet_len) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) (next_buff_pos <= BATADV_MAX_AGGREGATION_BYTES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) * batadv_v_ogm_process() - process an incoming batman v OGM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) * @skb: the skb containing the OGM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) * @ogm_offset: offset to the OGM which should be processed (for aggregates)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) * @if_incoming: the interface where this packet was received
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) static void batadv_v_ogm_process(const struct sk_buff *skb, int ogm_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) struct batadv_hard_iface *if_incoming)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) struct ethhdr *ethhdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) struct batadv_orig_node *orig_node = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) struct batadv_hardif_neigh_node *hardif_neigh = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) struct batadv_neigh_node *neigh_node = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) struct batadv_hard_iface *hard_iface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) struct batadv_ogm2_packet *ogm_packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) u32 ogm_throughput, link_throughput, path_throughput;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) ethhdr = eth_hdr(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) ogm_packet = (struct batadv_ogm2_packet *)(skb->data + ogm_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) ogm_throughput = ntohl(ogm_packet->throughput);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) "Received OGM2 packet via NB: %pM, IF: %s [%pM] (from OG: %pM, seqno %u, throughput %u, TTL %u, V %u, tvlv_len %u)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) ethhdr->h_source, if_incoming->net_dev->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) if_incoming->net_dev->dev_addr, ogm_packet->orig,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) ntohl(ogm_packet->seqno), ogm_throughput, ogm_packet->ttl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) ogm_packet->version, ntohs(ogm_packet->tvlv_len));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) if (batadv_is_my_mac(bat_priv, ogm_packet->orig)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) "Drop packet: originator packet from ourself\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) /* If the throughput metric is 0, immediately drop the packet. No need
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) * to create orig_node / neigh_node for an unusable route.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) if (ogm_throughput == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) "Drop packet: originator packet with throughput metric of 0\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) /* require ELP packets be to received from this neighbor first */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) hardif_neigh = batadv_hardif_neigh_get(if_incoming, ethhdr->h_source);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) if (!hardif_neigh) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) "Drop packet: OGM via unknown neighbor!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) orig_node = batadv_v_ogm_orig_get(bat_priv, ogm_packet->orig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) if (!orig_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) neigh_node = batadv_neigh_node_get_or_create(orig_node, if_incoming,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) ethhdr->h_source);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) if (!neigh_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) /* Update the received throughput metric to match the link
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) * characteristic:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) * - If this OGM traveled one hop so far (emitted by single hop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) * neighbor) the path throughput metric equals the link throughput.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) * - For OGMs traversing more than hop the path throughput metric is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) * the smaller of the path throughput and the link throughput.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) link_throughput = ewma_throughput_read(&hardif_neigh->bat_v.throughput);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) path_throughput = min_t(u32, link_throughput, ogm_throughput);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) ogm_packet->throughput = htonl(path_throughput);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) batadv_v_ogm_process_per_outif(bat_priv, ethhdr, ogm_packet, orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) neigh_node, if_incoming,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) BATADV_IF_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) if (hard_iface->if_status != BATADV_IF_ACTIVE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) if (hard_iface->soft_iface != bat_priv->soft_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) if (!kref_get_unless_zero(&hard_iface->refcount))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) ret = batadv_hardif_no_broadcast(hard_iface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) ogm_packet->orig,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) hardif_neigh->orig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) char *type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) switch (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) case BATADV_HARDIF_BCAST_NORECIPIENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) type = "no neighbor";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) case BATADV_HARDIF_BCAST_DUPFWD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) type = "single neighbor is source";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) case BATADV_HARDIF_BCAST_DUPORIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) type = "single neighbor is originator";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) type = "unknown";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) batadv_dbg(BATADV_DBG_BATMAN, bat_priv, "OGM2 packet from %pM on %s suppressed: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) ogm_packet->orig, hard_iface->net_dev->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) batadv_hardif_put(hard_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) batadv_v_ogm_process_per_outif(bat_priv, ethhdr, ogm_packet,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) orig_node, neigh_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) if_incoming, hard_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) batadv_hardif_put(hard_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) if (orig_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) batadv_orig_node_put(orig_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) if (neigh_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) batadv_neigh_node_put(neigh_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) if (hardif_neigh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) batadv_hardif_neigh_put(hardif_neigh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) * batadv_v_ogm_packet_recv() - OGM2 receiving handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) * @skb: the received OGM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) * @if_incoming: the interface where this OGM has been received
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) * Return: NET_RX_SUCCESS and consume the skb on success or returns NET_RX_DROP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) * (without freeing the skb) on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) int batadv_v_ogm_packet_recv(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) struct batadv_hard_iface *if_incoming)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) struct batadv_ogm2_packet *ogm_packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) struct ethhdr *ethhdr = eth_hdr(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) int ogm_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) u8 *packet_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) int ret = NET_RX_DROP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) /* did we receive a OGM2 packet on an interface that does not have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) * B.A.T.M.A.N. V enabled ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) if (strcmp(bat_priv->algo_ops->name, "BATMAN_V") != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) goto free_skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) if (!batadv_check_management_packet(skb, if_incoming, BATADV_OGM2_HLEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) goto free_skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) if (batadv_is_my_mac(bat_priv, ethhdr->h_source))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) goto free_skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) batadv_inc_counter(bat_priv, BATADV_CNT_MGMT_RX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) batadv_add_counter(bat_priv, BATADV_CNT_MGMT_RX_BYTES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) skb->len + ETH_HLEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) ogm_offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) ogm_packet = (struct batadv_ogm2_packet *)skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) while (batadv_v_ogm_aggr_packet(ogm_offset, skb_headlen(skb),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) ogm_packet)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) batadv_v_ogm_process(skb, ogm_offset, if_incoming);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) ogm_offset += BATADV_OGM2_HLEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) ogm_offset += ntohs(ogm_packet->tvlv_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) packet_pos = skb->data + ogm_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) ogm_packet = (struct batadv_ogm2_packet *)packet_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) ret = NET_RX_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) free_skb:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) if (ret == NET_RX_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) consume_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) * batadv_v_ogm_init() - initialise the OGM2 engine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) * Return: 0 on success or a negative error code in case of failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) int batadv_v_ogm_init(struct batadv_priv *bat_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) struct batadv_ogm2_packet *ogm_packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) unsigned char *ogm_buff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) u32 random_seqno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) bat_priv->bat_v.ogm_buff_len = BATADV_OGM2_HLEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) ogm_buff = kzalloc(bat_priv->bat_v.ogm_buff_len, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) if (!ogm_buff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) bat_priv->bat_v.ogm_buff = ogm_buff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) ogm_packet = (struct batadv_ogm2_packet *)ogm_buff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) ogm_packet->packet_type = BATADV_OGM2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) ogm_packet->version = BATADV_COMPAT_VERSION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) ogm_packet->ttl = BATADV_TTL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) ogm_packet->flags = BATADV_NO_FLAGS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) ogm_packet->throughput = htonl(BATADV_THROUGHPUT_MAX_VALUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) /* randomize initial seqno to avoid collision */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) get_random_bytes(&random_seqno, sizeof(random_seqno));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) atomic_set(&bat_priv->bat_v.ogm_seqno, random_seqno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) INIT_DELAYED_WORK(&bat_priv->bat_v.ogm_wq, batadv_v_ogm_send);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) mutex_init(&bat_priv->bat_v.ogm_buff_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) * batadv_v_ogm_free() - free OGM private resources
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) void batadv_v_ogm_free(struct batadv_priv *bat_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) cancel_delayed_work_sync(&bat_priv->bat_v.ogm_wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) mutex_lock(&bat_priv->bat_v.ogm_buff_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) kfree(bat_priv->bat_v.ogm_buff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) bat_priv->bat_v.ogm_buff = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) bat_priv->bat_v.ogm_buff_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) mutex_unlock(&bat_priv->bat_v.ogm_buff_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) }