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  * Linus Lüssing, Marek Lindner
0005  */
0006 
0007 #include "bat_v_elp.h"
0008 #include "main.h"
0009 
0010 #include <linux/atomic.h>
0011 #include <linux/bitops.h>
0012 #include <linux/byteorder/generic.h>
0013 #include <linux/container_of.h>
0014 #include <linux/errno.h>
0015 #include <linux/etherdevice.h>
0016 #include <linux/ethtool.h>
0017 #include <linux/gfp.h>
0018 #include <linux/if_ether.h>
0019 #include <linux/jiffies.h>
0020 #include <linux/kref.h>
0021 #include <linux/minmax.h>
0022 #include <linux/netdevice.h>
0023 #include <linux/nl80211.h>
0024 #include <linux/prandom.h>
0025 #include <linux/random.h>
0026 #include <linux/rculist.h>
0027 #include <linux/rcupdate.h>
0028 #include <linux/rtnetlink.h>
0029 #include <linux/skbuff.h>
0030 #include <linux/stddef.h>
0031 #include <linux/string.h>
0032 #include <linux/types.h>
0033 #include <linux/workqueue.h>
0034 #include <net/cfg80211.h>
0035 #include <uapi/linux/batadv_packet.h>
0036 
0037 #include "bat_algo.h"
0038 #include "bat_v_ogm.h"
0039 #include "hard-interface.h"
0040 #include "log.h"
0041 #include "originator.h"
0042 #include "routing.h"
0043 #include "send.h"
0044 
0045 /**
0046  * batadv_v_elp_start_timer() - restart timer for ELP periodic work
0047  * @hard_iface: the interface for which the timer has to be reset
0048  */
0049 static void batadv_v_elp_start_timer(struct batadv_hard_iface *hard_iface)
0050 {
0051     unsigned int msecs;
0052 
0053     msecs = atomic_read(&hard_iface->bat_v.elp_interval) - BATADV_JITTER;
0054     msecs += prandom_u32_max(2 * BATADV_JITTER);
0055 
0056     queue_delayed_work(batadv_event_workqueue, &hard_iface->bat_v.elp_wq,
0057                msecs_to_jiffies(msecs));
0058 }
0059 
0060 /**
0061  * batadv_v_elp_get_throughput() - get the throughput towards a neighbour
0062  * @neigh: the neighbour for which the throughput has to be obtained
0063  *
0064  * Return: The throughput towards the given neighbour in multiples of 100kpbs
0065  *         (a value of '1' equals 0.1Mbps, '10' equals 1Mbps, etc).
0066  */
0067 static u32 batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh)
0068 {
0069     struct batadv_hard_iface *hard_iface = neigh->if_incoming;
0070     struct ethtool_link_ksettings link_settings;
0071     struct net_device *real_netdev;
0072     struct station_info sinfo;
0073     u32 throughput;
0074     int ret;
0075 
0076     /* if the user specified a customised value for this interface, then
0077      * return it directly
0078      */
0079     throughput =  atomic_read(&hard_iface->bat_v.throughput_override);
0080     if (throughput != 0)
0081         return throughput;
0082 
0083     /* if this is a wireless device, then ask its throughput through
0084      * cfg80211 API
0085      */
0086     if (batadv_is_wifi_hardif(hard_iface)) {
0087         if (!batadv_is_cfg80211_hardif(hard_iface))
0088             /* unsupported WiFi driver version */
0089             goto default_throughput;
0090 
0091         real_netdev = batadv_get_real_netdev(hard_iface->net_dev);
0092         if (!real_netdev)
0093             goto default_throughput;
0094 
0095         ret = cfg80211_get_station(real_netdev, neigh->addr, &sinfo);
0096 
0097         if (!ret) {
0098             /* free the TID stats immediately */
0099             cfg80211_sinfo_release_content(&sinfo);
0100         }
0101 
0102         dev_put(real_netdev);
0103         if (ret == -ENOENT) {
0104             /* Node is not associated anymore! It would be
0105              * possible to delete this neighbor. For now set
0106              * the throughput metric to 0.
0107              */
0108             return 0;
0109         }
0110         if (ret)
0111             goto default_throughput;
0112 
0113         if (sinfo.filled & BIT(NL80211_STA_INFO_EXPECTED_THROUGHPUT))
0114             return sinfo.expected_throughput / 100;
0115 
0116         /* try to estimate the expected throughput based on reported tx
0117          * rates
0118          */
0119         if (sinfo.filled & BIT(NL80211_STA_INFO_TX_BITRATE))
0120             return cfg80211_calculate_bitrate(&sinfo.txrate) / 3;
0121 
0122         goto default_throughput;
0123     }
0124 
0125     /* if not a wifi interface, check if this device provides data via
0126      * ethtool (e.g. an Ethernet adapter)
0127      */
0128     memset(&link_settings, 0, sizeof(link_settings));
0129     rtnl_lock();
0130     ret = __ethtool_get_link_ksettings(hard_iface->net_dev, &link_settings);
0131     rtnl_unlock();
0132     if (ret == 0) {
0133         /* link characteristics might change over time */
0134         if (link_settings.base.duplex == DUPLEX_FULL)
0135             hard_iface->bat_v.flags |= BATADV_FULL_DUPLEX;
0136         else
0137             hard_iface->bat_v.flags &= ~BATADV_FULL_DUPLEX;
0138 
0139         throughput = link_settings.base.speed;
0140         if (throughput && throughput != SPEED_UNKNOWN)
0141             return throughput * 10;
0142     }
0143 
0144 default_throughput:
0145     if (!(hard_iface->bat_v.flags & BATADV_WARNING_DEFAULT)) {
0146         batadv_info(hard_iface->soft_iface,
0147                 "WiFi driver or ethtool info does not provide information about link speeds on interface %s, therefore defaulting to hardcoded throughput values of %u.%1u Mbps. Consider overriding the throughput manually or checking your driver.\n",
0148                 hard_iface->net_dev->name,
0149                 BATADV_THROUGHPUT_DEFAULT_VALUE / 10,
0150                 BATADV_THROUGHPUT_DEFAULT_VALUE % 10);
0151         hard_iface->bat_v.flags |= BATADV_WARNING_DEFAULT;
0152     }
0153 
0154     /* if none of the above cases apply, return the base_throughput */
0155     return BATADV_THROUGHPUT_DEFAULT_VALUE;
0156 }
0157 
0158 /**
0159  * batadv_v_elp_throughput_metric_update() - worker updating the throughput
0160  *  metric of a single hop neighbour
0161  * @work: the work queue item
0162  */
0163 void batadv_v_elp_throughput_metric_update(struct work_struct *work)
0164 {
0165     struct batadv_hardif_neigh_node_bat_v *neigh_bat_v;
0166     struct batadv_hardif_neigh_node *neigh;
0167 
0168     neigh_bat_v = container_of(work, struct batadv_hardif_neigh_node_bat_v,
0169                    metric_work);
0170     neigh = container_of(neigh_bat_v, struct batadv_hardif_neigh_node,
0171                  bat_v);
0172 
0173     ewma_throughput_add(&neigh->bat_v.throughput,
0174                 batadv_v_elp_get_throughput(neigh));
0175 
0176     /* decrement refcounter to balance increment performed before scheduling
0177      * this task
0178      */
0179     batadv_hardif_neigh_put(neigh);
0180 }
0181 
0182 /**
0183  * batadv_v_elp_wifi_neigh_probe() - send link probing packets to a neighbour
0184  * @neigh: the neighbour to probe
0185  *
0186  * Sends a predefined number of unicast wifi packets to a given neighbour in
0187  * order to trigger the throughput estimation on this link by the RC algorithm.
0188  * Packets are sent only if there is not enough payload unicast traffic towards
0189  * this neighbour..
0190  *
0191  * Return: True on success and false in case of error during skb preparation.
0192  */
0193 static bool
0194 batadv_v_elp_wifi_neigh_probe(struct batadv_hardif_neigh_node *neigh)
0195 {
0196     struct batadv_hard_iface *hard_iface = neigh->if_incoming;
0197     struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
0198     unsigned long last_tx_diff;
0199     struct sk_buff *skb;
0200     int probe_len, i;
0201     int elp_skb_len;
0202 
0203     /* this probing routine is for Wifi neighbours only */
0204     if (!batadv_is_wifi_hardif(hard_iface))
0205         return true;
0206 
0207     /* probe the neighbor only if no unicast packets have been sent
0208      * to it in the last 100 milliseconds: this is the rate control
0209      * algorithm sampling interval (minstrel). In this way, if not
0210      * enough traffic has been sent to the neighbor, batman-adv can
0211      * generate 2 probe packets and push the RC algorithm to perform
0212      * the sampling
0213      */
0214     last_tx_diff = jiffies_to_msecs(jiffies - neigh->bat_v.last_unicast_tx);
0215     if (last_tx_diff <= BATADV_ELP_PROBE_MAX_TX_DIFF)
0216         return true;
0217 
0218     probe_len = max_t(int, sizeof(struct batadv_elp_packet),
0219               BATADV_ELP_MIN_PROBE_SIZE);
0220 
0221     for (i = 0; i < BATADV_ELP_PROBES_PER_NODE; i++) {
0222         elp_skb_len = hard_iface->bat_v.elp_skb->len;
0223         skb = skb_copy_expand(hard_iface->bat_v.elp_skb, 0,
0224                       probe_len - elp_skb_len,
0225                       GFP_ATOMIC);
0226         if (!skb)
0227             return false;
0228 
0229         /* Tell the skb to get as big as the allocated space (we want
0230          * the packet to be exactly of that size to make the link
0231          * throughput estimation effective.
0232          */
0233         skb_put_zero(skb, probe_len - hard_iface->bat_v.elp_skb->len);
0234 
0235         batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
0236                "Sending unicast (probe) ELP packet on interface %s to %pM\n",
0237                hard_iface->net_dev->name, neigh->addr);
0238 
0239         batadv_send_skb_packet(skb, hard_iface, neigh->addr);
0240     }
0241 
0242     return true;
0243 }
0244 
0245 /**
0246  * batadv_v_elp_periodic_work() - ELP periodic task per interface
0247  * @work: work queue item
0248  *
0249  * Emits broadcast ELP messages in regular intervals.
0250  */
0251 static void batadv_v_elp_periodic_work(struct work_struct *work)
0252 {
0253     struct batadv_hardif_neigh_node *hardif_neigh;
0254     struct batadv_hard_iface *hard_iface;
0255     struct batadv_hard_iface_bat_v *bat_v;
0256     struct batadv_elp_packet *elp_packet;
0257     struct batadv_priv *bat_priv;
0258     struct sk_buff *skb;
0259     u32 elp_interval;
0260     bool ret;
0261 
0262     bat_v = container_of(work, struct batadv_hard_iface_bat_v, elp_wq.work);
0263     hard_iface = container_of(bat_v, struct batadv_hard_iface, bat_v);
0264     bat_priv = netdev_priv(hard_iface->soft_iface);
0265 
0266     if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING)
0267         goto out;
0268 
0269     /* we are in the process of shutting this interface down */
0270     if (hard_iface->if_status == BATADV_IF_NOT_IN_USE ||
0271         hard_iface->if_status == BATADV_IF_TO_BE_REMOVED)
0272         goto out;
0273 
0274     /* the interface was enabled but may not be ready yet */
0275     if (hard_iface->if_status != BATADV_IF_ACTIVE)
0276         goto restart_timer;
0277 
0278     skb = skb_copy(hard_iface->bat_v.elp_skb, GFP_ATOMIC);
0279     if (!skb)
0280         goto restart_timer;
0281 
0282     elp_packet = (struct batadv_elp_packet *)skb->data;
0283     elp_packet->seqno = htonl(atomic_read(&hard_iface->bat_v.elp_seqno));
0284     elp_interval = atomic_read(&hard_iface->bat_v.elp_interval);
0285     elp_packet->elp_interval = htonl(elp_interval);
0286 
0287     batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
0288            "Sending broadcast ELP packet on interface %s, seqno %u\n",
0289            hard_iface->net_dev->name,
0290            atomic_read(&hard_iface->bat_v.elp_seqno));
0291 
0292     batadv_send_broadcast_skb(skb, hard_iface);
0293 
0294     atomic_inc(&hard_iface->bat_v.elp_seqno);
0295 
0296     /* The throughput metric is updated on each sent packet. This way, if a
0297      * node is dead and no longer sends packets, batman-adv is still able to
0298      * react timely to its death.
0299      *
0300      * The throughput metric is updated by following these steps:
0301      * 1) if the hard_iface is wifi => send a number of unicast ELPs for
0302      *    probing/sampling to each neighbor
0303      * 2) update the throughput metric value of each neighbor (note that the
0304      *    value retrieved in this step might be 100ms old because the
0305      *    probing packets at point 1) could still be in the HW queue)
0306      */
0307     rcu_read_lock();
0308     hlist_for_each_entry_rcu(hardif_neigh, &hard_iface->neigh_list, list) {
0309         if (!batadv_v_elp_wifi_neigh_probe(hardif_neigh))
0310             /* if something goes wrong while probing, better to stop
0311              * sending packets immediately and reschedule the task
0312              */
0313             break;
0314 
0315         if (!kref_get_unless_zero(&hardif_neigh->refcount))
0316             continue;
0317 
0318         /* Reading the estimated throughput from cfg80211 is a task that
0319          * may sleep and that is not allowed in an rcu protected
0320          * context. Therefore schedule a task for that.
0321          */
0322         ret = queue_work(batadv_event_workqueue,
0323                  &hardif_neigh->bat_v.metric_work);
0324 
0325         if (!ret)
0326             batadv_hardif_neigh_put(hardif_neigh);
0327     }
0328     rcu_read_unlock();
0329 
0330 restart_timer:
0331     batadv_v_elp_start_timer(hard_iface);
0332 out:
0333     return;
0334 }
0335 
0336 /**
0337  * batadv_v_elp_iface_enable() - setup the ELP interface private resources
0338  * @hard_iface: interface for which the data has to be prepared
0339  *
0340  * Return: 0 on success or a -ENOMEM in case of failure.
0341  */
0342 int batadv_v_elp_iface_enable(struct batadv_hard_iface *hard_iface)
0343 {
0344     static const size_t tvlv_padding = sizeof(__be32);
0345     struct batadv_elp_packet *elp_packet;
0346     unsigned char *elp_buff;
0347     u32 random_seqno;
0348     size_t size;
0349     int res = -ENOMEM;
0350 
0351     size = ETH_HLEN + NET_IP_ALIGN + BATADV_ELP_HLEN + tvlv_padding;
0352     hard_iface->bat_v.elp_skb = dev_alloc_skb(size);
0353     if (!hard_iface->bat_v.elp_skb)
0354         goto out;
0355 
0356     skb_reserve(hard_iface->bat_v.elp_skb, ETH_HLEN + NET_IP_ALIGN);
0357     elp_buff = skb_put_zero(hard_iface->bat_v.elp_skb,
0358                 BATADV_ELP_HLEN + tvlv_padding);
0359     elp_packet = (struct batadv_elp_packet *)elp_buff;
0360 
0361     elp_packet->packet_type = BATADV_ELP;
0362     elp_packet->version = BATADV_COMPAT_VERSION;
0363 
0364     /* randomize initial seqno to avoid collision */
0365     get_random_bytes(&random_seqno, sizeof(random_seqno));
0366     atomic_set(&hard_iface->bat_v.elp_seqno, random_seqno);
0367 
0368     /* assume full-duplex by default */
0369     hard_iface->bat_v.flags |= BATADV_FULL_DUPLEX;
0370 
0371     /* warn the user (again) if there is no throughput data is available */
0372     hard_iface->bat_v.flags &= ~BATADV_WARNING_DEFAULT;
0373 
0374     if (batadv_is_wifi_hardif(hard_iface))
0375         hard_iface->bat_v.flags &= ~BATADV_FULL_DUPLEX;
0376 
0377     INIT_DELAYED_WORK(&hard_iface->bat_v.elp_wq,
0378               batadv_v_elp_periodic_work);
0379     batadv_v_elp_start_timer(hard_iface);
0380     res = 0;
0381 
0382 out:
0383     return res;
0384 }
0385 
0386 /**
0387  * batadv_v_elp_iface_disable() - release ELP interface private resources
0388  * @hard_iface: interface for which the resources have to be released
0389  */
0390 void batadv_v_elp_iface_disable(struct batadv_hard_iface *hard_iface)
0391 {
0392     cancel_delayed_work_sync(&hard_iface->bat_v.elp_wq);
0393 
0394     dev_kfree_skb(hard_iface->bat_v.elp_skb);
0395     hard_iface->bat_v.elp_skb = NULL;
0396 }
0397 
0398 /**
0399  * batadv_v_elp_iface_activate() - update the ELP buffer belonging to the given
0400  *  hard-interface
0401  * @primary_iface: the new primary interface
0402  * @hard_iface: interface holding the to-be-updated buffer
0403  */
0404 void batadv_v_elp_iface_activate(struct batadv_hard_iface *primary_iface,
0405                  struct batadv_hard_iface *hard_iface)
0406 {
0407     struct batadv_elp_packet *elp_packet;
0408     struct sk_buff *skb;
0409 
0410     if (!hard_iface->bat_v.elp_skb)
0411         return;
0412 
0413     skb = hard_iface->bat_v.elp_skb;
0414     elp_packet = (struct batadv_elp_packet *)skb->data;
0415     ether_addr_copy(elp_packet->orig,
0416             primary_iface->net_dev->dev_addr);
0417 }
0418 
0419 /**
0420  * batadv_v_elp_primary_iface_set() - change internal data to reflect the new
0421  *  primary interface
0422  * @primary_iface: the new primary interface
0423  */
0424 void batadv_v_elp_primary_iface_set(struct batadv_hard_iface *primary_iface)
0425 {
0426     struct batadv_hard_iface *hard_iface;
0427 
0428     /* update orig field of every elp iface belonging to this mesh */
0429     rcu_read_lock();
0430     list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
0431         if (primary_iface->soft_iface != hard_iface->soft_iface)
0432             continue;
0433 
0434         batadv_v_elp_iface_activate(primary_iface, hard_iface);
0435     }
0436     rcu_read_unlock();
0437 }
0438 
0439 /**
0440  * batadv_v_elp_neigh_update() - update an ELP neighbour node
0441  * @bat_priv: the bat priv with all the soft interface information
0442  * @neigh_addr: the neighbour interface address
0443  * @if_incoming: the interface the packet was received through
0444  * @elp_packet: the received ELP packet
0445  *
0446  * Updates the ELP neighbour node state with the data received within the new
0447  * ELP packet.
0448  */
0449 static void batadv_v_elp_neigh_update(struct batadv_priv *bat_priv,
0450                       u8 *neigh_addr,
0451                       struct batadv_hard_iface *if_incoming,
0452                       struct batadv_elp_packet *elp_packet)
0453 
0454 {
0455     struct batadv_neigh_node *neigh;
0456     struct batadv_orig_node *orig_neigh;
0457     struct batadv_hardif_neigh_node *hardif_neigh;
0458     s32 seqno_diff;
0459     s32 elp_latest_seqno;
0460 
0461     orig_neigh = batadv_v_ogm_orig_get(bat_priv, elp_packet->orig);
0462     if (!orig_neigh)
0463         return;
0464 
0465     neigh = batadv_neigh_node_get_or_create(orig_neigh,
0466                         if_incoming, neigh_addr);
0467     if (!neigh)
0468         goto orig_free;
0469 
0470     hardif_neigh = batadv_hardif_neigh_get(if_incoming, neigh_addr);
0471     if (!hardif_neigh)
0472         goto neigh_free;
0473 
0474     elp_latest_seqno = hardif_neigh->bat_v.elp_latest_seqno;
0475     seqno_diff = ntohl(elp_packet->seqno) - elp_latest_seqno;
0476 
0477     /* known or older sequence numbers are ignored. However always adopt
0478      * if the router seems to have been restarted.
0479      */
0480     if (seqno_diff < 1 && seqno_diff > -BATADV_ELP_MAX_AGE)
0481         goto hardif_free;
0482 
0483     neigh->last_seen = jiffies;
0484     hardif_neigh->last_seen = jiffies;
0485     hardif_neigh->bat_v.elp_latest_seqno = ntohl(elp_packet->seqno);
0486     hardif_neigh->bat_v.elp_interval = ntohl(elp_packet->elp_interval);
0487 
0488 hardif_free:
0489     batadv_hardif_neigh_put(hardif_neigh);
0490 neigh_free:
0491     batadv_neigh_node_put(neigh);
0492 orig_free:
0493     batadv_orig_node_put(orig_neigh);
0494 }
0495 
0496 /**
0497  * batadv_v_elp_packet_recv() - main ELP packet handler
0498  * @skb: the received packet
0499  * @if_incoming: the interface this packet was received through
0500  *
0501  * Return: NET_RX_SUCCESS and consumes the skb if the packet was properly
0502  * processed or NET_RX_DROP in case of failure.
0503  */
0504 int batadv_v_elp_packet_recv(struct sk_buff *skb,
0505                  struct batadv_hard_iface *if_incoming)
0506 {
0507     struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
0508     struct batadv_elp_packet *elp_packet;
0509     struct batadv_hard_iface *primary_if;
0510     struct ethhdr *ethhdr = (struct ethhdr *)skb_mac_header(skb);
0511     bool res;
0512     int ret = NET_RX_DROP;
0513 
0514     res = batadv_check_management_packet(skb, if_incoming, BATADV_ELP_HLEN);
0515     if (!res)
0516         goto free_skb;
0517 
0518     if (batadv_is_my_mac(bat_priv, ethhdr->h_source))
0519         goto free_skb;
0520 
0521     /* did we receive a B.A.T.M.A.N. V ELP packet on an interface
0522      * that does not have B.A.T.M.A.N. V ELP enabled ?
0523      */
0524     if (strcmp(bat_priv->algo_ops->name, "BATMAN_V") != 0)
0525         goto free_skb;
0526 
0527     elp_packet = (struct batadv_elp_packet *)skb->data;
0528 
0529     batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
0530            "Received ELP packet from %pM seqno %u ORIG: %pM\n",
0531            ethhdr->h_source, ntohl(elp_packet->seqno),
0532            elp_packet->orig);
0533 
0534     primary_if = batadv_primary_if_get_selected(bat_priv);
0535     if (!primary_if)
0536         goto free_skb;
0537 
0538     batadv_v_elp_neigh_update(bat_priv, ethhdr->h_source, if_incoming,
0539                   elp_packet);
0540 
0541     ret = NET_RX_SUCCESS;
0542     batadv_hardif_put(primary_if);
0543 
0544 free_skb:
0545     if (ret == NET_RX_SUCCESS)
0546         consume_skb(skb);
0547     else
0548         kfree_skb(skb);
0549 
0550     return ret;
0551 }