Commit c1f066d4ee0bde4bb0ff4ac295218b631729e0de
Merge tag 'batman-adv-for-davem' of git://git.open-mesh.org/linux-merge
Antonio Quartulli says: ==================== Included changes: - avoid integer overflow in GW selection routine - prevent race condition by making capability bit changes atomic (use clear/set/test_bit) - fix synchronization issue in mcast tvlv handler - fix crash on double list removal of TT Request objects - fix leak by puring packets enqueued for sending upon iface removal - ensure network header pointer is set in skb ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Showing 9 changed files Side-by-side Diff
net/batman-adv/distributed-arp-table.c
... | ... | @@ -19,6 +19,7 @@ |
19 | 19 | #include "main.h" |
20 | 20 | |
21 | 21 | #include <linux/atomic.h> |
22 | +#include <linux/bitops.h> | |
22 | 23 | #include <linux/byteorder/generic.h> |
23 | 24 | #include <linux/errno.h> |
24 | 25 | #include <linux/etherdevice.h> |
... | ... | @@ -453,7 +454,7 @@ |
453 | 454 | int j; |
454 | 455 | |
455 | 456 | /* check if orig node candidate is running DAT */ |
456 | - if (!(candidate->capabilities & BATADV_ORIG_CAPA_HAS_DAT)) | |
457 | + if (!test_bit(BATADV_ORIG_CAPA_HAS_DAT, &candidate->capabilities)) | |
457 | 458 | goto out; |
458 | 459 | |
459 | 460 | /* Check if this node has already been selected... */ |
460 | 461 | |
... | ... | @@ -713,9 +714,9 @@ |
713 | 714 | uint16_t tvlv_value_len) |
714 | 715 | { |
715 | 716 | if (flags & BATADV_TVLV_HANDLER_OGM_CIFNOTFND) |
716 | - orig->capabilities &= ~BATADV_ORIG_CAPA_HAS_DAT; | |
717 | + clear_bit(BATADV_ORIG_CAPA_HAS_DAT, &orig->capabilities); | |
717 | 718 | else |
718 | - orig->capabilities |= BATADV_ORIG_CAPA_HAS_DAT; | |
719 | + set_bit(BATADV_ORIG_CAPA_HAS_DAT, &orig->capabilities); | |
719 | 720 | } |
720 | 721 | |
721 | 722 | /** |
net/batman-adv/gateway_client.c
... | ... | @@ -153,15 +153,11 @@ |
153 | 153 | struct batadv_neigh_node *router; |
154 | 154 | struct batadv_neigh_ifinfo *router_ifinfo; |
155 | 155 | struct batadv_gw_node *gw_node, *curr_gw = NULL; |
156 | - uint32_t max_gw_factor = 0, tmp_gw_factor = 0; | |
157 | - uint32_t gw_divisor; | |
156 | + uint64_t max_gw_factor = 0, tmp_gw_factor = 0; | |
158 | 157 | uint8_t max_tq = 0; |
159 | 158 | uint8_t tq_avg; |
160 | 159 | struct batadv_orig_node *orig_node; |
161 | 160 | |
162 | - gw_divisor = BATADV_TQ_LOCAL_WINDOW_SIZE * BATADV_TQ_LOCAL_WINDOW_SIZE; | |
163 | - gw_divisor *= 64; | |
164 | - | |
165 | 161 | rcu_read_lock(); |
166 | 162 | hlist_for_each_entry_rcu(gw_node, &bat_priv->gw.list, list) { |
167 | 163 | if (gw_node->deleted) |
... | ... | @@ -187,7 +183,7 @@ |
187 | 183 | tmp_gw_factor = tq_avg * tq_avg; |
188 | 184 | tmp_gw_factor *= gw_node->bandwidth_down; |
189 | 185 | tmp_gw_factor *= 100 * 100; |
190 | - tmp_gw_factor /= gw_divisor; | |
186 | + tmp_gw_factor >>= 18; | |
191 | 187 | |
192 | 188 | if ((tmp_gw_factor > max_gw_factor) || |
193 | 189 | ((tmp_gw_factor == max_gw_factor) && |
net/batman-adv/multicast.c
... | ... | @@ -19,6 +19,8 @@ |
19 | 19 | #include "main.h" |
20 | 20 | |
21 | 21 | #include <linux/atomic.h> |
22 | +#include <linux/bitops.h> | |
23 | +#include <linux/bug.h> | |
22 | 24 | #include <linux/byteorder/generic.h> |
23 | 25 | #include <linux/errno.h> |
24 | 26 | #include <linux/etherdevice.h> |
25 | 27 | |
26 | 28 | |
... | ... | @@ -588,19 +590,26 @@ |
588 | 590 | * |
589 | 591 | * If the BATADV_MCAST_WANT_ALL_UNSNOOPABLES flag of this originator, |
590 | 592 | * orig, has toggled then this method updates counter and list accordingly. |
593 | + * | |
594 | + * Caller needs to hold orig->mcast_handler_lock. | |
591 | 595 | */ |
592 | 596 | static void batadv_mcast_want_unsnoop_update(struct batadv_priv *bat_priv, |
593 | 597 | struct batadv_orig_node *orig, |
594 | 598 | uint8_t mcast_flags) |
595 | 599 | { |
600 | + struct hlist_node *node = &orig->mcast_want_all_unsnoopables_node; | |
601 | + struct hlist_head *head = &bat_priv->mcast.want_all_unsnoopables_list; | |
602 | + | |
596 | 603 | /* switched from flag unset to set */ |
597 | 604 | if (mcast_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES && |
598 | 605 | !(orig->mcast_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES)) { |
599 | 606 | atomic_inc(&bat_priv->mcast.num_want_all_unsnoopables); |
600 | 607 | |
601 | 608 | spin_lock_bh(&bat_priv->mcast.want_lists_lock); |
602 | - hlist_add_head_rcu(&orig->mcast_want_all_unsnoopables_node, | |
603 | - &bat_priv->mcast.want_all_unsnoopables_list); | |
609 | + /* flag checks above + mcast_handler_lock prevents this */ | |
610 | + WARN_ON(!hlist_unhashed(node)); | |
611 | + | |
612 | + hlist_add_head_rcu(node, head); | |
604 | 613 | spin_unlock_bh(&bat_priv->mcast.want_lists_lock); |
605 | 614 | /* switched from flag set to unset */ |
606 | 615 | } else if (!(mcast_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES) && |
... | ... | @@ -608,7 +617,10 @@ |
608 | 617 | atomic_dec(&bat_priv->mcast.num_want_all_unsnoopables); |
609 | 618 | |
610 | 619 | spin_lock_bh(&bat_priv->mcast.want_lists_lock); |
611 | - hlist_del_rcu(&orig->mcast_want_all_unsnoopables_node); | |
620 | + /* flag checks above + mcast_handler_lock prevents this */ | |
621 | + WARN_ON(hlist_unhashed(node)); | |
622 | + | |
623 | + hlist_del_init_rcu(node); | |
612 | 624 | spin_unlock_bh(&bat_priv->mcast.want_lists_lock); |
613 | 625 | } |
614 | 626 | } |
615 | 627 | |
616 | 628 | |
... | ... | @@ -621,19 +633,26 @@ |
621 | 633 | * |
622 | 634 | * If the BATADV_MCAST_WANT_ALL_IPV4 flag of this originator, orig, has |
623 | 635 | * toggled then this method updates counter and list accordingly. |
636 | + * | |
637 | + * Caller needs to hold orig->mcast_handler_lock. | |
624 | 638 | */ |
625 | 639 | static void batadv_mcast_want_ipv4_update(struct batadv_priv *bat_priv, |
626 | 640 | struct batadv_orig_node *orig, |
627 | 641 | uint8_t mcast_flags) |
628 | 642 | { |
643 | + struct hlist_node *node = &orig->mcast_want_all_ipv4_node; | |
644 | + struct hlist_head *head = &bat_priv->mcast.want_all_ipv4_list; | |
645 | + | |
629 | 646 | /* switched from flag unset to set */ |
630 | 647 | if (mcast_flags & BATADV_MCAST_WANT_ALL_IPV4 && |
631 | 648 | !(orig->mcast_flags & BATADV_MCAST_WANT_ALL_IPV4)) { |
632 | 649 | atomic_inc(&bat_priv->mcast.num_want_all_ipv4); |
633 | 650 | |
634 | 651 | spin_lock_bh(&bat_priv->mcast.want_lists_lock); |
635 | - hlist_add_head_rcu(&orig->mcast_want_all_ipv4_node, | |
636 | - &bat_priv->mcast.want_all_ipv4_list); | |
652 | + /* flag checks above + mcast_handler_lock prevents this */ | |
653 | + WARN_ON(!hlist_unhashed(node)); | |
654 | + | |
655 | + hlist_add_head_rcu(node, head); | |
637 | 656 | spin_unlock_bh(&bat_priv->mcast.want_lists_lock); |
638 | 657 | /* switched from flag set to unset */ |
639 | 658 | } else if (!(mcast_flags & BATADV_MCAST_WANT_ALL_IPV4) && |
... | ... | @@ -641,7 +660,10 @@ |
641 | 660 | atomic_dec(&bat_priv->mcast.num_want_all_ipv4); |
642 | 661 | |
643 | 662 | spin_lock_bh(&bat_priv->mcast.want_lists_lock); |
644 | - hlist_del_rcu(&orig->mcast_want_all_ipv4_node); | |
663 | + /* flag checks above + mcast_handler_lock prevents this */ | |
664 | + WARN_ON(hlist_unhashed(node)); | |
665 | + | |
666 | + hlist_del_init_rcu(node); | |
645 | 667 | spin_unlock_bh(&bat_priv->mcast.want_lists_lock); |
646 | 668 | } |
647 | 669 | } |
648 | 670 | |
649 | 671 | |
... | ... | @@ -654,19 +676,26 @@ |
654 | 676 | * |
655 | 677 | * If the BATADV_MCAST_WANT_ALL_IPV6 flag of this originator, orig, has |
656 | 678 | * toggled then this method updates counter and list accordingly. |
679 | + * | |
680 | + * Caller needs to hold orig->mcast_handler_lock. | |
657 | 681 | */ |
658 | 682 | static void batadv_mcast_want_ipv6_update(struct batadv_priv *bat_priv, |
659 | 683 | struct batadv_orig_node *orig, |
660 | 684 | uint8_t mcast_flags) |
661 | 685 | { |
686 | + struct hlist_node *node = &orig->mcast_want_all_ipv6_node; | |
687 | + struct hlist_head *head = &bat_priv->mcast.want_all_ipv6_list; | |
688 | + | |
662 | 689 | /* switched from flag unset to set */ |
663 | 690 | if (mcast_flags & BATADV_MCAST_WANT_ALL_IPV6 && |
664 | 691 | !(orig->mcast_flags & BATADV_MCAST_WANT_ALL_IPV6)) { |
665 | 692 | atomic_inc(&bat_priv->mcast.num_want_all_ipv6); |
666 | 693 | |
667 | 694 | spin_lock_bh(&bat_priv->mcast.want_lists_lock); |
668 | - hlist_add_head_rcu(&orig->mcast_want_all_ipv6_node, | |
669 | - &bat_priv->mcast.want_all_ipv6_list); | |
695 | + /* flag checks above + mcast_handler_lock prevents this */ | |
696 | + WARN_ON(!hlist_unhashed(node)); | |
697 | + | |
698 | + hlist_add_head_rcu(node, head); | |
670 | 699 | spin_unlock_bh(&bat_priv->mcast.want_lists_lock); |
671 | 700 | /* switched from flag set to unset */ |
672 | 701 | } else if (!(mcast_flags & BATADV_MCAST_WANT_ALL_IPV6) && |
... | ... | @@ -674,7 +703,10 @@ |
674 | 703 | atomic_dec(&bat_priv->mcast.num_want_all_ipv6); |
675 | 704 | |
676 | 705 | spin_lock_bh(&bat_priv->mcast.want_lists_lock); |
677 | - hlist_del_rcu(&orig->mcast_want_all_ipv6_node); | |
706 | + /* flag checks above + mcast_handler_lock prevents this */ | |
707 | + WARN_ON(hlist_unhashed(node)); | |
708 | + | |
709 | + hlist_del_init_rcu(node); | |
678 | 710 | spin_unlock_bh(&bat_priv->mcast.want_lists_lock); |
679 | 711 | } |
680 | 712 | } |
681 | 713 | |
682 | 714 | |
683 | 715 | |
684 | 716 | |
685 | 717 | |
686 | 718 | |
687 | 719 | |
688 | 720 | |
... | ... | @@ -697,39 +729,42 @@ |
697 | 729 | uint8_t mcast_flags = BATADV_NO_FLAGS; |
698 | 730 | bool orig_initialized; |
699 | 731 | |
700 | - orig_initialized = orig->capa_initialized & BATADV_ORIG_CAPA_HAS_MCAST; | |
732 | + if (orig_mcast_enabled && tvlv_value && | |
733 | + (tvlv_value_len >= sizeof(mcast_flags))) | |
734 | + mcast_flags = *(uint8_t *)tvlv_value; | |
701 | 735 | |
736 | + spin_lock_bh(&orig->mcast_handler_lock); | |
737 | + orig_initialized = test_bit(BATADV_ORIG_CAPA_HAS_MCAST, | |
738 | + &orig->capa_initialized); | |
739 | + | |
702 | 740 | /* If mcast support is turned on decrease the disabled mcast node |
703 | 741 | * counter only if we had increased it for this node before. If this |
704 | 742 | * is a completely new orig_node no need to decrease the counter. |
705 | 743 | */ |
706 | 744 | if (orig_mcast_enabled && |
707 | - !(orig->capabilities & BATADV_ORIG_CAPA_HAS_MCAST)) { | |
745 | + !test_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capabilities)) { | |
708 | 746 | if (orig_initialized) |
709 | 747 | atomic_dec(&bat_priv->mcast.num_disabled); |
710 | - orig->capabilities |= BATADV_ORIG_CAPA_HAS_MCAST; | |
748 | + set_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capabilities); | |
711 | 749 | /* If mcast support is being switched off or if this is an initial |
712 | 750 | * OGM without mcast support then increase the disabled mcast |
713 | 751 | * node counter. |
714 | 752 | */ |
715 | 753 | } else if (!orig_mcast_enabled && |
716 | - (orig->capabilities & BATADV_ORIG_CAPA_HAS_MCAST || | |
754 | + (test_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capabilities) || | |
717 | 755 | !orig_initialized)) { |
718 | 756 | atomic_inc(&bat_priv->mcast.num_disabled); |
719 | - orig->capabilities &= ~BATADV_ORIG_CAPA_HAS_MCAST; | |
757 | + clear_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capabilities); | |
720 | 758 | } |
721 | 759 | |
722 | - orig->capa_initialized |= BATADV_ORIG_CAPA_HAS_MCAST; | |
760 | + set_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capa_initialized); | |
723 | 761 | |
724 | - if (orig_mcast_enabled && tvlv_value && | |
725 | - (tvlv_value_len >= sizeof(mcast_flags))) | |
726 | - mcast_flags = *(uint8_t *)tvlv_value; | |
727 | - | |
728 | 762 | batadv_mcast_want_unsnoop_update(bat_priv, orig, mcast_flags); |
729 | 763 | batadv_mcast_want_ipv4_update(bat_priv, orig, mcast_flags); |
730 | 764 | batadv_mcast_want_ipv6_update(bat_priv, orig, mcast_flags); |
731 | 765 | |
732 | 766 | orig->mcast_flags = mcast_flags; |
767 | + spin_unlock_bh(&orig->mcast_handler_lock); | |
733 | 768 | } |
734 | 769 | |
735 | 770 | /** |
736 | 771 | |
... | ... | @@ -763,12 +798,16 @@ |
763 | 798 | { |
764 | 799 | struct batadv_priv *bat_priv = orig->bat_priv; |
765 | 800 | |
766 | - if (!(orig->capabilities & BATADV_ORIG_CAPA_HAS_MCAST) && | |
767 | - orig->capa_initialized & BATADV_ORIG_CAPA_HAS_MCAST) | |
801 | + spin_lock_bh(&orig->mcast_handler_lock); | |
802 | + | |
803 | + if (!test_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capabilities) && | |
804 | + test_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capa_initialized)) | |
768 | 805 | atomic_dec(&bat_priv->mcast.num_disabled); |
769 | 806 | |
770 | 807 | batadv_mcast_want_unsnoop_update(bat_priv, orig, BATADV_NO_FLAGS); |
771 | 808 | batadv_mcast_want_ipv4_update(bat_priv, orig, BATADV_NO_FLAGS); |
772 | 809 | batadv_mcast_want_ipv6_update(bat_priv, orig, BATADV_NO_FLAGS); |
810 | + | |
811 | + spin_unlock_bh(&orig->mcast_handler_lock); | |
773 | 812 | } |
net/batman-adv/network-coding.c
... | ... | @@ -19,6 +19,7 @@ |
19 | 19 | #include "main.h" |
20 | 20 | |
21 | 21 | #include <linux/atomic.h> |
22 | +#include <linux/bitops.h> | |
22 | 23 | #include <linux/byteorder/generic.h> |
23 | 24 | #include <linux/compiler.h> |
24 | 25 | #include <linux/debugfs.h> |
25 | 26 | |
... | ... | @@ -134,9 +135,9 @@ |
134 | 135 | uint16_t tvlv_value_len) |
135 | 136 | { |
136 | 137 | if (flags & BATADV_TVLV_HANDLER_OGM_CIFNOTFND) |
137 | - orig->capabilities &= ~BATADV_ORIG_CAPA_HAS_NC; | |
138 | + clear_bit(BATADV_ORIG_CAPA_HAS_NC, &orig->capabilities); | |
138 | 139 | else |
139 | - orig->capabilities |= BATADV_ORIG_CAPA_HAS_NC; | |
140 | + set_bit(BATADV_ORIG_CAPA_HAS_NC, &orig->capabilities); | |
140 | 141 | } |
141 | 142 | |
142 | 143 | /** |
... | ... | @@ -894,7 +895,7 @@ |
894 | 895 | goto out; |
895 | 896 | |
896 | 897 | /* check if orig node is network coding enabled */ |
897 | - if (!(orig_node->capabilities & BATADV_ORIG_CAPA_HAS_NC)) | |
898 | + if (!test_bit(BATADV_ORIG_CAPA_HAS_NC, &orig_node->capabilities)) | |
898 | 899 | goto out; |
899 | 900 | |
900 | 901 | /* accept ogms from 'good' neighbors and single hop neighbors */ |
net/batman-adv/originator.c
... | ... | @@ -696,8 +696,13 @@ |
696 | 696 | orig_node->last_seen = jiffies; |
697 | 697 | reset_time = jiffies - 1 - msecs_to_jiffies(BATADV_RESET_PROTECTION_MS); |
698 | 698 | orig_node->bcast_seqno_reset = reset_time; |
699 | + | |
699 | 700 | #ifdef CONFIG_BATMAN_ADV_MCAST |
700 | 701 | orig_node->mcast_flags = BATADV_NO_FLAGS; |
702 | + INIT_HLIST_NODE(&orig_node->mcast_want_all_unsnoopables_node); | |
703 | + INIT_HLIST_NODE(&orig_node->mcast_want_all_ipv4_node); | |
704 | + INIT_HLIST_NODE(&orig_node->mcast_want_all_ipv6_node); | |
705 | + spin_lock_init(&orig_node->mcast_handler_lock); | |
701 | 706 | #endif |
702 | 707 | |
703 | 708 | /* create a vlan object for the "untagged" LAN */ |
net/batman-adv/send.c
... | ... | @@ -616,7 +616,8 @@ |
616 | 616 | * we delete only packets belonging to the given interface |
617 | 617 | */ |
618 | 618 | if ((hard_iface) && |
619 | - (forw_packet->if_incoming != hard_iface)) | |
619 | + (forw_packet->if_incoming != hard_iface) && | |
620 | + (forw_packet->if_outgoing != hard_iface)) | |
620 | 621 | continue; |
621 | 622 | |
622 | 623 | spin_unlock_bh(&bat_priv->forw_bcast_list_lock); |
net/batman-adv/soft-interface.c
... | ... | @@ -202,6 +202,7 @@ |
202 | 202 | int gw_mode; |
203 | 203 | enum batadv_forw_mode forw_mode; |
204 | 204 | struct batadv_orig_node *mcast_single_orig = NULL; |
205 | + int network_offset = ETH_HLEN; | |
205 | 206 | |
206 | 207 | if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE) |
207 | 208 | goto dropped; |
208 | 209 | |
209 | 210 | |
... | ... | @@ -214,13 +215,17 @@ |
214 | 215 | case ETH_P_8021Q: |
215 | 216 | vhdr = vlan_eth_hdr(skb); |
216 | 217 | |
217 | - if (vhdr->h_vlan_encapsulated_proto != ethertype) | |
218 | + if (vhdr->h_vlan_encapsulated_proto != ethertype) { | |
219 | + network_offset += VLAN_HLEN; | |
218 | 220 | break; |
221 | + } | |
219 | 222 | |
220 | 223 | /* fall through */ |
221 | 224 | case ETH_P_BATMAN: |
222 | 225 | goto dropped; |
223 | 226 | } |
227 | + | |
228 | + skb_set_network_header(skb, network_offset); | |
224 | 229 | |
225 | 230 | if (batadv_bla_tx(bat_priv, skb, vid)) |
226 | 231 | goto dropped; |
net/batman-adv/translation-table.c
... | ... | @@ -19,6 +19,7 @@ |
19 | 19 | #include "main.h" |
20 | 20 | |
21 | 21 | #include <linux/atomic.h> |
22 | +#include <linux/bitops.h> | |
22 | 23 | #include <linux/bug.h> |
23 | 24 | #include <linux/byteorder/generic.h> |
24 | 25 | #include <linux/compiler.h> |
... | ... | @@ -1879,7 +1880,7 @@ |
1879 | 1880 | } |
1880 | 1881 | spin_unlock_bh(list_lock); |
1881 | 1882 | } |
1882 | - orig_node->capa_initialized &= ~BATADV_ORIG_CAPA_HAS_TT; | |
1883 | + clear_bit(BATADV_ORIG_CAPA_HAS_TT, &orig_node->capa_initialized); | |
1883 | 1884 | } |
1884 | 1885 | |
1885 | 1886 | static bool batadv_tt_global_to_purge(struct batadv_tt_global_entry *tt_global, |
... | ... | @@ -2212,7 +2213,7 @@ |
2212 | 2213 | spin_lock_bh(&bat_priv->tt.req_list_lock); |
2213 | 2214 | |
2214 | 2215 | list_for_each_entry_safe(node, safe, &bat_priv->tt.req_list, list) { |
2215 | - list_del(&node->list); | |
2216 | + list_del_init(&node->list); | |
2216 | 2217 | kfree(node); |
2217 | 2218 | } |
2218 | 2219 | |
... | ... | @@ -2248,7 +2249,7 @@ |
2248 | 2249 | list_for_each_entry_safe(node, safe, &bat_priv->tt.req_list, list) { |
2249 | 2250 | if (batadv_has_timed_out(node->issued_at, |
2250 | 2251 | BATADV_TT_REQUEST_TIMEOUT)) { |
2251 | - list_del(&node->list); | |
2252 | + list_del_init(&node->list); | |
2252 | 2253 | kfree(node); |
2253 | 2254 | } |
2254 | 2255 | } |
... | ... | @@ -2530,7 +2531,8 @@ |
2530 | 2531 | batadv_hardif_free_ref(primary_if); |
2531 | 2532 | if (ret && tt_req_node) { |
2532 | 2533 | spin_lock_bh(&bat_priv->tt.req_list_lock); |
2533 | - list_del(&tt_req_node->list); | |
2534 | + /* list_del_init() verifies tt_req_node still is in the list */ | |
2535 | + list_del_init(&tt_req_node->list); | |
2534 | 2536 | spin_unlock_bh(&bat_priv->tt.req_list_lock); |
2535 | 2537 | kfree(tt_req_node); |
2536 | 2538 | } |
... | ... | @@ -2838,7 +2840,7 @@ |
2838 | 2840 | return; |
2839 | 2841 | } |
2840 | 2842 | } |
2841 | - orig_node->capa_initialized |= BATADV_ORIG_CAPA_HAS_TT; | |
2843 | + set_bit(BATADV_ORIG_CAPA_HAS_TT, &orig_node->capa_initialized); | |
2842 | 2844 | } |
2843 | 2845 | |
2844 | 2846 | static void batadv_tt_fill_gtable(struct batadv_priv *bat_priv, |
... | ... | @@ -2967,7 +2969,7 @@ |
2967 | 2969 | list_for_each_entry_safe(node, safe, &bat_priv->tt.req_list, list) { |
2968 | 2970 | if (!batadv_compare_eth(node->addr, resp_src)) |
2969 | 2971 | continue; |
2970 | - list_del(&node->list); | |
2972 | + list_del_init(&node->list); | |
2971 | 2973 | kfree(node); |
2972 | 2974 | } |
2973 | 2975 | |
... | ... | @@ -3340,7 +3342,8 @@ |
3340 | 3342 | bool has_tt_init; |
3341 | 3343 | |
3342 | 3344 | tt_vlan = (struct batadv_tvlv_tt_vlan_data *)tt_buff; |
3343 | - has_tt_init = orig_node->capa_initialized & BATADV_ORIG_CAPA_HAS_TT; | |
3345 | + has_tt_init = test_bit(BATADV_ORIG_CAPA_HAS_TT, | |
3346 | + &orig_node->capa_initialized); | |
3344 | 3347 | |
3345 | 3348 | /* orig table not initialised AND first diff is in the OGM OR the ttvn |
3346 | 3349 | * increased by one -> we can apply the attached changes |
net/batman-adv/types.h
... | ... | @@ -221,6 +221,7 @@ |
221 | 221 | * @batadv_dat_addr_t: address of the orig node in the distributed hash |
222 | 222 | * @last_seen: time when last packet from this node was received |
223 | 223 | * @bcast_seqno_reset: time when the broadcast seqno window was reset |
224 | + * @mcast_handler_lock: synchronizes mcast-capability and -flag changes | |
224 | 225 | * @mcast_flags: multicast flags announced by the orig node |
225 | 226 | * @mcast_want_all_unsnoop_node: a list node for the |
226 | 227 | * mcast.want_all_unsnoopables list |
227 | 228 | |
... | ... | @@ -268,13 +269,15 @@ |
268 | 269 | unsigned long last_seen; |
269 | 270 | unsigned long bcast_seqno_reset; |
270 | 271 | #ifdef CONFIG_BATMAN_ADV_MCAST |
272 | + /* synchronizes mcast tvlv specific orig changes */ | |
273 | + spinlock_t mcast_handler_lock; | |
271 | 274 | uint8_t mcast_flags; |
272 | 275 | struct hlist_node mcast_want_all_unsnoopables_node; |
273 | 276 | struct hlist_node mcast_want_all_ipv4_node; |
274 | 277 | struct hlist_node mcast_want_all_ipv6_node; |
275 | 278 | #endif |
276 | - uint8_t capabilities; | |
277 | - uint8_t capa_initialized; | |
279 | + unsigned long capabilities; | |
280 | + unsigned long capa_initialized; | |
278 | 281 | atomic_t last_ttvn; |
279 | 282 | unsigned char *tt_buff; |
280 | 283 | int16_t tt_buff_len; |
... | ... | @@ -313,10 +316,10 @@ |
313 | 316 | * (= orig node announces a tvlv of type BATADV_TVLV_MCAST) |
314 | 317 | */ |
315 | 318 | enum batadv_orig_capabilities { |
316 | - BATADV_ORIG_CAPA_HAS_DAT = BIT(0), | |
317 | - BATADV_ORIG_CAPA_HAS_NC = BIT(1), | |
318 | - BATADV_ORIG_CAPA_HAS_TT = BIT(2), | |
319 | - BATADV_ORIG_CAPA_HAS_MCAST = BIT(3), | |
319 | + BATADV_ORIG_CAPA_HAS_DAT, | |
320 | + BATADV_ORIG_CAPA_HAS_NC, | |
321 | + BATADV_ORIG_CAPA_HAS_TT, | |
322 | + BATADV_ORIG_CAPA_HAS_MCAST, | |
320 | 323 | }; |
321 | 324 | |
322 | 325 | /** |