aboutsummaryrefslogtreecommitdiffstats
path: root/net/batman-adv
diff options
context:
space:
mode:
authorSimon Wunderlich <simon@open-mesh.com>2013-11-13 13:14:49 -0500
committerAntonio Quartulli <antonio@meshcoding.com>2014-01-12 08:41:14 -0500
commitef0a937f7a1450d3a133ccd83c9c7d07587e7a00 (patch)
treec6118349ffdb8d12835f3aa0c8d9ca24a385c577 /net/batman-adv
parentc039876892e3247928ce5ad3d0ba46aee7d7099a (diff)
batman-adv: consider outgoing interface in OGM sending
The current OGM sending an aggregation functionality decides on which interfaces a packet should be sent when it parses the forward packet struct. However, with the network wide multi interface optimization the outgoing interface is decided by the OGM processing function. This is reflected by moving the decision in the OGM processing function and add the outgoing interface in the forwarding packet struct. This practically implies that an OGM may be added multiple times (once per outgoing interface), and this also affects aggregation which needs to consider the outgoing interface as well. Signed-off-by: Simon Wunderlich <simon@open-mesh.com> Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch> Signed-off-by: Antonio Quartulli <antonio@meshcoding.com>
Diffstat (limited to 'net/batman-adv')
-rw-r--r--net/batman-adv/bat_iv_ogm.c153
-rw-r--r--net/batman-adv/send.c19
-rw-r--r--net/batman-adv/types.h7
3 files changed, 115 insertions, 64 deletions
diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c
index 789aaa9f2e3a..a9b7e82feb31 100644
--- a/net/batman-adv/bat_iv_ogm.c
+++ b/net/batman-adv/bat_iv_ogm.c
@@ -466,17 +466,9 @@ static void batadv_iv_ogm_send_to_if(struct batadv_forw_packet *forw_packet,
466/* send a batman ogm packet */ 466/* send a batman ogm packet */
467static void batadv_iv_ogm_emit(struct batadv_forw_packet *forw_packet) 467static void batadv_iv_ogm_emit(struct batadv_forw_packet *forw_packet)
468{ 468{
469 struct batadv_hard_iface *hard_iface;
470 struct net_device *soft_iface; 469 struct net_device *soft_iface;
471 struct batadv_priv *bat_priv; 470 struct batadv_priv *bat_priv;
472 struct batadv_hard_iface *primary_if = NULL; 471 struct batadv_hard_iface *primary_if = NULL;
473 struct batadv_ogm_packet *batadv_ogm_packet;
474 unsigned char directlink;
475 uint8_t *packet_pos;
476
477 packet_pos = forw_packet->skb->data;
478 batadv_ogm_packet = (struct batadv_ogm_packet *)packet_pos;
479 directlink = (batadv_ogm_packet->flags & BATADV_DIRECTLINK ? 1 : 0);
480 472
481 if (!forw_packet->if_incoming) { 473 if (!forw_packet->if_incoming) {
482 pr_err("Error - can't forward packet: incoming iface not specified\n"); 474 pr_err("Error - can't forward packet: incoming iface not specified\n");
@@ -486,59 +478,48 @@ static void batadv_iv_ogm_emit(struct batadv_forw_packet *forw_packet)
486 soft_iface = forw_packet->if_incoming->soft_iface; 478 soft_iface = forw_packet->if_incoming->soft_iface;
487 bat_priv = netdev_priv(soft_iface); 479 bat_priv = netdev_priv(soft_iface);
488 480
489 if (forw_packet->if_incoming->if_status != BATADV_IF_ACTIVE) 481 if (WARN_ON(!forw_packet->if_outgoing))
490 goto out; 482 goto out;
491 483
492 primary_if = batadv_primary_if_get_selected(bat_priv); 484 if (WARN_ON(forw_packet->if_outgoing->soft_iface != soft_iface))
493 if (!primary_if)
494 goto out; 485 goto out;
495 486
496 /* multihomed peer assumed 487 if (forw_packet->if_incoming->if_status != BATADV_IF_ACTIVE)
497 * non-primary OGMs are only broadcasted on their interface
498 */
499 if ((directlink && (batadv_ogm_packet->ttl == 1)) ||
500 (forw_packet->own && (forw_packet->if_incoming != primary_if))) {
501 /* FIXME: what about aggregated packets ? */
502 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
503 "%s packet (originator %pM, seqno %u, TTL %d) on interface %s [%pM]\n",
504 (forw_packet->own ? "Sending own" : "Forwarding"),
505 batadv_ogm_packet->orig,
506 ntohl(batadv_ogm_packet->seqno),
507 batadv_ogm_packet->ttl,
508 forw_packet->if_incoming->net_dev->name,
509 forw_packet->if_incoming->net_dev->dev_addr);
510
511 /* skb is only used once and than forw_packet is free'd */
512 batadv_send_skb_packet(forw_packet->skb,
513 forw_packet->if_incoming,
514 batadv_broadcast_addr);
515 forw_packet->skb = NULL;
516
517 goto out; 488 goto out;
518 }
519 489
520 /* broadcast on every interface */ 490 primary_if = batadv_primary_if_get_selected(bat_priv);
521 rcu_read_lock(); 491 if (!primary_if)
522 list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) { 492 goto out;
523 if (hard_iface->soft_iface != soft_iface)
524 continue;
525 493
526 batadv_iv_ogm_send_to_if(forw_packet, hard_iface); 494 /* only for one specific outgoing interface */
527 } 495 batadv_iv_ogm_send_to_if(forw_packet, forw_packet->if_outgoing);
528 rcu_read_unlock();
529 496
530out: 497out:
531 if (primary_if) 498 if (primary_if)
532 batadv_hardif_free_ref(primary_if); 499 batadv_hardif_free_ref(primary_if);
533} 500}
534 501
535/* return true if new_packet can be aggregated with forw_packet */ 502/**
503 * batadv_iv_ogm_can_aggregate - find out if an OGM can be aggregated on an
504 * existing forward packet
505 * @new_bat_ogm_packet: OGM packet to be aggregated
506 * @bat_priv: the bat priv with all the soft interface information
507 * @packet_len: (total) length of the OGM
508 * @send_time: timestamp (jiffies) when the packet is to be sent
509 * @direktlink: true if this is a direct link packet
510 * @if_incoming: interface where the packet was received
511 * @if_outgoing: interface for which the retransmission should be considered
512 * @forw_packet: the forwarded packet which should be checked
513 *
514 * Returns true if new_packet can be aggregated with forw_packet
515 */
536static bool 516static bool
537batadv_iv_ogm_can_aggregate(const struct batadv_ogm_packet *new_bat_ogm_packet, 517batadv_iv_ogm_can_aggregate(const struct batadv_ogm_packet *new_bat_ogm_packet,
538 struct batadv_priv *bat_priv, 518 struct batadv_priv *bat_priv,
539 int packet_len, unsigned long send_time, 519 int packet_len, unsigned long send_time,
540 bool directlink, 520 bool directlink,
541 const struct batadv_hard_iface *if_incoming, 521 const struct batadv_hard_iface *if_incoming,
522 const struct batadv_hard_iface *if_outgoing,
542 const struct batadv_forw_packet *forw_packet) 523 const struct batadv_forw_packet *forw_packet)
543{ 524{
544 struct batadv_ogm_packet *batadv_ogm_packet; 525 struct batadv_ogm_packet *batadv_ogm_packet;
@@ -572,6 +553,10 @@ batadv_iv_ogm_can_aggregate(const struct batadv_ogm_packet *new_bat_ogm_packet,
572 if (!primary_if) 553 if (!primary_if)
573 goto out; 554 goto out;
574 555
556 /* packet is not leaving on the same interface. */
557 if (forw_packet->if_outgoing != if_outgoing)
558 goto out;
559
575 /* packets without direct link flag and high TTL 560 /* packets without direct link flag and high TTL
576 * are flooded through the net 561 * are flooded through the net
577 */ 562 */
@@ -613,11 +598,21 @@ out:
613 return res; 598 return res;
614} 599}
615 600
616/* create a new aggregated packet and add this packet to it */ 601/* batadv_iv_ogm_aggregate_new - create a new aggregated packet and add this
602 * packet to it.
603 * @packet_buff: pointer to the OGM
604 * @packet_len: (total) length of the OGM
605 * @send_time: timestamp (jiffies) when the packet is to be sent
606 * @direct_link: whether this OGM has direct link status
607 * @if_incoming: interface where the packet was received
608 * @if_outgoing: interface for which the retransmission should be considered
609 * @own_packet: true if it is a self-generated ogm
610 */
617static void batadv_iv_ogm_aggregate_new(const unsigned char *packet_buff, 611static void batadv_iv_ogm_aggregate_new(const unsigned char *packet_buff,
618 int packet_len, unsigned long send_time, 612 int packet_len, unsigned long send_time,
619 bool direct_link, 613 bool direct_link,
620 struct batadv_hard_iface *if_incoming, 614 struct batadv_hard_iface *if_incoming,
615 struct batadv_hard_iface *if_outgoing,
621 int own_packet) 616 int own_packet)
622{ 617{
623 struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface); 618 struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
@@ -628,6 +623,9 @@ static void batadv_iv_ogm_aggregate_new(const unsigned char *packet_buff,
628 if (!atomic_inc_not_zero(&if_incoming->refcount)) 623 if (!atomic_inc_not_zero(&if_incoming->refcount))
629 return; 624 return;
630 625
626 if (!atomic_inc_not_zero(&if_outgoing->refcount))
627 goto out_free_incoming;
628
631 /* own packet should always be scheduled */ 629 /* own packet should always be scheduled */
632 if (!own_packet) { 630 if (!own_packet) {
633 if (!batadv_atomic_dec_not_zero(&bat_priv->batman_queue_left)) { 631 if (!batadv_atomic_dec_not_zero(&bat_priv->batman_queue_left)) {
@@ -668,6 +666,7 @@ static void batadv_iv_ogm_aggregate_new(const unsigned char *packet_buff,
668 666
669 forw_packet_aggr->own = own_packet; 667 forw_packet_aggr->own = own_packet;
670 forw_packet_aggr->if_incoming = if_incoming; 668 forw_packet_aggr->if_incoming = if_incoming;
669 forw_packet_aggr->if_outgoing = if_outgoing;
671 forw_packet_aggr->num_packets = 0; 670 forw_packet_aggr->num_packets = 0;
672 forw_packet_aggr->direct_link_flags = BATADV_NO_FLAGS; 671 forw_packet_aggr->direct_link_flags = BATADV_NO_FLAGS;
673 forw_packet_aggr->send_time = send_time; 672 forw_packet_aggr->send_time = send_time;
@@ -690,6 +689,8 @@ static void batadv_iv_ogm_aggregate_new(const unsigned char *packet_buff,
690 689
691 return; 690 return;
692out: 691out:
692 batadv_hardif_free_ref(if_outgoing);
693out_free_incoming:
693 batadv_hardif_free_ref(if_incoming); 694 batadv_hardif_free_ref(if_incoming);
694} 695}
695 696
@@ -713,10 +714,21 @@ static void batadv_iv_ogm_aggregate(struct batadv_forw_packet *forw_packet_aggr,
713 } 714 }
714} 715}
715 716
717/**
718 * batadv_iv_ogm_queue_add - queue up an OGM for transmission
719 * @bat_priv: the bat priv with all the soft interface information
720 * @packet_buff: pointer to the OGM
721 * @packet_len: (total) length of the OGM
722 * @if_incoming: interface where the packet was received
723 * @if_outgoing: interface for which the retransmission should be considered
724 * @own_packet: true if it is a self-generated ogm
725 * @send_time: timestamp (jiffies) when the packet is to be sent
726 */
716static void batadv_iv_ogm_queue_add(struct batadv_priv *bat_priv, 727static void batadv_iv_ogm_queue_add(struct batadv_priv *bat_priv,
717 unsigned char *packet_buff, 728 unsigned char *packet_buff,
718 int packet_len, 729 int packet_len,
719 struct batadv_hard_iface *if_incoming, 730 struct batadv_hard_iface *if_incoming,
731 struct batadv_hard_iface *if_outgoing,
720 int own_packet, unsigned long send_time) 732 int own_packet, unsigned long send_time)
721{ 733{
722 /* _aggr -> pointer to the packet we want to aggregate with 734 /* _aggr -> pointer to the packet we want to aggregate with
@@ -742,6 +754,7 @@ static void batadv_iv_ogm_queue_add(struct batadv_priv *bat_priv,
742 bat_priv, packet_len, 754 bat_priv, packet_len,
743 send_time, direct_link, 755 send_time, direct_link,
744 if_incoming, 756 if_incoming,
757 if_outgoing,
745 forw_packet_pos)) { 758 forw_packet_pos)) {
746 forw_packet_aggr = forw_packet_pos; 759 forw_packet_aggr = forw_packet_pos;
747 break; 760 break;
@@ -765,7 +778,8 @@ static void batadv_iv_ogm_queue_add(struct batadv_priv *bat_priv,
765 778
766 batadv_iv_ogm_aggregate_new(packet_buff, packet_len, 779 batadv_iv_ogm_aggregate_new(packet_buff, packet_len,
767 send_time, direct_link, 780 send_time, direct_link,
768 if_incoming, own_packet); 781 if_incoming, if_outgoing,
782 own_packet);
769 } else { 783 } else {
770 batadv_iv_ogm_aggregate(forw_packet_aggr, packet_buff, 784 batadv_iv_ogm_aggregate(forw_packet_aggr, packet_buff,
771 packet_len, direct_link); 785 packet_len, direct_link);
@@ -778,7 +792,8 @@ static void batadv_iv_ogm_forward(struct batadv_orig_node *orig_node,
778 struct batadv_ogm_packet *batadv_ogm_packet, 792 struct batadv_ogm_packet *batadv_ogm_packet,
779 bool is_single_hop_neigh, 793 bool is_single_hop_neigh,
780 bool is_from_best_next_hop, 794 bool is_from_best_next_hop,
781 struct batadv_hard_iface *if_incoming) 795 struct batadv_hard_iface *if_incoming,
796 struct batadv_hard_iface *if_outgoing)
782{ 797{
783 struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface); 798 struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
784 uint16_t tvlv_len; 799 uint16_t tvlv_len;
@@ -823,7 +838,8 @@ static void batadv_iv_ogm_forward(struct batadv_orig_node *orig_node,
823 838
824 batadv_iv_ogm_queue_add(bat_priv, (unsigned char *)batadv_ogm_packet, 839 batadv_iv_ogm_queue_add(bat_priv, (unsigned char *)batadv_ogm_packet,
825 BATADV_OGM_HLEN + tvlv_len, 840 BATADV_OGM_HLEN + tvlv_len,
826 if_incoming, 0, batadv_iv_ogm_fwd_send_time()); 841 if_incoming, if_outgoing, 0,
842 batadv_iv_ogm_fwd_send_time());
827} 843}
828 844
829/** 845/**
@@ -868,10 +884,11 @@ static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
868 struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface); 884 struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
869 unsigned char **ogm_buff = &hard_iface->bat_iv.ogm_buff; 885 unsigned char **ogm_buff = &hard_iface->bat_iv.ogm_buff;
870 struct batadv_ogm_packet *batadv_ogm_packet; 886 struct batadv_ogm_packet *batadv_ogm_packet;
871 struct batadv_hard_iface *primary_if; 887 struct batadv_hard_iface *primary_if, *tmp_hard_iface;
872 int *ogm_buff_len = &hard_iface->bat_iv.ogm_buff_len; 888 int *ogm_buff_len = &hard_iface->bat_iv.ogm_buff_len;
873 uint32_t seqno; 889 uint32_t seqno;
874 uint16_t tvlv_len = 0; 890 uint16_t tvlv_len = 0;
891 unsigned long send_time;
875 892
876 primary_if = batadv_primary_if_get_selected(bat_priv); 893 primary_if = batadv_primary_if_get_selected(bat_priv);
877 894
@@ -894,10 +911,32 @@ static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
894 atomic_inc(&hard_iface->bat_iv.ogm_seqno); 911 atomic_inc(&hard_iface->bat_iv.ogm_seqno);
895 912
896 batadv_iv_ogm_slide_own_bcast_window(hard_iface); 913 batadv_iv_ogm_slide_own_bcast_window(hard_iface);
897 batadv_iv_ogm_queue_add(bat_priv, hard_iface->bat_iv.ogm_buff,
898 hard_iface->bat_iv.ogm_buff_len, hard_iface, 1,
899 batadv_iv_ogm_emit_send_time(bat_priv));
900 914
915 send_time = batadv_iv_ogm_emit_send_time(bat_priv);
916
917 if (hard_iface != primary_if) {
918 /* OGMs from secondary interfaces are only scheduled on their
919 * respective interfaces.
920 */
921 batadv_iv_ogm_queue_add(bat_priv, *ogm_buff, *ogm_buff_len,
922 hard_iface, hard_iface, 1, send_time);
923 goto out;
924 }
925
926 /* OGMs from primary interfaces are scheduled on all
927 * interfaces.
928 */
929 rcu_read_lock();
930 list_for_each_entry_rcu(tmp_hard_iface, &batadv_hardif_list, list) {
931 if (tmp_hard_iface->soft_iface != hard_iface->soft_iface)
932 continue;
933 batadv_iv_ogm_queue_add(bat_priv, *ogm_buff,
934 *ogm_buff_len, hard_iface,
935 tmp_hard_iface, 1, send_time);
936 }
937 rcu_read_unlock();
938
939out:
901 if (primary_if) 940 if (primary_if)
902 batadv_hardif_free_ref(primary_if); 941 batadv_hardif_free_ref(primary_if);
903} 942}
@@ -1446,6 +1485,10 @@ batadv_iv_ogm_process_per_outif(const struct sk_buff *skb, int ogm_offset,
1446 } 1485 }
1447 batadv_orig_ifinfo_free_ref(orig_ifinfo); 1486 batadv_orig_ifinfo_free_ref(orig_ifinfo);
1448 1487
1488 /* only forward for specific interface, not for the default one. */
1489 if (if_outgoing == BATADV_IF_DEFAULT)
1490 goto out_neigh;
1491
1449 /* is single hop (direct) neighbor */ 1492 /* is single hop (direct) neighbor */
1450 if (is_single_hop_neigh) { 1493 if (is_single_hop_neigh) {
1451 /* OGMs from secondary interfaces should only scheduled once 1494 /* OGMs from secondary interfaces should only scheduled once
@@ -1460,7 +1503,8 @@ batadv_iv_ogm_process_per_outif(const struct sk_buff *skb, int ogm_offset,
1460 /* mark direct link on incoming interface */ 1503 /* mark direct link on incoming interface */
1461 batadv_iv_ogm_forward(orig_node, ethhdr, ogm_packet, 1504 batadv_iv_ogm_forward(orig_node, ethhdr, ogm_packet,
1462 is_single_hop_neigh, 1505 is_single_hop_neigh,
1463 is_from_best_next_hop, if_incoming); 1506 is_from_best_next_hop, if_incoming,
1507 if_outgoing);
1464 1508
1465 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, 1509 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1466 "Forwarding packet: rebroadcast neighbor packet with direct link flag\n"); 1510 "Forwarding packet: rebroadcast neighbor packet with direct link flag\n");
@@ -1480,16 +1524,11 @@ batadv_iv_ogm_process_per_outif(const struct sk_buff *skb, int ogm_offset,
1480 goto out_neigh; 1524 goto out_neigh;
1481 } 1525 }
1482 1526
1483 /* only forward the packet on the default interface until the
1484 * OGM forwarding has been reworked to send on specific interfaces.
1485 */
1486 if (if_outgoing != BATADV_IF_DEFAULT)
1487 goto out_neigh;
1488 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, 1527 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1489 "Forwarding packet: rebroadcast originator packet\n"); 1528 "Forwarding packet: rebroadcast originator packet\n");
1490 batadv_iv_ogm_forward(orig_node, ethhdr, ogm_packet, 1529 batadv_iv_ogm_forward(orig_node, ethhdr, ogm_packet,
1491 is_single_hop_neigh, is_from_best_next_hop, 1530 is_single_hop_neigh, is_from_best_next_hop,
1492 if_incoming); 1531 if_incoming, if_outgoing);
1493 1532
1494out_neigh: 1533out_neigh:
1495 if ((orig_neigh_node) && (!is_single_hop_neigh)) 1534 if ((orig_neigh_node) && (!is_single_hop_neigh))
diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c
index 30d12c445ea3..c93b92df17cf 100644
--- a/net/batman-adv/send.c
+++ b/net/batman-adv/send.c
@@ -387,6 +387,8 @@ static void batadv_forw_packet_free(struct batadv_forw_packet *forw_packet)
387 kfree_skb(forw_packet->skb); 387 kfree_skb(forw_packet->skb);
388 if (forw_packet->if_incoming) 388 if (forw_packet->if_incoming)
389 batadv_hardif_free_ref(forw_packet->if_incoming); 389 batadv_hardif_free_ref(forw_packet->if_incoming);
390 if (forw_packet->if_outgoing)
391 batadv_hardif_free_ref(forw_packet->if_outgoing);
390 kfree(forw_packet); 392 kfree(forw_packet);
391} 393}
392 394
@@ -450,6 +452,7 @@ int batadv_add_bcast_packet_to_list(struct batadv_priv *bat_priv,
450 452
451 forw_packet->skb = newskb; 453 forw_packet->skb = newskb;
452 forw_packet->if_incoming = primary_if; 454 forw_packet->if_incoming = primary_if;
455 forw_packet->if_outgoing = NULL;
453 456
454 /* how often did we send the bcast packet ? */ 457 /* how often did we send the bcast packet ? */
455 forw_packet->num_packets = 0; 458 forw_packet->num_packets = 0;
@@ -545,11 +548,16 @@ void batadv_send_outstanding_bat_ogm_packet(struct work_struct *work)
545 548
546 bat_priv->bat_algo_ops->bat_ogm_emit(forw_packet); 549 bat_priv->bat_algo_ops->bat_ogm_emit(forw_packet);
547 550
548 /* we have to have at least one packet in the queue 551 /* we have to have at least one packet in the queue to determine the
549 * to determine the queues wake up time unless we are 552 * queues wake up time unless we are shutting down.
550 * shutting down 553 *
554 * only re-schedule if this is the "original" copy, e.g. the OGM of the
555 * primary interface should only be rescheduled once per period, but
556 * this function will be called for the forw_packet instances of the
557 * other secondary interfaces as well.
551 */ 558 */
552 if (forw_packet->own) 559 if (forw_packet->own &&
560 forw_packet->if_incoming == forw_packet->if_outgoing)
553 batadv_schedule_bat_ogm(forw_packet->if_incoming); 561 batadv_schedule_bat_ogm(forw_packet->if_incoming);
554 562
555out: 563out:
@@ -610,7 +618,8 @@ batadv_purge_outstanding_packets(struct batadv_priv *bat_priv,
610 * we delete only packets belonging to the given interface 618 * we delete only packets belonging to the given interface
611 */ 619 */
612 if ((hard_iface) && 620 if ((hard_iface) &&
613 (forw_packet->if_incoming != hard_iface)) 621 (forw_packet->if_incoming != hard_iface) &&
622 (forw_packet->if_outgoing != hard_iface))
614 continue; 623 continue;
615 624
616 spin_unlock_bh(&bat_priv->forw_bat_list_lock); 625 spin_unlock_bh(&bat_priv->forw_bat_list_lock);
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index d3e2bf486ec0..c317dfc932bf 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -1018,8 +1018,10 @@ struct batadv_skb_cb {
1018 * @direct_link_flags: direct link flags for aggregated OGM packets 1018 * @direct_link_flags: direct link flags for aggregated OGM packets
1019 * @num_packets: counter for bcast packet retransmission 1019 * @num_packets: counter for bcast packet retransmission
1020 * @delayed_work: work queue callback item for packet sending 1020 * @delayed_work: work queue callback item for packet sending
1021 * @if_incoming: pointer incoming hard-iface or primary iface if locally 1021 * @if_incoming: pointer to incoming hard-iface or primary iface if
1022 * generated packet 1022 * locally generated packet
1023 * @if_outgoing: packet where the packet should be sent to, or NULL if
1024 * unspecified
1023 */ 1025 */
1024struct batadv_forw_packet { 1026struct batadv_forw_packet {
1025 struct hlist_node list; 1027 struct hlist_node list;
@@ -1031,6 +1033,7 @@ struct batadv_forw_packet {
1031 uint8_t num_packets; 1033 uint8_t num_packets;
1032 struct delayed_work delayed_work; 1034 struct delayed_work delayed_work;
1033 struct batadv_hard_iface *if_incoming; 1035 struct batadv_hard_iface *if_incoming;
1036 struct batadv_hard_iface *if_outgoing;
1034}; 1037};
1035 1038
1036/** 1039/**