^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /* Copyright (C) 2007-2020 B.A.T.M.A.N. contributors:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Marek Lindner
^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 "icmp_socket.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include "main.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/atomic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/compiler.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/debugfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/etherdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/eventpoll.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/fcntl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/gfp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/if_ether.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/pkt_sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/poll.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/printk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/sched.h> /* for linux/wait.h */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/skbuff.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/stddef.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/wait.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <uapi/linux/batadv_packet.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include "debugfs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include "hard-interface.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include "log.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include "originator.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include "send.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) static struct batadv_socket_client *batadv_socket_client_hash[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) static void batadv_socket_add_packet(struct batadv_socket_client *socket_client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) struct batadv_icmp_header *icmph,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) size_t icmp_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * batadv_socket_init() - Initialize soft interface independent socket data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) void batadv_socket_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) memset(batadv_socket_client_hash, 0, sizeof(batadv_socket_client_hash));
^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) static int batadv_socket_open(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) struct batadv_socket_client *socket_client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) if (!try_module_get(THIS_MODULE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) batadv_debugfs_deprecated(file, "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) stream_open(inode, file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) socket_client = kmalloc(sizeof(*socket_client), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) if (!socket_client) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) module_put(THIS_MODULE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) for (i = 0; i < ARRAY_SIZE(batadv_socket_client_hash); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) if (!batadv_socket_client_hash[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) batadv_socket_client_hash[i] = socket_client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) if (i == ARRAY_SIZE(batadv_socket_client_hash)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) pr_err("Error - can't add another packet client: maximum number of clients reached\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) kfree(socket_client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) module_put(THIS_MODULE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) return -EXFULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) INIT_LIST_HEAD(&socket_client->queue_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) socket_client->queue_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) socket_client->index = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) socket_client->bat_priv = inode->i_private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) spin_lock_init(&socket_client->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) init_waitqueue_head(&socket_client->queue_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) file->private_data = socket_client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) static int batadv_socket_release(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) struct batadv_socket_client *client = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) struct batadv_socket_packet *packet, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) spin_lock_bh(&client->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) /* for all packets in the queue ... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) list_for_each_entry_safe(packet, tmp, &client->queue_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) list_del(&packet->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) kfree(packet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) batadv_socket_client_hash[client->index] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) spin_unlock_bh(&client->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) kfree(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) module_put(THIS_MODULE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) return 0;
^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) static ssize_t batadv_socket_read(struct file *file, char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) struct batadv_socket_client *socket_client = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) struct batadv_socket_packet *socket_packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) size_t packet_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) if ((file->f_flags & O_NONBLOCK) && socket_client->queue_len == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) if (!buf || count < sizeof(struct batadv_icmp_packet))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) error = wait_event_interruptible(socket_client->queue_wait,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) socket_client->queue_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) spin_lock_bh(&socket_client->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) socket_packet = list_first_entry(&socket_client->queue_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) struct batadv_socket_packet, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) list_del(&socket_packet->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) socket_client->queue_len--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) spin_unlock_bh(&socket_client->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) packet_len = min(count, socket_packet->icmp_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) error = copy_to_user(buf, &socket_packet->icmp_packet, packet_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) kfree(socket_packet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) return packet_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) static ssize_t batadv_socket_write(struct file *file, const char __user *buff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) size_t len, loff_t *off)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) struct batadv_socket_client *socket_client = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) struct batadv_priv *bat_priv = socket_client->bat_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) struct batadv_hard_iface *primary_if = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) struct batadv_icmp_packet_rr *icmp_packet_rr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) struct batadv_icmp_header *icmp_header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) struct batadv_orig_node *orig_node = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) struct batadv_neigh_node *neigh_node = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) size_t packet_len = sizeof(struct batadv_icmp_packet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) u8 *addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) if (len < sizeof(struct batadv_icmp_header)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) "Error - can't send packet from char device: invalid packet size\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) primary_if = batadv_primary_if_get_selected(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) if (!primary_if) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) len = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) goto out;
^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) if (len >= BATADV_ICMP_MAX_PACKET_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) packet_len = BATADV_ICMP_MAX_PACKET_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) packet_len = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) skb = netdev_alloc_skb_ip_align(NULL, packet_len + ETH_HLEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) if (!skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) len = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) skb->priority = TC_PRIO_CONTROL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) skb_reserve(skb, ETH_HLEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) icmp_header = skb_put(skb, packet_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) if (copy_from_user(icmp_header, buff, packet_len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) len = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) goto free_skb;
^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) if (icmp_header->packet_type != BATADV_ICMP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) "Error - can't send packet from char device: got bogus packet type (expected: BAT_ICMP)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) len = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) goto free_skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) switch (icmp_header->msg_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) case BATADV_ECHO_REQUEST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) if (len < sizeof(struct batadv_icmp_packet)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) "Error - can't send packet from char device: invalid packet size\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) len = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) goto free_skb;
^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) if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) goto dst_unreach;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) orig_node = batadv_orig_hash_find(bat_priv, icmp_header->dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) if (!orig_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) goto dst_unreach;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) neigh_node = batadv_orig_router_get(orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) BATADV_IF_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) if (!neigh_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) goto dst_unreach;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) if (!neigh_node->if_incoming)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) goto dst_unreach;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) if (neigh_node->if_incoming->if_status != BATADV_IF_ACTIVE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) goto dst_unreach;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) icmp_packet_rr = (struct batadv_icmp_packet_rr *)icmp_header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) if (packet_len == sizeof(*icmp_packet_rr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) addr = neigh_node->if_incoming->net_dev->dev_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) ether_addr_copy(icmp_packet_rr->rr[0], addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) "Error - can't send packet from char device: got unknown message type\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) len = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) goto free_skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) icmp_header->uid = socket_client->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) if (icmp_header->version != BATADV_COMPAT_VERSION) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) icmp_header->msg_type = BATADV_PARAMETER_PROBLEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) icmp_header->version = BATADV_COMPAT_VERSION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) batadv_socket_add_packet(socket_client, icmp_header,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) packet_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) goto free_skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) ether_addr_copy(icmp_header->orig, primary_if->net_dev->dev_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) batadv_send_unicast_skb(skb, neigh_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) dst_unreach:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) icmp_header->msg_type = BATADV_DESTINATION_UNREACHABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) batadv_socket_add_packet(socket_client, icmp_header, packet_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) free_skb:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) if (primary_if)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) batadv_hardif_put(primary_if);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) if (neigh_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) batadv_neigh_node_put(neigh_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) if (orig_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) batadv_orig_node_put(orig_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) static __poll_t batadv_socket_poll(struct file *file, poll_table *wait)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) struct batadv_socket_client *socket_client = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) poll_wait(file, &socket_client->queue_wait, wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) if (socket_client->queue_len > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) return EPOLLIN | EPOLLRDNORM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) static const struct file_operations batadv_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) .open = batadv_socket_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) .release = batadv_socket_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) .read = batadv_socket_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) .write = batadv_socket_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) .poll = batadv_socket_poll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) .llseek = no_llseek,
^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) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) * batadv_socket_setup() - Create debugfs "socket" file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) void batadv_socket_setup(struct batadv_priv *bat_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) debugfs_create_file(BATADV_ICMP_SOCKET, 0600, bat_priv->debug_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) bat_priv, &batadv_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) * batadv_socket_add_packet() - schedule an icmp packet to be sent to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) * userspace on an icmp socket.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) * @socket_client: the socket this packet belongs to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) * @icmph: pointer to the header of the icmp packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) * @icmp_len: total length of the icmp packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) static void batadv_socket_add_packet(struct batadv_socket_client *socket_client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) struct batadv_icmp_header *icmph,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) size_t icmp_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) struct batadv_socket_packet *socket_packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) size_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) socket_packet = kmalloc(sizeof(*socket_packet), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) if (!socket_packet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) len = icmp_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) /* check the maximum length before filling the buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) if (len > sizeof(socket_packet->icmp_packet))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) len = sizeof(socket_packet->icmp_packet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) INIT_LIST_HEAD(&socket_packet->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) memcpy(&socket_packet->icmp_packet, icmph, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) socket_packet->icmp_len = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) spin_lock_bh(&socket_client->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) /* while waiting for the lock the socket_client could have been
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) * deleted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) if (!batadv_socket_client_hash[icmph->uid]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) spin_unlock_bh(&socket_client->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) kfree(socket_packet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) list_add_tail(&socket_packet->list, &socket_client->queue_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) socket_client->queue_len++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) if (socket_client->queue_len > 100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) socket_packet = list_first_entry(&socket_client->queue_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) struct batadv_socket_packet,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) list_del(&socket_packet->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) kfree(socket_packet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) socket_client->queue_len--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) spin_unlock_bh(&socket_client->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) wake_up(&socket_client->queue_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) * batadv_socket_receive_packet() - schedule an icmp packet to be received
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) * locally and sent to userspace.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) * @icmph: pointer to the header of the icmp packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) * @icmp_len: total length of the icmp packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) void batadv_socket_receive_packet(struct batadv_icmp_header *icmph,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) size_t icmp_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) struct batadv_socket_client *hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) hash = batadv_socket_client_hash[icmph->uid];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) if (hash)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) batadv_socket_add_packet(hash, icmph, icmp_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }