aboutsummaryrefslogtreecommitdiffstats
path: root/net/batman-adv
diff options
context:
space:
mode:
Diffstat (limited to 'net/batman-adv')
-rw-r--r--net/batman-adv/bat_iv_ogm.c99
-rw-r--r--net/batman-adv/bitarray.h6
-rw-r--r--net/batman-adv/bridge_loop_avoidance.c214
-rw-r--r--net/batman-adv/bridge_loop_avoidance.h11
-rw-r--r--net/batman-adv/debugfs.c12
-rw-r--r--net/batman-adv/gateway_client.c53
-rw-r--r--net/batman-adv/hard-interface.c13
-rw-r--r--net/batman-adv/main.c27
-rw-r--r--net/batman-adv/main.h29
-rw-r--r--net/batman-adv/packet.h35
-rw-r--r--net/batman-adv/routing.c85
-rw-r--r--net/batman-adv/send.c8
-rw-r--r--net/batman-adv/soft-interface.c86
-rw-r--r--net/batman-adv/soft-interface.h5
-rw-r--r--net/batman-adv/translation-table.c416
-rw-r--r--net/batman-adv/translation-table.h4
-rw-r--r--net/batman-adv/types.h120
-rw-r--r--net/batman-adv/unicast.c16
-rw-r--r--net/batman-adv/vis.c144
-rw-r--r--net/batman-adv/vis.h2
20 files changed, 825 insertions, 560 deletions
diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c
index e877af8bdd1..b02b75dae3a 100644
--- a/net/batman-adv/bat_iv_ogm.c
+++ b/net/batman-adv/bat_iv_ogm.c
@@ -166,13 +166,15 @@ static void batadv_iv_ogm_send_to_if(struct batadv_forw_packet *forw_packet,
166 int16_t buff_pos; 166 int16_t buff_pos;
167 struct batadv_ogm_packet *batadv_ogm_packet; 167 struct batadv_ogm_packet *batadv_ogm_packet;
168 struct sk_buff *skb; 168 struct sk_buff *skb;
169 uint8_t *packet_pos;
169 170
170 if (hard_iface->if_status != BATADV_IF_ACTIVE) 171 if (hard_iface->if_status != BATADV_IF_ACTIVE)
171 return; 172 return;
172 173
173 packet_num = 0; 174 packet_num = 0;
174 buff_pos = 0; 175 buff_pos = 0;
175 batadv_ogm_packet = (struct batadv_ogm_packet *)forw_packet->skb->data; 176 packet_pos = forw_packet->skb->data;
177 batadv_ogm_packet = (struct batadv_ogm_packet *)packet_pos;
176 178
177 /* adjust all flags and log packets */ 179 /* adjust all flags and log packets */
178 while (batadv_iv_ogm_aggr_packet(buff_pos, forw_packet->packet_len, 180 while (batadv_iv_ogm_aggr_packet(buff_pos, forw_packet->packet_len,
@@ -181,15 +183,17 @@ static void batadv_iv_ogm_send_to_if(struct batadv_forw_packet *forw_packet,
181 /* we might have aggregated direct link packets with an 183 /* we might have aggregated direct link packets with an
182 * ordinary base packet 184 * ordinary base packet
183 */ 185 */
184 if ((forw_packet->direct_link_flags & (1 << packet_num)) && 186 if (forw_packet->direct_link_flags & BIT(packet_num) &&
185 (forw_packet->if_incoming == hard_iface)) 187 forw_packet->if_incoming == hard_iface)
186 batadv_ogm_packet->flags |= BATADV_DIRECTLINK; 188 batadv_ogm_packet->flags |= BATADV_DIRECTLINK;
187 else 189 else
188 batadv_ogm_packet->flags &= ~BATADV_DIRECTLINK; 190 batadv_ogm_packet->flags &= ~BATADV_DIRECTLINK;
189 191
190 fwd_str = (packet_num > 0 ? "Forwarding" : (forw_packet->own ? 192 if (packet_num > 0 || !forw_packet->own)
191 "Sending own" : 193 fwd_str = "Forwarding";
192 "Forwarding")); 194 else
195 fwd_str = "Sending own";
196
193 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, 197 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
194 "%s %spacket (originator %pM, seqno %u, TQ %d, TTL %d, IDF %s, ttvn %d) on interface %s [%pM]\n", 198 "%s %spacket (originator %pM, seqno %u, TQ %d, TTL %d, IDF %s, ttvn %d) on interface %s [%pM]\n",
195 fwd_str, (packet_num > 0 ? "aggregated " : ""), 199 fwd_str, (packet_num > 0 ? "aggregated " : ""),
@@ -204,8 +208,8 @@ static void batadv_iv_ogm_send_to_if(struct batadv_forw_packet *forw_packet,
204 buff_pos += BATADV_OGM_HLEN; 208 buff_pos += BATADV_OGM_HLEN;
205 buff_pos += batadv_tt_len(batadv_ogm_packet->tt_num_changes); 209 buff_pos += batadv_tt_len(batadv_ogm_packet->tt_num_changes);
206 packet_num++; 210 packet_num++;
207 batadv_ogm_packet = (struct batadv_ogm_packet *) 211 packet_pos = forw_packet->skb->data + buff_pos;
208 (forw_packet->skb->data + buff_pos); 212 batadv_ogm_packet = (struct batadv_ogm_packet *)packet_pos;
209 } 213 }
210 214
211 /* create clone because function is called more than once */ 215 /* create clone because function is called more than once */
@@ -227,9 +231,10 @@ static void batadv_iv_ogm_emit(struct batadv_forw_packet *forw_packet)
227 struct batadv_hard_iface *primary_if = NULL; 231 struct batadv_hard_iface *primary_if = NULL;
228 struct batadv_ogm_packet *batadv_ogm_packet; 232 struct batadv_ogm_packet *batadv_ogm_packet;
229 unsigned char directlink; 233 unsigned char directlink;
234 uint8_t *packet_pos;
230 235
231 batadv_ogm_packet = (struct batadv_ogm_packet *) 236 packet_pos = forw_packet->skb->data;
232 (forw_packet->skb->data); 237 batadv_ogm_packet = (struct batadv_ogm_packet *)packet_pos;
233 directlink = (batadv_ogm_packet->flags & BATADV_DIRECTLINK ? 1 : 0); 238 directlink = (batadv_ogm_packet->flags & BATADV_DIRECTLINK ? 1 : 0);
234 239
235 if (!forw_packet->if_incoming) { 240 if (!forw_packet->if_incoming) {
@@ -454,6 +459,7 @@ static void batadv_iv_ogm_aggregate(struct batadv_forw_packet *forw_packet_aggr,
454 int packet_len, bool direct_link) 459 int packet_len, bool direct_link)
455{ 460{
456 unsigned char *skb_buff; 461 unsigned char *skb_buff;
462 unsigned long new_direct_link_flag;
457 463
458 skb_buff = skb_put(forw_packet_aggr->skb, packet_len); 464 skb_buff = skb_put(forw_packet_aggr->skb, packet_len);
459 memcpy(skb_buff, packet_buff, packet_len); 465 memcpy(skb_buff, packet_buff, packet_len);
@@ -461,9 +467,10 @@ static void batadv_iv_ogm_aggregate(struct batadv_forw_packet *forw_packet_aggr,
461 forw_packet_aggr->num_packets++; 467 forw_packet_aggr->num_packets++;
462 468
463 /* save packet direct link flag status */ 469 /* save packet direct link flag status */
464 if (direct_link) 470 if (direct_link) {
465 forw_packet_aggr->direct_link_flags |= 471 new_direct_link_flag = BIT(forw_packet_aggr->num_packets);
466 (1 << forw_packet_aggr->num_packets); 472 forw_packet_aggr->direct_link_flags |= new_direct_link_flag;
473 }
467} 474}
468 475
469static void batadv_iv_ogm_queue_add(struct batadv_priv *bat_priv, 476static void batadv_iv_ogm_queue_add(struct batadv_priv *bat_priv,
@@ -586,6 +593,8 @@ static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
586 struct batadv_ogm_packet *batadv_ogm_packet; 593 struct batadv_ogm_packet *batadv_ogm_packet;
587 struct batadv_hard_iface *primary_if; 594 struct batadv_hard_iface *primary_if;
588 int vis_server, tt_num_changes = 0; 595 int vis_server, tt_num_changes = 0;
596 uint32_t seqno;
597 uint8_t bandwidth;
589 598
590 vis_server = atomic_read(&bat_priv->vis_mode); 599 vis_server = atomic_read(&bat_priv->vis_mode);
591 primary_if = batadv_primary_if_get_selected(bat_priv); 600 primary_if = batadv_primary_if_get_selected(bat_priv);
@@ -599,12 +608,12 @@ static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
599 batadv_ogm_packet = (struct batadv_ogm_packet *)hard_iface->packet_buff; 608 batadv_ogm_packet = (struct batadv_ogm_packet *)hard_iface->packet_buff;
600 609
601 /* change sequence number to network order */ 610 /* change sequence number to network order */
602 batadv_ogm_packet->seqno = 611 seqno = (uint32_t)atomic_read(&hard_iface->seqno);
603 htonl((uint32_t)atomic_read(&hard_iface->seqno)); 612 batadv_ogm_packet->seqno = htonl(seqno);
604 atomic_inc(&hard_iface->seqno); 613 atomic_inc(&hard_iface->seqno);
605 614
606 batadv_ogm_packet->ttvn = atomic_read(&bat_priv->ttvn); 615 batadv_ogm_packet->ttvn = atomic_read(&bat_priv->tt.vn);
607 batadv_ogm_packet->tt_crc = htons(bat_priv->tt_crc); 616 batadv_ogm_packet->tt_crc = htons(bat_priv->tt.local_crc);
608 if (tt_num_changes >= 0) 617 if (tt_num_changes >= 0)
609 batadv_ogm_packet->tt_num_changes = tt_num_changes; 618 batadv_ogm_packet->tt_num_changes = tt_num_changes;
610 619
@@ -613,12 +622,13 @@ static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
613 else 622 else
614 batadv_ogm_packet->flags &= ~BATADV_VIS_SERVER; 623 batadv_ogm_packet->flags &= ~BATADV_VIS_SERVER;
615 624
616 if ((hard_iface == primary_if) && 625 if (hard_iface == primary_if &&
617 (atomic_read(&bat_priv->gw_mode) == BATADV_GW_MODE_SERVER)) 626 atomic_read(&bat_priv->gw_mode) == BATADV_GW_MODE_SERVER) {
618 batadv_ogm_packet->gw_flags = 627 bandwidth = (uint8_t)atomic_read(&bat_priv->gw_bandwidth);
619 (uint8_t)atomic_read(&bat_priv->gw_bandwidth); 628 batadv_ogm_packet->gw_flags = bandwidth;
620 else 629 } else {
621 batadv_ogm_packet->gw_flags = BATADV_NO_FLAGS; 630 batadv_ogm_packet->gw_flags = BATADV_NO_FLAGS;
631 }
622 632
623 batadv_slide_own_bcast_window(hard_iface); 633 batadv_slide_own_bcast_window(hard_iface);
624 batadv_iv_ogm_queue_add(bat_priv, hard_iface->packet_buff, 634 batadv_iv_ogm_queue_add(bat_priv, hard_iface->packet_buff,
@@ -642,8 +652,10 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv,
642 struct batadv_neigh_node *router = NULL; 652 struct batadv_neigh_node *router = NULL;
643 struct batadv_orig_node *orig_node_tmp; 653 struct batadv_orig_node *orig_node_tmp;
644 struct hlist_node *node; 654 struct hlist_node *node;
645 uint8_t bcast_own_sum_orig, bcast_own_sum_neigh; 655 int if_num;
656 uint8_t sum_orig, sum_neigh;
646 uint8_t *neigh_addr; 657 uint8_t *neigh_addr;
658 uint8_t tq_avg;
647 659
648 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, 660 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
649 "update_originator(): Searching and updating originator entry of received packet\n"); 661 "update_originator(): Searching and updating originator entry of received packet\n");
@@ -667,8 +679,8 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv,
667 spin_lock_bh(&tmp_neigh_node->lq_update_lock); 679 spin_lock_bh(&tmp_neigh_node->lq_update_lock);
668 batadv_ring_buffer_set(tmp_neigh_node->tq_recv, 680 batadv_ring_buffer_set(tmp_neigh_node->tq_recv,
669 &tmp_neigh_node->tq_index, 0); 681 &tmp_neigh_node->tq_index, 0);
670 tmp_neigh_node->tq_avg = 682 tq_avg = batadv_ring_buffer_avg(tmp_neigh_node->tq_recv);
671 batadv_ring_buffer_avg(tmp_neigh_node->tq_recv); 683 tmp_neigh_node->tq_avg = tq_avg;
672 spin_unlock_bh(&tmp_neigh_node->lq_update_lock); 684 spin_unlock_bh(&tmp_neigh_node->lq_update_lock);
673 } 685 }
674 686
@@ -727,17 +739,17 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv,
727 if (router && (neigh_node->tq_avg == router->tq_avg)) { 739 if (router && (neigh_node->tq_avg == router->tq_avg)) {
728 orig_node_tmp = router->orig_node; 740 orig_node_tmp = router->orig_node;
729 spin_lock_bh(&orig_node_tmp->ogm_cnt_lock); 741 spin_lock_bh(&orig_node_tmp->ogm_cnt_lock);
730 bcast_own_sum_orig = 742 if_num = router->if_incoming->if_num;
731 orig_node_tmp->bcast_own_sum[if_incoming->if_num]; 743 sum_orig = orig_node_tmp->bcast_own_sum[if_num];
732 spin_unlock_bh(&orig_node_tmp->ogm_cnt_lock); 744 spin_unlock_bh(&orig_node_tmp->ogm_cnt_lock);
733 745
734 orig_node_tmp = neigh_node->orig_node; 746 orig_node_tmp = neigh_node->orig_node;
735 spin_lock_bh(&orig_node_tmp->ogm_cnt_lock); 747 spin_lock_bh(&orig_node_tmp->ogm_cnt_lock);
736 bcast_own_sum_neigh = 748 if_num = neigh_node->if_incoming->if_num;
737 orig_node_tmp->bcast_own_sum[if_incoming->if_num]; 749 sum_neigh = orig_node_tmp->bcast_own_sum[if_num];
738 spin_unlock_bh(&orig_node_tmp->ogm_cnt_lock); 750 spin_unlock_bh(&orig_node_tmp->ogm_cnt_lock);
739 751
740 if (bcast_own_sum_orig >= bcast_own_sum_neigh) 752 if (sum_orig >= sum_neigh)
741 goto update_tt; 753 goto update_tt;
742 } 754 }
743 755
@@ -835,8 +847,10 @@ static int batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node,
835 spin_unlock_bh(&orig_node->ogm_cnt_lock); 847 spin_unlock_bh(&orig_node->ogm_cnt_lock);
836 848
837 /* pay attention to not get a value bigger than 100 % */ 849 /* pay attention to not get a value bigger than 100 % */
838 total_count = (orig_eq_count > neigh_rq_count ? 850 if (orig_eq_count > neigh_rq_count)
839 neigh_rq_count : orig_eq_count); 851 total_count = neigh_rq_count;
852 else
853 total_count = orig_eq_count;
840 854
841 /* if we have too few packets (too less data) we set tq_own to zero 855 /* if we have too few packets (too less data) we set tq_own to zero
842 * if we receive too few packets it is not considered bidirectional 856 * if we receive too few packets it is not considered bidirectional
@@ -910,6 +924,7 @@ batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr,
910 int set_mark, ret = -1; 924 int set_mark, ret = -1;
911 uint32_t seqno = ntohl(batadv_ogm_packet->seqno); 925 uint32_t seqno = ntohl(batadv_ogm_packet->seqno);
912 uint8_t *neigh_addr; 926 uint8_t *neigh_addr;
927 uint8_t packet_count;
913 928
914 orig_node = batadv_get_orig_node(bat_priv, batadv_ogm_packet->orig); 929 orig_node = batadv_get_orig_node(bat_priv, batadv_ogm_packet->orig);
915 if (!orig_node) 930 if (!orig_node)
@@ -944,9 +959,9 @@ batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr,
944 tmp_neigh_node->real_bits, 959 tmp_neigh_node->real_bits,
945 seq_diff, set_mark); 960 seq_diff, set_mark);
946 961
947 tmp_neigh_node->real_packet_count = 962 packet_count = bitmap_weight(tmp_neigh_node->real_bits,
948 bitmap_weight(tmp_neigh_node->real_bits, 963 BATADV_TQ_LOCAL_WINDOW_SIZE);
949 BATADV_TQ_LOCAL_WINDOW_SIZE); 964 tmp_neigh_node->real_packet_count = packet_count;
950 } 965 }
951 rcu_read_unlock(); 966 rcu_read_unlock();
952 967
@@ -1163,9 +1178,12 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr,
1163 /* if sender is a direct neighbor the sender mac equals 1178 /* if sender is a direct neighbor the sender mac equals
1164 * originator mac 1179 * originator mac
1165 */ 1180 */
1166 orig_neigh_node = (is_single_hop_neigh ? 1181 if (is_single_hop_neigh)
1167 orig_node : 1182 orig_neigh_node = orig_node;
1168 batadv_get_orig_node(bat_priv, ethhdr->h_source)); 1183 else
1184 orig_neigh_node = batadv_get_orig_node(bat_priv,
1185 ethhdr->h_source);
1186
1169 if (!orig_neigh_node) 1187 if (!orig_neigh_node)
1170 goto out; 1188 goto out;
1171 1189
@@ -1251,6 +1269,7 @@ static int batadv_iv_ogm_receive(struct sk_buff *skb,
1251 int buff_pos = 0, packet_len; 1269 int buff_pos = 0, packet_len;
1252 unsigned char *tt_buff, *packet_buff; 1270 unsigned char *tt_buff, *packet_buff;
1253 bool ret; 1271 bool ret;
1272 uint8_t *packet_pos;
1254 1273
1255 ret = batadv_check_management_packet(skb, if_incoming, BATADV_OGM_HLEN); 1274 ret = batadv_check_management_packet(skb, if_incoming, BATADV_OGM_HLEN);
1256 if (!ret) 1275 if (!ret)
@@ -1281,8 +1300,8 @@ static int batadv_iv_ogm_receive(struct sk_buff *skb,
1281 buff_pos += BATADV_OGM_HLEN; 1300 buff_pos += BATADV_OGM_HLEN;
1282 buff_pos += batadv_tt_len(batadv_ogm_packet->tt_num_changes); 1301 buff_pos += batadv_tt_len(batadv_ogm_packet->tt_num_changes);
1283 1302
1284 batadv_ogm_packet = (struct batadv_ogm_packet *) 1303 packet_pos = packet_buff + buff_pos;
1285 (packet_buff + buff_pos); 1304 batadv_ogm_packet = (struct batadv_ogm_packet *)packet_pos;
1286 } while (batadv_iv_ogm_aggr_packet(buff_pos, packet_len, 1305 } while (batadv_iv_ogm_aggr_packet(buff_pos, packet_len,
1287 batadv_ogm_packet->tt_num_changes)); 1306 batadv_ogm_packet->tt_num_changes));
1288 1307
diff --git a/net/batman-adv/bitarray.h b/net/batman-adv/bitarray.h
index a081ce1c051..cebaae7e148 100644
--- a/net/batman-adv/bitarray.h
+++ b/net/batman-adv/bitarray.h
@@ -20,8 +20,8 @@
20#ifndef _NET_BATMAN_ADV_BITARRAY_H_ 20#ifndef _NET_BATMAN_ADV_BITARRAY_H_
21#define _NET_BATMAN_ADV_BITARRAY_H_ 21#define _NET_BATMAN_ADV_BITARRAY_H_
22 22
23/* returns true if the corresponding bit in the given seq_bits indicates true 23/* Returns 1 if the corresponding bit in the given seq_bits indicates true
24 * and curr_seqno is within range of last_seqno 24 * and curr_seqno is within range of last_seqno. Otherwise returns 0.
25 */ 25 */
26static inline int batadv_test_bit(const unsigned long *seq_bits, 26static inline int batadv_test_bit(const unsigned long *seq_bits,
27 uint32_t last_seqno, uint32_t curr_seqno) 27 uint32_t last_seqno, uint32_t curr_seqno)
@@ -32,7 +32,7 @@ static inline int batadv_test_bit(const unsigned long *seq_bits,
32 if (diff < 0 || diff >= BATADV_TQ_LOCAL_WINDOW_SIZE) 32 if (diff < 0 || diff >= BATADV_TQ_LOCAL_WINDOW_SIZE)
33 return 0; 33 return 0;
34 else 34 else
35 return test_bit(diff, seq_bits); 35 return test_bit(diff, seq_bits) != 0;
36} 36}
37 37
38/* turn corresponding bit on, so we can remember that we got the packet */ 38/* turn corresponding bit on, so we can remember that we got the packet */
diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c
index 6705d35b17c..0a9084ad19a 100644
--- a/net/batman-adv/bridge_loop_avoidance.c
+++ b/net/batman-adv/bridge_loop_avoidance.c
@@ -133,7 +133,7 @@ static void batadv_claim_free_ref(struct batadv_claim *claim)
133static struct batadv_claim *batadv_claim_hash_find(struct batadv_priv *bat_priv, 133static struct batadv_claim *batadv_claim_hash_find(struct batadv_priv *bat_priv,
134 struct batadv_claim *data) 134 struct batadv_claim *data)
135{ 135{
136 struct batadv_hashtable *hash = bat_priv->claim_hash; 136 struct batadv_hashtable *hash = bat_priv->bla.claim_hash;
137 struct hlist_head *head; 137 struct hlist_head *head;
138 struct hlist_node *node; 138 struct hlist_node *node;
139 struct batadv_claim *claim; 139 struct batadv_claim *claim;
@@ -174,7 +174,7 @@ static struct batadv_backbone_gw *
174batadv_backbone_hash_find(struct batadv_priv *bat_priv, 174batadv_backbone_hash_find(struct batadv_priv *bat_priv,
175 uint8_t *addr, short vid) 175 uint8_t *addr, short vid)
176{ 176{
177 struct batadv_hashtable *hash = bat_priv->backbone_hash; 177 struct batadv_hashtable *hash = bat_priv->bla.backbone_hash;
178 struct hlist_head *head; 178 struct hlist_head *head;
179 struct hlist_node *node; 179 struct hlist_node *node;
180 struct batadv_backbone_gw search_entry, *backbone_gw; 180 struct batadv_backbone_gw search_entry, *backbone_gw;
@@ -218,7 +218,7 @@ batadv_bla_del_backbone_claims(struct batadv_backbone_gw *backbone_gw)
218 int i; 218 int i;
219 spinlock_t *list_lock; /* protects write access to the hash lists */ 219 spinlock_t *list_lock; /* protects write access to the hash lists */
220 220
221 hash = backbone_gw->bat_priv->claim_hash; 221 hash = backbone_gw->bat_priv->bla.claim_hash;
222 if (!hash) 222 if (!hash)
223 return; 223 return;
224 224
@@ -265,7 +265,7 @@ static void batadv_bla_send_claim(struct batadv_priv *bat_priv, uint8_t *mac,
265 if (!primary_if) 265 if (!primary_if)
266 return; 266 return;
267 267
268 memcpy(&local_claim_dest, &bat_priv->claim_dest, 268 memcpy(&local_claim_dest, &bat_priv->bla.claim_dest,
269 sizeof(local_claim_dest)); 269 sizeof(local_claim_dest));
270 local_claim_dest.type = claimtype; 270 local_claim_dest.type = claimtype;
271 271
@@ -281,7 +281,7 @@ static void batadv_bla_send_claim(struct batadv_priv *bat_priv, uint8_t *mac,
281 NULL, 281 NULL,
282 /* Ethernet SRC/HW SRC: originator mac */ 282 /* Ethernet SRC/HW SRC: originator mac */
283 primary_if->net_dev->dev_addr, 283 primary_if->net_dev->dev_addr,
284 /* HW DST: FF:43:05:XX:00:00 284 /* HW DST: FF:43:05:XX:YY:YY
285 * with XX = claim type 285 * with XX = claim type
286 * and YY:YY = group id 286 * and YY:YY = group id
287 */ 287 */
@@ -295,7 +295,7 @@ static void batadv_bla_send_claim(struct batadv_priv *bat_priv, uint8_t *mac,
295 295
296 /* now we pretend that the client would have sent this ... */ 296 /* now we pretend that the client would have sent this ... */
297 switch (claimtype) { 297 switch (claimtype) {
298 case BATADV_CLAIM_TYPE_ADD: 298 case BATADV_CLAIM_TYPE_CLAIM:
299 /* normal claim frame 299 /* normal claim frame
300 * set Ethernet SRC to the clients mac 300 * set Ethernet SRC to the clients mac
301 */ 301 */
@@ -303,7 +303,7 @@ static void batadv_bla_send_claim(struct batadv_priv *bat_priv, uint8_t *mac,
303 batadv_dbg(BATADV_DBG_BLA, bat_priv, 303 batadv_dbg(BATADV_DBG_BLA, bat_priv,
304 "bla_send_claim(): CLAIM %pM on vid %d\n", mac, vid); 304 "bla_send_claim(): CLAIM %pM on vid %d\n", mac, vid);
305 break; 305 break;
306 case BATADV_CLAIM_TYPE_DEL: 306 case BATADV_CLAIM_TYPE_UNCLAIM:
307 /* unclaim frame 307 /* unclaim frame
308 * set HW SRC to the clients mac 308 * set HW SRC to the clients mac
309 */ 309 */
@@ -323,7 +323,8 @@ static void batadv_bla_send_claim(struct batadv_priv *bat_priv, uint8_t *mac,
323 break; 323 break;
324 case BATADV_CLAIM_TYPE_REQUEST: 324 case BATADV_CLAIM_TYPE_REQUEST:
325 /* request frame 325 /* request frame
326 * set HW SRC to the special mac containg the crc 326 * set HW SRC and header destination to the receiving backbone
327 * gws mac
327 */ 328 */
328 memcpy(hw_src, mac, ETH_ALEN); 329 memcpy(hw_src, mac, ETH_ALEN);
329 memcpy(ethhdr->h_dest, mac, ETH_ALEN); 330 memcpy(ethhdr->h_dest, mac, ETH_ALEN);
@@ -339,8 +340,9 @@ static void batadv_bla_send_claim(struct batadv_priv *bat_priv, uint8_t *mac,
339 340
340 skb_reset_mac_header(skb); 341 skb_reset_mac_header(skb);
341 skb->protocol = eth_type_trans(skb, soft_iface); 342 skb->protocol = eth_type_trans(skb, soft_iface);
342 bat_priv->stats.rx_packets++; 343 batadv_inc_counter(bat_priv, BATADV_CNT_RX);
343 bat_priv->stats.rx_bytes += skb->len + ETH_HLEN; 344 batadv_add_counter(bat_priv, BATADV_CNT_RX_BYTES,
345 skb->len + ETH_HLEN);
344 soft_iface->last_rx = jiffies; 346 soft_iface->last_rx = jiffies;
345 347
346 netif_rx(skb); 348 netif_rx(skb);
@@ -389,7 +391,7 @@ batadv_bla_get_backbone_gw(struct batadv_priv *bat_priv, uint8_t *orig,
389 /* one for the hash, one for returning */ 391 /* one for the hash, one for returning */
390 atomic_set(&entry->refcount, 2); 392 atomic_set(&entry->refcount, 2);
391 393
392 hash_added = batadv_hash_add(bat_priv->backbone_hash, 394 hash_added = batadv_hash_add(bat_priv->bla.backbone_hash,
393 batadv_compare_backbone_gw, 395 batadv_compare_backbone_gw,
394 batadv_choose_backbone_gw, entry, 396 batadv_choose_backbone_gw, entry,
395 &entry->hash_entry); 397 &entry->hash_entry);
@@ -456,7 +458,7 @@ static void batadv_bla_answer_request(struct batadv_priv *bat_priv,
456 if (!backbone_gw) 458 if (!backbone_gw)
457 return; 459 return;
458 460
459 hash = bat_priv->claim_hash; 461 hash = bat_priv->bla.claim_hash;
460 for (i = 0; i < hash->size; i++) { 462 for (i = 0; i < hash->size; i++) {
461 head = &hash->table[i]; 463 head = &hash->table[i];
462 464
@@ -467,7 +469,7 @@ static void batadv_bla_answer_request(struct batadv_priv *bat_priv,
467 continue; 469 continue;
468 470
469 batadv_bla_send_claim(bat_priv, claim->addr, claim->vid, 471 batadv_bla_send_claim(bat_priv, claim->addr, claim->vid,
470 BATADV_CLAIM_TYPE_ADD); 472 BATADV_CLAIM_TYPE_CLAIM);
471 } 473 }
472 rcu_read_unlock(); 474 rcu_read_unlock();
473 } 475 }
@@ -497,7 +499,7 @@ static void batadv_bla_send_request(struct batadv_backbone_gw *backbone_gw)
497 499
498 /* no local broadcasts should be sent or received, for now. */ 500 /* no local broadcasts should be sent or received, for now. */
499 if (!atomic_read(&backbone_gw->request_sent)) { 501 if (!atomic_read(&backbone_gw->request_sent)) {
500 atomic_inc(&backbone_gw->bat_priv->bla_num_requests); 502 atomic_inc(&backbone_gw->bat_priv->bla.num_requests);
501 atomic_set(&backbone_gw->request_sent, 1); 503 atomic_set(&backbone_gw->request_sent, 1);
502 } 504 }
503} 505}
@@ -557,7 +559,7 @@ static void batadv_bla_add_claim(struct batadv_priv *bat_priv,
557 batadv_dbg(BATADV_DBG_BLA, bat_priv, 559 batadv_dbg(BATADV_DBG_BLA, bat_priv,
558 "bla_add_claim(): adding new entry %pM, vid %d to hash ...\n", 560 "bla_add_claim(): adding new entry %pM, vid %d to hash ...\n",
559 mac, vid); 561 mac, vid);
560 hash_added = batadv_hash_add(bat_priv->claim_hash, 562 hash_added = batadv_hash_add(bat_priv->bla.claim_hash,
561 batadv_compare_claim, 563 batadv_compare_claim,
562 batadv_choose_claim, claim, 564 batadv_choose_claim, claim,
563 &claim->hash_entry); 565 &claim->hash_entry);
@@ -577,8 +579,7 @@ static void batadv_bla_add_claim(struct batadv_priv *bat_priv,
577 "bla_add_claim(): changing ownership for %pM, vid %d\n", 579 "bla_add_claim(): changing ownership for %pM, vid %d\n",
578 mac, vid); 580 mac, vid);
579 581
580 claim->backbone_gw->crc ^= 582 claim->backbone_gw->crc ^= crc16(0, claim->addr, ETH_ALEN);
581 crc16(0, claim->addr, ETH_ALEN);
582 batadv_backbone_gw_free_ref(claim->backbone_gw); 583 batadv_backbone_gw_free_ref(claim->backbone_gw);
583 584
584 } 585 }
@@ -610,7 +611,7 @@ static void batadv_bla_del_claim(struct batadv_priv *bat_priv,
610 batadv_dbg(BATADV_DBG_BLA, bat_priv, "bla_del_claim(): %pM, vid %d\n", 611 batadv_dbg(BATADV_DBG_BLA, bat_priv, "bla_del_claim(): %pM, vid %d\n",
611 mac, vid); 612 mac, vid);
612 613
613 batadv_hash_remove(bat_priv->claim_hash, batadv_compare_claim, 614 batadv_hash_remove(bat_priv->bla.claim_hash, batadv_compare_claim,
614 batadv_choose_claim, claim); 615 batadv_choose_claim, claim);
615 batadv_claim_free_ref(claim); /* reference from the hash is gone */ 616 batadv_claim_free_ref(claim); /* reference from the hash is gone */
616 617
@@ -657,7 +658,7 @@ static int batadv_handle_announce(struct batadv_priv *bat_priv,
657 * we can allow traffic again. 658 * we can allow traffic again.
658 */ 659 */
659 if (atomic_read(&backbone_gw->request_sent)) { 660 if (atomic_read(&backbone_gw->request_sent)) {
660 atomic_dec(&backbone_gw->bat_priv->bla_num_requests); 661 atomic_dec(&backbone_gw->bat_priv->bla.num_requests);
661 atomic_set(&backbone_gw->request_sent, 0); 662 atomic_set(&backbone_gw->request_sent, 0);
662 } 663 }
663 } 664 }
@@ -702,7 +703,7 @@ static int batadv_handle_unclaim(struct batadv_priv *bat_priv,
702 if (primary_if && batadv_compare_eth(backbone_addr, 703 if (primary_if && batadv_compare_eth(backbone_addr,
703 primary_if->net_dev->dev_addr)) 704 primary_if->net_dev->dev_addr))
704 batadv_bla_send_claim(bat_priv, claim_addr, vid, 705 batadv_bla_send_claim(bat_priv, claim_addr, vid,
705 BATADV_CLAIM_TYPE_DEL); 706 BATADV_CLAIM_TYPE_UNCLAIM);
706 707
707 backbone_gw = batadv_backbone_hash_find(bat_priv, backbone_addr, vid); 708 backbone_gw = batadv_backbone_hash_find(bat_priv, backbone_addr, vid);
708 709
@@ -738,7 +739,7 @@ static int batadv_handle_claim(struct batadv_priv *bat_priv,
738 batadv_bla_add_claim(bat_priv, claim_addr, vid, backbone_gw); 739 batadv_bla_add_claim(bat_priv, claim_addr, vid, backbone_gw);
739 if (batadv_compare_eth(backbone_addr, primary_if->net_dev->dev_addr)) 740 if (batadv_compare_eth(backbone_addr, primary_if->net_dev->dev_addr))
740 batadv_bla_send_claim(bat_priv, claim_addr, vid, 741 batadv_bla_send_claim(bat_priv, claim_addr, vid,
741 BATADV_CLAIM_TYPE_ADD); 742 BATADV_CLAIM_TYPE_CLAIM);
742 743
743 /* TODO: we could call something like tt_local_del() here. */ 744 /* TODO: we could call something like tt_local_del() here. */
744 745
@@ -772,7 +773,7 @@ static int batadv_check_claim_group(struct batadv_priv *bat_priv,
772 struct batadv_bla_claim_dst *bla_dst, *bla_dst_own; 773 struct batadv_bla_claim_dst *bla_dst, *bla_dst_own;
773 774
774 bla_dst = (struct batadv_bla_claim_dst *)hw_dst; 775 bla_dst = (struct batadv_bla_claim_dst *)hw_dst;
775 bla_dst_own = &bat_priv->claim_dest; 776 bla_dst_own = &bat_priv->bla.claim_dest;
776 777
777 /* check if it is a claim packet in general */ 778 /* check if it is a claim packet in general */
778 if (memcmp(bla_dst->magic, bla_dst_own->magic, 779 if (memcmp(bla_dst->magic, bla_dst_own->magic,
@@ -783,12 +784,12 @@ static int batadv_check_claim_group(struct batadv_priv *bat_priv,
783 * otherwise assume it is in the hw_src 784 * otherwise assume it is in the hw_src
784 */ 785 */
785 switch (bla_dst->type) { 786 switch (bla_dst->type) {
786 case BATADV_CLAIM_TYPE_ADD: 787 case BATADV_CLAIM_TYPE_CLAIM:
787 backbone_addr = hw_src; 788 backbone_addr = hw_src;
788 break; 789 break;
789 case BATADV_CLAIM_TYPE_REQUEST: 790 case BATADV_CLAIM_TYPE_REQUEST:
790 case BATADV_CLAIM_TYPE_ANNOUNCE: 791 case BATADV_CLAIM_TYPE_ANNOUNCE:
791 case BATADV_CLAIM_TYPE_DEL: 792 case BATADV_CLAIM_TYPE_UNCLAIM:
792 backbone_addr = ethhdr->h_source; 793 backbone_addr = ethhdr->h_source;
793 break; 794 break;
794 default: 795 default:
@@ -904,12 +905,12 @@ static int batadv_bla_process_claim(struct batadv_priv *bat_priv,
904 905
905 /* check for the different types of claim frames ... */ 906 /* check for the different types of claim frames ... */
906 switch (bla_dst->type) { 907 switch (bla_dst->type) {
907 case BATADV_CLAIM_TYPE_ADD: 908 case BATADV_CLAIM_TYPE_CLAIM:
908 if (batadv_handle_claim(bat_priv, primary_if, hw_src, 909 if (batadv_handle_claim(bat_priv, primary_if, hw_src,
909 ethhdr->h_source, vid)) 910 ethhdr->h_source, vid))
910 return 1; 911 return 1;
911 break; 912 break;
912 case BATADV_CLAIM_TYPE_DEL: 913 case BATADV_CLAIM_TYPE_UNCLAIM:
913 if (batadv_handle_unclaim(bat_priv, primary_if, 914 if (batadv_handle_unclaim(bat_priv, primary_if,
914 ethhdr->h_source, hw_src, vid)) 915 ethhdr->h_source, hw_src, vid))
915 return 1; 916 return 1;
@@ -945,7 +946,7 @@ static void batadv_bla_purge_backbone_gw(struct batadv_priv *bat_priv, int now)
945 spinlock_t *list_lock; /* protects write access to the hash lists */ 946 spinlock_t *list_lock; /* protects write access to the hash lists */
946 int i; 947 int i;
947 948
948 hash = bat_priv->backbone_hash; 949 hash = bat_priv->bla.backbone_hash;
949 if (!hash) 950 if (!hash)
950 return; 951 return;
951 952
@@ -969,7 +970,7 @@ static void batadv_bla_purge_backbone_gw(struct batadv_priv *bat_priv, int now)
969purge_now: 970purge_now:
970 /* don't wait for the pending request anymore */ 971 /* don't wait for the pending request anymore */
971 if (atomic_read(&backbone_gw->request_sent)) 972 if (atomic_read(&backbone_gw->request_sent))
972 atomic_dec(&bat_priv->bla_num_requests); 973 atomic_dec(&bat_priv->bla.num_requests);
973 974
974 batadv_bla_del_backbone_claims(backbone_gw); 975 batadv_bla_del_backbone_claims(backbone_gw);
975 976
@@ -999,7 +1000,7 @@ static void batadv_bla_purge_claims(struct batadv_priv *bat_priv,
999 struct batadv_hashtable *hash; 1000 struct batadv_hashtable *hash;
1000 int i; 1001 int i;
1001 1002
1002 hash = bat_priv->claim_hash; 1003 hash = bat_priv->bla.claim_hash;
1003 if (!hash) 1004 if (!hash)
1004 return; 1005 return;
1005 1006
@@ -1046,11 +1047,12 @@ void batadv_bla_update_orig_address(struct batadv_priv *bat_priv,
1046 struct hlist_node *node; 1047 struct hlist_node *node;
1047 struct hlist_head *head; 1048 struct hlist_head *head;
1048 struct batadv_hashtable *hash; 1049 struct batadv_hashtable *hash;
1050 __be16 group;
1049 int i; 1051 int i;
1050 1052
1051 /* reset bridge loop avoidance group id */ 1053 /* reset bridge loop avoidance group id */
1052 bat_priv->claim_dest.group = 1054 group = htons(crc16(0, primary_if->net_dev->dev_addr, ETH_ALEN));
1053 htons(crc16(0, primary_if->net_dev->dev_addr, ETH_ALEN)); 1055 bat_priv->bla.claim_dest.group = group;
1054 1056
1055 if (!oldif) { 1057 if (!oldif) {
1056 batadv_bla_purge_claims(bat_priv, NULL, 1); 1058 batadv_bla_purge_claims(bat_priv, NULL, 1);
@@ -1058,7 +1060,7 @@ void batadv_bla_update_orig_address(struct batadv_priv *bat_priv,
1058 return; 1060 return;
1059 } 1061 }
1060 1062
1061 hash = bat_priv->backbone_hash; 1063 hash = bat_priv->bla.backbone_hash;
1062 if (!hash) 1064 if (!hash)
1063 return; 1065 return;
1064 1066
@@ -1088,8 +1090,8 @@ void batadv_bla_update_orig_address(struct batadv_priv *bat_priv,
1088/* (re)start the timer */ 1090/* (re)start the timer */
1089static void batadv_bla_start_timer(struct batadv_priv *bat_priv) 1091static void batadv_bla_start_timer(struct batadv_priv *bat_priv)
1090{ 1092{
1091 INIT_DELAYED_WORK(&bat_priv->bla_work, batadv_bla_periodic_work); 1093 INIT_DELAYED_WORK(&bat_priv->bla.work, batadv_bla_periodic_work);
1092 queue_delayed_work(batadv_event_workqueue, &bat_priv->bla_work, 1094 queue_delayed_work(batadv_event_workqueue, &bat_priv->bla.work,
1093 msecs_to_jiffies(BATADV_BLA_PERIOD_LENGTH)); 1095 msecs_to_jiffies(BATADV_BLA_PERIOD_LENGTH));
1094} 1096}
1095 1097
@@ -1099,9 +1101,9 @@ static void batadv_bla_start_timer(struct batadv_priv *bat_priv)
1099 */ 1101 */
1100static void batadv_bla_periodic_work(struct work_struct *work) 1102static void batadv_bla_periodic_work(struct work_struct *work)
1101{ 1103{
1102 struct delayed_work *delayed_work = 1104 struct delayed_work *delayed_work;
1103 container_of(work, struct delayed_work, work);
1104 struct batadv_priv *bat_priv; 1105 struct batadv_priv *bat_priv;
1106 struct batadv_priv_bla *priv_bla;
1105 struct hlist_node *node; 1107 struct hlist_node *node;
1106 struct hlist_head *head; 1108 struct hlist_head *head;
1107 struct batadv_backbone_gw *backbone_gw; 1109 struct batadv_backbone_gw *backbone_gw;
@@ -1109,7 +1111,9 @@ static void batadv_bla_periodic_work(struct work_struct *work)
1109 struct batadv_hard_iface *primary_if; 1111 struct batadv_hard_iface *primary_if;
1110 int i; 1112 int i;
1111 1113
1112 bat_priv = container_of(delayed_work, struct batadv_priv, bla_work); 1114 delayed_work = container_of(work, struct delayed_work, work);
1115 priv_bla = container_of(delayed_work, struct batadv_priv_bla, work);
1116 bat_priv = container_of(priv_bla, struct batadv_priv, bla);
1113 primary_if = batadv_primary_if_get_selected(bat_priv); 1117 primary_if = batadv_primary_if_get_selected(bat_priv);
1114 if (!primary_if) 1118 if (!primary_if)
1115 goto out; 1119 goto out;
@@ -1120,7 +1124,7 @@ static void batadv_bla_periodic_work(struct work_struct *work)
1120 if (!atomic_read(&bat_priv->bridge_loop_avoidance)) 1124 if (!atomic_read(&bat_priv->bridge_loop_avoidance))
1121 goto out; 1125 goto out;
1122 1126
1123 hash = bat_priv->backbone_hash; 1127 hash = bat_priv->bla.backbone_hash;
1124 if (!hash) 1128 if (!hash)
1125 goto out; 1129 goto out;
1126 1130
@@ -1160,40 +1164,41 @@ int batadv_bla_init(struct batadv_priv *bat_priv)
1160 int i; 1164 int i;
1161 uint8_t claim_dest[ETH_ALEN] = {0xff, 0x43, 0x05, 0x00, 0x00, 0x00}; 1165 uint8_t claim_dest[ETH_ALEN] = {0xff, 0x43, 0x05, 0x00, 0x00, 0x00};
1162 struct batadv_hard_iface *primary_if; 1166 struct batadv_hard_iface *primary_if;
1167 uint16_t crc;
1168 unsigned long entrytime;
1163 1169
1164 batadv_dbg(BATADV_DBG_BLA, bat_priv, "bla hash registering\n"); 1170 batadv_dbg(BATADV_DBG_BLA, bat_priv, "bla hash registering\n");
1165 1171
1166 /* setting claim destination address */ 1172 /* setting claim destination address */
1167 memcpy(&bat_priv->claim_dest.magic, claim_dest, 3); 1173 memcpy(&bat_priv->bla.claim_dest.magic, claim_dest, 3);
1168 bat_priv->claim_dest.type = 0; 1174 bat_priv->bla.claim_dest.type = 0;
1169 primary_if = batadv_primary_if_get_selected(bat_priv); 1175 primary_if = batadv_primary_if_get_selected(bat_priv);
1170 if (primary_if) { 1176 if (primary_if) {
1171 bat_priv->claim_dest.group = 1177 crc = crc16(0, primary_if->net_dev->dev_addr, ETH_ALEN);
1172 htons(crc16(0, primary_if->net_dev->dev_addr, 1178 bat_priv->bla.claim_dest.group = htons(crc);
1173 ETH_ALEN));
1174 batadv_hardif_free_ref(primary_if); 1179 batadv_hardif_free_ref(primary_if);
1175 } else { 1180 } else {
1176 bat_priv->claim_dest.group = 0; /* will be set later */ 1181 bat_priv->bla.claim_dest.group = 0; /* will be set later */
1177 } 1182 }
1178 1183
1179 /* initialize the duplicate list */ 1184 /* initialize the duplicate list */
1185 entrytime = jiffies - msecs_to_jiffies(BATADV_DUPLIST_TIMEOUT);
1180 for (i = 0; i < BATADV_DUPLIST_SIZE; i++) 1186 for (i = 0; i < BATADV_DUPLIST_SIZE; i++)
1181 bat_priv->bcast_duplist[i].entrytime = 1187 bat_priv->bla.bcast_duplist[i].entrytime = entrytime;
1182 jiffies - msecs_to_jiffies(BATADV_DUPLIST_TIMEOUT); 1188 bat_priv->bla.bcast_duplist_curr = 0;
1183 bat_priv->bcast_duplist_curr = 0;
1184 1189
1185 if (bat_priv->claim_hash) 1190 if (bat_priv->bla.claim_hash)
1186 return 0; 1191 return 0;
1187 1192
1188 bat_priv->claim_hash = batadv_hash_new(128); 1193 bat_priv->bla.claim_hash = batadv_hash_new(128);
1189 bat_priv->backbone_hash = batadv_hash_new(32); 1194 bat_priv->bla.backbone_hash = batadv_hash_new(32);
1190 1195
1191 if (!bat_priv->claim_hash || !bat_priv->backbone_hash) 1196 if (!bat_priv->bla.claim_hash || !bat_priv->bla.backbone_hash)
1192 return -ENOMEM; 1197 return -ENOMEM;
1193 1198
1194 batadv_hash_set_lock_class(bat_priv->claim_hash, 1199 batadv_hash_set_lock_class(bat_priv->bla.claim_hash,
1195 &batadv_claim_hash_lock_class_key); 1200 &batadv_claim_hash_lock_class_key);
1196 batadv_hash_set_lock_class(bat_priv->backbone_hash, 1201 batadv_hash_set_lock_class(bat_priv->bla.backbone_hash,
1197 &batadv_backbone_hash_lock_class_key); 1202 &batadv_backbone_hash_lock_class_key);
1198 1203
1199 batadv_dbg(BATADV_DBG_BLA, bat_priv, "bla hashes initialized\n"); 1204 batadv_dbg(BATADV_DBG_BLA, bat_priv, "bla hashes initialized\n");
@@ -1234,8 +1239,9 @@ int batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv,
1234 crc = crc16(0, content, length); 1239 crc = crc16(0, content, length);
1235 1240
1236 for (i = 0; i < BATADV_DUPLIST_SIZE; i++) { 1241 for (i = 0; i < BATADV_DUPLIST_SIZE; i++) {
1237 curr = (bat_priv->bcast_duplist_curr + i) % BATADV_DUPLIST_SIZE; 1242 curr = (bat_priv->bla.bcast_duplist_curr + i);
1238 entry = &bat_priv->bcast_duplist[curr]; 1243 curr %= BATADV_DUPLIST_SIZE;
1244 entry = &bat_priv->bla.bcast_duplist[curr];
1239 1245
1240 /* we can stop searching if the entry is too old ; 1246 /* we can stop searching if the entry is too old ;
1241 * later entries will be even older 1247 * later entries will be even older
@@ -1256,13 +1262,13 @@ int batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv,
1256 return 1; 1262 return 1;
1257 } 1263 }
1258 /* not found, add a new entry (overwrite the oldest entry) */ 1264 /* not found, add a new entry (overwrite the oldest entry) */
1259 curr = (bat_priv->bcast_duplist_curr + BATADV_DUPLIST_SIZE - 1); 1265 curr = (bat_priv->bla.bcast_duplist_curr + BATADV_DUPLIST_SIZE - 1);
1260 curr %= BATADV_DUPLIST_SIZE; 1266 curr %= BATADV_DUPLIST_SIZE;
1261 entry = &bat_priv->bcast_duplist[curr]; 1267 entry = &bat_priv->bla.bcast_duplist[curr];
1262 entry->crc = crc; 1268 entry->crc = crc;
1263 entry->entrytime = jiffies; 1269 entry->entrytime = jiffies;
1264 memcpy(entry->orig, bcast_packet->orig, ETH_ALEN); 1270 memcpy(entry->orig, bcast_packet->orig, ETH_ALEN);
1265 bat_priv->bcast_duplist_curr = curr; 1271 bat_priv->bla.bcast_duplist_curr = curr;
1266 1272
1267 /* allow it, its the first occurence. */ 1273 /* allow it, its the first occurence. */
1268 return 0; 1274 return 0;
@@ -1279,7 +1285,7 @@ int batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv,
1279 */ 1285 */
1280int batadv_bla_is_backbone_gw_orig(struct batadv_priv *bat_priv, uint8_t *orig) 1286int batadv_bla_is_backbone_gw_orig(struct batadv_priv *bat_priv, uint8_t *orig)
1281{ 1287{
1282 struct batadv_hashtable *hash = bat_priv->backbone_hash; 1288 struct batadv_hashtable *hash = bat_priv->bla.backbone_hash;
1283 struct hlist_head *head; 1289 struct hlist_head *head;
1284 struct hlist_node *node; 1290 struct hlist_node *node;
1285 struct batadv_backbone_gw *backbone_gw; 1291 struct batadv_backbone_gw *backbone_gw;
@@ -1339,8 +1345,7 @@ int batadv_bla_is_backbone_gw(struct sk_buff *skb,
1339 if (!pskb_may_pull(skb, hdr_size + sizeof(struct vlan_ethhdr))) 1345 if (!pskb_may_pull(skb, hdr_size + sizeof(struct vlan_ethhdr)))
1340 return 0; 1346 return 0;
1341 1347
1342 vhdr = (struct vlan_ethhdr *)(((uint8_t *)skb->data) + 1348 vhdr = (struct vlan_ethhdr *)(skb->data + hdr_size);
1343 hdr_size);
1344 vid = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK; 1349 vid = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK;
1345 } 1350 }
1346 1351
@@ -1359,18 +1364,18 @@ void batadv_bla_free(struct batadv_priv *bat_priv)
1359{ 1364{
1360 struct batadv_hard_iface *primary_if; 1365 struct batadv_hard_iface *primary_if;
1361 1366
1362 cancel_delayed_work_sync(&bat_priv->bla_work); 1367 cancel_delayed_work_sync(&bat_priv->bla.work);
1363 primary_if = batadv_primary_if_get_selected(bat_priv); 1368 primary_if = batadv_primary_if_get_selected(bat_priv);
1364 1369
1365 if (bat_priv->claim_hash) { 1370 if (bat_priv->bla.claim_hash) {
1366 batadv_bla_purge_claims(bat_priv, primary_if, 1); 1371 batadv_bla_purge_claims(bat_priv, primary_if, 1);
1367 batadv_hash_destroy(bat_priv->claim_hash); 1372 batadv_hash_destroy(bat_priv->bla.claim_hash);
1368 bat_priv->claim_hash = NULL; 1373 bat_priv->bla.claim_hash = NULL;
1369 } 1374 }
1370 if (bat_priv->backbone_hash) { 1375 if (bat_priv->bla.backbone_hash) {
1371 batadv_bla_purge_backbone_gw(bat_priv, 1); 1376 batadv_bla_purge_backbone_gw(bat_priv, 1);
1372 batadv_hash_destroy(bat_priv->backbone_hash); 1377 batadv_hash_destroy(bat_priv->bla.backbone_hash);
1373 bat_priv->backbone_hash = NULL; 1378 bat_priv->bla.backbone_hash = NULL;
1374 } 1379 }
1375 if (primary_if) 1380 if (primary_if)
1376 batadv_hardif_free_ref(primary_if); 1381 batadv_hardif_free_ref(primary_if);
@@ -1409,7 +1414,7 @@ int batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb, short vid,
1409 goto allow; 1414 goto allow;
1410 1415
1411 1416
1412 if (unlikely(atomic_read(&bat_priv->bla_num_requests))) 1417 if (unlikely(atomic_read(&bat_priv->bla.num_requests)))
1413 /* don't allow broadcasts while requests are in flight */ 1418 /* don't allow broadcasts while requests are in flight */
1414 if (is_multicast_ether_addr(ethhdr->h_dest) && is_bcast) 1419 if (is_multicast_ether_addr(ethhdr->h_dest) && is_bcast)
1415 goto handled; 1420 goto handled;
@@ -1508,7 +1513,7 @@ int batadv_bla_tx(struct batadv_priv *bat_priv, struct sk_buff *skb, short vid)
1508 1513
1509 ethhdr = (struct ethhdr *)skb_mac_header(skb); 1514 ethhdr = (struct ethhdr *)skb_mac_header(skb);
1510 1515
1511 if (unlikely(atomic_read(&bat_priv->bla_num_requests))) 1516 if (unlikely(atomic_read(&bat_priv->bla.num_requests)))
1512 /* don't allow broadcasts while requests are in flight */ 1517 /* don't allow broadcasts while requests are in flight */
1513 if (is_multicast_ether_addr(ethhdr->h_dest)) 1518 if (is_multicast_ether_addr(ethhdr->h_dest))
1514 goto handled; 1519 goto handled;
@@ -1564,7 +1569,7 @@ int batadv_bla_claim_table_seq_print_text(struct seq_file *seq, void *offset)
1564{ 1569{
1565 struct net_device *net_dev = (struct net_device *)seq->private; 1570 struct net_device *net_dev = (struct net_device *)seq->private;
1566 struct batadv_priv *bat_priv = netdev_priv(net_dev); 1571 struct batadv_priv *bat_priv = netdev_priv(net_dev);
1567 struct batadv_hashtable *hash = bat_priv->claim_hash; 1572 struct batadv_hashtable *hash = bat_priv->bla.claim_hash;
1568 struct batadv_claim *claim; 1573 struct batadv_claim *claim;
1569 struct batadv_hard_iface *primary_if; 1574 struct batadv_hard_iface *primary_if;
1570 struct hlist_node *node; 1575 struct hlist_node *node;
@@ -1593,7 +1598,7 @@ int batadv_bla_claim_table_seq_print_text(struct seq_file *seq, void *offset)
1593 seq_printf(seq, 1598 seq_printf(seq,
1594 "Claims announced for the mesh %s (orig %pM, group id %04x)\n", 1599 "Claims announced for the mesh %s (orig %pM, group id %04x)\n",
1595 net_dev->name, primary_addr, 1600 net_dev->name, primary_addr,
1596 ntohs(bat_priv->claim_dest.group)); 1601 ntohs(bat_priv->bla.claim_dest.group));
1597 seq_printf(seq, " %-17s %-5s %-17s [o] (%-4s)\n", 1602 seq_printf(seq, " %-17s %-5s %-17s [o] (%-4s)\n",
1598 "Client", "VID", "Originator", "CRC"); 1603 "Client", "VID", "Originator", "CRC");
1599 for (i = 0; i < hash->size; i++) { 1604 for (i = 0; i < hash->size; i++) {
@@ -1616,3 +1621,68 @@ out:
1616 batadv_hardif_free_ref(primary_if); 1621 batadv_hardif_free_ref(primary_if);
1617 return ret; 1622 return ret;
1618} 1623}
1624
1625int batadv_bla_backbone_table_seq_print_text(struct seq_file *seq, void *offset)
1626{
1627 struct net_device *net_dev = (struct net_device *)seq->private;
1628 struct batadv_priv *bat_priv = netdev_priv(net_dev);
1629 struct batadv_hashtable *hash = bat_priv->bla.backbone_hash;
1630 struct batadv_backbone_gw *backbone_gw;
1631 struct batadv_hard_iface *primary_if;
1632 struct hlist_node *node;
1633 struct hlist_head *head;
1634 int secs, msecs;
1635 uint32_t i;
1636 bool is_own;
1637 int ret = 0;
1638 uint8_t *primary_addr;
1639
1640 primary_if = batadv_primary_if_get_selected(bat_priv);
1641 if (!primary_if) {
1642 ret = seq_printf(seq,
1643 "BATMAN mesh %s disabled - please specify interfaces to enable it\n",
1644 net_dev->name);
1645 goto out;
1646 }
1647
1648 if (primary_if->if_status != BATADV_IF_ACTIVE) {
1649 ret = seq_printf(seq,
1650 "BATMAN mesh %s disabled - primary interface not active\n",
1651 net_dev->name);
1652 goto out;
1653 }
1654
1655 primary_addr = primary_if->net_dev->dev_addr;
1656 seq_printf(seq,
1657 "Backbones announced for the mesh %s (orig %pM, group id %04x)\n",
1658 net_dev->name, primary_addr,
1659 ntohs(bat_priv->bla.claim_dest.group));
1660 seq_printf(seq, " %-17s %-5s %-9s (%-4s)\n",
1661 "Originator", "VID", "last seen", "CRC");
1662 for (i = 0; i < hash->size; i++) {
1663 head = &hash->table[i];
1664
1665 rcu_read_lock();
1666 hlist_for_each_entry_rcu(backbone_gw, node, head, hash_entry) {
1667 msecs = jiffies_to_msecs(jiffies -
1668 backbone_gw->lasttime);
1669 secs = msecs / 1000;
1670 msecs = msecs % 1000;
1671
1672 is_own = batadv_compare_eth(backbone_gw->orig,
1673 primary_addr);
1674 if (is_own)
1675 continue;
1676
1677 seq_printf(seq,
1678 " * %pM on % 5d % 4i.%03is (%04x)\n",
1679 backbone_gw->orig, backbone_gw->vid,
1680 secs, msecs, backbone_gw->crc);
1681 }
1682 rcu_read_unlock();
1683 }
1684out:
1685 if (primary_if)
1686 batadv_hardif_free_ref(primary_if);
1687 return ret;
1688}
diff --git a/net/batman-adv/bridge_loop_avoidance.h b/net/batman-adv/bridge_loop_avoidance.h
index 563cfbf94a7..789cb73bde6 100644
--- a/net/batman-adv/bridge_loop_avoidance.h
+++ b/net/batman-adv/bridge_loop_avoidance.h
@@ -27,6 +27,8 @@ int batadv_bla_tx(struct batadv_priv *bat_priv, struct sk_buff *skb, short vid);
27int batadv_bla_is_backbone_gw(struct sk_buff *skb, 27int batadv_bla_is_backbone_gw(struct sk_buff *skb,
28 struct batadv_orig_node *orig_node, int hdr_size); 28 struct batadv_orig_node *orig_node, int hdr_size);
29int batadv_bla_claim_table_seq_print_text(struct seq_file *seq, void *offset); 29int batadv_bla_claim_table_seq_print_text(struct seq_file *seq, void *offset);
30int batadv_bla_backbone_table_seq_print_text(struct seq_file *seq,
31 void *offset);
30int batadv_bla_is_backbone_gw_orig(struct batadv_priv *bat_priv, uint8_t *orig); 32int batadv_bla_is_backbone_gw_orig(struct batadv_priv *bat_priv, uint8_t *orig);
31int batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv, 33int batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv,
32 struct batadv_bcast_packet *bcast_packet, 34 struct batadv_bcast_packet *bcast_packet,
@@ -41,8 +43,7 @@ void batadv_bla_free(struct batadv_priv *bat_priv);
41#else /* ifdef CONFIG_BATMAN_ADV_BLA */ 43#else /* ifdef CONFIG_BATMAN_ADV_BLA */
42 44
43static inline int batadv_bla_rx(struct batadv_priv *bat_priv, 45static inline int batadv_bla_rx(struct batadv_priv *bat_priv,
44 struct sk_buff *skb, short vid, 46 struct sk_buff *skb, short vid, bool is_bcast)
45 bool is_bcast)
46{ 47{
47 return 0; 48 return 0;
48} 49}
@@ -66,6 +67,12 @@ static inline int batadv_bla_claim_table_seq_print_text(struct seq_file *seq,
66 return 0; 67 return 0;
67} 68}
68 69
70static inline int batadv_bla_backbone_table_seq_print_text(struct seq_file *seq,
71 void *offset)
72{
73 return 0;
74}
75
69static inline int batadv_bla_is_backbone_gw_orig(struct batadv_priv *bat_priv, 76static inline int batadv_bla_is_backbone_gw_orig(struct batadv_priv *bat_priv,
70 uint8_t *orig) 77 uint8_t *orig)
71{ 78{
diff --git a/net/batman-adv/debugfs.c b/net/batman-adv/debugfs.c
index 34fbb1667bc..391d4fb2026 100644
--- a/net/batman-adv/debugfs.c
+++ b/net/batman-adv/debugfs.c
@@ -267,6 +267,15 @@ static int batadv_bla_claim_table_open(struct inode *inode, struct file *file)
267 return single_open(file, batadv_bla_claim_table_seq_print_text, 267 return single_open(file, batadv_bla_claim_table_seq_print_text,
268 net_dev); 268 net_dev);
269} 269}
270
271static int batadv_bla_backbone_table_open(struct inode *inode,
272 struct file *file)
273{
274 struct net_device *net_dev = (struct net_device *)inode->i_private;
275 return single_open(file, batadv_bla_backbone_table_seq_print_text,
276 net_dev);
277}
278
270#endif 279#endif
271 280
272static int batadv_transtable_local_open(struct inode *inode, struct file *file) 281static int batadv_transtable_local_open(struct inode *inode, struct file *file)
@@ -305,6 +314,8 @@ static BATADV_DEBUGINFO(transtable_global, S_IRUGO,
305 batadv_transtable_global_open); 314 batadv_transtable_global_open);
306#ifdef CONFIG_BATMAN_ADV_BLA 315#ifdef CONFIG_BATMAN_ADV_BLA
307static BATADV_DEBUGINFO(bla_claim_table, S_IRUGO, batadv_bla_claim_table_open); 316static BATADV_DEBUGINFO(bla_claim_table, S_IRUGO, batadv_bla_claim_table_open);
317static BATADV_DEBUGINFO(bla_backbone_table, S_IRUGO,
318 batadv_bla_backbone_table_open);
308#endif 319#endif
309static BATADV_DEBUGINFO(transtable_local, S_IRUGO, 320static BATADV_DEBUGINFO(transtable_local, S_IRUGO,
310 batadv_transtable_local_open); 321 batadv_transtable_local_open);
@@ -316,6 +327,7 @@ static struct batadv_debuginfo *batadv_mesh_debuginfos[] = {
316 &batadv_debuginfo_transtable_global, 327 &batadv_debuginfo_transtable_global,
317#ifdef CONFIG_BATMAN_ADV_BLA 328#ifdef CONFIG_BATMAN_ADV_BLA
318 &batadv_debuginfo_bla_claim_table, 329 &batadv_debuginfo_bla_claim_table,
330 &batadv_debuginfo_bla_backbone_table,
319#endif 331#endif
320 &batadv_debuginfo_transtable_local, 332 &batadv_debuginfo_transtable_local,
321 &batadv_debuginfo_vis_data, 333 &batadv_debuginfo_vis_data,
diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c
index fc866f2e452..15d67abc10a 100644
--- a/net/batman-adv/gateway_client.c
+++ b/net/batman-adv/gateway_client.c
@@ -48,7 +48,7 @@ batadv_gw_get_selected_gw_node(struct batadv_priv *bat_priv)
48 struct batadv_gw_node *gw_node; 48 struct batadv_gw_node *gw_node;
49 49
50 rcu_read_lock(); 50 rcu_read_lock();
51 gw_node = rcu_dereference(bat_priv->curr_gw); 51 gw_node = rcu_dereference(bat_priv->gw.curr_gw);
52 if (!gw_node) 52 if (!gw_node)
53 goto out; 53 goto out;
54 54
@@ -91,23 +91,23 @@ static void batadv_gw_select(struct batadv_priv *bat_priv,
91{ 91{
92 struct batadv_gw_node *curr_gw_node; 92 struct batadv_gw_node *curr_gw_node;
93 93
94 spin_lock_bh(&bat_priv->gw_list_lock); 94 spin_lock_bh(&bat_priv->gw.list_lock);
95 95
96 if (new_gw_node && !atomic_inc_not_zero(&new_gw_node->refcount)) 96 if (new_gw_node && !atomic_inc_not_zero(&new_gw_node->refcount))
97 new_gw_node = NULL; 97 new_gw_node = NULL;
98 98
99 curr_gw_node = rcu_dereference_protected(bat_priv->curr_gw, 1); 99 curr_gw_node = rcu_dereference_protected(bat_priv->gw.curr_gw, 1);
100 rcu_assign_pointer(bat_priv->curr_gw, new_gw_node); 100 rcu_assign_pointer(bat_priv->gw.curr_gw, new_gw_node);
101 101
102 if (curr_gw_node) 102 if (curr_gw_node)
103 batadv_gw_node_free_ref(curr_gw_node); 103 batadv_gw_node_free_ref(curr_gw_node);
104 104
105 spin_unlock_bh(&bat_priv->gw_list_lock); 105 spin_unlock_bh(&bat_priv->gw.list_lock);
106} 106}
107 107
108void batadv_gw_deselect(struct batadv_priv *bat_priv) 108void batadv_gw_deselect(struct batadv_priv *bat_priv)
109{ 109{
110 atomic_set(&bat_priv->gw_reselect, 1); 110 atomic_set(&bat_priv->gw.reselect, 1);
111} 111}
112 112
113static struct batadv_gw_node * 113static struct batadv_gw_node *
@@ -117,12 +117,17 @@ batadv_gw_get_best_gw_node(struct batadv_priv *bat_priv)
117 struct hlist_node *node; 117 struct hlist_node *node;
118 struct batadv_gw_node *gw_node, *curr_gw = NULL; 118 struct batadv_gw_node *gw_node, *curr_gw = NULL;
119 uint32_t max_gw_factor = 0, tmp_gw_factor = 0; 119 uint32_t max_gw_factor = 0, tmp_gw_factor = 0;
120 uint32_t gw_divisor;
120 uint8_t max_tq = 0; 121 uint8_t max_tq = 0;
121 int down, up; 122 int down, up;
123 uint8_t tq_avg;
122 struct batadv_orig_node *orig_node; 124 struct batadv_orig_node *orig_node;
123 125
126 gw_divisor = BATADV_TQ_LOCAL_WINDOW_SIZE * BATADV_TQ_LOCAL_WINDOW_SIZE;
127 gw_divisor *= 64;
128
124 rcu_read_lock(); 129 rcu_read_lock();
125 hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) { 130 hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw.list, list) {
126 if (gw_node->deleted) 131 if (gw_node->deleted)
127 continue; 132 continue;
128 133
@@ -134,19 +139,19 @@ batadv_gw_get_best_gw_node(struct batadv_priv *bat_priv)
134 if (!atomic_inc_not_zero(&gw_node->refcount)) 139 if (!atomic_inc_not_zero(&gw_node->refcount))
135 goto next; 140 goto next;
136 141
142 tq_avg = router->tq_avg;
143
137 switch (atomic_read(&bat_priv->gw_sel_class)) { 144 switch (atomic_read(&bat_priv->gw_sel_class)) {
138 case 1: /* fast connection */ 145 case 1: /* fast connection */
139 batadv_gw_bandwidth_to_kbit(orig_node->gw_flags, 146 batadv_gw_bandwidth_to_kbit(orig_node->gw_flags,
140 &down, &up); 147 &down, &up);
141 148
142 tmp_gw_factor = (router->tq_avg * router->tq_avg * 149 tmp_gw_factor = tq_avg * tq_avg * down * 100 * 100;
143 down * 100 * 100) / 150 tmp_gw_factor /= gw_divisor;
144 (BATADV_TQ_LOCAL_WINDOW_SIZE *
145 BATADV_TQ_LOCAL_WINDOW_SIZE * 64);
146 151
147 if ((tmp_gw_factor > max_gw_factor) || 152 if ((tmp_gw_factor > max_gw_factor) ||
148 ((tmp_gw_factor == max_gw_factor) && 153 ((tmp_gw_factor == max_gw_factor) &&
149 (router->tq_avg > max_tq))) { 154 (tq_avg > max_tq))) {
150 if (curr_gw) 155 if (curr_gw)
151 batadv_gw_node_free_ref(curr_gw); 156 batadv_gw_node_free_ref(curr_gw);
152 curr_gw = gw_node; 157 curr_gw = gw_node;
@@ -161,7 +166,7 @@ batadv_gw_get_best_gw_node(struct batadv_priv *bat_priv)
161 * soon as a better gateway appears which has 166 * soon as a better gateway appears which has
162 * $routing_class more tq points) 167 * $routing_class more tq points)
163 */ 168 */
164 if (router->tq_avg > max_tq) { 169 if (tq_avg > max_tq) {
165 if (curr_gw) 170 if (curr_gw)
166 batadv_gw_node_free_ref(curr_gw); 171 batadv_gw_node_free_ref(curr_gw);
167 curr_gw = gw_node; 172 curr_gw = gw_node;
@@ -170,8 +175,8 @@ batadv_gw_get_best_gw_node(struct batadv_priv *bat_priv)
170 break; 175 break;
171 } 176 }
172 177
173 if (router->tq_avg > max_tq) 178 if (tq_avg > max_tq)
174 max_tq = router->tq_avg; 179 max_tq = tq_avg;
175 180
176 if (tmp_gw_factor > max_gw_factor) 181 if (tmp_gw_factor > max_gw_factor)
177 max_gw_factor = tmp_gw_factor; 182 max_gw_factor = tmp_gw_factor;
@@ -202,7 +207,7 @@ void batadv_gw_election(struct batadv_priv *bat_priv)
202 207
203 curr_gw = batadv_gw_get_selected_gw_node(bat_priv); 208 curr_gw = batadv_gw_get_selected_gw_node(bat_priv);
204 209
205 if (!batadv_atomic_dec_not_zero(&bat_priv->gw_reselect) && curr_gw) 210 if (!batadv_atomic_dec_not_zero(&bat_priv->gw.reselect) && curr_gw)
206 goto out; 211 goto out;
207 212
208 next_gw = batadv_gw_get_best_gw_node(bat_priv); 213 next_gw = batadv_gw_get_best_gw_node(bat_priv);
@@ -321,9 +326,9 @@ static void batadv_gw_node_add(struct batadv_priv *bat_priv,
321 gw_node->orig_node = orig_node; 326 gw_node->orig_node = orig_node;
322 atomic_set(&gw_node->refcount, 1); 327 atomic_set(&gw_node->refcount, 1);
323 328
324 spin_lock_bh(&bat_priv->gw_list_lock); 329 spin_lock_bh(&bat_priv->gw.list_lock);
325 hlist_add_head_rcu(&gw_node->list, &bat_priv->gw_list); 330 hlist_add_head_rcu(&gw_node->list, &bat_priv->gw.list);
326 spin_unlock_bh(&bat_priv->gw_list_lock); 331 spin_unlock_bh(&bat_priv->gw.list_lock);
327 332
328 batadv_gw_bandwidth_to_kbit(new_gwflags, &down, &up); 333 batadv_gw_bandwidth_to_kbit(new_gwflags, &down, &up);
329 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, 334 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
@@ -350,7 +355,7 @@ void batadv_gw_node_update(struct batadv_priv *bat_priv,
350 curr_gw = batadv_gw_get_selected_gw_node(bat_priv); 355 curr_gw = batadv_gw_get_selected_gw_node(bat_priv);
351 356
352 rcu_read_lock(); 357 rcu_read_lock();
353 hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) { 358 hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw.list, list) {
354 if (gw_node->orig_node != orig_node) 359 if (gw_node->orig_node != orig_node)
355 continue; 360 continue;
356 361
@@ -404,10 +409,10 @@ void batadv_gw_node_purge(struct batadv_priv *bat_priv)
404 409
405 curr_gw = batadv_gw_get_selected_gw_node(bat_priv); 410 curr_gw = batadv_gw_get_selected_gw_node(bat_priv);
406 411
407 spin_lock_bh(&bat_priv->gw_list_lock); 412 spin_lock_bh(&bat_priv->gw.list_lock);
408 413
409 hlist_for_each_entry_safe(gw_node, node, node_tmp, 414 hlist_for_each_entry_safe(gw_node, node, node_tmp,
410 &bat_priv->gw_list, list) { 415 &bat_priv->gw.list, list) {
411 if (((!gw_node->deleted) || 416 if (((!gw_node->deleted) ||
412 (time_before(jiffies, gw_node->deleted + timeout))) && 417 (time_before(jiffies, gw_node->deleted + timeout))) &&
413 atomic_read(&bat_priv->mesh_state) == BATADV_MESH_ACTIVE) 418 atomic_read(&bat_priv->mesh_state) == BATADV_MESH_ACTIVE)
@@ -420,7 +425,7 @@ void batadv_gw_node_purge(struct batadv_priv *bat_priv)
420 batadv_gw_node_free_ref(gw_node); 425 batadv_gw_node_free_ref(gw_node);
421 } 426 }
422 427
423 spin_unlock_bh(&bat_priv->gw_list_lock); 428 spin_unlock_bh(&bat_priv->gw.list_lock);
424 429
425 /* gw_deselect() needs to acquire the gw_list_lock */ 430 /* gw_deselect() needs to acquire the gw_list_lock */
426 if (do_deselect) 431 if (do_deselect)
@@ -496,7 +501,7 @@ int batadv_gw_client_seq_print_text(struct seq_file *seq, void *offset)
496 primary_if->net_dev->dev_addr, net_dev->name); 501 primary_if->net_dev->dev_addr, net_dev->name);
497 502
498 rcu_read_lock(); 503 rcu_read_lock();
499 hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) { 504 hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw.list, list) {
500 if (gw_node->deleted) 505 if (gw_node->deleted)
501 continue; 506 continue;
502 507
diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c
index 282bf6e9353..d112fd6750b 100644
--- a/net/batman-adv/hard-interface.c
+++ b/net/batman-adv/hard-interface.c
@@ -103,13 +103,14 @@ static void batadv_primary_if_update_addr(struct batadv_priv *bat_priv,
103{ 103{
104 struct batadv_vis_packet *vis_packet; 104 struct batadv_vis_packet *vis_packet;
105 struct batadv_hard_iface *primary_if; 105 struct batadv_hard_iface *primary_if;
106 struct sk_buff *skb;
106 107
107 primary_if = batadv_primary_if_get_selected(bat_priv); 108 primary_if = batadv_primary_if_get_selected(bat_priv);
108 if (!primary_if) 109 if (!primary_if)
109 goto out; 110 goto out;
110 111
111 vis_packet = (struct batadv_vis_packet *) 112 skb = bat_priv->vis.my_info->skb_packet;
112 bat_priv->my_vis_info->skb_packet->data; 113 vis_packet = (struct batadv_vis_packet *)skb->data;
113 memcpy(vis_packet->vis_orig, primary_if->net_dev->dev_addr, ETH_ALEN); 114 memcpy(vis_packet->vis_orig, primary_if->net_dev->dev_addr, ETH_ALEN);
114 memcpy(vis_packet->sender_orig, 115 memcpy(vis_packet->sender_orig,
115 primary_if->net_dev->dev_addr, ETH_ALEN); 116 primary_if->net_dev->dev_addr, ETH_ALEN);
@@ -313,7 +314,13 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface,
313 hard_iface->if_num = bat_priv->num_ifaces; 314 hard_iface->if_num = bat_priv->num_ifaces;
314 bat_priv->num_ifaces++; 315 bat_priv->num_ifaces++;
315 hard_iface->if_status = BATADV_IF_INACTIVE; 316 hard_iface->if_status = BATADV_IF_INACTIVE;
316 batadv_orig_hash_add_if(hard_iface, bat_priv->num_ifaces); 317 ret = batadv_orig_hash_add_if(hard_iface, bat_priv->num_ifaces);
318 if (ret < 0) {
319 bat_priv->bat_algo_ops->bat_iface_disable(hard_iface);
320 bat_priv->num_ifaces--;
321 hard_iface->if_status = BATADV_IF_NOT_IN_USE;
322 goto err_dev;
323 }
317 324
318 hard_iface->batman_adv_ptype.type = ethertype; 325 hard_iface->batman_adv_ptype.type = ethertype;
319 hard_iface->batman_adv_ptype.func = batadv_batman_skb_recv; 326 hard_iface->batman_adv_ptype.func = batadv_batman_skb_recv;
diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c
index 13c88b25ab3..b4aa470bc4a 100644
--- a/net/batman-adv/main.c
+++ b/net/batman-adv/main.c
@@ -58,9 +58,6 @@ static int __init batadv_init(void)
58 58
59 batadv_iv_init(); 59 batadv_iv_init();
60 60
61 /* the name should not be longer than 10 chars - see
62 * http://lwn.net/Articles/23634/
63 */
64 batadv_event_workqueue = create_singlethread_workqueue("bat_events"); 61 batadv_event_workqueue = create_singlethread_workqueue("bat_events");
65 62
66 if (!batadv_event_workqueue) 63 if (!batadv_event_workqueue)
@@ -97,20 +94,20 @@ int batadv_mesh_init(struct net_device *soft_iface)
97 94
98 spin_lock_init(&bat_priv->forw_bat_list_lock); 95 spin_lock_init(&bat_priv->forw_bat_list_lock);
99 spin_lock_init(&bat_priv->forw_bcast_list_lock); 96 spin_lock_init(&bat_priv->forw_bcast_list_lock);
100 spin_lock_init(&bat_priv->tt_changes_list_lock); 97 spin_lock_init(&bat_priv->tt.changes_list_lock);
101 spin_lock_init(&bat_priv->tt_req_list_lock); 98 spin_lock_init(&bat_priv->tt.req_list_lock);
102 spin_lock_init(&bat_priv->tt_roam_list_lock); 99 spin_lock_init(&bat_priv->tt.roam_list_lock);
103 spin_lock_init(&bat_priv->tt_buff_lock); 100 spin_lock_init(&bat_priv->tt.last_changeset_lock);
104 spin_lock_init(&bat_priv->gw_list_lock); 101 spin_lock_init(&bat_priv->gw.list_lock);
105 spin_lock_init(&bat_priv->vis_hash_lock); 102 spin_lock_init(&bat_priv->vis.hash_lock);
106 spin_lock_init(&bat_priv->vis_list_lock); 103 spin_lock_init(&bat_priv->vis.list_lock);
107 104
108 INIT_HLIST_HEAD(&bat_priv->forw_bat_list); 105 INIT_HLIST_HEAD(&bat_priv->forw_bat_list);
109 INIT_HLIST_HEAD(&bat_priv->forw_bcast_list); 106 INIT_HLIST_HEAD(&bat_priv->forw_bcast_list);
110 INIT_HLIST_HEAD(&bat_priv->gw_list); 107 INIT_HLIST_HEAD(&bat_priv->gw.list);
111 INIT_LIST_HEAD(&bat_priv->tt_changes_list); 108 INIT_LIST_HEAD(&bat_priv->tt.changes_list);
112 INIT_LIST_HEAD(&bat_priv->tt_req_list); 109 INIT_LIST_HEAD(&bat_priv->tt.req_list);
113 INIT_LIST_HEAD(&bat_priv->tt_roam_list); 110 INIT_LIST_HEAD(&bat_priv->tt.roam_list);
114 111
115 ret = batadv_originator_init(bat_priv); 112 ret = batadv_originator_init(bat_priv);
116 if (ret < 0) 113 if (ret < 0)
@@ -131,7 +128,7 @@ int batadv_mesh_init(struct net_device *soft_iface)
131 if (ret < 0) 128 if (ret < 0)
132 goto err; 129 goto err;
133 130
134 atomic_set(&bat_priv->gw_reselect, 0); 131 atomic_set(&bat_priv->gw.reselect, 0);
135 atomic_set(&bat_priv->mesh_state, BATADV_MESH_ACTIVE); 132 atomic_set(&bat_priv->mesh_state, BATADV_MESH_ACTIVE);
136 133
137 return 0; 134 return 0;
diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h
index 5d8fa075794..d57b746219d 100644
--- a/net/batman-adv/main.h
+++ b/net/batman-adv/main.h
@@ -26,7 +26,7 @@
26#define BATADV_DRIVER_DEVICE "batman-adv" 26#define BATADV_DRIVER_DEVICE "batman-adv"
27 27
28#ifndef BATADV_SOURCE_VERSION 28#ifndef BATADV_SOURCE_VERSION
29#define BATADV_SOURCE_VERSION "2012.3.0" 29#define BATADV_SOURCE_VERSION "2012.4.0"
30#endif 30#endif
31 31
32/* B.A.T.M.A.N. parameters */ 32/* B.A.T.M.A.N. parameters */
@@ -41,13 +41,14 @@
41 * -> TODO: check influence on BATADV_TQ_LOCAL_WINDOW_SIZE 41 * -> TODO: check influence on BATADV_TQ_LOCAL_WINDOW_SIZE
42 */ 42 */
43#define BATADV_PURGE_TIMEOUT 200000 /* 200 seconds */ 43#define BATADV_PURGE_TIMEOUT 200000 /* 200 seconds */
44#define BATADV_TT_LOCAL_TIMEOUT 3600000 /* in miliseconds */ 44#define BATADV_TT_LOCAL_TIMEOUT 3600000 /* in milliseconds */
45#define BATADV_TT_CLIENT_ROAM_TIMEOUT 600000 /* in miliseconds */ 45#define BATADV_TT_CLIENT_ROAM_TIMEOUT 600000 /* in milliseconds */
46#define BATADV_TT_CLIENT_TEMP_TIMEOUT 600000 /* in milliseconds */
46/* sliding packet range of received originator messages in sequence numbers 47/* sliding packet range of received originator messages in sequence numbers
47 * (should be a multiple of our word size) 48 * (should be a multiple of our word size)
48 */ 49 */
49#define BATADV_TQ_LOCAL_WINDOW_SIZE 64 50#define BATADV_TQ_LOCAL_WINDOW_SIZE 64
50/* miliseconds we have to keep pending tt_req */ 51/* milliseconds we have to keep pending tt_req */
51#define BATADV_TT_REQUEST_TIMEOUT 3000 52#define BATADV_TT_REQUEST_TIMEOUT 3000
52 53
53#define BATADV_TQ_GLOBAL_WINDOW_SIZE 5 54#define BATADV_TQ_GLOBAL_WINDOW_SIZE 5
@@ -59,7 +60,7 @@
59#define BATADV_TT_OGM_APPEND_MAX 3 60#define BATADV_TT_OGM_APPEND_MAX 3
60 61
61/* Time in which a client can roam at most ROAMING_MAX_COUNT times in 62/* Time in which a client can roam at most ROAMING_MAX_COUNT times in
62 * miliseconds 63 * milliseconds
63 */ 64 */
64#define BATADV_ROAMING_MAX_TIME 20000 65#define BATADV_ROAMING_MAX_TIME 20000
65#define BATADV_ROAMING_MAX_COUNT 5 66#define BATADV_ROAMING_MAX_COUNT 5
@@ -123,15 +124,6 @@ enum batadv_uev_type {
123/* Append 'batman-adv: ' before kernel messages */ 124/* Append 'batman-adv: ' before kernel messages */
124#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 125#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
125 126
126/* all messages related to routing / flooding / broadcasting / etc */
127enum batadv_dbg_level {
128 BATADV_DBG_BATMAN = 1 << 0,
129 BATADV_DBG_ROUTES = 1 << 1, /* route added / changed / deleted */
130 BATADV_DBG_TT = 1 << 2, /* translation table operations */
131 BATADV_DBG_BLA = 1 << 3, /* bridge loop avoidance */
132 BATADV_DBG_ALL = 15,
133};
134
135/* Kernel headers */ 127/* Kernel headers */
136 128
137#include <linux/mutex.h> /* mutex */ 129#include <linux/mutex.h> /* mutex */
@@ -173,6 +165,15 @@ int batadv_algo_register(struct batadv_algo_ops *bat_algo_ops);
173int batadv_algo_select(struct batadv_priv *bat_priv, char *name); 165int batadv_algo_select(struct batadv_priv *bat_priv, char *name);
174int batadv_algo_seq_print_text(struct seq_file *seq, void *offset); 166int batadv_algo_seq_print_text(struct seq_file *seq, void *offset);
175 167
168/* all messages related to routing / flooding / broadcasting / etc */
169enum batadv_dbg_level {
170 BATADV_DBG_BATMAN = BIT(0),
171 BATADV_DBG_ROUTES = BIT(1), /* route added / changed / deleted */
172 BATADV_DBG_TT = BIT(2), /* translation table operations */
173 BATADV_DBG_BLA = BIT(3), /* bridge loop avoidance */
174 BATADV_DBG_ALL = 15,
175};
176
176#ifdef CONFIG_BATMAN_ADV_DEBUG 177#ifdef CONFIG_BATMAN_ADV_DEBUG
177int batadv_debug_log(struct batadv_priv *bat_priv, const char *fmt, ...) 178int batadv_debug_log(struct batadv_priv *bat_priv, const char *fmt, ...)
178__printf(2, 3); 179__printf(2, 3);
diff --git a/net/batman-adv/packet.h b/net/batman-adv/packet.h
index 8d3e55a96ad..2d23a14c220 100644
--- a/net/batman-adv/packet.h
+++ b/net/batman-adv/packet.h
@@ -37,10 +37,10 @@ enum batadv_packettype {
37#define BATADV_COMPAT_VERSION 14 37#define BATADV_COMPAT_VERSION 14
38 38
39enum batadv_iv_flags { 39enum batadv_iv_flags {
40 BATADV_NOT_BEST_NEXT_HOP = 1 << 3, 40 BATADV_NOT_BEST_NEXT_HOP = BIT(3),
41 BATADV_PRIMARIES_FIRST_HOP = 1 << 4, 41 BATADV_PRIMARIES_FIRST_HOP = BIT(4),
42 BATADV_VIS_SERVER = 1 << 5, 42 BATADV_VIS_SERVER = BIT(5),
43 BATADV_DIRECTLINK = 1 << 6, 43 BATADV_DIRECTLINK = BIT(6),
44}; 44};
45 45
46/* ICMP message types */ 46/* ICMP message types */
@@ -60,8 +60,8 @@ enum batadv_vis_packettype {
60 60
61/* fragmentation defines */ 61/* fragmentation defines */
62enum batadv_unicast_frag_flags { 62enum batadv_unicast_frag_flags {
63 BATADV_UNI_FRAG_HEAD = 1 << 0, 63 BATADV_UNI_FRAG_HEAD = BIT(0),
64 BATADV_UNI_FRAG_LARGETAIL = 1 << 1, 64 BATADV_UNI_FRAG_LARGETAIL = BIT(1),
65}; 65};
66 66
67/* TT_QUERY subtypes */ 67/* TT_QUERY subtypes */
@@ -74,26 +74,27 @@ enum batadv_tt_query_packettype {
74 74
75/* TT_QUERY flags */ 75/* TT_QUERY flags */
76enum batadv_tt_query_flags { 76enum batadv_tt_query_flags {
77 BATADV_TT_FULL_TABLE = 1 << 2, 77 BATADV_TT_FULL_TABLE = BIT(2),
78}; 78};
79 79
80/* BATADV_TT_CLIENT flags. 80/* BATADV_TT_CLIENT flags.
81 * Flags from 1 to 1 << 7 are sent on the wire, while flags from 1 << 8 to 81 * Flags from BIT(0) to BIT(7) are sent on the wire, while flags from BIT(8) to
82 * 1 << 15 are used for local computation only 82 * BIT(15) are used for local computation only
83 */ 83 */
84enum batadv_tt_client_flags { 84enum batadv_tt_client_flags {
85 BATADV_TT_CLIENT_DEL = 1 << 0, 85 BATADV_TT_CLIENT_DEL = BIT(0),
86 BATADV_TT_CLIENT_ROAM = 1 << 1, 86 BATADV_TT_CLIENT_ROAM = BIT(1),
87 BATADV_TT_CLIENT_WIFI = 1 << 2, 87 BATADV_TT_CLIENT_WIFI = BIT(2),
88 BATADV_TT_CLIENT_NOPURGE = 1 << 8, 88 BATADV_TT_CLIENT_TEMP = BIT(3),
89 BATADV_TT_CLIENT_NEW = 1 << 9, 89 BATADV_TT_CLIENT_NOPURGE = BIT(8),
90 BATADV_TT_CLIENT_PENDING = 1 << 10, 90 BATADV_TT_CLIENT_NEW = BIT(9),
91 BATADV_TT_CLIENT_PENDING = BIT(10),
91}; 92};
92 93
93/* claim frame types for the bridge loop avoidance */ 94/* claim frame types for the bridge loop avoidance */
94enum batadv_bla_claimframe { 95enum batadv_bla_claimframe {
95 BATADV_CLAIM_TYPE_ADD = 0x00, 96 BATADV_CLAIM_TYPE_CLAIM = 0x00,
96 BATADV_CLAIM_TYPE_DEL = 0x01, 97 BATADV_CLAIM_TYPE_UNCLAIM = 0x01,
97 BATADV_CLAIM_TYPE_ANNOUNCE = 0x02, 98 BATADV_CLAIM_TYPE_ANNOUNCE = 0x02,
98 BATADV_CLAIM_TYPE_REQUEST = 0x03, 99 BATADV_CLAIM_TYPE_REQUEST = 0x03,
99}; 100};
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
index bc2b88bbea1..939fc01371d 100644
--- a/net/batman-adv/routing.c
+++ b/net/batman-adv/routing.c
@@ -579,32 +579,45 @@ batadv_find_ifalter_router(struct batadv_orig_node *primary_orig,
579 return router; 579 return router;
580} 580}
581 581
582int batadv_recv_tt_query(struct sk_buff *skb, struct batadv_hard_iface *recv_if) 582static int batadv_check_unicast_packet(struct sk_buff *skb, int hdr_size)
583{ 583{
584 struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface);
585 struct batadv_tt_query_packet *tt_query;
586 uint16_t tt_size;
587 struct ethhdr *ethhdr; 584 struct ethhdr *ethhdr;
588 char tt_flag;
589 size_t packet_size;
590 585
591 /* drop packet if it has not necessary minimum size */ 586 /* drop packet if it has not necessary minimum size */
592 if (unlikely(!pskb_may_pull(skb, 587 if (unlikely(!pskb_may_pull(skb, hdr_size)))
593 sizeof(struct batadv_tt_query_packet)))) 588 return -1;
594 goto out;
595
596 /* I could need to modify it */
597 if (skb_cow(skb, sizeof(struct batadv_tt_query_packet)) < 0)
598 goto out;
599 589
600 ethhdr = (struct ethhdr *)skb_mac_header(skb); 590 ethhdr = (struct ethhdr *)skb_mac_header(skb);
601 591
602 /* packet with unicast indication but broadcast recipient */ 592 /* packet with unicast indication but broadcast recipient */
603 if (is_broadcast_ether_addr(ethhdr->h_dest)) 593 if (is_broadcast_ether_addr(ethhdr->h_dest))
604 goto out; 594 return -1;
605 595
606 /* packet with broadcast sender address */ 596 /* packet with broadcast sender address */
607 if (is_broadcast_ether_addr(ethhdr->h_source)) 597 if (is_broadcast_ether_addr(ethhdr->h_source))
598 return -1;
599
600 /* not for me */
601 if (!batadv_is_my_mac(ethhdr->h_dest))
602 return -1;
603
604 return 0;
605}
606
607int batadv_recv_tt_query(struct sk_buff *skb, struct batadv_hard_iface *recv_if)
608{
609 struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface);
610 struct batadv_tt_query_packet *tt_query;
611 uint16_t tt_size;
612 int hdr_size = sizeof(*tt_query);
613 char tt_flag;
614 size_t packet_size;
615
616 if (batadv_check_unicast_packet(skb, hdr_size) < 0)
617 return NET_RX_DROP;
618
619 /* I could need to modify it */
620 if (skb_cow(skb, sizeof(struct batadv_tt_query_packet)) < 0)
608 goto out; 621 goto out;
609 622
610 tt_query = (struct batadv_tt_query_packet *)skb->data; 623 tt_query = (struct batadv_tt_query_packet *)skb->data;
@@ -721,7 +734,7 @@ int batadv_recv_roam_adv(struct sk_buff *skb, struct batadv_hard_iface *recv_if)
721 * been incremented yet. This flag will make me check all the incoming 734 * been incremented yet. This flag will make me check all the incoming
722 * packets for the correct destination. 735 * packets for the correct destination.
723 */ 736 */
724 bat_priv->tt_poss_change = true; 737 bat_priv->tt.poss_change = true;
725 738
726 batadv_orig_node_free_ref(orig_node); 739 batadv_orig_node_free_ref(orig_node);
727out: 740out:
@@ -819,31 +832,6 @@ err:
819 return NULL; 832 return NULL;
820} 833}
821 834
822static int batadv_check_unicast_packet(struct sk_buff *skb, int hdr_size)
823{
824 struct ethhdr *ethhdr;
825
826 /* drop packet if it has not necessary minimum size */
827 if (unlikely(!pskb_may_pull(skb, hdr_size)))
828 return -1;
829
830 ethhdr = (struct ethhdr *)skb_mac_header(skb);
831
832 /* packet with unicast indication but broadcast recipient */
833 if (is_broadcast_ether_addr(ethhdr->h_dest))
834 return -1;
835
836 /* packet with broadcast sender address */
837 if (is_broadcast_ether_addr(ethhdr->h_source))
838 return -1;
839
840 /* not for me */
841 if (!batadv_is_my_mac(ethhdr->h_dest))
842 return -1;
843
844 return 0;
845}
846
847static int batadv_route_unicast_packet(struct sk_buff *skb, 835static int batadv_route_unicast_packet(struct sk_buff *skb,
848 struct batadv_hard_iface *recv_if) 836 struct batadv_hard_iface *recv_if)
849{ 837{
@@ -947,8 +935,8 @@ static int batadv_check_unicast_ttvn(struct batadv_priv *bat_priv,
947 unicast_packet = (struct batadv_unicast_packet *)skb->data; 935 unicast_packet = (struct batadv_unicast_packet *)skb->data;
948 936
949 if (batadv_is_my_mac(unicast_packet->dest)) { 937 if (batadv_is_my_mac(unicast_packet->dest)) {
950 tt_poss_change = bat_priv->tt_poss_change; 938 tt_poss_change = bat_priv->tt.poss_change;
951 curr_ttvn = (uint8_t)atomic_read(&bat_priv->ttvn); 939 curr_ttvn = (uint8_t)atomic_read(&bat_priv->tt.vn);
952 } else { 940 } else {
953 orig_node = batadv_orig_hash_find(bat_priv, 941 orig_node = batadv_orig_hash_find(bat_priv,
954 unicast_packet->dest); 942 unicast_packet->dest);
@@ -993,8 +981,7 @@ static int batadv_check_unicast_ttvn(struct batadv_priv *bat_priv,
993 } else { 981 } else {
994 memcpy(unicast_packet->dest, orig_node->orig, 982 memcpy(unicast_packet->dest, orig_node->orig,
995 ETH_ALEN); 983 ETH_ALEN);
996 curr_ttvn = (uint8_t) 984 curr_ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn);
997 atomic_read(&orig_node->last_ttvn);
998 batadv_orig_node_free_ref(orig_node); 985 batadv_orig_node_free_ref(orig_node);
999 } 986 }
1000 987
@@ -1025,8 +1012,9 @@ int batadv_recv_unicast_packet(struct sk_buff *skb,
1025 1012
1026 /* packet for me */ 1013 /* packet for me */
1027 if (batadv_is_my_mac(unicast_packet->dest)) { 1014 if (batadv_is_my_mac(unicast_packet->dest)) {
1028 batadv_interface_rx(recv_if->soft_iface, skb, recv_if, 1015 batadv_interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size,
1029 hdr_size); 1016 NULL);
1017
1030 return NET_RX_SUCCESS; 1018 return NET_RX_SUCCESS;
1031 } 1019 }
1032 1020
@@ -1063,7 +1051,7 @@ int batadv_recv_ucast_frag_packet(struct sk_buff *skb,
1063 return NET_RX_SUCCESS; 1051 return NET_RX_SUCCESS;
1064 1052
1065 batadv_interface_rx(recv_if->soft_iface, new_skb, recv_if, 1053 batadv_interface_rx(recv_if->soft_iface, new_skb, recv_if,
1066 sizeof(struct batadv_unicast_packet)); 1054 sizeof(struct batadv_unicast_packet), NULL);
1067 return NET_RX_SUCCESS; 1055 return NET_RX_SUCCESS;
1068 } 1056 }
1069 1057
@@ -1150,7 +1138,8 @@ int batadv_recv_bcast_packet(struct sk_buff *skb,
1150 goto out; 1138 goto out;
1151 1139
1152 /* broadcast for me */ 1140 /* broadcast for me */
1153 batadv_interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size); 1141 batadv_interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size,
1142 orig_node);
1154 ret = NET_RX_SUCCESS; 1143 ret = NET_RX_SUCCESS;
1155 goto out; 1144 goto out;
1156 1145
diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c
index 3b4b2daa3b3..570a8bce036 100644
--- a/net/batman-adv/send.c
+++ b/net/batman-adv/send.c
@@ -190,13 +190,13 @@ out:
190static void batadv_send_outstanding_bcast_packet(struct work_struct *work) 190static void batadv_send_outstanding_bcast_packet(struct work_struct *work)
191{ 191{
192 struct batadv_hard_iface *hard_iface; 192 struct batadv_hard_iface *hard_iface;
193 struct delayed_work *delayed_work = 193 struct delayed_work *delayed_work;
194 container_of(work, struct delayed_work, work);
195 struct batadv_forw_packet *forw_packet; 194 struct batadv_forw_packet *forw_packet;
196 struct sk_buff *skb1; 195 struct sk_buff *skb1;
197 struct net_device *soft_iface; 196 struct net_device *soft_iface;
198 struct batadv_priv *bat_priv; 197 struct batadv_priv *bat_priv;
199 198
199 delayed_work = container_of(work, struct delayed_work, work);
200 forw_packet = container_of(delayed_work, struct batadv_forw_packet, 200 forw_packet = container_of(delayed_work, struct batadv_forw_packet,
201 delayed_work); 201 delayed_work);
202 soft_iface = forw_packet->if_incoming->soft_iface; 202 soft_iface = forw_packet->if_incoming->soft_iface;
@@ -239,11 +239,11 @@ out:
239 239
240void batadv_send_outstanding_bat_ogm_packet(struct work_struct *work) 240void batadv_send_outstanding_bat_ogm_packet(struct work_struct *work)
241{ 241{
242 struct delayed_work *delayed_work = 242 struct delayed_work *delayed_work;
243 container_of(work, struct delayed_work, work);
244 struct batadv_forw_packet *forw_packet; 243 struct batadv_forw_packet *forw_packet;
245 struct batadv_priv *bat_priv; 244 struct batadv_priv *bat_priv;
246 245
246 delayed_work = container_of(work, struct delayed_work, work);
247 forw_packet = container_of(delayed_work, struct batadv_forw_packet, 247 forw_packet = container_of(delayed_work, struct batadv_forw_packet,
248 delayed_work); 248 delayed_work);
249 bat_priv = netdev_priv(forw_packet->if_incoming->soft_iface); 249 bat_priv = netdev_priv(forw_packet->if_incoming->soft_iface);
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
index 109ea2aae96..b9a28d2dd3e 100644
--- a/net/batman-adv/soft-interface.c
+++ b/net/batman-adv/soft-interface.c
@@ -93,25 +93,35 @@ static int batadv_interface_release(struct net_device *dev)
93static struct net_device_stats *batadv_interface_stats(struct net_device *dev) 93static struct net_device_stats *batadv_interface_stats(struct net_device *dev)
94{ 94{
95 struct batadv_priv *bat_priv = netdev_priv(dev); 95 struct batadv_priv *bat_priv = netdev_priv(dev);
96 return &bat_priv->stats; 96 struct net_device_stats *stats = &bat_priv->stats;
97
98 stats->tx_packets = batadv_sum_counter(bat_priv, BATADV_CNT_TX);
99 stats->tx_bytes = batadv_sum_counter(bat_priv, BATADV_CNT_TX_BYTES);
100 stats->tx_dropped = batadv_sum_counter(bat_priv, BATADV_CNT_TX_DROPPED);
101 stats->rx_packets = batadv_sum_counter(bat_priv, BATADV_CNT_RX);
102 stats->rx_bytes = batadv_sum_counter(bat_priv, BATADV_CNT_RX_BYTES);
103 return stats;
97} 104}
98 105
99static int batadv_interface_set_mac_addr(struct net_device *dev, void *p) 106static int batadv_interface_set_mac_addr(struct net_device *dev, void *p)
100{ 107{
101 struct batadv_priv *bat_priv = netdev_priv(dev); 108 struct batadv_priv *bat_priv = netdev_priv(dev);
102 struct sockaddr *addr = p; 109 struct sockaddr *addr = p;
110 uint8_t old_addr[ETH_ALEN];
103 111
104 if (!is_valid_ether_addr(addr->sa_data)) 112 if (!is_valid_ether_addr(addr->sa_data))
105 return -EADDRNOTAVAIL; 113 return -EADDRNOTAVAIL;
106 114
115 memcpy(old_addr, dev->dev_addr, ETH_ALEN);
116 memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
117
107 /* only modify transtable if it has been initialized before */ 118 /* only modify transtable if it has been initialized before */
108 if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_ACTIVE) { 119 if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_ACTIVE) {
109 batadv_tt_local_remove(bat_priv, dev->dev_addr, 120 batadv_tt_local_remove(bat_priv, old_addr,
110 "mac address changed", false); 121 "mac address changed", false);
111 batadv_tt_local_add(dev, addr->sa_data, BATADV_NULL_IFINDEX); 122 batadv_tt_local_add(dev, addr->sa_data, BATADV_NULL_IFINDEX);
112 } 123 }
113 124
114 memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
115 dev->addr_assign_type &= ~NET_ADDR_RANDOM; 125 dev->addr_assign_type &= ~NET_ADDR_RANDOM;
116 return 0; 126 return 0;
117} 127}
@@ -142,6 +152,7 @@ static int batadv_interface_tx(struct sk_buff *skb,
142 int data_len = skb->len, ret; 152 int data_len = skb->len, ret;
143 short vid __maybe_unused = -1; 153 short vid __maybe_unused = -1;
144 bool do_bcast = false; 154 bool do_bcast = false;
155 uint32_t seqno;
145 156
146 if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE) 157 if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE)
147 goto dropped; 158 goto dropped;
@@ -223,8 +234,8 @@ static int batadv_interface_tx(struct sk_buff *skb,
223 primary_if->net_dev->dev_addr, ETH_ALEN); 234 primary_if->net_dev->dev_addr, ETH_ALEN);
224 235
225 /* set broadcast sequence number */ 236 /* set broadcast sequence number */
226 bcast_packet->seqno = 237 seqno = atomic_inc_return(&bat_priv->bcast_seqno);
227 htonl(atomic_inc_return(&bat_priv->bcast_seqno)); 238 bcast_packet->seqno = htonl(seqno);
228 239
229 batadv_add_bcast_packet_to_list(bat_priv, skb, 1); 240 batadv_add_bcast_packet_to_list(bat_priv, skb, 1);
230 241
@@ -246,14 +257,14 @@ static int batadv_interface_tx(struct sk_buff *skb,
246 goto dropped_freed; 257 goto dropped_freed;
247 } 258 }
248 259
249 bat_priv->stats.tx_packets++; 260 batadv_inc_counter(bat_priv, BATADV_CNT_TX);
250 bat_priv->stats.tx_bytes += data_len; 261 batadv_add_counter(bat_priv, BATADV_CNT_TX_BYTES, data_len);
251 goto end; 262 goto end;
252 263
253dropped: 264dropped:
254 kfree_skb(skb); 265 kfree_skb(skb);
255dropped_freed: 266dropped_freed:
256 bat_priv->stats.tx_dropped++; 267 batadv_inc_counter(bat_priv, BATADV_CNT_TX_DROPPED);
257end: 268end:
258 if (primary_if) 269 if (primary_if)
259 batadv_hardif_free_ref(primary_if); 270 batadv_hardif_free_ref(primary_if);
@@ -262,7 +273,7 @@ end:
262 273
263void batadv_interface_rx(struct net_device *soft_iface, 274void batadv_interface_rx(struct net_device *soft_iface,
264 struct sk_buff *skb, struct batadv_hard_iface *recv_if, 275 struct sk_buff *skb, struct batadv_hard_iface *recv_if,
265 int hdr_size) 276 int hdr_size, struct batadv_orig_node *orig_node)
266{ 277{
267 struct batadv_priv *bat_priv = netdev_priv(soft_iface); 278 struct batadv_priv *bat_priv = netdev_priv(soft_iface);
268 struct ethhdr *ethhdr; 279 struct ethhdr *ethhdr;
@@ -308,11 +319,16 @@ void batadv_interface_rx(struct net_device *soft_iface,
308 319
309 /* skb->ip_summed = CHECKSUM_UNNECESSARY; */ 320 /* skb->ip_summed = CHECKSUM_UNNECESSARY; */
310 321
311 bat_priv->stats.rx_packets++; 322 batadv_inc_counter(bat_priv, BATADV_CNT_RX);
312 bat_priv->stats.rx_bytes += skb->len + ETH_HLEN; 323 batadv_add_counter(bat_priv, BATADV_CNT_RX_BYTES,
324 skb->len + ETH_HLEN);
313 325
314 soft_iface->last_rx = jiffies; 326 soft_iface->last_rx = jiffies;
315 327
328 if (orig_node)
329 batadv_tt_add_temporary_global_entry(bat_priv, orig_node,
330 ethhdr->h_source);
331
316 if (batadv_is_ap_isolated(bat_priv, ethhdr->h_source, ethhdr->h_dest)) 332 if (batadv_is_ap_isolated(bat_priv, ethhdr->h_source, ethhdr->h_dest))
317 goto dropped; 333 goto dropped;
318 334
@@ -379,15 +395,22 @@ struct net_device *batadv_softif_create(const char *name)
379 if (!soft_iface) 395 if (!soft_iface)
380 goto out; 396 goto out;
381 397
398 bat_priv = netdev_priv(soft_iface);
399
400 /* batadv_interface_stats() needs to be available as soon as
401 * register_netdevice() has been called
402 */
403 bat_priv->bat_counters = __alloc_percpu(cnt_len, __alignof__(uint64_t));
404 if (!bat_priv->bat_counters)
405 goto free_soft_iface;
406
382 ret = register_netdevice(soft_iface); 407 ret = register_netdevice(soft_iface);
383 if (ret < 0) { 408 if (ret < 0) {
384 pr_err("Unable to register the batman interface '%s': %i\n", 409 pr_err("Unable to register the batman interface '%s': %i\n",
385 name, ret); 410 name, ret);
386 goto free_soft_iface; 411 goto free_bat_counters;
387 } 412 }
388 413
389 bat_priv = netdev_priv(soft_iface);
390
391 atomic_set(&bat_priv->aggregated_ogms, 1); 414 atomic_set(&bat_priv->aggregated_ogms, 1);
392 atomic_set(&bat_priv->bonding, 0); 415 atomic_set(&bat_priv->bonding, 0);
393 atomic_set(&bat_priv->bridge_loop_avoidance, 0); 416 atomic_set(&bat_priv->bridge_loop_avoidance, 0);
@@ -405,29 +428,26 @@ struct net_device *batadv_softif_create(const char *name)
405 428
406 atomic_set(&bat_priv->mesh_state, BATADV_MESH_INACTIVE); 429 atomic_set(&bat_priv->mesh_state, BATADV_MESH_INACTIVE);
407 atomic_set(&bat_priv->bcast_seqno, 1); 430 atomic_set(&bat_priv->bcast_seqno, 1);
408 atomic_set(&bat_priv->ttvn, 0); 431 atomic_set(&bat_priv->tt.vn, 0);
409 atomic_set(&bat_priv->tt_local_changes, 0); 432 atomic_set(&bat_priv->tt.local_changes, 0);
410 atomic_set(&bat_priv->tt_ogm_append_cnt, 0); 433 atomic_set(&bat_priv->tt.ogm_append_cnt, 0);
411 atomic_set(&bat_priv->bla_num_requests, 0); 434#ifdef CONFIG_BATMAN_ADV_BLA
412 435 atomic_set(&bat_priv->bla.num_requests, 0);
413 bat_priv->tt_buff = NULL; 436#endif
414 bat_priv->tt_buff_len = 0; 437 bat_priv->tt.last_changeset = NULL;
415 bat_priv->tt_poss_change = false; 438 bat_priv->tt.last_changeset_len = 0;
439 bat_priv->tt.poss_change = false;
416 440
417 bat_priv->primary_if = NULL; 441 bat_priv->primary_if = NULL;
418 bat_priv->num_ifaces = 0; 442 bat_priv->num_ifaces = 0;
419 443
420 bat_priv->bat_counters = __alloc_percpu(cnt_len, __alignof__(uint64_t));
421 if (!bat_priv->bat_counters)
422 goto unreg_soft_iface;
423
424 ret = batadv_algo_select(bat_priv, batadv_routing_algo); 444 ret = batadv_algo_select(bat_priv, batadv_routing_algo);
425 if (ret < 0) 445 if (ret < 0)
426 goto free_bat_counters; 446 goto unreg_soft_iface;
427 447
428 ret = batadv_sysfs_add_meshif(soft_iface); 448 ret = batadv_sysfs_add_meshif(soft_iface);
429 if (ret < 0) 449 if (ret < 0)
430 goto free_bat_counters; 450 goto unreg_soft_iface;
431 451
432 ret = batadv_debugfs_add_meshif(soft_iface); 452 ret = batadv_debugfs_add_meshif(soft_iface);
433 if (ret < 0) 453 if (ret < 0)
@@ -443,12 +463,13 @@ unreg_debugfs:
443 batadv_debugfs_del_meshif(soft_iface); 463 batadv_debugfs_del_meshif(soft_iface);
444unreg_sysfs: 464unreg_sysfs:
445 batadv_sysfs_del_meshif(soft_iface); 465 batadv_sysfs_del_meshif(soft_iface);
446free_bat_counters:
447 free_percpu(bat_priv->bat_counters);
448unreg_soft_iface: 466unreg_soft_iface:
467 free_percpu(bat_priv->bat_counters);
449 unregister_netdevice(soft_iface); 468 unregister_netdevice(soft_iface);
450 return NULL; 469 return NULL;
451 470
471free_bat_counters:
472 free_percpu(bat_priv->bat_counters);
452free_soft_iface: 473free_soft_iface:
453 free_netdev(soft_iface); 474 free_netdev(soft_iface);
454out: 475out:
@@ -518,6 +539,11 @@ static u32 batadv_get_link(struct net_device *dev)
518static const struct { 539static const struct {
519 const char name[ETH_GSTRING_LEN]; 540 const char name[ETH_GSTRING_LEN];
520} batadv_counters_strings[] = { 541} batadv_counters_strings[] = {
542 { "tx" },
543 { "tx_bytes" },
544 { "tx_dropped" },
545 { "rx" },
546 { "rx_bytes" },
521 { "forward" }, 547 { "forward" },
522 { "forward_bytes" }, 548 { "forward_bytes" },
523 { "mgmt_tx" }, 549 { "mgmt_tx" },
diff --git a/net/batman-adv/soft-interface.h b/net/batman-adv/soft-interface.h
index 852c683b06a..07a08fed28b 100644
--- a/net/batman-adv/soft-interface.h
+++ b/net/batman-adv/soft-interface.h
@@ -21,8 +21,9 @@
21#define _NET_BATMAN_ADV_SOFT_INTERFACE_H_ 21#define _NET_BATMAN_ADV_SOFT_INTERFACE_H_
22 22
23int batadv_skb_head_push(struct sk_buff *skb, unsigned int len); 23int batadv_skb_head_push(struct sk_buff *skb, unsigned int len);
24void batadv_interface_rx(struct net_device *soft_iface, struct sk_buff *skb, 24void batadv_interface_rx(struct net_device *soft_iface,
25 struct batadv_hard_iface *recv_if, int hdr_size); 25 struct sk_buff *skb, struct batadv_hard_iface *recv_if,
26 int hdr_size, struct batadv_orig_node *orig_node);
26struct net_device *batadv_softif_create(const char *name); 27struct net_device *batadv_softif_create(const char *name);
27void batadv_softif_destroy(struct net_device *soft_iface); 28void batadv_softif_destroy(struct net_device *soft_iface);
28int batadv_softif_is_valid(const struct net_device *net_dev); 29int batadv_softif_is_valid(const struct net_device *net_dev);
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index 99dd8f75b3f..112edd371b2 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -34,6 +34,10 @@ static void batadv_send_roam_adv(struct batadv_priv *bat_priv, uint8_t *client,
34static void batadv_tt_purge(struct work_struct *work); 34static void batadv_tt_purge(struct work_struct *work);
35static void 35static void
36batadv_tt_global_del_orig_list(struct batadv_tt_global_entry *tt_global_entry); 36batadv_tt_global_del_orig_list(struct batadv_tt_global_entry *tt_global_entry);
37static void batadv_tt_global_del(struct batadv_priv *bat_priv,
38 struct batadv_orig_node *orig_node,
39 const unsigned char *addr,
40 const char *message, bool roaming);
37 41
38/* returns 1 if they are the same mac addr */ 42/* returns 1 if they are the same mac addr */
39static int batadv_compare_tt(const struct hlist_node *node, const void *data2) 43static int batadv_compare_tt(const struct hlist_node *node, const void *data2)
@@ -46,8 +50,8 @@ static int batadv_compare_tt(const struct hlist_node *node, const void *data2)
46 50
47static void batadv_tt_start_timer(struct batadv_priv *bat_priv) 51static void batadv_tt_start_timer(struct batadv_priv *bat_priv)
48{ 52{
49 INIT_DELAYED_WORK(&bat_priv->tt_work, batadv_tt_purge); 53 INIT_DELAYED_WORK(&bat_priv->tt.work, batadv_tt_purge);
50 queue_delayed_work(batadv_event_workqueue, &bat_priv->tt_work, 54 queue_delayed_work(batadv_event_workqueue, &bat_priv->tt.work,
51 msecs_to_jiffies(5000)); 55 msecs_to_jiffies(5000));
52} 56}
53 57
@@ -88,7 +92,7 @@ batadv_tt_local_hash_find(struct batadv_priv *bat_priv, const void *data)
88 struct batadv_tt_common_entry *tt_common_entry; 92 struct batadv_tt_common_entry *tt_common_entry;
89 struct batadv_tt_local_entry *tt_local_entry = NULL; 93 struct batadv_tt_local_entry *tt_local_entry = NULL;
90 94
91 tt_common_entry = batadv_tt_hash_find(bat_priv->tt_local_hash, data); 95 tt_common_entry = batadv_tt_hash_find(bat_priv->tt.local_hash, data);
92 if (tt_common_entry) 96 if (tt_common_entry)
93 tt_local_entry = container_of(tt_common_entry, 97 tt_local_entry = container_of(tt_common_entry,
94 struct batadv_tt_local_entry, 98 struct batadv_tt_local_entry,
@@ -102,7 +106,7 @@ batadv_tt_global_hash_find(struct batadv_priv *bat_priv, const void *data)
102 struct batadv_tt_common_entry *tt_common_entry; 106 struct batadv_tt_common_entry *tt_common_entry;
103 struct batadv_tt_global_entry *tt_global_entry = NULL; 107 struct batadv_tt_global_entry *tt_global_entry = NULL;
104 108
105 tt_common_entry = batadv_tt_hash_find(bat_priv->tt_global_hash, data); 109 tt_common_entry = batadv_tt_hash_find(bat_priv->tt.global_hash, data);
106 if (tt_common_entry) 110 if (tt_common_entry)
107 tt_global_entry = container_of(tt_common_entry, 111 tt_global_entry = container_of(tt_common_entry,
108 struct batadv_tt_global_entry, 112 struct batadv_tt_global_entry,
@@ -152,6 +156,8 @@ static void batadv_tt_orig_list_entry_free_rcu(struct rcu_head *rcu)
152static void 156static void
153batadv_tt_orig_list_entry_free_ref(struct batadv_tt_orig_list_entry *orig_entry) 157batadv_tt_orig_list_entry_free_ref(struct batadv_tt_orig_list_entry *orig_entry)
154{ 158{
159 if (!atomic_dec_and_test(&orig_entry->refcount))
160 return;
155 /* to avoid race conditions, immediately decrease the tt counter */ 161 /* to avoid race conditions, immediately decrease the tt counter */
156 atomic_dec(&orig_entry->orig_node->tt_size); 162 atomic_dec(&orig_entry->orig_node->tt_size);
157 call_rcu(&orig_entry->rcu, batadv_tt_orig_list_entry_free_rcu); 163 call_rcu(&orig_entry->rcu, batadv_tt_orig_list_entry_free_rcu);
@@ -175,8 +181,8 @@ static void batadv_tt_local_event(struct batadv_priv *bat_priv,
175 del_op_requested = flags & BATADV_TT_CLIENT_DEL; 181 del_op_requested = flags & BATADV_TT_CLIENT_DEL;
176 182
177 /* check for ADD+DEL or DEL+ADD events */ 183 /* check for ADD+DEL or DEL+ADD events */
178 spin_lock_bh(&bat_priv->tt_changes_list_lock); 184 spin_lock_bh(&bat_priv->tt.changes_list_lock);
179 list_for_each_entry_safe(entry, safe, &bat_priv->tt_changes_list, 185 list_for_each_entry_safe(entry, safe, &bat_priv->tt.changes_list,
180 list) { 186 list) {
181 if (!batadv_compare_eth(entry->change.addr, addr)) 187 if (!batadv_compare_eth(entry->change.addr, addr))
182 continue; 188 continue;
@@ -203,15 +209,15 @@ del:
203 } 209 }
204 210
205 /* track the change in the OGMinterval list */ 211 /* track the change in the OGMinterval list */
206 list_add_tail(&tt_change_node->list, &bat_priv->tt_changes_list); 212 list_add_tail(&tt_change_node->list, &bat_priv->tt.changes_list);
207 213
208unlock: 214unlock:
209 spin_unlock_bh(&bat_priv->tt_changes_list_lock); 215 spin_unlock_bh(&bat_priv->tt.changes_list_lock);
210 216
211 if (event_removed) 217 if (event_removed)
212 atomic_dec(&bat_priv->tt_local_changes); 218 atomic_dec(&bat_priv->tt.local_changes);
213 else 219 else
214 atomic_inc(&bat_priv->tt_local_changes); 220 atomic_inc(&bat_priv->tt.local_changes);
215} 221}
216 222
217int batadv_tt_len(int changes_num) 223int batadv_tt_len(int changes_num)
@@ -221,12 +227,12 @@ int batadv_tt_len(int changes_num)
221 227
222static int batadv_tt_local_init(struct batadv_priv *bat_priv) 228static int batadv_tt_local_init(struct batadv_priv *bat_priv)
223{ 229{
224 if (bat_priv->tt_local_hash) 230 if (bat_priv->tt.local_hash)
225 return 0; 231 return 0;
226 232
227 bat_priv->tt_local_hash = batadv_hash_new(1024); 233 bat_priv->tt.local_hash = batadv_hash_new(1024);
228 234
229 if (!bat_priv->tt_local_hash) 235 if (!bat_priv->tt.local_hash)
230 return -ENOMEM; 236 return -ENOMEM;
231 237
232 return 0; 238 return 0;
@@ -258,7 +264,7 @@ void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
258 264
259 batadv_dbg(BATADV_DBG_TT, bat_priv, 265 batadv_dbg(BATADV_DBG_TT, bat_priv,
260 "Creating new local tt entry: %pM (ttvn: %d)\n", addr, 266 "Creating new local tt entry: %pM (ttvn: %d)\n", addr,
261 (uint8_t)atomic_read(&bat_priv->ttvn)); 267 (uint8_t)atomic_read(&bat_priv->tt.vn));
262 268
263 memcpy(tt_local_entry->common.addr, addr, ETH_ALEN); 269 memcpy(tt_local_entry->common.addr, addr, ETH_ALEN);
264 tt_local_entry->common.flags = BATADV_NO_FLAGS; 270 tt_local_entry->common.flags = BATADV_NO_FLAGS;
@@ -266,6 +272,7 @@ void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
266 tt_local_entry->common.flags |= BATADV_TT_CLIENT_WIFI; 272 tt_local_entry->common.flags |= BATADV_TT_CLIENT_WIFI;
267 atomic_set(&tt_local_entry->common.refcount, 2); 273 atomic_set(&tt_local_entry->common.refcount, 2);
268 tt_local_entry->last_seen = jiffies; 274 tt_local_entry->last_seen = jiffies;
275 tt_local_entry->common.added_at = tt_local_entry->last_seen;
269 276
270 /* the batman interface mac address should never be purged */ 277 /* the batman interface mac address should never be purged */
271 if (batadv_compare_eth(addr, soft_iface->dev_addr)) 278 if (batadv_compare_eth(addr, soft_iface->dev_addr))
@@ -277,7 +284,7 @@ void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
277 */ 284 */
278 tt_local_entry->common.flags |= BATADV_TT_CLIENT_NEW; 285 tt_local_entry->common.flags |= BATADV_TT_CLIENT_NEW;
279 286
280 hash_added = batadv_hash_add(bat_priv->tt_local_hash, batadv_compare_tt, 287 hash_added = batadv_hash_add(bat_priv->tt.local_hash, batadv_compare_tt,
281 batadv_choose_orig, 288 batadv_choose_orig,
282 &tt_local_entry->common, 289 &tt_local_entry->common,
283 &tt_local_entry->common.hash_entry); 290 &tt_local_entry->common.hash_entry);
@@ -348,7 +355,7 @@ static void batadv_tt_prepare_packet_buff(struct batadv_priv *bat_priv,
348 primary_if = batadv_primary_if_get_selected(bat_priv); 355 primary_if = batadv_primary_if_get_selected(bat_priv);
349 356
350 req_len = min_packet_len; 357 req_len = min_packet_len;
351 req_len += batadv_tt_len(atomic_read(&bat_priv->tt_local_changes)); 358 req_len += batadv_tt_len(atomic_read(&bat_priv->tt.local_changes));
352 359
353 /* if we have too many changes for one packet don't send any 360 /* if we have too many changes for one packet don't send any
354 * and wait for the tt table request which will be fragmented 361 * and wait for the tt table request which will be fragmented
@@ -381,10 +388,10 @@ static int batadv_tt_changes_fill_buff(struct batadv_priv *bat_priv,
381 if (new_len > 0) 388 if (new_len > 0)
382 tot_changes = new_len / batadv_tt_len(1); 389 tot_changes = new_len / batadv_tt_len(1);
383 390
384 spin_lock_bh(&bat_priv->tt_changes_list_lock); 391 spin_lock_bh(&bat_priv->tt.changes_list_lock);
385 atomic_set(&bat_priv->tt_local_changes, 0); 392 atomic_set(&bat_priv->tt.local_changes, 0);
386 393
387 list_for_each_entry_safe(entry, safe, &bat_priv->tt_changes_list, 394 list_for_each_entry_safe(entry, safe, &bat_priv->tt.changes_list,
388 list) { 395 list) {
389 if (count < tot_changes) { 396 if (count < tot_changes) {
390 memcpy(tt_buff + batadv_tt_len(count), 397 memcpy(tt_buff + batadv_tt_len(count),
@@ -394,25 +401,25 @@ static int batadv_tt_changes_fill_buff(struct batadv_priv *bat_priv,
394 list_del(&entry->list); 401 list_del(&entry->list);
395 kfree(entry); 402 kfree(entry);
396 } 403 }
397 spin_unlock_bh(&bat_priv->tt_changes_list_lock); 404 spin_unlock_bh(&bat_priv->tt.changes_list_lock);
398 405
399 /* Keep the buffer for possible tt_request */ 406 /* Keep the buffer for possible tt_request */
400 spin_lock_bh(&bat_priv->tt_buff_lock); 407 spin_lock_bh(&bat_priv->tt.last_changeset_lock);
401 kfree(bat_priv->tt_buff); 408 kfree(bat_priv->tt.last_changeset);
402 bat_priv->tt_buff_len = 0; 409 bat_priv->tt.last_changeset_len = 0;
403 bat_priv->tt_buff = NULL; 410 bat_priv->tt.last_changeset = NULL;
404 /* check whether this new OGM has no changes due to size problems */ 411 /* check whether this new OGM has no changes due to size problems */
405 if (new_len > 0) { 412 if (new_len > 0) {
406 /* if kmalloc() fails we will reply with the full table 413 /* if kmalloc() fails we will reply with the full table
407 * instead of providing the diff 414 * instead of providing the diff
408 */ 415 */
409 bat_priv->tt_buff = kmalloc(new_len, GFP_ATOMIC); 416 bat_priv->tt.last_changeset = kmalloc(new_len, GFP_ATOMIC);
410 if (bat_priv->tt_buff) { 417 if (bat_priv->tt.last_changeset) {
411 memcpy(bat_priv->tt_buff, tt_buff, new_len); 418 memcpy(bat_priv->tt.last_changeset, tt_buff, new_len);
412 bat_priv->tt_buff_len = new_len; 419 bat_priv->tt.last_changeset_len = new_len;
413 } 420 }
414 } 421 }
415 spin_unlock_bh(&bat_priv->tt_buff_lock); 422 spin_unlock_bh(&bat_priv->tt.last_changeset_lock);
416 423
417 return count; 424 return count;
418} 425}
@@ -421,7 +428,7 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset)
421{ 428{
422 struct net_device *net_dev = (struct net_device *)seq->private; 429 struct net_device *net_dev = (struct net_device *)seq->private;
423 struct batadv_priv *bat_priv = netdev_priv(net_dev); 430 struct batadv_priv *bat_priv = netdev_priv(net_dev);
424 struct batadv_hashtable *hash = bat_priv->tt_local_hash; 431 struct batadv_hashtable *hash = bat_priv->tt.local_hash;
425 struct batadv_tt_common_entry *tt_common_entry; 432 struct batadv_tt_common_entry *tt_common_entry;
426 struct batadv_hard_iface *primary_if; 433 struct batadv_hard_iface *primary_if;
427 struct hlist_node *node; 434 struct hlist_node *node;
@@ -446,7 +453,7 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset)
446 453
447 seq_printf(seq, 454 seq_printf(seq,
448 "Locally retrieved addresses (from %s) announced via TT (TTVN: %u):\n", 455 "Locally retrieved addresses (from %s) announced via TT (TTVN: %u):\n",
449 net_dev->name, (uint8_t)atomic_read(&bat_priv->ttvn)); 456 net_dev->name, (uint8_t)atomic_read(&bat_priv->tt.vn));
450 457
451 for (i = 0; i < hash->size; i++) { 458 for (i = 0; i < hash->size; i++) {
452 head = &hash->table[i]; 459 head = &hash->table[i];
@@ -544,7 +551,7 @@ static void batadv_tt_local_purge_list(struct batadv_priv *bat_priv,
544 551
545static void batadv_tt_local_purge(struct batadv_priv *bat_priv) 552static void batadv_tt_local_purge(struct batadv_priv *bat_priv)
546{ 553{
547 struct batadv_hashtable *hash = bat_priv->tt_local_hash; 554 struct batadv_hashtable *hash = bat_priv->tt.local_hash;
548 struct hlist_head *head; 555 struct hlist_head *head;
549 spinlock_t *list_lock; /* protects write access to the hash lists */ 556 spinlock_t *list_lock; /* protects write access to the hash lists */
550 uint32_t i; 557 uint32_t i;
@@ -570,10 +577,10 @@ static void batadv_tt_local_table_free(struct batadv_priv *bat_priv)
570 struct hlist_head *head; 577 struct hlist_head *head;
571 uint32_t i; 578 uint32_t i;
572 579
573 if (!bat_priv->tt_local_hash) 580 if (!bat_priv->tt.local_hash)
574 return; 581 return;
575 582
576 hash = bat_priv->tt_local_hash; 583 hash = bat_priv->tt.local_hash;
577 584
578 for (i = 0; i < hash->size; i++) { 585 for (i = 0; i < hash->size; i++) {
579 head = &hash->table[i]; 586 head = &hash->table[i];
@@ -593,17 +600,17 @@ static void batadv_tt_local_table_free(struct batadv_priv *bat_priv)
593 600
594 batadv_hash_destroy(hash); 601 batadv_hash_destroy(hash);
595 602
596 bat_priv->tt_local_hash = NULL; 603 bat_priv->tt.local_hash = NULL;
597} 604}
598 605
599static int batadv_tt_global_init(struct batadv_priv *bat_priv) 606static int batadv_tt_global_init(struct batadv_priv *bat_priv)
600{ 607{
601 if (bat_priv->tt_global_hash) 608 if (bat_priv->tt.global_hash)
602 return 0; 609 return 0;
603 610
604 bat_priv->tt_global_hash = batadv_hash_new(1024); 611 bat_priv->tt.global_hash = batadv_hash_new(1024);
605 612
606 if (!bat_priv->tt_global_hash) 613 if (!bat_priv->tt.global_hash)
607 return -ENOMEM; 614 return -ENOMEM;
608 615
609 return 0; 616 return 0;
@@ -613,62 +620,99 @@ static void batadv_tt_changes_list_free(struct batadv_priv *bat_priv)
613{ 620{
614 struct batadv_tt_change_node *entry, *safe; 621 struct batadv_tt_change_node *entry, *safe;
615 622
616 spin_lock_bh(&bat_priv->tt_changes_list_lock); 623 spin_lock_bh(&bat_priv->tt.changes_list_lock);
617 624
618 list_for_each_entry_safe(entry, safe, &bat_priv->tt_changes_list, 625 list_for_each_entry_safe(entry, safe, &bat_priv->tt.changes_list,
619 list) { 626 list) {
620 list_del(&entry->list); 627 list_del(&entry->list);
621 kfree(entry); 628 kfree(entry);
622 } 629 }
623 630
624 atomic_set(&bat_priv->tt_local_changes, 0); 631 atomic_set(&bat_priv->tt.local_changes, 0);
625 spin_unlock_bh(&bat_priv->tt_changes_list_lock); 632 spin_unlock_bh(&bat_priv->tt.changes_list_lock);
626} 633}
627 634
628/* find out if an orig_node is already in the list of a tt_global_entry. 635/* retrieves the orig_tt_list_entry belonging to orig_node from the
629 * returns 1 if found, 0 otherwise 636 * batadv_tt_global_entry list
637 *
638 * returns it with an increased refcounter, NULL if not found
630 */ 639 */
631static bool 640static struct batadv_tt_orig_list_entry *
632batadv_tt_global_entry_has_orig(const struct batadv_tt_global_entry *entry, 641batadv_tt_global_orig_entry_find(const struct batadv_tt_global_entry *entry,
633 const struct batadv_orig_node *orig_node) 642 const struct batadv_orig_node *orig_node)
634{ 643{
635 struct batadv_tt_orig_list_entry *tmp_orig_entry; 644 struct batadv_tt_orig_list_entry *tmp_orig_entry, *orig_entry = NULL;
636 const struct hlist_head *head; 645 const struct hlist_head *head;
637 struct hlist_node *node; 646 struct hlist_node *node;
638 bool found = false;
639 647
640 rcu_read_lock(); 648 rcu_read_lock();
641 head = &entry->orig_list; 649 head = &entry->orig_list;
642 hlist_for_each_entry_rcu(tmp_orig_entry, node, head, list) { 650 hlist_for_each_entry_rcu(tmp_orig_entry, node, head, list) {
643 if (tmp_orig_entry->orig_node == orig_node) { 651 if (tmp_orig_entry->orig_node != orig_node)
644 found = true; 652 continue;
645 break; 653 if (!atomic_inc_not_zero(&tmp_orig_entry->refcount))
646 } 654 continue;
655
656 orig_entry = tmp_orig_entry;
657 break;
647 } 658 }
648 rcu_read_unlock(); 659 rcu_read_unlock();
660
661 return orig_entry;
662}
663
664/* find out if an orig_node is already in the list of a tt_global_entry.
665 * returns true if found, false otherwise
666 */
667static bool
668batadv_tt_global_entry_has_orig(const struct batadv_tt_global_entry *entry,
669 const struct batadv_orig_node *orig_node)
670{
671 struct batadv_tt_orig_list_entry *orig_entry;
672 bool found = false;
673
674 orig_entry = batadv_tt_global_orig_entry_find(entry, orig_node);
675 if (orig_entry) {
676 found = true;
677 batadv_tt_orig_list_entry_free_ref(orig_entry);
678 }
679
649 return found; 680 return found;
650} 681}
651 682
652static void 683static void
653batadv_tt_global_add_orig_entry(struct batadv_tt_global_entry *tt_global_entry, 684batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry *tt_global,
654 struct batadv_orig_node *orig_node, int ttvn) 685 struct batadv_orig_node *orig_node, int ttvn)
655{ 686{
656 struct batadv_tt_orig_list_entry *orig_entry; 687 struct batadv_tt_orig_list_entry *orig_entry;
657 688
689 orig_entry = batadv_tt_global_orig_entry_find(tt_global, orig_node);
690 if (orig_entry) {
691 /* refresh the ttvn: the current value could be a bogus one that
692 * was added during a "temporary client detection"
693 */
694 orig_entry->ttvn = ttvn;
695 goto out;
696 }
697
658 orig_entry = kzalloc(sizeof(*orig_entry), GFP_ATOMIC); 698 orig_entry = kzalloc(sizeof(*orig_entry), GFP_ATOMIC);
659 if (!orig_entry) 699 if (!orig_entry)
660 return; 700 goto out;
661 701
662 INIT_HLIST_NODE(&orig_entry->list); 702 INIT_HLIST_NODE(&orig_entry->list);
663 atomic_inc(&orig_node->refcount); 703 atomic_inc(&orig_node->refcount);
664 atomic_inc(&orig_node->tt_size); 704 atomic_inc(&orig_node->tt_size);
665 orig_entry->orig_node = orig_node; 705 orig_entry->orig_node = orig_node;
666 orig_entry->ttvn = ttvn; 706 orig_entry->ttvn = ttvn;
707 atomic_set(&orig_entry->refcount, 2);
667 708
668 spin_lock_bh(&tt_global_entry->list_lock); 709 spin_lock_bh(&tt_global->list_lock);
669 hlist_add_head_rcu(&orig_entry->list, 710 hlist_add_head_rcu(&orig_entry->list,
670 &tt_global_entry->orig_list); 711 &tt_global->orig_list);
671 spin_unlock_bh(&tt_global_entry->list_lock); 712 spin_unlock_bh(&tt_global->list_lock);
713out:
714 if (orig_entry)
715 batadv_tt_orig_list_entry_free_ref(orig_entry);
672} 716}
673 717
674/* caller must hold orig_node refcount */ 718/* caller must hold orig_node refcount */
@@ -695,11 +739,12 @@ int batadv_tt_global_add(struct batadv_priv *bat_priv,
695 common->flags = flags; 739 common->flags = flags;
696 tt_global_entry->roam_at = 0; 740 tt_global_entry->roam_at = 0;
697 atomic_set(&common->refcount, 2); 741 atomic_set(&common->refcount, 2);
742 common->added_at = jiffies;
698 743
699 INIT_HLIST_HEAD(&tt_global_entry->orig_list); 744 INIT_HLIST_HEAD(&tt_global_entry->orig_list);
700 spin_lock_init(&tt_global_entry->list_lock); 745 spin_lock_init(&tt_global_entry->list_lock);
701 746
702 hash_added = batadv_hash_add(bat_priv->tt_global_hash, 747 hash_added = batadv_hash_add(bat_priv->tt.global_hash,
703 batadv_compare_tt, 748 batadv_compare_tt,
704 batadv_choose_orig, common, 749 batadv_choose_orig, common,
705 &common->hash_entry); 750 &common->hash_entry);
@@ -709,11 +754,20 @@ int batadv_tt_global_add(struct batadv_priv *bat_priv,
709 batadv_tt_global_entry_free_ref(tt_global_entry); 754 batadv_tt_global_entry_free_ref(tt_global_entry);
710 goto out_remove; 755 goto out_remove;
711 } 756 }
712
713 batadv_tt_global_add_orig_entry(tt_global_entry, orig_node,
714 ttvn);
715 } else { 757 } else {
716 /* there is already a global entry, use this one. */ 758 /* If there is already a global entry, we can use this one for
759 * our processing.
760 * But if we are trying to add a temporary client we can exit
761 * directly because the temporary information should never
762 * override any already known client state (whatever it is)
763 */
764 if (flags & BATADV_TT_CLIENT_TEMP)
765 goto out;
766
767 /* if the client was temporary added before receiving the first
768 * OGM announcing it, we have to clear the TEMP flag
769 */
770 tt_global_entry->common.flags &= ~BATADV_TT_CLIENT_TEMP;
717 771
718 /* If there is the BATADV_TT_CLIENT_ROAM flag set, there is only 772 /* If there is the BATADV_TT_CLIENT_ROAM flag set, there is only
719 * one originator left in the list and we previously received a 773 * one originator left in the list and we previously received a
@@ -727,12 +781,9 @@ int batadv_tt_global_add(struct batadv_priv *bat_priv,
727 tt_global_entry->common.flags &= ~BATADV_TT_CLIENT_ROAM; 781 tt_global_entry->common.flags &= ~BATADV_TT_CLIENT_ROAM;
728 tt_global_entry->roam_at = 0; 782 tt_global_entry->roam_at = 0;
729 } 783 }
730
731 if (!batadv_tt_global_entry_has_orig(tt_global_entry,
732 orig_node))
733 batadv_tt_global_add_orig_entry(tt_global_entry,
734 orig_node, ttvn);
735 } 784 }
785 /* add the new orig_entry (if needed) or update it */
786 batadv_tt_global_orig_entry_add(tt_global_entry, orig_node, ttvn);
736 787
737 batadv_dbg(BATADV_DBG_TT, bat_priv, 788 batadv_dbg(BATADV_DBG_TT, bat_priv,
738 "Creating new global tt entry: %pM (via %pM)\n", 789 "Creating new global tt entry: %pM (via %pM)\n",
@@ -771,11 +822,12 @@ batadv_tt_global_print_entry(struct batadv_tt_global_entry *tt_global_entry,
771 hlist_for_each_entry_rcu(orig_entry, node, head, list) { 822 hlist_for_each_entry_rcu(orig_entry, node, head, list) {
772 flags = tt_common_entry->flags; 823 flags = tt_common_entry->flags;
773 last_ttvn = atomic_read(&orig_entry->orig_node->last_ttvn); 824 last_ttvn = atomic_read(&orig_entry->orig_node->last_ttvn);
774 seq_printf(seq, " * %pM (%3u) via %pM (%3u) [%c%c]\n", 825 seq_printf(seq, " * %pM (%3u) via %pM (%3u) [%c%c%c]\n",
775 tt_global_entry->common.addr, orig_entry->ttvn, 826 tt_global_entry->common.addr, orig_entry->ttvn,
776 orig_entry->orig_node->orig, last_ttvn, 827 orig_entry->orig_node->orig, last_ttvn,
777 (flags & BATADV_TT_CLIENT_ROAM ? 'R' : '.'), 828 (flags & BATADV_TT_CLIENT_ROAM ? 'R' : '.'),
778 (flags & BATADV_TT_CLIENT_WIFI ? 'W' : '.')); 829 (flags & BATADV_TT_CLIENT_WIFI ? 'W' : '.'),
830 (flags & BATADV_TT_CLIENT_TEMP ? 'T' : '.'));
779 } 831 }
780} 832}
781 833
@@ -783,7 +835,7 @@ int batadv_tt_global_seq_print_text(struct seq_file *seq, void *offset)
783{ 835{
784 struct net_device *net_dev = (struct net_device *)seq->private; 836 struct net_device *net_dev = (struct net_device *)seq->private;
785 struct batadv_priv *bat_priv = netdev_priv(net_dev); 837 struct batadv_priv *bat_priv = netdev_priv(net_dev);
786 struct batadv_hashtable *hash = bat_priv->tt_global_hash; 838 struct batadv_hashtable *hash = bat_priv->tt.global_hash;
787 struct batadv_tt_common_entry *tt_common_entry; 839 struct batadv_tt_common_entry *tt_common_entry;
788 struct batadv_tt_global_entry *tt_global; 840 struct batadv_tt_global_entry *tt_global;
789 struct batadv_hard_iface *primary_if; 841 struct batadv_hard_iface *primary_if;
@@ -884,7 +936,7 @@ batadv_tt_global_del_struct(struct batadv_priv *bat_priv,
884 "Deleting global tt entry %pM: %s\n", 936 "Deleting global tt entry %pM: %s\n",
885 tt_global_entry->common.addr, message); 937 tt_global_entry->common.addr, message);
886 938
887 batadv_hash_remove(bat_priv->tt_global_hash, batadv_compare_tt, 939 batadv_hash_remove(bat_priv->tt.global_hash, batadv_compare_tt,
888 batadv_choose_orig, tt_global_entry->common.addr); 940 batadv_choose_orig, tt_global_entry->common.addr);
889 batadv_tt_global_entry_free_ref(tt_global_entry); 941 batadv_tt_global_entry_free_ref(tt_global_entry);
890 942
@@ -995,7 +1047,7 @@ void batadv_tt_global_del_orig(struct batadv_priv *bat_priv,
995 struct batadv_tt_global_entry *tt_global; 1047 struct batadv_tt_global_entry *tt_global;
996 struct batadv_tt_common_entry *tt_common_entry; 1048 struct batadv_tt_common_entry *tt_common_entry;
997 uint32_t i; 1049 uint32_t i;
998 struct batadv_hashtable *hash = bat_priv->tt_global_hash; 1050 struct batadv_hashtable *hash = bat_priv->tt.global_hash;
999 struct hlist_node *node, *safe; 1051 struct hlist_node *node, *safe;
1000 struct hlist_head *head; 1052 struct hlist_head *head;
1001 spinlock_t *list_lock; /* protects write access to the hash lists */ 1053 spinlock_t *list_lock; /* protects write access to the hash lists */
@@ -1030,49 +1082,63 @@ void batadv_tt_global_del_orig(struct batadv_priv *bat_priv,
1030 orig_node->tt_initialised = false; 1082 orig_node->tt_initialised = false;
1031} 1083}
1032 1084
1033static void batadv_tt_global_roam_purge_list(struct batadv_priv *bat_priv, 1085static bool batadv_tt_global_to_purge(struct batadv_tt_global_entry *tt_global,
1034 struct hlist_head *head) 1086 char **msg)
1035{ 1087{
1036 struct batadv_tt_common_entry *tt_common_entry; 1088 bool purge = false;
1037 struct batadv_tt_global_entry *tt_global_entry; 1089 unsigned long roam_timeout = BATADV_TT_CLIENT_ROAM_TIMEOUT;
1038 struct hlist_node *node, *node_tmp; 1090 unsigned long temp_timeout = BATADV_TT_CLIENT_TEMP_TIMEOUT;
1039
1040 hlist_for_each_entry_safe(tt_common_entry, node, node_tmp, head,
1041 hash_entry) {
1042 tt_global_entry = container_of(tt_common_entry,
1043 struct batadv_tt_global_entry,
1044 common);
1045 if (!(tt_global_entry->common.flags & BATADV_TT_CLIENT_ROAM))
1046 continue;
1047 if (!batadv_has_timed_out(tt_global_entry->roam_at,
1048 BATADV_TT_CLIENT_ROAM_TIMEOUT))
1049 continue;
1050 1091
1051 batadv_dbg(BATADV_DBG_TT, bat_priv, 1092 if ((tt_global->common.flags & BATADV_TT_CLIENT_ROAM) &&
1052 "Deleting global tt entry (%pM): Roaming timeout\n", 1093 batadv_has_timed_out(tt_global->roam_at, roam_timeout)) {
1053 tt_global_entry->common.addr); 1094 purge = true;
1095 *msg = "Roaming timeout\n";
1096 }
1054 1097
1055 hlist_del_rcu(node); 1098 if ((tt_global->common.flags & BATADV_TT_CLIENT_TEMP) &&
1056 batadv_tt_global_entry_free_ref(tt_global_entry); 1099 batadv_has_timed_out(tt_global->common.added_at, temp_timeout)) {
1100 purge = true;
1101 *msg = "Temporary client timeout\n";
1057 } 1102 }
1103
1104 return purge;
1058} 1105}
1059 1106
1060static void batadv_tt_global_roam_purge(struct batadv_priv *bat_priv) 1107static void batadv_tt_global_purge(struct batadv_priv *bat_priv)
1061{ 1108{
1062 struct batadv_hashtable *hash = bat_priv->tt_global_hash; 1109 struct batadv_hashtable *hash = bat_priv->tt.global_hash;
1063 struct hlist_head *head; 1110 struct hlist_head *head;
1111 struct hlist_node *node, *node_tmp;
1064 spinlock_t *list_lock; /* protects write access to the hash lists */ 1112 spinlock_t *list_lock; /* protects write access to the hash lists */
1065 uint32_t i; 1113 uint32_t i;
1114 char *msg = NULL;
1115 struct batadv_tt_common_entry *tt_common;
1116 struct batadv_tt_global_entry *tt_global;
1066 1117
1067 for (i = 0; i < hash->size; i++) { 1118 for (i = 0; i < hash->size; i++) {
1068 head = &hash->table[i]; 1119 head = &hash->table[i];
1069 list_lock = &hash->list_locks[i]; 1120 list_lock = &hash->list_locks[i];
1070 1121
1071 spin_lock_bh(list_lock); 1122 spin_lock_bh(list_lock);
1072 batadv_tt_global_roam_purge_list(bat_priv, head); 1123 hlist_for_each_entry_safe(tt_common, node, node_tmp, head,
1124 hash_entry) {
1125 tt_global = container_of(tt_common,
1126 struct batadv_tt_global_entry,
1127 common);
1128
1129 if (!batadv_tt_global_to_purge(tt_global, &msg))
1130 continue;
1131
1132 batadv_dbg(BATADV_DBG_TT, bat_priv,
1133 "Deleting global tt entry (%pM): %s\n",
1134 tt_global->common.addr, msg);
1135
1136 hlist_del_rcu(node);
1137
1138 batadv_tt_global_entry_free_ref(tt_global);
1139 }
1073 spin_unlock_bh(list_lock); 1140 spin_unlock_bh(list_lock);
1074 } 1141 }
1075
1076} 1142}
1077 1143
1078static void batadv_tt_global_table_free(struct batadv_priv *bat_priv) 1144static void batadv_tt_global_table_free(struct batadv_priv *bat_priv)
@@ -1085,10 +1151,10 @@ static void batadv_tt_global_table_free(struct batadv_priv *bat_priv)
1085 struct hlist_head *head; 1151 struct hlist_head *head;
1086 uint32_t i; 1152 uint32_t i;
1087 1153
1088 if (!bat_priv->tt_global_hash) 1154 if (!bat_priv->tt.global_hash)
1089 return; 1155 return;
1090 1156
1091 hash = bat_priv->tt_global_hash; 1157 hash = bat_priv->tt.global_hash;
1092 1158
1093 for (i = 0; i < hash->size; i++) { 1159 for (i = 0; i < hash->size; i++) {
1094 head = &hash->table[i]; 1160 head = &hash->table[i];
@@ -1108,7 +1174,7 @@ static void batadv_tt_global_table_free(struct batadv_priv *bat_priv)
1108 1174
1109 batadv_hash_destroy(hash); 1175 batadv_hash_destroy(hash);
1110 1176
1111 bat_priv->tt_global_hash = NULL; 1177 bat_priv->tt.global_hash = NULL;
1112} 1178}
1113 1179
1114static bool 1180static bool
@@ -1187,7 +1253,7 @@ static uint16_t batadv_tt_global_crc(struct batadv_priv *bat_priv,
1187 struct batadv_orig_node *orig_node) 1253 struct batadv_orig_node *orig_node)
1188{ 1254{
1189 uint16_t total = 0, total_one; 1255 uint16_t total = 0, total_one;
1190 struct batadv_hashtable *hash = bat_priv->tt_global_hash; 1256 struct batadv_hashtable *hash = bat_priv->tt.global_hash;
1191 struct batadv_tt_common_entry *tt_common; 1257 struct batadv_tt_common_entry *tt_common;
1192 struct batadv_tt_global_entry *tt_global; 1258 struct batadv_tt_global_entry *tt_global;
1193 struct hlist_node *node; 1259 struct hlist_node *node;
@@ -1210,6 +1276,12 @@ static uint16_t batadv_tt_global_crc(struct batadv_priv *bat_priv,
1210 */ 1276 */
1211 if (tt_common->flags & BATADV_TT_CLIENT_ROAM) 1277 if (tt_common->flags & BATADV_TT_CLIENT_ROAM)
1212 continue; 1278 continue;
1279 /* Temporary clients have not been announced yet, so
1280 * they have to be skipped while computing the global
1281 * crc
1282 */
1283 if (tt_common->flags & BATADV_TT_CLIENT_TEMP)
1284 continue;
1213 1285
1214 /* find out if this global entry is announced by this 1286 /* find out if this global entry is announced by this
1215 * originator 1287 * originator
@@ -1234,7 +1306,7 @@ static uint16_t batadv_tt_global_crc(struct batadv_priv *bat_priv,
1234static uint16_t batadv_tt_local_crc(struct batadv_priv *bat_priv) 1306static uint16_t batadv_tt_local_crc(struct batadv_priv *bat_priv)
1235{ 1307{
1236 uint16_t total = 0, total_one; 1308 uint16_t total = 0, total_one;
1237 struct batadv_hashtable *hash = bat_priv->tt_local_hash; 1309 struct batadv_hashtable *hash = bat_priv->tt.local_hash;
1238 struct batadv_tt_common_entry *tt_common; 1310 struct batadv_tt_common_entry *tt_common;
1239 struct hlist_node *node; 1311 struct hlist_node *node;
1240 struct hlist_head *head; 1312 struct hlist_head *head;
@@ -1267,14 +1339,14 @@ static void batadv_tt_req_list_free(struct batadv_priv *bat_priv)
1267{ 1339{
1268 struct batadv_tt_req_node *node, *safe; 1340 struct batadv_tt_req_node *node, *safe;
1269 1341
1270 spin_lock_bh(&bat_priv->tt_req_list_lock); 1342 spin_lock_bh(&bat_priv->tt.req_list_lock);
1271 1343
1272 list_for_each_entry_safe(node, safe, &bat_priv->tt_req_list, list) { 1344 list_for_each_entry_safe(node, safe, &bat_priv->tt.req_list, list) {
1273 list_del(&node->list); 1345 list_del(&node->list);
1274 kfree(node); 1346 kfree(node);
1275 } 1347 }
1276 1348
1277 spin_unlock_bh(&bat_priv->tt_req_list_lock); 1349 spin_unlock_bh(&bat_priv->tt.req_list_lock);
1278} 1350}
1279 1351
1280static void batadv_tt_save_orig_buffer(struct batadv_priv *bat_priv, 1352static void batadv_tt_save_orig_buffer(struct batadv_priv *bat_priv,
@@ -1304,15 +1376,15 @@ static void batadv_tt_req_purge(struct batadv_priv *bat_priv)
1304{ 1376{
1305 struct batadv_tt_req_node *node, *safe; 1377 struct batadv_tt_req_node *node, *safe;
1306 1378
1307 spin_lock_bh(&bat_priv->tt_req_list_lock); 1379 spin_lock_bh(&bat_priv->tt.req_list_lock);
1308 list_for_each_entry_safe(node, safe, &bat_priv->tt_req_list, list) { 1380 list_for_each_entry_safe(node, safe, &bat_priv->tt.req_list, list) {
1309 if (batadv_has_timed_out(node->issued_at, 1381 if (batadv_has_timed_out(node->issued_at,
1310 BATADV_TT_REQUEST_TIMEOUT)) { 1382 BATADV_TT_REQUEST_TIMEOUT)) {
1311 list_del(&node->list); 1383 list_del(&node->list);
1312 kfree(node); 1384 kfree(node);
1313 } 1385 }
1314 } 1386 }
1315 spin_unlock_bh(&bat_priv->tt_req_list_lock); 1387 spin_unlock_bh(&bat_priv->tt.req_list_lock);
1316} 1388}
1317 1389
1318/* returns the pointer to the new tt_req_node struct if no request 1390/* returns the pointer to the new tt_req_node struct if no request
@@ -1324,8 +1396,8 @@ batadv_new_tt_req_node(struct batadv_priv *bat_priv,
1324{ 1396{
1325 struct batadv_tt_req_node *tt_req_node_tmp, *tt_req_node = NULL; 1397 struct batadv_tt_req_node *tt_req_node_tmp, *tt_req_node = NULL;
1326 1398
1327 spin_lock_bh(&bat_priv->tt_req_list_lock); 1399 spin_lock_bh(&bat_priv->tt.req_list_lock);
1328 list_for_each_entry(tt_req_node_tmp, &bat_priv->tt_req_list, list) { 1400 list_for_each_entry(tt_req_node_tmp, &bat_priv->tt.req_list, list) {
1329 if (batadv_compare_eth(tt_req_node_tmp, orig_node) && 1401 if (batadv_compare_eth(tt_req_node_tmp, orig_node) &&
1330 !batadv_has_timed_out(tt_req_node_tmp->issued_at, 1402 !batadv_has_timed_out(tt_req_node_tmp->issued_at,
1331 BATADV_TT_REQUEST_TIMEOUT)) 1403 BATADV_TT_REQUEST_TIMEOUT))
@@ -1339,9 +1411,9 @@ batadv_new_tt_req_node(struct batadv_priv *bat_priv,
1339 memcpy(tt_req_node->addr, orig_node->orig, ETH_ALEN); 1411 memcpy(tt_req_node->addr, orig_node->orig, ETH_ALEN);
1340 tt_req_node->issued_at = jiffies; 1412 tt_req_node->issued_at = jiffies;
1341 1413
1342 list_add(&tt_req_node->list, &bat_priv->tt_req_list); 1414 list_add(&tt_req_node->list, &bat_priv->tt.req_list);
1343unlock: 1415unlock:
1344 spin_unlock_bh(&bat_priv->tt_req_list_lock); 1416 spin_unlock_bh(&bat_priv->tt.req_list_lock);
1345 return tt_req_node; 1417 return tt_req_node;
1346} 1418}
1347 1419
@@ -1363,7 +1435,8 @@ static int batadv_tt_global_valid(const void *entry_ptr,
1363 const struct batadv_tt_global_entry *tt_global_entry; 1435 const struct batadv_tt_global_entry *tt_global_entry;
1364 const struct batadv_orig_node *orig_node = data_ptr; 1436 const struct batadv_orig_node *orig_node = data_ptr;
1365 1437
1366 if (tt_common_entry->flags & BATADV_TT_CLIENT_ROAM) 1438 if (tt_common_entry->flags & BATADV_TT_CLIENT_ROAM ||
1439 tt_common_entry->flags & BATADV_TT_CLIENT_TEMP)
1367 return 0; 1440 return 0;
1368 1441
1369 tt_global_entry = container_of(tt_common_entry, 1442 tt_global_entry = container_of(tt_common_entry,
@@ -1507,9 +1580,9 @@ out:
1507 if (ret) 1580 if (ret)
1508 kfree_skb(skb); 1581 kfree_skb(skb);
1509 if (ret && tt_req_node) { 1582 if (ret && tt_req_node) {
1510 spin_lock_bh(&bat_priv->tt_req_list_lock); 1583 spin_lock_bh(&bat_priv->tt.req_list_lock);
1511 list_del(&tt_req_node->list); 1584 list_del(&tt_req_node->list);
1512 spin_unlock_bh(&bat_priv->tt_req_list_lock); 1585 spin_unlock_bh(&bat_priv->tt.req_list_lock);
1513 kfree(tt_req_node); 1586 kfree(tt_req_node);
1514 } 1587 }
1515 return ret; 1588 return ret;
@@ -1530,6 +1603,7 @@ batadv_send_other_tt_response(struct batadv_priv *bat_priv,
1530 uint16_t tt_len, tt_tot; 1603 uint16_t tt_len, tt_tot;
1531 struct sk_buff *skb = NULL; 1604 struct sk_buff *skb = NULL;
1532 struct batadv_tt_query_packet *tt_response; 1605 struct batadv_tt_query_packet *tt_response;
1606 uint8_t *packet_pos;
1533 size_t len; 1607 size_t len;
1534 1608
1535 batadv_dbg(BATADV_DBG_TT, bat_priv, 1609 batadv_dbg(BATADV_DBG_TT, bat_priv,
@@ -1583,8 +1657,8 @@ batadv_send_other_tt_response(struct batadv_priv *bat_priv,
1583 goto unlock; 1657 goto unlock;
1584 1658
1585 skb_reserve(skb, ETH_HLEN); 1659 skb_reserve(skb, ETH_HLEN);
1586 tt_response = (struct batadv_tt_query_packet *)skb_put(skb, 1660 packet_pos = skb_put(skb, len);
1587 len); 1661 tt_response = (struct batadv_tt_query_packet *)packet_pos;
1588 tt_response->ttvn = req_ttvn; 1662 tt_response->ttvn = req_ttvn;
1589 tt_response->tt_data = htons(tt_tot); 1663 tt_response->tt_data = htons(tt_tot);
1590 1664
@@ -1600,7 +1674,7 @@ batadv_send_other_tt_response(struct batadv_priv *bat_priv,
1600 ttvn = (uint8_t)atomic_read(&req_dst_orig_node->last_ttvn); 1674 ttvn = (uint8_t)atomic_read(&req_dst_orig_node->last_ttvn);
1601 1675
1602 skb = batadv_tt_response_fill_table(tt_len, ttvn, 1676 skb = batadv_tt_response_fill_table(tt_len, ttvn,
1603 bat_priv->tt_global_hash, 1677 bat_priv->tt.global_hash,
1604 primary_if, 1678 primary_if,
1605 batadv_tt_global_valid, 1679 batadv_tt_global_valid,
1606 req_dst_orig_node); 1680 req_dst_orig_node);
@@ -1663,6 +1737,7 @@ batadv_send_my_tt_response(struct batadv_priv *bat_priv,
1663 uint16_t tt_len, tt_tot; 1737 uint16_t tt_len, tt_tot;
1664 struct sk_buff *skb = NULL; 1738 struct sk_buff *skb = NULL;
1665 struct batadv_tt_query_packet *tt_response; 1739 struct batadv_tt_query_packet *tt_response;
1740 uint8_t *packet_pos;
1666 size_t len; 1741 size_t len;
1667 1742
1668 batadv_dbg(BATADV_DBG_TT, bat_priv, 1743 batadv_dbg(BATADV_DBG_TT, bat_priv,
@@ -1671,7 +1746,7 @@ batadv_send_my_tt_response(struct batadv_priv *bat_priv,
1671 (tt_request->flags & BATADV_TT_FULL_TABLE ? 'F' : '.')); 1746 (tt_request->flags & BATADV_TT_FULL_TABLE ? 'F' : '.'));
1672 1747
1673 1748
1674 my_ttvn = (uint8_t)atomic_read(&bat_priv->ttvn); 1749 my_ttvn = (uint8_t)atomic_read(&bat_priv->tt.vn);
1675 req_ttvn = tt_request->ttvn; 1750 req_ttvn = tt_request->ttvn;
1676 1751
1677 orig_node = batadv_orig_hash_find(bat_priv, tt_request->src); 1752 orig_node = batadv_orig_hash_find(bat_priv, tt_request->src);
@@ -1690,7 +1765,7 @@ batadv_send_my_tt_response(struct batadv_priv *bat_priv,
1690 * is too big send the whole local translation table 1765 * is too big send the whole local translation table
1691 */ 1766 */
1692 if (tt_request->flags & BATADV_TT_FULL_TABLE || my_ttvn != req_ttvn || 1767 if (tt_request->flags & BATADV_TT_FULL_TABLE || my_ttvn != req_ttvn ||
1693 !bat_priv->tt_buff) 1768 !bat_priv->tt.last_changeset)
1694 full_table = true; 1769 full_table = true;
1695 else 1770 else
1696 full_table = false; 1771 full_table = false;
@@ -1699,8 +1774,8 @@ batadv_send_my_tt_response(struct batadv_priv *bat_priv,
1699 * I'll send only one packet with as much TT entries as I can 1774 * I'll send only one packet with as much TT entries as I can
1700 */ 1775 */
1701 if (!full_table) { 1776 if (!full_table) {
1702 spin_lock_bh(&bat_priv->tt_buff_lock); 1777 spin_lock_bh(&bat_priv->tt.last_changeset_lock);
1703 tt_len = bat_priv->tt_buff_len; 1778 tt_len = bat_priv->tt.last_changeset_len;
1704 tt_tot = tt_len / sizeof(struct batadv_tt_change); 1779 tt_tot = tt_len / sizeof(struct batadv_tt_change);
1705 1780
1706 len = sizeof(*tt_response) + tt_len; 1781 len = sizeof(*tt_response) + tt_len;
@@ -1709,22 +1784,22 @@ batadv_send_my_tt_response(struct batadv_priv *bat_priv,
1709 goto unlock; 1784 goto unlock;
1710 1785
1711 skb_reserve(skb, ETH_HLEN); 1786 skb_reserve(skb, ETH_HLEN);
1712 tt_response = (struct batadv_tt_query_packet *)skb_put(skb, 1787 packet_pos = skb_put(skb, len);
1713 len); 1788 tt_response = (struct batadv_tt_query_packet *)packet_pos;
1714 tt_response->ttvn = req_ttvn; 1789 tt_response->ttvn = req_ttvn;
1715 tt_response->tt_data = htons(tt_tot); 1790 tt_response->tt_data = htons(tt_tot);
1716 1791
1717 tt_buff = skb->data + sizeof(*tt_response); 1792 tt_buff = skb->data + sizeof(*tt_response);
1718 memcpy(tt_buff, bat_priv->tt_buff, 1793 memcpy(tt_buff, bat_priv->tt.last_changeset,
1719 bat_priv->tt_buff_len); 1794 bat_priv->tt.last_changeset_len);
1720 spin_unlock_bh(&bat_priv->tt_buff_lock); 1795 spin_unlock_bh(&bat_priv->tt.last_changeset_lock);
1721 } else { 1796 } else {
1722 tt_len = (uint16_t)atomic_read(&bat_priv->num_local_tt); 1797 tt_len = (uint16_t)atomic_read(&bat_priv->tt.local_entry_num);
1723 tt_len *= sizeof(struct batadv_tt_change); 1798 tt_len *= sizeof(struct batadv_tt_change);
1724 ttvn = (uint8_t)atomic_read(&bat_priv->ttvn); 1799 ttvn = (uint8_t)atomic_read(&bat_priv->tt.vn);
1725 1800
1726 skb = batadv_tt_response_fill_table(tt_len, ttvn, 1801 skb = batadv_tt_response_fill_table(tt_len, ttvn,
1727 bat_priv->tt_local_hash, 1802 bat_priv->tt.local_hash,
1728 primary_if, 1803 primary_if,
1729 batadv_tt_local_valid_entry, 1804 batadv_tt_local_valid_entry,
1730 NULL); 1805 NULL);
@@ -1756,7 +1831,7 @@ batadv_send_my_tt_response(struct batadv_priv *bat_priv,
1756 goto out; 1831 goto out;
1757 1832
1758unlock: 1833unlock:
1759 spin_unlock_bh(&bat_priv->tt_buff_lock); 1834 spin_unlock_bh(&bat_priv->tt.last_changeset_lock);
1760out: 1835out:
1761 if (orig_node) 1836 if (orig_node)
1762 batadv_orig_node_free_ref(orig_node); 1837 batadv_orig_node_free_ref(orig_node);
@@ -1909,14 +1984,14 @@ void batadv_handle_tt_response(struct batadv_priv *bat_priv,
1909 } 1984 }
1910 1985
1911 /* Delete the tt_req_node from pending tt_requests list */ 1986 /* Delete the tt_req_node from pending tt_requests list */
1912 spin_lock_bh(&bat_priv->tt_req_list_lock); 1987 spin_lock_bh(&bat_priv->tt.req_list_lock);
1913 list_for_each_entry_safe(node, safe, &bat_priv->tt_req_list, list) { 1988 list_for_each_entry_safe(node, safe, &bat_priv->tt.req_list, list) {
1914 if (!batadv_compare_eth(node->addr, tt_response->src)) 1989 if (!batadv_compare_eth(node->addr, tt_response->src))
1915 continue; 1990 continue;
1916 list_del(&node->list); 1991 list_del(&node->list);
1917 kfree(node); 1992 kfree(node);
1918 } 1993 }
1919 spin_unlock_bh(&bat_priv->tt_req_list_lock); 1994 spin_unlock_bh(&bat_priv->tt.req_list_lock);
1920 1995
1921 /* Recalculate the CRC for this orig_node and store it */ 1996 /* Recalculate the CRC for this orig_node and store it */
1922 orig_node->tt_crc = batadv_tt_global_crc(bat_priv, orig_node); 1997 orig_node->tt_crc = batadv_tt_global_crc(bat_priv, orig_node);
@@ -1950,22 +2025,22 @@ static void batadv_tt_roam_list_free(struct batadv_priv *bat_priv)
1950{ 2025{
1951 struct batadv_tt_roam_node *node, *safe; 2026 struct batadv_tt_roam_node *node, *safe;
1952 2027
1953 spin_lock_bh(&bat_priv->tt_roam_list_lock); 2028 spin_lock_bh(&bat_priv->tt.roam_list_lock);
1954 2029
1955 list_for_each_entry_safe(node, safe, &bat_priv->tt_roam_list, list) { 2030 list_for_each_entry_safe(node, safe, &bat_priv->tt.roam_list, list) {
1956 list_del(&node->list); 2031 list_del(&node->list);
1957 kfree(node); 2032 kfree(node);
1958 } 2033 }
1959 2034
1960 spin_unlock_bh(&bat_priv->tt_roam_list_lock); 2035 spin_unlock_bh(&bat_priv->tt.roam_list_lock);
1961} 2036}
1962 2037
1963static void batadv_tt_roam_purge(struct batadv_priv *bat_priv) 2038static void batadv_tt_roam_purge(struct batadv_priv *bat_priv)
1964{ 2039{
1965 struct batadv_tt_roam_node *node, *safe; 2040 struct batadv_tt_roam_node *node, *safe;
1966 2041
1967 spin_lock_bh(&bat_priv->tt_roam_list_lock); 2042 spin_lock_bh(&bat_priv->tt.roam_list_lock);
1968 list_for_each_entry_safe(node, safe, &bat_priv->tt_roam_list, list) { 2043 list_for_each_entry_safe(node, safe, &bat_priv->tt.roam_list, list) {
1969 if (!batadv_has_timed_out(node->first_time, 2044 if (!batadv_has_timed_out(node->first_time,
1970 BATADV_ROAMING_MAX_TIME)) 2045 BATADV_ROAMING_MAX_TIME))
1971 continue; 2046 continue;
@@ -1973,7 +2048,7 @@ static void batadv_tt_roam_purge(struct batadv_priv *bat_priv)
1973 list_del(&node->list); 2048 list_del(&node->list);
1974 kfree(node); 2049 kfree(node);
1975 } 2050 }
1976 spin_unlock_bh(&bat_priv->tt_roam_list_lock); 2051 spin_unlock_bh(&bat_priv->tt.roam_list_lock);
1977} 2052}
1978 2053
1979/* This function checks whether the client already reached the 2054/* This function checks whether the client already reached the
@@ -1988,11 +2063,11 @@ static bool batadv_tt_check_roam_count(struct batadv_priv *bat_priv,
1988 struct batadv_tt_roam_node *tt_roam_node; 2063 struct batadv_tt_roam_node *tt_roam_node;
1989 bool ret = false; 2064 bool ret = false;
1990 2065
1991 spin_lock_bh(&bat_priv->tt_roam_list_lock); 2066 spin_lock_bh(&bat_priv->tt.roam_list_lock);
1992 /* The new tt_req will be issued only if I'm not waiting for a 2067 /* The new tt_req will be issued only if I'm not waiting for a
1993 * reply from the same orig_node yet 2068 * reply from the same orig_node yet
1994 */ 2069 */
1995 list_for_each_entry(tt_roam_node, &bat_priv->tt_roam_list, list) { 2070 list_for_each_entry(tt_roam_node, &bat_priv->tt.roam_list, list) {
1996 if (!batadv_compare_eth(tt_roam_node->addr, client)) 2071 if (!batadv_compare_eth(tt_roam_node->addr, client))
1997 continue; 2072 continue;
1998 2073
@@ -2017,12 +2092,12 @@ static bool batadv_tt_check_roam_count(struct batadv_priv *bat_priv,
2017 BATADV_ROAMING_MAX_COUNT - 1); 2092 BATADV_ROAMING_MAX_COUNT - 1);
2018 memcpy(tt_roam_node->addr, client, ETH_ALEN); 2093 memcpy(tt_roam_node->addr, client, ETH_ALEN);
2019 2094
2020 list_add(&tt_roam_node->list, &bat_priv->tt_roam_list); 2095 list_add(&tt_roam_node->list, &bat_priv->tt.roam_list);
2021 ret = true; 2096 ret = true;
2022 } 2097 }
2023 2098
2024unlock: 2099unlock:
2025 spin_unlock_bh(&bat_priv->tt_roam_list_lock); 2100 spin_unlock_bh(&bat_priv->tt.roam_list_lock);
2026 return ret; 2101 return ret;
2027} 2102}
2028 2103
@@ -2086,13 +2161,15 @@ out:
2086static void batadv_tt_purge(struct work_struct *work) 2161static void batadv_tt_purge(struct work_struct *work)
2087{ 2162{
2088 struct delayed_work *delayed_work; 2163 struct delayed_work *delayed_work;
2164 struct batadv_priv_tt *priv_tt;
2089 struct batadv_priv *bat_priv; 2165 struct batadv_priv *bat_priv;
2090 2166
2091 delayed_work = container_of(work, struct delayed_work, work); 2167 delayed_work = container_of(work, struct delayed_work, work);
2092 bat_priv = container_of(delayed_work, struct batadv_priv, tt_work); 2168 priv_tt = container_of(delayed_work, struct batadv_priv_tt, work);
2169 bat_priv = container_of(priv_tt, struct batadv_priv, tt);
2093 2170
2094 batadv_tt_local_purge(bat_priv); 2171 batadv_tt_local_purge(bat_priv);
2095 batadv_tt_global_roam_purge(bat_priv); 2172 batadv_tt_global_purge(bat_priv);
2096 batadv_tt_req_purge(bat_priv); 2173 batadv_tt_req_purge(bat_priv);
2097 batadv_tt_roam_purge(bat_priv); 2174 batadv_tt_roam_purge(bat_priv);
2098 2175
@@ -2101,7 +2178,7 @@ static void batadv_tt_purge(struct work_struct *work)
2101 2178
2102void batadv_tt_free(struct batadv_priv *bat_priv) 2179void batadv_tt_free(struct batadv_priv *bat_priv)
2103{ 2180{
2104 cancel_delayed_work_sync(&bat_priv->tt_work); 2181 cancel_delayed_work_sync(&bat_priv->tt.work);
2105 2182
2106 batadv_tt_local_table_free(bat_priv); 2183 batadv_tt_local_table_free(bat_priv);
2107 batadv_tt_global_table_free(bat_priv); 2184 batadv_tt_global_table_free(bat_priv);
@@ -2109,7 +2186,7 @@ void batadv_tt_free(struct batadv_priv *bat_priv)
2109 batadv_tt_changes_list_free(bat_priv); 2186 batadv_tt_changes_list_free(bat_priv);
2110 batadv_tt_roam_list_free(bat_priv); 2187 batadv_tt_roam_list_free(bat_priv);
2111 2188
2112 kfree(bat_priv->tt_buff); 2189 kfree(bat_priv->tt.last_changeset);
2113} 2190}
2114 2191
2115/* This function will enable or disable the specified flags for all the entries 2192/* This function will enable or disable the specified flags for all the entries
@@ -2153,7 +2230,7 @@ out:
2153/* Purge out all the tt local entries marked with BATADV_TT_CLIENT_PENDING */ 2230/* Purge out all the tt local entries marked with BATADV_TT_CLIENT_PENDING */
2154static void batadv_tt_local_purge_pending_clients(struct batadv_priv *bat_priv) 2231static void batadv_tt_local_purge_pending_clients(struct batadv_priv *bat_priv)
2155{ 2232{
2156 struct batadv_hashtable *hash = bat_priv->tt_local_hash; 2233 struct batadv_hashtable *hash = bat_priv->tt.local_hash;
2157 struct batadv_tt_common_entry *tt_common; 2234 struct batadv_tt_common_entry *tt_common;
2158 struct batadv_tt_local_entry *tt_local; 2235 struct batadv_tt_local_entry *tt_local;
2159 struct hlist_node *node, *node_tmp; 2236 struct hlist_node *node, *node_tmp;
@@ -2178,7 +2255,7 @@ static void batadv_tt_local_purge_pending_clients(struct batadv_priv *bat_priv)
2178 "Deleting local tt entry (%pM): pending\n", 2255 "Deleting local tt entry (%pM): pending\n",
2179 tt_common->addr); 2256 tt_common->addr);
2180 2257
2181 atomic_dec(&bat_priv->num_local_tt); 2258 atomic_dec(&bat_priv->tt.local_entry_num);
2182 hlist_del_rcu(node); 2259 hlist_del_rcu(node);
2183 tt_local = container_of(tt_common, 2260 tt_local = container_of(tt_common,
2184 struct batadv_tt_local_entry, 2261 struct batadv_tt_local_entry,
@@ -2196,26 +2273,26 @@ static int batadv_tt_commit_changes(struct batadv_priv *bat_priv,
2196{ 2273{
2197 uint16_t changed_num = 0; 2274 uint16_t changed_num = 0;
2198 2275
2199 if (atomic_read(&bat_priv->tt_local_changes) < 1) 2276 if (atomic_read(&bat_priv->tt.local_changes) < 1)
2200 return -ENOENT; 2277 return -ENOENT;
2201 2278
2202 changed_num = batadv_tt_set_flags(bat_priv->tt_local_hash, 2279 changed_num = batadv_tt_set_flags(bat_priv->tt.local_hash,
2203 BATADV_TT_CLIENT_NEW, false); 2280 BATADV_TT_CLIENT_NEW, false);
2204 2281
2205 /* all reset entries have to be counted as local entries */ 2282 /* all reset entries have to be counted as local entries */
2206 atomic_add(changed_num, &bat_priv->num_local_tt); 2283 atomic_add(changed_num, &bat_priv->tt.local_entry_num);
2207 batadv_tt_local_purge_pending_clients(bat_priv); 2284 batadv_tt_local_purge_pending_clients(bat_priv);
2208 bat_priv->tt_crc = batadv_tt_local_crc(bat_priv); 2285 bat_priv->tt.local_crc = batadv_tt_local_crc(bat_priv);
2209 2286
2210 /* Increment the TTVN only once per OGM interval */ 2287 /* Increment the TTVN only once per OGM interval */
2211 atomic_inc(&bat_priv->ttvn); 2288 atomic_inc(&bat_priv->tt.vn);
2212 batadv_dbg(BATADV_DBG_TT, bat_priv, 2289 batadv_dbg(BATADV_DBG_TT, bat_priv,
2213 "Local changes committed, updating to ttvn %u\n", 2290 "Local changes committed, updating to ttvn %u\n",
2214 (uint8_t)atomic_read(&bat_priv->ttvn)); 2291 (uint8_t)atomic_read(&bat_priv->tt.vn));
2215 bat_priv->tt_poss_change = false; 2292 bat_priv->tt.poss_change = false;
2216 2293
2217 /* reset the sending counter */ 2294 /* reset the sending counter */
2218 atomic_set(&bat_priv->tt_ogm_append_cnt, BATADV_TT_OGM_APPEND_MAX); 2295 atomic_set(&bat_priv->tt.ogm_append_cnt, BATADV_TT_OGM_APPEND_MAX);
2219 2296
2220 return batadv_tt_changes_fill_buff(bat_priv, packet_buff, 2297 return batadv_tt_changes_fill_buff(bat_priv, packet_buff,
2221 packet_buff_len, packet_min_len); 2298 packet_buff_len, packet_min_len);
@@ -2235,7 +2312,7 @@ int batadv_tt_append_diff(struct batadv_priv *bat_priv,
2235 2312
2236 /* if the changes have been sent often enough */ 2313 /* if the changes have been sent often enough */
2237 if ((tt_num_changes < 0) && 2314 if ((tt_num_changes < 0) &&
2238 (!batadv_atomic_dec_not_zero(&bat_priv->tt_ogm_append_cnt))) { 2315 (!batadv_atomic_dec_not_zero(&bat_priv->tt.ogm_append_cnt))) {
2239 batadv_tt_realloc_packet_buff(packet_buff, packet_buff_len, 2316 batadv_tt_realloc_packet_buff(packet_buff, packet_buff_len,
2240 packet_min_len, packet_min_len); 2317 packet_min_len, packet_min_len);
2241 tt_num_changes = 0; 2318 tt_num_changes = 0;
@@ -2366,3 +2443,22 @@ bool batadv_tt_global_client_is_roaming(struct batadv_priv *bat_priv,
2366out: 2443out:
2367 return ret; 2444 return ret;
2368} 2445}
2446
2447bool batadv_tt_add_temporary_global_entry(struct batadv_priv *bat_priv,
2448 struct batadv_orig_node *orig_node,
2449 const unsigned char *addr)
2450{
2451 bool ret = false;
2452
2453 if (!batadv_tt_global_add(bat_priv, orig_node, addr,
2454 BATADV_TT_CLIENT_TEMP,
2455 atomic_read(&orig_node->last_ttvn)))
2456 goto out;
2457
2458 batadv_dbg(BATADV_DBG_TT, bat_priv,
2459 "Added temporary global client (addr: %pM orig: %pM)\n",
2460 addr, orig_node->orig);
2461 ret = true;
2462out:
2463 return ret;
2464}
diff --git a/net/batman-adv/translation-table.h b/net/batman-adv/translation-table.h
index ffa87355096..811fffd4760 100644
--- a/net/batman-adv/translation-table.h
+++ b/net/batman-adv/translation-table.h
@@ -59,6 +59,8 @@ int batadv_tt_append_diff(struct batadv_priv *bat_priv,
59 int packet_min_len); 59 int packet_min_len);
60bool batadv_tt_global_client_is_roaming(struct batadv_priv *bat_priv, 60bool batadv_tt_global_client_is_roaming(struct batadv_priv *bat_priv,
61 uint8_t *addr); 61 uint8_t *addr);
62 62bool batadv_tt_add_temporary_global_entry(struct batadv_priv *bat_priv,
63 struct batadv_orig_node *orig_node,
64 const unsigned char *addr);
63 65
64#endif /* _NET_BATMAN_ADV_TRANSLATION_TABLE_H_ */ 66#endif /* _NET_BATMAN_ADV_TRANSLATION_TABLE_H_ */
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index 12635fd2c3d..2ed82caacdc 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -145,6 +145,11 @@ struct batadv_bcast_duplist_entry {
145#endif 145#endif
146 146
147enum batadv_counters { 147enum batadv_counters {
148 BATADV_CNT_TX,
149 BATADV_CNT_TX_BYTES,
150 BATADV_CNT_TX_DROPPED,
151 BATADV_CNT_RX,
152 BATADV_CNT_RX_BYTES,
148 BATADV_CNT_FORWARD, 153 BATADV_CNT_FORWARD,
149 BATADV_CNT_FORWARD_BYTES, 154 BATADV_CNT_FORWARD_BYTES,
150 BATADV_CNT_MGMT_TX, 155 BATADV_CNT_MGMT_TX,
@@ -160,6 +165,67 @@ enum batadv_counters {
160 BATADV_CNT_NUM, 165 BATADV_CNT_NUM,
161}; 166};
162 167
168/**
169 * struct batadv_priv_tt - per mesh interface translation table data
170 * @vn: translation table version number
171 * @local_changes: changes registered in an originator interval
172 * @poss_change: Detect an ongoing roaming phase. If true, then this node
173 * received a roaming_adv and has to inspect every packet directed to it to
174 * check whether it still is the true destination or not. This flag will be
175 * reset to false as soon as the this node's ttvn is increased
176 * @changes_list: tracks tt local changes within an originator interval
177 * @req_list: list of pending tt_requests
178 * @local_crc: Checksum of the local table, recomputed before sending a new OGM
179 */
180struct batadv_priv_tt {
181 atomic_t vn;
182 atomic_t ogm_append_cnt;
183 atomic_t local_changes;
184 bool poss_change;
185 struct list_head changes_list;
186 struct batadv_hashtable *local_hash;
187 struct batadv_hashtable *global_hash;
188 struct list_head req_list;
189 struct list_head roam_list;
190 spinlock_t changes_list_lock; /* protects changes */
191 spinlock_t req_list_lock; /* protects req_list */
192 spinlock_t roam_list_lock; /* protects roam_list */
193 atomic_t local_entry_num;
194 uint16_t local_crc;
195 unsigned char *last_changeset;
196 int16_t last_changeset_len;
197 spinlock_t last_changeset_lock; /* protects last_changeset */
198 struct delayed_work work;
199};
200
201#ifdef CONFIG_BATMAN_ADV_BLA
202struct batadv_priv_bla {
203 atomic_t num_requests; /* number of bla requests in flight */
204 struct batadv_hashtable *claim_hash;
205 struct batadv_hashtable *backbone_hash;
206 struct batadv_bcast_duplist_entry bcast_duplist[BATADV_DUPLIST_SIZE];
207 int bcast_duplist_curr;
208 struct batadv_bla_claim_dst claim_dest;
209 struct delayed_work work;
210};
211#endif
212
213struct batadv_priv_gw {
214 struct hlist_head list;
215 spinlock_t list_lock; /* protects gw_list and curr_gw */
216 struct batadv_gw_node __rcu *curr_gw; /* rcu protected pointer */
217 atomic_t reselect;
218};
219
220struct batadv_priv_vis {
221 struct list_head send_list;
222 struct batadv_hashtable *hash;
223 spinlock_t hash_lock; /* protects hash */
224 spinlock_t list_lock; /* protects info::recv_list */
225 struct delayed_work work;
226 struct batadv_vis_info *my_info;
227};
228
163struct batadv_priv { 229struct batadv_priv {
164 atomic_t mesh_state; 230 atomic_t mesh_state;
165 struct net_device_stats stats; 231 struct net_device_stats stats;
@@ -179,64 +245,24 @@ struct batadv_priv {
179 atomic_t bcast_seqno; 245 atomic_t bcast_seqno;
180 atomic_t bcast_queue_left; 246 atomic_t bcast_queue_left;
181 atomic_t batman_queue_left; 247 atomic_t batman_queue_left;
182 atomic_t ttvn; /* translation table version number */
183 atomic_t tt_ogm_append_cnt;
184 atomic_t tt_local_changes; /* changes registered in a OGM interval */
185 atomic_t bla_num_requests; /* number of bla requests in flight */
186 /* The tt_poss_change flag is used to detect an ongoing roaming phase.
187 * If true, then I received a Roaming_adv and I have to inspect every
188 * packet directed to me to check whether I am still the true
189 * destination or not. This flag will be reset to false as soon as I
190 * increase my TTVN
191 */
192 bool tt_poss_change;
193 char num_ifaces; 248 char num_ifaces;
194 struct batadv_debug_log *debug_log; 249 struct batadv_debug_log *debug_log;
195 struct kobject *mesh_obj; 250 struct kobject *mesh_obj;
196 struct dentry *debug_dir; 251 struct dentry *debug_dir;
197 struct hlist_head forw_bat_list; 252 struct hlist_head forw_bat_list;
198 struct hlist_head forw_bcast_list; 253 struct hlist_head forw_bcast_list;
199 struct hlist_head gw_list;
200 struct list_head tt_changes_list; /* tracks changes in a OGM int */
201 struct list_head vis_send_list;
202 struct batadv_hashtable *orig_hash; 254 struct batadv_hashtable *orig_hash;
203 struct batadv_hashtable *tt_local_hash;
204 struct batadv_hashtable *tt_global_hash;
205#ifdef CONFIG_BATMAN_ADV_BLA
206 struct batadv_hashtable *claim_hash;
207 struct batadv_hashtable *backbone_hash;
208#endif
209 struct list_head tt_req_list; /* list of pending tt_requests */
210 struct list_head tt_roam_list;
211 struct batadv_hashtable *vis_hash;
212#ifdef CONFIG_BATMAN_ADV_BLA
213 struct batadv_bcast_duplist_entry bcast_duplist[BATADV_DUPLIST_SIZE];
214 int bcast_duplist_curr;
215 struct batadv_bla_claim_dst claim_dest;
216#endif
217 spinlock_t forw_bat_list_lock; /* protects forw_bat_list */ 255 spinlock_t forw_bat_list_lock; /* protects forw_bat_list */
218 spinlock_t forw_bcast_list_lock; /* protects */ 256 spinlock_t forw_bcast_list_lock; /* protects */
219 spinlock_t tt_changes_list_lock; /* protects tt_changes */
220 spinlock_t tt_req_list_lock; /* protects tt_req_list */
221 spinlock_t tt_roam_list_lock; /* protects tt_roam_list */
222 spinlock_t gw_list_lock; /* protects gw_list and curr_gw */
223 spinlock_t vis_hash_lock; /* protects vis_hash */
224 spinlock_t vis_list_lock; /* protects vis_info::recv_list */
225 atomic_t num_local_tt;
226 /* Checksum of the local table, recomputed before sending a new OGM */
227 uint16_t tt_crc;
228 unsigned char *tt_buff;
229 int16_t tt_buff_len;
230 spinlock_t tt_buff_lock; /* protects tt_buff */
231 struct delayed_work tt_work;
232 struct delayed_work orig_work; 257 struct delayed_work orig_work;
233 struct delayed_work vis_work;
234 struct delayed_work bla_work;
235 struct batadv_gw_node __rcu *curr_gw; /* rcu protected pointer */
236 atomic_t gw_reselect;
237 struct batadv_hard_iface __rcu *primary_if; /* rcu protected pointer */ 258 struct batadv_hard_iface __rcu *primary_if; /* rcu protected pointer */
238 struct batadv_vis_info *my_vis_info;
239 struct batadv_algo_ops *bat_algo_ops; 259 struct batadv_algo_ops *bat_algo_ops;
260#ifdef CONFIG_BATMAN_ADV_BLA
261 struct batadv_priv_bla bla;
262#endif
263 struct batadv_priv_gw gw;
264 struct batadv_priv_tt tt;
265 struct batadv_priv_vis vis;
240}; 266};
241 267
242struct batadv_socket_client { 268struct batadv_socket_client {
@@ -258,6 +284,7 @@ struct batadv_tt_common_entry {
258 uint8_t addr[ETH_ALEN]; 284 uint8_t addr[ETH_ALEN];
259 struct hlist_node hash_entry; 285 struct hlist_node hash_entry;
260 uint16_t flags; 286 uint16_t flags;
287 unsigned long added_at;
261 atomic_t refcount; 288 atomic_t refcount;
262 struct rcu_head rcu; 289 struct rcu_head rcu;
263}; 290};
@@ -277,6 +304,7 @@ struct batadv_tt_global_entry {
277struct batadv_tt_orig_list_entry { 304struct batadv_tt_orig_list_entry {
278 struct batadv_orig_node *orig_node; 305 struct batadv_orig_node *orig_node;
279 uint8_t ttvn; 306 uint8_t ttvn;
307 atomic_t refcount;
280 struct rcu_head rcu; 308 struct rcu_head rcu;
281 struct hlist_node list; 309 struct hlist_node list;
282}; 310};
diff --git a/net/batman-adv/unicast.c b/net/batman-adv/unicast.c
index 00164645b3f..f39723281ca 100644
--- a/net/batman-adv/unicast.c
+++ b/net/batman-adv/unicast.c
@@ -39,6 +39,7 @@ batadv_frag_merge_packet(struct list_head *head,
39 struct batadv_unicast_packet *unicast_packet; 39 struct batadv_unicast_packet *unicast_packet;
40 int hdr_len = sizeof(*unicast_packet); 40 int hdr_len = sizeof(*unicast_packet);
41 int uni_diff = sizeof(*up) - hdr_len; 41 int uni_diff = sizeof(*up) - hdr_len;
42 uint8_t *packet_pos;
42 43
43 up = (struct batadv_unicast_frag_packet *)skb->data; 44 up = (struct batadv_unicast_frag_packet *)skb->data;
44 /* set skb to the first part and tmp_skb to the second part */ 45 /* set skb to the first part and tmp_skb to the second part */
@@ -65,8 +66,8 @@ batadv_frag_merge_packet(struct list_head *head,
65 kfree_skb(tmp_skb); 66 kfree_skb(tmp_skb);
66 67
67 memmove(skb->data + uni_diff, skb->data, hdr_len); 68 memmove(skb->data + uni_diff, skb->data, hdr_len);
68 unicast_packet = (struct batadv_unicast_packet *)skb_pull(skb, 69 packet_pos = skb_pull(skb, uni_diff);
69 uni_diff); 70 unicast_packet = (struct batadv_unicast_packet *)packet_pos;
70 unicast_packet->header.packet_type = BATADV_UNICAST; 71 unicast_packet->header.packet_type = BATADV_UNICAST;
71 72
72 return skb; 73 return skb;
@@ -121,6 +122,7 @@ batadv_frag_search_packet(struct list_head *head,
121{ 122{
122 struct batadv_frag_packet_list_entry *tfp; 123 struct batadv_frag_packet_list_entry *tfp;
123 struct batadv_unicast_frag_packet *tmp_up = NULL; 124 struct batadv_unicast_frag_packet *tmp_up = NULL;
125 int is_head_tmp, is_head;
124 uint16_t search_seqno; 126 uint16_t search_seqno;
125 127
126 if (up->flags & BATADV_UNI_FRAG_HEAD) 128 if (up->flags & BATADV_UNI_FRAG_HEAD)
@@ -128,6 +130,8 @@ batadv_frag_search_packet(struct list_head *head,
128 else 130 else
129 search_seqno = ntohs(up->seqno)-1; 131 search_seqno = ntohs(up->seqno)-1;
130 132
133 is_head = !!(up->flags & BATADV_UNI_FRAG_HEAD);
134
131 list_for_each_entry(tfp, head, list) { 135 list_for_each_entry(tfp, head, list) {
132 136
133 if (!tfp->skb) 137 if (!tfp->skb)
@@ -139,9 +143,8 @@ batadv_frag_search_packet(struct list_head *head,
139 tmp_up = (struct batadv_unicast_frag_packet *)tfp->skb->data; 143 tmp_up = (struct batadv_unicast_frag_packet *)tfp->skb->data;
140 144
141 if (tfp->seqno == search_seqno) { 145 if (tfp->seqno == search_seqno) {
142 146 is_head_tmp = !!(tmp_up->flags & BATADV_UNI_FRAG_HEAD);
143 if ((tmp_up->flags & BATADV_UNI_FRAG_HEAD) != 147 if (is_head_tmp != is_head)
144 (up->flags & BATADV_UNI_FRAG_HEAD))
145 return tfp; 148 return tfp;
146 else 149 else
147 goto mov_tail; 150 goto mov_tail;
@@ -334,8 +337,7 @@ find_router:
334 /* copy the destination for faster routing */ 337 /* copy the destination for faster routing */
335 memcpy(unicast_packet->dest, orig_node->orig, ETH_ALEN); 338 memcpy(unicast_packet->dest, orig_node->orig, ETH_ALEN);
336 /* set the destination tt version number */ 339 /* set the destination tt version number */
337 unicast_packet->ttvn = 340 unicast_packet->ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn);
338 (uint8_t)atomic_read(&orig_node->last_ttvn);
339 341
340 /* inform the destination node that we are still missing a correct route 342 /* inform the destination node that we are still missing a correct route
341 * for this client. The destination will receive this packet and will 343 * for this client. The destination will receive this packet and will
diff --git a/net/batman-adv/vis.c b/net/batman-adv/vis.c
index 2a2ea068146..5abd1454fb0 100644
--- a/net/batman-adv/vis.c
+++ b/net/batman-adv/vis.c
@@ -41,13 +41,13 @@ static void batadv_free_info(struct kref *ref)
41 bat_priv = info->bat_priv; 41 bat_priv = info->bat_priv;
42 42
43 list_del_init(&info->send_list); 43 list_del_init(&info->send_list);
44 spin_lock_bh(&bat_priv->vis_list_lock); 44 spin_lock_bh(&bat_priv->vis.list_lock);
45 list_for_each_entry_safe(entry, tmp, &info->recv_list, list) { 45 list_for_each_entry_safe(entry, tmp, &info->recv_list, list) {
46 list_del(&entry->list); 46 list_del(&entry->list);
47 kfree(entry); 47 kfree(entry);
48 } 48 }
49 49
50 spin_unlock_bh(&bat_priv->vis_list_lock); 50 spin_unlock_bh(&bat_priv->vis.list_lock);
51 kfree_skb(info->skb_packet); 51 kfree_skb(info->skb_packet);
52 kfree(info); 52 kfree(info);
53} 53}
@@ -94,7 +94,7 @@ static uint32_t batadv_vis_info_choose(const void *data, uint32_t size)
94static struct batadv_vis_info * 94static struct batadv_vis_info *
95batadv_vis_hash_find(struct batadv_priv *bat_priv, const void *data) 95batadv_vis_hash_find(struct batadv_priv *bat_priv, const void *data)
96{ 96{
97 struct batadv_hashtable *hash = bat_priv->vis_hash; 97 struct batadv_hashtable *hash = bat_priv->vis.hash;
98 struct hlist_head *head; 98 struct hlist_head *head;
99 struct hlist_node *node; 99 struct hlist_node *node;
100 struct batadv_vis_info *vis_info, *vis_info_tmp = NULL; 100 struct batadv_vis_info *vis_info, *vis_info_tmp = NULL;
@@ -252,7 +252,7 @@ int batadv_vis_seq_print_text(struct seq_file *seq, void *offset)
252 struct hlist_head *head; 252 struct hlist_head *head;
253 struct net_device *net_dev = (struct net_device *)seq->private; 253 struct net_device *net_dev = (struct net_device *)seq->private;
254 struct batadv_priv *bat_priv = netdev_priv(net_dev); 254 struct batadv_priv *bat_priv = netdev_priv(net_dev);
255 struct batadv_hashtable *hash = bat_priv->vis_hash; 255 struct batadv_hashtable *hash = bat_priv->vis.hash;
256 uint32_t i; 256 uint32_t i;
257 int ret = 0; 257 int ret = 0;
258 int vis_server = atomic_read(&bat_priv->vis_mode); 258 int vis_server = atomic_read(&bat_priv->vis_mode);
@@ -264,12 +264,12 @@ int batadv_vis_seq_print_text(struct seq_file *seq, void *offset)
264 if (vis_server == BATADV_VIS_TYPE_CLIENT_UPDATE) 264 if (vis_server == BATADV_VIS_TYPE_CLIENT_UPDATE)
265 goto out; 265 goto out;
266 266
267 spin_lock_bh(&bat_priv->vis_hash_lock); 267 spin_lock_bh(&bat_priv->vis.hash_lock);
268 for (i = 0; i < hash->size; i++) { 268 for (i = 0; i < hash->size; i++) {
269 head = &hash->table[i]; 269 head = &hash->table[i];
270 batadv_vis_seq_print_text_bucket(seq, head); 270 batadv_vis_seq_print_text_bucket(seq, head);
271 } 271 }
272 spin_unlock_bh(&bat_priv->vis_hash_lock); 272 spin_unlock_bh(&bat_priv->vis.hash_lock);
273 273
274out: 274out:
275 if (primary_if) 275 if (primary_if)
@@ -285,7 +285,7 @@ static void batadv_send_list_add(struct batadv_priv *bat_priv,
285{ 285{
286 if (list_empty(&info->send_list)) { 286 if (list_empty(&info->send_list)) {
287 kref_get(&info->refcount); 287 kref_get(&info->refcount);
288 list_add_tail(&info->send_list, &bat_priv->vis_send_list); 288 list_add_tail(&info->send_list, &bat_priv->vis.send_list);
289 } 289 }
290} 290}
291 291
@@ -311,9 +311,9 @@ static void batadv_recv_list_add(struct batadv_priv *bat_priv,
311 return; 311 return;
312 312
313 memcpy(entry->mac, mac, ETH_ALEN); 313 memcpy(entry->mac, mac, ETH_ALEN);
314 spin_lock_bh(&bat_priv->vis_list_lock); 314 spin_lock_bh(&bat_priv->vis.list_lock);
315 list_add_tail(&entry->list, recv_list); 315 list_add_tail(&entry->list, recv_list);
316 spin_unlock_bh(&bat_priv->vis_list_lock); 316 spin_unlock_bh(&bat_priv->vis.list_lock);
317} 317}
318 318
319/* returns 1 if this mac is in the recv_list */ 319/* returns 1 if this mac is in the recv_list */
@@ -323,14 +323,14 @@ static int batadv_recv_list_is_in(struct batadv_priv *bat_priv,
323{ 323{
324 const struct batadv_recvlist_node *entry; 324 const struct batadv_recvlist_node *entry;
325 325
326 spin_lock_bh(&bat_priv->vis_list_lock); 326 spin_lock_bh(&bat_priv->vis.list_lock);
327 list_for_each_entry(entry, recv_list, list) { 327 list_for_each_entry(entry, recv_list, list) {
328 if (batadv_compare_eth(entry->mac, mac)) { 328 if (batadv_compare_eth(entry->mac, mac)) {
329 spin_unlock_bh(&bat_priv->vis_list_lock); 329 spin_unlock_bh(&bat_priv->vis.list_lock);
330 return 1; 330 return 1;
331 } 331 }
332 } 332 }
333 spin_unlock_bh(&bat_priv->vis_list_lock); 333 spin_unlock_bh(&bat_priv->vis.list_lock);
334 return 0; 334 return 0;
335} 335}
336 336
@@ -354,7 +354,7 @@ batadv_add_packet(struct batadv_priv *bat_priv,
354 354
355 *is_new = 0; 355 *is_new = 0;
356 /* sanity check */ 356 /* sanity check */
357 if (!bat_priv->vis_hash) 357 if (!bat_priv->vis.hash)
358 return NULL; 358 return NULL;
359 359
360 /* see if the packet is already in vis_hash */ 360 /* see if the packet is already in vis_hash */
@@ -385,7 +385,7 @@ batadv_add_packet(struct batadv_priv *bat_priv,
385 } 385 }
386 } 386 }
387 /* remove old entry */ 387 /* remove old entry */
388 batadv_hash_remove(bat_priv->vis_hash, batadv_vis_info_cmp, 388 batadv_hash_remove(bat_priv->vis.hash, batadv_vis_info_cmp,
389 batadv_vis_info_choose, old_info); 389 batadv_vis_info_choose, old_info);
390 batadv_send_list_del(old_info); 390 batadv_send_list_del(old_info);
391 kref_put(&old_info->refcount, batadv_free_info); 391 kref_put(&old_info->refcount, batadv_free_info);
@@ -426,7 +426,7 @@ batadv_add_packet(struct batadv_priv *bat_priv,
426 batadv_recv_list_add(bat_priv, &info->recv_list, packet->sender_orig); 426 batadv_recv_list_add(bat_priv, &info->recv_list, packet->sender_orig);
427 427
428 /* try to add it */ 428 /* try to add it */
429 hash_added = batadv_hash_add(bat_priv->vis_hash, batadv_vis_info_cmp, 429 hash_added = batadv_hash_add(bat_priv->vis.hash, batadv_vis_info_cmp,
430 batadv_vis_info_choose, info, 430 batadv_vis_info_choose, info,
431 &info->hash_entry); 431 &info->hash_entry);
432 if (hash_added != 0) { 432 if (hash_added != 0) {
@@ -449,7 +449,7 @@ void batadv_receive_server_sync_packet(struct batadv_priv *bat_priv,
449 449
450 make_broadcast = (vis_server == BATADV_VIS_TYPE_SERVER_SYNC); 450 make_broadcast = (vis_server == BATADV_VIS_TYPE_SERVER_SYNC);
451 451
452 spin_lock_bh(&bat_priv->vis_hash_lock); 452 spin_lock_bh(&bat_priv->vis.hash_lock);
453 info = batadv_add_packet(bat_priv, vis_packet, vis_info_len, 453 info = batadv_add_packet(bat_priv, vis_packet, vis_info_len,
454 &is_new, make_broadcast); 454 &is_new, make_broadcast);
455 if (!info) 455 if (!info)
@@ -461,7 +461,7 @@ void batadv_receive_server_sync_packet(struct batadv_priv *bat_priv,
461 if (vis_server == BATADV_VIS_TYPE_SERVER_SYNC && is_new) 461 if (vis_server == BATADV_VIS_TYPE_SERVER_SYNC && is_new)
462 batadv_send_list_add(bat_priv, info); 462 batadv_send_list_add(bat_priv, info);
463end: 463end:
464 spin_unlock_bh(&bat_priv->vis_hash_lock); 464 spin_unlock_bh(&bat_priv->vis.hash_lock);
465} 465}
466 466
467/* handle an incoming client update packet and schedule forward if needed. */ 467/* handle an incoming client update packet and schedule forward if needed. */
@@ -484,7 +484,7 @@ void batadv_receive_client_update_packet(struct batadv_priv *bat_priv,
484 batadv_is_my_mac(vis_packet->target_orig)) 484 batadv_is_my_mac(vis_packet->target_orig))
485 are_target = 1; 485 are_target = 1;
486 486
487 spin_lock_bh(&bat_priv->vis_hash_lock); 487 spin_lock_bh(&bat_priv->vis.hash_lock);
488 info = batadv_add_packet(bat_priv, vis_packet, vis_info_len, 488 info = batadv_add_packet(bat_priv, vis_packet, vis_info_len,
489 &is_new, are_target); 489 &is_new, are_target);
490 490
@@ -505,7 +505,7 @@ void batadv_receive_client_update_packet(struct batadv_priv *bat_priv,
505 } 505 }
506 506
507end: 507end:
508 spin_unlock_bh(&bat_priv->vis_hash_lock); 508 spin_unlock_bh(&bat_priv->vis.hash_lock);
509} 509}
510 510
511/* Walk the originators and find the VIS server with the best tq. Set the packet 511/* Walk the originators and find the VIS server with the best tq. Set the packet
@@ -574,10 +574,11 @@ static int batadv_generate_vis_packet(struct batadv_priv *bat_priv)
574 struct hlist_head *head; 574 struct hlist_head *head;
575 struct batadv_orig_node *orig_node; 575 struct batadv_orig_node *orig_node;
576 struct batadv_neigh_node *router; 576 struct batadv_neigh_node *router;
577 struct batadv_vis_info *info = bat_priv->my_vis_info; 577 struct batadv_vis_info *info = bat_priv->vis.my_info;
578 struct batadv_vis_packet *packet; 578 struct batadv_vis_packet *packet;
579 struct batadv_vis_info_entry *entry; 579 struct batadv_vis_info_entry *entry;
580 struct batadv_tt_common_entry *tt_common_entry; 580 struct batadv_tt_common_entry *tt_common_entry;
581 uint8_t *packet_pos;
581 int best_tq = -1; 582 int best_tq = -1;
582 uint32_t i; 583 uint32_t i;
583 584
@@ -618,8 +619,8 @@ static int batadv_generate_vis_packet(struct batadv_priv *bat_priv)
618 goto next; 619 goto next;
619 620
620 /* fill one entry into buffer. */ 621 /* fill one entry into buffer. */
621 entry = (struct batadv_vis_info_entry *) 622 packet_pos = skb_put(info->skb_packet, sizeof(*entry));
622 skb_put(info->skb_packet, sizeof(*entry)); 623 entry = (struct batadv_vis_info_entry *)packet_pos;
623 memcpy(entry->src, 624 memcpy(entry->src,
624 router->if_incoming->net_dev->dev_addr, 625 router->if_incoming->net_dev->dev_addr,
625 ETH_ALEN); 626 ETH_ALEN);
@@ -636,7 +637,7 @@ next:
636 rcu_read_unlock(); 637 rcu_read_unlock();
637 } 638 }
638 639
639 hash = bat_priv->tt_local_hash; 640 hash = bat_priv->tt.local_hash;
640 641
641 for (i = 0; i < hash->size; i++) { 642 for (i = 0; i < hash->size; i++) {
642 head = &hash->table[i]; 643 head = &hash->table[i];
@@ -644,9 +645,8 @@ next:
644 rcu_read_lock(); 645 rcu_read_lock();
645 hlist_for_each_entry_rcu(tt_common_entry, node, head, 646 hlist_for_each_entry_rcu(tt_common_entry, node, head,
646 hash_entry) { 647 hash_entry) {
647 entry = (struct batadv_vis_info_entry *) 648 packet_pos = skb_put(info->skb_packet, sizeof(*entry));
648 skb_put(info->skb_packet, 649 entry = (struct batadv_vis_info_entry *)packet_pos;
649 sizeof(*entry));
650 memset(entry->src, 0, ETH_ALEN); 650 memset(entry->src, 0, ETH_ALEN);
651 memcpy(entry->dest, tt_common_entry->addr, ETH_ALEN); 651 memcpy(entry->dest, tt_common_entry->addr, ETH_ALEN);
652 entry->quality = 0; /* 0 means TT */ 652 entry->quality = 0; /* 0 means TT */
@@ -671,7 +671,7 @@ unlock:
671static void batadv_purge_vis_packets(struct batadv_priv *bat_priv) 671static void batadv_purge_vis_packets(struct batadv_priv *bat_priv)
672{ 672{
673 uint32_t i; 673 uint32_t i;
674 struct batadv_hashtable *hash = bat_priv->vis_hash; 674 struct batadv_hashtable *hash = bat_priv->vis.hash;
675 struct hlist_node *node, *node_tmp; 675 struct hlist_node *node, *node_tmp;
676 struct hlist_head *head; 676 struct hlist_head *head;
677 struct batadv_vis_info *info; 677 struct batadv_vis_info *info;
@@ -682,7 +682,7 @@ static void batadv_purge_vis_packets(struct batadv_priv *bat_priv)
682 hlist_for_each_entry_safe(info, node, node_tmp, 682 hlist_for_each_entry_safe(info, node, node_tmp,
683 head, hash_entry) { 683 head, hash_entry) {
684 /* never purge own data. */ 684 /* never purge own data. */
685 if (info == bat_priv->my_vis_info) 685 if (info == bat_priv->vis.my_info)
686 continue; 686 continue;
687 687
688 if (batadv_has_timed_out(info->first_seen, 688 if (batadv_has_timed_out(info->first_seen,
@@ -814,34 +814,36 @@ out:
814/* called from timer; send (and maybe generate) vis packet. */ 814/* called from timer; send (and maybe generate) vis packet. */
815static void batadv_send_vis_packets(struct work_struct *work) 815static void batadv_send_vis_packets(struct work_struct *work)
816{ 816{
817 struct delayed_work *delayed_work = 817 struct delayed_work *delayed_work;
818 container_of(work, struct delayed_work, work);
819 struct batadv_priv *bat_priv; 818 struct batadv_priv *bat_priv;
819 struct batadv_priv_vis *priv_vis;
820 struct batadv_vis_info *info; 820 struct batadv_vis_info *info;
821 821
822 bat_priv = container_of(delayed_work, struct batadv_priv, vis_work); 822 delayed_work = container_of(work, struct delayed_work, work);
823 spin_lock_bh(&bat_priv->vis_hash_lock); 823 priv_vis = container_of(delayed_work, struct batadv_priv_vis, work);
824 bat_priv = container_of(priv_vis, struct batadv_priv, vis);
825 spin_lock_bh(&bat_priv->vis.hash_lock);
824 batadv_purge_vis_packets(bat_priv); 826 batadv_purge_vis_packets(bat_priv);
825 827
826 if (batadv_generate_vis_packet(bat_priv) == 0) { 828 if (batadv_generate_vis_packet(bat_priv) == 0) {
827 /* schedule if generation was successful */ 829 /* schedule if generation was successful */
828 batadv_send_list_add(bat_priv, bat_priv->my_vis_info); 830 batadv_send_list_add(bat_priv, bat_priv->vis.my_info);
829 } 831 }
830 832
831 while (!list_empty(&bat_priv->vis_send_list)) { 833 while (!list_empty(&bat_priv->vis.send_list)) {
832 info = list_first_entry(&bat_priv->vis_send_list, 834 info = list_first_entry(&bat_priv->vis.send_list,
833 typeof(*info), send_list); 835 typeof(*info), send_list);
834 836
835 kref_get(&info->refcount); 837 kref_get(&info->refcount);
836 spin_unlock_bh(&bat_priv->vis_hash_lock); 838 spin_unlock_bh(&bat_priv->vis.hash_lock);
837 839
838 batadv_send_vis_packet(bat_priv, info); 840 batadv_send_vis_packet(bat_priv, info);
839 841
840 spin_lock_bh(&bat_priv->vis_hash_lock); 842 spin_lock_bh(&bat_priv->vis.hash_lock);
841 batadv_send_list_del(info); 843 batadv_send_list_del(info);
842 kref_put(&info->refcount, batadv_free_info); 844 kref_put(&info->refcount, batadv_free_info);
843 } 845 }
844 spin_unlock_bh(&bat_priv->vis_hash_lock); 846 spin_unlock_bh(&bat_priv->vis.hash_lock);
845 batadv_start_vis_timer(bat_priv); 847 batadv_start_vis_timer(bat_priv);
846} 848}
847 849
@@ -856,37 +858,37 @@ int batadv_vis_init(struct batadv_priv *bat_priv)
856 unsigned long first_seen; 858 unsigned long first_seen;
857 struct sk_buff *tmp_skb; 859 struct sk_buff *tmp_skb;
858 860
859 if (bat_priv->vis_hash) 861 if (bat_priv->vis.hash)
860 return 0; 862 return 0;
861 863
862 spin_lock_bh(&bat_priv->vis_hash_lock); 864 spin_lock_bh(&bat_priv->vis.hash_lock);
863 865
864 bat_priv->vis_hash = batadv_hash_new(256); 866 bat_priv->vis.hash = batadv_hash_new(256);
865 if (!bat_priv->vis_hash) { 867 if (!bat_priv->vis.hash) {
866 pr_err("Can't initialize vis_hash\n"); 868 pr_err("Can't initialize vis_hash\n");
867 goto err; 869 goto err;
868 } 870 }
869 871
870 bat_priv->my_vis_info = kmalloc(BATADV_MAX_VIS_PACKET_SIZE, GFP_ATOMIC); 872 bat_priv->vis.my_info = kmalloc(BATADV_MAX_VIS_PACKET_SIZE, GFP_ATOMIC);
871 if (!bat_priv->my_vis_info) 873 if (!bat_priv->vis.my_info)
872 goto err; 874 goto err;
873 875
874 len = sizeof(*packet) + BATADV_MAX_VIS_PACKET_SIZE + ETH_HLEN; 876 len = sizeof(*packet) + BATADV_MAX_VIS_PACKET_SIZE + ETH_HLEN;
875 bat_priv->my_vis_info->skb_packet = dev_alloc_skb(len); 877 bat_priv->vis.my_info->skb_packet = dev_alloc_skb(len);
876 if (!bat_priv->my_vis_info->skb_packet) 878 if (!bat_priv->vis.my_info->skb_packet)
877 goto free_info; 879 goto free_info;
878 880
879 skb_reserve(bat_priv->my_vis_info->skb_packet, ETH_HLEN); 881 skb_reserve(bat_priv->vis.my_info->skb_packet, ETH_HLEN);
880 tmp_skb = bat_priv->my_vis_info->skb_packet; 882 tmp_skb = bat_priv->vis.my_info->skb_packet;
881 packet = (struct batadv_vis_packet *)skb_put(tmp_skb, sizeof(*packet)); 883 packet = (struct batadv_vis_packet *)skb_put(tmp_skb, sizeof(*packet));
882 884
883 /* prefill the vis info */ 885 /* prefill the vis info */
884 first_seen = jiffies - msecs_to_jiffies(BATADV_VIS_INTERVAL); 886 first_seen = jiffies - msecs_to_jiffies(BATADV_VIS_INTERVAL);
885 bat_priv->my_vis_info->first_seen = first_seen; 887 bat_priv->vis.my_info->first_seen = first_seen;
886 INIT_LIST_HEAD(&bat_priv->my_vis_info->recv_list); 888 INIT_LIST_HEAD(&bat_priv->vis.my_info->recv_list);
887 INIT_LIST_HEAD(&bat_priv->my_vis_info->send_list); 889 INIT_LIST_HEAD(&bat_priv->vis.my_info->send_list);
888 kref_init(&bat_priv->my_vis_info->refcount); 890 kref_init(&bat_priv->vis.my_info->refcount);
889 bat_priv->my_vis_info->bat_priv = bat_priv; 891 bat_priv->vis.my_info->bat_priv = bat_priv;
890 packet->header.version = BATADV_COMPAT_VERSION; 892 packet->header.version = BATADV_COMPAT_VERSION;
891 packet->header.packet_type = BATADV_VIS; 893 packet->header.packet_type = BATADV_VIS;
892 packet->header.ttl = BATADV_TTL; 894 packet->header.ttl = BATADV_TTL;
@@ -894,28 +896,28 @@ int batadv_vis_init(struct batadv_priv *bat_priv)
894 packet->reserved = 0; 896 packet->reserved = 0;
895 packet->entries = 0; 897 packet->entries = 0;
896 898
897 INIT_LIST_HEAD(&bat_priv->vis_send_list); 899 INIT_LIST_HEAD(&bat_priv->vis.send_list);
898 900
899 hash_added = batadv_hash_add(bat_priv->vis_hash, batadv_vis_info_cmp, 901 hash_added = batadv_hash_add(bat_priv->vis.hash, batadv_vis_info_cmp,
900 batadv_vis_info_choose, 902 batadv_vis_info_choose,
901 bat_priv->my_vis_info, 903 bat_priv->vis.my_info,
902 &bat_priv->my_vis_info->hash_entry); 904 &bat_priv->vis.my_info->hash_entry);
903 if (hash_added != 0) { 905 if (hash_added != 0) {
904 pr_err("Can't add own vis packet into hash\n"); 906 pr_err("Can't add own vis packet into hash\n");
905 /* not in hash, need to remove it manually. */ 907 /* not in hash, need to remove it manually. */
906 kref_put(&bat_priv->my_vis_info->refcount, batadv_free_info); 908 kref_put(&bat_priv->vis.my_info->refcount, batadv_free_info);
907 goto err; 909 goto err;
908 } 910 }
909 911
910 spin_unlock_bh(&bat_priv->vis_hash_lock); 912 spin_unlock_bh(&bat_priv->vis.hash_lock);
911 batadv_start_vis_timer(bat_priv); 913 batadv_start_vis_timer(bat_priv);
912 return 0; 914 return 0;
913 915
914free_info: 916free_info:
915 kfree(bat_priv->my_vis_info); 917 kfree(bat_priv->vis.my_info);
916 bat_priv->my_vis_info = NULL; 918 bat_priv->vis.my_info = NULL;
917err: 919err:
918 spin_unlock_bh(&bat_priv->vis_hash_lock); 920 spin_unlock_bh(&bat_priv->vis.hash_lock);
919 batadv_vis_quit(bat_priv); 921 batadv_vis_quit(bat_priv);
920 return -ENOMEM; 922 return -ENOMEM;
921} 923}
@@ -933,23 +935,23 @@ static void batadv_free_info_ref(struct hlist_node *node, void *arg)
933/* shutdown vis-server */ 935/* shutdown vis-server */
934void batadv_vis_quit(struct batadv_priv *bat_priv) 936void batadv_vis_quit(struct batadv_priv *bat_priv)
935{ 937{
936 if (!bat_priv->vis_hash) 938 if (!bat_priv->vis.hash)
937 return; 939 return;
938 940
939 cancel_delayed_work_sync(&bat_priv->vis_work); 941 cancel_delayed_work_sync(&bat_priv->vis.work);
940 942
941 spin_lock_bh(&bat_priv->vis_hash_lock); 943 spin_lock_bh(&bat_priv->vis.hash_lock);
942 /* properly remove, kill timers ... */ 944 /* properly remove, kill timers ... */
943 batadv_hash_delete(bat_priv->vis_hash, batadv_free_info_ref, NULL); 945 batadv_hash_delete(bat_priv->vis.hash, batadv_free_info_ref, NULL);
944 bat_priv->vis_hash = NULL; 946 bat_priv->vis.hash = NULL;
945 bat_priv->my_vis_info = NULL; 947 bat_priv->vis.my_info = NULL;
946 spin_unlock_bh(&bat_priv->vis_hash_lock); 948 spin_unlock_bh(&bat_priv->vis.hash_lock);
947} 949}
948 950
949/* schedule packets for (re)transmission */ 951/* schedule packets for (re)transmission */
950static void batadv_start_vis_timer(struct batadv_priv *bat_priv) 952static void batadv_start_vis_timer(struct batadv_priv *bat_priv)
951{ 953{
952 INIT_DELAYED_WORK(&bat_priv->vis_work, batadv_send_vis_packets); 954 INIT_DELAYED_WORK(&bat_priv->vis.work, batadv_send_vis_packets);
953 queue_delayed_work(batadv_event_workqueue, &bat_priv->vis_work, 955 queue_delayed_work(batadv_event_workqueue, &bat_priv->vis.work,
954 msecs_to_jiffies(BATADV_VIS_INTERVAL)); 956 msecs_to_jiffies(BATADV_VIS_INTERVAL));
955} 957}
diff --git a/net/batman-adv/vis.h b/net/batman-adv/vis.h
index 84e716ed896..873282fa86d 100644
--- a/net/batman-adv/vis.h
+++ b/net/batman-adv/vis.h
@@ -20,7 +20,7 @@
20#ifndef _NET_BATMAN_ADV_VIS_H_ 20#ifndef _NET_BATMAN_ADV_VIS_H_
21#define _NET_BATMAN_ADV_VIS_H_ 21#define _NET_BATMAN_ADV_VIS_H_
22 22
23/* timeout of vis packets in miliseconds */ 23/* timeout of vis packets in milliseconds */
24#define BATADV_VIS_TIMEOUT 200000 24#define BATADV_VIS_TIMEOUT 200000
25 25
26int batadv_vis_seq_print_text(struct seq_file *seq, void *offset); 26int batadv_vis_seq_print_text(struct seq_file *seq, void *offset);