0001
0002
0003
0004
0005
0006
0007 #include "bat_v_ogm.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/etherdevice.h>
0015 #include <linux/gfp.h>
0016 #include <linux/if_ether.h>
0017 #include <linux/jiffies.h>
0018 #include <linux/kref.h>
0019 #include <linux/list.h>
0020 #include <linux/lockdep.h>
0021 #include <linux/minmax.h>
0022 #include <linux/mutex.h>
0023 #include <linux/netdevice.h>
0024 #include <linux/prandom.h>
0025 #include <linux/random.h>
0026 #include <linux/rculist.h>
0027 #include <linux/rcupdate.h>
0028 #include <linux/skbuff.h>
0029 #include <linux/slab.h>
0030 #include <linux/spinlock.h>
0031 #include <linux/stddef.h>
0032 #include <linux/string.h>
0033 #include <linux/types.h>
0034 #include <linux/workqueue.h>
0035 #include <uapi/linux/batadv_packet.h>
0036
0037 #include "bat_algo.h"
0038 #include "hard-interface.h"
0039 #include "hash.h"
0040 #include "log.h"
0041 #include "originator.h"
0042 #include "routing.h"
0043 #include "send.h"
0044 #include "translation-table.h"
0045 #include "tvlv.h"
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056 struct batadv_orig_node *batadv_v_ogm_orig_get(struct batadv_priv *bat_priv,
0057 const u8 *addr)
0058 {
0059 struct batadv_orig_node *orig_node;
0060 int hash_added;
0061
0062 orig_node = batadv_orig_hash_find(bat_priv, addr);
0063 if (orig_node)
0064 return orig_node;
0065
0066 orig_node = batadv_orig_node_new(bat_priv, addr);
0067 if (!orig_node)
0068 return NULL;
0069
0070 kref_get(&orig_node->refcount);
0071 hash_added = batadv_hash_add(bat_priv->orig_hash, batadv_compare_orig,
0072 batadv_choose_orig, orig_node,
0073 &orig_node->hash_entry);
0074 if (hash_added != 0) {
0075
0076 batadv_orig_node_put(orig_node);
0077 batadv_orig_node_put(orig_node);
0078 orig_node = NULL;
0079 }
0080
0081 return orig_node;
0082 }
0083
0084
0085
0086
0087
0088 static void batadv_v_ogm_start_queue_timer(struct batadv_hard_iface *hard_iface)
0089 {
0090 unsigned int msecs = BATADV_MAX_AGGREGATION_MS * 1000;
0091
0092
0093 msecs += prandom_u32_max(msecs / 5) - (msecs / 10);
0094 queue_delayed_work(batadv_event_workqueue, &hard_iface->bat_v.aggr_wq,
0095 msecs_to_jiffies(msecs / 1000));
0096 }
0097
0098
0099
0100
0101
0102 static void batadv_v_ogm_start_timer(struct batadv_priv *bat_priv)
0103 {
0104 unsigned long msecs;
0105
0106
0107
0108 if (delayed_work_pending(&bat_priv->bat_v.ogm_wq))
0109 return;
0110
0111 msecs = atomic_read(&bat_priv->orig_interval) - BATADV_JITTER;
0112 msecs += prandom_u32_max(2 * BATADV_JITTER);
0113 queue_delayed_work(batadv_event_workqueue, &bat_priv->bat_v.ogm_wq,
0114 msecs_to_jiffies(msecs));
0115 }
0116
0117
0118
0119
0120
0121
0122 static void batadv_v_ogm_send_to_if(struct sk_buff *skb,
0123 struct batadv_hard_iface *hard_iface)
0124 {
0125 struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
0126
0127 if (hard_iface->if_status != BATADV_IF_ACTIVE)
0128 return;
0129
0130 batadv_inc_counter(bat_priv, BATADV_CNT_MGMT_TX);
0131 batadv_add_counter(bat_priv, BATADV_CNT_MGMT_TX_BYTES,
0132 skb->len + ETH_HLEN);
0133
0134 batadv_send_broadcast_skb(skb, hard_iface);
0135 }
0136
0137
0138
0139
0140
0141
0142
0143
0144 static unsigned int batadv_v_ogm_len(struct sk_buff *skb)
0145 {
0146 struct batadv_ogm2_packet *ogm_packet;
0147
0148 ogm_packet = (struct batadv_ogm2_packet *)skb->data;
0149 return BATADV_OGM2_HLEN + ntohs(ogm_packet->tvlv_len);
0150 }
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161 static bool batadv_v_ogm_queue_left(struct sk_buff *skb,
0162 struct batadv_hard_iface *hard_iface)
0163 {
0164 unsigned int max = min_t(unsigned int, hard_iface->net_dev->mtu,
0165 BATADV_MAX_AGGREGATION_BYTES);
0166 unsigned int ogm_len = batadv_v_ogm_len(skb);
0167
0168 lockdep_assert_held(&hard_iface->bat_v.aggr_list.lock);
0169
0170 return hard_iface->bat_v.aggr_len + ogm_len <= max;
0171 }
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181 static void batadv_v_ogm_aggr_list_free(struct batadv_hard_iface *hard_iface)
0182 {
0183 lockdep_assert_held(&hard_iface->bat_v.aggr_list.lock);
0184
0185 __skb_queue_purge(&hard_iface->bat_v.aggr_list);
0186 hard_iface->bat_v.aggr_len = 0;
0187 }
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200 static void batadv_v_ogm_aggr_send(struct batadv_hard_iface *hard_iface)
0201 {
0202 unsigned int aggr_len = hard_iface->bat_v.aggr_len;
0203 struct sk_buff *skb_aggr;
0204 unsigned int ogm_len;
0205 struct sk_buff *skb;
0206
0207 lockdep_assert_held(&hard_iface->bat_v.aggr_list.lock);
0208
0209 if (!aggr_len)
0210 return;
0211
0212 skb_aggr = dev_alloc_skb(aggr_len + ETH_HLEN + NET_IP_ALIGN);
0213 if (!skb_aggr) {
0214 batadv_v_ogm_aggr_list_free(hard_iface);
0215 return;
0216 }
0217
0218 skb_reserve(skb_aggr, ETH_HLEN + NET_IP_ALIGN);
0219 skb_reset_network_header(skb_aggr);
0220
0221 while ((skb = __skb_dequeue(&hard_iface->bat_v.aggr_list))) {
0222 hard_iface->bat_v.aggr_len -= batadv_v_ogm_len(skb);
0223
0224 ogm_len = batadv_v_ogm_len(skb);
0225 skb_put_data(skb_aggr, skb->data, ogm_len);
0226
0227 consume_skb(skb);
0228 }
0229
0230 batadv_v_ogm_send_to_if(skb_aggr, hard_iface);
0231 }
0232
0233
0234
0235
0236
0237
0238 static void batadv_v_ogm_queue_on_if(struct sk_buff *skb,
0239 struct batadv_hard_iface *hard_iface)
0240 {
0241 struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
0242
0243 if (!atomic_read(&bat_priv->aggregated_ogms)) {
0244 batadv_v_ogm_send_to_if(skb, hard_iface);
0245 return;
0246 }
0247
0248 spin_lock_bh(&hard_iface->bat_v.aggr_list.lock);
0249 if (!batadv_v_ogm_queue_left(skb, hard_iface))
0250 batadv_v_ogm_aggr_send(hard_iface);
0251
0252 hard_iface->bat_v.aggr_len += batadv_v_ogm_len(skb);
0253 __skb_queue_tail(&hard_iface->bat_v.aggr_list, skb);
0254 spin_unlock_bh(&hard_iface->bat_v.aggr_list.lock);
0255 }
0256
0257
0258
0259
0260
0261 static void batadv_v_ogm_send_softif(struct batadv_priv *bat_priv)
0262 {
0263 struct batadv_hard_iface *hard_iface;
0264 struct batadv_ogm2_packet *ogm_packet;
0265 struct sk_buff *skb, *skb_tmp;
0266 unsigned char *ogm_buff;
0267 int ogm_buff_len;
0268 u16 tvlv_len = 0;
0269 int ret;
0270
0271 lockdep_assert_held(&bat_priv->bat_v.ogm_buff_mutex);
0272
0273 if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING)
0274 goto out;
0275
0276 ogm_buff = bat_priv->bat_v.ogm_buff;
0277 ogm_buff_len = bat_priv->bat_v.ogm_buff_len;
0278
0279
0280
0281 batadv_tt_local_commit_changes(bat_priv);
0282 tvlv_len = batadv_tvlv_container_ogm_append(bat_priv, &ogm_buff,
0283 &ogm_buff_len,
0284 BATADV_OGM2_HLEN);
0285
0286 bat_priv->bat_v.ogm_buff = ogm_buff;
0287 bat_priv->bat_v.ogm_buff_len = ogm_buff_len;
0288
0289 skb = netdev_alloc_skb_ip_align(NULL, ETH_HLEN + ogm_buff_len);
0290 if (!skb)
0291 goto reschedule;
0292
0293 skb_reserve(skb, ETH_HLEN);
0294 skb_put_data(skb, ogm_buff, ogm_buff_len);
0295
0296 ogm_packet = (struct batadv_ogm2_packet *)skb->data;
0297 ogm_packet->seqno = htonl(atomic_read(&bat_priv->bat_v.ogm_seqno));
0298 atomic_inc(&bat_priv->bat_v.ogm_seqno);
0299 ogm_packet->tvlv_len = htons(tvlv_len);
0300
0301
0302 rcu_read_lock();
0303 list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
0304 if (hard_iface->soft_iface != bat_priv->soft_iface)
0305 continue;
0306
0307 if (!kref_get_unless_zero(&hard_iface->refcount))
0308 continue;
0309
0310 ret = batadv_hardif_no_broadcast(hard_iface, NULL, NULL);
0311 if (ret) {
0312 char *type;
0313
0314 switch (ret) {
0315 case BATADV_HARDIF_BCAST_NORECIPIENT:
0316 type = "no neighbor";
0317 break;
0318 case BATADV_HARDIF_BCAST_DUPFWD:
0319 type = "single neighbor is source";
0320 break;
0321 case BATADV_HARDIF_BCAST_DUPORIG:
0322 type = "single neighbor is originator";
0323 break;
0324 default:
0325 type = "unknown";
0326 }
0327
0328 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, "OGM2 from ourselves on %s suppressed: %s\n",
0329 hard_iface->net_dev->name, type);
0330
0331 batadv_hardif_put(hard_iface);
0332 continue;
0333 }
0334
0335 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
0336 "Sending own OGM2 packet (originator %pM, seqno %u, throughput %u, TTL %d) on interface %s [%pM]\n",
0337 ogm_packet->orig, ntohl(ogm_packet->seqno),
0338 ntohl(ogm_packet->throughput), ogm_packet->ttl,
0339 hard_iface->net_dev->name,
0340 hard_iface->net_dev->dev_addr);
0341
0342
0343 skb_tmp = skb_clone(skb, GFP_ATOMIC);
0344 if (!skb_tmp) {
0345 batadv_hardif_put(hard_iface);
0346 break;
0347 }
0348
0349 batadv_v_ogm_queue_on_if(skb_tmp, hard_iface);
0350 batadv_hardif_put(hard_iface);
0351 }
0352 rcu_read_unlock();
0353
0354 consume_skb(skb);
0355
0356 reschedule:
0357 batadv_v_ogm_start_timer(bat_priv);
0358 out:
0359 return;
0360 }
0361
0362
0363
0364
0365
0366 static void batadv_v_ogm_send(struct work_struct *work)
0367 {
0368 struct batadv_priv_bat_v *bat_v;
0369 struct batadv_priv *bat_priv;
0370
0371 bat_v = container_of(work, struct batadv_priv_bat_v, ogm_wq.work);
0372 bat_priv = container_of(bat_v, struct batadv_priv, bat_v);
0373
0374 mutex_lock(&bat_priv->bat_v.ogm_buff_mutex);
0375 batadv_v_ogm_send_softif(bat_priv);
0376 mutex_unlock(&bat_priv->bat_v.ogm_buff_mutex);
0377 }
0378
0379
0380
0381
0382
0383
0384
0385 void batadv_v_ogm_aggr_work(struct work_struct *work)
0386 {
0387 struct batadv_hard_iface_bat_v *batv;
0388 struct batadv_hard_iface *hard_iface;
0389
0390 batv = container_of(work, struct batadv_hard_iface_bat_v, aggr_wq.work);
0391 hard_iface = container_of(batv, struct batadv_hard_iface, bat_v);
0392
0393 spin_lock_bh(&hard_iface->bat_v.aggr_list.lock);
0394 batadv_v_ogm_aggr_send(hard_iface);
0395 spin_unlock_bh(&hard_iface->bat_v.aggr_list.lock);
0396
0397 batadv_v_ogm_start_queue_timer(hard_iface);
0398 }
0399
0400
0401
0402
0403
0404
0405
0406
0407
0408 int batadv_v_ogm_iface_enable(struct batadv_hard_iface *hard_iface)
0409 {
0410 struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
0411
0412 batadv_v_ogm_start_queue_timer(hard_iface);
0413 batadv_v_ogm_start_timer(bat_priv);
0414
0415 return 0;
0416 }
0417
0418
0419
0420
0421
0422 void batadv_v_ogm_iface_disable(struct batadv_hard_iface *hard_iface)
0423 {
0424 cancel_delayed_work_sync(&hard_iface->bat_v.aggr_wq);
0425
0426 spin_lock_bh(&hard_iface->bat_v.aggr_list.lock);
0427 batadv_v_ogm_aggr_list_free(hard_iface);
0428 spin_unlock_bh(&hard_iface->bat_v.aggr_list.lock);
0429 }
0430
0431
0432
0433
0434
0435 void batadv_v_ogm_primary_iface_set(struct batadv_hard_iface *primary_iface)
0436 {
0437 struct batadv_priv *bat_priv = netdev_priv(primary_iface->soft_iface);
0438 struct batadv_ogm2_packet *ogm_packet;
0439
0440 mutex_lock(&bat_priv->bat_v.ogm_buff_mutex);
0441 if (!bat_priv->bat_v.ogm_buff)
0442 goto unlock;
0443
0444 ogm_packet = (struct batadv_ogm2_packet *)bat_priv->bat_v.ogm_buff;
0445 ether_addr_copy(ogm_packet->orig, primary_iface->net_dev->dev_addr);
0446
0447 unlock:
0448 mutex_unlock(&bat_priv->bat_v.ogm_buff_mutex);
0449 }
0450
0451
0452
0453
0454
0455
0456
0457
0458
0459
0460
0461
0462
0463
0464
0465
0466
0467
0468
0469
0470
0471
0472
0473
0474 static u32 batadv_v_forward_penalty(struct batadv_priv *bat_priv,
0475 struct batadv_hard_iface *if_incoming,
0476 struct batadv_hard_iface *if_outgoing,
0477 u32 throughput)
0478 {
0479 int if_hop_penalty = atomic_read(&if_incoming->hop_penalty);
0480 int hop_penalty = atomic_read(&bat_priv->hop_penalty);
0481 int hop_penalty_max = BATADV_TQ_MAX_VALUE;
0482
0483
0484 throughput = throughput * (hop_penalty_max - if_hop_penalty) /
0485 hop_penalty_max;
0486
0487
0488 if (if_outgoing == BATADV_IF_DEFAULT)
0489 return throughput;
0490
0491
0492
0493
0494
0495 if (throughput > 10 &&
0496 if_incoming == if_outgoing &&
0497 !(if_incoming->bat_v.flags & BATADV_FULL_DUPLEX))
0498 return throughput / 2;
0499
0500
0501 return throughput * (hop_penalty_max - hop_penalty) / hop_penalty_max;
0502 }
0503
0504
0505
0506
0507
0508
0509
0510
0511
0512
0513
0514
0515
0516
0517 static void batadv_v_ogm_forward(struct batadv_priv *bat_priv,
0518 const struct batadv_ogm2_packet *ogm_received,
0519 struct batadv_orig_node *orig_node,
0520 struct batadv_neigh_node *neigh_node,
0521 struct batadv_hard_iface *if_incoming,
0522 struct batadv_hard_iface *if_outgoing)
0523 {
0524 struct batadv_neigh_ifinfo *neigh_ifinfo = NULL;
0525 struct batadv_orig_ifinfo *orig_ifinfo = NULL;
0526 struct batadv_neigh_node *router = NULL;
0527 struct batadv_ogm2_packet *ogm_forward;
0528 unsigned char *skb_buff;
0529 struct sk_buff *skb;
0530 size_t packet_len;
0531 u16 tvlv_len;
0532
0533
0534 if (if_outgoing == BATADV_IF_DEFAULT)
0535 goto out;
0536
0537 orig_ifinfo = batadv_orig_ifinfo_new(orig_node, if_outgoing);
0538 if (!orig_ifinfo)
0539 goto out;
0540
0541
0542 router = batadv_orig_router_get(orig_node, if_outgoing);
0543
0544
0545 if (neigh_node != router)
0546 goto out;
0547
0548
0549 if (orig_ifinfo->last_seqno_forwarded == ntohl(ogm_received->seqno))
0550 goto out;
0551
0552 orig_ifinfo->last_seqno_forwarded = ntohl(ogm_received->seqno);
0553
0554 if (ogm_received->ttl <= 1) {
0555 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, "ttl exceeded\n");
0556 goto out;
0557 }
0558
0559 neigh_ifinfo = batadv_neigh_ifinfo_get(neigh_node, if_outgoing);
0560 if (!neigh_ifinfo)
0561 goto out;
0562
0563 tvlv_len = ntohs(ogm_received->tvlv_len);
0564
0565 packet_len = BATADV_OGM2_HLEN + tvlv_len;
0566 skb = netdev_alloc_skb_ip_align(if_outgoing->net_dev,
0567 ETH_HLEN + packet_len);
0568 if (!skb)
0569 goto out;
0570
0571 skb_reserve(skb, ETH_HLEN);
0572 skb_buff = skb_put_data(skb, ogm_received, packet_len);
0573
0574
0575 ogm_forward = (struct batadv_ogm2_packet *)skb_buff;
0576 ogm_forward->throughput = htonl(neigh_ifinfo->bat_v.throughput);
0577 ogm_forward->ttl--;
0578
0579 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
0580 "Forwarding OGM2 packet on %s: throughput %u, ttl %u, received via %s\n",
0581 if_outgoing->net_dev->name, ntohl(ogm_forward->throughput),
0582 ogm_forward->ttl, if_incoming->net_dev->name);
0583
0584 batadv_v_ogm_queue_on_if(skb, if_outgoing);
0585
0586 out:
0587 batadv_orig_ifinfo_put(orig_ifinfo);
0588 batadv_neigh_node_put(router);
0589 batadv_neigh_ifinfo_put(neigh_ifinfo);
0590 }
0591
0592
0593
0594
0595
0596
0597
0598
0599
0600
0601
0602
0603
0604
0605
0606 static int batadv_v_ogm_metric_update(struct batadv_priv *bat_priv,
0607 const struct batadv_ogm2_packet *ogm2,
0608 struct batadv_orig_node *orig_node,
0609 struct batadv_neigh_node *neigh_node,
0610 struct batadv_hard_iface *if_incoming,
0611 struct batadv_hard_iface *if_outgoing)
0612 {
0613 struct batadv_orig_ifinfo *orig_ifinfo;
0614 struct batadv_neigh_ifinfo *neigh_ifinfo = NULL;
0615 bool protection_started = false;
0616 int ret = -EINVAL;
0617 u32 path_throughput;
0618 s32 seq_diff;
0619
0620 orig_ifinfo = batadv_orig_ifinfo_new(orig_node, if_outgoing);
0621 if (!orig_ifinfo)
0622 goto out;
0623
0624 seq_diff = ntohl(ogm2->seqno) - orig_ifinfo->last_real_seqno;
0625
0626 if (!hlist_empty(&orig_node->neigh_list) &&
0627 batadv_window_protected(bat_priv, seq_diff,
0628 BATADV_OGM_MAX_AGE,
0629 &orig_ifinfo->batman_seqno_reset,
0630 &protection_started)) {
0631 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
0632 "Drop packet: packet within window protection time from %pM\n",
0633 ogm2->orig);
0634 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
0635 "Last reset: %ld, %ld\n",
0636 orig_ifinfo->batman_seqno_reset, jiffies);
0637 goto out;
0638 }
0639
0640
0641
0642
0643 if (seq_diff < 0 && !protection_started)
0644 goto out;
0645
0646 neigh_node->last_seen = jiffies;
0647
0648 orig_node->last_seen = jiffies;
0649
0650 orig_ifinfo->last_real_seqno = ntohl(ogm2->seqno);
0651 orig_ifinfo->last_ttl = ogm2->ttl;
0652
0653 neigh_ifinfo = batadv_neigh_ifinfo_new(neigh_node, if_outgoing);
0654 if (!neigh_ifinfo)
0655 goto out;
0656
0657 path_throughput = batadv_v_forward_penalty(bat_priv, if_incoming,
0658 if_outgoing,
0659 ntohl(ogm2->throughput));
0660 neigh_ifinfo->bat_v.throughput = path_throughput;
0661 neigh_ifinfo->bat_v.last_seqno = ntohl(ogm2->seqno);
0662 neigh_ifinfo->last_ttl = ogm2->ttl;
0663
0664 if (seq_diff > 0 || protection_started)
0665 ret = 1;
0666 else
0667 ret = 0;
0668 out:
0669 batadv_orig_ifinfo_put(orig_ifinfo);
0670 batadv_neigh_ifinfo_put(neigh_ifinfo);
0671
0672 return ret;
0673 }
0674
0675
0676
0677
0678
0679
0680
0681
0682
0683
0684
0685
0686
0687 static bool batadv_v_ogm_route_update(struct batadv_priv *bat_priv,
0688 const struct ethhdr *ethhdr,
0689 const struct batadv_ogm2_packet *ogm2,
0690 struct batadv_orig_node *orig_node,
0691 struct batadv_neigh_node *neigh_node,
0692 struct batadv_hard_iface *if_incoming,
0693 struct batadv_hard_iface *if_outgoing)
0694 {
0695 struct batadv_neigh_node *router = NULL;
0696 struct batadv_orig_node *orig_neigh_node;
0697 struct batadv_neigh_node *orig_neigh_router = NULL;
0698 struct batadv_neigh_ifinfo *router_ifinfo = NULL, *neigh_ifinfo = NULL;
0699 u32 router_throughput, neigh_throughput;
0700 u32 router_last_seqno;
0701 u32 neigh_last_seqno;
0702 s32 neigh_seq_diff;
0703 bool forward = false;
0704
0705 orig_neigh_node = batadv_v_ogm_orig_get(bat_priv, ethhdr->h_source);
0706 if (!orig_neigh_node)
0707 goto out;
0708
0709 orig_neigh_router = batadv_orig_router_get(orig_neigh_node,
0710 if_outgoing);
0711
0712
0713
0714
0715 router = batadv_orig_router_get(orig_node, if_outgoing);
0716 if (router && router->orig_node != orig_node && !orig_neigh_router) {
0717 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
0718 "Drop packet: OGM via unknown neighbor!\n");
0719 goto out;
0720 }
0721
0722
0723
0724
0725 forward = true;
0726
0727 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
0728 "Searching and updating originator entry of received packet\n");
0729
0730
0731
0732
0733 if (router == neigh_node)
0734 goto out;
0735
0736
0737
0738
0739
0740 if (router) {
0741 router_ifinfo = batadv_neigh_ifinfo_get(router, if_outgoing);
0742 neigh_ifinfo = batadv_neigh_ifinfo_get(neigh_node, if_outgoing);
0743
0744
0745 if (!router_ifinfo || !neigh_ifinfo)
0746 goto out;
0747
0748 neigh_last_seqno = neigh_ifinfo->bat_v.last_seqno;
0749 router_last_seqno = router_ifinfo->bat_v.last_seqno;
0750 neigh_seq_diff = neigh_last_seqno - router_last_seqno;
0751 router_throughput = router_ifinfo->bat_v.throughput;
0752 neigh_throughput = neigh_ifinfo->bat_v.throughput;
0753
0754 if (neigh_seq_diff < BATADV_OGM_MAX_ORIGDIFF &&
0755 router_throughput >= neigh_throughput)
0756 goto out;
0757 }
0758
0759 batadv_update_route(bat_priv, orig_node, if_outgoing, neigh_node);
0760 out:
0761 batadv_neigh_node_put(router);
0762 batadv_neigh_node_put(orig_neigh_router);
0763 batadv_orig_node_put(orig_neigh_node);
0764 batadv_neigh_ifinfo_put(router_ifinfo);
0765 batadv_neigh_ifinfo_put(neigh_ifinfo);
0766
0767 return forward;
0768 }
0769
0770
0771
0772
0773
0774
0775
0776
0777
0778
0779
0780 static void
0781 batadv_v_ogm_process_per_outif(struct batadv_priv *bat_priv,
0782 const struct ethhdr *ethhdr,
0783 const struct batadv_ogm2_packet *ogm2,
0784 struct batadv_orig_node *orig_node,
0785 struct batadv_neigh_node *neigh_node,
0786 struct batadv_hard_iface *if_incoming,
0787 struct batadv_hard_iface *if_outgoing)
0788 {
0789 int seqno_age;
0790 bool forward;
0791
0792
0793 seqno_age = batadv_v_ogm_metric_update(bat_priv, ogm2, orig_node,
0794 neigh_node, if_incoming,
0795 if_outgoing);
0796
0797
0798 if (seqno_age < 0)
0799 return;
0800
0801
0802 if (seqno_age > 0 && if_outgoing == BATADV_IF_DEFAULT)
0803 batadv_tvlv_containers_process(bat_priv, true, orig_node,
0804 NULL, NULL,
0805 (unsigned char *)(ogm2 + 1),
0806 ntohs(ogm2->tvlv_len));
0807
0808
0809 forward = batadv_v_ogm_route_update(bat_priv, ethhdr, ogm2, orig_node,
0810 neigh_node, if_incoming,
0811 if_outgoing);
0812
0813
0814 if (forward)
0815 batadv_v_ogm_forward(bat_priv, ogm2, orig_node, neigh_node,
0816 if_incoming, if_outgoing);
0817 }
0818
0819
0820
0821
0822
0823
0824
0825
0826
0827 static bool
0828 batadv_v_ogm_aggr_packet(int buff_pos, int packet_len,
0829 const struct batadv_ogm2_packet *ogm2_packet)
0830 {
0831 int next_buff_pos = 0;
0832
0833
0834 next_buff_pos += buff_pos + sizeof(*ogm2_packet);
0835 if (next_buff_pos > packet_len)
0836 return false;
0837
0838
0839 next_buff_pos += ntohs(ogm2_packet->tvlv_len);
0840
0841 return (next_buff_pos <= packet_len) &&
0842 (next_buff_pos <= BATADV_MAX_AGGREGATION_BYTES);
0843 }
0844
0845
0846
0847
0848
0849
0850
0851 static void batadv_v_ogm_process(const struct sk_buff *skb, int ogm_offset,
0852 struct batadv_hard_iface *if_incoming)
0853 {
0854 struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
0855 struct ethhdr *ethhdr;
0856 struct batadv_orig_node *orig_node = NULL;
0857 struct batadv_hardif_neigh_node *hardif_neigh = NULL;
0858 struct batadv_neigh_node *neigh_node = NULL;
0859 struct batadv_hard_iface *hard_iface;
0860 struct batadv_ogm2_packet *ogm_packet;
0861 u32 ogm_throughput, link_throughput, path_throughput;
0862 int ret;
0863
0864 ethhdr = eth_hdr(skb);
0865 ogm_packet = (struct batadv_ogm2_packet *)(skb->data + ogm_offset);
0866
0867 ogm_throughput = ntohl(ogm_packet->throughput);
0868
0869 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
0870 "Received OGM2 packet via NB: %pM, IF: %s [%pM] (from OG: %pM, seqno %u, throughput %u, TTL %u, V %u, tvlv_len %u)\n",
0871 ethhdr->h_source, if_incoming->net_dev->name,
0872 if_incoming->net_dev->dev_addr, ogm_packet->orig,
0873 ntohl(ogm_packet->seqno), ogm_throughput, ogm_packet->ttl,
0874 ogm_packet->version, ntohs(ogm_packet->tvlv_len));
0875
0876 if (batadv_is_my_mac(bat_priv, ogm_packet->orig)) {
0877 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
0878 "Drop packet: originator packet from ourself\n");
0879 return;
0880 }
0881
0882
0883
0884
0885 if (ogm_throughput == 0) {
0886 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
0887 "Drop packet: originator packet with throughput metric of 0\n");
0888 return;
0889 }
0890
0891
0892 hardif_neigh = batadv_hardif_neigh_get(if_incoming, ethhdr->h_source);
0893 if (!hardif_neigh) {
0894 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
0895 "Drop packet: OGM via unknown neighbor!\n");
0896 goto out;
0897 }
0898
0899 orig_node = batadv_v_ogm_orig_get(bat_priv, ogm_packet->orig);
0900 if (!orig_node)
0901 goto out;
0902
0903 neigh_node = batadv_neigh_node_get_or_create(orig_node, if_incoming,
0904 ethhdr->h_source);
0905 if (!neigh_node)
0906 goto out;
0907
0908
0909
0910
0911
0912
0913
0914
0915 link_throughput = ewma_throughput_read(&hardif_neigh->bat_v.throughput);
0916 path_throughput = min_t(u32, link_throughput, ogm_throughput);
0917 ogm_packet->throughput = htonl(path_throughput);
0918
0919 batadv_v_ogm_process_per_outif(bat_priv, ethhdr, ogm_packet, orig_node,
0920 neigh_node, if_incoming,
0921 BATADV_IF_DEFAULT);
0922
0923 rcu_read_lock();
0924 list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
0925 if (hard_iface->if_status != BATADV_IF_ACTIVE)
0926 continue;
0927
0928 if (hard_iface->soft_iface != bat_priv->soft_iface)
0929 continue;
0930
0931 if (!kref_get_unless_zero(&hard_iface->refcount))
0932 continue;
0933
0934 ret = batadv_hardif_no_broadcast(hard_iface,
0935 ogm_packet->orig,
0936 hardif_neigh->orig);
0937
0938 if (ret) {
0939 char *type;
0940
0941 switch (ret) {
0942 case BATADV_HARDIF_BCAST_NORECIPIENT:
0943 type = "no neighbor";
0944 break;
0945 case BATADV_HARDIF_BCAST_DUPFWD:
0946 type = "single neighbor is source";
0947 break;
0948 case BATADV_HARDIF_BCAST_DUPORIG:
0949 type = "single neighbor is originator";
0950 break;
0951 default:
0952 type = "unknown";
0953 }
0954
0955 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, "OGM2 packet from %pM on %s suppressed: %s\n",
0956 ogm_packet->orig, hard_iface->net_dev->name,
0957 type);
0958
0959 batadv_hardif_put(hard_iface);
0960 continue;
0961 }
0962
0963 batadv_v_ogm_process_per_outif(bat_priv, ethhdr, ogm_packet,
0964 orig_node, neigh_node,
0965 if_incoming, hard_iface);
0966
0967 batadv_hardif_put(hard_iface);
0968 }
0969 rcu_read_unlock();
0970 out:
0971 batadv_orig_node_put(orig_node);
0972 batadv_neigh_node_put(neigh_node);
0973 batadv_hardif_neigh_put(hardif_neigh);
0974 }
0975
0976
0977
0978
0979
0980
0981
0982
0983
0984 int batadv_v_ogm_packet_recv(struct sk_buff *skb,
0985 struct batadv_hard_iface *if_incoming)
0986 {
0987 struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
0988 struct batadv_ogm2_packet *ogm_packet;
0989 struct ethhdr *ethhdr = eth_hdr(skb);
0990 int ogm_offset;
0991 u8 *packet_pos;
0992 int ret = NET_RX_DROP;
0993
0994
0995
0996
0997 if (strcmp(bat_priv->algo_ops->name, "BATMAN_V") != 0)
0998 goto free_skb;
0999
1000 if (!batadv_check_management_packet(skb, if_incoming, BATADV_OGM2_HLEN))
1001 goto free_skb;
1002
1003 if (batadv_is_my_mac(bat_priv, ethhdr->h_source))
1004 goto free_skb;
1005
1006 batadv_inc_counter(bat_priv, BATADV_CNT_MGMT_RX);
1007 batadv_add_counter(bat_priv, BATADV_CNT_MGMT_RX_BYTES,
1008 skb->len + ETH_HLEN);
1009
1010 ogm_offset = 0;
1011 ogm_packet = (struct batadv_ogm2_packet *)skb->data;
1012
1013 while (batadv_v_ogm_aggr_packet(ogm_offset, skb_headlen(skb),
1014 ogm_packet)) {
1015 batadv_v_ogm_process(skb, ogm_offset, if_incoming);
1016
1017 ogm_offset += BATADV_OGM2_HLEN;
1018 ogm_offset += ntohs(ogm_packet->tvlv_len);
1019
1020 packet_pos = skb->data + ogm_offset;
1021 ogm_packet = (struct batadv_ogm2_packet *)packet_pos;
1022 }
1023
1024 ret = NET_RX_SUCCESS;
1025
1026 free_skb:
1027 if (ret == NET_RX_SUCCESS)
1028 consume_skb(skb);
1029 else
1030 kfree_skb(skb);
1031
1032 return ret;
1033 }
1034
1035
1036
1037
1038
1039
1040
1041 int batadv_v_ogm_init(struct batadv_priv *bat_priv)
1042 {
1043 struct batadv_ogm2_packet *ogm_packet;
1044 unsigned char *ogm_buff;
1045 u32 random_seqno;
1046
1047 bat_priv->bat_v.ogm_buff_len = BATADV_OGM2_HLEN;
1048 ogm_buff = kzalloc(bat_priv->bat_v.ogm_buff_len, GFP_ATOMIC);
1049 if (!ogm_buff)
1050 return -ENOMEM;
1051
1052 bat_priv->bat_v.ogm_buff = ogm_buff;
1053 ogm_packet = (struct batadv_ogm2_packet *)ogm_buff;
1054 ogm_packet->packet_type = BATADV_OGM2;
1055 ogm_packet->version = BATADV_COMPAT_VERSION;
1056 ogm_packet->ttl = BATADV_TTL;
1057 ogm_packet->flags = BATADV_NO_FLAGS;
1058 ogm_packet->throughput = htonl(BATADV_THROUGHPUT_MAX_VALUE);
1059
1060
1061 get_random_bytes(&random_seqno, sizeof(random_seqno));
1062 atomic_set(&bat_priv->bat_v.ogm_seqno, random_seqno);
1063 INIT_DELAYED_WORK(&bat_priv->bat_v.ogm_wq, batadv_v_ogm_send);
1064
1065 mutex_init(&bat_priv->bat_v.ogm_buff_mutex);
1066
1067 return 0;
1068 }
1069
1070
1071
1072
1073
1074 void batadv_v_ogm_free(struct batadv_priv *bat_priv)
1075 {
1076 cancel_delayed_work_sync(&bat_priv->bat_v.ogm_wq);
1077
1078 mutex_lock(&bat_priv->bat_v.ogm_buff_mutex);
1079
1080 kfree(bat_priv->bat_v.ogm_buff);
1081 bat_priv->bat_v.ogm_buff = NULL;
1082 bat_priv->bat_v.ogm_buff_len = 0;
1083
1084 mutex_unlock(&bat_priv->bat_v.ogm_buff_mutex);
1085 }