^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) 2011-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 "distributed-arp-table.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 <asm/unaligned.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/atomic.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/byteorder/generic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/etherdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/gfp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/if_arp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/if_ether.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/if_vlan.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/in.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/ip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/jiffies.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/kref.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/netlink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/rculist.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/rcupdate.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/seq_file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/skbuff.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/stddef.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/udp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <linux/workqueue.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <net/arp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <net/genetlink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <net/netlink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <net/sock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <uapi/linux/batman_adv.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include "bridge_loop_avoidance.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include "hard-interface.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include "hash.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #include "log.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #include "netlink.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #include "originator.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #include "send.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #include "soft-interface.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #include "translation-table.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #include "tvlv.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) enum batadv_bootpop {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) BATADV_BOOTREPLY = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) enum batadv_boothtype {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) BATADV_HTYPE_ETHERNET = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) enum batadv_dhcpoptioncode {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) BATADV_DHCP_OPT_PAD = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) BATADV_DHCP_OPT_MSG_TYPE = 53,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) BATADV_DHCP_OPT_END = 255,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) enum batadv_dhcptype {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) BATADV_DHCPACK = 5,
^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) /* { 99, 130, 83, 99 } */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define BATADV_DHCP_MAGIC 1669485411
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) struct batadv_dhcp_packet {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) __u8 op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) __u8 htype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) __u8 hlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) __u8 hops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) __be32 xid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) __be16 secs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) __be16 flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) __be32 ciaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) __be32 yiaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) __be32 siaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) __be32 giaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) __u8 chaddr[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) __u8 sname[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) __u8 file[128];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) __be32 magic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) __u8 options[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define BATADV_DHCP_YIADDR_LEN sizeof(((struct batadv_dhcp_packet *)0)->yiaddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define BATADV_DHCP_CHADDR_LEN sizeof(((struct batadv_dhcp_packet *)0)->chaddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) static void batadv_dat_purge(struct work_struct *work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * batadv_dat_start_timer() - initialise the DAT periodic worker
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) static void batadv_dat_start_timer(struct batadv_priv *bat_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) INIT_DELAYED_WORK(&bat_priv->dat.work, batadv_dat_purge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) queue_delayed_work(batadv_event_workqueue, &bat_priv->dat.work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) msecs_to_jiffies(10000));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) * batadv_dat_entry_release() - release dat_entry from lists and queue for free
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * after rcu grace period
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) * @ref: kref pointer of the dat_entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) static void batadv_dat_entry_release(struct kref *ref)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) struct batadv_dat_entry *dat_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) dat_entry = container_of(ref, struct batadv_dat_entry, refcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) kfree_rcu(dat_entry, rcu);
^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) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) * batadv_dat_entry_put() - decrement the dat_entry refcounter and possibly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) * release it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) * @dat_entry: dat_entry to be free'd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) static void batadv_dat_entry_put(struct batadv_dat_entry *dat_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) if (!dat_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) kref_put(&dat_entry->refcount, batadv_dat_entry_release);
^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) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) * batadv_dat_to_purge() - check whether a dat_entry has to be purged or not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) * @dat_entry: the entry to check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) * Return: true if the entry has to be purged now, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) static bool batadv_dat_to_purge(struct batadv_dat_entry *dat_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) return batadv_has_timed_out(dat_entry->last_update,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) BATADV_DAT_ENTRY_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) * __batadv_dat_purge() - delete entries from the DAT local storage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) * @to_purge: function in charge to decide whether an entry has to be purged or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) * not. This function takes the dat_entry as argument and has to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) * returns a boolean value: true is the entry has to be deleted,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) * false otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) * Loops over each entry in the DAT local storage and deletes it if and only if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) * the to_purge function passed as argument returns true.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) static void __batadv_dat_purge(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) bool (*to_purge)(struct batadv_dat_entry *))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) spinlock_t *list_lock; /* protects write access to the hash lists */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) struct batadv_dat_entry *dat_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) struct hlist_node *node_tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) struct hlist_head *head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) u32 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) if (!bat_priv->dat.hash)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) for (i = 0; i < bat_priv->dat.hash->size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) head = &bat_priv->dat.hash->table[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) list_lock = &bat_priv->dat.hash->list_locks[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) spin_lock_bh(list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) hlist_for_each_entry_safe(dat_entry, node_tmp, head,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) hash_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) /* if a helper function has been passed as parameter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) * ask it if the entry has to be purged or not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) if (to_purge && !to_purge(dat_entry))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) hlist_del_rcu(&dat_entry->hash_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) batadv_dat_entry_put(dat_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) spin_unlock_bh(list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^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) * batadv_dat_purge() - periodic task that deletes old entries from the local
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) * DAT hash table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * @work: kernel work struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) static void batadv_dat_purge(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) struct delayed_work *delayed_work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) struct batadv_priv_dat *priv_dat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) struct batadv_priv *bat_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) delayed_work = to_delayed_work(work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) priv_dat = container_of(delayed_work, struct batadv_priv_dat, work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) bat_priv = container_of(priv_dat, struct batadv_priv, dat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) __batadv_dat_purge(bat_priv, batadv_dat_to_purge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) batadv_dat_start_timer(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^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) * batadv_compare_dat() - comparing function used in the local DAT hash table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) * @node: node in the local table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) * @data2: second object to compare the node to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) * Return: true if the two entries are the same, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) static bool batadv_compare_dat(const struct hlist_node *node, const void *data2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) const void *data1 = container_of(node, struct batadv_dat_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) hash_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) return memcmp(data1, data2, sizeof(__be32)) == 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) }
^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) * batadv_arp_hw_src() - extract the hw_src field from an ARP packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) * @skb: ARP packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) * @hdr_size: size of the possible header before the ARP packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) * Return: the value of the hw_src field in the ARP packet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) static u8 *batadv_arp_hw_src(struct sk_buff *skb, int hdr_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) u8 *addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) addr = (u8 *)(skb->data + hdr_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) addr += ETH_HLEN + sizeof(struct arphdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) return addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) * batadv_arp_ip_src() - extract the ip_src field from an ARP packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) * @skb: ARP packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) * @hdr_size: size of the possible header before the ARP packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) * Return: the value of the ip_src field in the ARP packet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) static __be32 batadv_arp_ip_src(struct sk_buff *skb, int hdr_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) return *(__force __be32 *)(batadv_arp_hw_src(skb, hdr_size) + ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) }
^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) * batadv_arp_hw_dst() - extract the hw_dst field from an ARP packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) * @skb: ARP packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) * @hdr_size: size of the possible header before the ARP packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) * Return: the value of the hw_dst field in the ARP packet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) static u8 *batadv_arp_hw_dst(struct sk_buff *skb, int hdr_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) return batadv_arp_hw_src(skb, hdr_size) + ETH_ALEN + 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) * batadv_arp_ip_dst() - extract the ip_dst field from an ARP packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) * @skb: ARP packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) * @hdr_size: size of the possible header before the ARP packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) * Return: the value of the ip_dst field in the ARP packet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) static __be32 batadv_arp_ip_dst(struct sk_buff *skb, int hdr_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) u8 *dst = batadv_arp_hw_src(skb, hdr_size) + ETH_ALEN * 2 + 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) return *(__force __be32 *)dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) * batadv_hash_dat() - compute the hash value for an IP address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) * @data: data to hash
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) * @size: size of the hash table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) * Return: the selected index in the hash table for the given data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) static u32 batadv_hash_dat(const void *data, u32 size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) u32 hash = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) const struct batadv_dat_entry *dat = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) const unsigned char *key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) __be16 vid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) u32 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) key = (__force const unsigned char *)&dat->ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) for (i = 0; i < sizeof(dat->ip); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) hash += key[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) hash += (hash << 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) hash ^= (hash >> 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) vid = htons(dat->vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) key = (__force const unsigned char *)&vid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) for (i = 0; i < sizeof(dat->vid); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) hash += key[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) hash += (hash << 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) hash ^= (hash >> 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) hash += (hash << 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) hash ^= (hash >> 11);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) hash += (hash << 15);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) return hash % size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) * batadv_dat_entry_hash_find() - look for a given dat_entry in the local hash
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) * table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) * @ip: search key
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) * @vid: VLAN identifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) * Return: the dat_entry if found, NULL otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) static struct batadv_dat_entry *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) batadv_dat_entry_hash_find(struct batadv_priv *bat_priv, __be32 ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) unsigned short vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) struct hlist_head *head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) struct batadv_dat_entry to_find, *dat_entry, *dat_entry_tmp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) struct batadv_hashtable *hash = bat_priv->dat.hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) u32 index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) if (!hash)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) to_find.ip = ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) to_find.vid = vid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) index = batadv_hash_dat(&to_find, hash->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) head = &hash->table[index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) hlist_for_each_entry_rcu(dat_entry, head, hash_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) if (dat_entry->ip != ip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) if (!kref_get_unless_zero(&dat_entry->refcount))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) dat_entry_tmp = dat_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) return dat_entry_tmp;
^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_dat_entry_add() - add a new dat entry or update it if already exists
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) * @ip: ipv4 to add/edit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) * @mac_addr: mac address to assign to the given ipv4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) * @vid: VLAN identifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) static void batadv_dat_entry_add(struct batadv_priv *bat_priv, __be32 ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) u8 *mac_addr, unsigned short vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) struct batadv_dat_entry *dat_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) int hash_added;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) dat_entry = batadv_dat_entry_hash_find(bat_priv, ip, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) /* if this entry is already known, just update it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) if (dat_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) if (!batadv_compare_eth(dat_entry->mac_addr, mac_addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) ether_addr_copy(dat_entry->mac_addr, mac_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) dat_entry->last_update = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) batadv_dbg(BATADV_DBG_DAT, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) "Entry updated: %pI4 %pM (vid: %d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) &dat_entry->ip, dat_entry->mac_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) batadv_print_vid(vid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) dat_entry = kmalloc(sizeof(*dat_entry), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) if (!dat_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) dat_entry->ip = ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) dat_entry->vid = vid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) ether_addr_copy(dat_entry->mac_addr, mac_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) dat_entry->last_update = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) kref_init(&dat_entry->refcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) kref_get(&dat_entry->refcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) hash_added = batadv_hash_add(bat_priv->dat.hash, batadv_compare_dat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) batadv_hash_dat, dat_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) &dat_entry->hash_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) if (unlikely(hash_added != 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) /* remove the reference for the hash */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) batadv_dat_entry_put(dat_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) goto out;
^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) batadv_dbg(BATADV_DBG_DAT, bat_priv, "New entry added: %pI4 %pM (vid: %d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) &dat_entry->ip, dat_entry->mac_addr, batadv_print_vid(vid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) if (dat_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) batadv_dat_entry_put(dat_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) #ifdef CONFIG_BATMAN_ADV_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) * batadv_dbg_arp() - print a debug message containing all the ARP packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) * details
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) * @skb: ARP packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) * @hdr_size: size of the possible header before the ARP packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) * @msg: message to print together with the debugging information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) static void batadv_dbg_arp(struct batadv_priv *bat_priv, struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) int hdr_size, char *msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) struct batadv_unicast_4addr_packet *unicast_4addr_packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) struct batadv_bcast_packet *bcast_pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) u8 *orig_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) __be32 ip_src, ip_dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) if (msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) batadv_dbg(BATADV_DBG_DAT, bat_priv, "%s\n", msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) ip_src = batadv_arp_ip_src(skb, hdr_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) ip_dst = batadv_arp_ip_dst(skb, hdr_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) batadv_dbg(BATADV_DBG_DAT, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) "ARP MSG = [src: %pM-%pI4 dst: %pM-%pI4]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) batadv_arp_hw_src(skb, hdr_size), &ip_src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) batadv_arp_hw_dst(skb, hdr_size), &ip_dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) if (hdr_size < sizeof(struct batadv_unicast_packet))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) unicast_4addr_packet = (struct batadv_unicast_4addr_packet *)skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) switch (unicast_4addr_packet->u.packet_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) case BATADV_UNICAST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) batadv_dbg(BATADV_DBG_DAT, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) "* encapsulated within a UNICAST packet\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) case BATADV_UNICAST_4ADDR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) batadv_dbg(BATADV_DBG_DAT, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) "* encapsulated within a UNICAST_4ADDR packet (src: %pM)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) unicast_4addr_packet->src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) switch (unicast_4addr_packet->subtype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) case BATADV_P_DAT_DHT_PUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) batadv_dbg(BATADV_DBG_DAT, bat_priv, "* type: DAT_DHT_PUT\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) case BATADV_P_DAT_DHT_GET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) batadv_dbg(BATADV_DBG_DAT, bat_priv, "* type: DAT_DHT_GET\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) case BATADV_P_DAT_CACHE_REPLY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) batadv_dbg(BATADV_DBG_DAT, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) "* type: DAT_CACHE_REPLY\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) case BATADV_P_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) batadv_dbg(BATADV_DBG_DAT, bat_priv, "* type: DATA\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) batadv_dbg(BATADV_DBG_DAT, bat_priv, "* type: Unknown (%u)!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) unicast_4addr_packet->u.packet_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) case BATADV_BCAST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) bcast_pkt = (struct batadv_bcast_packet *)unicast_4addr_packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) orig_addr = bcast_pkt->orig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) batadv_dbg(BATADV_DBG_DAT, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) "* encapsulated within a BCAST packet (src: %pM)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) orig_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) batadv_dbg(BATADV_DBG_DAT, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) "* encapsulated within an unknown packet type (0x%x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) unicast_4addr_packet->u.packet_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) static void batadv_dbg_arp(struct batadv_priv *bat_priv, struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) int hdr_size, char *msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) #endif /* CONFIG_BATMAN_ADV_DEBUG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) * batadv_is_orig_node_eligible() - check whether a node can be a DHT candidate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) * @res: the array with the already selected candidates
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) * @select: number of already selected candidates
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) * @tmp_max: address of the currently evaluated node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) * @max: current round max address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) * @last_max: address of the last selected candidate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) * @candidate: orig_node under evaluation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) * @max_orig_node: last selected candidate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) * Return: true if the node has been elected as next candidate or false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) * otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) static bool batadv_is_orig_node_eligible(struct batadv_dat_candidate *res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) int select, batadv_dat_addr_t tmp_max,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) batadv_dat_addr_t max,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) batadv_dat_addr_t last_max,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) struct batadv_orig_node *candidate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) struct batadv_orig_node *max_orig_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) bool ret = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) int j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) /* check if orig node candidate is running DAT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) if (!test_bit(BATADV_ORIG_CAPA_HAS_DAT, &candidate->capabilities))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) /* Check if this node has already been selected... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) for (j = 0; j < select; j++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) if (res[j].orig_node == candidate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) /* ..and possibly skip it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) if (j < select)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) /* sanity check: has it already been selected? This should not happen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) if (tmp_max > last_max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) /* check if during this iteration an originator with a closer dht
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) * address has already been found
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) if (tmp_max < max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) /* this is an hash collision with the temporary selected node. Choose
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) * the one with the lowest address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) if (tmp_max == max && max_orig_node &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) batadv_compare_eth(candidate->orig, max_orig_node->orig))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) ret = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) * batadv_choose_next_candidate() - select the next DHT candidate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) * @cands: candidates array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) * @select: number of candidates already present in the array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) * @ip_key: key to look up in the DHT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) * @last_max: pointer where the address of the selected candidate will be saved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) static void batadv_choose_next_candidate(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) struct batadv_dat_candidate *cands,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) int select, batadv_dat_addr_t ip_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) batadv_dat_addr_t *last_max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) batadv_dat_addr_t max = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) batadv_dat_addr_t tmp_max = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) struct batadv_orig_node *orig_node, *max_orig_node = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) struct batadv_hashtable *hash = bat_priv->orig_hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) struct hlist_head *head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) /* if no node is eligible as candidate, leave the candidate type as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) * NOT_FOUND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) cands[select].type = BATADV_DAT_CANDIDATE_NOT_FOUND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) /* iterate over the originator list and find the node with the closest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) * dat_address which has not been selected yet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) for (i = 0; i < hash->size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) head = &hash->table[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) /* the dht space is a ring using unsigned addresses */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) tmp_max = BATADV_DAT_ADDR_MAX - orig_node->dat_addr +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) ip_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) if (!batadv_is_orig_node_eligible(cands, select,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) tmp_max, max,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) *last_max, orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) max_orig_node))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) if (!kref_get_unless_zero(&orig_node->refcount))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) max = tmp_max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) if (max_orig_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) batadv_orig_node_put(max_orig_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) max_orig_node = orig_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) if (max_orig_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) cands[select].type = BATADV_DAT_CANDIDATE_ORIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) cands[select].orig_node = max_orig_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) batadv_dbg(BATADV_DBG_DAT, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) "dat_select_candidates() %d: selected %pM addr=%u dist=%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) select, max_orig_node->orig, max_orig_node->dat_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) *last_max = max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) * batadv_dat_select_candidates() - select the nodes which the DHT message has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) * to be sent to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) * @ip_dst: ipv4 to look up in the DHT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) * @vid: VLAN identifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) * An originator O is selected if and only if its DHT_ID value is one of three
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) * closest values (from the LEFT, with wrap around if needed) then the hash
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) * value of the key. ip_dst is the key.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) * Return: the candidate array of size BATADV_DAT_CANDIDATE_NUM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) static struct batadv_dat_candidate *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) batadv_dat_select_candidates(struct batadv_priv *bat_priv, __be32 ip_dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) unsigned short vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) int select;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) batadv_dat_addr_t last_max = BATADV_DAT_ADDR_MAX, ip_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) struct batadv_dat_candidate *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) struct batadv_dat_entry dat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) if (!bat_priv->orig_hash)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) res = kmalloc_array(BATADV_DAT_CANDIDATES_NUM, sizeof(*res),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) if (!res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) dat.ip = ip_dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) dat.vid = vid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) ip_key = (batadv_dat_addr_t)batadv_hash_dat(&dat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) BATADV_DAT_ADDR_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) batadv_dbg(BATADV_DBG_DAT, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) "%s(): IP=%pI4 hash(IP)=%u\n", __func__, &ip_dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) ip_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) for (select = 0; select < BATADV_DAT_CANDIDATES_NUM; select++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) batadv_choose_next_candidate(bat_priv, res, select, ip_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) &last_max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) * batadv_dat_forward_data() - copy and send payload to the selected candidates
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) * @skb: payload to send
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) * @ip: the DHT key
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) * @vid: VLAN identifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) * @packet_subtype: unicast4addr packet subtype to use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) * This function copies the skb with pskb_copy() and is sent as a unicast packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) * to each of the selected candidates.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) * Return: true if the packet is sent to at least one candidate, false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) * otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) static bool batadv_dat_forward_data(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) struct sk_buff *skb, __be32 ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) unsigned short vid, int packet_subtype)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) bool ret = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) int send_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) struct batadv_neigh_node *neigh_node = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) struct sk_buff *tmp_skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) struct batadv_dat_candidate *cand;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) cand = batadv_dat_select_candidates(bat_priv, ip, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) if (!cand)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) batadv_dbg(BATADV_DBG_DAT, bat_priv, "DHT_SEND for %pI4\n", &ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) for (i = 0; i < BATADV_DAT_CANDIDATES_NUM; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) if (cand[i].type == BATADV_DAT_CANDIDATE_NOT_FOUND)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) neigh_node = batadv_orig_router_get(cand[i].orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) BATADV_IF_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) if (!neigh_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) goto free_orig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) tmp_skb = pskb_copy_for_clone(skb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) if (!batadv_send_skb_prepare_unicast_4addr(bat_priv, tmp_skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) cand[i].orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) packet_subtype)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) kfree_skb(tmp_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) goto free_neigh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) send_status = batadv_send_unicast_skb(tmp_skb, neigh_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) if (send_status == NET_XMIT_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) /* count the sent packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) switch (packet_subtype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) case BATADV_P_DAT_DHT_GET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) batadv_inc_counter(bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) BATADV_CNT_DAT_GET_TX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) case BATADV_P_DAT_DHT_PUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) batadv_inc_counter(bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) BATADV_CNT_DAT_PUT_TX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) break;
^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) /* packet sent to a candidate: return true */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) ret = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) free_neigh:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) batadv_neigh_node_put(neigh_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) free_orig:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) batadv_orig_node_put(cand[i].orig_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) kfree(cand);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) * batadv_dat_tvlv_container_update() - update the dat tvlv container after dat
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) * setting change
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) static void batadv_dat_tvlv_container_update(struct batadv_priv *bat_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) char dat_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) dat_mode = atomic_read(&bat_priv->distributed_arp_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) switch (dat_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_DAT, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) batadv_tvlv_container_register(bat_priv, BATADV_TVLV_DAT, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) }
^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_dat_status_update() - update the dat tvlv container after dat
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) * setting change
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) * @net_dev: the soft interface net device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) void batadv_dat_status_update(struct net_device *net_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) struct batadv_priv *bat_priv = netdev_priv(net_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) batadv_dat_tvlv_container_update(bat_priv);
^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) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) * batadv_dat_tvlv_ogm_handler_v1() - process incoming dat tvlv container
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) * @orig: the orig_node of the ogm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) * @flags: flags indicating the tvlv state (see batadv_tvlv_handler_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) * @tvlv_value: tvlv buffer containing the gateway data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) * @tvlv_value_len: tvlv buffer length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) static void batadv_dat_tvlv_ogm_handler_v1(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) struct batadv_orig_node *orig,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) u8 flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) void *tvlv_value, u16 tvlv_value_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) if (flags & BATADV_TVLV_HANDLER_OGM_CIFNOTFND)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) clear_bit(BATADV_ORIG_CAPA_HAS_DAT, &orig->capabilities);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) set_bit(BATADV_ORIG_CAPA_HAS_DAT, &orig->capabilities);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) * batadv_dat_hash_free() - free the local DAT hash table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) static void batadv_dat_hash_free(struct batadv_priv *bat_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) if (!bat_priv->dat.hash)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) __batadv_dat_purge(bat_priv, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) batadv_hash_destroy(bat_priv->dat.hash);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) bat_priv->dat.hash = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) * batadv_dat_init() - initialise the DAT internals
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) * Return: 0 in case of success, a negative error code otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) int batadv_dat_init(struct batadv_priv *bat_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) if (bat_priv->dat.hash)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) bat_priv->dat.hash = batadv_hash_new(1024);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) if (!bat_priv->dat.hash)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) batadv_dat_start_timer(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) batadv_tvlv_handler_register(bat_priv, batadv_dat_tvlv_ogm_handler_v1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) NULL, BATADV_TVLV_DAT, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) BATADV_TVLV_HANDLER_OGM_CIFNOTFND);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) batadv_dat_tvlv_container_update(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) * batadv_dat_free() - free the DAT internals
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) void batadv_dat_free(struct batadv_priv *bat_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_DAT, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) batadv_tvlv_handler_unregister(bat_priv, BATADV_TVLV_DAT, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) cancel_delayed_work_sync(&bat_priv->dat.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) batadv_dat_hash_free(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) #ifdef CONFIG_BATMAN_ADV_DEBUGFS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) * batadv_dat_cache_seq_print_text() - print the local DAT hash table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) * @seq: seq file to print on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) * @offset: not used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) * Return: always 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) int batadv_dat_cache_seq_print_text(struct seq_file *seq, void *offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) struct net_device *net_dev = (struct net_device *)seq->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) struct batadv_priv *bat_priv = netdev_priv(net_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) struct batadv_hashtable *hash = bat_priv->dat.hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) struct batadv_dat_entry *dat_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) struct batadv_hard_iface *primary_if;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) struct hlist_head *head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) unsigned long last_seen_jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) int last_seen_msecs, last_seen_secs, last_seen_mins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) u32 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) primary_if = batadv_seq_print_text_primary_if_get(seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) if (!primary_if)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) seq_printf(seq, "Distributed ARP Table (%s):\n", net_dev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) seq_puts(seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) " IPv4 MAC VID last-seen\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) for (i = 0; i < hash->size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) head = &hash->table[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) hlist_for_each_entry_rcu(dat_entry, head, hash_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) last_seen_jiffies = jiffies - dat_entry->last_update;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) last_seen_msecs = jiffies_to_msecs(last_seen_jiffies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) last_seen_mins = last_seen_msecs / 60000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) last_seen_msecs = last_seen_msecs % 60000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) last_seen_secs = last_seen_msecs / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) seq_printf(seq, " * %15pI4 %pM %4i %6i:%02i\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) &dat_entry->ip, dat_entry->mac_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) batadv_print_vid(dat_entry->vid),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) last_seen_mins, last_seen_secs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) if (primary_if)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) batadv_hardif_put(primary_if);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) * batadv_dat_cache_dump_entry() - dump one entry of the DAT cache table to a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) * netlink socket
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) * @msg: buffer for the message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) * @portid: netlink port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) * @cb: Control block containing additional options
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) * @dat_entry: entry to dump
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) * Return: 0 or error code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) batadv_dat_cache_dump_entry(struct sk_buff *msg, u32 portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) struct netlink_callback *cb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) struct batadv_dat_entry *dat_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) int msecs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) hdr = genlmsg_put(msg, portid, cb->nlh->nlmsg_seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) &batadv_netlink_family, NLM_F_MULTI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) BATADV_CMD_GET_DAT_CACHE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) genl_dump_check_consistent(cb, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) msecs = jiffies_to_msecs(jiffies - dat_entry->last_update);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) if (nla_put_in_addr(msg, BATADV_ATTR_DAT_CACHE_IP4ADDRESS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) dat_entry->ip) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) nla_put(msg, BATADV_ATTR_DAT_CACHE_HWADDRESS, ETH_ALEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) dat_entry->mac_addr) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) nla_put_u16(msg, BATADV_ATTR_DAT_CACHE_VID, dat_entry->vid) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) nla_put_u32(msg, BATADV_ATTR_LAST_SEEN_MSECS, msecs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) genlmsg_cancel(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) * batadv_dat_cache_dump_bucket() - dump one bucket of the DAT cache table to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) * a netlink socket
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) * @msg: buffer for the message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) * @portid: netlink port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) * @cb: Control block containing additional options
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) * @hash: hash to dump
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) * @bucket: bucket index to dump
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) * @idx_skip: How many entries to skip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) * Return: 0 or error code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) batadv_dat_cache_dump_bucket(struct sk_buff *msg, u32 portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) struct netlink_callback *cb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) struct batadv_hashtable *hash, unsigned int bucket,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) int *idx_skip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) struct batadv_dat_entry *dat_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) int idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) spin_lock_bh(&hash->list_locks[bucket]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) cb->seq = atomic_read(&hash->generation) << 1 | 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) hlist_for_each_entry(dat_entry, &hash->table[bucket], hash_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) if (idx < *idx_skip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) goto skip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) if (batadv_dat_cache_dump_entry(msg, portid, cb, dat_entry)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) spin_unlock_bh(&hash->list_locks[bucket]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) *idx_skip = idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) skip:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) idx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) spin_unlock_bh(&hash->list_locks[bucket]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) }
^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) * batadv_dat_cache_dump() - dump DAT cache table to a netlink socket
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) * @msg: buffer for the message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) * @cb: callback structure containing arguments
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) * Return: message length.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) int batadv_dat_cache_dump(struct sk_buff *msg, struct netlink_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) struct batadv_hard_iface *primary_if = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) int portid = NETLINK_CB(cb->skb).portid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) struct net *net = sock_net(cb->skb->sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) struct net_device *soft_iface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) struct batadv_hashtable *hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) struct batadv_priv *bat_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) int bucket = cb->args[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) int idx = cb->args[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) int ifindex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) ifindex = batadv_netlink_get_ifindex(cb->nlh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) BATADV_ATTR_MESH_IFINDEX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) if (!ifindex)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) soft_iface = dev_get_by_index(net, ifindex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) if (!soft_iface || !batadv_softif_is_valid(soft_iface)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) bat_priv = netdev_priv(soft_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) hash = bat_priv->dat.hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) primary_if = batadv_primary_if_get_selected(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) if (!primary_if || primary_if->if_status != BATADV_IF_ACTIVE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) ret = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) while (bucket < hash->size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) if (batadv_dat_cache_dump_bucket(msg, portid, cb, hash, bucket,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) &idx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) bucket++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) idx = 0;
^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) cb->args[0] = bucket;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) cb->args[1] = idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) ret = msg->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) if (primary_if)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) batadv_hardif_put(primary_if);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) if (soft_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) dev_put(soft_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) * batadv_arp_get_type() - parse an ARP packet and gets the type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) * @skb: packet to analyse
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) * @hdr_size: size of the possible header before the ARP packet in the skb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) * Return: the ARP type if the skb contains a valid ARP packet, 0 otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) static u16 batadv_arp_get_type(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) struct sk_buff *skb, int hdr_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) struct arphdr *arphdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) struct ethhdr *ethhdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) __be32 ip_src, ip_dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) u8 *hw_src, *hw_dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) u16 type = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) /* pull the ethernet header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) if (unlikely(!pskb_may_pull(skb, hdr_size + ETH_HLEN)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) ethhdr = (struct ethhdr *)(skb->data + hdr_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) if (ethhdr->h_proto != htons(ETH_P_ARP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) /* pull the ARP payload */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) if (unlikely(!pskb_may_pull(skb, hdr_size + ETH_HLEN +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) arp_hdr_len(skb->dev))))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) arphdr = (struct arphdr *)(skb->data + hdr_size + ETH_HLEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) /* check whether the ARP packet carries a valid IP information */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) if (arphdr->ar_hrd != htons(ARPHRD_ETHER))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) if (arphdr->ar_pro != htons(ETH_P_IP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) if (arphdr->ar_hln != ETH_ALEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) if (arphdr->ar_pln != 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) /* Check for bad reply/request. If the ARP message is not sane, DAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) * will simply ignore it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) ip_src = batadv_arp_ip_src(skb, hdr_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) ip_dst = batadv_arp_ip_dst(skb, hdr_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) if (ipv4_is_loopback(ip_src) || ipv4_is_multicast(ip_src) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) ipv4_is_loopback(ip_dst) || ipv4_is_multicast(ip_dst) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) ipv4_is_zeronet(ip_src) || ipv4_is_lbcast(ip_src) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) ipv4_is_zeronet(ip_dst) || ipv4_is_lbcast(ip_dst))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) hw_src = batadv_arp_hw_src(skb, hdr_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) if (is_zero_ether_addr(hw_src) || is_multicast_ether_addr(hw_src))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) /* don't care about the destination MAC address in ARP requests */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) if (arphdr->ar_op != htons(ARPOP_REQUEST)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) hw_dst = batadv_arp_hw_dst(skb, hdr_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) if (is_zero_ether_addr(hw_dst) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) is_multicast_ether_addr(hw_dst))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) type = ntohs(arphdr->ar_op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) return type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) * batadv_dat_get_vid() - extract the VLAN identifier from skb if any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) * @skb: the buffer containing the packet to extract the VID from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) * @hdr_size: the size of the batman-adv header encapsulating the packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) * Return: If the packet embedded in the skb is vlan tagged this function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) * returns the VID with the BATADV_VLAN_HAS_TAG flag. Otherwise BATADV_NO_FLAGS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) * is returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) static unsigned short batadv_dat_get_vid(struct sk_buff *skb, int *hdr_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) unsigned short vid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) vid = batadv_get_vid(skb, *hdr_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) /* ARP parsing functions jump forward of hdr_size + ETH_HLEN.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) * If the header contained in the packet is a VLAN one (which is longer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) * hdr_size is updated so that the functions will still skip the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) * correct amount of bytes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) if (vid & BATADV_VLAN_HAS_TAG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) *hdr_size += VLAN_HLEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) return vid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) * batadv_dat_arp_create_reply() - create an ARP Reply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) * @ip_src: ARP sender IP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) * @ip_dst: ARP target IP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) * @hw_src: Ethernet source and ARP sender MAC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) * @hw_dst: Ethernet destination and ARP target MAC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) * @vid: VLAN identifier (optional, set to zero otherwise)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) * Creates an ARP Reply from the given values, optionally encapsulated in a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) * VLAN header.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) * Return: An skb containing an ARP Reply.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) static struct sk_buff *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) batadv_dat_arp_create_reply(struct batadv_priv *bat_priv, __be32 ip_src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) __be32 ip_dst, u8 *hw_src, u8 *hw_dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) unsigned short vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) skb = arp_create(ARPOP_REPLY, ETH_P_ARP, ip_dst, bat_priv->soft_iface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) ip_src, hw_dst, hw_src, hw_dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) skb_reset_mac_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) if (vid & BATADV_VLAN_HAS_TAG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) skb = vlan_insert_tag(skb, htons(ETH_P_8021Q),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) vid & VLAN_VID_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) return skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) * batadv_dat_snoop_outgoing_arp_request() - snoop the ARP request and try to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) * answer using DAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) * @skb: packet to check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) * Return: true if the message has been sent to the dht candidates, false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) * otherwise. In case of a positive return value the message has to be enqueued
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) * to permit the fallback.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) bool batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) u16 type = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) __be32 ip_dst, ip_src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) u8 *hw_src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) bool ret = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) struct batadv_dat_entry *dat_entry = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) struct sk_buff *skb_new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) struct net_device *soft_iface = bat_priv->soft_iface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) int hdr_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) unsigned short vid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) if (!atomic_read(&bat_priv->distributed_arp_table))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) vid = batadv_dat_get_vid(skb, &hdr_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) type = batadv_arp_get_type(bat_priv, skb, hdr_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) /* If the node gets an ARP_REQUEST it has to send a DHT_GET unicast
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) * message to the selected DHT candidates
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) if (type != ARPOP_REQUEST)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) batadv_dbg_arp(bat_priv, skb, hdr_size, "Parsing outgoing ARP REQUEST");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) ip_src = batadv_arp_ip_src(skb, hdr_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) hw_src = batadv_arp_hw_src(skb, hdr_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) ip_dst = batadv_arp_ip_dst(skb, hdr_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) batadv_dat_entry_add(bat_priv, ip_src, hw_src, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) dat_entry = batadv_dat_entry_hash_find(bat_priv, ip_dst, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) if (dat_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) /* If the ARP request is destined for a local client the local
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) * client will answer itself. DAT would only generate a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) * duplicate packet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) * Moreover, if the soft-interface is enslaved into a bridge, an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) * additional DAT answer may trigger kernel warnings about
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) * a packet coming from the wrong port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) if (batadv_is_my_client(bat_priv, dat_entry->mac_addr, vid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) ret = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) goto out;
^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) /* If BLA is enabled, only send ARP replies if we have claimed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) * the destination for the ARP request or if no one else of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) * the backbone gws belonging to our backbone has claimed the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) * destination.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) if (!batadv_bla_check_claim(bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) dat_entry->mac_addr, vid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) batadv_dbg(BATADV_DBG_DAT, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) "Device %pM claimed by another backbone gw. Don't send ARP reply!",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) dat_entry->mac_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) ret = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) skb_new = batadv_dat_arp_create_reply(bat_priv, ip_dst, ip_src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) dat_entry->mac_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) hw_src, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) if (!skb_new)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) skb_new->protocol = eth_type_trans(skb_new, soft_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) batadv_inc_counter(bat_priv, BATADV_CNT_RX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) batadv_add_counter(bat_priv, BATADV_CNT_RX_BYTES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) skb->len + ETH_HLEN + hdr_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) netif_rx(skb_new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) batadv_dbg(BATADV_DBG_DAT, bat_priv, "ARP request replied locally\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) ret = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) /* Send the request to the DHT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) ret = batadv_dat_forward_data(bat_priv, skb, ip_dst, vid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) BATADV_P_DAT_DHT_GET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) if (dat_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) batadv_dat_entry_put(dat_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) * batadv_dat_snoop_incoming_arp_request() - snoop the ARP request and try to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) * answer using the local DAT storage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) * @skb: packet to check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) * @hdr_size: size of the encapsulation header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) * Return: true if the request has been answered, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) bool batadv_dat_snoop_incoming_arp_request(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) struct sk_buff *skb, int hdr_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) u16 type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) __be32 ip_src, ip_dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) u8 *hw_src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) struct sk_buff *skb_new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) struct batadv_dat_entry *dat_entry = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) bool ret = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) unsigned short vid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) if (!atomic_read(&bat_priv->distributed_arp_table))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) vid = batadv_dat_get_vid(skb, &hdr_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) type = batadv_arp_get_type(bat_priv, skb, hdr_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) if (type != ARPOP_REQUEST)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) hw_src = batadv_arp_hw_src(skb, hdr_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) ip_src = batadv_arp_ip_src(skb, hdr_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) ip_dst = batadv_arp_ip_dst(skb, hdr_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) batadv_dbg_arp(bat_priv, skb, hdr_size, "Parsing incoming ARP REQUEST");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) batadv_dat_entry_add(bat_priv, ip_src, hw_src, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) dat_entry = batadv_dat_entry_hash_find(bat_priv, ip_dst, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) if (!dat_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) skb_new = batadv_dat_arp_create_reply(bat_priv, ip_dst, ip_src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) dat_entry->mac_addr, hw_src, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) if (!skb_new)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) /* To preserve backwards compatibility, the node has choose the outgoing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) * format based on the incoming request packet type. The assumption is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) * that a node not using the 4addr packet format doesn't support it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) if (hdr_size == sizeof(struct batadv_unicast_4addr_packet))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) err = batadv_send_skb_via_tt_4addr(bat_priv, skb_new,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) BATADV_P_DAT_CACHE_REPLY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) NULL, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) err = batadv_send_skb_via_tt(bat_priv, skb_new, NULL, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) if (err != NET_XMIT_DROP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) batadv_inc_counter(bat_priv, BATADV_CNT_DAT_CACHED_REPLY_TX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) ret = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) if (dat_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) batadv_dat_entry_put(dat_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) * batadv_dat_snoop_outgoing_arp_reply() - snoop the ARP reply and fill the DHT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) * @skb: packet to check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) void batadv_dat_snoop_outgoing_arp_reply(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) u16 type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) __be32 ip_src, ip_dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) u8 *hw_src, *hw_dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) int hdr_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) unsigned short vid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) if (!atomic_read(&bat_priv->distributed_arp_table))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) vid = batadv_dat_get_vid(skb, &hdr_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) type = batadv_arp_get_type(bat_priv, skb, hdr_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) if (type != ARPOP_REPLY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) batadv_dbg_arp(bat_priv, skb, hdr_size, "Parsing outgoing ARP REPLY");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) hw_src = batadv_arp_hw_src(skb, hdr_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) ip_src = batadv_arp_ip_src(skb, hdr_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) hw_dst = batadv_arp_hw_dst(skb, hdr_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) ip_dst = batadv_arp_ip_dst(skb, hdr_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) batadv_dat_entry_add(bat_priv, ip_src, hw_src, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) batadv_dat_entry_add(bat_priv, ip_dst, hw_dst, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) /* Send the ARP reply to the candidates for both the IP addresses that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) * the node obtained from the ARP reply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) batadv_dat_forward_data(bat_priv, skb, ip_src, vid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) BATADV_P_DAT_DHT_PUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) batadv_dat_forward_data(bat_priv, skb, ip_dst, vid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) BATADV_P_DAT_DHT_PUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) }
^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) * batadv_dat_snoop_incoming_arp_reply() - snoop the ARP reply and fill the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) * local DAT storage only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) * @skb: packet to check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) * @hdr_size: size of the encapsulation header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) * Return: true if the packet was snooped and consumed by DAT. False if the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) * packet has to be delivered to the interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) bool batadv_dat_snoop_incoming_arp_reply(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) struct sk_buff *skb, int hdr_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) struct batadv_dat_entry *dat_entry = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) u16 type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) __be32 ip_src, ip_dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) u8 *hw_src, *hw_dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) bool dropped = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) unsigned short vid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) if (!atomic_read(&bat_priv->distributed_arp_table))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) vid = batadv_dat_get_vid(skb, &hdr_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) type = batadv_arp_get_type(bat_priv, skb, hdr_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) if (type != ARPOP_REPLY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) batadv_dbg_arp(bat_priv, skb, hdr_size, "Parsing incoming ARP REPLY");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) hw_src = batadv_arp_hw_src(skb, hdr_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) ip_src = batadv_arp_ip_src(skb, hdr_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) hw_dst = batadv_arp_hw_dst(skb, hdr_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) ip_dst = batadv_arp_ip_dst(skb, hdr_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) /* If ip_dst is already in cache and has the right mac address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) * drop this frame if this ARP reply is destined for us because it's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) * most probably an ARP reply generated by another node of the DHT.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) * We have most probably received already a reply earlier. Delivering
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) * this frame would lead to doubled receive of an ARP reply.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) dat_entry = batadv_dat_entry_hash_find(bat_priv, ip_src, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) if (dat_entry && batadv_compare_eth(hw_src, dat_entry->mac_addr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) batadv_dbg(BATADV_DBG_DAT, bat_priv, "Doubled ARP reply removed: ARP MSG = [src: %pM-%pI4 dst: %pM-%pI4]; dat_entry: %pM-%pI4\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) hw_src, &ip_src, hw_dst, &ip_dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) dat_entry->mac_addr, &dat_entry->ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) dropped = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) /* Update our internal cache with both the IP addresses the node got
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) * within the ARP reply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) batadv_dat_entry_add(bat_priv, ip_src, hw_src, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) batadv_dat_entry_add(bat_priv, ip_dst, hw_dst, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) if (dropped)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) /* If BLA is enabled, only forward ARP replies if we have claimed the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) * source of the ARP reply or if no one else of the same backbone has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) * already claimed that client. This prevents that different gateways
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) * to the same backbone all forward the ARP reply leading to multiple
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) * replies in the backbone.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) if (!batadv_bla_check_claim(bat_priv, hw_src, vid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) batadv_dbg(BATADV_DBG_DAT, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) "Device %pM claimed by another backbone gw. Drop ARP reply.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) hw_src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) dropped = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) /* if this REPLY is directed to a client of mine, let's deliver the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) * packet to the interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) dropped = !batadv_is_my_client(bat_priv, hw_dst, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) /* if this REPLY is sent on behalf of a client of mine, let's drop the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) * packet because the client will reply by itself
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) dropped |= batadv_is_my_client(bat_priv, hw_src, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) if (dropped)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) if (dat_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) batadv_dat_entry_put(dat_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) /* if dropped == false -> deliver to the interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) return dropped;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) * batadv_dat_check_dhcp_ipudp() - check skb for IP+UDP headers valid for DHCP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) * @skb: the packet to check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) * @ip_src: a buffer to store the IPv4 source address in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) * Checks whether the given skb has an IP and UDP header valid for a DHCP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) * message from a DHCP server. And if so, stores the IPv4 source address in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) * the provided buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) * Return: True if valid, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) static bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) batadv_dat_check_dhcp_ipudp(struct sk_buff *skb, __be32 *ip_src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) unsigned int offset = skb_network_offset(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) struct udphdr *udphdr, _udphdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) struct iphdr *iphdr, _iphdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) iphdr = skb_header_pointer(skb, offset, sizeof(_iphdr), &_iphdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) if (!iphdr || iphdr->version != 4 || iphdr->ihl * 4 < sizeof(_iphdr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) if (iphdr->protocol != IPPROTO_UDP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) offset += iphdr->ihl * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) skb_set_transport_header(skb, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) udphdr = skb_header_pointer(skb, offset, sizeof(_udphdr), &_udphdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) if (!udphdr || udphdr->source != htons(67))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) *ip_src = get_unaligned(&iphdr->saddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) * batadv_dat_check_dhcp() - examine packet for valid DHCP message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) * @skb: the packet to check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) * @proto: ethernet protocol hint (behind a potential vlan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) * @ip_src: a buffer to store the IPv4 source address in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) * Checks whether the given skb is a valid DHCP packet. And if so, stores the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) * IPv4 source address in the provided buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) * Caller needs to ensure that the skb network header is set correctly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) * Return: If skb is a valid DHCP packet, then returns its op code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) * (e.g. BOOTREPLY vs. BOOTREQUEST). Otherwise returns -EINVAL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) batadv_dat_check_dhcp(struct sk_buff *skb, __be16 proto, __be32 *ip_src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) __be32 *magic, _magic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) unsigned int offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) __u8 op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) __u8 htype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) __u8 hlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) __u8 hops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) } *dhcp_h, _dhcp_h;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) if (proto != htons(ETH_P_IP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) if (!batadv_dat_check_dhcp_ipudp(skb, ip_src))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) offset = skb_transport_offset(skb) + sizeof(struct udphdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) if (skb->len < offset + sizeof(struct batadv_dhcp_packet))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) dhcp_h = skb_header_pointer(skb, offset, sizeof(_dhcp_h), &_dhcp_h);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) if (!dhcp_h || dhcp_h->htype != BATADV_HTYPE_ETHERNET ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) dhcp_h->hlen != ETH_ALEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) offset += offsetof(struct batadv_dhcp_packet, magic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) magic = skb_header_pointer(skb, offset, sizeof(_magic), &_magic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) if (!magic || get_unaligned(magic) != htonl(BATADV_DHCP_MAGIC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) return dhcp_h->op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) * batadv_dat_get_dhcp_message_type() - get message type of a DHCP packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) * @skb: the DHCP packet to parse
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) * Iterates over the DHCP options of the given DHCP packet to find a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) * DHCP Message Type option and parse it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) * Caller needs to ensure that the given skb is a valid DHCP packet and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) * that the skb transport header is set correctly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) * Return: The found DHCP message type value, if found. -EINVAL otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) static int batadv_dat_get_dhcp_message_type(struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) unsigned int offset = skb_transport_offset(skb) + sizeof(struct udphdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) u8 *type, _type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) u8 type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) u8 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) } *tl, _tl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) offset += sizeof(struct batadv_dhcp_packet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) while ((tl = skb_header_pointer(skb, offset, sizeof(_tl), &_tl))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) if (tl->type == BATADV_DHCP_OPT_MSG_TYPE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) if (tl->type == BATADV_DHCP_OPT_END)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) if (tl->type == BATADV_DHCP_OPT_PAD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) offset++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) offset += tl->len + sizeof(_tl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) /* Option Overload Code not supported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) if (!tl || tl->type != BATADV_DHCP_OPT_MSG_TYPE ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) tl->len != sizeof(_type))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) offset += sizeof(_tl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) type = skb_header_pointer(skb, offset, sizeof(_type), &_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) if (!type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) return *type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) * batadv_dat_get_dhcp_yiaddr() - get yiaddr from a DHCP packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) * @skb: the DHCP packet to parse
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) * @buf: a buffer to store the yiaddr in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) * Caller needs to ensure that the given skb is a valid DHCP packet and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) * that the skb transport header is set correctly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) * Return: True on success, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) static bool batadv_dat_dhcp_get_yiaddr(struct sk_buff *skb, __be32 *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) unsigned int offset = skb_transport_offset(skb) + sizeof(struct udphdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) __be32 *yiaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) offset += offsetof(struct batadv_dhcp_packet, yiaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) yiaddr = skb_header_pointer(skb, offset, BATADV_DHCP_YIADDR_LEN, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) if (!yiaddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) if (yiaddr != buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) *buf = get_unaligned(yiaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) * batadv_dat_get_dhcp_chaddr() - get chaddr from a DHCP packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) * @skb: the DHCP packet to parse
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) * @buf: a buffer to store the chaddr in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) * Caller needs to ensure that the given skb is a valid DHCP packet and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) * that the skb transport header is set correctly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) * Return: True on success, false otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) static bool batadv_dat_get_dhcp_chaddr(struct sk_buff *skb, u8 *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) unsigned int offset = skb_transport_offset(skb) + sizeof(struct udphdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) u8 *chaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) offset += offsetof(struct batadv_dhcp_packet, chaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) chaddr = skb_header_pointer(skb, offset, BATADV_DHCP_CHADDR_LEN, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) if (!chaddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) if (chaddr != buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) memcpy(buf, chaddr, BATADV_DHCP_CHADDR_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) * batadv_dat_put_dhcp() - puts addresses from a DHCP packet into the DHT and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) * DAT cache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) * @chaddr: the DHCP client MAC address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) * @yiaddr: the DHCP client IP address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) * @hw_dst: the DHCP server MAC address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) * @ip_dst: the DHCP server IP address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) * @vid: VLAN identifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) * Adds given MAC/IP pairs to the local DAT cache and propagates them further
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) * into the DHT.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) * For the DHT propagation, client MAC + IP will appear as the ARP Reply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) * transmitter (and hw_dst/ip_dst as the target).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) static void batadv_dat_put_dhcp(struct batadv_priv *bat_priv, u8 *chaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) __be32 yiaddr, u8 *hw_dst, __be32 ip_dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) unsigned short vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) skb = batadv_dat_arp_create_reply(bat_priv, yiaddr, ip_dst, chaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) hw_dst, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) skb_set_network_header(skb, ETH_HLEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) batadv_dat_entry_add(bat_priv, yiaddr, chaddr, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) batadv_dat_entry_add(bat_priv, ip_dst, hw_dst, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) batadv_dat_forward_data(bat_priv, skb, yiaddr, vid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) BATADV_P_DAT_DHT_PUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) batadv_dat_forward_data(bat_priv, skb, ip_dst, vid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) BATADV_P_DAT_DHT_PUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) consume_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) batadv_dbg(BATADV_DBG_DAT, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) "Snooped from outgoing DHCPACK (server address): %pI4, %pM (vid: %i)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) &ip_dst, hw_dst, batadv_print_vid(vid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) batadv_dbg(BATADV_DBG_DAT, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) "Snooped from outgoing DHCPACK (client address): %pI4, %pM (vid: %i)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) &yiaddr, chaddr, batadv_print_vid(vid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) * batadv_dat_check_dhcp_ack() - examine packet for valid DHCP message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) * @skb: the packet to check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) * @proto: ethernet protocol hint (behind a potential vlan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) * @ip_src: a buffer to store the IPv4 source address in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) * @chaddr: a buffer to store the DHCP Client Hardware Address in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) * @yiaddr: a buffer to store the DHCP Your IP Address in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) * Checks whether the given skb is a valid DHCPACK. And if so, stores the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) * IPv4 server source address (ip_src), client MAC address (chaddr) and client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) * IPv4 address (yiaddr) in the provided buffers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) * Caller needs to ensure that the skb network header is set correctly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) * Return: True if the skb is a valid DHCPACK. False otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) static bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) batadv_dat_check_dhcp_ack(struct sk_buff *skb, __be16 proto, __be32 *ip_src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) u8 *chaddr, __be32 *yiaddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) int type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) type = batadv_dat_check_dhcp(skb, proto, ip_src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) if (type != BATADV_BOOTREPLY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) type = batadv_dat_get_dhcp_message_type(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) if (type != BATADV_DHCPACK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) if (!batadv_dat_dhcp_get_yiaddr(skb, yiaddr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) if (!batadv_dat_get_dhcp_chaddr(skb, chaddr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) * batadv_dat_snoop_outgoing_dhcp_ack() - snoop DHCPACK and fill DAT with it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) * @skb: the packet to snoop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) * @proto: ethernet protocol hint (behind a potential vlan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) * @vid: VLAN identifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) * This function first checks whether the given skb is a valid DHCPACK. If
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) * so then its source MAC and IP as well as its DHCP Client Hardware Address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) * field and DHCP Your IP Address field are added to the local DAT cache and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) * propagated into the DHT.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) * Caller needs to ensure that the skb mac and network headers are set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) * correctly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) void batadv_dat_snoop_outgoing_dhcp_ack(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) __be16 proto,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) unsigned short vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) u8 chaddr[BATADV_DHCP_CHADDR_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) __be32 ip_src, yiaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) if (!atomic_read(&bat_priv->distributed_arp_table))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) if (!batadv_dat_check_dhcp_ack(skb, proto, &ip_src, chaddr, &yiaddr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) batadv_dat_put_dhcp(bat_priv, chaddr, yiaddr, eth_hdr(skb)->h_source,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) ip_src, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) * batadv_dat_snoop_incoming_dhcp_ack() - snoop DHCPACK and fill DAT cache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) * @skb: the packet to snoop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) * @hdr_size: header size, up to the tail of the batman-adv header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) * This function first checks whether the given skb is a valid DHCPACK. If
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) * so then its source MAC and IP as well as its DHCP Client Hardware Address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) * field and DHCP Your IP Address field are added to the local DAT cache.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) void batadv_dat_snoop_incoming_dhcp_ack(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) struct sk_buff *skb, int hdr_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) u8 chaddr[BATADV_DHCP_CHADDR_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) struct ethhdr *ethhdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) __be32 ip_src, yiaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) unsigned short vid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) __be16 proto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) u8 *hw_src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) if (!atomic_read(&bat_priv->distributed_arp_table))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) if (unlikely(!pskb_may_pull(skb, hdr_size + ETH_HLEN)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) ethhdr = (struct ethhdr *)(skb->data + hdr_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) skb_set_network_header(skb, hdr_size + ETH_HLEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) proto = ethhdr->h_proto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) if (!batadv_dat_check_dhcp_ack(skb, proto, &ip_src, chaddr, &yiaddr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) hw_src = ethhdr->h_source;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) vid = batadv_dat_get_vid(skb, &hdr_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) batadv_dat_entry_add(bat_priv, yiaddr, chaddr, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) batadv_dat_entry_add(bat_priv, ip_src, hw_src, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) batadv_dbg(BATADV_DBG_DAT, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) "Snooped from incoming DHCPACK (server address): %pI4, %pM (vid: %i)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) &ip_src, hw_src, batadv_print_vid(vid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) batadv_dbg(BATADV_DBG_DAT, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) "Snooped from incoming DHCPACK (client address): %pI4, %pM (vid: %i)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) &yiaddr, chaddr, batadv_print_vid(vid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) * batadv_dat_drop_broadcast_packet() - check if an ARP request has to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) * dropped (because the node has already obtained the reply via DAT) or not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) * @forw_packet: the broadcast packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) * Return: true if the node can drop the packet, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) bool batadv_dat_drop_broadcast_packet(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) struct batadv_forw_packet *forw_packet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) u16 type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) __be32 ip_dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) struct batadv_dat_entry *dat_entry = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) bool ret = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) int hdr_size = sizeof(struct batadv_bcast_packet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) unsigned short vid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) if (!atomic_read(&bat_priv->distributed_arp_table))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) /* If this packet is an ARP_REQUEST and the node already has the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) * information that it is going to ask, then the packet can be dropped
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) if (batadv_forw_packet_is_rebroadcast(forw_packet))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) vid = batadv_dat_get_vid(forw_packet->skb, &hdr_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) type = batadv_arp_get_type(bat_priv, forw_packet->skb, hdr_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) if (type != ARPOP_REQUEST)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) ip_dst = batadv_arp_ip_dst(forw_packet->skb, hdr_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) dat_entry = batadv_dat_entry_hash_find(bat_priv, ip_dst, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) /* check if the node already got this entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) if (!dat_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) batadv_dbg(BATADV_DBG_DAT, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) "ARP Request for %pI4: fallback\n", &ip_dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) goto out;
^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_dbg(BATADV_DBG_DAT, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) "ARP Request for %pI4: fallback prevented\n", &ip_dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) ret = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) if (dat_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) batadv_dat_entry_put(dat_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) }