0001
0002
0003
0004
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
0047
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
0062
0063
0064
0065
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
0077
0078
0079 throughput = atomic_read(&hard_iface->bat_v.throughput_override);
0080 if (throughput != 0)
0081 return throughput;
0082
0083
0084
0085
0086 if (batadv_is_wifi_hardif(hard_iface)) {
0087 if (!batadv_is_cfg80211_hardif(hard_iface))
0088
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
0099 cfg80211_sinfo_release_content(&sinfo);
0100 }
0101
0102 dev_put(real_netdev);
0103 if (ret == -ENOENT) {
0104
0105
0106
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
0117
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
0126
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
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
0155 return BATADV_THROUGHPUT_DEFAULT_VALUE;
0156 }
0157
0158
0159
0160
0161
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
0177
0178
0179 batadv_hardif_neigh_put(neigh);
0180 }
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191
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
0204 if (!batadv_is_wifi_hardif(hard_iface))
0205 return true;
0206
0207
0208
0209
0210
0211
0212
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
0230
0231
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
0247
0248
0249
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
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
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
0297
0298
0299
0300
0301
0302
0303
0304
0305
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
0311
0312
0313 break;
0314
0315 if (!kref_get_unless_zero(&hardif_neigh->refcount))
0316 continue;
0317
0318
0319
0320
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
0338
0339
0340
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
0365 get_random_bytes(&random_seqno, sizeof(random_seqno));
0366 atomic_set(&hard_iface->bat_v.elp_seqno, random_seqno);
0367
0368
0369 hard_iface->bat_v.flags |= BATADV_FULL_DUPLEX;
0370
0371
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
0388
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
0400
0401
0402
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
0421
0422
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
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
0441
0442
0443
0444
0445
0446
0447
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
0478
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
0498
0499
0500
0501
0502
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
0522
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 }