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