Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /* Copyright (C) B.A.T.M.A.N. contributors:
0003  *
0004  * Marek Lindner, Simon Wunderlich
0005  */
0006 
0007 #include "hard-interface.h"
0008 #include "main.h"
0009 
0010 #include <linux/atomic.h>
0011 #include <linux/byteorder/generic.h>
0012 #include <linux/container_of.h>
0013 #include <linux/errno.h>
0014 #include <linux/gfp.h>
0015 #include <linux/if.h>
0016 #include <linux/if_arp.h>
0017 #include <linux/if_ether.h>
0018 #include <linux/kref.h>
0019 #include <linux/limits.h>
0020 #include <linux/list.h>
0021 #include <linux/minmax.h>
0022 #include <linux/mutex.h>
0023 #include <linux/netdevice.h>
0024 #include <linux/printk.h>
0025 #include <linux/rculist.h>
0026 #include <linux/rtnetlink.h>
0027 #include <linux/slab.h>
0028 #include <linux/spinlock.h>
0029 #include <net/net_namespace.h>
0030 #include <net/rtnetlink.h>
0031 #include <uapi/linux/batadv_packet.h>
0032 
0033 #include "bat_v.h"
0034 #include "bridge_loop_avoidance.h"
0035 #include "distributed-arp-table.h"
0036 #include "gateway_client.h"
0037 #include "log.h"
0038 #include "originator.h"
0039 #include "send.h"
0040 #include "soft-interface.h"
0041 #include "translation-table.h"
0042 
0043 /**
0044  * batadv_hardif_release() - release hard interface from lists and queue for
0045  *  free after rcu grace period
0046  * @ref: kref pointer of the hard interface
0047  */
0048 void batadv_hardif_release(struct kref *ref)
0049 {
0050     struct batadv_hard_iface *hard_iface;
0051 
0052     hard_iface = container_of(ref, struct batadv_hard_iface, refcount);
0053     dev_put(hard_iface->net_dev);
0054 
0055     kfree_rcu(hard_iface, rcu);
0056 }
0057 
0058 /**
0059  * batadv_hardif_get_by_netdev() - Get hard interface object of a net_device
0060  * @net_dev: net_device to search for
0061  *
0062  * Return: batadv_hard_iface of net_dev (with increased refcnt), NULL on errors
0063  */
0064 struct batadv_hard_iface *
0065 batadv_hardif_get_by_netdev(const struct net_device *net_dev)
0066 {
0067     struct batadv_hard_iface *hard_iface;
0068 
0069     rcu_read_lock();
0070     list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
0071         if (hard_iface->net_dev == net_dev &&
0072             kref_get_unless_zero(&hard_iface->refcount))
0073             goto out;
0074     }
0075 
0076     hard_iface = NULL;
0077 
0078 out:
0079     rcu_read_unlock();
0080     return hard_iface;
0081 }
0082 
0083 /**
0084  * batadv_getlink_net() - return link net namespace (of use fallback)
0085  * @netdev: net_device to check
0086  * @fallback_net: return in case get_link_net is not available for @netdev
0087  *
0088  * Return: result of rtnl_link_ops->get_link_net or @fallback_net
0089  */
0090 static struct net *batadv_getlink_net(const struct net_device *netdev,
0091                       struct net *fallback_net)
0092 {
0093     if (!netdev->rtnl_link_ops)
0094         return fallback_net;
0095 
0096     if (!netdev->rtnl_link_ops->get_link_net)
0097         return fallback_net;
0098 
0099     return netdev->rtnl_link_ops->get_link_net(netdev);
0100 }
0101 
0102 /**
0103  * batadv_mutual_parents() - check if two devices are each others parent
0104  * @dev1: 1st net dev
0105  * @net1: 1st devices netns
0106  * @dev2: 2nd net dev
0107  * @net2: 2nd devices netns
0108  *
0109  * veth devices come in pairs and each is the parent of the other!
0110  *
0111  * Return: true if the devices are each others parent, otherwise false
0112  */
0113 static bool batadv_mutual_parents(const struct net_device *dev1,
0114                   struct net *net1,
0115                   const struct net_device *dev2,
0116                   struct net *net2)
0117 {
0118     int dev1_parent_iflink = dev_get_iflink(dev1);
0119     int dev2_parent_iflink = dev_get_iflink(dev2);
0120     const struct net *dev1_parent_net;
0121     const struct net *dev2_parent_net;
0122 
0123     dev1_parent_net = batadv_getlink_net(dev1, net1);
0124     dev2_parent_net = batadv_getlink_net(dev2, net2);
0125 
0126     if (!dev1_parent_iflink || !dev2_parent_iflink)
0127         return false;
0128 
0129     return (dev1_parent_iflink == dev2->ifindex) &&
0130            (dev2_parent_iflink == dev1->ifindex) &&
0131            net_eq(dev1_parent_net, net2) &&
0132            net_eq(dev2_parent_net, net1);
0133 }
0134 
0135 /**
0136  * batadv_is_on_batman_iface() - check if a device is a batman iface descendant
0137  * @net_dev: the device to check
0138  *
0139  * If the user creates any virtual device on top of a batman-adv interface, it
0140  * is important to prevent this new interface from being used to create a new
0141  * mesh network (this behaviour would lead to a batman-over-batman
0142  * configuration). This function recursively checks all the fathers of the
0143  * device passed as argument looking for a batman-adv soft interface.
0144  *
0145  * Return: true if the device is descendant of a batman-adv mesh interface (or
0146  * if it is a batman-adv interface itself), false otherwise
0147  */
0148 static bool batadv_is_on_batman_iface(const struct net_device *net_dev)
0149 {
0150     struct net *net = dev_net(net_dev);
0151     struct net_device *parent_dev;
0152     struct net *parent_net;
0153     int iflink;
0154     bool ret;
0155 
0156     /* check if this is a batman-adv mesh interface */
0157     if (batadv_softif_is_valid(net_dev))
0158         return true;
0159 
0160     iflink = dev_get_iflink(net_dev);
0161     if (iflink == 0)
0162         return false;
0163 
0164     parent_net = batadv_getlink_net(net_dev, net);
0165 
0166     /* iflink to itself, most likely physical device */
0167     if (net == parent_net && iflink == net_dev->ifindex)
0168         return false;
0169 
0170     /* recurse over the parent device */
0171     parent_dev = __dev_get_by_index((struct net *)parent_net, iflink);
0172     if (!parent_dev) {
0173         pr_warn("Cannot find parent device. Skipping batadv-on-batadv check for %s\n",
0174             net_dev->name);
0175         return false;
0176     }
0177 
0178     if (batadv_mutual_parents(net_dev, net, parent_dev, parent_net))
0179         return false;
0180 
0181     ret = batadv_is_on_batman_iface(parent_dev);
0182 
0183     return ret;
0184 }
0185 
0186 static bool batadv_is_valid_iface(const struct net_device *net_dev)
0187 {
0188     if (net_dev->flags & IFF_LOOPBACK)
0189         return false;
0190 
0191     if (net_dev->type != ARPHRD_ETHER)
0192         return false;
0193 
0194     if (net_dev->addr_len != ETH_ALEN)
0195         return false;
0196 
0197     /* no batman over batman */
0198     if (batadv_is_on_batman_iface(net_dev))
0199         return false;
0200 
0201     return true;
0202 }
0203 
0204 /**
0205  * batadv_get_real_netdevice() - check if the given netdev struct is a virtual
0206  *  interface on top of another 'real' interface
0207  * @netdev: the device to check
0208  *
0209  * Callers must hold the rtnl semaphore. You may want batadv_get_real_netdev()
0210  * instead of this.
0211  *
0212  * Return: the 'real' net device or the original net device and NULL in case
0213  *  of an error.
0214  */
0215 static struct net_device *batadv_get_real_netdevice(struct net_device *netdev)
0216 {
0217     struct batadv_hard_iface *hard_iface = NULL;
0218     struct net_device *real_netdev = NULL;
0219     struct net *real_net;
0220     struct net *net;
0221     int iflink;
0222 
0223     ASSERT_RTNL();
0224 
0225     if (!netdev)
0226         return NULL;
0227 
0228     iflink = dev_get_iflink(netdev);
0229     if (iflink == 0) {
0230         dev_hold(netdev);
0231         return netdev;
0232     }
0233 
0234     hard_iface = batadv_hardif_get_by_netdev(netdev);
0235     if (!hard_iface || !hard_iface->soft_iface)
0236         goto out;
0237 
0238     net = dev_net(hard_iface->soft_iface);
0239     real_net = batadv_getlink_net(netdev, net);
0240 
0241     /* iflink to itself, most likely physical device */
0242     if (net == real_net && netdev->ifindex == iflink) {
0243         real_netdev = netdev;
0244         dev_hold(real_netdev);
0245         goto out;
0246     }
0247 
0248     real_netdev = dev_get_by_index(real_net, iflink);
0249 
0250 out:
0251     batadv_hardif_put(hard_iface);
0252     return real_netdev;
0253 }
0254 
0255 /**
0256  * batadv_get_real_netdev() - check if the given net_device struct is a virtual
0257  *  interface on top of another 'real' interface
0258  * @net_device: the device to check
0259  *
0260  * Return: the 'real' net device or the original net device and NULL in case
0261  *  of an error.
0262  */
0263 struct net_device *batadv_get_real_netdev(struct net_device *net_device)
0264 {
0265     struct net_device *real_netdev;
0266 
0267     rtnl_lock();
0268     real_netdev = batadv_get_real_netdevice(net_device);
0269     rtnl_unlock();
0270 
0271     return real_netdev;
0272 }
0273 
0274 /**
0275  * batadv_is_wext_netdev() - check if the given net_device struct is a
0276  *  wext wifi interface
0277  * @net_device: the device to check
0278  *
0279  * Return: true if the net device is a wext wireless device, false
0280  *  otherwise.
0281  */
0282 static bool batadv_is_wext_netdev(struct net_device *net_device)
0283 {
0284     if (!net_device)
0285         return false;
0286 
0287 #ifdef CONFIG_WIRELESS_EXT
0288     /* pre-cfg80211 drivers have to implement WEXT, so it is possible to
0289      * check for wireless_handlers != NULL
0290      */
0291     if (net_device->wireless_handlers)
0292         return true;
0293 #endif
0294 
0295     return false;
0296 }
0297 
0298 /**
0299  * batadv_is_cfg80211_netdev() - check if the given net_device struct is a
0300  *  cfg80211 wifi interface
0301  * @net_device: the device to check
0302  *
0303  * Return: true if the net device is a cfg80211 wireless device, false
0304  *  otherwise.
0305  */
0306 static bool batadv_is_cfg80211_netdev(struct net_device *net_device)
0307 {
0308     if (!net_device)
0309         return false;
0310 
0311 #if IS_ENABLED(CONFIG_CFG80211)
0312     /* cfg80211 drivers have to set ieee80211_ptr */
0313     if (net_device->ieee80211_ptr)
0314         return true;
0315 #endif
0316 
0317     return false;
0318 }
0319 
0320 /**
0321  * batadv_wifi_flags_evaluate() - calculate wifi flags for net_device
0322  * @net_device: the device to check
0323  *
0324  * Return: batadv_hard_iface_wifi_flags flags of the device
0325  */
0326 static u32 batadv_wifi_flags_evaluate(struct net_device *net_device)
0327 {
0328     u32 wifi_flags = 0;
0329     struct net_device *real_netdev;
0330 
0331     if (batadv_is_wext_netdev(net_device))
0332         wifi_flags |= BATADV_HARDIF_WIFI_WEXT_DIRECT;
0333 
0334     if (batadv_is_cfg80211_netdev(net_device))
0335         wifi_flags |= BATADV_HARDIF_WIFI_CFG80211_DIRECT;
0336 
0337     real_netdev = batadv_get_real_netdevice(net_device);
0338     if (!real_netdev)
0339         return wifi_flags;
0340 
0341     if (real_netdev == net_device)
0342         goto out;
0343 
0344     if (batadv_is_wext_netdev(real_netdev))
0345         wifi_flags |= BATADV_HARDIF_WIFI_WEXT_INDIRECT;
0346 
0347     if (batadv_is_cfg80211_netdev(real_netdev))
0348         wifi_flags |= BATADV_HARDIF_WIFI_CFG80211_INDIRECT;
0349 
0350 out:
0351     dev_put(real_netdev);
0352     return wifi_flags;
0353 }
0354 
0355 /**
0356  * batadv_is_cfg80211_hardif() - check if the given hardif is a cfg80211 wifi
0357  *  interface
0358  * @hard_iface: the device to check
0359  *
0360  * Return: true if the net device is a cfg80211 wireless device, false
0361  *  otherwise.
0362  */
0363 bool batadv_is_cfg80211_hardif(struct batadv_hard_iface *hard_iface)
0364 {
0365     u32 allowed_flags = 0;
0366 
0367     allowed_flags |= BATADV_HARDIF_WIFI_CFG80211_DIRECT;
0368     allowed_flags |= BATADV_HARDIF_WIFI_CFG80211_INDIRECT;
0369 
0370     return !!(hard_iface->wifi_flags & allowed_flags);
0371 }
0372 
0373 /**
0374  * batadv_is_wifi_hardif() - check if the given hardif is a wifi interface
0375  * @hard_iface: the device to check
0376  *
0377  * Return: true if the net device is a 802.11 wireless device, false otherwise.
0378  */
0379 bool batadv_is_wifi_hardif(struct batadv_hard_iface *hard_iface)
0380 {
0381     if (!hard_iface)
0382         return false;
0383 
0384     return hard_iface->wifi_flags != 0;
0385 }
0386 
0387 /**
0388  * batadv_hardif_no_broadcast() - check whether (re)broadcast is necessary
0389  * @if_outgoing: the outgoing interface checked and considered for (re)broadcast
0390  * @orig_addr: the originator of this packet
0391  * @orig_neigh: originator address of the forwarder we just got the packet from
0392  *  (NULL if we originated)
0393  *
0394  * Checks whether a packet needs to be (re)broadcasted on the given interface.
0395  *
0396  * Return:
0397  *  BATADV_HARDIF_BCAST_NORECIPIENT: No neighbor on interface
0398  *  BATADV_HARDIF_BCAST_DUPFWD: Just one neighbor, but it is the forwarder
0399  *  BATADV_HARDIF_BCAST_DUPORIG: Just one neighbor, but it is the originator
0400  *  BATADV_HARDIF_BCAST_OK: Several neighbors, must broadcast
0401  */
0402 int batadv_hardif_no_broadcast(struct batadv_hard_iface *if_outgoing,
0403                    u8 *orig_addr, u8 *orig_neigh)
0404 {
0405     struct batadv_hardif_neigh_node *hardif_neigh;
0406     struct hlist_node *first;
0407     int ret = BATADV_HARDIF_BCAST_OK;
0408 
0409     rcu_read_lock();
0410 
0411     /* 0 neighbors -> no (re)broadcast */
0412     first = rcu_dereference(hlist_first_rcu(&if_outgoing->neigh_list));
0413     if (!first) {
0414         ret = BATADV_HARDIF_BCAST_NORECIPIENT;
0415         goto out;
0416     }
0417 
0418     /* >1 neighbors -> (re)broadcast */
0419     if (rcu_dereference(hlist_next_rcu(first)))
0420         goto out;
0421 
0422     hardif_neigh = hlist_entry(first, struct batadv_hardif_neigh_node,
0423                    list);
0424 
0425     /* 1 neighbor, is the originator -> no rebroadcast */
0426     if (orig_addr && batadv_compare_eth(hardif_neigh->orig, orig_addr)) {
0427         ret = BATADV_HARDIF_BCAST_DUPORIG;
0428     /* 1 neighbor, is the one we received from -> no rebroadcast */
0429     } else if (orig_neigh &&
0430            batadv_compare_eth(hardif_neigh->orig, orig_neigh)) {
0431         ret = BATADV_HARDIF_BCAST_DUPFWD;
0432     }
0433 
0434 out:
0435     rcu_read_unlock();
0436     return ret;
0437 }
0438 
0439 static struct batadv_hard_iface *
0440 batadv_hardif_get_active(const struct net_device *soft_iface)
0441 {
0442     struct batadv_hard_iface *hard_iface;
0443 
0444     rcu_read_lock();
0445     list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
0446         if (hard_iface->soft_iface != soft_iface)
0447             continue;
0448 
0449         if (hard_iface->if_status == BATADV_IF_ACTIVE &&
0450             kref_get_unless_zero(&hard_iface->refcount))
0451             goto out;
0452     }
0453 
0454     hard_iface = NULL;
0455 
0456 out:
0457     rcu_read_unlock();
0458     return hard_iface;
0459 }
0460 
0461 static void batadv_primary_if_update_addr(struct batadv_priv *bat_priv,
0462                       struct batadv_hard_iface *oldif)
0463 {
0464     struct batadv_hard_iface *primary_if;
0465 
0466     primary_if = batadv_primary_if_get_selected(bat_priv);
0467     if (!primary_if)
0468         goto out;
0469 
0470     batadv_dat_init_own_addr(bat_priv, primary_if);
0471     batadv_bla_update_orig_address(bat_priv, primary_if, oldif);
0472 out:
0473     batadv_hardif_put(primary_if);
0474 }
0475 
0476 static void batadv_primary_if_select(struct batadv_priv *bat_priv,
0477                      struct batadv_hard_iface *new_hard_iface)
0478 {
0479     struct batadv_hard_iface *curr_hard_iface;
0480 
0481     ASSERT_RTNL();
0482 
0483     if (new_hard_iface)
0484         kref_get(&new_hard_iface->refcount);
0485 
0486     curr_hard_iface = rcu_replace_pointer(bat_priv->primary_if,
0487                           new_hard_iface, 1);
0488 
0489     if (!new_hard_iface)
0490         goto out;
0491 
0492     bat_priv->algo_ops->iface.primary_set(new_hard_iface);
0493     batadv_primary_if_update_addr(bat_priv, curr_hard_iface);
0494 
0495 out:
0496     batadv_hardif_put(curr_hard_iface);
0497 }
0498 
0499 static bool
0500 batadv_hardif_is_iface_up(const struct batadv_hard_iface *hard_iface)
0501 {
0502     if (hard_iface->net_dev->flags & IFF_UP)
0503         return true;
0504 
0505     return false;
0506 }
0507 
0508 static void batadv_check_known_mac_addr(const struct net_device *net_dev)
0509 {
0510     const struct batadv_hard_iface *hard_iface;
0511 
0512     rcu_read_lock();
0513     list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
0514         if (hard_iface->if_status != BATADV_IF_ACTIVE &&
0515             hard_iface->if_status != BATADV_IF_TO_BE_ACTIVATED)
0516             continue;
0517 
0518         if (hard_iface->net_dev == net_dev)
0519             continue;
0520 
0521         if (!batadv_compare_eth(hard_iface->net_dev->dev_addr,
0522                     net_dev->dev_addr))
0523             continue;
0524 
0525         pr_warn("The newly added mac address (%pM) already exists on: %s\n",
0526             net_dev->dev_addr, hard_iface->net_dev->name);
0527         pr_warn("It is strongly recommended to keep mac addresses unique to avoid problems!\n");
0528     }
0529     rcu_read_unlock();
0530 }
0531 
0532 /**
0533  * batadv_hardif_recalc_extra_skbroom() - Recalculate skbuff extra head/tailroom
0534  * @soft_iface: netdev struct of the mesh interface
0535  */
0536 static void batadv_hardif_recalc_extra_skbroom(struct net_device *soft_iface)
0537 {
0538     const struct batadv_hard_iface *hard_iface;
0539     unsigned short lower_header_len = ETH_HLEN;
0540     unsigned short lower_headroom = 0;
0541     unsigned short lower_tailroom = 0;
0542     unsigned short needed_headroom;
0543 
0544     rcu_read_lock();
0545     list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
0546         if (hard_iface->if_status == BATADV_IF_NOT_IN_USE)
0547             continue;
0548 
0549         if (hard_iface->soft_iface != soft_iface)
0550             continue;
0551 
0552         lower_header_len = max_t(unsigned short, lower_header_len,
0553                      hard_iface->net_dev->hard_header_len);
0554 
0555         lower_headroom = max_t(unsigned short, lower_headroom,
0556                        hard_iface->net_dev->needed_headroom);
0557 
0558         lower_tailroom = max_t(unsigned short, lower_tailroom,
0559                        hard_iface->net_dev->needed_tailroom);
0560     }
0561     rcu_read_unlock();
0562 
0563     needed_headroom = lower_headroom + (lower_header_len - ETH_HLEN);
0564     needed_headroom += batadv_max_header_len();
0565 
0566     /* fragmentation headers don't strip the unicast/... header */
0567     needed_headroom += sizeof(struct batadv_frag_packet);
0568 
0569     soft_iface->needed_headroom = needed_headroom;
0570     soft_iface->needed_tailroom = lower_tailroom;
0571 }
0572 
0573 /**
0574  * batadv_hardif_min_mtu() - Calculate maximum MTU for soft interface
0575  * @soft_iface: netdev struct of the soft interface
0576  *
0577  * Return: MTU for the soft-interface (limited by the minimal MTU of all active
0578  *  slave interfaces)
0579  */
0580 int batadv_hardif_min_mtu(struct net_device *soft_iface)
0581 {
0582     struct batadv_priv *bat_priv = netdev_priv(soft_iface);
0583     const struct batadv_hard_iface *hard_iface;
0584     int min_mtu = INT_MAX;
0585 
0586     rcu_read_lock();
0587     list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
0588         if (hard_iface->if_status != BATADV_IF_ACTIVE &&
0589             hard_iface->if_status != BATADV_IF_TO_BE_ACTIVATED)
0590             continue;
0591 
0592         if (hard_iface->soft_iface != soft_iface)
0593             continue;
0594 
0595         min_mtu = min_t(int, hard_iface->net_dev->mtu, min_mtu);
0596     }
0597     rcu_read_unlock();
0598 
0599     if (atomic_read(&bat_priv->fragmentation) == 0)
0600         goto out;
0601 
0602     /* with fragmentation enabled the maximum size of internally generated
0603      * packets such as translation table exchanges or tvlv containers, etc
0604      * has to be calculated
0605      */
0606     min_mtu = min_t(int, min_mtu, BATADV_FRAG_MAX_FRAG_SIZE);
0607     min_mtu -= sizeof(struct batadv_frag_packet);
0608     min_mtu *= BATADV_FRAG_MAX_FRAGMENTS;
0609 
0610 out:
0611     /* report to the other components the maximum amount of bytes that
0612      * batman-adv can send over the wire (without considering the payload
0613      * overhead). For example, this value is used by TT to compute the
0614      * maximum local table size
0615      */
0616     atomic_set(&bat_priv->packet_size_max, min_mtu);
0617 
0618     /* the real soft-interface MTU is computed by removing the payload
0619      * overhead from the maximum amount of bytes that was just computed.
0620      *
0621      * However batman-adv does not support MTUs bigger than ETH_DATA_LEN
0622      */
0623     return min_t(int, min_mtu - batadv_max_header_len(), ETH_DATA_LEN);
0624 }
0625 
0626 /**
0627  * batadv_update_min_mtu() - Adjusts the MTU if a new interface with a smaller
0628  *  MTU appeared
0629  * @soft_iface: netdev struct of the soft interface
0630  */
0631 void batadv_update_min_mtu(struct net_device *soft_iface)
0632 {
0633     soft_iface->mtu = batadv_hardif_min_mtu(soft_iface);
0634 
0635     /* Check if the local translate table should be cleaned up to match a
0636      * new (and smaller) MTU.
0637      */
0638     batadv_tt_local_resize_to_mtu(soft_iface);
0639 }
0640 
0641 static void
0642 batadv_hardif_activate_interface(struct batadv_hard_iface *hard_iface)
0643 {
0644     struct batadv_priv *bat_priv;
0645     struct batadv_hard_iface *primary_if = NULL;
0646 
0647     if (hard_iface->if_status != BATADV_IF_INACTIVE)
0648         goto out;
0649 
0650     bat_priv = netdev_priv(hard_iface->soft_iface);
0651 
0652     bat_priv->algo_ops->iface.update_mac(hard_iface);
0653     hard_iface->if_status = BATADV_IF_TO_BE_ACTIVATED;
0654 
0655     /* the first active interface becomes our primary interface or
0656      * the next active interface after the old primary interface was removed
0657      */
0658     primary_if = batadv_primary_if_get_selected(bat_priv);
0659     if (!primary_if)
0660         batadv_primary_if_select(bat_priv, hard_iface);
0661 
0662     batadv_info(hard_iface->soft_iface, "Interface activated: %s\n",
0663             hard_iface->net_dev->name);
0664 
0665     batadv_update_min_mtu(hard_iface->soft_iface);
0666 
0667     if (bat_priv->algo_ops->iface.activate)
0668         bat_priv->algo_ops->iface.activate(hard_iface);
0669 
0670 out:
0671     batadv_hardif_put(primary_if);
0672 }
0673 
0674 static void
0675 batadv_hardif_deactivate_interface(struct batadv_hard_iface *hard_iface)
0676 {
0677     if (hard_iface->if_status != BATADV_IF_ACTIVE &&
0678         hard_iface->if_status != BATADV_IF_TO_BE_ACTIVATED)
0679         return;
0680 
0681     hard_iface->if_status = BATADV_IF_INACTIVE;
0682 
0683     batadv_info(hard_iface->soft_iface, "Interface deactivated: %s\n",
0684             hard_iface->net_dev->name);
0685 
0686     batadv_update_min_mtu(hard_iface->soft_iface);
0687 }
0688 
0689 /**
0690  * batadv_hardif_enable_interface() - Enslave hard interface to soft interface
0691  * @hard_iface: hard interface to add to soft interface
0692  * @soft_iface: netdev struct of the mesh interface
0693  *
0694  * Return: 0 on success or negative error number in case of failure
0695  */
0696 int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface,
0697                    struct net_device *soft_iface)
0698 {
0699     struct batadv_priv *bat_priv;
0700     __be16 ethertype = htons(ETH_P_BATMAN);
0701     int max_header_len = batadv_max_header_len();
0702     int ret;
0703 
0704     if (hard_iface->net_dev->mtu < ETH_MIN_MTU + max_header_len)
0705         return -EINVAL;
0706 
0707     if (hard_iface->if_status != BATADV_IF_NOT_IN_USE)
0708         goto out;
0709 
0710     kref_get(&hard_iface->refcount);
0711 
0712     dev_hold(soft_iface);
0713     hard_iface->soft_iface = soft_iface;
0714     bat_priv = netdev_priv(hard_iface->soft_iface);
0715 
0716     ret = netdev_master_upper_dev_link(hard_iface->net_dev,
0717                        soft_iface, NULL, NULL, NULL);
0718     if (ret)
0719         goto err_dev;
0720 
0721     ret = bat_priv->algo_ops->iface.enable(hard_iface);
0722     if (ret < 0)
0723         goto err_upper;
0724 
0725     hard_iface->if_status = BATADV_IF_INACTIVE;
0726 
0727     kref_get(&hard_iface->refcount);
0728     hard_iface->batman_adv_ptype.type = ethertype;
0729     hard_iface->batman_adv_ptype.func = batadv_batman_skb_recv;
0730     hard_iface->batman_adv_ptype.dev = hard_iface->net_dev;
0731     dev_add_pack(&hard_iface->batman_adv_ptype);
0732 
0733     batadv_info(hard_iface->soft_iface, "Adding interface: %s\n",
0734             hard_iface->net_dev->name);
0735 
0736     if (atomic_read(&bat_priv->fragmentation) &&
0737         hard_iface->net_dev->mtu < ETH_DATA_LEN + max_header_len)
0738         batadv_info(hard_iface->soft_iface,
0739                 "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",
0740                 hard_iface->net_dev->name, hard_iface->net_dev->mtu,
0741                 ETH_DATA_LEN + max_header_len);
0742 
0743     if (!atomic_read(&bat_priv->fragmentation) &&
0744         hard_iface->net_dev->mtu < ETH_DATA_LEN + max_header_len)
0745         batadv_info(hard_iface->soft_iface,
0746                 "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",
0747                 hard_iface->net_dev->name, hard_iface->net_dev->mtu,
0748                 ETH_DATA_LEN + max_header_len);
0749 
0750     if (batadv_hardif_is_iface_up(hard_iface))
0751         batadv_hardif_activate_interface(hard_iface);
0752     else
0753         batadv_err(hard_iface->soft_iface,
0754                "Not using interface %s (retrying later): interface not active\n",
0755                hard_iface->net_dev->name);
0756 
0757     batadv_hardif_recalc_extra_skbroom(soft_iface);
0758 
0759     if (bat_priv->algo_ops->iface.enabled)
0760         bat_priv->algo_ops->iface.enabled(hard_iface);
0761 
0762 out:
0763     return 0;
0764 
0765 err_upper:
0766     netdev_upper_dev_unlink(hard_iface->net_dev, soft_iface);
0767 err_dev:
0768     hard_iface->soft_iface = NULL;
0769     dev_put(soft_iface);
0770     batadv_hardif_put(hard_iface);
0771     return ret;
0772 }
0773 
0774 /**
0775  * batadv_hardif_cnt() - get number of interfaces enslaved to soft interface
0776  * @soft_iface: soft interface to check
0777  *
0778  * This function is only using RCU for locking - the result can therefore be
0779  * off when another function is modifying the list at the same time. The
0780  * caller can use the rtnl_lock to make sure that the count is accurate.
0781  *
0782  * Return: number of connected/enslaved hard interfaces
0783  */
0784 static size_t batadv_hardif_cnt(const struct net_device *soft_iface)
0785 {
0786     struct batadv_hard_iface *hard_iface;
0787     size_t count = 0;
0788 
0789     rcu_read_lock();
0790     list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
0791         if (hard_iface->soft_iface != soft_iface)
0792             continue;
0793 
0794         count++;
0795     }
0796     rcu_read_unlock();
0797 
0798     return count;
0799 }
0800 
0801 /**
0802  * batadv_hardif_disable_interface() - Remove hard interface from soft interface
0803  * @hard_iface: hard interface to be removed
0804  */
0805 void batadv_hardif_disable_interface(struct batadv_hard_iface *hard_iface)
0806 {
0807     struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
0808     struct batadv_hard_iface *primary_if = NULL;
0809 
0810     batadv_hardif_deactivate_interface(hard_iface);
0811 
0812     if (hard_iface->if_status != BATADV_IF_INACTIVE)
0813         goto out;
0814 
0815     batadv_info(hard_iface->soft_iface, "Removing interface: %s\n",
0816             hard_iface->net_dev->name);
0817     dev_remove_pack(&hard_iface->batman_adv_ptype);
0818     batadv_hardif_put(hard_iface);
0819 
0820     primary_if = batadv_primary_if_get_selected(bat_priv);
0821     if (hard_iface == primary_if) {
0822         struct batadv_hard_iface *new_if;
0823 
0824         new_if = batadv_hardif_get_active(hard_iface->soft_iface);
0825         batadv_primary_if_select(bat_priv, new_if);
0826 
0827         batadv_hardif_put(new_if);
0828     }
0829 
0830     bat_priv->algo_ops->iface.disable(hard_iface);
0831     hard_iface->if_status = BATADV_IF_NOT_IN_USE;
0832 
0833     /* delete all references to this hard_iface */
0834     batadv_purge_orig_ref(bat_priv);
0835     batadv_purge_outstanding_packets(bat_priv, hard_iface);
0836     dev_put(hard_iface->soft_iface);
0837 
0838     netdev_upper_dev_unlink(hard_iface->net_dev, hard_iface->soft_iface);
0839     batadv_hardif_recalc_extra_skbroom(hard_iface->soft_iface);
0840 
0841     /* nobody uses this interface anymore */
0842     if (batadv_hardif_cnt(hard_iface->soft_iface) <= 1)
0843         batadv_gw_check_client_stop(bat_priv);
0844 
0845     hard_iface->soft_iface = NULL;
0846     batadv_hardif_put(hard_iface);
0847 
0848 out:
0849     batadv_hardif_put(primary_if);
0850 }
0851 
0852 static struct batadv_hard_iface *
0853 batadv_hardif_add_interface(struct net_device *net_dev)
0854 {
0855     struct batadv_hard_iface *hard_iface;
0856 
0857     ASSERT_RTNL();
0858 
0859     if (!batadv_is_valid_iface(net_dev))
0860         goto out;
0861 
0862     dev_hold(net_dev);
0863 
0864     hard_iface = kzalloc(sizeof(*hard_iface), GFP_ATOMIC);
0865     if (!hard_iface)
0866         goto release_dev;
0867 
0868     hard_iface->net_dev = net_dev;
0869     hard_iface->soft_iface = NULL;
0870     hard_iface->if_status = BATADV_IF_NOT_IN_USE;
0871 
0872     INIT_LIST_HEAD(&hard_iface->list);
0873     INIT_HLIST_HEAD(&hard_iface->neigh_list);
0874 
0875     mutex_init(&hard_iface->bat_iv.ogm_buff_mutex);
0876     spin_lock_init(&hard_iface->neigh_list_lock);
0877     kref_init(&hard_iface->refcount);
0878 
0879     hard_iface->num_bcasts = BATADV_NUM_BCASTS_DEFAULT;
0880     hard_iface->wifi_flags = batadv_wifi_flags_evaluate(net_dev);
0881     if (batadv_is_wifi_hardif(hard_iface))
0882         hard_iface->num_bcasts = BATADV_NUM_BCASTS_WIRELESS;
0883 
0884     atomic_set(&hard_iface->hop_penalty, 0);
0885 
0886     batadv_v_hardif_init(hard_iface);
0887 
0888     batadv_check_known_mac_addr(hard_iface->net_dev);
0889     kref_get(&hard_iface->refcount);
0890     list_add_tail_rcu(&hard_iface->list, &batadv_hardif_list);
0891     batadv_hardif_generation++;
0892 
0893     return hard_iface;
0894 
0895 release_dev:
0896     dev_put(net_dev);
0897 out:
0898     return NULL;
0899 }
0900 
0901 static void batadv_hardif_remove_interface(struct batadv_hard_iface *hard_iface)
0902 {
0903     ASSERT_RTNL();
0904 
0905     /* first deactivate interface */
0906     if (hard_iface->if_status != BATADV_IF_NOT_IN_USE)
0907         batadv_hardif_disable_interface(hard_iface);
0908 
0909     if (hard_iface->if_status != BATADV_IF_NOT_IN_USE)
0910         return;
0911 
0912     hard_iface->if_status = BATADV_IF_TO_BE_REMOVED;
0913     batadv_hardif_put(hard_iface);
0914 }
0915 
0916 /**
0917  * batadv_hard_if_event_softif() - Handle events for soft interfaces
0918  * @event: NETDEV_* event to handle
0919  * @net_dev: net_device which generated an event
0920  *
0921  * Return: NOTIFY_* result
0922  */
0923 static int batadv_hard_if_event_softif(unsigned long event,
0924                        struct net_device *net_dev)
0925 {
0926     struct batadv_priv *bat_priv;
0927 
0928     switch (event) {
0929     case NETDEV_REGISTER:
0930         bat_priv = netdev_priv(net_dev);
0931         batadv_softif_create_vlan(bat_priv, BATADV_NO_FLAGS);
0932         break;
0933     }
0934 
0935     return NOTIFY_DONE;
0936 }
0937 
0938 static int batadv_hard_if_event(struct notifier_block *this,
0939                 unsigned long event, void *ptr)
0940 {
0941     struct net_device *net_dev = netdev_notifier_info_to_dev(ptr);
0942     struct batadv_hard_iface *hard_iface;
0943     struct batadv_hard_iface *primary_if = NULL;
0944     struct batadv_priv *bat_priv;
0945 
0946     if (batadv_softif_is_valid(net_dev))
0947         return batadv_hard_if_event_softif(event, net_dev);
0948 
0949     hard_iface = batadv_hardif_get_by_netdev(net_dev);
0950     if (!hard_iface && (event == NETDEV_REGISTER ||
0951                 event == NETDEV_POST_TYPE_CHANGE))
0952         hard_iface = batadv_hardif_add_interface(net_dev);
0953 
0954     if (!hard_iface)
0955         goto out;
0956 
0957     switch (event) {
0958     case NETDEV_UP:
0959         batadv_hardif_activate_interface(hard_iface);
0960         break;
0961     case NETDEV_GOING_DOWN:
0962     case NETDEV_DOWN:
0963         batadv_hardif_deactivate_interface(hard_iface);
0964         break;
0965     case NETDEV_UNREGISTER:
0966     case NETDEV_PRE_TYPE_CHANGE:
0967         list_del_rcu(&hard_iface->list);
0968         batadv_hardif_generation++;
0969 
0970         batadv_hardif_remove_interface(hard_iface);
0971         break;
0972     case NETDEV_CHANGEMTU:
0973         if (hard_iface->soft_iface)
0974             batadv_update_min_mtu(hard_iface->soft_iface);
0975         break;
0976     case NETDEV_CHANGEADDR:
0977         if (hard_iface->if_status == BATADV_IF_NOT_IN_USE)
0978             goto hardif_put;
0979 
0980         batadv_check_known_mac_addr(hard_iface->net_dev);
0981 
0982         bat_priv = netdev_priv(hard_iface->soft_iface);
0983         bat_priv->algo_ops->iface.update_mac(hard_iface);
0984 
0985         primary_if = batadv_primary_if_get_selected(bat_priv);
0986         if (!primary_if)
0987             goto hardif_put;
0988 
0989         if (hard_iface == primary_if)
0990             batadv_primary_if_update_addr(bat_priv, NULL);
0991         break;
0992     case NETDEV_CHANGEUPPER:
0993         hard_iface->wifi_flags = batadv_wifi_flags_evaluate(net_dev);
0994         if (batadv_is_wifi_hardif(hard_iface))
0995             hard_iface->num_bcasts = BATADV_NUM_BCASTS_WIRELESS;
0996         break;
0997     default:
0998         break;
0999     }
1000 
1001 hardif_put:
1002     batadv_hardif_put(hard_iface);
1003 out:
1004     batadv_hardif_put(primary_if);
1005     return NOTIFY_DONE;
1006 }
1007 
1008 struct notifier_block batadv_hard_if_notifier = {
1009     .notifier_call = batadv_hard_if_event,
1010 };