diff options
author | David S. Miller <davem@davemloft.net> | 2016-05-10 23:36:14 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-05-10 23:36:14 -0400 |
commit | cf88585b1d5ce49515aabb381812976e2840a967 (patch) | |
tree | e878f445261d1d28c53660c580d3d6d47aac565e /net | |
parent | 953abb3823633385b1235add9c30c3e775dee0bc (diff) | |
parent | 676970e55b1033af7f0a03d4037b4d9b76327ded (diff) |
Merge tag 'batman-adv-for-davem' of git://git.open-mesh.org/linux-merge
Antonio Quartulli says:
====================
Included changes:
- remove useless skb size check in batadv_interface_rx
- basic netns support introduced by Andrew Lunn:
- prevent virtual interface from changing netns by setting
NETIF_F_NETNS_LOCAL
- create virtual interface within the netns of the first
hard-interface
- introduce detection of complex bridge loops and report event
to the user (via udev) when the Bridge Loop Avoidance mechanism
can't prevent them
- minor reference counting bugfixes for the hard_iface object that
couldn't make it via the net tree
- use kref_get() instead of kref_get_unless_zero() to make reference
counting bug more visible
- use batadv_compare_eth() all over the code when possible instead of
plain memcmp()
- minor code cleanup and style adjustments
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
26 files changed, 465 insertions, 295 deletions
diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index 8c1710bba803..7f98a9d39883 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c | |||
@@ -681,18 +681,12 @@ static void batadv_iv_ogm_aggregate_new(const unsigned char *packet_buff, | |||
681 | unsigned char *skb_buff; | 681 | unsigned char *skb_buff; |
682 | unsigned int skb_size; | 682 | unsigned int skb_size; |
683 | 683 | ||
684 | if (!kref_get_unless_zero(&if_incoming->refcount)) | ||
685 | return; | ||
686 | |||
687 | if (!kref_get_unless_zero(&if_outgoing->refcount)) | ||
688 | goto out_free_incoming; | ||
689 | |||
690 | /* own packet should always be scheduled */ | 684 | /* own packet should always be scheduled */ |
691 | if (!own_packet) { | 685 | if (!own_packet) { |
692 | if (!batadv_atomic_dec_not_zero(&bat_priv->batman_queue_left)) { | 686 | if (!batadv_atomic_dec_not_zero(&bat_priv->batman_queue_left)) { |
693 | batadv_dbg(BATADV_DBG_BATMAN, bat_priv, | 687 | batadv_dbg(BATADV_DBG_BATMAN, bat_priv, |
694 | "batman packet queue full\n"); | 688 | "batman packet queue full\n"); |
695 | goto out_free_outgoing; | 689 | return; |
696 | } | 690 | } |
697 | } | 691 | } |
698 | 692 | ||
@@ -718,6 +712,8 @@ static void batadv_iv_ogm_aggregate_new(const unsigned char *packet_buff, | |||
718 | forw_packet_aggr->packet_len = packet_len; | 712 | forw_packet_aggr->packet_len = packet_len; |
719 | memcpy(skb_buff, packet_buff, packet_len); | 713 | memcpy(skb_buff, packet_buff, packet_len); |
720 | 714 | ||
715 | kref_get(&if_incoming->refcount); | ||
716 | kref_get(&if_outgoing->refcount); | ||
721 | forw_packet_aggr->own = own_packet; | 717 | forw_packet_aggr->own = own_packet; |
722 | forw_packet_aggr->if_incoming = if_incoming; | 718 | forw_packet_aggr->if_incoming = if_incoming; |
723 | forw_packet_aggr->if_outgoing = if_outgoing; | 719 | forw_packet_aggr->if_outgoing = if_outgoing; |
@@ -747,10 +743,6 @@ out_free_forw_packet: | |||
747 | out_nomem: | 743 | out_nomem: |
748 | if (!own_packet) | 744 | if (!own_packet) |
749 | atomic_inc(&bat_priv->batman_queue_left); | 745 | atomic_inc(&bat_priv->batman_queue_left); |
750 | out_free_outgoing: | ||
751 | batadv_hardif_put(if_outgoing); | ||
752 | out_free_incoming: | ||
753 | batadv_hardif_put(if_incoming); | ||
754 | } | 746 | } |
755 | 747 | ||
756 | /* aggregate a new packet into the existing ogm packet */ | 748 | /* aggregate a new packet into the existing ogm packet */ |
@@ -987,9 +979,15 @@ static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface) | |||
987 | list_for_each_entry_rcu(tmp_hard_iface, &batadv_hardif_list, list) { | 979 | list_for_each_entry_rcu(tmp_hard_iface, &batadv_hardif_list, list) { |
988 | if (tmp_hard_iface->soft_iface != hard_iface->soft_iface) | 980 | if (tmp_hard_iface->soft_iface != hard_iface->soft_iface) |
989 | continue; | 981 | continue; |
982 | |||
983 | if (!kref_get_unless_zero(&tmp_hard_iface->refcount)) | ||
984 | continue; | ||
985 | |||
990 | batadv_iv_ogm_queue_add(bat_priv, *ogm_buff, | 986 | batadv_iv_ogm_queue_add(bat_priv, *ogm_buff, |
991 | *ogm_buff_len, hard_iface, | 987 | *ogm_buff_len, hard_iface, |
992 | tmp_hard_iface, 1, send_time); | 988 | tmp_hard_iface, 1, send_time); |
989 | |||
990 | batadv_hardif_put(tmp_hard_iface); | ||
993 | } | 991 | } |
994 | rcu_read_unlock(); | 992 | rcu_read_unlock(); |
995 | 993 | ||
@@ -1170,13 +1168,13 @@ out: | |||
1170 | * @if_incoming: interface where the packet was received | 1168 | * @if_incoming: interface where the packet was received |
1171 | * @if_outgoing: interface for which the retransmission should be considered | 1169 | * @if_outgoing: interface for which the retransmission should be considered |
1172 | * | 1170 | * |
1173 | * Return: 1 if the link can be considered bidirectional, 0 otherwise | 1171 | * Return: true if the link can be considered bidirectional, false otherwise |
1174 | */ | 1172 | */ |
1175 | static int batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node, | 1173 | static bool batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node, |
1176 | struct batadv_orig_node *orig_neigh_node, | 1174 | struct batadv_orig_node *orig_neigh_node, |
1177 | struct batadv_ogm_packet *batadv_ogm_packet, | 1175 | struct batadv_ogm_packet *batadv_ogm_packet, |
1178 | struct batadv_hard_iface *if_incoming, | 1176 | struct batadv_hard_iface *if_incoming, |
1179 | struct batadv_hard_iface *if_outgoing) | 1177 | struct batadv_hard_iface *if_outgoing) |
1180 | { | 1178 | { |
1181 | struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface); | 1179 | struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface); |
1182 | struct batadv_neigh_node *neigh_node = NULL, *tmp_neigh_node; | 1180 | struct batadv_neigh_node *neigh_node = NULL, *tmp_neigh_node; |
@@ -1184,9 +1182,10 @@ static int batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node, | |||
1184 | u8 total_count; | 1182 | u8 total_count; |
1185 | u8 orig_eq_count, neigh_rq_count, neigh_rq_inv, tq_own; | 1183 | u8 orig_eq_count, neigh_rq_count, neigh_rq_inv, tq_own; |
1186 | unsigned int neigh_rq_inv_cube, neigh_rq_max_cube; | 1184 | unsigned int neigh_rq_inv_cube, neigh_rq_max_cube; |
1187 | int tq_asym_penalty, inv_asym_penalty, if_num, ret = 0; | 1185 | int tq_asym_penalty, inv_asym_penalty, if_num; |
1188 | unsigned int combined_tq; | 1186 | unsigned int combined_tq; |
1189 | int tq_iface_penalty; | 1187 | int tq_iface_penalty; |
1188 | bool ret = false; | ||
1190 | 1189 | ||
1191 | /* find corresponding one hop neighbor */ | 1190 | /* find corresponding one hop neighbor */ |
1192 | rcu_read_lock(); | 1191 | rcu_read_lock(); |
@@ -1298,7 +1297,7 @@ static int batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node, | |||
1298 | * consider it bidirectional | 1297 | * consider it bidirectional |
1299 | */ | 1298 | */ |
1300 | if (batadv_ogm_packet->tq >= BATADV_TQ_TOTAL_BIDRECT_LIMIT) | 1299 | if (batadv_ogm_packet->tq >= BATADV_TQ_TOTAL_BIDRECT_LIMIT) |
1301 | ret = 1; | 1300 | ret = true; |
1302 | 1301 | ||
1303 | out: | 1302 | out: |
1304 | if (neigh_node) | 1303 | if (neigh_node) |
@@ -1327,9 +1326,9 @@ batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr, | |||
1327 | struct batadv_orig_ifinfo *orig_ifinfo = NULL; | 1326 | struct batadv_orig_ifinfo *orig_ifinfo = NULL; |
1328 | struct batadv_neigh_node *neigh_node; | 1327 | struct batadv_neigh_node *neigh_node; |
1329 | struct batadv_neigh_ifinfo *neigh_ifinfo; | 1328 | struct batadv_neigh_ifinfo *neigh_ifinfo; |
1330 | int is_dup; | 1329 | bool is_dup; |
1331 | s32 seq_diff; | 1330 | s32 seq_diff; |
1332 | int need_update = 0; | 1331 | bool need_update = false; |
1333 | int set_mark; | 1332 | int set_mark; |
1334 | enum batadv_dup_status ret = BATADV_NO_DUP; | 1333 | enum batadv_dup_status ret = BATADV_NO_DUP; |
1335 | u32 seqno = ntohl(batadv_ogm_packet->seqno); | 1334 | u32 seqno = ntohl(batadv_ogm_packet->seqno); |
@@ -1439,7 +1438,7 @@ batadv_iv_ogm_process_per_outif(const struct sk_buff *skb, int ogm_offset, | |||
1439 | struct sk_buff *skb_priv; | 1438 | struct sk_buff *skb_priv; |
1440 | struct ethhdr *ethhdr; | 1439 | struct ethhdr *ethhdr; |
1441 | u8 *prev_sender; | 1440 | u8 *prev_sender; |
1442 | int is_bidirect; | 1441 | bool is_bidirect; |
1443 | 1442 | ||
1444 | /* create a private copy of the skb, as some functions change tq value | 1443 | /* create a private copy of the skb, as some functions change tq value |
1445 | * and/or flags. | 1444 | * and/or flags. |
@@ -1767,8 +1766,13 @@ static void batadv_iv_ogm_process(const struct sk_buff *skb, int ogm_offset, | |||
1767 | if (hard_iface->soft_iface != bat_priv->soft_iface) | 1766 | if (hard_iface->soft_iface != bat_priv->soft_iface) |
1768 | continue; | 1767 | continue; |
1769 | 1768 | ||
1769 | if (!kref_get_unless_zero(&hard_iface->refcount)) | ||
1770 | continue; | ||
1771 | |||
1770 | batadv_iv_ogm_process_per_outif(skb, ogm_offset, orig_node, | 1772 | batadv_iv_ogm_process_per_outif(skb, ogm_offset, orig_node, |
1771 | if_incoming, hard_iface); | 1773 | if_incoming, hard_iface); |
1774 | |||
1775 | batadv_hardif_put(hard_iface); | ||
1772 | } | 1776 | } |
1773 | rcu_read_unlock(); | 1777 | rcu_read_unlock(); |
1774 | 1778 | ||
diff --git a/net/batman-adv/bat_v_ogm.c b/net/batman-adv/bat_v_ogm.c index 4155fa57cf6d..473ebb9a0e73 100644 --- a/net/batman-adv/bat_v_ogm.c +++ b/net/batman-adv/bat_v_ogm.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/if_ether.h> | 26 | #include <linux/if_ether.h> |
27 | #include <linux/jiffies.h> | 27 | #include <linux/jiffies.h> |
28 | #include <linux/kernel.h> | 28 | #include <linux/kernel.h> |
29 | #include <linux/kref.h> | ||
29 | #include <linux/list.h> | 30 | #include <linux/list.h> |
30 | #include <linux/netdevice.h> | 31 | #include <linux/netdevice.h> |
31 | #include <linux/random.h> | 32 | #include <linux/random.h> |
@@ -176,6 +177,9 @@ static void batadv_v_ogm_send(struct work_struct *work) | |||
176 | if (hard_iface->soft_iface != bat_priv->soft_iface) | 177 | if (hard_iface->soft_iface != bat_priv->soft_iface) |
177 | continue; | 178 | continue; |
178 | 179 | ||
180 | if (!kref_get_unless_zero(&hard_iface->refcount)) | ||
181 | continue; | ||
182 | |||
179 | batadv_dbg(BATADV_DBG_BATMAN, bat_priv, | 183 | batadv_dbg(BATADV_DBG_BATMAN, bat_priv, |
180 | "Sending own OGM2 packet (originator %pM, seqno %u, throughput %u, TTL %d) on interface %s [%pM]\n", | 184 | "Sending own OGM2 packet (originator %pM, seqno %u, throughput %u, TTL %d) on interface %s [%pM]\n", |
181 | ogm_packet->orig, ntohl(ogm_packet->seqno), | 185 | ogm_packet->orig, ntohl(ogm_packet->seqno), |
@@ -185,10 +189,13 @@ static void batadv_v_ogm_send(struct work_struct *work) | |||
185 | 189 | ||
186 | /* this skb gets consumed by batadv_v_ogm_send_to_if() */ | 190 | /* this skb gets consumed by batadv_v_ogm_send_to_if() */ |
187 | skb_tmp = skb_clone(skb, GFP_ATOMIC); | 191 | skb_tmp = skb_clone(skb, GFP_ATOMIC); |
188 | if (!skb_tmp) | 192 | if (!skb_tmp) { |
193 | batadv_hardif_put(hard_iface); | ||
189 | break; | 194 | break; |
195 | } | ||
190 | 196 | ||
191 | batadv_v_ogm_send_to_if(skb_tmp, hard_iface); | 197 | batadv_v_ogm_send_to_if(skb_tmp, hard_iface); |
198 | batadv_hardif_put(hard_iface); | ||
192 | } | 199 | } |
193 | rcu_read_unlock(); | 200 | rcu_read_unlock(); |
194 | 201 | ||
@@ -704,9 +711,14 @@ static void batadv_v_ogm_process(const struct sk_buff *skb, int ogm_offset, | |||
704 | if (hard_iface->soft_iface != bat_priv->soft_iface) | 711 | if (hard_iface->soft_iface != bat_priv->soft_iface) |
705 | continue; | 712 | continue; |
706 | 713 | ||
714 | if (!kref_get_unless_zero(&hard_iface->refcount)) | ||
715 | continue; | ||
716 | |||
707 | batadv_v_ogm_process_per_outif(bat_priv, ethhdr, ogm_packet, | 717 | batadv_v_ogm_process_per_outif(bat_priv, ethhdr, ogm_packet, |
708 | orig_node, neigh_node, | 718 | orig_node, neigh_node, |
709 | if_incoming, hard_iface); | 719 | if_incoming, hard_iface); |
720 | |||
721 | batadv_hardif_put(hard_iface); | ||
710 | } | 722 | } |
711 | rcu_read_unlock(); | 723 | rcu_read_unlock(); |
712 | out: | 724 | out: |
diff --git a/net/batman-adv/bitarray.c b/net/batman-adv/bitarray.c index b56bb000a0ab..a0c7913837a5 100644 --- a/net/batman-adv/bitarray.c +++ b/net/batman-adv/bitarray.c | |||
@@ -38,11 +38,11 @@ static void batadv_bitmap_shift_left(unsigned long *seq_bits, s32 n) | |||
38 | * the last sequence number | 38 | * the last sequence number |
39 | * @set_mark: whether this packet should be marked in seq_bits | 39 | * @set_mark: whether this packet should be marked in seq_bits |
40 | * | 40 | * |
41 | * Return: 1 if the window was moved (either new or very old), | 41 | * Return: true if the window was moved (either new or very old), |
42 | * 0 if the window was not moved/shifted. | 42 | * false if the window was not moved/shifted. |
43 | */ | 43 | */ |
44 | int batadv_bit_get_packet(void *priv, unsigned long *seq_bits, s32 seq_num_diff, | 44 | bool batadv_bit_get_packet(void *priv, unsigned long *seq_bits, |
45 | int set_mark) | 45 | s32 seq_num_diff, int set_mark) |
46 | { | 46 | { |
47 | struct batadv_priv *bat_priv = priv; | 47 | struct batadv_priv *bat_priv = priv; |
48 | 48 | ||
@@ -52,7 +52,7 @@ int batadv_bit_get_packet(void *priv, unsigned long *seq_bits, s32 seq_num_diff, | |||
52 | if (seq_num_diff <= 0 && seq_num_diff > -BATADV_TQ_LOCAL_WINDOW_SIZE) { | 52 | if (seq_num_diff <= 0 && seq_num_diff > -BATADV_TQ_LOCAL_WINDOW_SIZE) { |
53 | if (set_mark) | 53 | if (set_mark) |
54 | batadv_set_bit(seq_bits, -seq_num_diff); | 54 | batadv_set_bit(seq_bits, -seq_num_diff); |
55 | return 0; | 55 | return false; |
56 | } | 56 | } |
57 | 57 | ||
58 | /* sequence number is slightly newer, so we shift the window and | 58 | /* sequence number is slightly newer, so we shift the window and |
@@ -63,7 +63,7 @@ int batadv_bit_get_packet(void *priv, unsigned long *seq_bits, s32 seq_num_diff, | |||
63 | 63 | ||
64 | if (set_mark) | 64 | if (set_mark) |
65 | batadv_set_bit(seq_bits, 0); | 65 | batadv_set_bit(seq_bits, 0); |
66 | return 1; | 66 | return true; |
67 | } | 67 | } |
68 | 68 | ||
69 | /* sequence number is much newer, probably missed a lot of packets */ | 69 | /* sequence number is much newer, probably missed a lot of packets */ |
@@ -75,7 +75,7 @@ int batadv_bit_get_packet(void *priv, unsigned long *seq_bits, s32 seq_num_diff, | |||
75 | bitmap_zero(seq_bits, BATADV_TQ_LOCAL_WINDOW_SIZE); | 75 | bitmap_zero(seq_bits, BATADV_TQ_LOCAL_WINDOW_SIZE); |
76 | if (set_mark) | 76 | if (set_mark) |
77 | batadv_set_bit(seq_bits, 0); | 77 | batadv_set_bit(seq_bits, 0); |
78 | return 1; | 78 | return true; |
79 | } | 79 | } |
80 | 80 | ||
81 | /* received a much older packet. The other host either restarted | 81 | /* received a much older packet. The other host either restarted |
@@ -94,5 +94,5 @@ int batadv_bit_get_packet(void *priv, unsigned long *seq_bits, s32 seq_num_diff, | |||
94 | if (set_mark) | 94 | if (set_mark) |
95 | batadv_set_bit(seq_bits, 0); | 95 | batadv_set_bit(seq_bits, 0); |
96 | 96 | ||
97 | return 1; | 97 | return true; |
98 | } | 98 | } |
diff --git a/net/batman-adv/bitarray.h b/net/batman-adv/bitarray.h index 3e41bb80eb81..0e6e9d09078c 100644 --- a/net/batman-adv/bitarray.h +++ b/net/batman-adv/bitarray.h | |||
@@ -22,6 +22,7 @@ | |||
22 | 22 | ||
23 | #include <linux/bitops.h> | 23 | #include <linux/bitops.h> |
24 | #include <linux/compiler.h> | 24 | #include <linux/compiler.h> |
25 | #include <linux/stddef.h> | ||
25 | #include <linux/types.h> | 26 | #include <linux/types.h> |
26 | 27 | ||
27 | /** | 28 | /** |
@@ -31,17 +32,17 @@ | |||
31 | * @last_seqno: latest sequence number in seq_bits | 32 | * @last_seqno: latest sequence number in seq_bits |
32 | * @curr_seqno: sequence number to test for | 33 | * @curr_seqno: sequence number to test for |
33 | * | 34 | * |
34 | * Return: 1 if the corresponding bit in the given seq_bits indicates true | 35 | * Return: true if the corresponding bit in the given seq_bits indicates true |
35 | * and curr_seqno is within range of last_seqno. Otherwise returns 0. | 36 | * and curr_seqno is within range of last_seqno. Otherwise returns false. |
36 | */ | 37 | */ |
37 | static inline int batadv_test_bit(const unsigned long *seq_bits, | 38 | static inline bool batadv_test_bit(const unsigned long *seq_bits, |
38 | u32 last_seqno, u32 curr_seqno) | 39 | u32 last_seqno, u32 curr_seqno) |
39 | { | 40 | { |
40 | s32 diff; | 41 | s32 diff; |
41 | 42 | ||
42 | diff = last_seqno - curr_seqno; | 43 | diff = last_seqno - curr_seqno; |
43 | if (diff < 0 || diff >= BATADV_TQ_LOCAL_WINDOW_SIZE) | 44 | if (diff < 0 || diff >= BATADV_TQ_LOCAL_WINDOW_SIZE) |
44 | return 0; | 45 | return false; |
45 | return test_bit(diff, seq_bits) != 0; | 46 | return test_bit(diff, seq_bits) != 0; |
46 | } | 47 | } |
47 | 48 | ||
@@ -55,7 +56,7 @@ static inline void batadv_set_bit(unsigned long *seq_bits, s32 n) | |||
55 | set_bit(n, seq_bits); /* turn the position on */ | 56 | set_bit(n, seq_bits); /* turn the position on */ |
56 | } | 57 | } |
57 | 58 | ||
58 | int batadv_bit_get_packet(void *priv, unsigned long *seq_bits, s32 seq_num_diff, | 59 | bool batadv_bit_get_packet(void *priv, unsigned long *seq_bits, |
59 | int set_mark); | 60 | s32 seq_num_diff, int set_mark); |
60 | 61 | ||
61 | #endif /* _NET_BATMAN_ADV_BITARRAY_H_ */ | 62 | #endif /* _NET_BATMAN_ADV_BITARRAY_H_ */ |
diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c index 2c9aa671a49b..748a9ead7ce5 100644 --- a/net/batman-adv/bridge_loop_avoidance.c +++ b/net/batman-adv/bridge_loop_avoidance.c | |||
@@ -50,6 +50,7 @@ | |||
50 | #include "hash.h" | 50 | #include "hash.h" |
51 | #include "originator.h" | 51 | #include "originator.h" |
52 | #include "packet.h" | 52 | #include "packet.h" |
53 | #include "sysfs.h" | ||
53 | #include "translation-table.h" | 54 | #include "translation-table.h" |
54 | 55 | ||
55 | static const u8 batadv_announce_mac[4] = {0x43, 0x05, 0x43, 0x05}; | 56 | static const u8 batadv_announce_mac[4] = {0x43, 0x05, 0x43, 0x05}; |
@@ -100,10 +101,10 @@ static inline u32 batadv_choose_backbone_gw(const void *data, u32 size) | |||
100 | * @node: list node of the first entry to compare | 101 | * @node: list node of the first entry to compare |
101 | * @data2: pointer to the second backbone gateway | 102 | * @data2: pointer to the second backbone gateway |
102 | * | 103 | * |
103 | * Return: 1 if the backbones have the same data, 0 otherwise | 104 | * Return: true if the backbones have the same data, false otherwise |
104 | */ | 105 | */ |
105 | static int batadv_compare_backbone_gw(const struct hlist_node *node, | 106 | static bool batadv_compare_backbone_gw(const struct hlist_node *node, |
106 | const void *data2) | 107 | const void *data2) |
107 | { | 108 | { |
108 | const void *data1 = container_of(node, struct batadv_bla_backbone_gw, | 109 | const void *data1 = container_of(node, struct batadv_bla_backbone_gw, |
109 | hash_entry); | 110 | hash_entry); |
@@ -111,12 +112,12 @@ static int batadv_compare_backbone_gw(const struct hlist_node *node, | |||
111 | const struct batadv_bla_backbone_gw *gw2 = data2; | 112 | const struct batadv_bla_backbone_gw *gw2 = data2; |
112 | 113 | ||
113 | if (!batadv_compare_eth(gw1->orig, gw2->orig)) | 114 | if (!batadv_compare_eth(gw1->orig, gw2->orig)) |
114 | return 0; | 115 | return false; |
115 | 116 | ||
116 | if (gw1->vid != gw2->vid) | 117 | if (gw1->vid != gw2->vid) |
117 | return 0; | 118 | return false; |
118 | 119 | ||
119 | return 1; | 120 | return true; |
120 | } | 121 | } |
121 | 122 | ||
122 | /** | 123 | /** |
@@ -124,10 +125,10 @@ static int batadv_compare_backbone_gw(const struct hlist_node *node, | |||
124 | * @node: list node of the first entry to compare | 125 | * @node: list node of the first entry to compare |
125 | * @data2: pointer to the second claims | 126 | * @data2: pointer to the second claims |
126 | * | 127 | * |
127 | * Return: 1 if the claim have the same data, 0 otherwise | 128 | * Return: true if the claim have the same data, 0 otherwise |
128 | */ | 129 | */ |
129 | static int batadv_compare_claim(const struct hlist_node *node, | 130 | static bool batadv_compare_claim(const struct hlist_node *node, |
130 | const void *data2) | 131 | const void *data2) |
131 | { | 132 | { |
132 | const void *data1 = container_of(node, struct batadv_bla_claim, | 133 | const void *data1 = container_of(node, struct batadv_bla_claim, |
133 | hash_entry); | 134 | hash_entry); |
@@ -135,12 +136,12 @@ static int batadv_compare_claim(const struct hlist_node *node, | |||
135 | const struct batadv_bla_claim *cl2 = data2; | 136 | const struct batadv_bla_claim *cl2 = data2; |
136 | 137 | ||
137 | if (!batadv_compare_eth(cl1->addr, cl2->addr)) | 138 | if (!batadv_compare_eth(cl1->addr, cl2->addr)) |
138 | return 0; | 139 | return false; |
139 | 140 | ||
140 | if (cl1->vid != cl2->vid) | 141 | if (cl1->vid != cl2->vid) |
141 | return 0; | 142 | return false; |
142 | 143 | ||
143 | return 1; | 144 | return true; |
144 | } | 145 | } |
145 | 146 | ||
146 | /** | 147 | /** |
@@ -407,6 +408,14 @@ static void batadv_bla_send_claim(struct batadv_priv *bat_priv, u8 *mac, | |||
407 | ethhdr->h_source, ethhdr->h_dest, | 408 | ethhdr->h_source, ethhdr->h_dest, |
408 | BATADV_PRINT_VID(vid)); | 409 | BATADV_PRINT_VID(vid)); |
409 | break; | 410 | break; |
411 | case BATADV_CLAIM_TYPE_LOOPDETECT: | ||
412 | ether_addr_copy(ethhdr->h_source, mac); | ||
413 | batadv_dbg(BATADV_DBG_BLA, bat_priv, | ||
414 | "bla_send_claim(): LOOPDETECT of %pM to %pM on vid %d\n", | ||
415 | ethhdr->h_source, ethhdr->h_dest, | ||
416 | BATADV_PRINT_VID(vid)); | ||
417 | |||
418 | break; | ||
410 | } | 419 | } |
411 | 420 | ||
412 | if (vid & BATADV_VLAN_HAS_TAG) | 421 | if (vid & BATADV_VLAN_HAS_TAG) |
@@ -427,6 +436,36 @@ out: | |||
427 | } | 436 | } |
428 | 437 | ||
429 | /** | 438 | /** |
439 | * batadv_bla_loopdetect_report - worker for reporting the loop | ||
440 | * @work: work queue item | ||
441 | * | ||
442 | * Throws an uevent, as the loopdetect check function can't do that itself | ||
443 | * since the kernel may sleep while throwing uevents. | ||
444 | */ | ||
445 | static void batadv_bla_loopdetect_report(struct work_struct *work) | ||
446 | { | ||
447 | struct batadv_bla_backbone_gw *backbone_gw; | ||
448 | struct batadv_priv *bat_priv; | ||
449 | char vid_str[6] = { '\0' }; | ||
450 | |||
451 | backbone_gw = container_of(work, struct batadv_bla_backbone_gw, | ||
452 | report_work); | ||
453 | bat_priv = backbone_gw->bat_priv; | ||
454 | |||
455 | batadv_info(bat_priv->soft_iface, | ||
456 | "Possible loop on VLAN %d detected which can't be handled by BLA - please check your network setup!\n", | ||
457 | BATADV_PRINT_VID(backbone_gw->vid)); | ||
458 | snprintf(vid_str, sizeof(vid_str), "%d", | ||
459 | BATADV_PRINT_VID(backbone_gw->vid)); | ||
460 | vid_str[sizeof(vid_str) - 1] = 0; | ||
461 | |||
462 | batadv_throw_uevent(bat_priv, BATADV_UEV_BLA, BATADV_UEV_LOOPDETECT, | ||
463 | vid_str); | ||
464 | |||
465 | batadv_backbone_gw_put(backbone_gw); | ||
466 | } | ||
467 | |||
468 | /** | ||
430 | * batadv_bla_get_backbone_gw - finds or creates a backbone gateway | 469 | * batadv_bla_get_backbone_gw - finds or creates a backbone gateway |
431 | * @bat_priv: the bat priv with all the soft interface information | 470 | * @bat_priv: the bat priv with all the soft interface information |
432 | * @orig: the mac address of the originator | 471 | * @orig: the mac address of the originator |
@@ -464,6 +503,7 @@ batadv_bla_get_backbone_gw(struct batadv_priv *bat_priv, u8 *orig, | |||
464 | atomic_set(&entry->request_sent, 0); | 503 | atomic_set(&entry->request_sent, 0); |
465 | atomic_set(&entry->wait_periods, 0); | 504 | atomic_set(&entry->wait_periods, 0); |
466 | ether_addr_copy(entry->orig, orig); | 505 | ether_addr_copy(entry->orig, orig); |
506 | INIT_WORK(&entry->report_work, batadv_bla_loopdetect_report); | ||
467 | 507 | ||
468 | /* one for the hash, one for returning */ | 508 | /* one for the hash, one for returning */ |
469 | kref_init(&entry->refcount); | 509 | kref_init(&entry->refcount); |
@@ -735,22 +775,22 @@ static void batadv_bla_del_claim(struct batadv_priv *bat_priv, | |||
735 | * @backbone_addr: originator address of the sender (Ethernet source MAC) | 775 | * @backbone_addr: originator address of the sender (Ethernet source MAC) |
736 | * @vid: the VLAN ID of the frame | 776 | * @vid: the VLAN ID of the frame |
737 | * | 777 | * |
738 | * Return: 1 if handled | 778 | * Return: true if handled |
739 | */ | 779 | */ |
740 | static int batadv_handle_announce(struct batadv_priv *bat_priv, u8 *an_addr, | 780 | static bool batadv_handle_announce(struct batadv_priv *bat_priv, u8 *an_addr, |
741 | u8 *backbone_addr, unsigned short vid) | 781 | u8 *backbone_addr, unsigned short vid) |
742 | { | 782 | { |
743 | struct batadv_bla_backbone_gw *backbone_gw; | 783 | struct batadv_bla_backbone_gw *backbone_gw; |
744 | u16 backbone_crc, crc; | 784 | u16 backbone_crc, crc; |
745 | 785 | ||
746 | if (memcmp(an_addr, batadv_announce_mac, 4) != 0) | 786 | if (memcmp(an_addr, batadv_announce_mac, 4) != 0) |
747 | return 0; | 787 | return false; |
748 | 788 | ||
749 | backbone_gw = batadv_bla_get_backbone_gw(bat_priv, backbone_addr, vid, | 789 | backbone_gw = batadv_bla_get_backbone_gw(bat_priv, backbone_addr, vid, |
750 | false); | 790 | false); |
751 | 791 | ||
752 | if (unlikely(!backbone_gw)) | 792 | if (unlikely(!backbone_gw)) |
753 | return 1; | 793 | return true; |
754 | 794 | ||
755 | /* handle as ANNOUNCE frame */ | 795 | /* handle as ANNOUNCE frame */ |
756 | backbone_gw->lasttime = jiffies; | 796 | backbone_gw->lasttime = jiffies; |
@@ -783,7 +823,7 @@ static int batadv_handle_announce(struct batadv_priv *bat_priv, u8 *an_addr, | |||
783 | } | 823 | } |
784 | 824 | ||
785 | batadv_backbone_gw_put(backbone_gw); | 825 | batadv_backbone_gw_put(backbone_gw); |
786 | return 1; | 826 | return true; |
787 | } | 827 | } |
788 | 828 | ||
789 | /** | 829 | /** |
@@ -794,29 +834,29 @@ static int batadv_handle_announce(struct batadv_priv *bat_priv, u8 *an_addr, | |||
794 | * @ethhdr: ethernet header of a packet | 834 | * @ethhdr: ethernet header of a packet |
795 | * @vid: the VLAN ID of the frame | 835 | * @vid: the VLAN ID of the frame |
796 | * | 836 | * |
797 | * Return: 1 if handled | 837 | * Return: true if handled |
798 | */ | 838 | */ |
799 | static int batadv_handle_request(struct batadv_priv *bat_priv, | 839 | static bool batadv_handle_request(struct batadv_priv *bat_priv, |
800 | struct batadv_hard_iface *primary_if, | 840 | struct batadv_hard_iface *primary_if, |
801 | u8 *backbone_addr, struct ethhdr *ethhdr, | 841 | u8 *backbone_addr, struct ethhdr *ethhdr, |
802 | unsigned short vid) | 842 | unsigned short vid) |
803 | { | 843 | { |
804 | /* check for REQUEST frame */ | 844 | /* check for REQUEST frame */ |
805 | if (!batadv_compare_eth(backbone_addr, ethhdr->h_dest)) | 845 | if (!batadv_compare_eth(backbone_addr, ethhdr->h_dest)) |
806 | return 0; | 846 | return false; |
807 | 847 | ||
808 | /* sanity check, this should not happen on a normal switch, | 848 | /* sanity check, this should not happen on a normal switch, |
809 | * we ignore it in this case. | 849 | * we ignore it in this case. |
810 | */ | 850 | */ |
811 | if (!batadv_compare_eth(ethhdr->h_dest, primary_if->net_dev->dev_addr)) | 851 | if (!batadv_compare_eth(ethhdr->h_dest, primary_if->net_dev->dev_addr)) |
812 | return 1; | 852 | return true; |
813 | 853 | ||
814 | batadv_dbg(BATADV_DBG_BLA, bat_priv, | 854 | batadv_dbg(BATADV_DBG_BLA, bat_priv, |
815 | "handle_request(): REQUEST vid %d (sent by %pM)...\n", | 855 | "handle_request(): REQUEST vid %d (sent by %pM)...\n", |
816 | BATADV_PRINT_VID(vid), ethhdr->h_source); | 856 | BATADV_PRINT_VID(vid), ethhdr->h_source); |
817 | 857 | ||
818 | batadv_bla_answer_request(bat_priv, primary_if, vid); | 858 | batadv_bla_answer_request(bat_priv, primary_if, vid); |
819 | return 1; | 859 | return true; |
820 | } | 860 | } |
821 | 861 | ||
822 | /** | 862 | /** |
@@ -827,12 +867,12 @@ static int batadv_handle_request(struct batadv_priv *bat_priv, | |||
827 | * @claim_addr: Client to be unclaimed (ARP sender HW MAC) | 867 | * @claim_addr: Client to be unclaimed (ARP sender HW MAC) |
828 | * @vid: the VLAN ID of the frame | 868 | * @vid: the VLAN ID of the frame |
829 | * | 869 | * |
830 | * Return: 1 if handled | 870 | * Return: true if handled |
831 | */ | 871 | */ |
832 | static int batadv_handle_unclaim(struct batadv_priv *bat_priv, | 872 | static bool batadv_handle_unclaim(struct batadv_priv *bat_priv, |
833 | struct batadv_hard_iface *primary_if, | 873 | struct batadv_hard_iface *primary_if, |
834 | u8 *backbone_addr, u8 *claim_addr, | 874 | u8 *backbone_addr, u8 *claim_addr, |
835 | unsigned short vid) | 875 | unsigned short vid) |
836 | { | 876 | { |
837 | struct batadv_bla_backbone_gw *backbone_gw; | 877 | struct batadv_bla_backbone_gw *backbone_gw; |
838 | 878 | ||
@@ -845,7 +885,7 @@ static int batadv_handle_unclaim(struct batadv_priv *bat_priv, | |||
845 | backbone_gw = batadv_backbone_hash_find(bat_priv, backbone_addr, vid); | 885 | backbone_gw = batadv_backbone_hash_find(bat_priv, backbone_addr, vid); |
846 | 886 | ||
847 | if (!backbone_gw) | 887 | if (!backbone_gw) |
848 | return 1; | 888 | return true; |
849 | 889 | ||
850 | /* this must be an UNCLAIM frame */ | 890 | /* this must be an UNCLAIM frame */ |
851 | batadv_dbg(BATADV_DBG_BLA, bat_priv, | 891 | batadv_dbg(BATADV_DBG_BLA, bat_priv, |
@@ -854,7 +894,7 @@ static int batadv_handle_unclaim(struct batadv_priv *bat_priv, | |||
854 | 894 | ||
855 | batadv_bla_del_claim(bat_priv, claim_addr, vid); | 895 | batadv_bla_del_claim(bat_priv, claim_addr, vid); |
856 | batadv_backbone_gw_put(backbone_gw); | 896 | batadv_backbone_gw_put(backbone_gw); |
857 | return 1; | 897 | return true; |
858 | } | 898 | } |
859 | 899 | ||
860 | /** | 900 | /** |
@@ -865,12 +905,12 @@ static int batadv_handle_unclaim(struct batadv_priv *bat_priv, | |||
865 | * @claim_addr: client mac address to be claimed (ARP sender HW MAC) | 905 | * @claim_addr: client mac address to be claimed (ARP sender HW MAC) |
866 | * @vid: the VLAN ID of the frame | 906 | * @vid: the VLAN ID of the frame |
867 | * | 907 | * |
868 | * Return: 1 if handled | 908 | * Return: true if handled |
869 | */ | 909 | */ |
870 | static int batadv_handle_claim(struct batadv_priv *bat_priv, | 910 | static bool batadv_handle_claim(struct batadv_priv *bat_priv, |
871 | struct batadv_hard_iface *primary_if, | 911 | struct batadv_hard_iface *primary_if, |
872 | u8 *backbone_addr, u8 *claim_addr, | 912 | u8 *backbone_addr, u8 *claim_addr, |
873 | unsigned short vid) | 913 | unsigned short vid) |
874 | { | 914 | { |
875 | struct batadv_bla_backbone_gw *backbone_gw; | 915 | struct batadv_bla_backbone_gw *backbone_gw; |
876 | 916 | ||
@@ -880,7 +920,7 @@ static int batadv_handle_claim(struct batadv_priv *bat_priv, | |||
880 | false); | 920 | false); |
881 | 921 | ||
882 | if (unlikely(!backbone_gw)) | 922 | if (unlikely(!backbone_gw)) |
883 | return 1; | 923 | return true; |
884 | 924 | ||
885 | /* this must be a CLAIM frame */ | 925 | /* this must be a CLAIM frame */ |
886 | batadv_bla_add_claim(bat_priv, claim_addr, vid, backbone_gw); | 926 | batadv_bla_add_claim(bat_priv, claim_addr, vid, backbone_gw); |
@@ -891,7 +931,7 @@ static int batadv_handle_claim(struct batadv_priv *bat_priv, | |||
891 | /* TODO: we could call something like tt_local_del() here. */ | 931 | /* TODO: we could call something like tt_local_del() here. */ |
892 | 932 | ||
893 | batadv_backbone_gw_put(backbone_gw); | 933 | batadv_backbone_gw_put(backbone_gw); |
894 | return 1; | 934 | return true; |
895 | } | 935 | } |
896 | 936 | ||
897 | /** | 937 | /** |
@@ -975,12 +1015,12 @@ static int batadv_check_claim_group(struct batadv_priv *bat_priv, | |||
975 | * @primary_if: the primary hard interface of this batman soft interface | 1015 | * @primary_if: the primary hard interface of this batman soft interface |
976 | * @skb: the frame to be checked | 1016 | * @skb: the frame to be checked |
977 | * | 1017 | * |
978 | * Return: 1 if it was a claim frame, otherwise return 0 to | 1018 | * Return: true if it was a claim frame, otherwise return false to |
979 | * tell the callee that it can use the frame on its own. | 1019 | * tell the callee that it can use the frame on its own. |
980 | */ | 1020 | */ |
981 | static int batadv_bla_process_claim(struct batadv_priv *bat_priv, | 1021 | static bool batadv_bla_process_claim(struct batadv_priv *bat_priv, |
982 | struct batadv_hard_iface *primary_if, | 1022 | struct batadv_hard_iface *primary_if, |
983 | struct sk_buff *skb) | 1023 | struct sk_buff *skb) |
984 | { | 1024 | { |
985 | struct batadv_bla_claim_dst *bla_dst, *bla_dst_own; | 1025 | struct batadv_bla_claim_dst *bla_dst, *bla_dst_own; |
986 | u8 *hw_src, *hw_dst; | 1026 | u8 *hw_src, *hw_dst; |
@@ -1011,7 +1051,7 @@ static int batadv_bla_process_claim(struct batadv_priv *bat_priv, | |||
1011 | vhdr = skb_header_pointer(skb, headlen, VLAN_HLEN, | 1051 | vhdr = skb_header_pointer(skb, headlen, VLAN_HLEN, |
1012 | &vhdr_buf); | 1052 | &vhdr_buf); |
1013 | if (!vhdr) | 1053 | if (!vhdr) |
1014 | return 0; | 1054 | return false; |
1015 | 1055 | ||
1016 | proto = vhdr->h_vlan_encapsulated_proto; | 1056 | proto = vhdr->h_vlan_encapsulated_proto; |
1017 | headlen += VLAN_HLEN; | 1057 | headlen += VLAN_HLEN; |
@@ -1020,12 +1060,12 @@ static int batadv_bla_process_claim(struct batadv_priv *bat_priv, | |||
1020 | } | 1060 | } |
1021 | 1061 | ||
1022 | if (proto != htons(ETH_P_ARP)) | 1062 | if (proto != htons(ETH_P_ARP)) |
1023 | return 0; /* not a claim frame */ | 1063 | return false; /* not a claim frame */ |
1024 | 1064 | ||
1025 | /* this must be a ARP frame. check if it is a claim. */ | 1065 | /* this must be a ARP frame. check if it is a claim. */ |
1026 | 1066 | ||
1027 | if (unlikely(!pskb_may_pull(skb, headlen + arp_hdr_len(skb->dev)))) | 1067 | if (unlikely(!pskb_may_pull(skb, headlen + arp_hdr_len(skb->dev)))) |
1028 | return 0; | 1068 | return false; |
1029 | 1069 | ||
1030 | /* pskb_may_pull() may have modified the pointers, get ethhdr again */ | 1070 | /* pskb_may_pull() may have modified the pointers, get ethhdr again */ |
1031 | ethhdr = eth_hdr(skb); | 1071 | ethhdr = eth_hdr(skb); |
@@ -1035,13 +1075,13 @@ static int batadv_bla_process_claim(struct batadv_priv *bat_priv, | |||
1035 | * IP information | 1075 | * IP information |
1036 | */ | 1076 | */ |
1037 | if (arphdr->ar_hrd != htons(ARPHRD_ETHER)) | 1077 | if (arphdr->ar_hrd != htons(ARPHRD_ETHER)) |
1038 | return 0; | 1078 | return false; |
1039 | if (arphdr->ar_pro != htons(ETH_P_IP)) | 1079 | if (arphdr->ar_pro != htons(ETH_P_IP)) |
1040 | return 0; | 1080 | return false; |
1041 | if (arphdr->ar_hln != ETH_ALEN) | 1081 | if (arphdr->ar_hln != ETH_ALEN) |
1042 | return 0; | 1082 | return false; |
1043 | if (arphdr->ar_pln != 4) | 1083 | if (arphdr->ar_pln != 4) |
1044 | return 0; | 1084 | return false; |
1045 | 1085 | ||
1046 | hw_src = (u8 *)arphdr + sizeof(struct arphdr); | 1086 | hw_src = (u8 *)arphdr + sizeof(struct arphdr); |
1047 | hw_dst = hw_src + ETH_ALEN + 4; | 1087 | hw_dst = hw_src + ETH_ALEN + 4; |
@@ -1051,14 +1091,18 @@ static int batadv_bla_process_claim(struct batadv_priv *bat_priv, | |||
1051 | /* check if it is a claim frame in general */ | 1091 | /* check if it is a claim frame in general */ |
1052 | if (memcmp(bla_dst->magic, bla_dst_own->magic, | 1092 | if (memcmp(bla_dst->magic, bla_dst_own->magic, |
1053 | sizeof(bla_dst->magic)) != 0) | 1093 | sizeof(bla_dst->magic)) != 0) |
1054 | return 0; | 1094 | return false; |
1055 | 1095 | ||
1056 | /* check if there is a claim frame encapsulated deeper in (QinQ) and | 1096 | /* check if there is a claim frame encapsulated deeper in (QinQ) and |
1057 | * drop that, as this is not supported by BLA but should also not be | 1097 | * drop that, as this is not supported by BLA but should also not be |
1058 | * sent via the mesh. | 1098 | * sent via the mesh. |
1059 | */ | 1099 | */ |
1060 | if (vlan_depth > 1) | 1100 | if (vlan_depth > 1) |
1061 | return 1; | 1101 | return true; |
1102 | |||
1103 | /* Let the loopdetect frames on the mesh in any case. */ | ||
1104 | if (bla_dst->type == BATADV_CLAIM_TYPE_LOOPDETECT) | ||
1105 | return 0; | ||
1062 | 1106 | ||
1063 | /* check if it is a claim frame. */ | 1107 | /* check if it is a claim frame. */ |
1064 | ret = batadv_check_claim_group(bat_priv, primary_if, hw_src, hw_dst, | 1108 | ret = batadv_check_claim_group(bat_priv, primary_if, hw_src, hw_dst, |
@@ -1070,7 +1114,7 @@ static int batadv_bla_process_claim(struct batadv_priv *bat_priv, | |||
1070 | hw_dst); | 1114 | hw_dst); |
1071 | 1115 | ||
1072 | if (ret < 2) | 1116 | if (ret < 2) |
1073 | return ret; | 1117 | return !!ret; |
1074 | 1118 | ||
1075 | /* become a backbone gw ourselves on this vlan if not happened yet */ | 1119 | /* become a backbone gw ourselves on this vlan if not happened yet */ |
1076 | batadv_bla_update_own_backbone_gw(bat_priv, primary_if, vid); | 1120 | batadv_bla_update_own_backbone_gw(bat_priv, primary_if, vid); |
@@ -1080,30 +1124,30 @@ static int batadv_bla_process_claim(struct batadv_priv *bat_priv, | |||
1080 | case BATADV_CLAIM_TYPE_CLAIM: | 1124 | case BATADV_CLAIM_TYPE_CLAIM: |
1081 | if (batadv_handle_claim(bat_priv, primary_if, hw_src, | 1125 | if (batadv_handle_claim(bat_priv, primary_if, hw_src, |
1082 | ethhdr->h_source, vid)) | 1126 | ethhdr->h_source, vid)) |
1083 | return 1; | 1127 | return true; |
1084 | break; | 1128 | break; |
1085 | case BATADV_CLAIM_TYPE_UNCLAIM: | 1129 | case BATADV_CLAIM_TYPE_UNCLAIM: |
1086 | if (batadv_handle_unclaim(bat_priv, primary_if, | 1130 | if (batadv_handle_unclaim(bat_priv, primary_if, |
1087 | ethhdr->h_source, hw_src, vid)) | 1131 | ethhdr->h_source, hw_src, vid)) |
1088 | return 1; | 1132 | return true; |
1089 | break; | 1133 | break; |
1090 | 1134 | ||
1091 | case BATADV_CLAIM_TYPE_ANNOUNCE: | 1135 | case BATADV_CLAIM_TYPE_ANNOUNCE: |
1092 | if (batadv_handle_announce(bat_priv, hw_src, ethhdr->h_source, | 1136 | if (batadv_handle_announce(bat_priv, hw_src, ethhdr->h_source, |
1093 | vid)) | 1137 | vid)) |
1094 | return 1; | 1138 | return true; |
1095 | break; | 1139 | break; |
1096 | case BATADV_CLAIM_TYPE_REQUEST: | 1140 | case BATADV_CLAIM_TYPE_REQUEST: |
1097 | if (batadv_handle_request(bat_priv, primary_if, hw_src, ethhdr, | 1141 | if (batadv_handle_request(bat_priv, primary_if, hw_src, ethhdr, |
1098 | vid)) | 1142 | vid)) |
1099 | return 1; | 1143 | return true; |
1100 | break; | 1144 | break; |
1101 | } | 1145 | } |
1102 | 1146 | ||
1103 | batadv_dbg(BATADV_DBG_BLA, bat_priv, | 1147 | batadv_dbg(BATADV_DBG_BLA, bat_priv, |
1104 | "bla_process_claim(): ERROR - this looks like a claim frame, but is useless. eth src %pM on vid %d ...(hw_src %pM, hw_dst %pM)\n", | 1148 | "bla_process_claim(): ERROR - this looks like a claim frame, but is useless. eth src %pM on vid %d ...(hw_src %pM, hw_dst %pM)\n", |
1105 | ethhdr->h_source, BATADV_PRINT_VID(vid), hw_src, hw_dst); | 1149 | ethhdr->h_source, BATADV_PRINT_VID(vid), hw_src, hw_dst); |
1106 | return 1; | 1150 | return true; |
1107 | } | 1151 | } |
1108 | 1152 | ||
1109 | /** | 1153 | /** |
@@ -1265,6 +1309,26 @@ void batadv_bla_update_orig_address(struct batadv_priv *bat_priv, | |||
1265 | } | 1309 | } |
1266 | 1310 | ||
1267 | /** | 1311 | /** |
1312 | * batadv_bla_send_loopdetect - send a loopdetect frame | ||
1313 | * @bat_priv: the bat priv with all the soft interface information | ||
1314 | * @backbone_gw: the backbone gateway for which a loop should be detected | ||
1315 | * | ||
1316 | * To detect loops that the bridge loop avoidance can't handle, send a loop | ||
1317 | * detection packet on the backbone. Unlike other BLA frames, this frame will | ||
1318 | * be allowed on the mesh by other nodes. If it is received on the mesh, this | ||
1319 | * indicates that there is a loop. | ||
1320 | */ | ||
1321 | static void | ||
1322 | batadv_bla_send_loopdetect(struct batadv_priv *bat_priv, | ||
1323 | struct batadv_bla_backbone_gw *backbone_gw) | ||
1324 | { | ||
1325 | batadv_dbg(BATADV_DBG_BLA, bat_priv, "Send loopdetect frame for vid %d\n", | ||
1326 | backbone_gw->vid); | ||
1327 | batadv_bla_send_claim(bat_priv, bat_priv->bla.loopdetect_addr, | ||
1328 | backbone_gw->vid, BATADV_CLAIM_TYPE_LOOPDETECT); | ||
1329 | } | ||
1330 | |||
1331 | /** | ||
1268 | * batadv_bla_status_update - purge bla interfaces if necessary | 1332 | * batadv_bla_status_update - purge bla interfaces if necessary |
1269 | * @net_dev: the soft interface net device | 1333 | * @net_dev: the soft interface net device |
1270 | */ | 1334 | */ |
@@ -1301,6 +1365,7 @@ static void batadv_bla_periodic_work(struct work_struct *work) | |||
1301 | struct batadv_bla_backbone_gw *backbone_gw; | 1365 | struct batadv_bla_backbone_gw *backbone_gw; |
1302 | struct batadv_hashtable *hash; | 1366 | struct batadv_hashtable *hash; |
1303 | struct batadv_hard_iface *primary_if; | 1367 | struct batadv_hard_iface *primary_if; |
1368 | bool send_loopdetect = false; | ||
1304 | int i; | 1369 | int i; |
1305 | 1370 | ||
1306 | delayed_work = to_delayed_work(work); | 1371 | delayed_work = to_delayed_work(work); |
@@ -1316,6 +1381,22 @@ static void batadv_bla_periodic_work(struct work_struct *work) | |||
1316 | if (!atomic_read(&bat_priv->bridge_loop_avoidance)) | 1381 | if (!atomic_read(&bat_priv->bridge_loop_avoidance)) |
1317 | goto out; | 1382 | goto out; |
1318 | 1383 | ||
1384 | if (atomic_dec_and_test(&bat_priv->bla.loopdetect_next)) { | ||
1385 | /* set a new random mac address for the next bridge loop | ||
1386 | * detection frames. Set the locally administered bit to avoid | ||
1387 | * collisions with users mac addresses. | ||
1388 | */ | ||
1389 | random_ether_addr(bat_priv->bla.loopdetect_addr); | ||
1390 | bat_priv->bla.loopdetect_addr[0] = 0xba; | ||
1391 | bat_priv->bla.loopdetect_addr[1] = 0xbe; | ||
1392 | bat_priv->bla.loopdetect_lasttime = jiffies; | ||
1393 | atomic_set(&bat_priv->bla.loopdetect_next, | ||
1394 | BATADV_BLA_LOOPDETECT_PERIODS); | ||
1395 | |||
1396 | /* mark for sending loop detect on all VLANs */ | ||
1397 | send_loopdetect = true; | ||
1398 | } | ||
1399 | |||
1319 | hash = bat_priv->bla.backbone_hash; | 1400 | hash = bat_priv->bla.backbone_hash; |
1320 | if (!hash) | 1401 | if (!hash) |
1321 | goto out; | 1402 | goto out; |
@@ -1332,6 +1413,9 @@ static void batadv_bla_periodic_work(struct work_struct *work) | |||
1332 | backbone_gw->lasttime = jiffies; | 1413 | backbone_gw->lasttime = jiffies; |
1333 | 1414 | ||
1334 | batadv_bla_send_announce(bat_priv, backbone_gw); | 1415 | batadv_bla_send_announce(bat_priv, backbone_gw); |
1416 | if (send_loopdetect) | ||
1417 | batadv_bla_send_loopdetect(bat_priv, | ||
1418 | backbone_gw); | ||
1335 | 1419 | ||
1336 | /* request_sent is only set after creation to avoid | 1420 | /* request_sent is only set after creation to avoid |
1337 | * problems when we are not yet known as backbone gw | 1421 | * problems when we are not yet known as backbone gw |
@@ -1405,6 +1489,9 @@ int batadv_bla_init(struct batadv_priv *bat_priv) | |||
1405 | bat_priv->bla.bcast_duplist[i].entrytime = entrytime; | 1489 | bat_priv->bla.bcast_duplist[i].entrytime = entrytime; |
1406 | bat_priv->bla.bcast_duplist_curr = 0; | 1490 | bat_priv->bla.bcast_duplist_curr = 0; |
1407 | 1491 | ||
1492 | atomic_set(&bat_priv->bla.loopdetect_next, | ||
1493 | BATADV_BLA_LOOPDETECT_PERIODS); | ||
1494 | |||
1408 | if (bat_priv->bla.claim_hash) | 1495 | if (bat_priv->bla.claim_hash) |
1409 | return 0; | 1496 | return 0; |
1410 | 1497 | ||
@@ -1442,15 +1529,16 @@ int batadv_bla_init(struct batadv_priv *bat_priv) | |||
1442 | * sent by another host, drop it. We allow equal packets from | 1529 | * sent by another host, drop it. We allow equal packets from |
1443 | * the same host however as this might be intended. | 1530 | * the same host however as this might be intended. |
1444 | * | 1531 | * |
1445 | * Return: 1 if a packet is in the duplicate list, 0 otherwise. | 1532 | * Return: true if a packet is in the duplicate list, false otherwise. |
1446 | */ | 1533 | */ |
1447 | int batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv, | 1534 | bool batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv, |
1448 | struct sk_buff *skb) | 1535 | struct sk_buff *skb) |
1449 | { | 1536 | { |
1450 | int i, curr, ret = 0; | 1537 | int i, curr; |
1451 | __be32 crc; | 1538 | __be32 crc; |
1452 | struct batadv_bcast_packet *bcast_packet; | 1539 | struct batadv_bcast_packet *bcast_packet; |
1453 | struct batadv_bcast_duplist_entry *entry; | 1540 | struct batadv_bcast_duplist_entry *entry; |
1541 | bool ret = false; | ||
1454 | 1542 | ||
1455 | bcast_packet = (struct batadv_bcast_packet *)skb->data; | 1543 | bcast_packet = (struct batadv_bcast_packet *)skb->data; |
1456 | 1544 | ||
@@ -1478,9 +1566,9 @@ int batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv, | |||
1478 | continue; | 1566 | continue; |
1479 | 1567 | ||
1480 | /* this entry seems to match: same crc, not too old, | 1568 | /* this entry seems to match: same crc, not too old, |
1481 | * and from another gw. therefore return 1 to forbid it. | 1569 | * and from another gw. therefore return true to forbid it. |
1482 | */ | 1570 | */ |
1483 | ret = 1; | 1571 | ret = true; |
1484 | goto out; | 1572 | goto out; |
1485 | } | 1573 | } |
1486 | /* not found, add a new entry (overwrite the oldest entry) | 1574 | /* not found, add a new entry (overwrite the oldest entry) |
@@ -1546,21 +1634,21 @@ bool batadv_bla_is_backbone_gw_orig(struct batadv_priv *bat_priv, u8 *orig, | |||
1546 | * @orig_node: the orig_node of the frame | 1634 | * @orig_node: the orig_node of the frame |
1547 | * @hdr_size: maximum length of the frame | 1635 | * @hdr_size: maximum length of the frame |
1548 | * | 1636 | * |
1549 | * Return: 1 if the orig_node is also a gateway on the soft interface, otherwise | 1637 | * Return: true if the orig_node is also a gateway on the soft interface, |
1550 | * it returns 0. | 1638 | * otherwise it returns false. |
1551 | */ | 1639 | */ |
1552 | int batadv_bla_is_backbone_gw(struct sk_buff *skb, | 1640 | bool batadv_bla_is_backbone_gw(struct sk_buff *skb, |
1553 | struct batadv_orig_node *orig_node, int hdr_size) | 1641 | struct batadv_orig_node *orig_node, int hdr_size) |
1554 | { | 1642 | { |
1555 | struct batadv_bla_backbone_gw *backbone_gw; | 1643 | struct batadv_bla_backbone_gw *backbone_gw; |
1556 | unsigned short vid; | 1644 | unsigned short vid; |
1557 | 1645 | ||
1558 | if (!atomic_read(&orig_node->bat_priv->bridge_loop_avoidance)) | 1646 | if (!atomic_read(&orig_node->bat_priv->bridge_loop_avoidance)) |
1559 | return 0; | 1647 | return false; |
1560 | 1648 | ||
1561 | /* first, find out the vid. */ | 1649 | /* first, find out the vid. */ |
1562 | if (!pskb_may_pull(skb, hdr_size + ETH_HLEN)) | 1650 | if (!pskb_may_pull(skb, hdr_size + ETH_HLEN)) |
1563 | return 0; | 1651 | return false; |
1564 | 1652 | ||
1565 | vid = batadv_get_vid(skb, hdr_size); | 1653 | vid = batadv_get_vid(skb, hdr_size); |
1566 | 1654 | ||
@@ -1568,10 +1656,10 @@ int batadv_bla_is_backbone_gw(struct sk_buff *skb, | |||
1568 | backbone_gw = batadv_backbone_hash_find(orig_node->bat_priv, | 1656 | backbone_gw = batadv_backbone_hash_find(orig_node->bat_priv, |
1569 | orig_node->orig, vid); | 1657 | orig_node->orig, vid); |
1570 | if (!backbone_gw) | 1658 | if (!backbone_gw) |
1571 | return 0; | 1659 | return false; |
1572 | 1660 | ||
1573 | batadv_backbone_gw_put(backbone_gw); | 1661 | batadv_backbone_gw_put(backbone_gw); |
1574 | return 1; | 1662 | return true; |
1575 | } | 1663 | } |
1576 | 1664 | ||
1577 | /** | 1665 | /** |
@@ -1602,6 +1690,55 @@ void batadv_bla_free(struct batadv_priv *bat_priv) | |||
1602 | } | 1690 | } |
1603 | 1691 | ||
1604 | /** | 1692 | /** |
1693 | * batadv_bla_loopdetect_check - check and handle a detected loop | ||
1694 | * @bat_priv: the bat priv with all the soft interface information | ||
1695 | * @skb: the packet to check | ||
1696 | * @primary_if: interface where the request came on | ||
1697 | * @vid: the VLAN ID of the frame | ||
1698 | * | ||
1699 | * Checks if this packet is a loop detect frame which has been sent by us, | ||
1700 | * throw an uevent and log the event if that is the case. | ||
1701 | * | ||
1702 | * Return: true if it is a loop detect frame which is to be dropped, false | ||
1703 | * otherwise. | ||
1704 | */ | ||
1705 | static bool | ||
1706 | batadv_bla_loopdetect_check(struct batadv_priv *bat_priv, struct sk_buff *skb, | ||
1707 | struct batadv_hard_iface *primary_if, | ||
1708 | unsigned short vid) | ||
1709 | { | ||
1710 | struct batadv_bla_backbone_gw *backbone_gw; | ||
1711 | struct ethhdr *ethhdr; | ||
1712 | |||
1713 | ethhdr = eth_hdr(skb); | ||
1714 | |||
1715 | /* Only check for the MAC address and skip more checks here for | ||
1716 | * performance reasons - this function is on the hotpath, after all. | ||
1717 | */ | ||
1718 | if (!batadv_compare_eth(ethhdr->h_source, | ||
1719 | bat_priv->bla.loopdetect_addr)) | ||
1720 | return false; | ||
1721 | |||
1722 | /* If the packet came too late, don't forward it on the mesh | ||
1723 | * but don't consider that as loop. It might be a coincidence. | ||
1724 | */ | ||
1725 | if (batadv_has_timed_out(bat_priv->bla.loopdetect_lasttime, | ||
1726 | BATADV_BLA_LOOPDETECT_TIMEOUT)) | ||
1727 | return true; | ||
1728 | |||
1729 | backbone_gw = batadv_bla_get_backbone_gw(bat_priv, | ||
1730 | primary_if->net_dev->dev_addr, | ||
1731 | vid, true); | ||
1732 | if (unlikely(!backbone_gw)) | ||
1733 | return true; | ||
1734 | |||
1735 | queue_work(batadv_event_workqueue, &backbone_gw->report_work); | ||
1736 | /* backbone_gw is unreferenced in the report work function function */ | ||
1737 | |||
1738 | return true; | ||
1739 | } | ||
1740 | |||
1741 | /** | ||
1605 | * batadv_bla_rx - check packets coming from the mesh. | 1742 | * batadv_bla_rx - check packets coming from the mesh. |
1606 | * @bat_priv: the bat priv with all the soft interface information | 1743 | * @bat_priv: the bat priv with all the soft interface information |
1607 | * @skb: the frame to be checked | 1744 | * @skb: the frame to be checked |
@@ -1614,16 +1751,16 @@ void batadv_bla_free(struct batadv_priv *bat_priv) | |||
1614 | * | 1751 | * |
1615 | * in these cases, the skb is further handled by this function | 1752 | * in these cases, the skb is further handled by this function |
1616 | * | 1753 | * |
1617 | * Return: 1 if handled, otherwise it returns 0 and the caller shall further | 1754 | * Return: true if handled, otherwise it returns false and the caller shall |
1618 | * process the skb. | 1755 | * further process the skb. |
1619 | */ | 1756 | */ |
1620 | int batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb, | 1757 | bool batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb, |
1621 | unsigned short vid, bool is_bcast) | 1758 | unsigned short vid, bool is_bcast) |
1622 | { | 1759 | { |
1623 | struct ethhdr *ethhdr; | 1760 | struct ethhdr *ethhdr; |
1624 | struct batadv_bla_claim search_claim, *claim = NULL; | 1761 | struct batadv_bla_claim search_claim, *claim = NULL; |
1625 | struct batadv_hard_iface *primary_if; | 1762 | struct batadv_hard_iface *primary_if; |
1626 | int ret; | 1763 | bool ret; |
1627 | 1764 | ||
1628 | ethhdr = eth_hdr(skb); | 1765 | ethhdr = eth_hdr(skb); |
1629 | 1766 | ||
@@ -1634,6 +1771,9 @@ int batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb, | |||
1634 | if (!atomic_read(&bat_priv->bridge_loop_avoidance)) | 1771 | if (!atomic_read(&bat_priv->bridge_loop_avoidance)) |
1635 | goto allow; | 1772 | goto allow; |
1636 | 1773 | ||
1774 | if (batadv_bla_loopdetect_check(bat_priv, skb, primary_if, vid)) | ||
1775 | goto handled; | ||
1776 | |||
1637 | if (unlikely(atomic_read(&bat_priv->bla.num_requests))) | 1777 | if (unlikely(atomic_read(&bat_priv->bla.num_requests))) |
1638 | /* don't allow broadcasts while requests are in flight */ | 1778 | /* don't allow broadcasts while requests are in flight */ |
1639 | if (is_multicast_ether_addr(ethhdr->h_dest) && is_bcast) | 1779 | if (is_multicast_ether_addr(ethhdr->h_dest) && is_bcast) |
@@ -1682,12 +1822,12 @@ int batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb, | |||
1682 | } | 1822 | } |
1683 | allow: | 1823 | allow: |
1684 | batadv_bla_update_own_backbone_gw(bat_priv, primary_if, vid); | 1824 | batadv_bla_update_own_backbone_gw(bat_priv, primary_if, vid); |
1685 | ret = 0; | 1825 | ret = false; |
1686 | goto out; | 1826 | goto out; |
1687 | 1827 | ||
1688 | handled: | 1828 | handled: |
1689 | kfree_skb(skb); | 1829 | kfree_skb(skb); |
1690 | ret = 1; | 1830 | ret = true; |
1691 | 1831 | ||
1692 | out: | 1832 | out: |
1693 | if (primary_if) | 1833 | if (primary_if) |
@@ -1711,16 +1851,16 @@ out: | |||
1711 | * | 1851 | * |
1712 | * This call might reallocate skb data. | 1852 | * This call might reallocate skb data. |
1713 | * | 1853 | * |
1714 | * Return: 1 if handled, otherwise it returns 0 and the caller shall further | 1854 | * Return: true if handled, otherwise it returns false and the caller shall |
1715 | * process the skb. | 1855 | * further process the skb. |
1716 | */ | 1856 | */ |
1717 | int batadv_bla_tx(struct batadv_priv *bat_priv, struct sk_buff *skb, | 1857 | bool batadv_bla_tx(struct batadv_priv *bat_priv, struct sk_buff *skb, |
1718 | unsigned short vid) | 1858 | unsigned short vid) |
1719 | { | 1859 | { |
1720 | struct ethhdr *ethhdr; | 1860 | struct ethhdr *ethhdr; |
1721 | struct batadv_bla_claim search_claim, *claim = NULL; | 1861 | struct batadv_bla_claim search_claim, *claim = NULL; |
1722 | struct batadv_hard_iface *primary_if; | 1862 | struct batadv_hard_iface *primary_if; |
1723 | int ret = 0; | 1863 | bool ret = false; |
1724 | 1864 | ||
1725 | primary_if = batadv_primary_if_get_selected(bat_priv); | 1865 | primary_if = batadv_primary_if_get_selected(bat_priv); |
1726 | if (!primary_if) | 1866 | if (!primary_if) |
@@ -1774,10 +1914,10 @@ int batadv_bla_tx(struct batadv_priv *bat_priv, struct sk_buff *skb, | |||
1774 | } | 1914 | } |
1775 | allow: | 1915 | allow: |
1776 | batadv_bla_update_own_backbone_gw(bat_priv, primary_if, vid); | 1916 | batadv_bla_update_own_backbone_gw(bat_priv, primary_if, vid); |
1777 | ret = 0; | 1917 | ret = false; |
1778 | goto out; | 1918 | goto out; |
1779 | handled: | 1919 | handled: |
1780 | ret = 1; | 1920 | ret = true; |
1781 | out: | 1921 | out: |
1782 | if (primary_if) | 1922 | if (primary_if) |
1783 | batadv_hardif_put(primary_if); | 1923 | batadv_hardif_put(primary_if); |
diff --git a/net/batman-adv/bridge_loop_avoidance.h b/net/batman-adv/bridge_loop_avoidance.h index 579f0fa6fe6a..0f01daeb359e 100644 --- a/net/batman-adv/bridge_loop_avoidance.h +++ b/net/batman-adv/bridge_loop_avoidance.h | |||
@@ -27,19 +27,20 @@ struct seq_file; | |||
27 | struct sk_buff; | 27 | struct sk_buff; |
28 | 28 | ||
29 | #ifdef CONFIG_BATMAN_ADV_BLA | 29 | #ifdef CONFIG_BATMAN_ADV_BLA |
30 | int batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb, | 30 | bool batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb, |
31 | unsigned short vid, bool is_bcast); | 31 | unsigned short vid, bool is_bcast); |
32 | int batadv_bla_tx(struct batadv_priv *bat_priv, struct sk_buff *skb, | 32 | bool batadv_bla_tx(struct batadv_priv *bat_priv, struct sk_buff *skb, |
33 | unsigned short vid); | 33 | unsigned short vid); |
34 | int batadv_bla_is_backbone_gw(struct sk_buff *skb, | 34 | bool batadv_bla_is_backbone_gw(struct sk_buff *skb, |
35 | struct batadv_orig_node *orig_node, int hdr_size); | 35 | struct batadv_orig_node *orig_node, |
36 | int hdr_size); | ||
36 | int batadv_bla_claim_table_seq_print_text(struct seq_file *seq, void *offset); | 37 | int batadv_bla_claim_table_seq_print_text(struct seq_file *seq, void *offset); |
37 | int batadv_bla_backbone_table_seq_print_text(struct seq_file *seq, | 38 | int batadv_bla_backbone_table_seq_print_text(struct seq_file *seq, |
38 | void *offset); | 39 | void *offset); |
39 | bool batadv_bla_is_backbone_gw_orig(struct batadv_priv *bat_priv, u8 *orig, | 40 | bool batadv_bla_is_backbone_gw_orig(struct batadv_priv *bat_priv, u8 *orig, |
40 | unsigned short vid); | 41 | unsigned short vid); |
41 | int batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv, | 42 | bool batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv, |
42 | struct sk_buff *skb); | 43 | struct sk_buff *skb); |
43 | void batadv_bla_update_orig_address(struct batadv_priv *bat_priv, | 44 | void batadv_bla_update_orig_address(struct batadv_priv *bat_priv, |
44 | struct batadv_hard_iface *primary_if, | 45 | struct batadv_hard_iface *primary_if, |
45 | struct batadv_hard_iface *oldif); | 46 | struct batadv_hard_iface *oldif); |
@@ -50,24 +51,24 @@ void batadv_bla_free(struct batadv_priv *bat_priv); | |||
50 | #define BATADV_BLA_CRC_INIT 0 | 51 | #define BATADV_BLA_CRC_INIT 0 |
51 | #else /* ifdef CONFIG_BATMAN_ADV_BLA */ | 52 | #else /* ifdef CONFIG_BATMAN_ADV_BLA */ |
52 | 53 | ||
53 | static inline int batadv_bla_rx(struct batadv_priv *bat_priv, | 54 | static inline bool batadv_bla_rx(struct batadv_priv *bat_priv, |
54 | struct sk_buff *skb, unsigned short vid, | 55 | struct sk_buff *skb, unsigned short vid, |
55 | bool is_bcast) | 56 | bool is_bcast) |
56 | { | 57 | { |
57 | return 0; | 58 | return false; |
58 | } | 59 | } |
59 | 60 | ||
60 | static inline int batadv_bla_tx(struct batadv_priv *bat_priv, | 61 | static inline bool batadv_bla_tx(struct batadv_priv *bat_priv, |
61 | struct sk_buff *skb, unsigned short vid) | 62 | struct sk_buff *skb, unsigned short vid) |
62 | { | 63 | { |
63 | return 0; | 64 | return false; |
64 | } | 65 | } |
65 | 66 | ||
66 | static inline int batadv_bla_is_backbone_gw(struct sk_buff *skb, | 67 | static inline bool batadv_bla_is_backbone_gw(struct sk_buff *skb, |
67 | struct batadv_orig_node *orig_node, | 68 | struct batadv_orig_node *orig_node, |
68 | int hdr_size) | 69 | int hdr_size) |
69 | { | 70 | { |
70 | return 0; | 71 | return false; |
71 | } | 72 | } |
72 | 73 | ||
73 | static inline int batadv_bla_claim_table_seq_print_text(struct seq_file *seq, | 74 | static inline int batadv_bla_claim_table_seq_print_text(struct seq_file *seq, |
@@ -88,11 +89,11 @@ static inline bool batadv_bla_is_backbone_gw_orig(struct batadv_priv *bat_priv, | |||
88 | return false; | 89 | return false; |
89 | } | 90 | } |
90 | 91 | ||
91 | static inline int | 92 | static inline bool |
92 | batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv, | 93 | batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv, |
93 | struct sk_buff *skb) | 94 | struct sk_buff *skb) |
94 | { | 95 | { |
95 | return 0; | 96 | return false; |
96 | } | 97 | } |
97 | 98 | ||
98 | static inline void | 99 | static inline void |
diff --git a/net/batman-adv/debugfs.c b/net/batman-adv/debugfs.c index aa315da83429..952900466d88 100644 --- a/net/batman-adv/debugfs.c +++ b/net/batman-adv/debugfs.c | |||
@@ -134,7 +134,7 @@ static int batadv_log_release(struct inode *inode, struct file *file) | |||
134 | return 0; | 134 | return 0; |
135 | } | 135 | } |
136 | 136 | ||
137 | static int batadv_log_empty(struct batadv_priv_debug_log *debug_log) | 137 | static bool batadv_log_empty(struct batadv_priv_debug_log *debug_log) |
138 | { | 138 | { |
139 | return !(debug_log->log_start - debug_log->log_end); | 139 | return !(debug_log->log_start - debug_log->log_end); |
140 | } | 140 | } |
diff --git a/net/batman-adv/distributed-arp-table.c b/net/batman-adv/distributed-arp-table.c index 67f44f5d630b..278800a99c69 100644 --- a/net/batman-adv/distributed-arp-table.c +++ b/net/batman-adv/distributed-arp-table.c | |||
@@ -165,14 +165,14 @@ static void batadv_dat_purge(struct work_struct *work) | |||
165 | * @node: node in the local table | 165 | * @node: node in the local table |
166 | * @data2: second object to compare the node to | 166 | * @data2: second object to compare the node to |
167 | * | 167 | * |
168 | * Return: 1 if the two entries are the same, 0 otherwise. | 168 | * Return: true if the two entries are the same, false otherwise. |
169 | */ | 169 | */ |
170 | static int batadv_compare_dat(const struct hlist_node *node, const void *data2) | 170 | static bool batadv_compare_dat(const struct hlist_node *node, const void *data2) |
171 | { | 171 | { |
172 | const void *data1 = container_of(node, struct batadv_dat_entry, | 172 | const void *data1 = container_of(node, struct batadv_dat_entry, |
173 | hash_entry); | 173 | hash_entry); |
174 | 174 | ||
175 | return memcmp(data1, data2, sizeof(__be32)) == 0 ? 1 : 0; | 175 | return memcmp(data1, data2, sizeof(__be32)) == 0; |
176 | } | 176 | } |
177 | 177 | ||
178 | /** | 178 | /** |
diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c index c59aff5ccac8..5839c569f769 100644 --- a/net/batman-adv/gateway_client.c +++ b/net/batman-adv/gateway_client.c | |||
@@ -135,8 +135,8 @@ static void batadv_gw_select(struct batadv_priv *bat_priv, | |||
135 | 135 | ||
136 | spin_lock_bh(&bat_priv->gw.list_lock); | 136 | spin_lock_bh(&bat_priv->gw.list_lock); |
137 | 137 | ||
138 | if (new_gw_node && !kref_get_unless_zero(&new_gw_node->refcount)) | 138 | if (new_gw_node) |
139 | new_gw_node = NULL; | 139 | kref_get(&new_gw_node->refcount); |
140 | 140 | ||
141 | curr_gw_node = rcu_dereference_protected(bat_priv->gw.curr_gw, 1); | 141 | curr_gw_node = rcu_dereference_protected(bat_priv->gw.curr_gw, 1); |
142 | rcu_assign_pointer(bat_priv->gw.curr_gw, new_gw_node); | 142 | rcu_assign_pointer(bat_priv->gw.curr_gw, new_gw_node); |
@@ -440,15 +440,11 @@ static void batadv_gw_node_add(struct batadv_priv *bat_priv, | |||
440 | if (gateway->bandwidth_down == 0) | 440 | if (gateway->bandwidth_down == 0) |
441 | return; | 441 | return; |
442 | 442 | ||
443 | if (!kref_get_unless_zero(&orig_node->refcount)) | ||
444 | return; | ||
445 | |||
446 | gw_node = kzalloc(sizeof(*gw_node), GFP_ATOMIC); | 443 | gw_node = kzalloc(sizeof(*gw_node), GFP_ATOMIC); |
447 | if (!gw_node) { | 444 | if (!gw_node) |
448 | batadv_orig_node_put(orig_node); | ||
449 | return; | 445 | return; |
450 | } | ||
451 | 446 | ||
447 | kref_get(&orig_node->refcount); | ||
452 | INIT_HLIST_NODE(&gw_node->list); | 448 | INIT_HLIST_NODE(&gw_node->list); |
453 | gw_node->orig_node = orig_node; | 449 | gw_node->orig_node = orig_node; |
454 | gw_node->bandwidth_down = ntohl(gateway->bandwidth_down); | 450 | gw_node->bandwidth_down = ntohl(gateway->bandwidth_down); |
diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c index 0a7deaf2670a..8c2f39962fa5 100644 --- a/net/batman-adv/hard-interface.c +++ b/net/batman-adv/hard-interface.c | |||
@@ -36,7 +36,6 @@ | |||
36 | #include <linux/slab.h> | 36 | #include <linux/slab.h> |
37 | #include <linux/spinlock.h> | 37 | #include <linux/spinlock.h> |
38 | #include <linux/workqueue.h> | 38 | #include <linux/workqueue.h> |
39 | #include <net/net_namespace.h> | ||
40 | 39 | ||
41 | #include "bridge_loop_avoidance.h" | 40 | #include "bridge_loop_avoidance.h" |
42 | #include "debugfs.h" | 41 | #include "debugfs.h" |
@@ -121,6 +120,7 @@ static bool batadv_mutual_parents(const struct net_device *dev1, | |||
121 | static bool batadv_is_on_batman_iface(const struct net_device *net_dev) | 120 | static bool batadv_is_on_batman_iface(const struct net_device *net_dev) |
122 | { | 121 | { |
123 | struct net_device *parent_dev; | 122 | struct net_device *parent_dev; |
123 | struct net *net = dev_net(net_dev); | ||
124 | bool ret; | 124 | bool ret; |
125 | 125 | ||
126 | /* check if this is a batman-adv mesh interface */ | 126 | /* check if this is a batman-adv mesh interface */ |
@@ -133,7 +133,7 @@ static bool batadv_is_on_batman_iface(const struct net_device *net_dev) | |||
133 | return false; | 133 | return false; |
134 | 134 | ||
135 | /* recurse over the parent device */ | 135 | /* recurse over the parent device */ |
136 | parent_dev = __dev_get_by_index(&init_net, dev_get_iflink(net_dev)); | 136 | parent_dev = __dev_get_by_index(net, dev_get_iflink(net_dev)); |
137 | /* if we got a NULL parent_dev there is something broken.. */ | 137 | /* if we got a NULL parent_dev there is something broken.. */ |
138 | if (WARN(!parent_dev, "Cannot find parent device")) | 138 | if (WARN(!parent_dev, "Cannot find parent device")) |
139 | return false; | 139 | return false; |
@@ -146,22 +146,22 @@ static bool batadv_is_on_batman_iface(const struct net_device *net_dev) | |||
146 | return ret; | 146 | return ret; |
147 | } | 147 | } |
148 | 148 | ||
149 | static int batadv_is_valid_iface(const struct net_device *net_dev) | 149 | static bool batadv_is_valid_iface(const struct net_device *net_dev) |
150 | { | 150 | { |
151 | if (net_dev->flags & IFF_LOOPBACK) | 151 | if (net_dev->flags & IFF_LOOPBACK) |
152 | return 0; | 152 | return false; |
153 | 153 | ||
154 | if (net_dev->type != ARPHRD_ETHER) | 154 | if (net_dev->type != ARPHRD_ETHER) |
155 | return 0; | 155 | return false; |
156 | 156 | ||
157 | if (net_dev->addr_len != ETH_ALEN) | 157 | if (net_dev->addr_len != ETH_ALEN) |
158 | return 0; | 158 | return false; |
159 | 159 | ||
160 | /* no batman over batman */ | 160 | /* no batman over batman */ |
161 | if (batadv_is_on_batman_iface(net_dev)) | 161 | if (batadv_is_on_batman_iface(net_dev)) |
162 | return 0; | 162 | return false; |
163 | 163 | ||
164 | return 1; | 164 | return true; |
165 | } | 165 | } |
166 | 166 | ||
167 | /** | 167 | /** |
@@ -236,8 +236,8 @@ static void batadv_primary_if_select(struct batadv_priv *bat_priv, | |||
236 | 236 | ||
237 | ASSERT_RTNL(); | 237 | ASSERT_RTNL(); |
238 | 238 | ||
239 | if (new_hard_iface && !kref_get_unless_zero(&new_hard_iface->refcount)) | 239 | if (new_hard_iface) |
240 | new_hard_iface = NULL; | 240 | kref_get(&new_hard_iface->refcount); |
241 | 241 | ||
242 | curr_hard_iface = rcu_dereference_protected(bat_priv->primary_if, 1); | 242 | curr_hard_iface = rcu_dereference_protected(bat_priv->primary_if, 1); |
243 | rcu_assign_pointer(bat_priv->primary_if, new_hard_iface); | 243 | rcu_assign_pointer(bat_priv->primary_if, new_hard_iface); |
@@ -456,7 +456,7 @@ static int batadv_master_del_slave(struct batadv_hard_iface *slave, | |||
456 | } | 456 | } |
457 | 457 | ||
458 | int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface, | 458 | int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface, |
459 | const char *iface_name) | 459 | struct net *net, const char *iface_name) |
460 | { | 460 | { |
461 | struct batadv_priv *bat_priv; | 461 | struct batadv_priv *bat_priv; |
462 | struct net_device *soft_iface, *master; | 462 | struct net_device *soft_iface, *master; |
@@ -467,13 +467,12 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface, | |||
467 | if (hard_iface->if_status != BATADV_IF_NOT_IN_USE) | 467 | if (hard_iface->if_status != BATADV_IF_NOT_IN_USE) |
468 | goto out; | 468 | goto out; |
469 | 469 | ||
470 | if (!kref_get_unless_zero(&hard_iface->refcount)) | 470 | kref_get(&hard_iface->refcount); |
471 | goto out; | ||
472 | 471 | ||
473 | soft_iface = dev_get_by_name(&init_net, iface_name); | 472 | soft_iface = dev_get_by_name(net, iface_name); |
474 | 473 | ||
475 | if (!soft_iface) { | 474 | if (!soft_iface) { |
476 | soft_iface = batadv_softif_create(iface_name); | 475 | soft_iface = batadv_softif_create(net, iface_name); |
477 | 476 | ||
478 | if (!soft_iface) { | 477 | if (!soft_iface) { |
479 | ret = -ENOMEM; | 478 | ret = -ENOMEM; |
@@ -522,6 +521,7 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface, | |||
522 | goto err_upper; | 521 | goto err_upper; |
523 | } | 522 | } |
524 | 523 | ||
524 | kref_get(&hard_iface->refcount); | ||
525 | hard_iface->batman_adv_ptype.type = ethertype; | 525 | hard_iface->batman_adv_ptype.type = ethertype; |
526 | hard_iface->batman_adv_ptype.func = batadv_batman_skb_recv; | 526 | hard_iface->batman_adv_ptype.func = batadv_batman_skb_recv; |
527 | hard_iface->batman_adv_ptype.dev = hard_iface->net_dev; | 527 | hard_iface->batman_adv_ptype.dev = hard_iface->net_dev; |
@@ -583,6 +583,7 @@ void batadv_hardif_disable_interface(struct batadv_hard_iface *hard_iface, | |||
583 | batadv_info(hard_iface->soft_iface, "Removing interface: %s\n", | 583 | batadv_info(hard_iface->soft_iface, "Removing interface: %s\n", |
584 | hard_iface->net_dev->name); | 584 | hard_iface->net_dev->name); |
585 | dev_remove_pack(&hard_iface->batman_adv_ptype); | 585 | dev_remove_pack(&hard_iface->batman_adv_ptype); |
586 | batadv_hardif_put(hard_iface); | ||
586 | 587 | ||
587 | bat_priv->num_ifaces--; | 588 | bat_priv->num_ifaces--; |
588 | batadv_orig_hash_del_if(hard_iface, bat_priv->num_ifaces); | 589 | batadv_orig_hash_del_if(hard_iface, bat_priv->num_ifaces); |
@@ -652,8 +653,7 @@ batadv_hardif_add_interface(struct net_device *net_dev) | |||
652 | 653 | ||
653 | ASSERT_RTNL(); | 654 | ASSERT_RTNL(); |
654 | 655 | ||
655 | ret = batadv_is_valid_iface(net_dev); | 656 | if (!batadv_is_valid_iface(net_dev)) |
656 | if (ret != 1) | ||
657 | goto out; | 657 | goto out; |
658 | 658 | ||
659 | dev_hold(net_dev); | 659 | dev_hold(net_dev); |
diff --git a/net/batman-adv/hard-interface.h b/net/batman-adv/hard-interface.h index d74f1983f33e..a76724d369bf 100644 --- a/net/batman-adv/hard-interface.h +++ b/net/batman-adv/hard-interface.h | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/types.h> | 28 | #include <linux/types.h> |
29 | 29 | ||
30 | struct net_device; | 30 | struct net_device; |
31 | struct net; | ||
31 | 32 | ||
32 | enum batadv_hard_if_state { | 33 | enum batadv_hard_if_state { |
33 | BATADV_IF_NOT_IN_USE, | 34 | BATADV_IF_NOT_IN_USE, |
@@ -55,7 +56,7 @@ bool batadv_is_wifi_iface(int ifindex); | |||
55 | struct batadv_hard_iface* | 56 | struct batadv_hard_iface* |
56 | batadv_hardif_get_by_netdev(const struct net_device *net_dev); | 57 | batadv_hardif_get_by_netdev(const struct net_device *net_dev); |
57 | int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface, | 58 | int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface, |
58 | const char *iface_name); | 59 | struct net *net, const char *iface_name); |
59 | void batadv_hardif_disable_interface(struct batadv_hard_iface *hard_iface, | 60 | void batadv_hardif_disable_interface(struct batadv_hard_iface *hard_iface, |
60 | enum batadv_hard_if_cleanup autodel); | 61 | enum batadv_hard_if_cleanup autodel); |
61 | void batadv_hardif_remove_interfaces(void); | 62 | void batadv_hardif_remove_interfaces(void); |
diff --git a/net/batman-adv/hash.h b/net/batman-adv/hash.h index 9bb57b87447c..cbbf87075f06 100644 --- a/net/batman-adv/hash.h +++ b/net/batman-adv/hash.h | |||
@@ -32,10 +32,10 @@ struct lock_class_key; | |||
32 | /* callback to a compare function. should compare 2 element datas for their | 32 | /* callback to a compare function. should compare 2 element datas for their |
33 | * keys | 33 | * keys |
34 | * | 34 | * |
35 | * Return: 0 if same and not 0 if not same | 35 | * Return: true if same and false if not same |
36 | */ | 36 | */ |
37 | typedef int (*batadv_hashdata_compare_cb)(const struct hlist_node *, | 37 | typedef bool (*batadv_hashdata_compare_cb)(const struct hlist_node *, |
38 | const void *); | 38 | const void *); |
39 | 39 | ||
40 | /* the hashfunction | 40 | /* the hashfunction |
41 | * | 41 | * |
diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c index 78c05a91ae6f..5f2974bd1227 100644 --- a/net/batman-adv/main.c +++ b/net/batman-adv/main.c | |||
@@ -401,11 +401,19 @@ int batadv_batman_skb_recv(struct sk_buff *skb, struct net_device *dev, | |||
401 | 401 | ||
402 | hard_iface = container_of(ptype, struct batadv_hard_iface, | 402 | hard_iface = container_of(ptype, struct batadv_hard_iface, |
403 | batman_adv_ptype); | 403 | batman_adv_ptype); |
404 | |||
405 | /* Prevent processing a packet received on an interface which is getting | ||
406 | * shut down otherwise the packet may trigger de-reference errors | ||
407 | * further down in the receive path. | ||
408 | */ | ||
409 | if (!kref_get_unless_zero(&hard_iface->refcount)) | ||
410 | goto err_out; | ||
411 | |||
404 | skb = skb_share_check(skb, GFP_ATOMIC); | 412 | skb = skb_share_check(skb, GFP_ATOMIC); |
405 | 413 | ||
406 | /* skb was released by skb_share_check() */ | 414 | /* skb was released by skb_share_check() */ |
407 | if (!skb) | 415 | if (!skb) |
408 | goto err_out; | 416 | goto err_put; |
409 | 417 | ||
410 | /* packet should hold at least type and version */ | 418 | /* packet should hold at least type and version */ |
411 | if (unlikely(!pskb_may_pull(skb, 2))) | 419 | if (unlikely(!pskb_may_pull(skb, 2))) |
@@ -448,6 +456,8 @@ int batadv_batman_skb_recv(struct sk_buff *skb, struct net_device *dev, | |||
448 | if (ret == NET_RX_DROP) | 456 | if (ret == NET_RX_DROP) |
449 | kfree_skb(skb); | 457 | kfree_skb(skb); |
450 | 458 | ||
459 | batadv_hardif_put(hard_iface); | ||
460 | |||
451 | /* return NET_RX_SUCCESS in any case as we | 461 | /* return NET_RX_SUCCESS in any case as we |
452 | * most probably dropped the packet for | 462 | * most probably dropped the packet for |
453 | * routing-logical reasons. | 463 | * routing-logical reasons. |
@@ -456,6 +466,8 @@ int batadv_batman_skb_recv(struct sk_buff *skb, struct net_device *dev, | |||
456 | 466 | ||
457 | err_free: | 467 | err_free: |
458 | kfree_skb(skb); | 468 | kfree_skb(skb); |
469 | err_put: | ||
470 | batadv_hardif_put(hard_iface); | ||
459 | err_out: | 471 | err_out: |
460 | return NET_RX_DROP; | 472 | return NET_RX_DROP; |
461 | } | 473 | } |
@@ -736,9 +748,7 @@ batadv_tvlv_container_get(struct batadv_priv *bat_priv, u8 type, u8 version) | |||
736 | if (tvlv_tmp->tvlv_hdr.version != version) | 748 | if (tvlv_tmp->tvlv_hdr.version != version) |
737 | continue; | 749 | continue; |
738 | 750 | ||
739 | if (!kref_get_unless_zero(&tvlv_tmp->refcount)) | 751 | kref_get(&tvlv_tmp->refcount); |
740 | continue; | ||
741 | |||
742 | tvlv = tvlv_tmp; | 752 | tvlv = tvlv_tmp; |
743 | break; | 753 | break; |
744 | } | 754 | } |
diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h index 07a6042d0ad6..76925266deed 100644 --- a/net/batman-adv/main.h +++ b/net/batman-adv/main.h | |||
@@ -120,6 +120,8 @@ | |||
120 | #define BATADV_BLA_BACKBONE_TIMEOUT (BATADV_BLA_PERIOD_LENGTH * 6) | 120 | #define BATADV_BLA_BACKBONE_TIMEOUT (BATADV_BLA_PERIOD_LENGTH * 6) |
121 | #define BATADV_BLA_CLAIM_TIMEOUT (BATADV_BLA_PERIOD_LENGTH * 10) | 121 | #define BATADV_BLA_CLAIM_TIMEOUT (BATADV_BLA_PERIOD_LENGTH * 10) |
122 | #define BATADV_BLA_WAIT_PERIODS 3 | 122 | #define BATADV_BLA_WAIT_PERIODS 3 |
123 | #define BATADV_BLA_LOOPDETECT_PERIODS 6 | ||
124 | #define BATADV_BLA_LOOPDETECT_TIMEOUT 3000 /* 3 seconds */ | ||
123 | 125 | ||
124 | #define BATADV_DUPLIST_SIZE 16 | 126 | #define BATADV_DUPLIST_SIZE 16 |
125 | #define BATADV_DUPLIST_TIMEOUT 500 /* 500 ms */ | 127 | #define BATADV_DUPLIST_TIMEOUT 500 /* 500 ms */ |
@@ -142,10 +144,12 @@ enum batadv_uev_action { | |||
142 | BATADV_UEV_ADD = 0, | 144 | BATADV_UEV_ADD = 0, |
143 | BATADV_UEV_DEL, | 145 | BATADV_UEV_DEL, |
144 | BATADV_UEV_CHANGE, | 146 | BATADV_UEV_CHANGE, |
147 | BATADV_UEV_LOOPDETECT, | ||
145 | }; | 148 | }; |
146 | 149 | ||
147 | enum batadv_uev_type { | 150 | enum batadv_uev_type { |
148 | BATADV_UEV_GW = 0, | 151 | BATADV_UEV_GW = 0, |
152 | BATADV_UEV_BLA, | ||
149 | }; | 153 | }; |
150 | 154 | ||
151 | #define BATADV_GW_THRESHOLD 50 | 155 | #define BATADV_GW_THRESHOLD 50 |
@@ -288,7 +292,7 @@ static inline void _batadv_dbg(int type __always_unused, | |||
288 | * | 292 | * |
289 | * note: can't use ether_addr_equal() as it requires aligned memory | 293 | * note: can't use ether_addr_equal() as it requires aligned memory |
290 | * | 294 | * |
291 | * Return: 1 if they are the same ethernet addr | 295 | * Return: true if they are the same ethernet addr |
292 | */ | 296 | */ |
293 | static inline bool batadv_compare_eth(const void *data1, const void *data2) | 297 | static inline bool batadv_compare_eth(const void *data1, const void *data2) |
294 | { | 298 | { |
diff --git a/net/batman-adv/network-coding.c b/net/batman-adv/network-coding.c index 1da8e0e1b18f..678f06865312 100644 --- a/net/batman-adv/network-coding.c +++ b/net/batman-adv/network-coding.c | |||
@@ -510,10 +510,10 @@ static u32 batadv_nc_hash_choose(const void *data, u32 size) | |||
510 | * @node: node in the local table | 510 | * @node: node in the local table |
511 | * @data2: second object to compare the node to | 511 | * @data2: second object to compare the node to |
512 | * | 512 | * |
513 | * Return: 1 if the two entry are the same, 0 otherwise | 513 | * Return: true if the two entry are the same, false otherwise |
514 | */ | 514 | */ |
515 | static int batadv_nc_hash_compare(const struct hlist_node *node, | 515 | static bool batadv_nc_hash_compare(const struct hlist_node *node, |
516 | const void *data2) | 516 | const void *data2) |
517 | { | 517 | { |
518 | const struct batadv_nc_path *nc_path1, *nc_path2; | 518 | const struct batadv_nc_path *nc_path1, *nc_path2; |
519 | 519 | ||
@@ -521,15 +521,13 @@ static int batadv_nc_hash_compare(const struct hlist_node *node, | |||
521 | nc_path2 = data2; | 521 | nc_path2 = data2; |
522 | 522 | ||
523 | /* Return 1 if the two keys are identical */ | 523 | /* Return 1 if the two keys are identical */ |
524 | if (memcmp(nc_path1->prev_hop, nc_path2->prev_hop, | 524 | if (!batadv_compare_eth(nc_path1->prev_hop, nc_path2->prev_hop)) |
525 | sizeof(nc_path1->prev_hop)) != 0) | 525 | return false; |
526 | return 0; | ||
527 | 526 | ||
528 | if (memcmp(nc_path1->next_hop, nc_path2->next_hop, | 527 | if (!batadv_compare_eth(nc_path1->next_hop, nc_path2->next_hop)) |
529 | sizeof(nc_path1->next_hop)) != 0) | 528 | return false; |
530 | return 0; | ||
531 | 529 | ||
532 | return 1; | 530 | return true; |
533 | } | 531 | } |
534 | 532 | ||
535 | /** | 533 | /** |
@@ -856,8 +854,7 @@ batadv_nc_get_nc_node(struct batadv_priv *bat_priv, | |||
856 | if (!nc_node) | 854 | if (!nc_node) |
857 | return NULL; | 855 | return NULL; |
858 | 856 | ||
859 | if (!kref_get_unless_zero(&orig_neigh_node->refcount)) | 857 | kref_get(&orig_neigh_node->refcount); |
860 | goto free; | ||
861 | 858 | ||
862 | /* Initialize nc_node */ | 859 | /* Initialize nc_node */ |
863 | INIT_LIST_HEAD(&nc_node->list); | 860 | INIT_LIST_HEAD(&nc_node->list); |
@@ -884,10 +881,6 @@ batadv_nc_get_nc_node(struct batadv_priv *bat_priv, | |||
884 | spin_unlock_bh(lock); | 881 | spin_unlock_bh(lock); |
885 | 882 | ||
886 | return nc_node; | 883 | return nc_node; |
887 | |||
888 | free: | ||
889 | kfree(nc_node); | ||
890 | return NULL; | ||
891 | } | 884 | } |
892 | 885 | ||
893 | /** | 886 | /** |
diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c index f885a41d06d5..1ff4ee473966 100644 --- a/net/batman-adv/originator.c +++ b/net/batman-adv/originator.c | |||
@@ -54,9 +54,9 @@ static void batadv_purge_orig(struct work_struct *work); | |||
54 | * @node: node in the local table | 54 | * @node: node in the local table |
55 | * @data2: second object to compare the node to | 55 | * @data2: second object to compare the node to |
56 | * | 56 | * |
57 | * Return: 1 if they are the same originator | 57 | * Return: true if they are the same originator |
58 | */ | 58 | */ |
59 | int batadv_compare_orig(const struct hlist_node *node, const void *data2) | 59 | bool batadv_compare_orig(const struct hlist_node *node, const void *data2) |
60 | { | 60 | { |
61 | const void *data1 = container_of(node, struct batadv_orig_node, | 61 | const void *data1 = container_of(node, struct batadv_orig_node, |
62 | hash_entry); | 62 | hash_entry); |
@@ -374,12 +374,8 @@ batadv_orig_ifinfo_new(struct batadv_orig_node *orig_node, | |||
374 | if (!orig_ifinfo) | 374 | if (!orig_ifinfo) |
375 | goto out; | 375 | goto out; |
376 | 376 | ||
377 | if (if_outgoing != BATADV_IF_DEFAULT && | 377 | if (if_outgoing != BATADV_IF_DEFAULT) |
378 | !kref_get_unless_zero(&if_outgoing->refcount)) { | 378 | kref_get(&if_outgoing->refcount); |
379 | kfree(orig_ifinfo); | ||
380 | orig_ifinfo = NULL; | ||
381 | goto out; | ||
382 | } | ||
383 | 379 | ||
384 | reset_time = jiffies - 1; | 380 | reset_time = jiffies - 1; |
385 | reset_time -= msecs_to_jiffies(BATADV_RESET_PROTECTION_MS); | 381 | reset_time -= msecs_to_jiffies(BATADV_RESET_PROTECTION_MS); |
@@ -455,11 +451,8 @@ batadv_neigh_ifinfo_new(struct batadv_neigh_node *neigh, | |||
455 | if (!neigh_ifinfo) | 451 | if (!neigh_ifinfo) |
456 | goto out; | 452 | goto out; |
457 | 453 | ||
458 | if (if_outgoing && !kref_get_unless_zero(&if_outgoing->refcount)) { | 454 | if (if_outgoing) |
459 | kfree(neigh_ifinfo); | 455 | kref_get(&if_outgoing->refcount); |
460 | neigh_ifinfo = NULL; | ||
461 | goto out; | ||
462 | } | ||
463 | 456 | ||
464 | INIT_HLIST_NODE(&neigh_ifinfo->list); | 457 | INIT_HLIST_NODE(&neigh_ifinfo->list); |
465 | kref_init(&neigh_ifinfo->refcount); | 458 | kref_init(&neigh_ifinfo->refcount); |
@@ -532,15 +525,11 @@ batadv_hardif_neigh_create(struct batadv_hard_iface *hard_iface, | |||
532 | if (hardif_neigh) | 525 | if (hardif_neigh) |
533 | goto out; | 526 | goto out; |
534 | 527 | ||
535 | if (!kref_get_unless_zero(&hard_iface->refcount)) | ||
536 | goto out; | ||
537 | |||
538 | hardif_neigh = kzalloc(sizeof(*hardif_neigh), GFP_ATOMIC); | 528 | hardif_neigh = kzalloc(sizeof(*hardif_neigh), GFP_ATOMIC); |
539 | if (!hardif_neigh) { | 529 | if (!hardif_neigh) |
540 | batadv_hardif_put(hard_iface); | ||
541 | goto out; | 530 | goto out; |
542 | } | ||
543 | 531 | ||
532 | kref_get(&hard_iface->refcount); | ||
544 | INIT_HLIST_NODE(&hardif_neigh->list); | 533 | INIT_HLIST_NODE(&hardif_neigh->list); |
545 | ether_addr_copy(hardif_neigh->addr, neigh_addr); | 534 | ether_addr_copy(hardif_neigh->addr, neigh_addr); |
546 | hardif_neigh->if_incoming = hard_iface; | 535 | hardif_neigh->if_incoming = hard_iface; |
@@ -643,16 +632,11 @@ batadv_neigh_node_new(struct batadv_orig_node *orig_node, | |||
643 | if (!neigh_node) | 632 | if (!neigh_node) |
644 | goto out; | 633 | goto out; |
645 | 634 | ||
646 | if (!kref_get_unless_zero(&hard_iface->refcount)) { | ||
647 | kfree(neigh_node); | ||
648 | neigh_node = NULL; | ||
649 | goto out; | ||
650 | } | ||
651 | |||
652 | INIT_HLIST_NODE(&neigh_node->list); | 635 | INIT_HLIST_NODE(&neigh_node->list); |
653 | INIT_HLIST_HEAD(&neigh_node->ifinfo_list); | 636 | INIT_HLIST_HEAD(&neigh_node->ifinfo_list); |
654 | spin_lock_init(&neigh_node->ifinfo_lock); | 637 | spin_lock_init(&neigh_node->ifinfo_lock); |
655 | 638 | ||
639 | kref_get(&hard_iface->refcount); | ||
656 | ether_addr_copy(neigh_node->addr, neigh_addr); | 640 | ether_addr_copy(neigh_node->addr, neigh_addr); |
657 | neigh_node->if_incoming = hard_iface; | 641 | neigh_node->if_incoming = hard_iface; |
658 | neigh_node->orig_node = orig_node; | 642 | neigh_node->orig_node = orig_node; |
@@ -1160,6 +1144,9 @@ static bool batadv_purge_orig_node(struct batadv_priv *bat_priv, | |||
1160 | if (hard_iface->soft_iface != bat_priv->soft_iface) | 1144 | if (hard_iface->soft_iface != bat_priv->soft_iface) |
1161 | continue; | 1145 | continue; |
1162 | 1146 | ||
1147 | if (!kref_get_unless_zero(&hard_iface->refcount)) | ||
1148 | continue; | ||
1149 | |||
1163 | best_neigh_node = batadv_find_best_neighbor(bat_priv, | 1150 | best_neigh_node = batadv_find_best_neighbor(bat_priv, |
1164 | orig_node, | 1151 | orig_node, |
1165 | hard_iface); | 1152 | hard_iface); |
@@ -1167,6 +1154,8 @@ static bool batadv_purge_orig_node(struct batadv_priv *bat_priv, | |||
1167 | best_neigh_node); | 1154 | best_neigh_node); |
1168 | if (best_neigh_node) | 1155 | if (best_neigh_node) |
1169 | batadv_neigh_node_put(best_neigh_node); | 1156 | batadv_neigh_node_put(best_neigh_node); |
1157 | |||
1158 | batadv_hardif_put(hard_iface); | ||
1170 | } | 1159 | } |
1171 | rcu_read_unlock(); | 1160 | rcu_read_unlock(); |
1172 | 1161 | ||
diff --git a/net/batman-adv/originator.h b/net/batman-adv/originator.h index 4e8b67f11051..64a8951e5844 100644 --- a/net/batman-adv/originator.h +++ b/net/batman-adv/originator.h | |||
@@ -33,7 +33,7 @@ | |||
33 | 33 | ||
34 | struct seq_file; | 34 | struct seq_file; |
35 | 35 | ||
36 | int batadv_compare_orig(const struct hlist_node *node, const void *data2); | 36 | bool batadv_compare_orig(const struct hlist_node *node, const void *data2); |
37 | int batadv_originator_init(struct batadv_priv *bat_priv); | 37 | int batadv_originator_init(struct batadv_priv *bat_priv); |
38 | void batadv_originator_free(struct batadv_priv *bat_priv); | 38 | void batadv_originator_free(struct batadv_priv *bat_priv); |
39 | void batadv_purge_orig_ref(struct batadv_priv *bat_priv); | 39 | void batadv_purge_orig_ref(struct batadv_priv *bat_priv); |
diff --git a/net/batman-adv/packet.h b/net/batman-adv/packet.h index 0796dfdfbb60..372128ddb474 100644 --- a/net/batman-adv/packet.h +++ b/net/batman-adv/packet.h | |||
@@ -175,6 +175,7 @@ enum batadv_bla_claimframe { | |||
175 | BATADV_CLAIM_TYPE_UNCLAIM = 0x01, | 175 | BATADV_CLAIM_TYPE_UNCLAIM = 0x01, |
176 | BATADV_CLAIM_TYPE_ANNOUNCE = 0x02, | 176 | BATADV_CLAIM_TYPE_ANNOUNCE = 0x02, |
177 | BATADV_CLAIM_TYPE_REQUEST = 0x03, | 177 | BATADV_CLAIM_TYPE_REQUEST = 0x03, |
178 | BATADV_CLAIM_TYPE_LOOPDETECT = 0x04, | ||
178 | }; | 179 | }; |
179 | 180 | ||
180 | /** | 181 | /** |
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index b781bf753250..ae850f2d11cb 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c | |||
@@ -100,10 +100,6 @@ static void _batadv_update_route(struct batadv_priv *bat_priv, | |||
100 | if (curr_router) | 100 | if (curr_router) |
101 | batadv_neigh_node_put(curr_router); | 101 | batadv_neigh_node_put(curr_router); |
102 | 102 | ||
103 | /* increase refcount of new best neighbor */ | ||
104 | if (neigh_node && !kref_get_unless_zero(&neigh_node->refcount)) | ||
105 | neigh_node = NULL; | ||
106 | |||
107 | spin_lock_bh(&orig_node->neigh_list_lock); | 103 | spin_lock_bh(&orig_node->neigh_list_lock); |
108 | /* curr_router used earlier may not be the current orig_ifinfo->router | 104 | /* curr_router used earlier may not be the current orig_ifinfo->router |
109 | * anymore because it was dereferenced outside of the neigh_list_lock | 105 | * anymore because it was dereferenced outside of the neigh_list_lock |
@@ -114,6 +110,10 @@ static void _batadv_update_route(struct batadv_priv *bat_priv, | |||
114 | */ | 110 | */ |
115 | curr_router = rcu_dereference_protected(orig_ifinfo->router, true); | 111 | curr_router = rcu_dereference_protected(orig_ifinfo->router, true); |
116 | 112 | ||
113 | /* increase refcount of new best neighbor */ | ||
114 | if (neigh_node) | ||
115 | kref_get(&neigh_node->refcount); | ||
116 | |||
117 | rcu_assign_pointer(orig_ifinfo->router, neigh_node); | 117 | rcu_assign_pointer(orig_ifinfo->router, neigh_node); |
118 | spin_unlock_bh(&orig_node->neigh_list_lock); | 118 | spin_unlock_bh(&orig_node->neigh_list_lock); |
119 | batadv_orig_ifinfo_put(orig_ifinfo); | 119 | batadv_orig_ifinfo_put(orig_ifinfo); |
@@ -163,18 +163,18 @@ out: | |||
163 | * doesn't change otherwise. | 163 | * doesn't change otherwise. |
164 | * | 164 | * |
165 | * Return: | 165 | * Return: |
166 | * 0 if the packet is to be accepted. | 166 | * false if the packet is to be accepted. |
167 | * 1 if the packet is to be ignored. | 167 | * true if the packet is to be ignored. |
168 | */ | 168 | */ |
169 | int batadv_window_protected(struct batadv_priv *bat_priv, s32 seq_num_diff, | 169 | bool batadv_window_protected(struct batadv_priv *bat_priv, s32 seq_num_diff, |
170 | s32 seq_old_max_diff, unsigned long *last_reset, | 170 | s32 seq_old_max_diff, unsigned long *last_reset, |
171 | bool *protection_started) | 171 | bool *protection_started) |
172 | { | 172 | { |
173 | if (seq_num_diff <= -seq_old_max_diff || | 173 | if (seq_num_diff <= -seq_old_max_diff || |
174 | seq_num_diff >= BATADV_EXPECTED_SEQNO_RANGE) { | 174 | seq_num_diff >= BATADV_EXPECTED_SEQNO_RANGE) { |
175 | if (!batadv_has_timed_out(*last_reset, | 175 | if (!batadv_has_timed_out(*last_reset, |
176 | BATADV_RESET_PROTECTION_MS)) | 176 | BATADV_RESET_PROTECTION_MS)) |
177 | return 1; | 177 | return true; |
178 | 178 | ||
179 | *last_reset = jiffies; | 179 | *last_reset = jiffies; |
180 | if (protection_started) | 180 | if (protection_started) |
@@ -183,7 +183,7 @@ int batadv_window_protected(struct batadv_priv *bat_priv, s32 seq_num_diff, | |||
183 | "old packet received, start protection\n"); | 183 | "old packet received, start protection\n"); |
184 | } | 184 | } |
185 | 185 | ||
186 | return 0; | 186 | return false; |
187 | } | 187 | } |
188 | 188 | ||
189 | bool batadv_check_management_packet(struct sk_buff *skb, | 189 | bool batadv_check_management_packet(struct sk_buff *skb, |
@@ -718,8 +718,9 @@ out: | |||
718 | return ret; | 718 | return ret; |
719 | } | 719 | } |
720 | 720 | ||
721 | static int batadv_check_unicast_ttvn(struct batadv_priv *bat_priv, | 721 | static bool batadv_check_unicast_ttvn(struct batadv_priv *bat_priv, |
722 | struct sk_buff *skb, int hdr_len) { | 722 | struct sk_buff *skb, int hdr_len) |
723 | { | ||
723 | struct batadv_unicast_packet *unicast_packet; | 724 | struct batadv_unicast_packet *unicast_packet; |
724 | struct batadv_hard_iface *primary_if; | 725 | struct batadv_hard_iface *primary_if; |
725 | struct batadv_orig_node *orig_node; | 726 | struct batadv_orig_node *orig_node; |
@@ -730,11 +731,11 @@ static int batadv_check_unicast_ttvn(struct batadv_priv *bat_priv, | |||
730 | 731 | ||
731 | /* check if there is enough data before accessing it */ | 732 | /* check if there is enough data before accessing it */ |
732 | if (!pskb_may_pull(skb, hdr_len + ETH_HLEN)) | 733 | if (!pskb_may_pull(skb, hdr_len + ETH_HLEN)) |
733 | return 0; | 734 | return false; |
734 | 735 | ||
735 | /* create a copy of the skb (in case of for re-routing) to modify it. */ | 736 | /* create a copy of the skb (in case of for re-routing) to modify it. */ |
736 | if (skb_cow(skb, sizeof(*unicast_packet)) < 0) | 737 | if (skb_cow(skb, sizeof(*unicast_packet)) < 0) |
737 | return 0; | 738 | return false; |
738 | 739 | ||
739 | unicast_packet = (struct batadv_unicast_packet *)skb->data; | 740 | unicast_packet = (struct batadv_unicast_packet *)skb->data; |
740 | vid = batadv_get_vid(skb, hdr_len); | 741 | vid = batadv_get_vid(skb, hdr_len); |
@@ -758,7 +759,7 @@ static int batadv_check_unicast_ttvn(struct batadv_priv *bat_priv, | |||
758 | * table. If not, let the packet go untouched anyway because | 759 | * table. If not, let the packet go untouched anyway because |
759 | * there is nothing the node can do | 760 | * there is nothing the node can do |
760 | */ | 761 | */ |
761 | return 1; | 762 | return true; |
762 | } | 763 | } |
763 | 764 | ||
764 | /* retrieve the TTVN known by this node for the packet destination. This | 765 | /* retrieve the TTVN known by this node for the packet destination. This |
@@ -774,7 +775,7 @@ static int batadv_check_unicast_ttvn(struct batadv_priv *bat_priv, | |||
774 | * not be possible to deliver it | 775 | * not be possible to deliver it |
775 | */ | 776 | */ |
776 | if (!orig_node) | 777 | if (!orig_node) |
777 | return 0; | 778 | return false; |
778 | 779 | ||
779 | curr_ttvn = (u8)atomic_read(&orig_node->last_ttvn); | 780 | curr_ttvn = (u8)atomic_read(&orig_node->last_ttvn); |
780 | batadv_orig_node_put(orig_node); | 781 | batadv_orig_node_put(orig_node); |
@@ -785,7 +786,7 @@ static int batadv_check_unicast_ttvn(struct batadv_priv *bat_priv, | |||
785 | */ | 786 | */ |
786 | is_old_ttvn = batadv_seq_before(unicast_packet->ttvn, curr_ttvn); | 787 | is_old_ttvn = batadv_seq_before(unicast_packet->ttvn, curr_ttvn); |
787 | if (!is_old_ttvn) | 788 | if (!is_old_ttvn) |
788 | return 1; | 789 | return true; |
789 | 790 | ||
790 | old_ttvn = unicast_packet->ttvn; | 791 | old_ttvn = unicast_packet->ttvn; |
791 | /* the packet was forged based on outdated network information. Its | 792 | /* the packet was forged based on outdated network information. Its |
@@ -798,7 +799,7 @@ static int batadv_check_unicast_ttvn(struct batadv_priv *bat_priv, | |||
798 | "Rerouting unicast packet to %pM (dst=%pM): TTVN mismatch old_ttvn=%u new_ttvn=%u\n", | 799 | "Rerouting unicast packet to %pM (dst=%pM): TTVN mismatch old_ttvn=%u new_ttvn=%u\n", |
799 | unicast_packet->dest, ethhdr->h_dest, | 800 | unicast_packet->dest, ethhdr->h_dest, |
800 | old_ttvn, curr_ttvn); | 801 | old_ttvn, curr_ttvn); |
801 | return 1; | 802 | return true; |
802 | } | 803 | } |
803 | 804 | ||
804 | /* the packet has not been re-routed: either the destination is | 805 | /* the packet has not been re-routed: either the destination is |
@@ -806,14 +807,14 @@ static int batadv_check_unicast_ttvn(struct batadv_priv *bat_priv, | |||
806 | * it is possible to drop the packet | 807 | * it is possible to drop the packet |
807 | */ | 808 | */ |
808 | if (!batadv_is_my_client(bat_priv, ethhdr->h_dest, vid)) | 809 | if (!batadv_is_my_client(bat_priv, ethhdr->h_dest, vid)) |
809 | return 0; | 810 | return false; |
810 | 811 | ||
811 | /* update the header in order to let the packet be delivered to this | 812 | /* update the header in order to let the packet be delivered to this |
812 | * node's soft interface | 813 | * node's soft interface |
813 | */ | 814 | */ |
814 | primary_if = batadv_primary_if_get_selected(bat_priv); | 815 | primary_if = batadv_primary_if_get_selected(bat_priv); |
815 | if (!primary_if) | 816 | if (!primary_if) |
816 | return 0; | 817 | return false; |
817 | 818 | ||
818 | ether_addr_copy(unicast_packet->dest, primary_if->net_dev->dev_addr); | 819 | ether_addr_copy(unicast_packet->dest, primary_if->net_dev->dev_addr); |
819 | 820 | ||
@@ -821,7 +822,7 @@ static int batadv_check_unicast_ttvn(struct batadv_priv *bat_priv, | |||
821 | 822 | ||
822 | unicast_packet->ttvn = curr_ttvn; | 823 | unicast_packet->ttvn = curr_ttvn; |
823 | 824 | ||
824 | return 1; | 825 | return true; |
825 | } | 826 | } |
826 | 827 | ||
827 | /** | 828 | /** |
@@ -912,7 +913,7 @@ int batadv_recv_unicast_packet(struct sk_buff *skb, | |||
912 | hdr_size)) | 913 | hdr_size)) |
913 | goto rx_success; | 914 | goto rx_success; |
914 | 915 | ||
915 | batadv_interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size, | 916 | batadv_interface_rx(recv_if->soft_iface, skb, hdr_size, |
916 | orig_node); | 917 | orig_node); |
917 | 918 | ||
918 | rx_success: | 919 | rx_success: |
@@ -1122,8 +1123,7 @@ int batadv_recv_bcast_packet(struct sk_buff *skb, | |||
1122 | goto rx_success; | 1123 | goto rx_success; |
1123 | 1124 | ||
1124 | /* broadcast for me */ | 1125 | /* broadcast for me */ |
1125 | batadv_interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size, | 1126 | batadv_interface_rx(recv_if->soft_iface, skb, hdr_size, orig_node); |
1126 | orig_node); | ||
1127 | 1127 | ||
1128 | rx_success: | 1128 | rx_success: |
1129 | ret = NET_RX_SUCCESS; | 1129 | ret = NET_RX_SUCCESS; |
diff --git a/net/batman-adv/routing.h b/net/batman-adv/routing.h index 02a5caa84127..05c3ff42e181 100644 --- a/net/batman-adv/routing.h +++ b/net/batman-adv/routing.h | |||
@@ -51,8 +51,8 @@ struct batadv_neigh_node * | |||
51 | batadv_find_router(struct batadv_priv *bat_priv, | 51 | batadv_find_router(struct batadv_priv *bat_priv, |
52 | struct batadv_orig_node *orig_node, | 52 | struct batadv_orig_node *orig_node, |
53 | struct batadv_hard_iface *recv_if); | 53 | struct batadv_hard_iface *recv_if); |
54 | int batadv_window_protected(struct batadv_priv *bat_priv, s32 seq_num_diff, | 54 | bool batadv_window_protected(struct batadv_priv *bat_priv, s32 seq_num_diff, |
55 | s32 seq_old_max_diff, unsigned long *last_reset, | 55 | s32 seq_old_max_diff, unsigned long *last_reset, |
56 | bool *protection_started); | 56 | bool *protection_started); |
57 | 57 | ||
58 | #endif /* _NET_BATMAN_ADV_ROUTING_H_ */ | 58 | #endif /* _NET_BATMAN_ADV_ROUTING_H_ */ |
diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c index 99ea9001cf8a..f2f125684ed9 100644 --- a/net/batman-adv/send.c +++ b/net/batman-adv/send.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/if.h> | 26 | #include <linux/if.h> |
27 | #include <linux/jiffies.h> | 27 | #include <linux/jiffies.h> |
28 | #include <linux/kernel.h> | 28 | #include <linux/kernel.h> |
29 | #include <linux/kref.h> | ||
29 | #include <linux/list.h> | 30 | #include <linux/list.h> |
30 | #include <linux/netdevice.h> | 31 | #include <linux/netdevice.h> |
31 | #include <linux/printk.h> | 32 | #include <linux/printk.h> |
@@ -577,10 +578,15 @@ static void batadv_send_outstanding_bcast_packet(struct work_struct *work) | |||
577 | if (forw_packet->num_packets >= hard_iface->num_bcasts) | 578 | if (forw_packet->num_packets >= hard_iface->num_bcasts) |
578 | continue; | 579 | continue; |
579 | 580 | ||
581 | if (!kref_get_unless_zero(&hard_iface->refcount)) | ||
582 | continue; | ||
583 | |||
580 | /* send a copy of the saved skb */ | 584 | /* send a copy of the saved skb */ |
581 | skb1 = skb_clone(forw_packet->skb, GFP_ATOMIC); | 585 | skb1 = skb_clone(forw_packet->skb, GFP_ATOMIC); |
582 | if (skb1) | 586 | if (skb1) |
583 | batadv_send_broadcast_skb(skb1, hard_iface); | 587 | batadv_send_broadcast_skb(skb1, hard_iface); |
588 | |||
589 | batadv_hardif_put(hard_iface); | ||
584 | } | 590 | } |
585 | rcu_read_unlock(); | 591 | rcu_read_unlock(); |
586 | 592 | ||
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index dfb4d56120b6..343d2c904399 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c | |||
@@ -186,7 +186,6 @@ static int batadv_interface_tx(struct sk_buff *skb, | |||
186 | struct batadv_priv *bat_priv = netdev_priv(soft_iface); | 186 | struct batadv_priv *bat_priv = netdev_priv(soft_iface); |
187 | struct batadv_hard_iface *primary_if = NULL; | 187 | struct batadv_hard_iface *primary_if = NULL; |
188 | struct batadv_bcast_packet *bcast_packet; | 188 | struct batadv_bcast_packet *bcast_packet; |
189 | __be16 ethertype = htons(ETH_P_BATMAN); | ||
190 | static const u8 stp_addr[ETH_ALEN] = {0x01, 0x80, 0xC2, 0x00, | 189 | static const u8 stp_addr[ETH_ALEN] = {0x01, 0x80, 0xC2, 0x00, |
191 | 0x00, 0x00}; | 190 | 0x00, 0x00}; |
192 | static const u8 ectp_addr[ETH_ALEN] = {0xCF, 0x00, 0x00, 0x00, | 191 | static const u8 ectp_addr[ETH_ALEN] = {0xCF, 0x00, 0x00, 0x00, |
@@ -216,7 +215,8 @@ static int batadv_interface_tx(struct sk_buff *skb, | |||
216 | case ETH_P_8021Q: | 215 | case ETH_P_8021Q: |
217 | vhdr = vlan_eth_hdr(skb); | 216 | vhdr = vlan_eth_hdr(skb); |
218 | 217 | ||
219 | if (vhdr->h_vlan_encapsulated_proto != ethertype) { | 218 | /* drop batman-in-batman packets to prevent loops */ |
219 | if (vhdr->h_vlan_encapsulated_proto != htons(ETH_P_BATMAN)) { | ||
220 | network_offset += VLAN_HLEN; | 220 | network_offset += VLAN_HLEN; |
221 | break; | 221 | break; |
222 | } | 222 | } |
@@ -385,7 +385,6 @@ end: | |||
385 | * batadv_interface_rx - receive ethernet frame on local batman-adv interface | 385 | * batadv_interface_rx - receive ethernet frame on local batman-adv interface |
386 | * @soft_iface: local interface which will receive the ethernet frame | 386 | * @soft_iface: local interface which will receive the ethernet frame |
387 | * @skb: ethernet frame for @soft_iface | 387 | * @skb: ethernet frame for @soft_iface |
388 | * @recv_if: interface on which the batman-adv packet was received | ||
389 | * @hdr_size: size of already parsed batman-adv header | 388 | * @hdr_size: size of already parsed batman-adv header |
390 | * @orig_node: originator from which the batman-adv packet was sent | 389 | * @orig_node: originator from which the batman-adv packet was sent |
391 | * | 390 | * |
@@ -400,12 +399,11 @@ end: | |||
400 | * isolated clients. | 399 | * isolated clients. |
401 | */ | 400 | */ |
402 | void batadv_interface_rx(struct net_device *soft_iface, | 401 | void batadv_interface_rx(struct net_device *soft_iface, |
403 | struct sk_buff *skb, struct batadv_hard_iface *recv_if, | 402 | struct sk_buff *skb, int hdr_size, |
404 | int hdr_size, struct batadv_orig_node *orig_node) | 403 | struct batadv_orig_node *orig_node) |
405 | { | 404 | { |
406 | struct batadv_bcast_packet *batadv_bcast_packet; | 405 | struct batadv_bcast_packet *batadv_bcast_packet; |
407 | struct batadv_priv *bat_priv = netdev_priv(soft_iface); | 406 | struct batadv_priv *bat_priv = netdev_priv(soft_iface); |
408 | __be16 ethertype = htons(ETH_P_BATMAN); | ||
409 | struct vlan_ethhdr *vhdr; | 407 | struct vlan_ethhdr *vhdr; |
410 | struct ethhdr *ethhdr; | 408 | struct ethhdr *ethhdr; |
411 | unsigned short vid; | 409 | unsigned short vid; |
@@ -414,10 +412,6 @@ void batadv_interface_rx(struct net_device *soft_iface, | |||
414 | batadv_bcast_packet = (struct batadv_bcast_packet *)skb->data; | 412 | batadv_bcast_packet = (struct batadv_bcast_packet *)skb->data; |
415 | is_bcast = (batadv_bcast_packet->packet_type == BATADV_BCAST); | 413 | is_bcast = (batadv_bcast_packet->packet_type == BATADV_BCAST); |
416 | 414 | ||
417 | /* check if enough space is available for pulling, and pull */ | ||
418 | if (!pskb_may_pull(skb, hdr_size)) | ||
419 | goto dropped; | ||
420 | |||
421 | skb_pull_rcsum(skb, hdr_size); | 415 | skb_pull_rcsum(skb, hdr_size); |
422 | skb_reset_mac_header(skb); | 416 | skb_reset_mac_header(skb); |
423 | 417 | ||
@@ -439,7 +433,8 @@ void batadv_interface_rx(struct net_device *soft_iface, | |||
439 | 433 | ||
440 | vhdr = (struct vlan_ethhdr *)skb->data; | 434 | vhdr = (struct vlan_ethhdr *)skb->data; |
441 | 435 | ||
442 | if (vhdr->h_vlan_encapsulated_proto != ethertype) | 436 | /* drop batman-in-batman packets to prevent loops */ |
437 | if (vhdr->h_vlan_encapsulated_proto != htons(ETH_P_BATMAN)) | ||
443 | break; | 438 | break; |
444 | 439 | ||
445 | /* fall through */ | 440 | /* fall through */ |
@@ -890,13 +885,14 @@ static int batadv_softif_slave_add(struct net_device *dev, | |||
890 | struct net_device *slave_dev) | 885 | struct net_device *slave_dev) |
891 | { | 886 | { |
892 | struct batadv_hard_iface *hard_iface; | 887 | struct batadv_hard_iface *hard_iface; |
888 | struct net *net = dev_net(dev); | ||
893 | int ret = -EINVAL; | 889 | int ret = -EINVAL; |
894 | 890 | ||
895 | hard_iface = batadv_hardif_get_by_netdev(slave_dev); | 891 | hard_iface = batadv_hardif_get_by_netdev(slave_dev); |
896 | if (!hard_iface || hard_iface->soft_iface) | 892 | if (!hard_iface || hard_iface->soft_iface) |
897 | goto out; | 893 | goto out; |
898 | 894 | ||
899 | ret = batadv_hardif_enable_interface(hard_iface, dev->name); | 895 | ret = batadv_hardif_enable_interface(hard_iface, net, dev->name); |
900 | 896 | ||
901 | out: | 897 | out: |
902 | if (hard_iface) | 898 | if (hard_iface) |
@@ -977,7 +973,7 @@ static void batadv_softif_init_early(struct net_device *dev) | |||
977 | 973 | ||
978 | dev->netdev_ops = &batadv_netdev_ops; | 974 | dev->netdev_ops = &batadv_netdev_ops; |
979 | dev->destructor = batadv_softif_free; | 975 | dev->destructor = batadv_softif_free; |
980 | dev->features |= NETIF_F_HW_VLAN_CTAG_FILTER; | 976 | dev->features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_NETNS_LOCAL; |
981 | dev->priv_flags |= IFF_NO_QUEUE; | 977 | dev->priv_flags |= IFF_NO_QUEUE; |
982 | 978 | ||
983 | /* can't call min_mtu, because the needed variables | 979 | /* can't call min_mtu, because the needed variables |
@@ -993,7 +989,7 @@ static void batadv_softif_init_early(struct net_device *dev) | |||
993 | memset(priv, 0, sizeof(*priv)); | 989 | memset(priv, 0, sizeof(*priv)); |
994 | } | 990 | } |
995 | 991 | ||
996 | struct net_device *batadv_softif_create(const char *name) | 992 | struct net_device *batadv_softif_create(struct net *net, const char *name) |
997 | { | 993 | { |
998 | struct net_device *soft_iface; | 994 | struct net_device *soft_iface; |
999 | int ret; | 995 | int ret; |
@@ -1003,6 +999,8 @@ struct net_device *batadv_softif_create(const char *name) | |||
1003 | if (!soft_iface) | 999 | if (!soft_iface) |
1004 | return NULL; | 1000 | return NULL; |
1005 | 1001 | ||
1002 | dev_net_set(soft_iface, net); | ||
1003 | |||
1006 | soft_iface->rtnl_link_ops = &batadv_link_ops; | 1004 | soft_iface->rtnl_link_ops = &batadv_link_ops; |
1007 | 1005 | ||
1008 | ret = register_netdevice(soft_iface); | 1006 | ret = register_netdevice(soft_iface); |
@@ -1047,12 +1045,12 @@ static void batadv_softif_destroy_netlink(struct net_device *soft_iface, | |||
1047 | unregister_netdevice_queue(soft_iface, head); | 1045 | unregister_netdevice_queue(soft_iface, head); |
1048 | } | 1046 | } |
1049 | 1047 | ||
1050 | int batadv_softif_is_valid(const struct net_device *net_dev) | 1048 | bool batadv_softif_is_valid(const struct net_device *net_dev) |
1051 | { | 1049 | { |
1052 | if (net_dev->netdev_ops->ndo_start_xmit == batadv_interface_tx) | 1050 | if (net_dev->netdev_ops->ndo_start_xmit == batadv_interface_tx) |
1053 | return 1; | 1051 | return true; |
1054 | 1052 | ||
1055 | return 0; | 1053 | return false; |
1056 | } | 1054 | } |
1057 | 1055 | ||
1058 | struct rtnl_link_ops batadv_link_ops __read_mostly = { | 1056 | struct rtnl_link_ops batadv_link_ops __read_mostly = { |
diff --git a/net/batman-adv/soft-interface.h b/net/batman-adv/soft-interface.h index 9ae265703d23..ec303ddbf647 100644 --- a/net/batman-adv/soft-interface.h +++ b/net/batman-adv/soft-interface.h | |||
@@ -20,18 +20,20 @@ | |||
20 | 20 | ||
21 | #include "main.h" | 21 | #include "main.h" |
22 | 22 | ||
23 | #include <linux/types.h> | ||
23 | #include <net/rtnetlink.h> | 24 | #include <net/rtnetlink.h> |
24 | 25 | ||
25 | struct net_device; | 26 | struct net_device; |
27 | struct net; | ||
26 | struct sk_buff; | 28 | struct sk_buff; |
27 | 29 | ||
28 | int batadv_skb_head_push(struct sk_buff *skb, unsigned int len); | 30 | int batadv_skb_head_push(struct sk_buff *skb, unsigned int len); |
29 | void batadv_interface_rx(struct net_device *soft_iface, | 31 | void batadv_interface_rx(struct net_device *soft_iface, |
30 | struct sk_buff *skb, struct batadv_hard_iface *recv_if, | 32 | struct sk_buff *skb, int hdr_size, |
31 | int hdr_size, struct batadv_orig_node *orig_node); | 33 | struct batadv_orig_node *orig_node); |
32 | struct net_device *batadv_softif_create(const char *name); | 34 | struct net_device *batadv_softif_create(struct net *net, const char *name); |
33 | void batadv_softif_destroy_sysfs(struct net_device *soft_iface); | 35 | void batadv_softif_destroy_sysfs(struct net_device *soft_iface); |
34 | int batadv_softif_is_valid(const struct net_device *net_dev); | 36 | bool batadv_softif_is_valid(const struct net_device *net_dev); |
35 | extern struct rtnl_link_ops batadv_link_ops; | 37 | extern struct rtnl_link_ops batadv_link_ops; |
36 | int batadv_softif_create_vlan(struct batadv_priv *bat_priv, unsigned short vid); | 38 | int batadv_softif_create_vlan(struct batadv_priv *bat_priv, unsigned short vid); |
37 | void batadv_softif_vlan_put(struct batadv_softif_vlan *softif_vlan); | 39 | void batadv_softif_vlan_put(struct batadv_softif_vlan *softif_vlan); |
diff --git a/net/batman-adv/sysfs.c b/net/batman-adv/sysfs.c index e7cf51333a36..414b2074165f 100644 --- a/net/batman-adv/sysfs.c +++ b/net/batman-adv/sysfs.c | |||
@@ -116,11 +116,13 @@ batadv_kobj_to_vlan(struct batadv_priv *bat_priv, struct kobject *obj) | |||
116 | static char *batadv_uev_action_str[] = { | 116 | static char *batadv_uev_action_str[] = { |
117 | "add", | 117 | "add", |
118 | "del", | 118 | "del", |
119 | "change" | 119 | "change", |
120 | "loopdetect", | ||
120 | }; | 121 | }; |
121 | 122 | ||
122 | static char *batadv_uev_type_str[] = { | 123 | static char *batadv_uev_type_str[] = { |
123 | "gw" | 124 | "gw", |
125 | "bla", | ||
124 | }; | 126 | }; |
125 | 127 | ||
126 | /* Use this, if you have customized show and store functions for vlan attrs */ | 128 | /* Use this, if you have customized show and store functions for vlan attrs */ |
@@ -830,6 +832,7 @@ static ssize_t batadv_store_mesh_iface(struct kobject *kobj, | |||
830 | size_t count) | 832 | size_t count) |
831 | { | 833 | { |
832 | struct net_device *net_dev = batadv_kobj_to_netdev(kobj); | 834 | struct net_device *net_dev = batadv_kobj_to_netdev(kobj); |
835 | struct net *net = dev_net(net_dev); | ||
833 | struct batadv_hard_iface *hard_iface; | 836 | struct batadv_hard_iface *hard_iface; |
834 | int status_tmp = -1; | 837 | int status_tmp = -1; |
835 | int ret = count; | 838 | int ret = count; |
@@ -873,7 +876,7 @@ static ssize_t batadv_store_mesh_iface(struct kobject *kobj, | |||
873 | batadv_hardif_disable_interface(hard_iface, | 876 | batadv_hardif_disable_interface(hard_iface, |
874 | BATADV_IF_CLEANUP_AUTO); | 877 | BATADV_IF_CLEANUP_AUTO); |
875 | 878 | ||
876 | ret = batadv_hardif_enable_interface(hard_iface, buff); | 879 | ret = batadv_hardif_enable_interface(hard_iface, net, buff); |
877 | 880 | ||
878 | unlock: | 881 | unlock: |
879 | rtnl_unlock(); | 882 | rtnl_unlock(); |
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index 942b3aa00bed..feaf492b01ca 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c | |||
@@ -43,7 +43,6 @@ | |||
43 | #include <linux/stddef.h> | 43 | #include <linux/stddef.h> |
44 | #include <linux/string.h> | 44 | #include <linux/string.h> |
45 | #include <linux/workqueue.h> | 45 | #include <linux/workqueue.h> |
46 | #include <net/net_namespace.h> | ||
47 | 46 | ||
48 | #include "bridge_loop_avoidance.h" | 47 | #include "bridge_loop_avoidance.h" |
49 | #include "hard-interface.h" | 48 | #include "hard-interface.h" |
@@ -76,9 +75,9 @@ static void batadv_tt_global_del(struct batadv_priv *bat_priv, | |||
76 | * | 75 | * |
77 | * Compare the MAC address and the VLAN ID of the two TT entries and check if | 76 | * Compare the MAC address and the VLAN ID of the two TT entries and check if |
78 | * they are the same TT client. | 77 | * they are the same TT client. |
79 | * Return: 1 if the two TT clients are the same, 0 otherwise | 78 | * Return: true if the two TT clients are the same, false otherwise |
80 | */ | 79 | */ |
81 | static int batadv_compare_tt(const struct hlist_node *node, const void *data2) | 80 | static bool batadv_compare_tt(const struct hlist_node *node, const void *data2) |
82 | { | 81 | { |
83 | const void *data1 = container_of(node, struct batadv_tt_common_entry, | 82 | const void *data1 = container_of(node, struct batadv_tt_common_entry, |
84 | hash_entry); | 83 | hash_entry); |
@@ -585,6 +584,7 @@ bool batadv_tt_local_add(struct net_device *soft_iface, const u8 *addr, | |||
585 | struct batadv_priv *bat_priv = netdev_priv(soft_iface); | 584 | struct batadv_priv *bat_priv = netdev_priv(soft_iface); |
586 | struct batadv_tt_local_entry *tt_local; | 585 | struct batadv_tt_local_entry *tt_local; |
587 | struct batadv_tt_global_entry *tt_global = NULL; | 586 | struct batadv_tt_global_entry *tt_global = NULL; |
587 | struct net *net = dev_net(soft_iface); | ||
588 | struct batadv_softif_vlan *vlan; | 588 | struct batadv_softif_vlan *vlan; |
589 | struct net_device *in_dev = NULL; | 589 | struct net_device *in_dev = NULL; |
590 | struct hlist_head *head; | 590 | struct hlist_head *head; |
@@ -596,7 +596,7 @@ bool batadv_tt_local_add(struct net_device *soft_iface, const u8 *addr, | |||
596 | u32 match_mark; | 596 | u32 match_mark; |
597 | 597 | ||
598 | if (ifindex != BATADV_NULL_IFINDEX) | 598 | if (ifindex != BATADV_NULL_IFINDEX) |
599 | in_dev = dev_get_by_index(&init_net, ifindex); | 599 | in_dev = dev_get_by_index(net, ifindex); |
600 | 600 | ||
601 | tt_local = batadv_tt_local_hash_find(bat_priv, addr, vid); | 601 | tt_local = batadv_tt_local_hash_find(bat_priv, addr, vid); |
602 | 602 | ||
@@ -2361,19 +2361,19 @@ unlock: | |||
2361 | * @entry_ptr: to be checked local tt entry | 2361 | * @entry_ptr: to be checked local tt entry |
2362 | * @data_ptr: not used but definition required to satisfy the callback prototype | 2362 | * @data_ptr: not used but definition required to satisfy the callback prototype |
2363 | * | 2363 | * |
2364 | * Return: 1 if the entry is a valid, 0 otherwise. | 2364 | * Return: true if the entry is a valid, false otherwise. |
2365 | */ | 2365 | */ |
2366 | static int batadv_tt_local_valid(const void *entry_ptr, const void *data_ptr) | 2366 | static bool batadv_tt_local_valid(const void *entry_ptr, const void *data_ptr) |
2367 | { | 2367 | { |
2368 | const struct batadv_tt_common_entry *tt_common_entry = entry_ptr; | 2368 | const struct batadv_tt_common_entry *tt_common_entry = entry_ptr; |
2369 | 2369 | ||
2370 | if (tt_common_entry->flags & BATADV_TT_CLIENT_NEW) | 2370 | if (tt_common_entry->flags & BATADV_TT_CLIENT_NEW) |
2371 | return 0; | 2371 | return false; |
2372 | return 1; | 2372 | return true; |
2373 | } | 2373 | } |
2374 | 2374 | ||
2375 | static int batadv_tt_global_valid(const void *entry_ptr, | 2375 | static bool batadv_tt_global_valid(const void *entry_ptr, |
2376 | const void *data_ptr) | 2376 | const void *data_ptr) |
2377 | { | 2377 | { |
2378 | const struct batadv_tt_common_entry *tt_common_entry = entry_ptr; | 2378 | const struct batadv_tt_common_entry *tt_common_entry = entry_ptr; |
2379 | const struct batadv_tt_global_entry *tt_global_entry; | 2379 | const struct batadv_tt_global_entry *tt_global_entry; |
@@ -2381,7 +2381,7 @@ static int batadv_tt_global_valid(const void *entry_ptr, | |||
2381 | 2381 | ||
2382 | if (tt_common_entry->flags & BATADV_TT_CLIENT_ROAM || | 2382 | if (tt_common_entry->flags & BATADV_TT_CLIENT_ROAM || |
2383 | tt_common_entry->flags & BATADV_TT_CLIENT_TEMP) | 2383 | tt_common_entry->flags & BATADV_TT_CLIENT_TEMP) |
2384 | return 0; | 2384 | return false; |
2385 | 2385 | ||
2386 | tt_global_entry = container_of(tt_common_entry, | 2386 | tt_global_entry = container_of(tt_common_entry, |
2387 | struct batadv_tt_global_entry, | 2387 | struct batadv_tt_global_entry, |
@@ -2403,7 +2403,8 @@ static int batadv_tt_global_valid(const void *entry_ptr, | |||
2403 | static void batadv_tt_tvlv_generate(struct batadv_priv *bat_priv, | 2403 | static void batadv_tt_tvlv_generate(struct batadv_priv *bat_priv, |
2404 | struct batadv_hashtable *hash, | 2404 | struct batadv_hashtable *hash, |
2405 | void *tvlv_buff, u16 tt_len, | 2405 | void *tvlv_buff, u16 tt_len, |
2406 | int (*valid_cb)(const void *, const void *), | 2406 | bool (*valid_cb)(const void *, |
2407 | const void *), | ||
2407 | void *cb_data) | 2408 | void *cb_data) |
2408 | { | 2409 | { |
2409 | struct batadv_tt_common_entry *tt_common_entry; | 2410 | struct batadv_tt_common_entry *tt_common_entry; |
@@ -2552,11 +2553,11 @@ static void batadv_tt_global_update_crc(struct batadv_priv *bat_priv, | |||
2552 | * | 2553 | * |
2553 | * Return: true if the TT Request was sent, false otherwise | 2554 | * Return: true if the TT Request was sent, false otherwise |
2554 | */ | 2555 | */ |
2555 | static int batadv_send_tt_request(struct batadv_priv *bat_priv, | 2556 | static bool batadv_send_tt_request(struct batadv_priv *bat_priv, |
2556 | struct batadv_orig_node *dst_orig_node, | 2557 | struct batadv_orig_node *dst_orig_node, |
2557 | u8 ttvn, | 2558 | u8 ttvn, |
2558 | struct batadv_tvlv_tt_vlan_data *tt_vlan, | 2559 | struct batadv_tvlv_tt_vlan_data *tt_vlan, |
2559 | u16 num_vlan, bool full_table) | 2560 | u16 num_vlan, bool full_table) |
2560 | { | 2561 | { |
2561 | struct batadv_tvlv_tt_data *tvlv_tt_data = NULL; | 2562 | struct batadv_tvlv_tt_data *tvlv_tt_data = NULL; |
2562 | struct batadv_tt_req_node *tt_req_node = NULL; | 2563 | struct batadv_tt_req_node *tt_req_node = NULL; |
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h index 1e47fbe8bb7b..6a577f4f8ba7 100644 --- a/net/batman-adv/types.h +++ b/net/batman-adv/types.h | |||
@@ -657,6 +657,9 @@ struct batadv_priv_tt { | |||
657 | * @num_requests: number of bla requests in flight | 657 | * @num_requests: number of bla requests in flight |
658 | * @claim_hash: hash table containing mesh nodes this host has claimed | 658 | * @claim_hash: hash table containing mesh nodes this host has claimed |
659 | * @backbone_hash: hash table containing all detected backbone gateways | 659 | * @backbone_hash: hash table containing all detected backbone gateways |
660 | * @loopdetect_addr: MAC address used for own loopdetection frames | ||
661 | * @loopdetect_lasttime: time when the loopdetection frames were sent | ||
662 | * @loopdetect_next: how many periods to wait for the next loopdetect process | ||
660 | * @bcast_duplist: recently received broadcast packets array (for broadcast | 663 | * @bcast_duplist: recently received broadcast packets array (for broadcast |
661 | * duplicate suppression) | 664 | * duplicate suppression) |
662 | * @bcast_duplist_curr: index of last broadcast packet added to bcast_duplist | 665 | * @bcast_duplist_curr: index of last broadcast packet added to bcast_duplist |
@@ -668,6 +671,9 @@ struct batadv_priv_bla { | |||
668 | atomic_t num_requests; | 671 | atomic_t num_requests; |
669 | struct batadv_hashtable *claim_hash; | 672 | struct batadv_hashtable *claim_hash; |
670 | struct batadv_hashtable *backbone_hash; | 673 | struct batadv_hashtable *backbone_hash; |
674 | u8 loopdetect_addr[ETH_ALEN]; | ||
675 | unsigned long loopdetect_lasttime; | ||
676 | atomic_t loopdetect_next; | ||
671 | struct batadv_bcast_duplist_entry bcast_duplist[BATADV_DUPLIST_SIZE]; | 677 | struct batadv_bcast_duplist_entry bcast_duplist[BATADV_DUPLIST_SIZE]; |
672 | int bcast_duplist_curr; | 678 | int bcast_duplist_curr; |
673 | /* protects bcast_duplist & bcast_duplist_curr */ | 679 | /* protects bcast_duplist & bcast_duplist_curr */ |
@@ -1012,6 +1018,7 @@ struct batadv_socket_packet { | |||
1012 | * resolved | 1018 | * resolved |
1013 | * @crc: crc16 checksum over all claims | 1019 | * @crc: crc16 checksum over all claims |
1014 | * @crc_lock: lock protecting crc | 1020 | * @crc_lock: lock protecting crc |
1021 | * @report_work: work struct for reporting detected loops | ||
1015 | * @refcount: number of contexts the object is used | 1022 | * @refcount: number of contexts the object is used |
1016 | * @rcu: struct used for freeing in an RCU-safe manner | 1023 | * @rcu: struct used for freeing in an RCU-safe manner |
1017 | */ | 1024 | */ |
@@ -1025,6 +1032,7 @@ struct batadv_bla_backbone_gw { | |||
1025 | atomic_t request_sent; | 1032 | atomic_t request_sent; |
1026 | u16 crc; | 1033 | u16 crc; |
1027 | spinlock_t crc_lock; /* protects crc */ | 1034 | spinlock_t crc_lock; /* protects crc */ |
1035 | struct work_struct report_work; | ||
1028 | struct kref refcount; | 1036 | struct kref refcount; |
1029 | struct rcu_head rcu; | 1037 | struct rcu_head rcu; |
1030 | }; | 1038 | }; |