^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /* Copyright (C) 2007-2020 B.A.T.M.A.N. contributors:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Marek Lindner, Simon Wunderlich
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include "hard-interface.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include "main.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/atomic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/byteorder/generic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/gfp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/if.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/if_arp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/if_ether.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/kref.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/limits.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/printk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/rculist.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/rtnetlink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <net/net_namespace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <net/rtnetlink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <uapi/linux/batadv_packet.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include "bat_v.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include "bridge_loop_avoidance.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include "debugfs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include "distributed-arp-table.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include "gateway_client.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include "log.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include "originator.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include "send.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include "soft-interface.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include "sysfs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include "translation-table.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * batadv_hardif_release() - release hard interface from lists and queue for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * free after rcu grace period
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * @ref: kref pointer of the hard interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) void batadv_hardif_release(struct kref *ref)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) struct batadv_hard_iface *hard_iface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) hard_iface = container_of(ref, struct batadv_hard_iface, refcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) dev_put(hard_iface->net_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) kfree_rcu(hard_iface, rcu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * batadv_hardif_get_by_netdev() - Get hard interface object of a net_device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * @net_dev: net_device to search for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * Return: batadv_hard_iface of net_dev (with increased refcnt), NULL on errors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) struct batadv_hard_iface *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) batadv_hardif_get_by_netdev(const struct net_device *net_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) struct batadv_hard_iface *hard_iface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) if (hard_iface->net_dev == net_dev &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) kref_get_unless_zero(&hard_iface->refcount))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) hard_iface = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) return hard_iface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * batadv_getlink_net() - return link net namespace (of use fallback)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * @netdev: net_device to check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * @fallback_net: return in case get_link_net is not available for @netdev
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * Return: result of rtnl_link_ops->get_link_net or @fallback_net
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) static struct net *batadv_getlink_net(const struct net_device *netdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) struct net *fallback_net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) if (!netdev->rtnl_link_ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) return fallback_net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) if (!netdev->rtnl_link_ops->get_link_net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) return fallback_net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) return netdev->rtnl_link_ops->get_link_net(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) * batadv_mutual_parents() - check if two devices are each others parent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * @dev1: 1st net dev
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * @net1: 1st devices netns
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * @dev2: 2nd net dev
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * @net2: 2nd devices netns
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * veth devices come in pairs and each is the parent of the other!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * Return: true if the devices are each others parent, otherwise false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) static bool batadv_mutual_parents(const struct net_device *dev1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) struct net *net1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) const struct net_device *dev2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) struct net *net2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) int dev1_parent_iflink = dev_get_iflink(dev1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) int dev2_parent_iflink = dev_get_iflink(dev2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) const struct net *dev1_parent_net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) const struct net *dev2_parent_net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) dev1_parent_net = batadv_getlink_net(dev1, net1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) dev2_parent_net = batadv_getlink_net(dev2, net2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) if (!dev1_parent_iflink || !dev2_parent_iflink)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) return (dev1_parent_iflink == dev2->ifindex) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) (dev2_parent_iflink == dev1->ifindex) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) net_eq(dev1_parent_net, net2) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) net_eq(dev2_parent_net, net1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) * batadv_is_on_batman_iface() - check if a device is a batman iface descendant
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) * @net_dev: the device to check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) * If the user creates any virtual device on top of a batman-adv interface, it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) * is important to prevent this new interface from being used to create a new
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) * mesh network (this behaviour would lead to a batman-over-batman
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * configuration). This function recursively checks all the fathers of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) * device passed as argument looking for a batman-adv soft interface.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) * Return: true if the device is descendant of a batman-adv mesh interface (or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) * if it is a batman-adv interface itself), false otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) static bool batadv_is_on_batman_iface(const struct net_device *net_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) struct net *net = dev_net(net_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) struct net_device *parent_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) struct net *parent_net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) int iflink;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) bool ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) /* check if this is a batman-adv mesh interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) if (batadv_softif_is_valid(net_dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) iflink = dev_get_iflink(net_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) if (iflink == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) parent_net = batadv_getlink_net(net_dev, net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) /* iflink to itself, most likely physical device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) if (net == parent_net && iflink == net_dev->ifindex)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) /* recurse over the parent device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) parent_dev = __dev_get_by_index((struct net *)parent_net, iflink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) /* if we got a NULL parent_dev there is something broken.. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) if (!parent_dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) pr_err("Cannot find parent device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) if (batadv_mutual_parents(net_dev, net, parent_dev, parent_net))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) ret = batadv_is_on_batman_iface(parent_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) static bool batadv_is_valid_iface(const struct net_device *net_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) if (net_dev->flags & IFF_LOOPBACK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) if (net_dev->type != ARPHRD_ETHER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) if (net_dev->addr_len != ETH_ALEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) /* no batman over batman */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) if (batadv_is_on_batman_iface(net_dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) * batadv_get_real_netdevice() - check if the given netdev struct is a virtual
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) * interface on top of another 'real' interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) * @netdev: the device to check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) * Callers must hold the rtnl semaphore. You may want batadv_get_real_netdev()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) * instead of this.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) * Return: the 'real' net device or the original net device and NULL in case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) * of an error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) static struct net_device *batadv_get_real_netdevice(struct net_device *netdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) struct batadv_hard_iface *hard_iface = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) struct net_device *real_netdev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) struct net *real_net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) struct net *net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) int iflink;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) ASSERT_RTNL();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) if (!netdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) iflink = dev_get_iflink(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) if (iflink == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) dev_hold(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) return netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) hard_iface = batadv_hardif_get_by_netdev(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) if (!hard_iface || !hard_iface->soft_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) net = dev_net(hard_iface->soft_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) real_net = batadv_getlink_net(netdev, net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) /* iflink to itself, most likely physical device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) if (net == real_net && netdev->ifindex == iflink) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) real_netdev = netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) dev_hold(real_netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) real_netdev = dev_get_by_index(real_net, iflink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) if (hard_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) batadv_hardif_put(hard_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) return real_netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) * batadv_get_real_netdev() - check if the given net_device struct is a virtual
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) * interface on top of another 'real' interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) * @net_device: the device to check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) * Return: the 'real' net device or the original net device and NULL in case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) * of an error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) struct net_device *batadv_get_real_netdev(struct net_device *net_device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) struct net_device *real_netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) rtnl_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) real_netdev = batadv_get_real_netdevice(net_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) return real_netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) * batadv_is_wext_netdev() - check if the given net_device struct is a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) * wext wifi interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) * @net_device: the device to check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) * Return: true if the net device is a wext wireless device, false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) * otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) static bool batadv_is_wext_netdev(struct net_device *net_device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) if (!net_device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) #ifdef CONFIG_WIRELESS_EXT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) /* pre-cfg80211 drivers have to implement WEXT, so it is possible to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) * check for wireless_handlers != NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) if (net_device->wireless_handlers)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) }
^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) * batadv_is_cfg80211_netdev() - check if the given net_device struct is a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) * cfg80211 wifi interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) * @net_device: the device to check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) * Return: true if the net device is a cfg80211 wireless device, false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) * otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) static bool batadv_is_cfg80211_netdev(struct net_device *net_device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) if (!net_device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) /* cfg80211 drivers have to set ieee80211_ptr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) if (net_device->ieee80211_ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) }
^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) * batadv_wifi_flags_evaluate() - calculate wifi flags for net_device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) * @net_device: the device to check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) * Return: batadv_hard_iface_wifi_flags flags of the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) static u32 batadv_wifi_flags_evaluate(struct net_device *net_device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) u32 wifi_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) struct net_device *real_netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) if (batadv_is_wext_netdev(net_device))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) wifi_flags |= BATADV_HARDIF_WIFI_WEXT_DIRECT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) if (batadv_is_cfg80211_netdev(net_device))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) wifi_flags |= BATADV_HARDIF_WIFI_CFG80211_DIRECT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) real_netdev = batadv_get_real_netdevice(net_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) if (!real_netdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) return wifi_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) if (real_netdev == net_device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) if (batadv_is_wext_netdev(real_netdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) wifi_flags |= BATADV_HARDIF_WIFI_WEXT_INDIRECT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) if (batadv_is_cfg80211_netdev(real_netdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) wifi_flags |= BATADV_HARDIF_WIFI_CFG80211_INDIRECT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) dev_put(real_netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) return wifi_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) * batadv_is_cfg80211_hardif() - check if the given hardif is a cfg80211 wifi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) * interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) * @hard_iface: the device to check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) * Return: true if the net device is a cfg80211 wireless device, false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) * otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) bool batadv_is_cfg80211_hardif(struct batadv_hard_iface *hard_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) u32 allowed_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) allowed_flags |= BATADV_HARDIF_WIFI_CFG80211_DIRECT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) allowed_flags |= BATADV_HARDIF_WIFI_CFG80211_INDIRECT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) return !!(hard_iface->wifi_flags & allowed_flags);
^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) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) * batadv_is_wifi_hardif() - check if the given hardif is a wifi interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) * @hard_iface: the device to check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) * Return: true if the net device is a 802.11 wireless device, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) bool batadv_is_wifi_hardif(struct batadv_hard_iface *hard_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) if (!hard_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) return hard_iface->wifi_flags != 0;
^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) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) * batadv_hardif_no_broadcast() - check whether (re)broadcast is necessary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) * @if_outgoing: the outgoing interface checked and considered for (re)broadcast
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) * @orig_addr: the originator of this packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) * @orig_neigh: originator address of the forwarder we just got the packet from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) * (NULL if we originated)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) * Checks whether a packet needs to be (re)broadcasted on the given interface.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) * Return:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) * BATADV_HARDIF_BCAST_NORECIPIENT: No neighbor on interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) * BATADV_HARDIF_BCAST_DUPFWD: Just one neighbor, but it is the forwarder
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) * BATADV_HARDIF_BCAST_DUPORIG: Just one neighbor, but it is the originator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) * BATADV_HARDIF_BCAST_OK: Several neighbors, must broadcast
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) int batadv_hardif_no_broadcast(struct batadv_hard_iface *if_outgoing,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) u8 *orig_addr, u8 *orig_neigh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) struct batadv_hardif_neigh_node *hardif_neigh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) struct hlist_node *first;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) int ret = BATADV_HARDIF_BCAST_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) /* 0 neighbors -> no (re)broadcast */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) first = rcu_dereference(hlist_first_rcu(&if_outgoing->neigh_list));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) if (!first) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) ret = BATADV_HARDIF_BCAST_NORECIPIENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) /* >1 neighbors -> (re)brodcast */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if (rcu_dereference(hlist_next_rcu(first)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) hardif_neigh = hlist_entry(first, struct batadv_hardif_neigh_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) /* 1 neighbor, is the originator -> no rebroadcast */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) if (orig_addr && batadv_compare_eth(hardif_neigh->orig, orig_addr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) ret = BATADV_HARDIF_BCAST_DUPORIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) /* 1 neighbor, is the one we received from -> no rebroadcast */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) } else if (orig_neigh &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) batadv_compare_eth(hardif_neigh->orig, orig_neigh)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) ret = BATADV_HARDIF_BCAST_DUPFWD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) static struct batadv_hard_iface *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) batadv_hardif_get_active(const struct net_device *soft_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) struct batadv_hard_iface *hard_iface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) if (hard_iface->soft_iface != soft_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) if (hard_iface->if_status == BATADV_IF_ACTIVE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) kref_get_unless_zero(&hard_iface->refcount))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) hard_iface = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) return hard_iface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) static void batadv_primary_if_update_addr(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) struct batadv_hard_iface *oldif)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) struct batadv_hard_iface *primary_if;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) primary_if = batadv_primary_if_get_selected(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) if (!primary_if)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) batadv_dat_init_own_addr(bat_priv, primary_if);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) batadv_bla_update_orig_address(bat_priv, primary_if, oldif);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) if (primary_if)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) batadv_hardif_put(primary_if);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) static void batadv_primary_if_select(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) struct batadv_hard_iface *new_hard_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) struct batadv_hard_iface *curr_hard_iface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) ASSERT_RTNL();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) if (new_hard_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) kref_get(&new_hard_iface->refcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) curr_hard_iface = rcu_replace_pointer(bat_priv->primary_if,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) new_hard_iface, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) if (!new_hard_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) bat_priv->algo_ops->iface.primary_set(new_hard_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) batadv_primary_if_update_addr(bat_priv, curr_hard_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) if (curr_hard_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) batadv_hardif_put(curr_hard_iface);
^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) static bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) batadv_hardif_is_iface_up(const struct batadv_hard_iface *hard_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) if (hard_iface->net_dev->flags & IFF_UP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) static void batadv_check_known_mac_addr(const struct net_device *net_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) const struct batadv_hard_iface *hard_iface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) if (hard_iface->if_status != BATADV_IF_ACTIVE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) hard_iface->if_status != BATADV_IF_TO_BE_ACTIVATED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) if (hard_iface->net_dev == net_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) if (!batadv_compare_eth(hard_iface->net_dev->dev_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) net_dev->dev_addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) pr_warn("The newly added mac address (%pM) already exists on: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) net_dev->dev_addr, hard_iface->net_dev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) pr_warn("It is strongly recommended to keep mac addresses unique to avoid problems!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) * batadv_hardif_recalc_extra_skbroom() - Recalculate skbuff extra head/tailroom
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) * @soft_iface: netdev struct of the mesh interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) static void batadv_hardif_recalc_extra_skbroom(struct net_device *soft_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) const struct batadv_hard_iface *hard_iface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) unsigned short lower_header_len = ETH_HLEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) unsigned short lower_headroom = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) unsigned short lower_tailroom = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) unsigned short needed_headroom;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) if (hard_iface->if_status == BATADV_IF_NOT_IN_USE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) if (hard_iface->soft_iface != soft_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) lower_header_len = max_t(unsigned short, lower_header_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) hard_iface->net_dev->hard_header_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) lower_headroom = max_t(unsigned short, lower_headroom,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) hard_iface->net_dev->needed_headroom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) lower_tailroom = max_t(unsigned short, lower_tailroom,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) hard_iface->net_dev->needed_tailroom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) needed_headroom = lower_headroom + (lower_header_len - ETH_HLEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) needed_headroom += batadv_max_header_len();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) /* fragmentation headers don't strip the unicast/... header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) needed_headroom += sizeof(struct batadv_frag_packet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) soft_iface->needed_headroom = needed_headroom;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) soft_iface->needed_tailroom = lower_tailroom;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) * batadv_hardif_min_mtu() - Calculate maximum MTU for soft interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) * @soft_iface: netdev struct of the soft interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) * Return: MTU for the soft-interface (limited by the minimal MTU of all active
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) * slave interfaces)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) int batadv_hardif_min_mtu(struct net_device *soft_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) struct batadv_priv *bat_priv = netdev_priv(soft_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) const struct batadv_hard_iface *hard_iface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) int min_mtu = INT_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) if (hard_iface->if_status != BATADV_IF_ACTIVE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) hard_iface->if_status != BATADV_IF_TO_BE_ACTIVATED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) if (hard_iface->soft_iface != soft_iface)
^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) min_mtu = min_t(int, hard_iface->net_dev->mtu, min_mtu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) if (atomic_read(&bat_priv->fragmentation) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) /* with fragmentation enabled the maximum size of internally generated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) * packets such as translation table exchanges or tvlv containers, etc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) * has to be calculated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) min_mtu = min_t(int, min_mtu, BATADV_FRAG_MAX_FRAG_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) min_mtu -= sizeof(struct batadv_frag_packet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) min_mtu *= BATADV_FRAG_MAX_FRAGMENTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) /* report to the other components the maximum amount of bytes that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) * batman-adv can send over the wire (without considering the payload
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) * overhead). For example, this value is used by TT to compute the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) * maximum local table size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) atomic_set(&bat_priv->packet_size_max, min_mtu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) /* the real soft-interface MTU is computed by removing the payload
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) * overhead from the maximum amount of bytes that was just computed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) * However batman-adv does not support MTUs bigger than ETH_DATA_LEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) return min_t(int, min_mtu - batadv_max_header_len(), ETH_DATA_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) * batadv_update_min_mtu() - Adjusts the MTU if a new interface with a smaller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) * MTU appeared
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) * @soft_iface: netdev struct of the soft interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) void batadv_update_min_mtu(struct net_device *soft_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) soft_iface->mtu = batadv_hardif_min_mtu(soft_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) /* Check if the local translate table should be cleaned up to match a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) * new (and smaller) MTU.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) batadv_tt_local_resize_to_mtu(soft_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) batadv_hardif_activate_interface(struct batadv_hard_iface *hard_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) struct batadv_priv *bat_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) struct batadv_hard_iface *primary_if = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) if (hard_iface->if_status != BATADV_IF_INACTIVE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) bat_priv = netdev_priv(hard_iface->soft_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) bat_priv->algo_ops->iface.update_mac(hard_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) hard_iface->if_status = BATADV_IF_TO_BE_ACTIVATED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) /* the first active interface becomes our primary interface or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) * the next active interface after the old primary interface was removed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) primary_if = batadv_primary_if_get_selected(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) if (!primary_if)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) batadv_primary_if_select(bat_priv, hard_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) batadv_info(hard_iface->soft_iface, "Interface activated: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) hard_iface->net_dev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) batadv_update_min_mtu(hard_iface->soft_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) if (bat_priv->algo_ops->iface.activate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) bat_priv->algo_ops->iface.activate(hard_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) if (primary_if)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) batadv_hardif_put(primary_if);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) batadv_hardif_deactivate_interface(struct batadv_hard_iface *hard_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) if (hard_iface->if_status != BATADV_IF_ACTIVE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) hard_iface->if_status != BATADV_IF_TO_BE_ACTIVATED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) hard_iface->if_status = BATADV_IF_INACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) batadv_info(hard_iface->soft_iface, "Interface deactivated: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) hard_iface->net_dev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) batadv_update_min_mtu(hard_iface->soft_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) * batadv_master_del_slave() - remove hard_iface from the current master iface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) * @slave: the interface enslaved in another master
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) * @master: the master from which slave has to be removed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) * Invoke ndo_del_slave on master passing slave as argument. In this way the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) * slave is free'd and the master can correctly change its internal state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) * Return: 0 on success, a negative value representing the error otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) static int batadv_master_del_slave(struct batadv_hard_iface *slave,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) struct net_device *master)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) if (!master)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) ret = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) if (master->netdev_ops->ndo_del_slave)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) ret = master->netdev_ops->ndo_del_slave(master, slave->net_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) * batadv_hardif_enable_interface() - Enslave hard interface to soft interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) * @hard_iface: hard interface to add to soft interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) * @net: the applicable net namespace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) * @iface_name: name of the soft interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) * Return: 0 on success or negative error number in case of failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) struct net *net, const char *iface_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) struct batadv_priv *bat_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) struct net_device *soft_iface, *master;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) __be16 ethertype = htons(ETH_P_BATMAN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) int max_header_len = batadv_max_header_len();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) if (hard_iface->if_status != BATADV_IF_NOT_IN_USE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) kref_get(&hard_iface->refcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) soft_iface = dev_get_by_name(net, iface_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) if (!soft_iface) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) soft_iface = batadv_softif_create(net, iface_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) if (!soft_iface) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) /* dev_get_by_name() increases the reference counter for us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) dev_hold(soft_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) if (!batadv_softif_is_valid(soft_iface)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) pr_err("Can't create batman mesh interface %s: already exists as regular interface\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) soft_iface->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) goto err_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) /* check if the interface is enslaved in another virtual one and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) * in that case unlink it first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) master = netdev_master_upper_dev_get(hard_iface->net_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) ret = batadv_master_del_slave(hard_iface, master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) goto err_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) hard_iface->soft_iface = soft_iface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) bat_priv = netdev_priv(hard_iface->soft_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) ret = netdev_master_upper_dev_link(hard_iface->net_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) soft_iface, NULL, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) goto err_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) ret = bat_priv->algo_ops->iface.enable(hard_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) goto err_upper;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) hard_iface->if_status = BATADV_IF_INACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) kref_get(&hard_iface->refcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) hard_iface->batman_adv_ptype.type = ethertype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) hard_iface->batman_adv_ptype.func = batadv_batman_skb_recv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) hard_iface->batman_adv_ptype.dev = hard_iface->net_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) dev_add_pack(&hard_iface->batman_adv_ptype);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) batadv_info(hard_iface->soft_iface, "Adding interface: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) hard_iface->net_dev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) if (atomic_read(&bat_priv->fragmentation) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) hard_iface->net_dev->mtu < ETH_DATA_LEN + max_header_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) batadv_info(hard_iface->soft_iface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) "The MTU of interface %s is too small (%i) to handle the transport of batman-adv packets. Packets going over this interface will be fragmented on layer2 which could impact the performance. Setting the MTU to %i would solve the problem.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) hard_iface->net_dev->name, hard_iface->net_dev->mtu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) ETH_DATA_LEN + max_header_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) if (!atomic_read(&bat_priv->fragmentation) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) hard_iface->net_dev->mtu < ETH_DATA_LEN + max_header_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) batadv_info(hard_iface->soft_iface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) "The MTU of interface %s is too small (%i) to handle the transport of batman-adv packets. If you experience problems getting traffic through try increasing the MTU to %i.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) hard_iface->net_dev->name, hard_iface->net_dev->mtu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) ETH_DATA_LEN + max_header_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) if (batadv_hardif_is_iface_up(hard_iface))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) batadv_hardif_activate_interface(hard_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) batadv_err(hard_iface->soft_iface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) "Not using interface %s (retrying later): interface not active\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) hard_iface->net_dev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) batadv_hardif_recalc_extra_skbroom(soft_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) if (bat_priv->algo_ops->iface.enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) bat_priv->algo_ops->iface.enabled(hard_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) out:
^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) err_upper:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) netdev_upper_dev_unlink(hard_iface->net_dev, soft_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) err_dev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) hard_iface->soft_iface = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) dev_put(soft_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) batadv_hardif_put(hard_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) * batadv_hardif_cnt() - get number of interfaces enslaved to soft interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) * @soft_iface: soft interface to check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) * This function is only using RCU for locking - the result can therefore be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) * off when another function is modifying the list at the same time. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) * caller can use the rtnl_lock to make sure that the count is accurate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) * Return: number of connected/enslaved hard interfaces
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) static size_t batadv_hardif_cnt(const struct net_device *soft_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) struct batadv_hard_iface *hard_iface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) size_t count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) if (hard_iface->soft_iface != soft_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) * batadv_hardif_disable_interface() - Remove hard interface from soft interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) * @hard_iface: hard interface to be removed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) * @autodel: whether to delete soft interface when it doesn't contain any other
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) * slave interfaces
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) void batadv_hardif_disable_interface(struct batadv_hard_iface *hard_iface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) enum batadv_hard_if_cleanup autodel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) struct batadv_hard_iface *primary_if = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) batadv_hardif_deactivate_interface(hard_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) if (hard_iface->if_status != BATADV_IF_INACTIVE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) batadv_info(hard_iface->soft_iface, "Removing interface: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) hard_iface->net_dev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) dev_remove_pack(&hard_iface->batman_adv_ptype);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) batadv_hardif_put(hard_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) primary_if = batadv_primary_if_get_selected(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) if (hard_iface == primary_if) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) struct batadv_hard_iface *new_if;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) new_if = batadv_hardif_get_active(hard_iface->soft_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) batadv_primary_if_select(bat_priv, new_if);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) if (new_if)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) batadv_hardif_put(new_if);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) bat_priv->algo_ops->iface.disable(hard_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) hard_iface->if_status = BATADV_IF_NOT_IN_USE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) /* delete all references to this hard_iface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) batadv_purge_orig_ref(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) batadv_purge_outstanding_packets(bat_priv, hard_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) dev_put(hard_iface->soft_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) netdev_upper_dev_unlink(hard_iface->net_dev, hard_iface->soft_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) batadv_hardif_recalc_extra_skbroom(hard_iface->soft_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) /* nobody uses this interface anymore */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) if (batadv_hardif_cnt(hard_iface->soft_iface) <= 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) batadv_gw_check_client_stop(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) if (autodel == BATADV_IF_CLEANUP_AUTO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) batadv_softif_destroy_sysfs(hard_iface->soft_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) hard_iface->soft_iface = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) batadv_hardif_put(hard_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) if (primary_if)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) batadv_hardif_put(primary_if);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) static struct batadv_hard_iface *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) batadv_hardif_add_interface(struct net_device *net_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) struct batadv_hard_iface *hard_iface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) ASSERT_RTNL();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) if (!batadv_is_valid_iface(net_dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) dev_hold(net_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) hard_iface = kzalloc(sizeof(*hard_iface), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) if (!hard_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) goto release_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) ret = batadv_sysfs_add_hardif(&hard_iface->hardif_obj, net_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) goto free_if;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) hard_iface->net_dev = net_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) hard_iface->soft_iface = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) hard_iface->if_status = BATADV_IF_NOT_IN_USE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) batadv_debugfs_add_hardif(hard_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) INIT_LIST_HEAD(&hard_iface->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) INIT_HLIST_HEAD(&hard_iface->neigh_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) mutex_init(&hard_iface->bat_iv.ogm_buff_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) spin_lock_init(&hard_iface->neigh_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) kref_init(&hard_iface->refcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) hard_iface->num_bcasts = BATADV_NUM_BCASTS_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) hard_iface->wifi_flags = batadv_wifi_flags_evaluate(net_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) if (batadv_is_wifi_hardif(hard_iface))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) hard_iface->num_bcasts = BATADV_NUM_BCASTS_WIRELESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) atomic_set(&hard_iface->hop_penalty, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) batadv_v_hardif_init(hard_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) batadv_check_known_mac_addr(hard_iface->net_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) kref_get(&hard_iface->refcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) list_add_tail_rcu(&hard_iface->list, &batadv_hardif_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) batadv_hardif_generation++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) return hard_iface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) free_if:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) kfree(hard_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) release_dev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) dev_put(net_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) static void batadv_hardif_remove_interface(struct batadv_hard_iface *hard_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) ASSERT_RTNL();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) /* first deactivate interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) if (hard_iface->if_status != BATADV_IF_NOT_IN_USE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) batadv_hardif_disable_interface(hard_iface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) BATADV_IF_CLEANUP_KEEP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) if (hard_iface->if_status != BATADV_IF_NOT_IN_USE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) hard_iface->if_status = BATADV_IF_TO_BE_REMOVED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) batadv_debugfs_del_hardif(hard_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) batadv_sysfs_del_hardif(&hard_iface->hardif_obj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) batadv_hardif_put(hard_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) * batadv_hard_if_event_softif() - Handle events for soft interfaces
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) * @event: NETDEV_* event to handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) * @net_dev: net_device which generated an event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) * Return: NOTIFY_* result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) static int batadv_hard_if_event_softif(unsigned long event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) struct net_device *net_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) struct batadv_priv *bat_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) switch (event) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) case NETDEV_REGISTER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) batadv_sysfs_add_meshif(net_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) bat_priv = netdev_priv(net_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) batadv_softif_create_vlan(bat_priv, BATADV_NO_FLAGS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) case NETDEV_CHANGENAME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) batadv_debugfs_rename_meshif(net_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) return NOTIFY_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) static int batadv_hard_if_event(struct notifier_block *this,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) unsigned long event, void *ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) struct net_device *net_dev = netdev_notifier_info_to_dev(ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) struct batadv_hard_iface *hard_iface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) struct batadv_hard_iface *primary_if = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) struct batadv_priv *bat_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) if (batadv_softif_is_valid(net_dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) return batadv_hard_if_event_softif(event, net_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) hard_iface = batadv_hardif_get_by_netdev(net_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) if (!hard_iface && (event == NETDEV_REGISTER ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) event == NETDEV_POST_TYPE_CHANGE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) hard_iface = batadv_hardif_add_interface(net_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) if (!hard_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) switch (event) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) case NETDEV_UP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) batadv_hardif_activate_interface(hard_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) case NETDEV_GOING_DOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) case NETDEV_DOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) batadv_hardif_deactivate_interface(hard_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) case NETDEV_UNREGISTER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) case NETDEV_PRE_TYPE_CHANGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) list_del_rcu(&hard_iface->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) batadv_hardif_generation++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) batadv_hardif_remove_interface(hard_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) case NETDEV_CHANGEMTU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) if (hard_iface->soft_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) batadv_update_min_mtu(hard_iface->soft_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) case NETDEV_CHANGEADDR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) if (hard_iface->if_status == BATADV_IF_NOT_IN_USE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) goto hardif_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) batadv_check_known_mac_addr(hard_iface->net_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) bat_priv = netdev_priv(hard_iface->soft_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) bat_priv->algo_ops->iface.update_mac(hard_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) primary_if = batadv_primary_if_get_selected(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) if (!primary_if)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) goto hardif_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) if (hard_iface == primary_if)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) batadv_primary_if_update_addr(bat_priv, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) case NETDEV_CHANGEUPPER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) hard_iface->wifi_flags = batadv_wifi_flags_evaluate(net_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) if (batadv_is_wifi_hardif(hard_iface))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) hard_iface->num_bcasts = BATADV_NUM_BCASTS_WIRELESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) case NETDEV_CHANGENAME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) batadv_debugfs_rename_hardif(hard_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) hardif_put:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) batadv_hardif_put(hard_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) if (primary_if)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) batadv_hardif_put(primary_if);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) return NOTIFY_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) struct notifier_block batadv_hard_if_notifier = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) .notifier_call = batadv_hard_if_event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) };