1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (C) B.A.T.M.A.N. contributors:
3 *
4 * Marek Lindner, Simon Wunderlich
5 */
6
7 #include "bat_iv_ogm.h"
8 #include "main.h"
9
10 #include <linux/atomic.h>
11 #include <linux/bitmap.h>
12 #include <linux/bitops.h>
13 #include <linux/bug.h>
14 #include <linux/byteorder/generic.h>
15 #include <linux/cache.h>
16 #include <linux/container_of.h>
17 #include <linux/errno.h>
18 #include <linux/etherdevice.h>
19 #include <linux/gfp.h>
20 #include <linux/if_ether.h>
21 #include <linux/init.h>
22 #include <linux/jiffies.h>
23 #include <linux/kref.h>
24 #include <linux/list.h>
25 #include <linux/lockdep.h>
26 #include <linux/minmax.h>
27 #include <linux/mutex.h>
28 #include <linux/netdevice.h>
29 #include <linux/netlink.h>
30 #include <linux/pkt_sched.h>
31 #include <linux/printk.h>
32 #include <linux/random.h>
33 #include <linux/rculist.h>
34 #include <linux/rcupdate.h>
35 #include <linux/skbuff.h>
36 #include <linux/slab.h>
37 #include <linux/spinlock.h>
38 #include <linux/stddef.h>
39 #include <linux/string.h>
40 #include <linux/string_choices.h>
41 #include <linux/types.h>
42 #include <linux/workqueue.h>
43 #include <net/genetlink.h>
44 #include <net/netlink.h>
45 #include <uapi/linux/batadv_packet.h>
46 #include <uapi/linux/batman_adv.h>
47
48 #include "bat_algo.h"
49 #include "bitarray.h"
50 #include "gateway_client.h"
51 #include "hard-interface.h"
52 #include "hash.h"
53 #include "log.h"
54 #include "netlink.h"
55 #include "originator.h"
56 #include "routing.h"
57 #include "send.h"
58 #include "translation-table.h"
59 #include "tvlv.h"
60
61 static void batadv_iv_send_outstanding_bat_ogm_packet(struct work_struct *work);
62
63 /**
64 * enum batadv_dup_status - duplicate status
65 */
66 enum batadv_dup_status {
67 /** @BATADV_NO_DUP: the packet is no duplicate */
68 BATADV_NO_DUP = 0,
69
70 /**
71 * @BATADV_ORIG_DUP: OGM is a duplicate in the originator (but not for
72 * the neighbor)
73 */
74 BATADV_ORIG_DUP,
75
76 /** @BATADV_NEIGH_DUP: OGM is a duplicate for the neighbor */
77 BATADV_NEIGH_DUP,
78
79 /**
80 * @BATADV_PROTECTED: originator is currently protected (after reboot)
81 */
82 BATADV_PROTECTED,
83 };
84
85 /**
86 * batadv_ring_buffer_set() - update the ring buffer with the given value
87 * @lq_recv: pointer to the ring buffer
88 * @lq_index: index to store the value at
89 * @value: value to store in the ring buffer
90 */
batadv_ring_buffer_set(u8 lq_recv[],u8 * lq_index,u8 value)91 static void batadv_ring_buffer_set(u8 lq_recv[], u8 *lq_index, u8 value)
92 {
93 lq_recv[*lq_index] = value;
94 *lq_index = (*lq_index + 1) % BATADV_TQ_GLOBAL_WINDOW_SIZE;
95 }
96
97 /**
98 * batadv_ring_buffer_avg() - compute the average of all non-zero values stored
99 * in the given ring buffer
100 * @lq_recv: pointer to the ring buffer
101 *
102 * Return: computed average value.
103 */
batadv_ring_buffer_avg(const u8 lq_recv[])104 static u8 batadv_ring_buffer_avg(const u8 lq_recv[])
105 {
106 const u8 *ptr;
107 u16 count = 0;
108 u16 i = 0;
109 u16 sum = 0;
110
111 ptr = lq_recv;
112
113 while (i < BATADV_TQ_GLOBAL_WINDOW_SIZE) {
114 if (*ptr != 0) {
115 count++;
116 sum += *ptr;
117 }
118
119 i++;
120 ptr++;
121 }
122
123 if (count == 0)
124 return 0;
125
126 return (u8)(sum / count);
127 }
128
129 /**
130 * batadv_iv_ogm_orig_get() - retrieve or create (if does not exist) an
131 * originator
132 * @bat_priv: the bat priv with all the mesh interface information
133 * @addr: mac address of the originator
134 *
135 * Return: the originator object corresponding to the passed mac address or NULL
136 * on failure.
137 * If the object does not exist, it is created and initialised.
138 */
139 static struct batadv_orig_node *
batadv_iv_ogm_orig_get(struct batadv_priv * bat_priv,const u8 * addr)140 batadv_iv_ogm_orig_get(struct batadv_priv *bat_priv, const u8 *addr)
141 {
142 struct batadv_orig_node *orig_node;
143 int hash_added;
144
145 orig_node = batadv_orig_hash_find(bat_priv, addr);
146 if (orig_node)
147 return orig_node;
148
149 orig_node = batadv_orig_node_new(bat_priv, addr);
150 if (!orig_node)
151 return NULL;
152
153 spin_lock_init(&orig_node->bat_iv.ogm_cnt_lock);
154
155 kref_get(&orig_node->refcount);
156 hash_added = batadv_hash_add(bat_priv->orig_hash, batadv_compare_orig,
157 batadv_choose_orig, orig_node,
158 &orig_node->hash_entry);
159 if (hash_added != 0)
160 goto free_orig_node_hash;
161
162 return orig_node;
163
164 free_orig_node_hash:
165 /* reference for batadv_hash_add */
166 batadv_orig_node_put(orig_node);
167 /* reference from batadv_orig_node_new */
168 batadv_orig_node_put(orig_node);
169
170 return NULL;
171 }
172
173 static struct batadv_neigh_node *
batadv_iv_ogm_neigh_new(struct batadv_hard_iface * hard_iface,const u8 * neigh_addr,struct batadv_orig_node * orig_node)174 batadv_iv_ogm_neigh_new(struct batadv_hard_iface *hard_iface,
175 const u8 *neigh_addr,
176 struct batadv_orig_node *orig_node)
177 {
178 struct batadv_neigh_node *neigh_node;
179
180 neigh_node = batadv_neigh_node_get_or_create(orig_node,
181 hard_iface, neigh_addr);
182 return neigh_node;
183 }
184
batadv_iv_ogm_iface_enable(struct batadv_hard_iface * hard_iface)185 static int batadv_iv_ogm_iface_enable(struct batadv_hard_iface *hard_iface)
186 {
187 struct batadv_ogm_packet *batadv_ogm_packet;
188 unsigned char *ogm_buff;
189 u32 random_seqno;
190
191 mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex);
192
193 /* randomize initial seqno to avoid collision */
194 get_random_bytes(&random_seqno, sizeof(random_seqno));
195 atomic_set(&hard_iface->bat_iv.ogm_seqno, random_seqno);
196
197 hard_iface->bat_iv.ogm_buff_len = BATADV_OGM_HLEN;
198 ogm_buff = kmalloc(hard_iface->bat_iv.ogm_buff_len, GFP_ATOMIC);
199 if (!ogm_buff) {
200 mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
201 return -ENOMEM;
202 }
203
204 hard_iface->bat_iv.ogm_buff = ogm_buff;
205
206 batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff;
207 batadv_ogm_packet->packet_type = BATADV_IV_OGM;
208 batadv_ogm_packet->version = BATADV_COMPAT_VERSION;
209 batadv_ogm_packet->ttl = 2;
210 batadv_ogm_packet->flags = BATADV_NO_FLAGS;
211 batadv_ogm_packet->reserved = 0;
212 batadv_ogm_packet->tq = BATADV_TQ_MAX_VALUE;
213
214 mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
215
216 return 0;
217 }
218
batadv_iv_ogm_iface_disable(struct batadv_hard_iface * hard_iface)219 static void batadv_iv_ogm_iface_disable(struct batadv_hard_iface *hard_iface)
220 {
221 mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex);
222
223 kfree(hard_iface->bat_iv.ogm_buff);
224 hard_iface->bat_iv.ogm_buff = NULL;
225
226 mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
227 }
228
batadv_iv_ogm_iface_update_mac(struct batadv_hard_iface * hard_iface)229 static void batadv_iv_ogm_iface_update_mac(struct batadv_hard_iface *hard_iface)
230 {
231 struct batadv_ogm_packet *batadv_ogm_packet;
232 void *ogm_buff;
233
234 mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex);
235
236 ogm_buff = hard_iface->bat_iv.ogm_buff;
237 if (!ogm_buff)
238 goto unlock;
239
240 batadv_ogm_packet = ogm_buff;
241 ether_addr_copy(batadv_ogm_packet->orig,
242 hard_iface->net_dev->dev_addr);
243 ether_addr_copy(batadv_ogm_packet->prev_sender,
244 hard_iface->net_dev->dev_addr);
245
246 unlock:
247 mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
248 }
249
250 static void
batadv_iv_ogm_primary_iface_set(struct batadv_hard_iface * hard_iface)251 batadv_iv_ogm_primary_iface_set(struct batadv_hard_iface *hard_iface)
252 {
253 struct batadv_ogm_packet *batadv_ogm_packet;
254 void *ogm_buff;
255
256 mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex);
257
258 ogm_buff = hard_iface->bat_iv.ogm_buff;
259 if (!ogm_buff)
260 goto unlock;
261
262 batadv_ogm_packet = ogm_buff;
263 batadv_ogm_packet->ttl = BATADV_TTL;
264
265 unlock:
266 mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
267 }
268
269 /* when do we schedule our own ogm to be sent */
270 static unsigned long
batadv_iv_ogm_emit_send_time(const struct batadv_priv * bat_priv)271 batadv_iv_ogm_emit_send_time(const struct batadv_priv *bat_priv)
272 {
273 unsigned int msecs;
274
275 msecs = atomic_read(&bat_priv->orig_interval) - BATADV_JITTER;
276 msecs += get_random_u32_below(2 * BATADV_JITTER);
277
278 return jiffies + msecs_to_jiffies(msecs);
279 }
280
281 /* when do we schedule a ogm packet to be sent */
batadv_iv_ogm_fwd_send_time(void)282 static unsigned long batadv_iv_ogm_fwd_send_time(void)
283 {
284 return jiffies + msecs_to_jiffies(get_random_u32_below(BATADV_JITTER / 2));
285 }
286
287 /* apply hop penalty for a normal link */
batadv_hop_penalty(u8 tq,const struct batadv_priv * bat_priv)288 static u8 batadv_hop_penalty(u8 tq, const struct batadv_priv *bat_priv)
289 {
290 int hop_penalty = atomic_read(&bat_priv->hop_penalty);
291 int new_tq;
292
293 new_tq = tq * (BATADV_TQ_MAX_VALUE - hop_penalty);
294 new_tq /= BATADV_TQ_MAX_VALUE;
295
296 return new_tq;
297 }
298
299 /**
300 * batadv_iv_ogm_aggr_packet() - checks if there is another OGM attached
301 * @buff_pos: current position in the skb
302 * @packet_len: total length of the skb
303 * @ogm_packet: potential OGM in buffer
304 *
305 * Return: true if there is enough space for another OGM, false otherwise.
306 */
307 static bool
batadv_iv_ogm_aggr_packet(int buff_pos,int packet_len,const struct batadv_ogm_packet * ogm_packet)308 batadv_iv_ogm_aggr_packet(int buff_pos, int packet_len,
309 const struct batadv_ogm_packet *ogm_packet)
310 {
311 int next_buff_pos = 0;
312
313 /* check if there is enough space for the header */
314 next_buff_pos += buff_pos + sizeof(*ogm_packet);
315 if (next_buff_pos > packet_len)
316 return false;
317
318 /* check if there is enough space for the optional TVLV */
319 next_buff_pos += ntohs(ogm_packet->tvlv_len);
320
321 return next_buff_pos <= packet_len;
322 }
323
324 /* send a batman ogm to a given interface */
batadv_iv_ogm_send_to_if(struct batadv_forw_packet * forw_packet,struct batadv_hard_iface * hard_iface)325 static void batadv_iv_ogm_send_to_if(struct batadv_forw_packet *forw_packet,
326 struct batadv_hard_iface *hard_iface)
327 {
328 struct batadv_priv *bat_priv = netdev_priv(hard_iface->mesh_iface);
329 const char *fwd_str;
330 u8 packet_num;
331 int buff_pos;
332 struct batadv_ogm_packet *batadv_ogm_packet;
333 struct sk_buff *skb;
334 u8 *packet_pos;
335
336 if (hard_iface->if_status != BATADV_IF_ACTIVE)
337 return;
338
339 packet_num = 0;
340 buff_pos = 0;
341 packet_pos = forw_packet->skb->data;
342 batadv_ogm_packet = (struct batadv_ogm_packet *)packet_pos;
343
344 /* adjust all flags and log packets */
345 while (batadv_iv_ogm_aggr_packet(buff_pos, forw_packet->packet_len,
346 batadv_ogm_packet)) {
347 /* we might have aggregated direct link packets with an
348 * ordinary base packet
349 */
350 if (test_bit(packet_num, forw_packet->direct_link_flags) &&
351 forw_packet->if_incoming == hard_iface)
352 batadv_ogm_packet->flags |= BATADV_DIRECTLINK;
353 else
354 batadv_ogm_packet->flags &= ~BATADV_DIRECTLINK;
355
356 if (packet_num > 0 || !forw_packet->own)
357 fwd_str = "Forwarding";
358 else
359 fwd_str = "Sending own";
360
361 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
362 "%s %spacket (originator %pM, seqno %u, TQ %d, TTL %d, IDF %s) on interface %s [%pM]\n",
363 fwd_str, (packet_num > 0 ? "aggregated " : ""),
364 batadv_ogm_packet->orig,
365 ntohl(batadv_ogm_packet->seqno),
366 batadv_ogm_packet->tq, batadv_ogm_packet->ttl,
367 str_on_off(batadv_ogm_packet->flags & BATADV_DIRECTLINK),
368 hard_iface->net_dev->name,
369 hard_iface->net_dev->dev_addr);
370
371 buff_pos += BATADV_OGM_HLEN;
372 buff_pos += ntohs(batadv_ogm_packet->tvlv_len);
373 packet_num++;
374 packet_pos = forw_packet->skb->data + buff_pos;
375 batadv_ogm_packet = (struct batadv_ogm_packet *)packet_pos;
376 }
377
378 /* create clone because function is called more than once */
379 skb = skb_clone(forw_packet->skb, GFP_ATOMIC);
380 if (skb) {
381 batadv_inc_counter(bat_priv, BATADV_CNT_MGMT_TX);
382 batadv_add_counter(bat_priv, BATADV_CNT_MGMT_TX_BYTES,
383 skb->len + ETH_HLEN);
384 batadv_send_broadcast_skb(skb, hard_iface);
385 }
386 }
387
388 /* send a batman ogm packet */
batadv_iv_ogm_emit(struct batadv_forw_packet * forw_packet)389 static void batadv_iv_ogm_emit(struct batadv_forw_packet *forw_packet)
390 {
391 struct net_device *mesh_iface;
392
393 if (!forw_packet->if_incoming) {
394 pr_err("Error - can't forward packet: incoming iface not specified\n");
395 return;
396 }
397
398 mesh_iface = forw_packet->if_incoming->mesh_iface;
399
400 if (WARN_ON(!forw_packet->if_outgoing))
401 return;
402
403 if (forw_packet->if_outgoing->mesh_iface != mesh_iface) {
404 pr_warn("%s: mesh interface switch for queued OGM\n", __func__);
405 return;
406 }
407
408 if (forw_packet->if_incoming->if_status != BATADV_IF_ACTIVE)
409 return;
410
411 /* only for one specific outgoing interface */
412 batadv_iv_ogm_send_to_if(forw_packet, forw_packet->if_outgoing);
413 }
414
415 /**
416 * batadv_iv_ogm_can_aggregate() - find out if an OGM can be aggregated on an
417 * existing forward packet
418 * @new_bat_ogm_packet: OGM packet to be aggregated
419 * @bat_priv: the bat priv with all the mesh interface information
420 * @packet_len: (total) length of the OGM
421 * @send_time: timestamp (jiffies) when the packet is to be sent
422 * @directlink: true if this is a direct link packet
423 * @if_incoming: interface where the packet was received
424 * @if_outgoing: interface for which the retransmission should be considered
425 * @forw_packet: the forwarded packet which should be checked
426 *
427 * Return: true if new_packet can be aggregated with forw_packet
428 */
429 static bool
batadv_iv_ogm_can_aggregate(const struct batadv_ogm_packet * new_bat_ogm_packet,struct batadv_priv * bat_priv,int packet_len,unsigned long send_time,bool directlink,const struct batadv_hard_iface * if_incoming,const struct batadv_hard_iface * if_outgoing,const struct batadv_forw_packet * forw_packet)430 batadv_iv_ogm_can_aggregate(const struct batadv_ogm_packet *new_bat_ogm_packet,
431 struct batadv_priv *bat_priv,
432 int packet_len, unsigned long send_time,
433 bool directlink,
434 const struct batadv_hard_iface *if_incoming,
435 const struct batadv_hard_iface *if_outgoing,
436 const struct batadv_forw_packet *forw_packet)
437 {
438 struct batadv_ogm_packet *batadv_ogm_packet;
439 unsigned int aggregated_bytes = forw_packet->packet_len + packet_len;
440 struct batadv_hard_iface *primary_if = NULL;
441 u8 packet_num = forw_packet->num_packets;
442 bool res = false;
443 unsigned long aggregation_end_time;
444 unsigned int max_bytes;
445
446 batadv_ogm_packet = (struct batadv_ogm_packet *)forw_packet->skb->data;
447 aggregation_end_time = send_time;
448 aggregation_end_time += msecs_to_jiffies(BATADV_MAX_AGGREGATION_MS);
449
450 max_bytes = min_t(unsigned int, if_outgoing->net_dev->mtu,
451 BATADV_MAX_AGGREGATION_BYTES);
452
453 /* we can aggregate the current packet to this aggregated packet
454 * if:
455 *
456 * - the send time is within our MAX_AGGREGATION_MS time
457 * - the resulting packet won't be bigger than
458 * MAX_AGGREGATION_BYTES and MTU of the outgoing interface
459 * - the number of packets is lower than MAX_AGGREGATION_PACKETS
460 * otherwise aggregation is not possible
461 */
462 if (!time_before(send_time, forw_packet->send_time) ||
463 !time_after_eq(aggregation_end_time, forw_packet->send_time))
464 return false;
465
466 if (aggregated_bytes > max_bytes)
467 return false;
468
469 if (skb_tailroom(forw_packet->skb) < packet_len)
470 return false;
471
472 if (packet_num >= BATADV_MAX_AGGREGATION_PACKETS)
473 return false;
474
475 /* packet is not leaving on the same interface. */
476 if (forw_packet->if_outgoing != if_outgoing)
477 return false;
478
479 /* check aggregation compatibility
480 * -> direct link packets are broadcasted on
481 * their interface only
482 * -> aggregate packet if the current packet is
483 * a "global" packet as well as the base
484 * packet
485 */
486 primary_if = batadv_primary_if_get_selected(bat_priv);
487 if (!primary_if)
488 return false;
489
490 /* packets without direct link flag and high TTL
491 * are flooded through the net
492 */
493 if (!directlink &&
494 !(batadv_ogm_packet->flags & BATADV_DIRECTLINK) &&
495 batadv_ogm_packet->ttl != 1 &&
496
497 /* own packets originating non-primary
498 * interfaces leave only that interface
499 */
500 (!forw_packet->own ||
501 forw_packet->if_incoming == primary_if)) {
502 res = true;
503 goto out;
504 }
505
506 /* if the incoming packet is sent via this one
507 * interface only - we still can aggregate
508 */
509 if (directlink &&
510 new_bat_ogm_packet->ttl == 1 &&
511 forw_packet->if_incoming == if_incoming &&
512
513 /* packets from direct neighbors or
514 * own secondary interface packets
515 * (= secondary interface packets in general)
516 */
517 (batadv_ogm_packet->flags & BATADV_DIRECTLINK ||
518 (forw_packet->own &&
519 forw_packet->if_incoming != primary_if))) {
520 res = true;
521 goto out;
522 }
523
524 out:
525 batadv_hardif_put(primary_if);
526 return res;
527 }
528
529 /**
530 * batadv_iv_ogm_aggregate_new() - create a new aggregated packet and add this
531 * packet to it.
532 * @packet_buff: pointer to the OGM
533 * @packet_len: (total) length of the OGM
534 * @send_time: timestamp (jiffies) when the packet is to be sent
535 * @direct_link: whether this OGM has direct link status
536 * @if_incoming: interface where the packet was received
537 * @if_outgoing: interface for which the retransmission should be considered
538 * @own_packet: true if it is a self-generated ogm
539 */
batadv_iv_ogm_aggregate_new(const unsigned char * packet_buff,int packet_len,unsigned long send_time,bool direct_link,struct batadv_hard_iface * if_incoming,struct batadv_hard_iface * if_outgoing,int own_packet)540 static void batadv_iv_ogm_aggregate_new(const unsigned char *packet_buff,
541 int packet_len, unsigned long send_time,
542 bool direct_link,
543 struct batadv_hard_iface *if_incoming,
544 struct batadv_hard_iface *if_outgoing,
545 int own_packet)
546 {
547 struct batadv_priv *bat_priv = netdev_priv(if_incoming->mesh_iface);
548 struct batadv_forw_packet *forw_packet_aggr;
549 struct sk_buff *skb;
550 unsigned char *skb_buff;
551 unsigned int skb_size;
552 atomic_t *queue_left = own_packet ? NULL : &bat_priv->batman_queue_left;
553
554 if (atomic_read(&bat_priv->aggregated_ogms))
555 skb_size = max_t(unsigned int, BATADV_MAX_AGGREGATION_BYTES,
556 packet_len);
557 else
558 skb_size = packet_len;
559
560 skb_size += ETH_HLEN;
561
562 skb = netdev_alloc_skb_ip_align(NULL, skb_size);
563 if (!skb)
564 return;
565
566 forw_packet_aggr = batadv_forw_packet_alloc(if_incoming, if_outgoing,
567 queue_left, bat_priv, skb);
568 if (!forw_packet_aggr) {
569 kfree_skb(skb);
570 return;
571 }
572
573 forw_packet_aggr->skb->priority = TC_PRIO_CONTROL;
574 skb_reserve(forw_packet_aggr->skb, ETH_HLEN);
575
576 skb_buff = skb_put(forw_packet_aggr->skb, packet_len);
577 forw_packet_aggr->packet_len = packet_len;
578 memcpy(skb_buff, packet_buff, packet_len);
579
580 forw_packet_aggr->own = own_packet;
581 bitmap_zero(forw_packet_aggr->direct_link_flags,
582 BATADV_MAX_AGGREGATION_PACKETS);
583 forw_packet_aggr->send_time = send_time;
584
585 /* save packet direct link flag status */
586 if (direct_link)
587 set_bit(0, forw_packet_aggr->direct_link_flags);
588
589 INIT_DELAYED_WORK(&forw_packet_aggr->delayed_work,
590 batadv_iv_send_outstanding_bat_ogm_packet);
591
592 batadv_forw_packet_ogmv1_queue(bat_priv, forw_packet_aggr, send_time);
593 }
594
595 /* aggregate a new packet into the existing ogm packet */
batadv_iv_ogm_aggregate(struct batadv_forw_packet * forw_packet_aggr,const unsigned char * packet_buff,int packet_len,bool direct_link)596 static void batadv_iv_ogm_aggregate(struct batadv_forw_packet *forw_packet_aggr,
597 const unsigned char *packet_buff,
598 int packet_len, bool direct_link)
599 {
600 skb_put_data(forw_packet_aggr->skb, packet_buff, packet_len);
601 forw_packet_aggr->packet_len += packet_len;
602
603 /* save packet direct link flag status */
604 if (direct_link)
605 set_bit(forw_packet_aggr->num_packets,
606 forw_packet_aggr->direct_link_flags);
607
608 forw_packet_aggr->num_packets++;
609 }
610
611 /**
612 * batadv_iv_ogm_queue_add() - queue up an OGM for transmission
613 * @bat_priv: the bat priv with all the mesh interface information
614 * @packet_buff: pointer to the OGM
615 * @packet_len: (total) length of the OGM
616 * @if_incoming: interface where the packet was received
617 * @if_outgoing: interface for which the retransmission should be considered
618 * @own_packet: true if it is a self-generated ogm
619 * @send_time: timestamp (jiffies) when the packet is to be sent
620 */
batadv_iv_ogm_queue_add(struct batadv_priv * bat_priv,unsigned char * packet_buff,int packet_len,struct batadv_hard_iface * if_incoming,struct batadv_hard_iface * if_outgoing,int own_packet,unsigned long send_time)621 static void batadv_iv_ogm_queue_add(struct batadv_priv *bat_priv,
622 unsigned char *packet_buff,
623 int packet_len,
624 struct batadv_hard_iface *if_incoming,
625 struct batadv_hard_iface *if_outgoing,
626 int own_packet, unsigned long send_time)
627 {
628 /* _aggr -> pointer to the packet we want to aggregate with
629 * _pos -> pointer to the position in the queue
630 */
631 struct batadv_forw_packet *forw_packet_aggr = NULL;
632 struct batadv_forw_packet *forw_packet_pos = NULL;
633 struct batadv_ogm_packet *batadv_ogm_packet;
634 bool direct_link;
635 unsigned long max_aggregation_jiffies;
636
637 batadv_ogm_packet = (struct batadv_ogm_packet *)packet_buff;
638 direct_link = !!(batadv_ogm_packet->flags & BATADV_DIRECTLINK);
639 max_aggregation_jiffies = msecs_to_jiffies(BATADV_MAX_AGGREGATION_MS);
640
641 /* find position for the packet in the forward queue */
642 spin_lock_bh(&bat_priv->forw_bat_list_lock);
643 /* own packets are not to be aggregated */
644 if (atomic_read(&bat_priv->aggregated_ogms) && !own_packet) {
645 hlist_for_each_entry(forw_packet_pos,
646 &bat_priv->forw_bat_list, list) {
647 if (batadv_iv_ogm_can_aggregate(batadv_ogm_packet,
648 bat_priv, packet_len,
649 send_time, direct_link,
650 if_incoming,
651 if_outgoing,
652 forw_packet_pos)) {
653 forw_packet_aggr = forw_packet_pos;
654 break;
655 }
656 }
657 }
658
659 /* nothing to aggregate with - either aggregation disabled or no
660 * suitable aggregation packet found
661 */
662 if (!forw_packet_aggr) {
663 /* the following section can run without the lock */
664 spin_unlock_bh(&bat_priv->forw_bat_list_lock);
665
666 /* if we could not aggregate this packet with one of the others
667 * we hold it back for a while, so that it might be aggregated
668 * later on
669 */
670 if (!own_packet && atomic_read(&bat_priv->aggregated_ogms))
671 send_time += max_aggregation_jiffies;
672
673 batadv_iv_ogm_aggregate_new(packet_buff, packet_len,
674 send_time, direct_link,
675 if_incoming, if_outgoing,
676 own_packet);
677 } else {
678 batadv_iv_ogm_aggregate(forw_packet_aggr, packet_buff,
679 packet_len, direct_link);
680 spin_unlock_bh(&bat_priv->forw_bat_list_lock);
681 }
682 }
683
batadv_iv_ogm_forward(struct batadv_orig_node * orig_node,const struct ethhdr * ethhdr,struct batadv_ogm_packet * batadv_ogm_packet,bool is_single_hop_neigh,bool is_from_best_next_hop,struct batadv_hard_iface * if_incoming,struct batadv_hard_iface * if_outgoing)684 static void batadv_iv_ogm_forward(struct batadv_orig_node *orig_node,
685 const struct ethhdr *ethhdr,
686 struct batadv_ogm_packet *batadv_ogm_packet,
687 bool is_single_hop_neigh,
688 bool is_from_best_next_hop,
689 struct batadv_hard_iface *if_incoming,
690 struct batadv_hard_iface *if_outgoing)
691 {
692 struct batadv_priv *bat_priv = netdev_priv(if_incoming->mesh_iface);
693 u16 tvlv_len;
694
695 if (batadv_ogm_packet->ttl <= 1) {
696 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, "ttl exceeded\n");
697 return;
698 }
699
700 if (!is_from_best_next_hop) {
701 /* Mark the forwarded packet when it is not coming from our
702 * best next hop. We still need to forward the packet for our
703 * neighbor link quality detection to work in case the packet
704 * originated from a single hop neighbor. Otherwise we can
705 * simply drop the ogm.
706 */
707 if (is_single_hop_neigh)
708 batadv_ogm_packet->flags |= BATADV_NOT_BEST_NEXT_HOP;
709 else
710 return;
711 }
712
713 tvlv_len = ntohs(batadv_ogm_packet->tvlv_len);
714
715 batadv_ogm_packet->ttl--;
716 ether_addr_copy(batadv_ogm_packet->prev_sender, ethhdr->h_source);
717
718 /* apply hop penalty */
719 batadv_ogm_packet->tq = batadv_hop_penalty(batadv_ogm_packet->tq,
720 bat_priv);
721
722 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
723 "Forwarding packet: tq: %i, ttl: %i\n",
724 batadv_ogm_packet->tq, batadv_ogm_packet->ttl);
725
726 if (is_single_hop_neigh)
727 batadv_ogm_packet->flags |= BATADV_DIRECTLINK;
728 else
729 batadv_ogm_packet->flags &= ~BATADV_DIRECTLINK;
730
731 batadv_iv_ogm_queue_add(bat_priv, (unsigned char *)batadv_ogm_packet,
732 BATADV_OGM_HLEN + tvlv_len,
733 if_incoming, if_outgoing, 0,
734 batadv_iv_ogm_fwd_send_time());
735 }
736
737 /**
738 * batadv_iv_ogm_slide_own_bcast_window() - bitshift own OGM broadcast windows
739 * for the given interface
740 * @hard_iface: the interface for which the windows have to be shifted
741 */
742 static void
batadv_iv_ogm_slide_own_bcast_window(struct batadv_hard_iface * hard_iface)743 batadv_iv_ogm_slide_own_bcast_window(struct batadv_hard_iface *hard_iface)
744 {
745 struct batadv_priv *bat_priv = netdev_priv(hard_iface->mesh_iface);
746 struct batadv_hashtable *hash = bat_priv->orig_hash;
747 struct hlist_head *head;
748 struct batadv_orig_node *orig_node;
749 struct batadv_orig_ifinfo *orig_ifinfo;
750 unsigned long *word;
751 u32 i;
752 u8 *w;
753
754 for (i = 0; i < hash->size; i++) {
755 head = &hash->table[i];
756
757 rcu_read_lock();
758 hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
759 hlist_for_each_entry_rcu(orig_ifinfo,
760 &orig_node->ifinfo_list,
761 list) {
762 if (orig_ifinfo->if_outgoing != hard_iface)
763 continue;
764
765 spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock);
766 word = orig_ifinfo->bat_iv.bcast_own;
767 batadv_bit_get_packet(bat_priv, word, 1, 0);
768 w = &orig_ifinfo->bat_iv.bcast_own_sum;
769 *w = bitmap_weight(word,
770 BATADV_TQ_LOCAL_WINDOW_SIZE);
771 spin_unlock_bh(&orig_node->bat_iv.ogm_cnt_lock);
772 }
773 }
774 rcu_read_unlock();
775 }
776 }
777
778 /**
779 * batadv_iv_ogm_schedule_buff() - schedule submission of hardif ogm buffer
780 * @hard_iface: interface whose ogm buffer should be transmitted
781 */
batadv_iv_ogm_schedule_buff(struct batadv_hard_iface * hard_iface)782 static void batadv_iv_ogm_schedule_buff(struct batadv_hard_iface *hard_iface)
783 {
784 struct batadv_priv *bat_priv = netdev_priv(hard_iface->mesh_iface);
785 unsigned char **ogm_buff = &hard_iface->bat_iv.ogm_buff;
786 struct batadv_ogm_packet *batadv_ogm_packet;
787 struct batadv_hard_iface *primary_if, *tmp_hard_iface;
788 int *ogm_buff_len = &hard_iface->bat_iv.ogm_buff_len;
789 struct list_head *iter;
790 u32 seqno;
791 u16 tvlv_len = 0;
792 unsigned long send_time;
793
794 lockdep_assert_held(&hard_iface->bat_iv.ogm_buff_mutex);
795
796 /* interface already disabled by batadv_iv_ogm_iface_disable */
797 if (!*ogm_buff)
798 return;
799
800 /* the interface gets activated here to avoid race conditions between
801 * the moment of activating the interface in
802 * hardif_activate_interface() where the originator mac is set and
803 * outdated packets (especially uninitialized mac addresses) in the
804 * packet queue
805 */
806 if (hard_iface->if_status == BATADV_IF_TO_BE_ACTIVATED)
807 hard_iface->if_status = BATADV_IF_ACTIVE;
808
809 primary_if = batadv_primary_if_get_selected(bat_priv);
810
811 if (hard_iface == primary_if) {
812 /* tt changes have to be committed before the tvlv data is
813 * appended as it may alter the tt tvlv container
814 */
815 batadv_tt_local_commit_changes(bat_priv);
816 tvlv_len = batadv_tvlv_container_ogm_append(bat_priv, ogm_buff,
817 ogm_buff_len,
818 BATADV_OGM_HLEN);
819 }
820
821 batadv_ogm_packet = (struct batadv_ogm_packet *)(*ogm_buff);
822 batadv_ogm_packet->tvlv_len = htons(tvlv_len);
823
824 /* change sequence number to network order */
825 seqno = (u32)atomic_read(&hard_iface->bat_iv.ogm_seqno);
826 batadv_ogm_packet->seqno = htonl(seqno);
827 atomic_inc(&hard_iface->bat_iv.ogm_seqno);
828
829 batadv_iv_ogm_slide_own_bcast_window(hard_iface);
830
831 send_time = batadv_iv_ogm_emit_send_time(bat_priv);
832
833 if (hard_iface != primary_if) {
834 /* OGMs from secondary interfaces are only scheduled on their
835 * respective interfaces.
836 */
837 batadv_iv_ogm_queue_add(bat_priv, *ogm_buff, *ogm_buff_len,
838 hard_iface, hard_iface, 1, send_time);
839 goto out;
840 }
841
842 /* OGMs from primary interfaces are scheduled on all
843 * interfaces.
844 */
845 rcu_read_lock();
846 netdev_for_each_lower_private_rcu(hard_iface->mesh_iface, tmp_hard_iface, iter) {
847 if (!kref_get_unless_zero(&tmp_hard_iface->refcount))
848 continue;
849
850 batadv_iv_ogm_queue_add(bat_priv, *ogm_buff,
851 *ogm_buff_len, hard_iface,
852 tmp_hard_iface, 1, send_time);
853
854 batadv_hardif_put(tmp_hard_iface);
855 }
856 rcu_read_unlock();
857
858 out:
859 batadv_hardif_put(primary_if);
860 }
861
batadv_iv_ogm_schedule(struct batadv_hard_iface * hard_iface)862 static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
863 {
864 if (hard_iface->if_status == BATADV_IF_NOT_IN_USE ||
865 hard_iface->if_status == BATADV_IF_TO_BE_REMOVED)
866 return;
867
868 mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex);
869 batadv_iv_ogm_schedule_buff(hard_iface);
870 mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
871 }
872
873 /**
874 * batadv_iv_orig_ifinfo_sum() - Get bcast_own sum for originator over interface
875 * @orig_node: originator which reproadcasted the OGMs directly
876 * @if_outgoing: interface which transmitted the original OGM and received the
877 * direct rebroadcast
878 *
879 * Return: Number of replied (rebroadcasted) OGMs which were transmitted by
880 * an originator and directly (without intermediate hop) received by a specific
881 * interface
882 */
batadv_iv_orig_ifinfo_sum(struct batadv_orig_node * orig_node,struct batadv_hard_iface * if_outgoing)883 static u8 batadv_iv_orig_ifinfo_sum(struct batadv_orig_node *orig_node,
884 struct batadv_hard_iface *if_outgoing)
885 {
886 struct batadv_orig_ifinfo *orig_ifinfo;
887 u8 sum;
888
889 orig_ifinfo = batadv_orig_ifinfo_get(orig_node, if_outgoing);
890 if (!orig_ifinfo)
891 return 0;
892
893 spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock);
894 sum = orig_ifinfo->bat_iv.bcast_own_sum;
895 spin_unlock_bh(&orig_node->bat_iv.ogm_cnt_lock);
896
897 batadv_orig_ifinfo_put(orig_ifinfo);
898
899 return sum;
900 }
901
902 /**
903 * batadv_iv_ogm_neigh_ifinfo_sum() - Get bcast_own sum for a last-hop neighbor
904 * @bat_priv: the bat priv with all the mesh interface information
905 * @neigh_node: last-hop neighbor of an originator
906 *
907 * Return: Number of replied (rebroadcasted) OGMs for the originator currently
908 * announced by the neighbor. Returns 0 if the neighbor's originator entry is
909 * not available anymore.
910 */
batadv_iv_ogm_neigh_ifinfo_sum(struct batadv_priv * bat_priv,const struct batadv_neigh_node * neigh_node)911 static u8 batadv_iv_ogm_neigh_ifinfo_sum(struct batadv_priv *bat_priv,
912 const struct batadv_neigh_node *neigh_node)
913 {
914 struct batadv_orig_node *orig_neigh;
915 u8 sum;
916
917 orig_neigh = batadv_orig_hash_find(bat_priv, neigh_node->addr);
918 if (!orig_neigh)
919 return 0;
920
921 sum = batadv_iv_orig_ifinfo_sum(orig_neigh, neigh_node->if_incoming);
922 batadv_orig_node_put(orig_neigh);
923
924 return sum;
925 }
926
927 /**
928 * batadv_iv_ogm_orig_update() - use OGM to update corresponding data in an
929 * originator
930 * @bat_priv: the bat priv with all the mesh interface information
931 * @orig_node: the orig node who originally emitted the ogm packet
932 * @orig_ifinfo: ifinfo for the outgoing interface of the orig_node
933 * @ethhdr: Ethernet header of the OGM
934 * @batadv_ogm_packet: the ogm packet
935 * @if_incoming: interface where the packet was received
936 * @if_outgoing: interface for which the retransmission should be considered
937 * @dup_status: the duplicate status of this ogm packet.
938 */
939 static void
batadv_iv_ogm_orig_update(struct batadv_priv * bat_priv,struct batadv_orig_node * orig_node,struct batadv_orig_ifinfo * orig_ifinfo,const struct ethhdr * ethhdr,const struct batadv_ogm_packet * batadv_ogm_packet,struct batadv_hard_iface * if_incoming,struct batadv_hard_iface * if_outgoing,enum batadv_dup_status dup_status)940 batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv,
941 struct batadv_orig_node *orig_node,
942 struct batadv_orig_ifinfo *orig_ifinfo,
943 const struct ethhdr *ethhdr,
944 const struct batadv_ogm_packet *batadv_ogm_packet,
945 struct batadv_hard_iface *if_incoming,
946 struct batadv_hard_iface *if_outgoing,
947 enum batadv_dup_status dup_status)
948 {
949 struct batadv_neigh_ifinfo *neigh_ifinfo = NULL;
950 struct batadv_neigh_ifinfo *router_ifinfo = NULL;
951 struct batadv_neigh_node *neigh_node = NULL;
952 struct batadv_neigh_node *tmp_neigh_node = NULL;
953 struct batadv_neigh_node *router = NULL;
954 u8 sum_orig, sum_neigh;
955 u8 *neigh_addr;
956 u8 tq_avg;
957
958 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
959 "%s(): Searching and updating originator entry of received packet\n",
960 __func__);
961
962 rcu_read_lock();
963 hlist_for_each_entry_rcu(tmp_neigh_node,
964 &orig_node->neigh_list, list) {
965 neigh_addr = tmp_neigh_node->addr;
966 if (batadv_compare_eth(neigh_addr, ethhdr->h_source) &&
967 tmp_neigh_node->if_incoming == if_incoming &&
968 kref_get_unless_zero(&tmp_neigh_node->refcount)) {
969 if (WARN(neigh_node, "too many matching neigh_nodes"))
970 batadv_neigh_node_put(neigh_node);
971 neigh_node = tmp_neigh_node;
972 continue;
973 }
974
975 if (dup_status != BATADV_NO_DUP)
976 continue;
977
978 /* only update the entry for this outgoing interface */
979 neigh_ifinfo = batadv_neigh_ifinfo_get(tmp_neigh_node,
980 if_outgoing);
981 if (!neigh_ifinfo)
982 continue;
983
984 spin_lock_bh(&tmp_neigh_node->ifinfo_lock);
985 batadv_ring_buffer_set(neigh_ifinfo->bat_iv.tq_recv,
986 &neigh_ifinfo->bat_iv.tq_index, 0);
987 tq_avg = batadv_ring_buffer_avg(neigh_ifinfo->bat_iv.tq_recv);
988 neigh_ifinfo->bat_iv.tq_avg = tq_avg;
989 spin_unlock_bh(&tmp_neigh_node->ifinfo_lock);
990
991 batadv_neigh_ifinfo_put(neigh_ifinfo);
992 neigh_ifinfo = NULL;
993 }
994
995 if (!neigh_node) {
996 neigh_node = batadv_iv_ogm_neigh_new(if_incoming,
997 ethhdr->h_source,
998 orig_node);
999 if (!neigh_node)
1000 goto unlock;
1001 } else {
1002 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1003 "Updating existing last-hop neighbor of originator\n");
1004 }
1005
1006 rcu_read_unlock();
1007 neigh_ifinfo = batadv_neigh_ifinfo_new(neigh_node, if_outgoing);
1008 if (!neigh_ifinfo)
1009 goto out;
1010
1011 neigh_node->last_seen = jiffies;
1012
1013 spin_lock_bh(&neigh_node->ifinfo_lock);
1014 batadv_ring_buffer_set(neigh_ifinfo->bat_iv.tq_recv,
1015 &neigh_ifinfo->bat_iv.tq_index,
1016 batadv_ogm_packet->tq);
1017 tq_avg = batadv_ring_buffer_avg(neigh_ifinfo->bat_iv.tq_recv);
1018 neigh_ifinfo->bat_iv.tq_avg = tq_avg;
1019 spin_unlock_bh(&neigh_node->ifinfo_lock);
1020
1021 if (dup_status == BATADV_NO_DUP) {
1022 orig_ifinfo->last_ttl = batadv_ogm_packet->ttl;
1023 neigh_ifinfo->last_ttl = batadv_ogm_packet->ttl;
1024 }
1025
1026 /* if this neighbor already is our next hop there is nothing
1027 * to change
1028 */
1029 router = batadv_orig_router_get(orig_node, if_outgoing);
1030 if (router == neigh_node)
1031 goto out;
1032
1033 if (router) {
1034 router_ifinfo = batadv_neigh_ifinfo_get(router, if_outgoing);
1035 if (!router_ifinfo)
1036 goto out;
1037
1038 /* if this neighbor does not offer a better TQ we won't
1039 * consider it
1040 */
1041 if (router_ifinfo->bat_iv.tq_avg > neigh_ifinfo->bat_iv.tq_avg)
1042 goto out;
1043 }
1044
1045 /* if the TQ is the same and the link not more symmetric we
1046 * won't consider it either
1047 */
1048 if (router_ifinfo &&
1049 neigh_ifinfo->bat_iv.tq_avg == router_ifinfo->bat_iv.tq_avg) {
1050 sum_orig = batadv_iv_ogm_neigh_ifinfo_sum(bat_priv, router);
1051 sum_neigh = batadv_iv_ogm_neigh_ifinfo_sum(bat_priv,
1052 neigh_node);
1053 if (sum_orig >= sum_neigh)
1054 goto out;
1055 }
1056
1057 batadv_update_route(bat_priv, orig_node, if_outgoing, neigh_node);
1058 goto out;
1059
1060 unlock:
1061 rcu_read_unlock();
1062 out:
1063 batadv_neigh_node_put(neigh_node);
1064 batadv_neigh_node_put(router);
1065 batadv_neigh_ifinfo_put(neigh_ifinfo);
1066 batadv_neigh_ifinfo_put(router_ifinfo);
1067 }
1068
1069 /**
1070 * batadv_iv_ogm_calc_tq() - calculate tq for current received ogm packet
1071 * @orig_node: the orig node who originally emitted the ogm packet
1072 * @orig_neigh_node: the orig node struct of the neighbor who sent the packet
1073 * @batadv_ogm_packet: the ogm packet
1074 * @if_incoming: interface where the packet was received
1075 * @if_outgoing: interface for which the retransmission should be considered
1076 *
1077 * Return: true if the link can be considered bidirectional, false otherwise
1078 */
batadv_iv_ogm_calc_tq(struct batadv_orig_node * orig_node,struct batadv_orig_node * orig_neigh_node,struct batadv_ogm_packet * batadv_ogm_packet,struct batadv_hard_iface * if_incoming,struct batadv_hard_iface * if_outgoing)1079 static bool batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node,
1080 struct batadv_orig_node *orig_neigh_node,
1081 struct batadv_ogm_packet *batadv_ogm_packet,
1082 struct batadv_hard_iface *if_incoming,
1083 struct batadv_hard_iface *if_outgoing)
1084 {
1085 struct batadv_priv *bat_priv = netdev_priv(if_incoming->mesh_iface);
1086 struct batadv_neigh_node *neigh_node = NULL, *tmp_neigh_node;
1087 struct batadv_neigh_ifinfo *neigh_ifinfo;
1088 u8 total_count;
1089 u8 orig_eq_count, neigh_rq_count, neigh_rq_inv, tq_own;
1090 unsigned int tq_iface_hop_penalty = BATADV_TQ_MAX_VALUE;
1091 unsigned int neigh_rq_inv_cube, neigh_rq_max_cube;
1092 unsigned int tq_asym_penalty, inv_asym_penalty;
1093 unsigned int combined_tq;
1094 bool ret = false;
1095
1096 /* find corresponding one hop neighbor */
1097 rcu_read_lock();
1098 hlist_for_each_entry_rcu(tmp_neigh_node,
1099 &orig_neigh_node->neigh_list, list) {
1100 if (!batadv_compare_eth(tmp_neigh_node->addr,
1101 orig_neigh_node->orig))
1102 continue;
1103
1104 if (tmp_neigh_node->if_incoming != if_incoming)
1105 continue;
1106
1107 if (!kref_get_unless_zero(&tmp_neigh_node->refcount))
1108 continue;
1109
1110 neigh_node = tmp_neigh_node;
1111 break;
1112 }
1113 rcu_read_unlock();
1114
1115 if (!neigh_node)
1116 neigh_node = batadv_iv_ogm_neigh_new(if_incoming,
1117 orig_neigh_node->orig,
1118 orig_neigh_node);
1119
1120 if (!neigh_node)
1121 goto out;
1122
1123 /* if orig_node is direct neighbor update neigh_node last_seen */
1124 if (orig_node == orig_neigh_node)
1125 neigh_node->last_seen = jiffies;
1126
1127 orig_node->last_seen = jiffies;
1128
1129 /* find packet count of corresponding one hop neighbor */
1130 orig_eq_count = batadv_iv_orig_ifinfo_sum(orig_neigh_node, if_incoming);
1131 neigh_ifinfo = batadv_neigh_ifinfo_new(neigh_node, if_outgoing);
1132 if (neigh_ifinfo) {
1133 neigh_rq_count = neigh_ifinfo->bat_iv.real_packet_count;
1134 batadv_neigh_ifinfo_put(neigh_ifinfo);
1135 } else {
1136 neigh_rq_count = 0;
1137 }
1138
1139 /* pay attention to not get a value bigger than 100 % */
1140 if (orig_eq_count > neigh_rq_count)
1141 total_count = neigh_rq_count;
1142 else
1143 total_count = orig_eq_count;
1144
1145 /* if we have too few packets (too less data) we set tq_own to zero
1146 * if we receive too few packets it is not considered bidirectional
1147 */
1148 if (total_count < BATADV_TQ_LOCAL_BIDRECT_SEND_MINIMUM ||
1149 neigh_rq_count < BATADV_TQ_LOCAL_BIDRECT_RECV_MINIMUM)
1150 tq_own = 0;
1151 else
1152 /* neigh_node->real_packet_count is never zero as we
1153 * only purge old information when getting new
1154 * information
1155 */
1156 tq_own = (BATADV_TQ_MAX_VALUE * total_count) / neigh_rq_count;
1157
1158 /* 1 - ((1-x) ** 3), normalized to TQ_MAX_VALUE this does
1159 * affect the nearly-symmetric links only a little, but
1160 * punishes asymmetric links more. This will give a value
1161 * between 0 and TQ_MAX_VALUE
1162 */
1163 neigh_rq_inv = BATADV_TQ_LOCAL_WINDOW_SIZE - neigh_rq_count;
1164 neigh_rq_inv_cube = neigh_rq_inv * neigh_rq_inv * neigh_rq_inv;
1165 neigh_rq_max_cube = BATADV_TQ_LOCAL_WINDOW_SIZE *
1166 BATADV_TQ_LOCAL_WINDOW_SIZE *
1167 BATADV_TQ_LOCAL_WINDOW_SIZE;
1168 inv_asym_penalty = BATADV_TQ_MAX_VALUE * neigh_rq_inv_cube;
1169 inv_asym_penalty /= neigh_rq_max_cube;
1170 tq_asym_penalty = BATADV_TQ_MAX_VALUE - inv_asym_penalty;
1171 tq_iface_hop_penalty -= atomic_read(&if_incoming->hop_penalty);
1172
1173 /* penalize if the OGM is forwarded on the same interface. WiFi
1174 * interfaces and other half duplex devices suffer from throughput
1175 * drops as they can't send and receive at the same time.
1176 */
1177 if (if_outgoing && if_incoming == if_outgoing &&
1178 batadv_is_wifi_hardif(if_outgoing))
1179 tq_iface_hop_penalty = batadv_hop_penalty(tq_iface_hop_penalty,
1180 bat_priv);
1181
1182 combined_tq = batadv_ogm_packet->tq *
1183 tq_own *
1184 tq_asym_penalty *
1185 tq_iface_hop_penalty;
1186 combined_tq /= BATADV_TQ_MAX_VALUE *
1187 BATADV_TQ_MAX_VALUE *
1188 BATADV_TQ_MAX_VALUE;
1189 batadv_ogm_packet->tq = combined_tq;
1190
1191 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1192 "bidirectional: orig = %pM neigh = %pM => own_bcast = %2i, real recv = %2i, local tq: %3i, asym_penalty: %3i, iface_hop_penalty: %3i, total tq: %3i, if_incoming = %s, if_outgoing = %s\n",
1193 orig_node->orig, orig_neigh_node->orig, total_count,
1194 neigh_rq_count, tq_own, tq_asym_penalty,
1195 tq_iface_hop_penalty, batadv_ogm_packet->tq,
1196 if_incoming->net_dev->name,
1197 if_outgoing ? if_outgoing->net_dev->name : "DEFAULT");
1198
1199 /* if link has the minimum required transmission quality
1200 * consider it bidirectional
1201 */
1202 if (batadv_ogm_packet->tq >= BATADV_TQ_TOTAL_BIDRECT_LIMIT)
1203 ret = true;
1204
1205 out:
1206 batadv_neigh_node_put(neigh_node);
1207 return ret;
1208 }
1209
1210 /**
1211 * batadv_iv_ogm_update_seqnos() - process a batman packet for all interfaces,
1212 * adjust the sequence number and find out whether it is a duplicate
1213 * @ethhdr: ethernet header of the packet
1214 * @batadv_ogm_packet: OGM packet to be considered
1215 * @if_incoming: interface on which the OGM packet was received
1216 * @if_outgoing: interface for which the retransmission should be considered
1217 *
1218 * Return: duplicate status as enum batadv_dup_status
1219 */
1220 static enum batadv_dup_status
batadv_iv_ogm_update_seqnos(const struct ethhdr * ethhdr,const struct batadv_ogm_packet * batadv_ogm_packet,const struct batadv_hard_iface * if_incoming,struct batadv_hard_iface * if_outgoing)1221 batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr,
1222 const struct batadv_ogm_packet *batadv_ogm_packet,
1223 const struct batadv_hard_iface *if_incoming,
1224 struct batadv_hard_iface *if_outgoing)
1225 {
1226 struct batadv_priv *bat_priv = netdev_priv(if_incoming->mesh_iface);
1227 struct batadv_orig_node *orig_node;
1228 struct batadv_orig_ifinfo *orig_ifinfo = NULL;
1229 struct batadv_neigh_node *neigh_node;
1230 struct batadv_neigh_ifinfo *neigh_ifinfo;
1231 bool is_dup;
1232 s32 seq_diff;
1233 bool need_update = false;
1234 int set_mark;
1235 enum batadv_dup_status ret = BATADV_NO_DUP;
1236 u32 seqno = ntohl(batadv_ogm_packet->seqno);
1237 u8 *neigh_addr;
1238 u8 packet_count;
1239 unsigned long *bitmap;
1240
1241 orig_node = batadv_iv_ogm_orig_get(bat_priv, batadv_ogm_packet->orig);
1242 if (!orig_node)
1243 return BATADV_NO_DUP;
1244
1245 orig_ifinfo = batadv_orig_ifinfo_new(orig_node, if_outgoing);
1246 if (WARN_ON(!orig_ifinfo)) {
1247 batadv_orig_node_put(orig_node);
1248 return 0;
1249 }
1250
1251 spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock);
1252 seq_diff = seqno - orig_ifinfo->last_real_seqno;
1253
1254 /* signalize caller that the packet is to be dropped. */
1255 if (!hlist_empty(&orig_node->neigh_list) &&
1256 batadv_window_protected(bat_priv, seq_diff,
1257 BATADV_TQ_LOCAL_WINDOW_SIZE,
1258 &orig_ifinfo->batman_seqno_reset, NULL)) {
1259 ret = BATADV_PROTECTED;
1260 goto out;
1261 }
1262
1263 rcu_read_lock();
1264 hlist_for_each_entry_rcu(neigh_node, &orig_node->neigh_list, list) {
1265 neigh_ifinfo = batadv_neigh_ifinfo_new(neigh_node,
1266 if_outgoing);
1267 if (!neigh_ifinfo)
1268 continue;
1269
1270 neigh_addr = neigh_node->addr;
1271 is_dup = batadv_test_bit(neigh_ifinfo->bat_iv.real_bits,
1272 orig_ifinfo->last_real_seqno,
1273 seqno);
1274
1275 if (batadv_compare_eth(neigh_addr, ethhdr->h_source) &&
1276 neigh_node->if_incoming == if_incoming) {
1277 set_mark = 1;
1278 if (is_dup)
1279 ret = BATADV_NEIGH_DUP;
1280 } else {
1281 set_mark = 0;
1282 if (is_dup && ret != BATADV_NEIGH_DUP)
1283 ret = BATADV_ORIG_DUP;
1284 }
1285
1286 /* if the window moved, set the update flag. */
1287 bitmap = neigh_ifinfo->bat_iv.real_bits;
1288 need_update |= batadv_bit_get_packet(bat_priv, bitmap,
1289 seq_diff, set_mark);
1290
1291 packet_count = bitmap_weight(bitmap,
1292 BATADV_TQ_LOCAL_WINDOW_SIZE);
1293 neigh_ifinfo->bat_iv.real_packet_count = packet_count;
1294 batadv_neigh_ifinfo_put(neigh_ifinfo);
1295 }
1296 rcu_read_unlock();
1297
1298 if (need_update) {
1299 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1300 "%s updating last_seqno: old %u, new %u\n",
1301 if_outgoing ? if_outgoing->net_dev->name : "DEFAULT",
1302 orig_ifinfo->last_real_seqno, seqno);
1303 orig_ifinfo->last_real_seqno = seqno;
1304 }
1305
1306 out:
1307 spin_unlock_bh(&orig_node->bat_iv.ogm_cnt_lock);
1308 batadv_orig_node_put(orig_node);
1309 batadv_orig_ifinfo_put(orig_ifinfo);
1310 return ret;
1311 }
1312
1313 /**
1314 * batadv_orig_to_direct_router() - get direct next hop neighbor to an orig address
1315 * @bat_priv: the bat priv with all the mesh interface information
1316 * @orig_addr: the originator MAC address to search the best next hop router for
1317 * @if_outgoing: the interface where the OGM should be sent to
1318 *
1319 * Return: A neighbor node which is the best router towards the given originator
1320 * address. Bonding candidates are ignored.
1321 */
1322 static struct batadv_neigh_node *
batadv_orig_to_direct_router(struct batadv_priv * bat_priv,u8 * orig_addr,struct batadv_hard_iface * if_outgoing)1323 batadv_orig_to_direct_router(struct batadv_priv *bat_priv, u8 *orig_addr,
1324 struct batadv_hard_iface *if_outgoing)
1325 {
1326 struct batadv_neigh_node *neigh_node;
1327 struct batadv_orig_node *orig_node;
1328
1329 orig_node = batadv_orig_hash_find(bat_priv, orig_addr);
1330 if (!orig_node)
1331 return NULL;
1332
1333 neigh_node = batadv_orig_router_get(orig_node, if_outgoing);
1334 batadv_orig_node_put(orig_node);
1335
1336 return neigh_node;
1337 }
1338
1339 /**
1340 * batadv_iv_ogm_process_per_outif() - process a batman iv OGM for an outgoing
1341 * interface
1342 * @skb: the skb containing the OGM
1343 * @ogm_offset: offset from skb->data to start of ogm header
1344 * @orig_node: the (cached) orig node for the originator of this OGM
1345 * @if_incoming: the interface where this packet was received
1346 * @if_outgoing: the interface for which the packet should be considered
1347 */
1348 static void
batadv_iv_ogm_process_per_outif(const struct sk_buff * skb,int ogm_offset,struct batadv_orig_node * orig_node,struct batadv_hard_iface * if_incoming,struct batadv_hard_iface * if_outgoing)1349 batadv_iv_ogm_process_per_outif(const struct sk_buff *skb, int ogm_offset,
1350 struct batadv_orig_node *orig_node,
1351 struct batadv_hard_iface *if_incoming,
1352 struct batadv_hard_iface *if_outgoing)
1353 {
1354 struct batadv_priv *bat_priv = netdev_priv(if_incoming->mesh_iface);
1355 struct batadv_hardif_neigh_node *hardif_neigh = NULL;
1356 struct batadv_neigh_node *router = NULL;
1357 struct batadv_neigh_node *router_router = NULL;
1358 struct batadv_orig_node *orig_neigh_node;
1359 struct batadv_orig_ifinfo *orig_ifinfo;
1360 struct batadv_neigh_node *orig_neigh_router = NULL;
1361 struct batadv_neigh_ifinfo *router_ifinfo = NULL;
1362 struct batadv_ogm_packet *ogm_packet;
1363 enum batadv_dup_status dup_status;
1364 bool is_from_best_next_hop = false;
1365 bool is_single_hop_neigh = false;
1366 bool sameseq, similar_ttl;
1367 struct sk_buff *skb_priv;
1368 struct ethhdr *ethhdr;
1369 u8 *prev_sender;
1370 bool is_bidirect;
1371
1372 /* create a private copy of the skb, as some functions change tq value
1373 * and/or flags.
1374 */
1375 skb_priv = skb_copy(skb, GFP_ATOMIC);
1376 if (!skb_priv)
1377 return;
1378
1379 ethhdr = eth_hdr(skb_priv);
1380 ogm_packet = (struct batadv_ogm_packet *)(skb_priv->data + ogm_offset);
1381
1382 dup_status = batadv_iv_ogm_update_seqnos(ethhdr, ogm_packet,
1383 if_incoming, if_outgoing);
1384 if (batadv_compare_eth(ethhdr->h_source, ogm_packet->orig))
1385 is_single_hop_neigh = true;
1386
1387 if (dup_status == BATADV_PROTECTED) {
1388 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1389 "Drop packet: packet within seqno protection time (sender: %pM)\n",
1390 ethhdr->h_source);
1391 goto out;
1392 }
1393
1394 if (ogm_packet->tq == 0) {
1395 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1396 "Drop packet: originator packet with tq equal 0\n");
1397 goto out;
1398 }
1399
1400 if (is_single_hop_neigh) {
1401 hardif_neigh = batadv_hardif_neigh_get(if_incoming,
1402 ethhdr->h_source);
1403 if (hardif_neigh)
1404 hardif_neigh->last_seen = jiffies;
1405 }
1406
1407 router = batadv_orig_router_get(orig_node, if_outgoing);
1408 if (router) {
1409 router_router = batadv_orig_to_direct_router(bat_priv,
1410 router->addr,
1411 if_outgoing);
1412 router_ifinfo = batadv_neigh_ifinfo_get(router, if_outgoing);
1413 }
1414
1415 if ((router_ifinfo && router_ifinfo->bat_iv.tq_avg != 0) &&
1416 (batadv_compare_eth(router->addr, ethhdr->h_source)))
1417 is_from_best_next_hop = true;
1418
1419 prev_sender = ogm_packet->prev_sender;
1420 /* avoid temporary routing loops */
1421 if (router && router_router &&
1422 (batadv_compare_eth(router->addr, prev_sender)) &&
1423 !(batadv_compare_eth(ogm_packet->orig, prev_sender)) &&
1424 (batadv_compare_eth(router->addr, router_router->addr))) {
1425 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1426 "Drop packet: ignoring all rebroadcast packets that may make me loop (sender: %pM)\n",
1427 ethhdr->h_source);
1428 goto out;
1429 }
1430
1431 if (if_outgoing == BATADV_IF_DEFAULT)
1432 batadv_tvlv_ogm_receive(bat_priv, ogm_packet, orig_node);
1433
1434 /* if sender is a direct neighbor the sender mac equals
1435 * originator mac
1436 */
1437 if (is_single_hop_neigh)
1438 orig_neigh_node = orig_node;
1439 else
1440 orig_neigh_node = batadv_iv_ogm_orig_get(bat_priv,
1441 ethhdr->h_source);
1442
1443 if (!orig_neigh_node)
1444 goto out;
1445
1446 orig_neigh_router = batadv_orig_router_get(orig_neigh_node,
1447 if_outgoing);
1448
1449 /* drop packet if sender is not a direct neighbor and if we
1450 * don't route towards it
1451 */
1452 if (!is_single_hop_neigh && !orig_neigh_router) {
1453 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1454 "Drop packet: OGM via unknown neighbor!\n");
1455 goto out_neigh;
1456 }
1457
1458 is_bidirect = batadv_iv_ogm_calc_tq(orig_node, orig_neigh_node,
1459 ogm_packet, if_incoming,
1460 if_outgoing);
1461
1462 /* update ranking if it is not a duplicate or has the same
1463 * seqno and similar ttl as the non-duplicate
1464 */
1465 orig_ifinfo = batadv_orig_ifinfo_new(orig_node, if_outgoing);
1466 if (!orig_ifinfo)
1467 goto out_neigh;
1468
1469 sameseq = orig_ifinfo->last_real_seqno == ntohl(ogm_packet->seqno);
1470 similar_ttl = (orig_ifinfo->last_ttl - 3) <= ogm_packet->ttl;
1471
1472 if (is_bidirect && (dup_status == BATADV_NO_DUP ||
1473 (sameseq && similar_ttl))) {
1474 batadv_iv_ogm_orig_update(bat_priv, orig_node,
1475 orig_ifinfo, ethhdr,
1476 ogm_packet, if_incoming,
1477 if_outgoing, dup_status);
1478 }
1479 batadv_orig_ifinfo_put(orig_ifinfo);
1480
1481 /* only forward for specific interface, not for the default one. */
1482 if (if_outgoing == BATADV_IF_DEFAULT)
1483 goto out_neigh;
1484
1485 /* is single hop (direct) neighbor */
1486 if (is_single_hop_neigh) {
1487 /* OGMs from secondary interfaces should only scheduled once
1488 * per interface where it has been received, not multiple times
1489 */
1490 if (ogm_packet->ttl <= 2 &&
1491 if_incoming != if_outgoing) {
1492 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1493 "Drop packet: OGM from secondary interface and wrong outgoing interface\n");
1494 goto out_neigh;
1495 }
1496 /* mark direct link on incoming interface */
1497 batadv_iv_ogm_forward(orig_node, ethhdr, ogm_packet,
1498 is_single_hop_neigh,
1499 is_from_best_next_hop, if_incoming,
1500 if_outgoing);
1501
1502 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1503 "Forwarding packet: rebroadcast neighbor packet with direct link flag\n");
1504 goto out_neigh;
1505 }
1506
1507 /* multihop originator */
1508 if (!is_bidirect) {
1509 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1510 "Drop packet: not received via bidirectional link\n");
1511 goto out_neigh;
1512 }
1513
1514 if (dup_status == BATADV_NEIGH_DUP) {
1515 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1516 "Drop packet: duplicate packet received\n");
1517 goto out_neigh;
1518 }
1519
1520 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1521 "Forwarding packet: rebroadcast originator packet\n");
1522 batadv_iv_ogm_forward(orig_node, ethhdr, ogm_packet,
1523 is_single_hop_neigh, is_from_best_next_hop,
1524 if_incoming, if_outgoing);
1525
1526 out_neigh:
1527 if (orig_neigh_node && !is_single_hop_neigh)
1528 batadv_orig_node_put(orig_neigh_node);
1529 out:
1530 batadv_neigh_ifinfo_put(router_ifinfo);
1531 batadv_neigh_node_put(router);
1532 batadv_neigh_node_put(router_router);
1533 batadv_neigh_node_put(orig_neigh_router);
1534 batadv_hardif_neigh_put(hardif_neigh);
1535
1536 consume_skb(skb_priv);
1537 }
1538
1539 /**
1540 * batadv_iv_ogm_process_reply() - Check OGM for direct reply and process it
1541 * @ogm_packet: rebroadcast OGM packet to process
1542 * @if_incoming: the interface where this packet was received
1543 * @orig_node: originator which reproadcasted the OGMs
1544 * @if_incoming_seqno: OGM sequence number when rebroadcast was received
1545 */
batadv_iv_ogm_process_reply(struct batadv_ogm_packet * ogm_packet,struct batadv_hard_iface * if_incoming,struct batadv_orig_node * orig_node,u32 if_incoming_seqno)1546 static void batadv_iv_ogm_process_reply(struct batadv_ogm_packet *ogm_packet,
1547 struct batadv_hard_iface *if_incoming,
1548 struct batadv_orig_node *orig_node,
1549 u32 if_incoming_seqno)
1550 {
1551 struct batadv_orig_ifinfo *orig_ifinfo;
1552 s32 bit_pos;
1553 u8 *weight;
1554
1555 /* neighbor has to indicate direct link and it has to
1556 * come via the corresponding interface
1557 */
1558 if (!(ogm_packet->flags & BATADV_DIRECTLINK))
1559 return;
1560
1561 if (!batadv_compare_eth(if_incoming->net_dev->dev_addr,
1562 ogm_packet->orig))
1563 return;
1564
1565 orig_ifinfo = batadv_orig_ifinfo_get(orig_node, if_incoming);
1566 if (!orig_ifinfo)
1567 return;
1568
1569 /* save packet seqno for bidirectional check */
1570 spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock);
1571 bit_pos = if_incoming_seqno - 2;
1572 bit_pos -= ntohl(ogm_packet->seqno);
1573 batadv_set_bit(orig_ifinfo->bat_iv.bcast_own, bit_pos);
1574 weight = &orig_ifinfo->bat_iv.bcast_own_sum;
1575 *weight = bitmap_weight(orig_ifinfo->bat_iv.bcast_own,
1576 BATADV_TQ_LOCAL_WINDOW_SIZE);
1577 spin_unlock_bh(&orig_node->bat_iv.ogm_cnt_lock);
1578
1579 batadv_orig_ifinfo_put(orig_ifinfo);
1580 }
1581
1582 /**
1583 * batadv_iv_ogm_process() - process an incoming batman iv OGM
1584 * @skb: the skb containing the OGM
1585 * @ogm_offset: offset to the OGM which should be processed (for aggregates)
1586 * @if_incoming: the interface where this packet was received
1587 */
batadv_iv_ogm_process(const struct sk_buff * skb,int ogm_offset,struct batadv_hard_iface * if_incoming)1588 static void batadv_iv_ogm_process(const struct sk_buff *skb, int ogm_offset,
1589 struct batadv_hard_iface *if_incoming)
1590 {
1591 struct batadv_priv *bat_priv = netdev_priv(if_incoming->mesh_iface);
1592 struct batadv_orig_node *orig_neigh_node, *orig_node;
1593 struct batadv_hard_iface *hard_iface;
1594 struct batadv_ogm_packet *ogm_packet;
1595 u32 if_incoming_seqno;
1596 bool has_directlink_flag;
1597 struct ethhdr *ethhdr;
1598 bool is_my_oldorig = false;
1599 bool is_my_addr = false;
1600 bool is_my_orig = false;
1601 struct list_head *iter;
1602
1603 ogm_packet = (struct batadv_ogm_packet *)(skb->data + ogm_offset);
1604 ethhdr = eth_hdr(skb);
1605
1606 /* Silently drop when the batman packet is actually not a
1607 * correct packet.
1608 *
1609 * This might happen if a packet is padded (e.g. Ethernet has a
1610 * minimum frame length of 64 byte) and the aggregation interprets
1611 * it as an additional length.
1612 *
1613 * TODO: A more sane solution would be to have a bit in the
1614 * batadv_ogm_packet to detect whether the packet is the last
1615 * packet in an aggregation. Here we expect that the padding
1616 * is always zero (or not 0x01)
1617 */
1618 if (ogm_packet->packet_type != BATADV_IV_OGM)
1619 return;
1620
1621 /* could be changed by schedule_own_packet() */
1622 if_incoming_seqno = atomic_read(&if_incoming->bat_iv.ogm_seqno);
1623
1624 if (ogm_packet->flags & BATADV_DIRECTLINK)
1625 has_directlink_flag = true;
1626 else
1627 has_directlink_flag = false;
1628
1629 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1630 "Received BATMAN packet via NB: %pM, IF: %s [%pM] (from OG: %pM, via prev OG: %pM, seqno %u, tq %d, TTL %d, V %d, IDF %d)\n",
1631 ethhdr->h_source, if_incoming->net_dev->name,
1632 if_incoming->net_dev->dev_addr, ogm_packet->orig,
1633 ogm_packet->prev_sender, ntohl(ogm_packet->seqno),
1634 ogm_packet->tq, ogm_packet->ttl,
1635 ogm_packet->version, has_directlink_flag);
1636
1637 rcu_read_lock();
1638
1639 netdev_for_each_lower_private_rcu(if_incoming->mesh_iface, hard_iface, iter) {
1640 if (hard_iface->if_status != BATADV_IF_ACTIVE)
1641 continue;
1642
1643 if (batadv_compare_eth(ethhdr->h_source,
1644 hard_iface->net_dev->dev_addr))
1645 is_my_addr = true;
1646
1647 if (batadv_compare_eth(ogm_packet->orig,
1648 hard_iface->net_dev->dev_addr))
1649 is_my_orig = true;
1650
1651 if (batadv_compare_eth(ogm_packet->prev_sender,
1652 hard_iface->net_dev->dev_addr))
1653 is_my_oldorig = true;
1654 }
1655 rcu_read_unlock();
1656
1657 if (is_my_addr) {
1658 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1659 "Drop packet: received my own broadcast (sender: %pM)\n",
1660 ethhdr->h_source);
1661 return;
1662 }
1663
1664 if (is_my_orig) {
1665 orig_neigh_node = batadv_iv_ogm_orig_get(bat_priv,
1666 ethhdr->h_source);
1667 if (!orig_neigh_node)
1668 return;
1669
1670 batadv_iv_ogm_process_reply(ogm_packet, if_incoming,
1671 orig_neigh_node, if_incoming_seqno);
1672
1673 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1674 "Drop packet: originator packet from myself (via neighbor)\n");
1675 batadv_orig_node_put(orig_neigh_node);
1676 return;
1677 }
1678
1679 if (is_my_oldorig) {
1680 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1681 "Drop packet: ignoring all rebroadcast echos (sender: %pM)\n",
1682 ethhdr->h_source);
1683 return;
1684 }
1685
1686 if (ogm_packet->flags & BATADV_NOT_BEST_NEXT_HOP) {
1687 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1688 "Drop packet: ignoring all packets not forwarded from the best next hop (sender: %pM)\n",
1689 ethhdr->h_source);
1690 return;
1691 }
1692
1693 orig_node = batadv_iv_ogm_orig_get(bat_priv, ogm_packet->orig);
1694 if (!orig_node)
1695 return;
1696
1697 batadv_iv_ogm_process_per_outif(skb, ogm_offset, orig_node,
1698 if_incoming, BATADV_IF_DEFAULT);
1699
1700 rcu_read_lock();
1701 netdev_for_each_lower_private_rcu(bat_priv->mesh_iface, hard_iface, iter) {
1702 if (hard_iface->if_status != BATADV_IF_ACTIVE)
1703 continue;
1704
1705 if (!kref_get_unless_zero(&hard_iface->refcount))
1706 continue;
1707
1708 batadv_iv_ogm_process_per_outif(skb, ogm_offset, orig_node,
1709 if_incoming, hard_iface);
1710
1711 batadv_hardif_put(hard_iface);
1712 }
1713 rcu_read_unlock();
1714
1715 batadv_orig_node_put(orig_node);
1716 }
1717
batadv_iv_send_outstanding_bat_ogm_packet(struct work_struct * work)1718 static void batadv_iv_send_outstanding_bat_ogm_packet(struct work_struct *work)
1719 {
1720 struct delayed_work *delayed_work;
1721 struct batadv_forw_packet *forw_packet;
1722 struct batadv_priv *bat_priv;
1723 bool dropped = false;
1724
1725 delayed_work = to_delayed_work(work);
1726 forw_packet = container_of(delayed_work, struct batadv_forw_packet,
1727 delayed_work);
1728 bat_priv = netdev_priv(forw_packet->if_incoming->mesh_iface);
1729
1730 if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING) {
1731 dropped = true;
1732 goto out;
1733 }
1734
1735 batadv_iv_ogm_emit(forw_packet);
1736
1737 /* we have to have at least one packet in the queue to determine the
1738 * queues wake up time unless we are shutting down.
1739 *
1740 * only re-schedule if this is the "original" copy, e.g. the OGM of the
1741 * primary interface should only be rescheduled once per period, but
1742 * this function will be called for the forw_packet instances of the
1743 * other secondary interfaces as well.
1744 */
1745 if (forw_packet->own &&
1746 forw_packet->if_incoming == forw_packet->if_outgoing)
1747 batadv_iv_ogm_schedule(forw_packet->if_incoming);
1748
1749 out:
1750 /* do we get something for free()? */
1751 if (batadv_forw_packet_steal(forw_packet,
1752 &bat_priv->forw_bat_list_lock))
1753 batadv_forw_packet_free(forw_packet, dropped);
1754 }
1755
batadv_iv_ogm_receive(struct sk_buff * skb,struct batadv_hard_iface * if_incoming)1756 static int batadv_iv_ogm_receive(struct sk_buff *skb,
1757 struct batadv_hard_iface *if_incoming)
1758 {
1759 struct batadv_priv *bat_priv = netdev_priv(if_incoming->mesh_iface);
1760 struct batadv_ogm_packet *ogm_packet;
1761 u8 *packet_pos;
1762 int ogm_offset;
1763 bool res;
1764 int ret = NET_RX_DROP;
1765
1766 res = batadv_check_management_packet(skb, if_incoming, BATADV_OGM_HLEN);
1767 if (!res)
1768 goto free_skb;
1769
1770 /* did we receive a B.A.T.M.A.N. IV OGM packet on an interface
1771 * that does not have B.A.T.M.A.N. IV enabled ?
1772 */
1773 if (bat_priv->algo_ops->iface.enable != batadv_iv_ogm_iface_enable)
1774 goto free_skb;
1775
1776 batadv_inc_counter(bat_priv, BATADV_CNT_MGMT_RX);
1777 batadv_add_counter(bat_priv, BATADV_CNT_MGMT_RX_BYTES,
1778 skb->len + ETH_HLEN);
1779
1780 ogm_offset = 0;
1781 ogm_packet = (struct batadv_ogm_packet *)skb->data;
1782
1783 /* unpack the aggregated packets and process them one by one */
1784 while (batadv_iv_ogm_aggr_packet(ogm_offset, skb_headlen(skb),
1785 ogm_packet)) {
1786 batadv_iv_ogm_process(skb, ogm_offset, if_incoming);
1787
1788 ogm_offset += BATADV_OGM_HLEN;
1789 ogm_offset += ntohs(ogm_packet->tvlv_len);
1790
1791 packet_pos = skb->data + ogm_offset;
1792 ogm_packet = (struct batadv_ogm_packet *)packet_pos;
1793 }
1794
1795 ret = NET_RX_SUCCESS;
1796
1797 free_skb:
1798 if (ret == NET_RX_SUCCESS)
1799 consume_skb(skb);
1800 else
1801 kfree_skb(skb);
1802
1803 return ret;
1804 }
1805
1806 /**
1807 * batadv_iv_ogm_neigh_get_tq_avg() - Get the TQ average for a neighbour on a
1808 * given outgoing interface.
1809 * @neigh_node: Neighbour of interest
1810 * @if_outgoing: Outgoing interface of interest
1811 * @tq_avg: Pointer of where to store the TQ average
1812 *
1813 * Return: False if no average TQ available, otherwise true.
1814 */
1815 static bool
batadv_iv_ogm_neigh_get_tq_avg(struct batadv_neigh_node * neigh_node,struct batadv_hard_iface * if_outgoing,u8 * tq_avg)1816 batadv_iv_ogm_neigh_get_tq_avg(struct batadv_neigh_node *neigh_node,
1817 struct batadv_hard_iface *if_outgoing,
1818 u8 *tq_avg)
1819 {
1820 struct batadv_neigh_ifinfo *n_ifinfo;
1821
1822 n_ifinfo = batadv_neigh_ifinfo_get(neigh_node, if_outgoing);
1823 if (!n_ifinfo)
1824 return false;
1825
1826 *tq_avg = n_ifinfo->bat_iv.tq_avg;
1827 batadv_neigh_ifinfo_put(n_ifinfo);
1828
1829 return true;
1830 }
1831
1832 /**
1833 * batadv_iv_ogm_orig_dump_subentry() - Dump an originator subentry into a
1834 * message
1835 * @msg: Netlink message to dump into
1836 * @portid: Port making netlink request
1837 * @seq: Sequence number of netlink message
1838 * @bat_priv: The bat priv with all the mesh interface information
1839 * @if_outgoing: Limit dump to entries with this outgoing interface
1840 * @orig_node: Originator to dump
1841 * @neigh_node: Single hops neighbour
1842 * @best: Is the best originator
1843 *
1844 * Return: Error code, or 0 on success
1845 */
1846 static int
batadv_iv_ogm_orig_dump_subentry(struct sk_buff * msg,u32 portid,u32 seq,struct batadv_priv * bat_priv,struct batadv_hard_iface * if_outgoing,struct batadv_orig_node * orig_node,struct batadv_neigh_node * neigh_node,bool best)1847 batadv_iv_ogm_orig_dump_subentry(struct sk_buff *msg, u32 portid, u32 seq,
1848 struct batadv_priv *bat_priv,
1849 struct batadv_hard_iface *if_outgoing,
1850 struct batadv_orig_node *orig_node,
1851 struct batadv_neigh_node *neigh_node,
1852 bool best)
1853 {
1854 void *hdr;
1855 u8 tq_avg;
1856 unsigned int last_seen_msecs;
1857
1858 last_seen_msecs = jiffies_to_msecs(jiffies - orig_node->last_seen);
1859
1860 if (!batadv_iv_ogm_neigh_get_tq_avg(neigh_node, if_outgoing, &tq_avg))
1861 return 0;
1862
1863 if (if_outgoing != BATADV_IF_DEFAULT &&
1864 if_outgoing != neigh_node->if_incoming)
1865 return 0;
1866
1867 hdr = genlmsg_put(msg, portid, seq, &batadv_netlink_family,
1868 NLM_F_MULTI, BATADV_CMD_GET_ORIGINATORS);
1869 if (!hdr)
1870 return -ENOBUFS;
1871
1872 if (nla_put(msg, BATADV_ATTR_ORIG_ADDRESS, ETH_ALEN,
1873 orig_node->orig) ||
1874 nla_put(msg, BATADV_ATTR_NEIGH_ADDRESS, ETH_ALEN,
1875 neigh_node->addr) ||
1876 nla_put_string(msg, BATADV_ATTR_HARD_IFNAME,
1877 neigh_node->if_incoming->net_dev->name) ||
1878 nla_put_u32(msg, BATADV_ATTR_HARD_IFINDEX,
1879 neigh_node->if_incoming->net_dev->ifindex) ||
1880 nla_put_u8(msg, BATADV_ATTR_TQ, tq_avg) ||
1881 nla_put_u32(msg, BATADV_ATTR_LAST_SEEN_MSECS,
1882 last_seen_msecs))
1883 goto nla_put_failure;
1884
1885 if (best && nla_put_flag(msg, BATADV_ATTR_FLAG_BEST))
1886 goto nla_put_failure;
1887
1888 genlmsg_end(msg, hdr);
1889 return 0;
1890
1891 nla_put_failure:
1892 genlmsg_cancel(msg, hdr);
1893 return -EMSGSIZE;
1894 }
1895
1896 /**
1897 * batadv_iv_ogm_orig_dump_entry() - Dump an originator entry into a message
1898 * @msg: Netlink message to dump into
1899 * @portid: Port making netlink request
1900 * @seq: Sequence number of netlink message
1901 * @bat_priv: The bat priv with all the mesh interface information
1902 * @if_outgoing: Limit dump to entries with this outgoing interface
1903 * @orig_node: Originator to dump
1904 * @sub_s: Number of sub entries to skip
1905 *
1906 * This function assumes the caller holds rcu_read_lock().
1907 *
1908 * Return: Error code, or 0 on success
1909 */
1910 static int
batadv_iv_ogm_orig_dump_entry(struct sk_buff * msg,u32 portid,u32 seq,struct batadv_priv * bat_priv,struct batadv_hard_iface * if_outgoing,struct batadv_orig_node * orig_node,int * sub_s)1911 batadv_iv_ogm_orig_dump_entry(struct sk_buff *msg, u32 portid, u32 seq,
1912 struct batadv_priv *bat_priv,
1913 struct batadv_hard_iface *if_outgoing,
1914 struct batadv_orig_node *orig_node, int *sub_s)
1915 {
1916 struct batadv_neigh_node *neigh_node_best;
1917 struct batadv_neigh_node *neigh_node;
1918 int sub = 0;
1919 bool best;
1920 u8 tq_avg_best;
1921
1922 neigh_node_best = batadv_orig_router_get(orig_node, if_outgoing);
1923 if (!neigh_node_best)
1924 goto out;
1925
1926 if (!batadv_iv_ogm_neigh_get_tq_avg(neigh_node_best, if_outgoing,
1927 &tq_avg_best))
1928 goto out;
1929
1930 if (tq_avg_best == 0)
1931 goto out;
1932
1933 hlist_for_each_entry_rcu(neigh_node, &orig_node->neigh_list, list) {
1934 if (sub++ < *sub_s)
1935 continue;
1936
1937 best = (neigh_node == neigh_node_best);
1938
1939 if (batadv_iv_ogm_orig_dump_subentry(msg, portid, seq,
1940 bat_priv, if_outgoing,
1941 orig_node, neigh_node,
1942 best)) {
1943 batadv_neigh_node_put(neigh_node_best);
1944
1945 *sub_s = sub - 1;
1946 return -EMSGSIZE;
1947 }
1948 }
1949
1950 out:
1951 batadv_neigh_node_put(neigh_node_best);
1952
1953 *sub_s = 0;
1954 return 0;
1955 }
1956
1957 /**
1958 * batadv_iv_ogm_orig_dump_bucket() - Dump an originator bucket into a
1959 * message
1960 * @msg: Netlink message to dump into
1961 * @portid: Port making netlink request
1962 * @seq: Sequence number of netlink message
1963 * @bat_priv: The bat priv with all the mesh interface information
1964 * @if_outgoing: Limit dump to entries with this outgoing interface
1965 * @head: Bucket to be dumped
1966 * @idx_s: Number of entries to be skipped
1967 * @sub: Number of sub entries to be skipped
1968 *
1969 * Return: Error code, or 0 on success
1970 */
1971 static int
batadv_iv_ogm_orig_dump_bucket(struct sk_buff * msg,u32 portid,u32 seq,struct batadv_priv * bat_priv,struct batadv_hard_iface * if_outgoing,struct hlist_head * head,int * idx_s,int * sub)1972 batadv_iv_ogm_orig_dump_bucket(struct sk_buff *msg, u32 portid, u32 seq,
1973 struct batadv_priv *bat_priv,
1974 struct batadv_hard_iface *if_outgoing,
1975 struct hlist_head *head, int *idx_s, int *sub)
1976 {
1977 struct batadv_orig_node *orig_node;
1978 int idx = 0;
1979
1980 rcu_read_lock();
1981 hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
1982 if (idx++ < *idx_s)
1983 continue;
1984
1985 if (batadv_iv_ogm_orig_dump_entry(msg, portid, seq, bat_priv,
1986 if_outgoing, orig_node,
1987 sub)) {
1988 rcu_read_unlock();
1989 *idx_s = idx - 1;
1990 return -EMSGSIZE;
1991 }
1992 }
1993 rcu_read_unlock();
1994
1995 *idx_s = 0;
1996 *sub = 0;
1997 return 0;
1998 }
1999
2000 /**
2001 * batadv_iv_ogm_orig_dump() - Dump the originators into a message
2002 * @msg: Netlink message to dump into
2003 * @cb: Control block containing additional options
2004 * @bat_priv: The bat priv with all the mesh interface information
2005 * @if_outgoing: Limit dump to entries with this outgoing interface
2006 */
2007 static void
batadv_iv_ogm_orig_dump(struct sk_buff * msg,struct netlink_callback * cb,struct batadv_priv * bat_priv,struct batadv_hard_iface * if_outgoing)2008 batadv_iv_ogm_orig_dump(struct sk_buff *msg, struct netlink_callback *cb,
2009 struct batadv_priv *bat_priv,
2010 struct batadv_hard_iface *if_outgoing)
2011 {
2012 struct batadv_hashtable *hash = bat_priv->orig_hash;
2013 struct hlist_head *head;
2014 int bucket = cb->args[0];
2015 int idx = cb->args[1];
2016 int sub = cb->args[2];
2017 int portid = NETLINK_CB(cb->skb).portid;
2018
2019 while (bucket < hash->size) {
2020 head = &hash->table[bucket];
2021
2022 if (batadv_iv_ogm_orig_dump_bucket(msg, portid,
2023 cb->nlh->nlmsg_seq,
2024 bat_priv, if_outgoing, head,
2025 &idx, &sub))
2026 break;
2027
2028 bucket++;
2029 }
2030
2031 cb->args[0] = bucket;
2032 cb->args[1] = idx;
2033 cb->args[2] = sub;
2034 }
2035
2036 /**
2037 * batadv_iv_ogm_neigh_diff() - calculate tq difference of two neighbors
2038 * @neigh1: the first neighbor object of the comparison
2039 * @if_outgoing1: outgoing interface for the first neighbor
2040 * @neigh2: the second neighbor object of the comparison
2041 * @if_outgoing2: outgoing interface for the second neighbor
2042 * @diff: pointer to integer receiving the calculated difference
2043 *
2044 * The content of *@diff is only valid when this function returns true.
2045 * It is less, equal to or greater than 0 if the metric via neigh1 is lower,
2046 * the same as or higher than the metric via neigh2
2047 *
2048 * Return: true when the difference could be calculated, false otherwise
2049 */
batadv_iv_ogm_neigh_diff(struct batadv_neigh_node * neigh1,struct batadv_hard_iface * if_outgoing1,struct batadv_neigh_node * neigh2,struct batadv_hard_iface * if_outgoing2,int * diff)2050 static bool batadv_iv_ogm_neigh_diff(struct batadv_neigh_node *neigh1,
2051 struct batadv_hard_iface *if_outgoing1,
2052 struct batadv_neigh_node *neigh2,
2053 struct batadv_hard_iface *if_outgoing2,
2054 int *diff)
2055 {
2056 struct batadv_neigh_ifinfo *neigh1_ifinfo, *neigh2_ifinfo;
2057 u8 tq1, tq2;
2058 bool ret = true;
2059
2060 neigh1_ifinfo = batadv_neigh_ifinfo_get(neigh1, if_outgoing1);
2061 neigh2_ifinfo = batadv_neigh_ifinfo_get(neigh2, if_outgoing2);
2062
2063 if (!neigh1_ifinfo || !neigh2_ifinfo) {
2064 ret = false;
2065 goto out;
2066 }
2067
2068 tq1 = neigh1_ifinfo->bat_iv.tq_avg;
2069 tq2 = neigh2_ifinfo->bat_iv.tq_avg;
2070 *diff = (int)tq1 - (int)tq2;
2071
2072 out:
2073 batadv_neigh_ifinfo_put(neigh1_ifinfo);
2074 batadv_neigh_ifinfo_put(neigh2_ifinfo);
2075
2076 return ret;
2077 }
2078
2079 /**
2080 * batadv_iv_ogm_neigh_dump_neigh() - Dump a neighbour into a netlink message
2081 * @msg: Netlink message to dump into
2082 * @portid: Port making netlink request
2083 * @seq: Sequence number of netlink message
2084 * @hardif_neigh: Neighbour to be dumped
2085 *
2086 * Return: Error code, or 0 on success
2087 */
2088 static int
batadv_iv_ogm_neigh_dump_neigh(struct sk_buff * msg,u32 portid,u32 seq,struct batadv_hardif_neigh_node * hardif_neigh)2089 batadv_iv_ogm_neigh_dump_neigh(struct sk_buff *msg, u32 portid, u32 seq,
2090 struct batadv_hardif_neigh_node *hardif_neigh)
2091 {
2092 void *hdr;
2093 unsigned int last_seen_msecs;
2094
2095 last_seen_msecs = jiffies_to_msecs(jiffies - hardif_neigh->last_seen);
2096
2097 hdr = genlmsg_put(msg, portid, seq, &batadv_netlink_family,
2098 NLM_F_MULTI, BATADV_CMD_GET_NEIGHBORS);
2099 if (!hdr)
2100 return -ENOBUFS;
2101
2102 if (nla_put(msg, BATADV_ATTR_NEIGH_ADDRESS, ETH_ALEN,
2103 hardif_neigh->addr) ||
2104 nla_put_string(msg, BATADV_ATTR_HARD_IFNAME,
2105 hardif_neigh->if_incoming->net_dev->name) ||
2106 nla_put_u32(msg, BATADV_ATTR_HARD_IFINDEX,
2107 hardif_neigh->if_incoming->net_dev->ifindex) ||
2108 nla_put_u32(msg, BATADV_ATTR_LAST_SEEN_MSECS,
2109 last_seen_msecs))
2110 goto nla_put_failure;
2111
2112 genlmsg_end(msg, hdr);
2113 return 0;
2114
2115 nla_put_failure:
2116 genlmsg_cancel(msg, hdr);
2117 return -EMSGSIZE;
2118 }
2119
2120 /**
2121 * batadv_iv_ogm_neigh_dump_hardif() - Dump the neighbours of a hard interface
2122 * into a message
2123 * @msg: Netlink message to dump into
2124 * @portid: Port making netlink request
2125 * @seq: Sequence number of netlink message
2126 * @bat_priv: The bat priv with all the mesh interface information
2127 * @hard_iface: Hard interface to dump the neighbours for
2128 * @idx_s: Number of entries to skip
2129 *
2130 * This function assumes the caller holds rcu_read_lock().
2131 *
2132 * Return: Error code, or 0 on success
2133 */
2134 static int
batadv_iv_ogm_neigh_dump_hardif(struct sk_buff * msg,u32 portid,u32 seq,struct batadv_priv * bat_priv,struct batadv_hard_iface * hard_iface,int * idx_s)2135 batadv_iv_ogm_neigh_dump_hardif(struct sk_buff *msg, u32 portid, u32 seq,
2136 struct batadv_priv *bat_priv,
2137 struct batadv_hard_iface *hard_iface,
2138 int *idx_s)
2139 {
2140 struct batadv_hardif_neigh_node *hardif_neigh;
2141 int idx = 0;
2142
2143 hlist_for_each_entry_rcu(hardif_neigh,
2144 &hard_iface->neigh_list, list) {
2145 if (idx++ < *idx_s)
2146 continue;
2147
2148 if (batadv_iv_ogm_neigh_dump_neigh(msg, portid, seq,
2149 hardif_neigh)) {
2150 *idx_s = idx - 1;
2151 return -EMSGSIZE;
2152 }
2153 }
2154
2155 *idx_s = 0;
2156 return 0;
2157 }
2158
2159 /**
2160 * batadv_iv_ogm_neigh_dump() - Dump the neighbours into a message
2161 * @msg: Netlink message to dump into
2162 * @cb: Control block containing additional options
2163 * @bat_priv: The bat priv with all the mesh interface information
2164 * @single_hardif: Limit dump to this hard interface
2165 */
2166 static void
batadv_iv_ogm_neigh_dump(struct sk_buff * msg,struct netlink_callback * cb,struct batadv_priv * bat_priv,struct batadv_hard_iface * single_hardif)2167 batadv_iv_ogm_neigh_dump(struct sk_buff *msg, struct netlink_callback *cb,
2168 struct batadv_priv *bat_priv,
2169 struct batadv_hard_iface *single_hardif)
2170 {
2171 struct batadv_hard_iface *hard_iface;
2172 struct list_head *iter;
2173 int i_hardif = 0;
2174 int i_hardif_s = cb->args[0];
2175 int idx = cb->args[1];
2176 int portid = NETLINK_CB(cb->skb).portid;
2177
2178 rcu_read_lock();
2179 if (single_hardif) {
2180 if (i_hardif_s == 0) {
2181 if (batadv_iv_ogm_neigh_dump_hardif(msg, portid,
2182 cb->nlh->nlmsg_seq,
2183 bat_priv,
2184 single_hardif,
2185 &idx) == 0)
2186 i_hardif++;
2187 }
2188 } else {
2189 netdev_for_each_lower_private_rcu(bat_priv->mesh_iface, hard_iface, iter) {
2190 if (i_hardif++ < i_hardif_s)
2191 continue;
2192
2193 if (batadv_iv_ogm_neigh_dump_hardif(msg, portid,
2194 cb->nlh->nlmsg_seq,
2195 bat_priv,
2196 hard_iface, &idx)) {
2197 i_hardif--;
2198 break;
2199 }
2200 }
2201 }
2202 rcu_read_unlock();
2203
2204 cb->args[0] = i_hardif;
2205 cb->args[1] = idx;
2206 }
2207
2208 /**
2209 * batadv_iv_ogm_neigh_cmp() - compare the metrics of two neighbors
2210 * @neigh1: the first neighbor object of the comparison
2211 * @if_outgoing1: outgoing interface for the first neighbor
2212 * @neigh2: the second neighbor object of the comparison
2213 * @if_outgoing2: outgoing interface for the second neighbor
2214 *
2215 * Return: a value less, equal to or greater than 0 if the metric via neigh1 is
2216 * lower, the same as or higher than the metric via neigh2
2217 */
batadv_iv_ogm_neigh_cmp(struct batadv_neigh_node * neigh1,struct batadv_hard_iface * if_outgoing1,struct batadv_neigh_node * neigh2,struct batadv_hard_iface * if_outgoing2)2218 static int batadv_iv_ogm_neigh_cmp(struct batadv_neigh_node *neigh1,
2219 struct batadv_hard_iface *if_outgoing1,
2220 struct batadv_neigh_node *neigh2,
2221 struct batadv_hard_iface *if_outgoing2)
2222 {
2223 bool ret;
2224 int diff;
2225
2226 ret = batadv_iv_ogm_neigh_diff(neigh1, if_outgoing1, neigh2,
2227 if_outgoing2, &diff);
2228 if (!ret)
2229 return 0;
2230
2231 return diff;
2232 }
2233
2234 /**
2235 * batadv_iv_ogm_neigh_is_sob() - check if neigh1 is similarly good or better
2236 * than neigh2 from the metric prospective
2237 * @neigh1: the first neighbor object of the comparison
2238 * @if_outgoing1: outgoing interface for the first neighbor
2239 * @neigh2: the second neighbor object of the comparison
2240 * @if_outgoing2: outgoing interface for the second neighbor
2241 *
2242 * Return: true if the metric via neigh1 is equally good or better than
2243 * the metric via neigh2, false otherwise.
2244 */
2245 static bool
batadv_iv_ogm_neigh_is_sob(struct batadv_neigh_node * neigh1,struct batadv_hard_iface * if_outgoing1,struct batadv_neigh_node * neigh2,struct batadv_hard_iface * if_outgoing2)2246 batadv_iv_ogm_neigh_is_sob(struct batadv_neigh_node *neigh1,
2247 struct batadv_hard_iface *if_outgoing1,
2248 struct batadv_neigh_node *neigh2,
2249 struct batadv_hard_iface *if_outgoing2)
2250 {
2251 bool ret;
2252 int diff;
2253
2254 ret = batadv_iv_ogm_neigh_diff(neigh1, if_outgoing1, neigh2,
2255 if_outgoing2, &diff);
2256 if (!ret)
2257 return false;
2258
2259 ret = diff > -BATADV_TQ_SIMILARITY_THRESHOLD;
2260 return ret;
2261 }
2262
batadv_iv_iface_enabled(struct batadv_hard_iface * hard_iface)2263 static void batadv_iv_iface_enabled(struct batadv_hard_iface *hard_iface)
2264 {
2265 /* begin scheduling originator messages on that interface */
2266 batadv_iv_ogm_schedule(hard_iface);
2267 }
2268
2269 /**
2270 * batadv_iv_init_sel_class() - initialize GW selection class
2271 * @bat_priv: the bat priv with all the mesh interface information
2272 */
batadv_iv_init_sel_class(struct batadv_priv * bat_priv)2273 static void batadv_iv_init_sel_class(struct batadv_priv *bat_priv)
2274 {
2275 /* set default TQ difference threshold to 20 */
2276 atomic_set(&bat_priv->gw.sel_class, 20);
2277 }
2278
2279 static struct batadv_gw_node *
batadv_iv_gw_get_best_gw_node(struct batadv_priv * bat_priv)2280 batadv_iv_gw_get_best_gw_node(struct batadv_priv *bat_priv)
2281 {
2282 struct batadv_neigh_node *router;
2283 struct batadv_neigh_ifinfo *router_ifinfo;
2284 struct batadv_gw_node *gw_node, *curr_gw = NULL;
2285 u64 max_gw_factor = 0;
2286 u64 tmp_gw_factor = 0;
2287 u8 max_tq = 0;
2288 u8 tq_avg;
2289 struct batadv_orig_node *orig_node;
2290
2291 rcu_read_lock();
2292 hlist_for_each_entry_rcu(gw_node, &bat_priv->gw.gateway_list, list) {
2293 orig_node = gw_node->orig_node;
2294 router = batadv_orig_router_get(orig_node, BATADV_IF_DEFAULT);
2295 if (!router)
2296 continue;
2297
2298 router_ifinfo = batadv_neigh_ifinfo_get(router,
2299 BATADV_IF_DEFAULT);
2300 if (!router_ifinfo)
2301 goto next;
2302
2303 if (!kref_get_unless_zero(&gw_node->refcount))
2304 goto next;
2305
2306 tq_avg = router_ifinfo->bat_iv.tq_avg;
2307
2308 switch (atomic_read(&bat_priv->gw.sel_class)) {
2309 case 1: /* fast connection */
2310 tmp_gw_factor = tq_avg * tq_avg;
2311 tmp_gw_factor *= gw_node->bandwidth_down;
2312 tmp_gw_factor *= 100 * 100;
2313 tmp_gw_factor >>= 18;
2314
2315 if (tmp_gw_factor > max_gw_factor ||
2316 (tmp_gw_factor == max_gw_factor &&
2317 tq_avg > max_tq)) {
2318 batadv_gw_node_put(curr_gw);
2319 curr_gw = gw_node;
2320 kref_get(&curr_gw->refcount);
2321 }
2322 break;
2323
2324 default: /* 2: stable connection (use best statistic)
2325 * 3: fast-switch (use best statistic but change as
2326 * soon as a better gateway appears)
2327 * XX: late-switch (use best statistic but change as
2328 * soon as a better gateway appears which has
2329 * $routing_class more tq points)
2330 */
2331 if (tq_avg > max_tq) {
2332 batadv_gw_node_put(curr_gw);
2333 curr_gw = gw_node;
2334 kref_get(&curr_gw->refcount);
2335 }
2336 break;
2337 }
2338
2339 if (tq_avg > max_tq)
2340 max_tq = tq_avg;
2341
2342 if (tmp_gw_factor > max_gw_factor)
2343 max_gw_factor = tmp_gw_factor;
2344
2345 batadv_gw_node_put(gw_node);
2346
2347 next:
2348 batadv_neigh_node_put(router);
2349 batadv_neigh_ifinfo_put(router_ifinfo);
2350 }
2351 rcu_read_unlock();
2352
2353 return curr_gw;
2354 }
2355
batadv_iv_gw_is_eligible(struct batadv_priv * bat_priv,struct batadv_orig_node * curr_gw_orig,struct batadv_orig_node * orig_node)2356 static bool batadv_iv_gw_is_eligible(struct batadv_priv *bat_priv,
2357 struct batadv_orig_node *curr_gw_orig,
2358 struct batadv_orig_node *orig_node)
2359 {
2360 struct batadv_neigh_ifinfo *router_orig_ifinfo = NULL;
2361 struct batadv_neigh_ifinfo *router_gw_ifinfo = NULL;
2362 struct batadv_neigh_node *router_gw = NULL;
2363 struct batadv_neigh_node *router_orig = NULL;
2364 u8 gw_tq_avg, orig_tq_avg;
2365 bool ret = false;
2366
2367 /* dynamic re-election is performed only on fast or late switch */
2368 if (atomic_read(&bat_priv->gw.sel_class) <= 2)
2369 return false;
2370
2371 router_gw = batadv_orig_router_get(curr_gw_orig, BATADV_IF_DEFAULT);
2372 if (!router_gw) {
2373 ret = true;
2374 goto out;
2375 }
2376
2377 router_gw_ifinfo = batadv_neigh_ifinfo_get(router_gw,
2378 BATADV_IF_DEFAULT);
2379 if (!router_gw_ifinfo) {
2380 ret = true;
2381 goto out;
2382 }
2383
2384 router_orig = batadv_orig_router_get(orig_node, BATADV_IF_DEFAULT);
2385 if (!router_orig)
2386 goto out;
2387
2388 router_orig_ifinfo = batadv_neigh_ifinfo_get(router_orig,
2389 BATADV_IF_DEFAULT);
2390 if (!router_orig_ifinfo)
2391 goto out;
2392
2393 gw_tq_avg = router_gw_ifinfo->bat_iv.tq_avg;
2394 orig_tq_avg = router_orig_ifinfo->bat_iv.tq_avg;
2395
2396 /* the TQ value has to be better */
2397 if (orig_tq_avg < gw_tq_avg)
2398 goto out;
2399
2400 /* if the routing class is greater than 3 the value tells us how much
2401 * greater the TQ value of the new gateway must be
2402 */
2403 if ((atomic_read(&bat_priv->gw.sel_class) > 3) &&
2404 (orig_tq_avg - gw_tq_avg < atomic_read(&bat_priv->gw.sel_class)))
2405 goto out;
2406
2407 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
2408 "Restarting gateway selection: better gateway found (tq curr: %i, tq new: %i)\n",
2409 gw_tq_avg, orig_tq_avg);
2410
2411 ret = true;
2412 out:
2413 batadv_neigh_ifinfo_put(router_gw_ifinfo);
2414 batadv_neigh_ifinfo_put(router_orig_ifinfo);
2415 batadv_neigh_node_put(router_gw);
2416 batadv_neigh_node_put(router_orig);
2417
2418 return ret;
2419 }
2420
2421 /**
2422 * batadv_iv_gw_dump_entry() - Dump a gateway into a message
2423 * @msg: Netlink message to dump into
2424 * @portid: Port making netlink request
2425 * @cb: Control block containing additional options
2426 * @bat_priv: The bat priv with all the mesh interface information
2427 * @gw_node: Gateway to be dumped
2428 *
2429 * Return: Error code, or 0 on success
2430 */
batadv_iv_gw_dump_entry(struct sk_buff * msg,u32 portid,struct netlink_callback * cb,struct batadv_priv * bat_priv,struct batadv_gw_node * gw_node)2431 static int batadv_iv_gw_dump_entry(struct sk_buff *msg, u32 portid,
2432 struct netlink_callback *cb,
2433 struct batadv_priv *bat_priv,
2434 struct batadv_gw_node *gw_node)
2435 {
2436 struct batadv_neigh_ifinfo *router_ifinfo = NULL;
2437 struct batadv_neigh_node *router;
2438 struct batadv_gw_node *curr_gw = NULL;
2439 int ret = 0;
2440 void *hdr;
2441
2442 router = batadv_orig_router_get(gw_node->orig_node, BATADV_IF_DEFAULT);
2443 if (!router)
2444 goto out;
2445
2446 router_ifinfo = batadv_neigh_ifinfo_get(router, BATADV_IF_DEFAULT);
2447 if (!router_ifinfo)
2448 goto out;
2449
2450 curr_gw = batadv_gw_get_selected_gw_node(bat_priv);
2451
2452 hdr = genlmsg_put(msg, portid, cb->nlh->nlmsg_seq,
2453 &batadv_netlink_family, NLM_F_MULTI,
2454 BATADV_CMD_GET_GATEWAYS);
2455 if (!hdr) {
2456 ret = -ENOBUFS;
2457 goto out;
2458 }
2459
2460 genl_dump_check_consistent(cb, hdr);
2461
2462 ret = -EMSGSIZE;
2463
2464 if (curr_gw == gw_node)
2465 if (nla_put_flag(msg, BATADV_ATTR_FLAG_BEST)) {
2466 genlmsg_cancel(msg, hdr);
2467 goto out;
2468 }
2469
2470 if (nla_put(msg, BATADV_ATTR_ORIG_ADDRESS, ETH_ALEN,
2471 gw_node->orig_node->orig) ||
2472 nla_put_u8(msg, BATADV_ATTR_TQ, router_ifinfo->bat_iv.tq_avg) ||
2473 nla_put(msg, BATADV_ATTR_ROUTER, ETH_ALEN,
2474 router->addr) ||
2475 nla_put_string(msg, BATADV_ATTR_HARD_IFNAME,
2476 router->if_incoming->net_dev->name) ||
2477 nla_put_u32(msg, BATADV_ATTR_HARD_IFINDEX,
2478 router->if_incoming->net_dev->ifindex) ||
2479 nla_put_u32(msg, BATADV_ATTR_BANDWIDTH_DOWN,
2480 gw_node->bandwidth_down) ||
2481 nla_put_u32(msg, BATADV_ATTR_BANDWIDTH_UP,
2482 gw_node->bandwidth_up)) {
2483 genlmsg_cancel(msg, hdr);
2484 goto out;
2485 }
2486
2487 genlmsg_end(msg, hdr);
2488 ret = 0;
2489
2490 out:
2491 batadv_gw_node_put(curr_gw);
2492 batadv_neigh_ifinfo_put(router_ifinfo);
2493 batadv_neigh_node_put(router);
2494 return ret;
2495 }
2496
2497 /**
2498 * batadv_iv_gw_dump() - Dump gateways into a message
2499 * @msg: Netlink message to dump into
2500 * @cb: Control block containing additional options
2501 * @bat_priv: The bat priv with all the mesh interface information
2502 */
batadv_iv_gw_dump(struct sk_buff * msg,struct netlink_callback * cb,struct batadv_priv * bat_priv)2503 static void batadv_iv_gw_dump(struct sk_buff *msg, struct netlink_callback *cb,
2504 struct batadv_priv *bat_priv)
2505 {
2506 int portid = NETLINK_CB(cb->skb).portid;
2507 struct batadv_gw_node *gw_node;
2508 int idx_skip = cb->args[0];
2509 int idx = 0;
2510
2511 spin_lock_bh(&bat_priv->gw.list_lock);
2512 cb->seq = bat_priv->gw.generation << 1 | 1;
2513
2514 hlist_for_each_entry(gw_node, &bat_priv->gw.gateway_list, list) {
2515 if (idx++ < idx_skip)
2516 continue;
2517
2518 if (batadv_iv_gw_dump_entry(msg, portid, cb, bat_priv,
2519 gw_node)) {
2520 idx_skip = idx - 1;
2521 goto unlock;
2522 }
2523 }
2524
2525 idx_skip = idx;
2526 unlock:
2527 spin_unlock_bh(&bat_priv->gw.list_lock);
2528
2529 cb->args[0] = idx_skip;
2530 }
2531
2532 static struct batadv_algo_ops batadv_batman_iv __read_mostly = {
2533 .name = "BATMAN_IV",
2534 .iface = {
2535 .enable = batadv_iv_ogm_iface_enable,
2536 .enabled = batadv_iv_iface_enabled,
2537 .disable = batadv_iv_ogm_iface_disable,
2538 .update_mac = batadv_iv_ogm_iface_update_mac,
2539 .primary_set = batadv_iv_ogm_primary_iface_set,
2540 },
2541 .neigh = {
2542 .cmp = batadv_iv_ogm_neigh_cmp,
2543 .is_similar_or_better = batadv_iv_ogm_neigh_is_sob,
2544 .dump = batadv_iv_ogm_neigh_dump,
2545 },
2546 .orig = {
2547 .dump = batadv_iv_ogm_orig_dump,
2548 },
2549 .gw = {
2550 .init_sel_class = batadv_iv_init_sel_class,
2551 .sel_class_max = BATADV_TQ_MAX_VALUE,
2552 .get_best_gw_node = batadv_iv_gw_get_best_gw_node,
2553 .is_eligible = batadv_iv_gw_is_eligible,
2554 .dump = batadv_iv_gw_dump,
2555 },
2556 };
2557
2558 /**
2559 * batadv_iv_init() - B.A.T.M.A.N. IV initialization function
2560 *
2561 * Return: 0 on success or negative error number in case of failure
2562 */
batadv_iv_init(void)2563 int __init batadv_iv_init(void)
2564 {
2565 int ret;
2566
2567 /* batman originator packet */
2568 ret = batadv_recv_handler_register(BATADV_IV_OGM,
2569 batadv_iv_ogm_receive);
2570 if (ret < 0)
2571 goto out;
2572
2573 ret = batadv_algo_register(&batadv_batman_iv);
2574 if (ret < 0)
2575 goto handler_unregister;
2576
2577 goto out;
2578
2579 handler_unregister:
2580 batadv_recv_handler_unregister(BATADV_IV_OGM);
2581 out:
2582 return ret;
2583 }
2584