aboutsummaryrefslogtreecommitdiffstats
path: root/net/batman-adv
diff options
context:
space:
mode:
Diffstat (limited to 'net/batman-adv')
-rw-r--r--net/batman-adv/Kconfig10
-rw-r--r--net/batman-adv/Makefile1
-rw-r--r--net/batman-adv/bat_iv_ogm.c51
-rw-r--r--net/batman-adv/bitarray.c23
-rw-r--r--net/batman-adv/bridge_loop_avoidance.c95
-rw-r--r--net/batman-adv/debugfs.c26
-rw-r--r--net/batman-adv/distributed-arp-table.c1066
-rw-r--r--net/batman-adv/distributed-arp-table.h167
-rw-r--r--net/batman-adv/gateway_client.c19
-rw-r--r--net/batman-adv/hard-interface.c48
-rw-r--r--net/batman-adv/hash.h22
-rw-r--r--net/batman-adv/icmp_socket.c16
-rw-r--r--net/batman-adv/main.c55
-rw-r--r--net/batman-adv/main.h33
-rw-r--r--net/batman-adv/originator.c22
-rw-r--r--net/batman-adv/packet.h68
-rw-r--r--net/batman-adv/routing.c270
-rw-r--r--net/batman-adv/send.c4
-rw-r--r--net/batman-adv/soft-interface.c85
-rw-r--r--net/batman-adv/sysfs.c58
-rw-r--r--net/batman-adv/translation-table.c371
-rw-r--r--net/batman-adv/translation-table.h8
-rw-r--r--net/batman-adv/types.h100
-rw-r--r--net/batman-adv/unicast.c135
-rw-r--r--net/batman-adv/unicast.h36
-rw-r--r--net/batman-adv/vis.c9
26 files changed, 2329 insertions, 469 deletions
diff --git a/net/batman-adv/Kconfig b/net/batman-adv/Kconfig
index 53f5244e28f8..250e0b58109c 100644
--- a/net/batman-adv/Kconfig
+++ b/net/batman-adv/Kconfig
@@ -25,6 +25,16 @@ config BATMAN_ADV_BLA
25 more than one mesh node in the same LAN, you can safely remove 25 more than one mesh node in the same LAN, you can safely remove
26 this feature and save some space. 26 this feature and save some space.
27 27
28config BATMAN_ADV_DAT
29 bool "Distributed ARP Table"
30 depends on BATMAN_ADV && INET
31 default n
32 help
33 This option enables DAT (Distributed ARP Table), a DHT based
34 mechanism that increases ARP reliability on sparse wireless
35 mesh networks. If you think that your network does not need
36 this option you can safely remove it and save some space.
37
28config BATMAN_ADV_DEBUG 38config BATMAN_ADV_DEBUG
29 bool "B.A.T.M.A.N. debugging" 39 bool "B.A.T.M.A.N. debugging"
30 depends on BATMAN_ADV 40 depends on BATMAN_ADV
diff --git a/net/batman-adv/Makefile b/net/batman-adv/Makefile
index 8676d2b1d574..e45e3b4e32e3 100644
--- a/net/batman-adv/Makefile
+++ b/net/batman-adv/Makefile
@@ -23,6 +23,7 @@ batman-adv-y += bat_iv_ogm.o
23batman-adv-y += bitarray.o 23batman-adv-y += bitarray.o
24batman-adv-$(CONFIG_BATMAN_ADV_BLA) += bridge_loop_avoidance.o 24batman-adv-$(CONFIG_BATMAN_ADV_BLA) += bridge_loop_avoidance.o
25batman-adv-y += debugfs.o 25batman-adv-y += debugfs.o
26batman-adv-$(CONFIG_BATMAN_ADV_DAT) += distributed-arp-table.o
26batman-adv-y += gateway_client.o 27batman-adv-y += gateway_client.o
27batman-adv-y += gateway_common.o 28batman-adv-y += gateway_common.o
28batman-adv-y += hard-interface.o 29batman-adv-y += hard-interface.o
diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c
index b02b75dae3a8..9f3925a85aab 100644
--- a/net/batman-adv/bat_iv_ogm.c
+++ b/net/batman-adv/bat_iv_ogm.c
@@ -57,20 +57,22 @@ out:
57static int batadv_iv_ogm_iface_enable(struct batadv_hard_iface *hard_iface) 57static int batadv_iv_ogm_iface_enable(struct batadv_hard_iface *hard_iface)
58{ 58{
59 struct batadv_ogm_packet *batadv_ogm_packet; 59 struct batadv_ogm_packet *batadv_ogm_packet;
60 unsigned char *ogm_buff;
60 uint32_t random_seqno; 61 uint32_t random_seqno;
61 int res = -ENOMEM; 62 int res = -ENOMEM;
62 63
63 /* randomize initial seqno to avoid collision */ 64 /* randomize initial seqno to avoid collision */
64 get_random_bytes(&random_seqno, sizeof(random_seqno)); 65 get_random_bytes(&random_seqno, sizeof(random_seqno));
65 atomic_set(&hard_iface->seqno, random_seqno); 66 atomic_set(&hard_iface->bat_iv.ogm_seqno, random_seqno);
66 67
67 hard_iface->packet_len = BATADV_OGM_HLEN; 68 hard_iface->bat_iv.ogm_buff_len = BATADV_OGM_HLEN;
68 hard_iface->packet_buff = kmalloc(hard_iface->packet_len, GFP_ATOMIC); 69 ogm_buff = kmalloc(hard_iface->bat_iv.ogm_buff_len, GFP_ATOMIC);
69 70 if (!ogm_buff)
70 if (!hard_iface->packet_buff)
71 goto out; 71 goto out;
72 72
73 batadv_ogm_packet = (struct batadv_ogm_packet *)hard_iface->packet_buff; 73 hard_iface->bat_iv.ogm_buff = ogm_buff;
74
75 batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff;
74 batadv_ogm_packet->header.packet_type = BATADV_IV_OGM; 76 batadv_ogm_packet->header.packet_type = BATADV_IV_OGM;
75 batadv_ogm_packet->header.version = BATADV_COMPAT_VERSION; 77 batadv_ogm_packet->header.version = BATADV_COMPAT_VERSION;
76 batadv_ogm_packet->header.ttl = 2; 78 batadv_ogm_packet->header.ttl = 2;
@@ -87,15 +89,16 @@ out:
87 89
88static void batadv_iv_ogm_iface_disable(struct batadv_hard_iface *hard_iface) 90static void batadv_iv_ogm_iface_disable(struct batadv_hard_iface *hard_iface)
89{ 91{
90 kfree(hard_iface->packet_buff); 92 kfree(hard_iface->bat_iv.ogm_buff);
91 hard_iface->packet_buff = NULL; 93 hard_iface->bat_iv.ogm_buff = NULL;
92} 94}
93 95
94static void batadv_iv_ogm_iface_update_mac(struct batadv_hard_iface *hard_iface) 96static void batadv_iv_ogm_iface_update_mac(struct batadv_hard_iface *hard_iface)
95{ 97{
96 struct batadv_ogm_packet *batadv_ogm_packet; 98 struct batadv_ogm_packet *batadv_ogm_packet;
99 unsigned char *ogm_buff = hard_iface->bat_iv.ogm_buff;
97 100
98 batadv_ogm_packet = (struct batadv_ogm_packet *)hard_iface->packet_buff; 101 batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff;
99 memcpy(batadv_ogm_packet->orig, 102 memcpy(batadv_ogm_packet->orig,
100 hard_iface->net_dev->dev_addr, ETH_ALEN); 103 hard_iface->net_dev->dev_addr, ETH_ALEN);
101 memcpy(batadv_ogm_packet->prev_sender, 104 memcpy(batadv_ogm_packet->prev_sender,
@@ -106,8 +109,9 @@ static void
106batadv_iv_ogm_primary_iface_set(struct batadv_hard_iface *hard_iface) 109batadv_iv_ogm_primary_iface_set(struct batadv_hard_iface *hard_iface)
107{ 110{
108 struct batadv_ogm_packet *batadv_ogm_packet; 111 struct batadv_ogm_packet *batadv_ogm_packet;
112 unsigned char *ogm_buff = hard_iface->bat_iv.ogm_buff;
109 113
110 batadv_ogm_packet = (struct batadv_ogm_packet *)hard_iface->packet_buff; 114 batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff;
111 batadv_ogm_packet->flags = BATADV_PRIMARIES_FIRST_HOP; 115 batadv_ogm_packet->flags = BATADV_PRIMARIES_FIRST_HOP;
112 batadv_ogm_packet->header.ttl = BATADV_TTL; 116 batadv_ogm_packet->header.ttl = BATADV_TTL;
113} 117}
@@ -407,9 +411,11 @@ static void batadv_iv_ogm_aggregate_new(const unsigned char *packet_buff,
407 411
408 if ((atomic_read(&bat_priv->aggregated_ogms)) && 412 if ((atomic_read(&bat_priv->aggregated_ogms)) &&
409 (packet_len < BATADV_MAX_AGGREGATION_BYTES)) 413 (packet_len < BATADV_MAX_AGGREGATION_BYTES))
410 skb_size = BATADV_MAX_AGGREGATION_BYTES + ETH_HLEN; 414 skb_size = BATADV_MAX_AGGREGATION_BYTES;
411 else 415 else
412 skb_size = packet_len + ETH_HLEN; 416 skb_size = packet_len;
417
418 skb_size += ETH_HLEN + NET_IP_ALIGN;
413 419
414 forw_packet_aggr->skb = dev_alloc_skb(skb_size); 420 forw_packet_aggr->skb = dev_alloc_skb(skb_size);
415 if (!forw_packet_aggr->skb) { 421 if (!forw_packet_aggr->skb) {
@@ -418,7 +424,7 @@ static void batadv_iv_ogm_aggregate_new(const unsigned char *packet_buff,
418 kfree(forw_packet_aggr); 424 kfree(forw_packet_aggr);
419 goto out; 425 goto out;
420 } 426 }
421 skb_reserve(forw_packet_aggr->skb, ETH_HLEN); 427 skb_reserve(forw_packet_aggr->skb, ETH_HLEN + NET_IP_ALIGN);
422 428
423 INIT_HLIST_NODE(&forw_packet_aggr->list); 429 INIT_HLIST_NODE(&forw_packet_aggr->list);
424 430
@@ -590,8 +596,10 @@ static void batadv_iv_ogm_forward(struct batadv_orig_node *orig_node,
590static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface) 596static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
591{ 597{
592 struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface); 598 struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
599 unsigned char **ogm_buff = &hard_iface->bat_iv.ogm_buff;
593 struct batadv_ogm_packet *batadv_ogm_packet; 600 struct batadv_ogm_packet *batadv_ogm_packet;
594 struct batadv_hard_iface *primary_if; 601 struct batadv_hard_iface *primary_if;
602 int *ogm_buff_len = &hard_iface->bat_iv.ogm_buff_len;
595 int vis_server, tt_num_changes = 0; 603 int vis_server, tt_num_changes = 0;
596 uint32_t seqno; 604 uint32_t seqno;
597 uint8_t bandwidth; 605 uint8_t bandwidth;
@@ -600,17 +608,16 @@ static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
600 primary_if = batadv_primary_if_get_selected(bat_priv); 608 primary_if = batadv_primary_if_get_selected(bat_priv);
601 609
602 if (hard_iface == primary_if) 610 if (hard_iface == primary_if)
603 tt_num_changes = batadv_tt_append_diff(bat_priv, 611 tt_num_changes = batadv_tt_append_diff(bat_priv, ogm_buff,
604 &hard_iface->packet_buff, 612 ogm_buff_len,
605 &hard_iface->packet_len,
606 BATADV_OGM_HLEN); 613 BATADV_OGM_HLEN);
607 614
608 batadv_ogm_packet = (struct batadv_ogm_packet *)hard_iface->packet_buff; 615 batadv_ogm_packet = (struct batadv_ogm_packet *)(*ogm_buff);
609 616
610 /* change sequence number to network order */ 617 /* change sequence number to network order */
611 seqno = (uint32_t)atomic_read(&hard_iface->seqno); 618 seqno = (uint32_t)atomic_read(&hard_iface->bat_iv.ogm_seqno);
612 batadv_ogm_packet->seqno = htonl(seqno); 619 batadv_ogm_packet->seqno = htonl(seqno);
613 atomic_inc(&hard_iface->seqno); 620 atomic_inc(&hard_iface->bat_iv.ogm_seqno);
614 621
615 batadv_ogm_packet->ttvn = atomic_read(&bat_priv->tt.vn); 622 batadv_ogm_packet->ttvn = atomic_read(&bat_priv->tt.vn);
616 batadv_ogm_packet->tt_crc = htons(bat_priv->tt.local_crc); 623 batadv_ogm_packet->tt_crc = htons(bat_priv->tt.local_crc);
@@ -631,8 +638,8 @@ static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
631 } 638 }
632 639
633 batadv_slide_own_bcast_window(hard_iface); 640 batadv_slide_own_bcast_window(hard_iface);
634 batadv_iv_ogm_queue_add(bat_priv, hard_iface->packet_buff, 641 batadv_iv_ogm_queue_add(bat_priv, hard_iface->bat_iv.ogm_buff,
635 hard_iface->packet_len, hard_iface, 1, 642 hard_iface->bat_iv.ogm_buff_len, hard_iface, 1,
636 batadv_iv_ogm_emit_send_time(bat_priv)); 643 batadv_iv_ogm_emit_send_time(bat_priv));
637 644
638 if (primary_if) 645 if (primary_if)
@@ -1015,7 +1022,7 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr,
1015 return; 1022 return;
1016 1023
1017 /* could be changed by schedule_own_packet() */ 1024 /* could be changed by schedule_own_packet() */
1018 if_incoming_seqno = atomic_read(&if_incoming->seqno); 1025 if_incoming_seqno = atomic_read(&if_incoming->bat_iv.ogm_seqno);
1019 1026
1020 if (batadv_ogm_packet->flags & BATADV_DIRECTLINK) 1027 if (batadv_ogm_packet->flags & BATADV_DIRECTLINK)
1021 has_directlink_flag = 1; 1028 has_directlink_flag = 1;
diff --git a/net/batman-adv/bitarray.c b/net/batman-adv/bitarray.c
index aea174cdbfbd..5453b17d8df2 100644
--- a/net/batman-adv/bitarray.c
+++ b/net/batman-adv/bitarray.c
@@ -79,20 +79,17 @@ int batadv_bit_get_packet(void *priv, unsigned long *seq_bits,
79 * or the old packet got delayed somewhere in the network. The 79 * or the old packet got delayed somewhere in the network. The
80 * packet should be dropped without calling this function if the 80 * packet should be dropped without calling this function if the
81 * seqno window is protected. 81 * seqno window is protected.
82 *
83 * seq_num_diff <= -BATADV_TQ_LOCAL_WINDOW_SIZE
84 * or
85 * seq_num_diff >= BATADV_EXPECTED_SEQNO_RANGE
82 */ 86 */
83 if (seq_num_diff <= -BATADV_TQ_LOCAL_WINDOW_SIZE || 87 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
84 seq_num_diff >= BATADV_EXPECTED_SEQNO_RANGE) { 88 "Other host probably restarted!\n");
85 89
86 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, 90 bitmap_zero(seq_bits, BATADV_TQ_LOCAL_WINDOW_SIZE);
87 "Other host probably restarted!\n"); 91 if (set_mark)
88 92 batadv_set_bit(seq_bits, 0);
89 bitmap_zero(seq_bits, BATADV_TQ_LOCAL_WINDOW_SIZE);
90 if (set_mark)
91 batadv_set_bit(seq_bits, 0);
92
93 return 1;
94 }
95 93
96 /* never reached */ 94 return 1;
97 return 0;
98} 95}
diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c
index fd8d5afec0dd..bda8b1710806 100644
--- a/net/batman-adv/bridge_loop_avoidance.c
+++ b/net/batman-adv/bridge_loop_avoidance.c
@@ -40,15 +40,11 @@ static void batadv_bla_send_announce(struct batadv_priv *bat_priv,
40/* return the index of the claim */ 40/* return the index of the claim */
41static inline uint32_t batadv_choose_claim(const void *data, uint32_t size) 41static inline uint32_t batadv_choose_claim(const void *data, uint32_t size)
42{ 42{
43 const unsigned char *key = data; 43 struct batadv_claim *claim = (struct batadv_claim *)data;
44 uint32_t hash = 0; 44 uint32_t hash = 0;
45 size_t i;
46 45
47 for (i = 0; i < ETH_ALEN + sizeof(short); i++) { 46 hash = batadv_hash_bytes(hash, &claim->addr, sizeof(claim->addr));
48 hash += key[i]; 47 hash = batadv_hash_bytes(hash, &claim->vid, sizeof(claim->vid));
49 hash += (hash << 10);
50 hash ^= (hash >> 6);
51 }
52 48
53 hash += (hash << 3); 49 hash += (hash << 3);
54 hash ^= (hash >> 11); 50 hash ^= (hash >> 11);
@@ -61,15 +57,11 @@ static inline uint32_t batadv_choose_claim(const void *data, uint32_t size)
61static inline uint32_t batadv_choose_backbone_gw(const void *data, 57static inline uint32_t batadv_choose_backbone_gw(const void *data,
62 uint32_t size) 58 uint32_t size)
63{ 59{
64 const unsigned char *key = data; 60 struct batadv_claim *claim = (struct batadv_claim *)data;
65 uint32_t hash = 0; 61 uint32_t hash = 0;
66 size_t i;
67 62
68 for (i = 0; i < ETH_ALEN + sizeof(short); i++) { 63 hash = batadv_hash_bytes(hash, &claim->addr, sizeof(claim->addr));
69 hash += key[i]; 64 hash = batadv_hash_bytes(hash, &claim->vid, sizeof(claim->vid));
70 hash += (hash << 10);
71 hash ^= (hash >> 6);
72 }
73 65
74 hash += (hash << 3); 66 hash += (hash << 3);
75 hash ^= (hash >> 11); 67 hash ^= (hash >> 11);
@@ -362,7 +354,7 @@ out:
362 */ 354 */
363static struct batadv_backbone_gw * 355static struct batadv_backbone_gw *
364batadv_bla_get_backbone_gw(struct batadv_priv *bat_priv, uint8_t *orig, 356batadv_bla_get_backbone_gw(struct batadv_priv *bat_priv, uint8_t *orig,
365 short vid) 357 short vid, bool own_backbone)
366{ 358{
367 struct batadv_backbone_gw *entry; 359 struct batadv_backbone_gw *entry;
368 struct batadv_orig_node *orig_node; 360 struct batadv_orig_node *orig_node;
@@ -386,6 +378,7 @@ batadv_bla_get_backbone_gw(struct batadv_priv *bat_priv, uint8_t *orig,
386 entry->crc = BATADV_BLA_CRC_INIT; 378 entry->crc = BATADV_BLA_CRC_INIT;
387 entry->bat_priv = bat_priv; 379 entry->bat_priv = bat_priv;
388 atomic_set(&entry->request_sent, 0); 380 atomic_set(&entry->request_sent, 0);
381 atomic_set(&entry->wait_periods, 0);
389 memcpy(entry->orig, orig, ETH_ALEN); 382 memcpy(entry->orig, orig, ETH_ALEN);
390 383
391 /* one for the hash, one for returning */ 384 /* one for the hash, one for returning */
@@ -409,6 +402,16 @@ batadv_bla_get_backbone_gw(struct batadv_priv *bat_priv, uint8_t *orig,
409 "became a backbone gateway"); 402 "became a backbone gateway");
410 batadv_orig_node_free_ref(orig_node); 403 batadv_orig_node_free_ref(orig_node);
411 } 404 }
405
406 if (own_backbone) {
407 batadv_bla_send_announce(bat_priv, entry);
408
409 /* this will be decreased in the worker thread */
410 atomic_inc(&entry->request_sent);
411 atomic_set(&entry->wait_periods, BATADV_BLA_WAIT_PERIODS);
412 atomic_inc(&bat_priv->bla.num_requests);
413 }
414
412 return entry; 415 return entry;
413} 416}
414 417
@@ -424,7 +427,7 @@ batadv_bla_update_own_backbone_gw(struct batadv_priv *bat_priv,
424 427
425 backbone_gw = batadv_bla_get_backbone_gw(bat_priv, 428 backbone_gw = batadv_bla_get_backbone_gw(bat_priv,
426 primary_if->net_dev->dev_addr, 429 primary_if->net_dev->dev_addr,
427 vid); 430 vid, true);
428 if (unlikely(!backbone_gw)) 431 if (unlikely(!backbone_gw))
429 return; 432 return;
430 433
@@ -632,7 +635,8 @@ static int batadv_handle_announce(struct batadv_priv *bat_priv,
632 if (memcmp(an_addr, batadv_announce_mac, 4) != 0) 635 if (memcmp(an_addr, batadv_announce_mac, 4) != 0)
633 return 0; 636 return 0;
634 637
635 backbone_gw = batadv_bla_get_backbone_gw(bat_priv, backbone_addr, vid); 638 backbone_gw = batadv_bla_get_backbone_gw(bat_priv, backbone_addr, vid,
639 false);
636 640
637 if (unlikely(!backbone_gw)) 641 if (unlikely(!backbone_gw))
638 return 1; 642 return 1;
@@ -730,7 +734,8 @@ static int batadv_handle_claim(struct batadv_priv *bat_priv,
730 734
731 /* register the gateway if not yet available, and add the claim. */ 735 /* register the gateway if not yet available, and add the claim. */
732 736
733 backbone_gw = batadv_bla_get_backbone_gw(bat_priv, backbone_addr, vid); 737 backbone_gw = batadv_bla_get_backbone_gw(bat_priv, backbone_addr, vid,
738 false);
734 739
735 if (unlikely(!backbone_gw)) 740 if (unlikely(!backbone_gw))
736 return 1; 741 return 1;
@@ -1140,6 +1145,24 @@ static void batadv_bla_periodic_work(struct work_struct *work)
1140 backbone_gw->lasttime = jiffies; 1145 backbone_gw->lasttime = jiffies;
1141 1146
1142 batadv_bla_send_announce(bat_priv, backbone_gw); 1147 batadv_bla_send_announce(bat_priv, backbone_gw);
1148
1149 /* request_sent is only set after creation to avoid
1150 * problems when we are not yet known as backbone gw
1151 * in the backbone.
1152 *
1153 * We can reset this now after we waited some periods
1154 * to give bridge forward delays and bla group forming
1155 * some grace time.
1156 */
1157
1158 if (atomic_read(&backbone_gw->request_sent) == 0)
1159 continue;
1160
1161 if (!atomic_dec_and_test(&backbone_gw->wait_periods))
1162 continue;
1163
1164 atomic_dec(&backbone_gw->bat_priv->bla.num_requests);
1165 atomic_set(&backbone_gw->request_sent, 0);
1143 } 1166 }
1144 rcu_read_unlock(); 1167 rcu_read_unlock();
1145 } 1168 }
@@ -1585,23 +1608,11 @@ int batadv_bla_claim_table_seq_print_text(struct seq_file *seq, void *offset)
1585 struct hlist_head *head; 1608 struct hlist_head *head;
1586 uint32_t i; 1609 uint32_t i;
1587 bool is_own; 1610 bool is_own;
1588 int ret = 0;
1589 uint8_t *primary_addr; 1611 uint8_t *primary_addr;
1590 1612
1591 primary_if = batadv_primary_if_get_selected(bat_priv); 1613 primary_if = batadv_seq_print_text_primary_if_get(seq);
1592 if (!primary_if) { 1614 if (!primary_if)
1593 ret = seq_printf(seq,
1594 "BATMAN mesh %s disabled - please specify interfaces to enable it\n",
1595 net_dev->name);
1596 goto out;
1597 }
1598
1599 if (primary_if->if_status != BATADV_IF_ACTIVE) {
1600 ret = seq_printf(seq,
1601 "BATMAN mesh %s disabled - primary interface not active\n",
1602 net_dev->name);
1603 goto out; 1615 goto out;
1604 }
1605 1616
1606 primary_addr = primary_if->net_dev->dev_addr; 1617 primary_addr = primary_if->net_dev->dev_addr;
1607 seq_printf(seq, 1618 seq_printf(seq,
@@ -1628,7 +1639,7 @@ int batadv_bla_claim_table_seq_print_text(struct seq_file *seq, void *offset)
1628out: 1639out:
1629 if (primary_if) 1640 if (primary_if)
1630 batadv_hardif_free_ref(primary_if); 1641 batadv_hardif_free_ref(primary_if);
1631 return ret; 1642 return 0;
1632} 1643}
1633 1644
1634int batadv_bla_backbone_table_seq_print_text(struct seq_file *seq, void *offset) 1645int batadv_bla_backbone_table_seq_print_text(struct seq_file *seq, void *offset)
@@ -1643,23 +1654,11 @@ int batadv_bla_backbone_table_seq_print_text(struct seq_file *seq, void *offset)
1643 int secs, msecs; 1654 int secs, msecs;
1644 uint32_t i; 1655 uint32_t i;
1645 bool is_own; 1656 bool is_own;
1646 int ret = 0;
1647 uint8_t *primary_addr; 1657 uint8_t *primary_addr;
1648 1658
1649 primary_if = batadv_primary_if_get_selected(bat_priv); 1659 primary_if = batadv_seq_print_text_primary_if_get(seq);
1650 if (!primary_if) { 1660 if (!primary_if)
1651 ret = seq_printf(seq,
1652 "BATMAN mesh %s disabled - please specify interfaces to enable it\n",
1653 net_dev->name);
1654 goto out;
1655 }
1656
1657 if (primary_if->if_status != BATADV_IF_ACTIVE) {
1658 ret = seq_printf(seq,
1659 "BATMAN mesh %s disabled - primary interface not active\n",
1660 net_dev->name);
1661 goto out; 1661 goto out;
1662 }
1663 1662
1664 primary_addr = primary_if->net_dev->dev_addr; 1663 primary_addr = primary_if->net_dev->dev_addr;
1665 seq_printf(seq, 1664 seq_printf(seq,
@@ -1693,5 +1692,5 @@ int batadv_bla_backbone_table_seq_print_text(struct seq_file *seq, void *offset)
1693out: 1692out:
1694 if (primary_if) 1693 if (primary_if)
1695 batadv_hardif_free_ref(primary_if); 1694 batadv_hardif_free_ref(primary_if);
1696 return ret; 1695 return 0;
1697} 1696}
diff --git a/net/batman-adv/debugfs.c b/net/batman-adv/debugfs.c
index 391d4fb2026f..3f679cb2d0e2 100644
--- a/net/batman-adv/debugfs.c
+++ b/net/batman-adv/debugfs.c
@@ -31,6 +31,7 @@
31#include "vis.h" 31#include "vis.h"
32#include "icmp_socket.h" 32#include "icmp_socket.h"
33#include "bridge_loop_avoidance.h" 33#include "bridge_loop_avoidance.h"
34#include "distributed-arp-table.h"
34 35
35static struct dentry *batadv_debugfs; 36static struct dentry *batadv_debugfs;
36 37
@@ -99,15 +100,17 @@ int batadv_debug_log(struct batadv_priv *bat_priv, const char *fmt, ...)
99 100
100static int batadv_log_open(struct inode *inode, struct file *file) 101static int batadv_log_open(struct inode *inode, struct file *file)
101{ 102{
103 if (!try_module_get(THIS_MODULE))
104 return -EBUSY;
105
102 nonseekable_open(inode, file); 106 nonseekable_open(inode, file);
103 file->private_data = inode->i_private; 107 file->private_data = inode->i_private;
104 batadv_inc_module_count();
105 return 0; 108 return 0;
106} 109}
107 110
108static int batadv_log_release(struct inode *inode, struct file *file) 111static int batadv_log_release(struct inode *inode, struct file *file)
109{ 112{
110 batadv_dec_module_count(); 113 module_put(THIS_MODULE);
111 return 0; 114 return 0;
112} 115}
113 116
@@ -278,6 +281,19 @@ static int batadv_bla_backbone_table_open(struct inode *inode,
278 281
279#endif 282#endif
280 283
284#ifdef CONFIG_BATMAN_ADV_DAT
285/**
286 * batadv_dat_cache_open - Prepare file handler for reads from dat_chache
287 * @inode: inode which was opened
288 * @file: file handle to be initialized
289 */
290static int batadv_dat_cache_open(struct inode *inode, struct file *file)
291{
292 struct net_device *net_dev = (struct net_device *)inode->i_private;
293 return single_open(file, batadv_dat_cache_seq_print_text, net_dev);
294}
295#endif
296
281static int batadv_transtable_local_open(struct inode *inode, struct file *file) 297static int batadv_transtable_local_open(struct inode *inode, struct file *file)
282{ 298{
283 struct net_device *net_dev = (struct net_device *)inode->i_private; 299 struct net_device *net_dev = (struct net_device *)inode->i_private;
@@ -317,6 +333,9 @@ static BATADV_DEBUGINFO(bla_claim_table, S_IRUGO, batadv_bla_claim_table_open);
317static BATADV_DEBUGINFO(bla_backbone_table, S_IRUGO, 333static BATADV_DEBUGINFO(bla_backbone_table, S_IRUGO,
318 batadv_bla_backbone_table_open); 334 batadv_bla_backbone_table_open);
319#endif 335#endif
336#ifdef CONFIG_BATMAN_ADV_DAT
337static BATADV_DEBUGINFO(dat_cache, S_IRUGO, batadv_dat_cache_open);
338#endif
320static BATADV_DEBUGINFO(transtable_local, S_IRUGO, 339static BATADV_DEBUGINFO(transtable_local, S_IRUGO,
321 batadv_transtable_local_open); 340 batadv_transtable_local_open);
322static BATADV_DEBUGINFO(vis_data, S_IRUGO, batadv_vis_data_open); 341static BATADV_DEBUGINFO(vis_data, S_IRUGO, batadv_vis_data_open);
@@ -329,6 +348,9 @@ static struct batadv_debuginfo *batadv_mesh_debuginfos[] = {
329 &batadv_debuginfo_bla_claim_table, 348 &batadv_debuginfo_bla_claim_table,
330 &batadv_debuginfo_bla_backbone_table, 349 &batadv_debuginfo_bla_backbone_table,
331#endif 350#endif
351#ifdef CONFIG_BATMAN_ADV_DAT
352 &batadv_debuginfo_dat_cache,
353#endif
332 &batadv_debuginfo_transtable_local, 354 &batadv_debuginfo_transtable_local,
333 &batadv_debuginfo_vis_data, 355 &batadv_debuginfo_vis_data,
334 NULL, 356 NULL,
diff --git a/net/batman-adv/distributed-arp-table.c b/net/batman-adv/distributed-arp-table.c
new file mode 100644
index 000000000000..8e1d89d2b1c1
--- /dev/null
+++ b/net/batman-adv/distributed-arp-table.c
@@ -0,0 +1,1066 @@
1/* Copyright (C) 2011-2012 B.A.T.M.A.N. contributors:
2 *
3 * Antonio Quartulli
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of version 2 of the GNU General Public
7 * License as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA
18 */
19
20#include <linux/if_ether.h>
21#include <linux/if_arp.h>
22#include <net/arp.h>
23
24#include "main.h"
25#include "hash.h"
26#include "distributed-arp-table.h"
27#include "hard-interface.h"
28#include "originator.h"
29#include "send.h"
30#include "types.h"
31#include "translation-table.h"
32#include "unicast.h"
33
34static void batadv_dat_purge(struct work_struct *work);
35
36/**
37 * batadv_dat_start_timer - initialise the DAT periodic worker
38 * @bat_priv: the bat priv with all the soft interface information
39 */
40static void batadv_dat_start_timer(struct batadv_priv *bat_priv)
41{
42 INIT_DELAYED_WORK(&bat_priv->dat.work, batadv_dat_purge);
43 queue_delayed_work(batadv_event_workqueue, &bat_priv->dat.work,
44 msecs_to_jiffies(10000));
45}
46
47/**
48 * batadv_dat_entry_free_ref - decrements the dat_entry refcounter and possibly
49 * free it
50 * @dat_entry: the oentry to free
51 */
52static void batadv_dat_entry_free_ref(struct batadv_dat_entry *dat_entry)
53{
54 if (atomic_dec_and_test(&dat_entry->refcount))
55 kfree_rcu(dat_entry, rcu);
56}
57
58/**
59 * batadv_dat_to_purge - checks whether a dat_entry has to be purged or not
60 * @dat_entry: the entry to check
61 *
62 * Returns true if the entry has to be purged now, false otherwise
63 */
64static bool batadv_dat_to_purge(struct batadv_dat_entry *dat_entry)
65{
66 return batadv_has_timed_out(dat_entry->last_update,
67 BATADV_DAT_ENTRY_TIMEOUT);
68}
69
70/**
71 * __batadv_dat_purge - delete entries from the DAT local storage
72 * @bat_priv: the bat priv with all the soft interface information
73 * @to_purge: function in charge to decide whether an entry has to be purged or
74 * not. This function takes the dat_entry as argument and has to
75 * returns a boolean value: true is the entry has to be deleted,
76 * false otherwise
77 *
78 * Loops over each entry in the DAT local storage and delete it if and only if
79 * the to_purge function passed as argument returns true
80 */
81static void __batadv_dat_purge(struct batadv_priv *bat_priv,
82 bool (*to_purge)(struct batadv_dat_entry *))
83{
84 spinlock_t *list_lock; /* protects write access to the hash lists */
85 struct batadv_dat_entry *dat_entry;
86 struct hlist_node *node, *node_tmp;
87 struct hlist_head *head;
88 uint32_t i;
89
90 if (!bat_priv->dat.hash)
91 return;
92
93 for (i = 0; i < bat_priv->dat.hash->size; i++) {
94 head = &bat_priv->dat.hash->table[i];
95 list_lock = &bat_priv->dat.hash->list_locks[i];
96
97 spin_lock_bh(list_lock);
98 hlist_for_each_entry_safe(dat_entry, node, node_tmp, head,
99 hash_entry) {
100 /* if an helper function has been passed as parameter,
101 * ask it if the entry has to be purged or not
102 */
103 if (to_purge && !to_purge(dat_entry))
104 continue;
105
106 hlist_del_rcu(node);
107 batadv_dat_entry_free_ref(dat_entry);
108 }
109 spin_unlock_bh(list_lock);
110 }
111}
112
113/**
114 * batadv_dat_purge - periodic task that deletes old entries from the local DAT
115 * hash table
116 * @work: kernel work struct
117 */
118static void batadv_dat_purge(struct work_struct *work)
119{
120 struct delayed_work *delayed_work;
121 struct batadv_priv_dat *priv_dat;
122 struct batadv_priv *bat_priv;
123
124 delayed_work = container_of(work, struct delayed_work, work);
125 priv_dat = container_of(delayed_work, struct batadv_priv_dat, work);
126 bat_priv = container_of(priv_dat, struct batadv_priv, dat);
127
128 __batadv_dat_purge(bat_priv, batadv_dat_to_purge);
129 batadv_dat_start_timer(bat_priv);
130}
131
132/**
133 * batadv_compare_dat - comparing function used in the local DAT hash table
134 * @node: node in the local table
135 * @data2: second object to compare the node to
136 *
137 * Returns 1 if the two entry are the same, 0 otherwise
138 */
139static int batadv_compare_dat(const struct hlist_node *node, const void *data2)
140{
141 const void *data1 = container_of(node, struct batadv_dat_entry,
142 hash_entry);
143
144 return (memcmp(data1, data2, sizeof(__be32)) == 0 ? 1 : 0);
145}
146
147/**
148 * batadv_arp_hw_src - extract the hw_src field from an ARP packet
149 * @skb: ARP packet
150 * @hdr_size: size of the possible header before the ARP packet
151 *
152 * Returns the value of the hw_src field in the ARP packet
153 */
154static uint8_t *batadv_arp_hw_src(struct sk_buff *skb, int hdr_size)
155{
156 uint8_t *addr;
157
158 addr = (uint8_t *)(skb->data + hdr_size);
159 addr += ETH_HLEN + sizeof(struct arphdr);
160
161 return addr;
162}
163
164/**
165 * batadv_arp_ip_src - extract the ip_src field from an ARP packet
166 * @skb: ARP packet
167 * @hdr_size: size of the possible header before the ARP packet
168 *
169 * Returns the value of the ip_src field in the ARP packet
170 */
171static __be32 batadv_arp_ip_src(struct sk_buff *skb, int hdr_size)
172{
173 return *(__be32 *)(batadv_arp_hw_src(skb, hdr_size) + ETH_ALEN);
174}
175
176/**
177 * batadv_arp_hw_dst - extract the hw_dst field from an ARP packet
178 * @skb: ARP packet
179 * @hdr_size: size of the possible header before the ARP packet
180 *
181 * Returns the value of the hw_dst field in the ARP packet
182 */
183static uint8_t *batadv_arp_hw_dst(struct sk_buff *skb, int hdr_size)
184{
185 return batadv_arp_hw_src(skb, hdr_size) + ETH_ALEN + 4;
186}
187
188/**
189 * batadv_arp_ip_dst - extract the ip_dst field from an ARP packet
190 * @skb: ARP packet
191 * @hdr_size: size of the possible header before the ARP packet
192 *
193 * Returns the value of the ip_dst field in the ARP packet
194 */
195static __be32 batadv_arp_ip_dst(struct sk_buff *skb, int hdr_size)
196{
197 return *(__be32 *)(batadv_arp_hw_src(skb, hdr_size) + ETH_ALEN * 2 + 4);
198}
199
200/**
201 * batadv_hash_dat - compute the hash value for an IP address
202 * @data: data to hash
203 * @size: size of the hash table
204 *
205 * Returns the selected index in the hash table for the given data
206 */
207static uint32_t batadv_hash_dat(const void *data, uint32_t size)
208{
209 const unsigned char *key = data;
210 uint32_t hash = 0;
211 size_t i;
212
213 for (i = 0; i < 4; i++) {
214 hash += key[i];
215 hash += (hash << 10);
216 hash ^= (hash >> 6);
217 }
218
219 hash += (hash << 3);
220 hash ^= (hash >> 11);
221 hash += (hash << 15);
222
223 return hash % size;
224}
225
226/**
227 * batadv_dat_entry_hash_find - looks for a given dat_entry in the local hash
228 * table
229 * @bat_priv: the bat priv with all the soft interface information
230 * @ip: search key
231 *
232 * Returns the dat_entry if found, NULL otherwise
233 */
234static struct batadv_dat_entry *
235batadv_dat_entry_hash_find(struct batadv_priv *bat_priv, __be32 ip)
236{
237 struct hlist_head *head;
238 struct hlist_node *node;
239 struct batadv_dat_entry *dat_entry, *dat_entry_tmp = NULL;
240 struct batadv_hashtable *hash = bat_priv->dat.hash;
241 uint32_t index;
242
243 if (!hash)
244 return NULL;
245
246 index = batadv_hash_dat(&ip, hash->size);
247 head = &hash->table[index];
248
249 rcu_read_lock();
250 hlist_for_each_entry_rcu(dat_entry, node, head, hash_entry) {
251 if (dat_entry->ip != ip)
252 continue;
253
254 if (!atomic_inc_not_zero(&dat_entry->refcount))
255 continue;
256
257 dat_entry_tmp = dat_entry;
258 break;
259 }
260 rcu_read_unlock();
261
262 return dat_entry_tmp;
263}
264
265/**
266 * batadv_dat_entry_add - add a new dat entry or update it if already exists
267 * @bat_priv: the bat priv with all the soft interface information
268 * @ip: ipv4 to add/edit
269 * @mac_addr: mac address to assign to the given ipv4
270 */
271static void batadv_dat_entry_add(struct batadv_priv *bat_priv, __be32 ip,
272 uint8_t *mac_addr)
273{
274 struct batadv_dat_entry *dat_entry;
275 int hash_added;
276
277 dat_entry = batadv_dat_entry_hash_find(bat_priv, ip);
278 /* if this entry is already known, just update it */
279 if (dat_entry) {
280 if (!batadv_compare_eth(dat_entry->mac_addr, mac_addr))
281 memcpy(dat_entry->mac_addr, mac_addr, ETH_ALEN);
282 dat_entry->last_update = jiffies;
283 batadv_dbg(BATADV_DBG_DAT, bat_priv,
284 "Entry updated: %pI4 %pM\n", &dat_entry->ip,
285 dat_entry->mac_addr);
286 goto out;
287 }
288
289 dat_entry = kmalloc(sizeof(*dat_entry), GFP_ATOMIC);
290 if (!dat_entry)
291 goto out;
292
293 dat_entry->ip = ip;
294 memcpy(dat_entry->mac_addr, mac_addr, ETH_ALEN);
295 dat_entry->last_update = jiffies;
296 atomic_set(&dat_entry->refcount, 2);
297
298 hash_added = batadv_hash_add(bat_priv->dat.hash, batadv_compare_dat,
299 batadv_hash_dat, &dat_entry->ip,
300 &dat_entry->hash_entry);
301
302 if (unlikely(hash_added != 0)) {
303 /* remove the reference for the hash */
304 batadv_dat_entry_free_ref(dat_entry);
305 goto out;
306 }
307
308 batadv_dbg(BATADV_DBG_DAT, bat_priv, "New entry added: %pI4 %pM\n",
309 &dat_entry->ip, dat_entry->mac_addr);
310
311out:
312 if (dat_entry)
313 batadv_dat_entry_free_ref(dat_entry);
314}
315
316#ifdef CONFIG_BATMAN_ADV_DEBUG
317
318/**
319 * batadv_dbg_arp - print a debug message containing all the ARP packet details
320 * @bat_priv: the bat priv with all the soft interface information
321 * @skb: ARP packet
322 * @type: ARP type
323 * @hdr_size: size of the possible header before the ARP packet
324 * @msg: message to print together with the debugging information
325 */
326static void batadv_dbg_arp(struct batadv_priv *bat_priv, struct sk_buff *skb,
327 uint16_t type, int hdr_size, char *msg)
328{
329 struct batadv_unicast_4addr_packet *unicast_4addr_packet;
330 struct batadv_bcast_packet *bcast_pkt;
331 uint8_t *orig_addr;
332 __be32 ip_src, ip_dst;
333
334 if (msg)
335 batadv_dbg(BATADV_DBG_DAT, bat_priv, "%s\n", msg);
336
337 ip_src = batadv_arp_ip_src(skb, hdr_size);
338 ip_dst = batadv_arp_ip_dst(skb, hdr_size);
339 batadv_dbg(BATADV_DBG_DAT, bat_priv,
340 "ARP MSG = [src: %pM-%pI4 dst: %pM-%pI4]\n",
341 batadv_arp_hw_src(skb, hdr_size), &ip_src,
342 batadv_arp_hw_dst(skb, hdr_size), &ip_dst);
343
344 if (hdr_size == 0)
345 return;
346
347 /* if the ARP packet is encapsulated in a batman packet, let's print
348 * some debug messages
349 */
350 unicast_4addr_packet = (struct batadv_unicast_4addr_packet *)skb->data;
351
352 switch (unicast_4addr_packet->u.header.packet_type) {
353 case BATADV_UNICAST:
354 batadv_dbg(BATADV_DBG_DAT, bat_priv,
355 "* encapsulated within a UNICAST packet\n");
356 break;
357 case BATADV_UNICAST_4ADDR:
358 batadv_dbg(BATADV_DBG_DAT, bat_priv,
359 "* encapsulated within a UNICAST_4ADDR packet (src: %pM)\n",
360 unicast_4addr_packet->src);
361 switch (unicast_4addr_packet->subtype) {
362 case BATADV_P_DAT_DHT_PUT:
363 batadv_dbg(BATADV_DBG_DAT, bat_priv, "* type: DAT_DHT_PUT\n");
364 break;
365 case BATADV_P_DAT_DHT_GET:
366 batadv_dbg(BATADV_DBG_DAT, bat_priv, "* type: DAT_DHT_GET\n");
367 break;
368 case BATADV_P_DAT_CACHE_REPLY:
369 batadv_dbg(BATADV_DBG_DAT, bat_priv,
370 "* type: DAT_CACHE_REPLY\n");
371 break;
372 case BATADV_P_DATA:
373 batadv_dbg(BATADV_DBG_DAT, bat_priv, "* type: DATA\n");
374 break;
375 default:
376 batadv_dbg(BATADV_DBG_DAT, bat_priv, "* type: Unknown (%u)!\n",
377 unicast_4addr_packet->u.header.packet_type);
378 }
379 break;
380 case BATADV_BCAST:
381 bcast_pkt = (struct batadv_bcast_packet *)unicast_4addr_packet;
382 orig_addr = bcast_pkt->orig;
383 batadv_dbg(BATADV_DBG_DAT, bat_priv,
384 "* encapsulated within a BCAST packet (src: %pM)\n",
385 orig_addr);
386 break;
387 default:
388 batadv_dbg(BATADV_DBG_DAT, bat_priv,
389 "* encapsulated within an unknown packet type (0x%x)\n",
390 unicast_4addr_packet->u.header.packet_type);
391 }
392}
393
394#else
395
396static void batadv_dbg_arp(struct batadv_priv *bat_priv, struct sk_buff *skb,
397 uint16_t type, int hdr_size, char *msg)
398{
399}
400
401#endif /* CONFIG_BATMAN_ADV_DEBUG */
402
403/**
404 * batadv_is_orig_node_eligible - check whether a node can be a DHT candidate
405 * @res: the array with the already selected candidates
406 * @select: number of already selected candidates
407 * @tmp_max: address of the currently evaluated node
408 * @max: current round max address
409 * @last_max: address of the last selected candidate
410 * @candidate: orig_node under evaluation
411 * @max_orig_node: last selected candidate
412 *
413 * Returns true if the node has been elected as next candidate or false othrwise
414 */
415static bool batadv_is_orig_node_eligible(struct batadv_dat_candidate *res,
416 int select, batadv_dat_addr_t tmp_max,
417 batadv_dat_addr_t max,
418 batadv_dat_addr_t last_max,
419 struct batadv_orig_node *candidate,
420 struct batadv_orig_node *max_orig_node)
421{
422 bool ret = false;
423 int j;
424
425 /* Check if this node has already been selected... */
426 for (j = 0; j < select; j++)
427 if (res[j].orig_node == candidate)
428 break;
429 /* ..and possibly skip it */
430 if (j < select)
431 goto out;
432 /* sanity check: has it already been selected? This should not happen */
433 if (tmp_max > last_max)
434 goto out;
435 /* check if during this iteration an originator with a closer dht
436 * address has already been found
437 */
438 if (tmp_max < max)
439 goto out;
440 /* this is an hash collision with the temporary selected node. Choose
441 * the one with the lowest address
442 */
443 if ((tmp_max == max) &&
444 (batadv_compare_eth(candidate->orig, max_orig_node->orig) > 0))
445 goto out;
446
447 ret = true;
448out:
449 return ret;
450}
451
452/**
453 * batadv_choose_next_candidate - select the next DHT candidate
454 * @bat_priv: the bat priv with all the soft interface information
455 * @cands: candidates array
456 * @select: number of candidates already present in the array
457 * @ip_key: key to look up in the DHT
458 * @last_max: pointer where the address of the selected candidate will be saved
459 */
460static void batadv_choose_next_candidate(struct batadv_priv *bat_priv,
461 struct batadv_dat_candidate *cands,
462 int select, batadv_dat_addr_t ip_key,
463 batadv_dat_addr_t *last_max)
464{
465 batadv_dat_addr_t max = 0, tmp_max = 0;
466 struct batadv_orig_node *orig_node, *max_orig_node = NULL;
467 struct batadv_hashtable *hash = bat_priv->orig_hash;
468 struct hlist_node *node;
469 struct hlist_head *head;
470 int i;
471
472 /* if no node is eligible as candidate, leave the candidate type as
473 * NOT_FOUND
474 */
475 cands[select].type = BATADV_DAT_CANDIDATE_NOT_FOUND;
476
477 /* iterate over the originator list and find the node with closest
478 * dat_address which has not been selected yet
479 */
480 for (i = 0; i < hash->size; i++) {
481 head = &hash->table[i];
482
483 rcu_read_lock();
484 hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) {
485 /* the dht space is a ring and addresses are unsigned */
486 tmp_max = BATADV_DAT_ADDR_MAX - orig_node->dat_addr +
487 ip_key;
488
489 if (!batadv_is_orig_node_eligible(cands, select,
490 tmp_max, max,
491 *last_max, orig_node,
492 max_orig_node))
493 continue;
494
495 if (!atomic_inc_not_zero(&orig_node->refcount))
496 continue;
497
498 max = tmp_max;
499 if (max_orig_node)
500 batadv_orig_node_free_ref(max_orig_node);
501 max_orig_node = orig_node;
502 }
503 rcu_read_unlock();
504 }
505 if (max_orig_node) {
506 cands[select].type = BATADV_DAT_CANDIDATE_ORIG;
507 cands[select].orig_node = max_orig_node;
508 batadv_dbg(BATADV_DBG_DAT, bat_priv,
509 "dat_select_candidates() %d: selected %pM addr=%u dist=%u\n",
510 select, max_orig_node->orig, max_orig_node->dat_addr,
511 max);
512 }
513 *last_max = max;
514}
515
516/**
517 * batadv_dat_select_candidates - selects the nodes which the DHT message has to
518 * be sent to
519 * @bat_priv: the bat priv with all the soft interface information
520 * @ip_dst: ipv4 to look up in the DHT
521 *
522 * An originator O is selected if and only if its DHT_ID value is one of three
523 * closest values (from the LEFT, with wrap around if needed) then the hash
524 * value of the key. ip_dst is the key.
525 *
526 * Returns the candidate array of size BATADV_DAT_CANDIDATE_NUM
527 */
528static struct batadv_dat_candidate *
529batadv_dat_select_candidates(struct batadv_priv *bat_priv, __be32 ip_dst)
530{
531 int select;
532 batadv_dat_addr_t last_max = BATADV_DAT_ADDR_MAX, ip_key;
533 struct batadv_dat_candidate *res;
534
535 if (!bat_priv->orig_hash)
536 return NULL;
537
538 res = kmalloc(BATADV_DAT_CANDIDATES_NUM * sizeof(*res), GFP_ATOMIC);
539 if (!res)
540 return NULL;
541
542 ip_key = (batadv_dat_addr_t)batadv_hash_dat(&ip_dst,
543 BATADV_DAT_ADDR_MAX);
544
545 batadv_dbg(BATADV_DBG_DAT, bat_priv,
546 "dat_select_candidates(): IP=%pI4 hash(IP)=%u\n", &ip_dst,
547 ip_key);
548
549 for (select = 0; select < BATADV_DAT_CANDIDATES_NUM; select++)
550 batadv_choose_next_candidate(bat_priv, res, select, ip_key,
551 &last_max);
552
553 return res;
554}
555
556/**
557 * batadv_dat_send_data - send a payload to the selected candidates
558 * @bat_priv: the bat priv with all the soft interface information
559 * @skb: payload to send
560 * @ip: the DHT key
561 * @packet_subtype: unicast4addr packet subtype to use
562 *
563 * In this function the skb is copied by means of pskb_copy() and is sent as
564 * unicast packet to each of the selected candidates
565 *
566 * Returns true if the packet is sent to at least one candidate, false otherwise
567 */
568static bool batadv_dat_send_data(struct batadv_priv *bat_priv,
569 struct sk_buff *skb, __be32 ip,
570 int packet_subtype)
571{
572 int i;
573 bool ret = false;
574 int send_status;
575 struct batadv_neigh_node *neigh_node = NULL;
576 struct sk_buff *tmp_skb;
577 struct batadv_dat_candidate *cand;
578
579 cand = batadv_dat_select_candidates(bat_priv, ip);
580 if (!cand)
581 goto out;
582
583 batadv_dbg(BATADV_DBG_DAT, bat_priv, "DHT_SEND for %pI4\n", &ip);
584
585 for (i = 0; i < BATADV_DAT_CANDIDATES_NUM; i++) {
586 if (cand[i].type == BATADV_DAT_CANDIDATE_NOT_FOUND)
587 continue;
588
589 neigh_node = batadv_orig_node_get_router(cand[i].orig_node);
590 if (!neigh_node)
591 goto free_orig;
592
593 tmp_skb = pskb_copy(skb, GFP_ATOMIC);
594 if (!batadv_unicast_4addr_prepare_skb(bat_priv, tmp_skb,
595 cand[i].orig_node,
596 packet_subtype)) {
597 kfree_skb(tmp_skb);
598 goto free_neigh;
599 }
600
601 send_status = batadv_send_skb_packet(tmp_skb,
602 neigh_node->if_incoming,
603 neigh_node->addr);
604 if (send_status == NET_XMIT_SUCCESS) {
605 /* count the sent packet */
606 switch (packet_subtype) {
607 case BATADV_P_DAT_DHT_GET:
608 batadv_inc_counter(bat_priv,
609 BATADV_CNT_DAT_GET_TX);
610 break;
611 case BATADV_P_DAT_DHT_PUT:
612 batadv_inc_counter(bat_priv,
613 BATADV_CNT_DAT_PUT_TX);
614 break;
615 }
616
617 /* packet sent to a candidate: return true */
618 ret = true;
619 }
620free_neigh:
621 batadv_neigh_node_free_ref(neigh_node);
622free_orig:
623 batadv_orig_node_free_ref(cand[i].orig_node);
624 }
625
626out:
627 kfree(cand);
628 return ret;
629}
630
631/**
632 * batadv_dat_hash_free - free the local DAT hash table
633 * @bat_priv: the bat priv with all the soft interface information
634 */
635static void batadv_dat_hash_free(struct batadv_priv *bat_priv)
636{
637 if (!bat_priv->dat.hash)
638 return;
639
640 __batadv_dat_purge(bat_priv, NULL);
641
642 batadv_hash_destroy(bat_priv->dat.hash);
643
644 bat_priv->dat.hash = NULL;
645}
646
647/**
648 * batadv_dat_init - initialise the DAT internals
649 * @bat_priv: the bat priv with all the soft interface information
650 */
651int batadv_dat_init(struct batadv_priv *bat_priv)
652{
653 if (bat_priv->dat.hash)
654 return 0;
655
656 bat_priv->dat.hash = batadv_hash_new(1024);
657
658 if (!bat_priv->dat.hash)
659 return -ENOMEM;
660
661 batadv_dat_start_timer(bat_priv);
662
663 return 0;
664}
665
666/**
667 * batadv_dat_free - free the DAT internals
668 * @bat_priv: the bat priv with all the soft interface information
669 */
670void batadv_dat_free(struct batadv_priv *bat_priv)
671{
672 cancel_delayed_work_sync(&bat_priv->dat.work);
673
674 batadv_dat_hash_free(bat_priv);
675}
676
677/**
678 * batadv_dat_cache_seq_print_text - print the local DAT hash table
679 * @seq: seq file to print on
680 * @offset: not used
681 */
682int batadv_dat_cache_seq_print_text(struct seq_file *seq, void *offset)
683{
684 struct net_device *net_dev = (struct net_device *)seq->private;
685 struct batadv_priv *bat_priv = netdev_priv(net_dev);
686 struct batadv_hashtable *hash = bat_priv->dat.hash;
687 struct batadv_dat_entry *dat_entry;
688 struct batadv_hard_iface *primary_if;
689 struct hlist_node *node;
690 struct hlist_head *head;
691 unsigned long last_seen_jiffies;
692 int last_seen_msecs, last_seen_secs, last_seen_mins;
693 uint32_t i;
694
695 primary_if = batadv_seq_print_text_primary_if_get(seq);
696 if (!primary_if)
697 goto out;
698
699 seq_printf(seq, "Distributed ARP Table (%s):\n", net_dev->name);
700 seq_printf(seq, " %-7s %-13s %5s\n", "IPv4", "MAC",
701 "last-seen");
702
703 for (i = 0; i < hash->size; i++) {
704 head = &hash->table[i];
705
706 rcu_read_lock();
707 hlist_for_each_entry_rcu(dat_entry, node, head, hash_entry) {
708 last_seen_jiffies = jiffies - dat_entry->last_update;
709 last_seen_msecs = jiffies_to_msecs(last_seen_jiffies);
710 last_seen_mins = last_seen_msecs / 60000;
711 last_seen_msecs = last_seen_msecs % 60000;
712 last_seen_secs = last_seen_msecs / 1000;
713
714 seq_printf(seq, " * %15pI4 %14pM %6i:%02i\n",
715 &dat_entry->ip, dat_entry->mac_addr,
716 last_seen_mins, last_seen_secs);
717 }
718 rcu_read_unlock();
719 }
720
721out:
722 if (primary_if)
723 batadv_hardif_free_ref(primary_if);
724 return 0;
725}
726
727/**
728 * batadv_arp_get_type - parse an ARP packet and gets the type
729 * @bat_priv: the bat priv with all the soft interface information
730 * @skb: packet to analyse
731 * @hdr_size: size of the possible header before the ARP packet in the skb
732 *
733 * Returns the ARP type if the skb contains a valid ARP packet, 0 otherwise
734 */
735static uint16_t batadv_arp_get_type(struct batadv_priv *bat_priv,
736 struct sk_buff *skb, int hdr_size)
737{
738 struct arphdr *arphdr;
739 struct ethhdr *ethhdr;
740 __be32 ip_src, ip_dst;
741 uint16_t type = 0;
742
743 /* pull the ethernet header */
744 if (unlikely(!pskb_may_pull(skb, hdr_size + ETH_HLEN)))
745 goto out;
746
747 ethhdr = (struct ethhdr *)(skb->data + hdr_size);
748
749 if (ethhdr->h_proto != htons(ETH_P_ARP))
750 goto out;
751
752 /* pull the ARP payload */
753 if (unlikely(!pskb_may_pull(skb, hdr_size + ETH_HLEN +
754 arp_hdr_len(skb->dev))))
755 goto out;
756
757 arphdr = (struct arphdr *)(skb->data + hdr_size + ETH_HLEN);
758
759 /* Check whether the ARP packet carries a valid
760 * IP information
761 */
762 if (arphdr->ar_hrd != htons(ARPHRD_ETHER))
763 goto out;
764
765 if (arphdr->ar_pro != htons(ETH_P_IP))
766 goto out;
767
768 if (arphdr->ar_hln != ETH_ALEN)
769 goto out;
770
771 if (arphdr->ar_pln != 4)
772 goto out;
773
774 /* Check for bad reply/request. If the ARP message is not sane, DAT
775 * will simply ignore it
776 */
777 ip_src = batadv_arp_ip_src(skb, hdr_size);
778 ip_dst = batadv_arp_ip_dst(skb, hdr_size);
779 if (ipv4_is_loopback(ip_src) || ipv4_is_multicast(ip_src) ||
780 ipv4_is_loopback(ip_dst) || ipv4_is_multicast(ip_dst))
781 goto out;
782
783 type = ntohs(arphdr->ar_op);
784out:
785 return type;
786}
787
788/**
789 * batadv_dat_snoop_outgoing_arp_request - snoop the ARP request and try to
790 * answer using DAT
791 * @bat_priv: the bat priv with all the soft interface information
792 * @skb: packet to check
793 *
794 * Returns true if the message has been sent to the dht candidates, false
795 * otherwise. In case of true the message has to be enqueued to permit the
796 * fallback
797 */
798bool batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv,
799 struct sk_buff *skb)
800{
801 uint16_t type = 0;
802 __be32 ip_dst, ip_src;
803 uint8_t *hw_src;
804 bool ret = false;
805 struct batadv_dat_entry *dat_entry = NULL;
806 struct sk_buff *skb_new;
807 struct batadv_hard_iface *primary_if = NULL;
808
809 if (!atomic_read(&bat_priv->distributed_arp_table))
810 goto out;
811
812 type = batadv_arp_get_type(bat_priv, skb, 0);
813 /* If the node gets an ARP_REQUEST it has to send a DHT_GET unicast
814 * message to the selected DHT candidates
815 */
816 if (type != ARPOP_REQUEST)
817 goto out;
818
819 batadv_dbg_arp(bat_priv, skb, type, 0, "Parsing outgoing ARP REQUEST");
820
821 ip_src = batadv_arp_ip_src(skb, 0);
822 hw_src = batadv_arp_hw_src(skb, 0);
823 ip_dst = batadv_arp_ip_dst(skb, 0);
824
825 batadv_dat_entry_add(bat_priv, ip_src, hw_src);
826
827 dat_entry = batadv_dat_entry_hash_find(bat_priv, ip_dst);
828 if (dat_entry) {
829 primary_if = batadv_primary_if_get_selected(bat_priv);
830 if (!primary_if)
831 goto out;
832
833 skb_new = arp_create(ARPOP_REPLY, ETH_P_ARP, ip_src,
834 primary_if->soft_iface, ip_dst, hw_src,
835 dat_entry->mac_addr, hw_src);
836 if (!skb_new)
837 goto out;
838
839 skb_reset_mac_header(skb_new);
840 skb_new->protocol = eth_type_trans(skb_new,
841 primary_if->soft_iface);
842 bat_priv->stats.rx_packets++;
843 bat_priv->stats.rx_bytes += skb->len + ETH_HLEN;
844 primary_if->soft_iface->last_rx = jiffies;
845
846 netif_rx(skb_new);
847 batadv_dbg(BATADV_DBG_DAT, bat_priv, "ARP request replied locally\n");
848 ret = true;
849 } else {
850 /* Send the request on the DHT */
851 ret = batadv_dat_send_data(bat_priv, skb, ip_dst,
852 BATADV_P_DAT_DHT_GET);
853 }
854out:
855 if (dat_entry)
856 batadv_dat_entry_free_ref(dat_entry);
857 if (primary_if)
858 batadv_hardif_free_ref(primary_if);
859 return ret;
860}
861
862/**
863 * batadv_dat_snoop_incoming_arp_request - snoop the ARP request and try to
864 * answer using the local DAT storage
865 * @bat_priv: the bat priv with all the soft interface information
866 * @skb: packet to check
867 * @hdr_size: size of the encapsulation header
868 *
869 * Returns true if the request has been answered, false otherwise
870 */
871bool batadv_dat_snoop_incoming_arp_request(struct batadv_priv *bat_priv,
872 struct sk_buff *skb, int hdr_size)
873{
874 uint16_t type;
875 __be32 ip_src, ip_dst;
876 uint8_t *hw_src;
877 struct sk_buff *skb_new;
878 struct batadv_hard_iface *primary_if = NULL;
879 struct batadv_dat_entry *dat_entry = NULL;
880 bool ret = false;
881 int err;
882
883 if (!atomic_read(&bat_priv->distributed_arp_table))
884 goto out;
885
886 type = batadv_arp_get_type(bat_priv, skb, hdr_size);
887 if (type != ARPOP_REQUEST)
888 goto out;
889
890 hw_src = batadv_arp_hw_src(skb, hdr_size);
891 ip_src = batadv_arp_ip_src(skb, hdr_size);
892 ip_dst = batadv_arp_ip_dst(skb, hdr_size);
893
894 batadv_dbg_arp(bat_priv, skb, type, hdr_size,
895 "Parsing incoming ARP REQUEST");
896
897 batadv_dat_entry_add(bat_priv, ip_src, hw_src);
898
899 dat_entry = batadv_dat_entry_hash_find(bat_priv, ip_dst);
900 if (!dat_entry)
901 goto out;
902
903 primary_if = batadv_primary_if_get_selected(bat_priv);
904 if (!primary_if)
905 goto out;
906
907 skb_new = arp_create(ARPOP_REPLY, ETH_P_ARP, ip_src,
908 primary_if->soft_iface, ip_dst, hw_src,
909 dat_entry->mac_addr, hw_src);
910
911 if (!skb_new)
912 goto out;
913
914 /* to preserve backwards compatibility, here the node has to answer
915 * using the same packet type it received for the request. This is due
916 * to that if a node is not using the 4addr packet format it may not
917 * support it.
918 */
919 if (hdr_size == sizeof(struct batadv_unicast_4addr_packet))
920 err = batadv_unicast_4addr_send_skb(bat_priv, skb_new,
921 BATADV_P_DAT_CACHE_REPLY);
922 else
923 err = batadv_unicast_send_skb(bat_priv, skb_new);
924
925 if (!err) {
926 batadv_inc_counter(bat_priv, BATADV_CNT_DAT_CACHED_REPLY_TX);
927 ret = true;
928 }
929out:
930 if (dat_entry)
931 batadv_dat_entry_free_ref(dat_entry);
932 if (primary_if)
933 batadv_hardif_free_ref(primary_if);
934 if (ret)
935 kfree_skb(skb);
936 return ret;
937}
938
939/**
940 * batadv_dat_snoop_outgoing_arp_reply - snoop the ARP reply and fill the DHT
941 * @bat_priv: the bat priv with all the soft interface information
942 * @skb: packet to check
943 */
944void batadv_dat_snoop_outgoing_arp_reply(struct batadv_priv *bat_priv,
945 struct sk_buff *skb)
946{
947 uint16_t type;
948 __be32 ip_src, ip_dst;
949 uint8_t *hw_src, *hw_dst;
950
951 if (!atomic_read(&bat_priv->distributed_arp_table))
952 return;
953
954 type = batadv_arp_get_type(bat_priv, skb, 0);
955 if (type != ARPOP_REPLY)
956 return;
957
958 batadv_dbg_arp(bat_priv, skb, type, 0, "Parsing outgoing ARP REPLY");
959
960 hw_src = batadv_arp_hw_src(skb, 0);
961 ip_src = batadv_arp_ip_src(skb, 0);
962 hw_dst = batadv_arp_hw_dst(skb, 0);
963 ip_dst = batadv_arp_ip_dst(skb, 0);
964
965 batadv_dat_entry_add(bat_priv, ip_src, hw_src);
966 batadv_dat_entry_add(bat_priv, ip_dst, hw_dst);
967
968 /* Send the ARP reply to the candidates for both the IP addresses that
969 * the node got within the ARP reply
970 */
971 batadv_dat_send_data(bat_priv, skb, ip_src, BATADV_P_DAT_DHT_PUT);
972 batadv_dat_send_data(bat_priv, skb, ip_dst, BATADV_P_DAT_DHT_PUT);
973}
974/**
975 * batadv_dat_snoop_incoming_arp_reply - snoop the ARP reply and fill the local
976 * DAT storage only
977 * @bat_priv: the bat priv with all the soft interface information
978 * @skb: packet to check
979 * @hdr_size: siaze of the encapsulation header
980 */
981bool batadv_dat_snoop_incoming_arp_reply(struct batadv_priv *bat_priv,
982 struct sk_buff *skb, int hdr_size)
983{
984 uint16_t type;
985 __be32 ip_src, ip_dst;
986 uint8_t *hw_src, *hw_dst;
987 bool ret = false;
988
989 if (!atomic_read(&bat_priv->distributed_arp_table))
990 goto out;
991
992 type = batadv_arp_get_type(bat_priv, skb, hdr_size);
993 if (type != ARPOP_REPLY)
994 goto out;
995
996 batadv_dbg_arp(bat_priv, skb, type, hdr_size,
997 "Parsing incoming ARP REPLY");
998
999 hw_src = batadv_arp_hw_src(skb, hdr_size);
1000 ip_src = batadv_arp_ip_src(skb, hdr_size);
1001 hw_dst = batadv_arp_hw_dst(skb, hdr_size);
1002 ip_dst = batadv_arp_ip_dst(skb, hdr_size);
1003
1004 /* Update our internal cache with both the IP addresses the node got
1005 * within the ARP reply
1006 */
1007 batadv_dat_entry_add(bat_priv, ip_src, hw_src);
1008 batadv_dat_entry_add(bat_priv, ip_dst, hw_dst);
1009
1010 /* if this REPLY is directed to a client of mine, let's deliver the
1011 * packet to the interface
1012 */
1013 ret = !batadv_is_my_client(bat_priv, hw_dst);
1014out:
1015 /* if ret == false -> packet has to be delivered to the interface */
1016 return ret;
1017}
1018
1019/**
1020 * batadv_dat_drop_broadcast_packet - check if an ARP request has to be dropped
1021 * (because the node has already got the reply via DAT) or not
1022 * @bat_priv: the bat priv with all the soft interface information
1023 * @forw_packet: the broadcast packet
1024 *
1025 * Returns true if the node can drop the packet, false otherwise
1026 */
1027bool batadv_dat_drop_broadcast_packet(struct batadv_priv *bat_priv,
1028 struct batadv_forw_packet *forw_packet)
1029{
1030 uint16_t type;
1031 __be32 ip_dst;
1032 struct batadv_dat_entry *dat_entry = NULL;
1033 bool ret = false;
1034 const size_t bcast_len = sizeof(struct batadv_bcast_packet);
1035
1036 if (!atomic_read(&bat_priv->distributed_arp_table))
1037 goto out;
1038
1039 /* If this packet is an ARP_REQUEST and the node already has the
1040 * information that it is going to ask, then the packet can be dropped
1041 */
1042 if (forw_packet->num_packets)
1043 goto out;
1044
1045 type = batadv_arp_get_type(bat_priv, forw_packet->skb, bcast_len);
1046 if (type != ARPOP_REQUEST)
1047 goto out;
1048
1049 ip_dst = batadv_arp_ip_dst(forw_packet->skb, bcast_len);
1050 dat_entry = batadv_dat_entry_hash_find(bat_priv, ip_dst);
1051 /* check if the node already got this entry */
1052 if (!dat_entry) {
1053 batadv_dbg(BATADV_DBG_DAT, bat_priv,
1054 "ARP Request for %pI4: fallback\n", &ip_dst);
1055 goto out;
1056 }
1057
1058 batadv_dbg(BATADV_DBG_DAT, bat_priv,
1059 "ARP Request for %pI4: fallback prevented\n", &ip_dst);
1060 ret = true;
1061
1062out:
1063 if (dat_entry)
1064 batadv_dat_entry_free_ref(dat_entry);
1065 return ret;
1066}
diff --git a/net/batman-adv/distributed-arp-table.h b/net/batman-adv/distributed-arp-table.h
new file mode 100644
index 000000000000..d060c033e7de
--- /dev/null
+++ b/net/batman-adv/distributed-arp-table.h
@@ -0,0 +1,167 @@
1/* Copyright (C) 2011-2012 B.A.T.M.A.N. contributors:
2 *
3 * Antonio Quartulli
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of version 2 of the GNU General Public
7 * License as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA
18 */
19
20#ifndef _NET_BATMAN_ADV_ARP_H_
21#define _NET_BATMAN_ADV_ARP_H_
22
23#ifdef CONFIG_BATMAN_ADV_DAT
24
25#include "types.h"
26#include "originator.h"
27
28#include <linux/if_arp.h>
29
30#define BATADV_DAT_ADDR_MAX ((batadv_dat_addr_t)~(batadv_dat_addr_t)0)
31
32bool batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv,
33 struct sk_buff *skb);
34bool batadv_dat_snoop_incoming_arp_request(struct batadv_priv *bat_priv,
35 struct sk_buff *skb, int hdr_size);
36void batadv_dat_snoop_outgoing_arp_reply(struct batadv_priv *bat_priv,
37 struct sk_buff *skb);
38bool batadv_dat_snoop_incoming_arp_reply(struct batadv_priv *bat_priv,
39 struct sk_buff *skb, int hdr_size);
40bool batadv_dat_drop_broadcast_packet(struct batadv_priv *bat_priv,
41 struct batadv_forw_packet *forw_packet);
42
43/**
44 * batadv_dat_init_orig_node_addr - assign a DAT address to the orig_node
45 * @orig_node: the node to assign the DAT address to
46 */
47static inline void
48batadv_dat_init_orig_node_addr(struct batadv_orig_node *orig_node)
49{
50 uint32_t addr;
51
52 addr = batadv_choose_orig(orig_node->orig, BATADV_DAT_ADDR_MAX);
53 orig_node->dat_addr = (batadv_dat_addr_t)addr;
54}
55
56/**
57 * batadv_dat_init_own_addr - assign a DAT address to the node itself
58 * @bat_priv: the bat priv with all the soft interface information
59 * @primary_if: a pointer to the primary interface
60 */
61static inline void
62batadv_dat_init_own_addr(struct batadv_priv *bat_priv,
63 struct batadv_hard_iface *primary_if)
64{
65 uint32_t addr;
66
67 addr = batadv_choose_orig(primary_if->net_dev->dev_addr,
68 BATADV_DAT_ADDR_MAX);
69
70 bat_priv->dat.addr = (batadv_dat_addr_t)addr;
71}
72
73int batadv_dat_init(struct batadv_priv *bat_priv);
74void batadv_dat_free(struct batadv_priv *bat_priv);
75int batadv_dat_cache_seq_print_text(struct seq_file *seq, void *offset);
76
77/**
78 * batadv_dat_inc_counter - increment the correct DAT packet counter
79 * @bat_priv: the bat priv with all the soft interface information
80 * @subtype: the 4addr subtype of the packet to be counted
81 *
82 * Updates the ethtool statistics for the received packet if it is a DAT subtype
83 */
84static inline void batadv_dat_inc_counter(struct batadv_priv *bat_priv,
85 uint8_t subtype)
86{
87 switch (subtype) {
88 case BATADV_P_DAT_DHT_GET:
89 batadv_inc_counter(bat_priv,
90 BATADV_CNT_DAT_GET_RX);
91 break;
92 case BATADV_P_DAT_DHT_PUT:
93 batadv_inc_counter(bat_priv,
94 BATADV_CNT_DAT_PUT_RX);
95 break;
96 }
97}
98
99#else
100
101static inline bool
102batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv,
103 struct sk_buff *skb)
104{
105 return false;
106}
107
108static inline bool
109batadv_dat_snoop_incoming_arp_request(struct batadv_priv *bat_priv,
110 struct sk_buff *skb, int hdr_size)
111{
112 return false;
113}
114
115static inline bool
116batadv_dat_snoop_outgoing_arp_reply(struct batadv_priv *bat_priv,
117 struct sk_buff *skb)
118{
119 return false;
120}
121
122static inline bool
123batadv_dat_snoop_incoming_arp_reply(struct batadv_priv *bat_priv,
124 struct sk_buff *skb, int hdr_size)
125{
126 return false;
127}
128
129static inline bool
130batadv_dat_drop_broadcast_packet(struct batadv_priv *bat_priv,
131 struct batadv_forw_packet *forw_packet)
132{
133 return false;
134}
135
136static inline void
137batadv_dat_init_orig_node_addr(struct batadv_orig_node *orig_node)
138{
139}
140
141static inline void batadv_dat_init_own_addr(struct batadv_priv *bat_priv,
142 struct batadv_hard_iface *iface)
143{
144}
145
146static inline void batadv_arp_change_timeout(struct net_device *soft_iface,
147 const char *name)
148{
149}
150
151static inline int batadv_dat_init(struct batadv_priv *bat_priv)
152{
153 return 0;
154}
155
156static inline void batadv_dat_free(struct batadv_priv *bat_priv)
157{
158}
159
160static inline void batadv_dat_inc_counter(struct batadv_priv *bat_priv,
161 uint8_t subtype)
162{
163}
164
165#endif /* CONFIG_BATMAN_ADV_DAT */
166
167#endif /* _NET_BATMAN_ADV_ARP_H_ */
diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c
index 15d67abc10a4..dd07c7e3654f 100644
--- a/net/batman-adv/gateway_client.c
+++ b/net/batman-adv/gateway_client.c
@@ -477,22 +477,11 @@ int batadv_gw_client_seq_print_text(struct seq_file *seq, void *offset)
477 struct batadv_hard_iface *primary_if; 477 struct batadv_hard_iface *primary_if;
478 struct batadv_gw_node *gw_node; 478 struct batadv_gw_node *gw_node;
479 struct hlist_node *node; 479 struct hlist_node *node;
480 int gw_count = 0, ret = 0; 480 int gw_count = 0;
481 481
482 primary_if = batadv_primary_if_get_selected(bat_priv); 482 primary_if = batadv_seq_print_text_primary_if_get(seq);
483 if (!primary_if) { 483 if (!primary_if)
484 ret = seq_printf(seq,
485 "BATMAN mesh %s disabled - please specify interfaces to enable it\n",
486 net_dev->name);
487 goto out; 484 goto out;
488 }
489
490 if (primary_if->if_status != BATADV_IF_ACTIVE) {
491 ret = seq_printf(seq,
492 "BATMAN mesh %s disabled - primary interface not active\n",
493 net_dev->name);
494 goto out;
495 }
496 485
497 seq_printf(seq, 486 seq_printf(seq,
498 " %-12s (%s/%i) %17s [%10s]: gw_class ... [B.A.T.M.A.N. adv %s, MainIF/MAC: %s/%pM (%s)]\n", 487 " %-12s (%s/%i) %17s [%10s]: gw_class ... [B.A.T.M.A.N. adv %s, MainIF/MAC: %s/%pM (%s)]\n",
@@ -519,7 +508,7 @@ int batadv_gw_client_seq_print_text(struct seq_file *seq, void *offset)
519out: 508out:
520 if (primary_if) 509 if (primary_if)
521 batadv_hardif_free_ref(primary_if); 510 batadv_hardif_free_ref(primary_if);
522 return ret; 511 return 0;
523} 512}
524 513
525static bool batadv_is_type_dhcprequest(struct sk_buff *skb, int header_len) 514static bool batadv_is_type_dhcprequest(struct sk_buff *skb, int header_len)
diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c
index d112fd6750b0..365ed74f3946 100644
--- a/net/batman-adv/hard-interface.c
+++ b/net/batman-adv/hard-interface.c
@@ -18,6 +18,7 @@
18 */ 18 */
19 19
20#include "main.h" 20#include "main.h"
21#include "distributed-arp-table.h"
21#include "hard-interface.h" 22#include "hard-interface.h"
22#include "soft-interface.h" 23#include "soft-interface.h"
23#include "send.h" 24#include "send.h"
@@ -58,6 +59,45 @@ out:
58 return hard_iface; 59 return hard_iface;
59} 60}
60 61
62/**
63 * batadv_is_on_batman_iface - check if a device is a batman iface descendant
64 * @net_dev: the device to check
65 *
66 * If the user creates any virtual device on top of a batman-adv interface, it
67 * is important to prevent this new interface to be used to create a new mesh
68 * network (this behaviour would lead to a batman-over-batman configuration).
69 * This function recursively checks all the fathers of the device passed as
70 * argument looking for a batman-adv soft interface.
71 *
72 * Returns true if the device is descendant of a batman-adv mesh interface (or
73 * if it is a batman-adv interface itself), false otherwise
74 */
75static bool batadv_is_on_batman_iface(const struct net_device *net_dev)
76{
77 struct net_device *parent_dev;
78 bool ret;
79
80 /* check if this is a batman-adv mesh interface */
81 if (batadv_softif_is_valid(net_dev))
82 return true;
83
84 /* no more parents..stop recursion */
85 if (net_dev->iflink == net_dev->ifindex)
86 return false;
87
88 /* recurse over the parent device */
89 parent_dev = dev_get_by_index(&init_net, net_dev->iflink);
90 /* if we got a NULL parent_dev there is something broken.. */
91 if (WARN(!parent_dev, "Cannot find parent device"))
92 return false;
93
94 ret = batadv_is_on_batman_iface(parent_dev);
95
96 if (parent_dev)
97 dev_put(parent_dev);
98 return ret;
99}
100
61static int batadv_is_valid_iface(const struct net_device *net_dev) 101static int batadv_is_valid_iface(const struct net_device *net_dev)
62{ 102{
63 if (net_dev->flags & IFF_LOOPBACK) 103 if (net_dev->flags & IFF_LOOPBACK)
@@ -70,7 +110,7 @@ static int batadv_is_valid_iface(const struct net_device *net_dev)
70 return 0; 110 return 0;
71 111
72 /* no batman over batman */ 112 /* no batman over batman */
73 if (batadv_softif_is_valid(net_dev)) 113 if (batadv_is_on_batman_iface(net_dev))
74 return 0; 114 return 0;
75 115
76 return 1; 116 return 1;
@@ -109,6 +149,8 @@ static void batadv_primary_if_update_addr(struct batadv_priv *bat_priv,
109 if (!primary_if) 149 if (!primary_if)
110 goto out; 150 goto out;
111 151
152 batadv_dat_init_own_addr(bat_priv, primary_if);
153
112 skb = bat_priv->vis.my_info->skb_packet; 154 skb = bat_priv->vis.my_info->skb_packet;
113 vis_packet = (struct batadv_vis_packet *)skb->data; 155 vis_packet = (struct batadv_vis_packet *)skb->data;
114 memcpy(vis_packet->vis_orig, primary_if->net_dev->dev_addr, ETH_ALEN); 156 memcpy(vis_packet->vis_orig, primary_if->net_dev->dev_addr, ETH_ALEN);
@@ -450,8 +492,8 @@ batadv_hardif_add_interface(struct net_device *net_dev)
450 /* This can't be called via a bat_priv callback because 492 /* This can't be called via a bat_priv callback because
451 * we have no bat_priv yet. 493 * we have no bat_priv yet.
452 */ 494 */
453 atomic_set(&hard_iface->seqno, 1); 495 atomic_set(&hard_iface->bat_iv.ogm_seqno, 1);
454 hard_iface->packet_buff = NULL; 496 hard_iface->bat_iv.ogm_buff = NULL;
455 497
456 return hard_iface; 498 return hard_iface;
457 499
diff --git a/net/batman-adv/hash.h b/net/batman-adv/hash.h
index 977de9c75fc2..e05333905afd 100644
--- a/net/batman-adv/hash.h
+++ b/net/batman-adv/hash.h
@@ -82,6 +82,28 @@ static inline void batadv_hash_delete(struct batadv_hashtable *hash,
82} 82}
83 83
84/** 84/**
85 * batadv_hash_bytes - hash some bytes and add them to the previous hash
86 * @hash: previous hash value
87 * @data: data to be hashed
88 * @size: number of bytes to be hashed
89 *
90 * Returns the new hash value.
91 */
92static inline uint32_t batadv_hash_bytes(uint32_t hash, void *data,
93 uint32_t size)
94{
95 const unsigned char *key = data;
96 int i;
97
98 for (i = 0; i < size; i++) {
99 hash += key[i];
100 hash += (hash << 10);
101 hash ^= (hash >> 6);
102 }
103 return hash;
104}
105
106/**
85 * batadv_hash_add - adds data to the hashtable 107 * batadv_hash_add - adds data to the hashtable
86 * @hash: storage hash table 108 * @hash: storage hash table
87 * @compare: callback to determine if 2 hash elements are identical 109 * @compare: callback to determine if 2 hash elements are identical
diff --git a/net/batman-adv/icmp_socket.c b/net/batman-adv/icmp_socket.c
index bde3cf747507..87ca8095b011 100644
--- a/net/batman-adv/icmp_socket.c
+++ b/net/batman-adv/icmp_socket.c
@@ -42,12 +42,16 @@ static int batadv_socket_open(struct inode *inode, struct file *file)
42 unsigned int i; 42 unsigned int i;
43 struct batadv_socket_client *socket_client; 43 struct batadv_socket_client *socket_client;
44 44
45 if (!try_module_get(THIS_MODULE))
46 return -EBUSY;
47
45 nonseekable_open(inode, file); 48 nonseekable_open(inode, file);
46 49
47 socket_client = kmalloc(sizeof(*socket_client), GFP_KERNEL); 50 socket_client = kmalloc(sizeof(*socket_client), GFP_KERNEL);
48 51 if (!socket_client) {
49 if (!socket_client) 52 module_put(THIS_MODULE);
50 return -ENOMEM; 53 return -ENOMEM;
54 }
51 55
52 for (i = 0; i < ARRAY_SIZE(batadv_socket_client_hash); i++) { 56 for (i = 0; i < ARRAY_SIZE(batadv_socket_client_hash); i++) {
53 if (!batadv_socket_client_hash[i]) { 57 if (!batadv_socket_client_hash[i]) {
@@ -59,6 +63,7 @@ static int batadv_socket_open(struct inode *inode, struct file *file)
59 if (i == ARRAY_SIZE(batadv_socket_client_hash)) { 63 if (i == ARRAY_SIZE(batadv_socket_client_hash)) {
60 pr_err("Error - can't add another packet client: maximum number of clients reached\n"); 64 pr_err("Error - can't add another packet client: maximum number of clients reached\n");
61 kfree(socket_client); 65 kfree(socket_client);
66 module_put(THIS_MODULE);
62 return -EXFULL; 67 return -EXFULL;
63 } 68 }
64 69
@@ -71,7 +76,6 @@ static int batadv_socket_open(struct inode *inode, struct file *file)
71 76
72 file->private_data = socket_client; 77 file->private_data = socket_client;
73 78
74 batadv_inc_module_count();
75 return 0; 79 return 0;
76} 80}
77 81
@@ -96,7 +100,7 @@ static int batadv_socket_release(struct inode *inode, struct file *file)
96 spin_unlock_bh(&socket_client->lock); 100 spin_unlock_bh(&socket_client->lock);
97 101
98 kfree(socket_client); 102 kfree(socket_client);
99 batadv_dec_module_count(); 103 module_put(THIS_MODULE);
100 104
101 return 0; 105 return 0;
102} 106}
@@ -173,13 +177,13 @@ static ssize_t batadv_socket_write(struct file *file, const char __user *buff,
173 if (len >= sizeof(struct batadv_icmp_packet_rr)) 177 if (len >= sizeof(struct batadv_icmp_packet_rr))
174 packet_len = sizeof(struct batadv_icmp_packet_rr); 178 packet_len = sizeof(struct batadv_icmp_packet_rr);
175 179
176 skb = dev_alloc_skb(packet_len + ETH_HLEN); 180 skb = dev_alloc_skb(packet_len + ETH_HLEN + NET_IP_ALIGN);
177 if (!skb) { 181 if (!skb) {
178 len = -ENOMEM; 182 len = -ENOMEM;
179 goto out; 183 goto out;
180 } 184 }
181 185
182 skb_reserve(skb, ETH_HLEN); 186 skb_reserve(skb, ETH_HLEN + NET_IP_ALIGN);
183 icmp_packet = (struct batadv_icmp_packet_rr *)skb_put(skb, packet_len); 187 icmp_packet = (struct batadv_icmp_packet_rr *)skb_put(skb, packet_len);
184 188
185 if (copy_from_user(icmp_packet, buff, packet_len)) { 189 if (copy_from_user(icmp_packet, buff, packet_len)) {
diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c
index b4aa470bc4a6..dc33a0c484a4 100644
--- a/net/batman-adv/main.c
+++ b/net/batman-adv/main.c
@@ -29,6 +29,7 @@
29#include "hard-interface.h" 29#include "hard-interface.h"
30#include "gateway_client.h" 30#include "gateway_client.h"
31#include "bridge_loop_avoidance.h" 31#include "bridge_loop_avoidance.h"
32#include "distributed-arp-table.h"
32#include "vis.h" 33#include "vis.h"
33#include "hash.h" 34#include "hash.h"
34#include "bat_algo.h" 35#include "bat_algo.h"
@@ -128,6 +129,10 @@ int batadv_mesh_init(struct net_device *soft_iface)
128 if (ret < 0) 129 if (ret < 0)
129 goto err; 130 goto err;
130 131
132 ret = batadv_dat_init(bat_priv);
133 if (ret < 0)
134 goto err;
135
131 atomic_set(&bat_priv->gw.reselect, 0); 136 atomic_set(&bat_priv->gw.reselect, 0);
132 atomic_set(&bat_priv->mesh_state, BATADV_MESH_ACTIVE); 137 atomic_set(&bat_priv->mesh_state, BATADV_MESH_ACTIVE);
133 138
@@ -155,21 +160,13 @@ void batadv_mesh_free(struct net_device *soft_iface)
155 160
156 batadv_bla_free(bat_priv); 161 batadv_bla_free(bat_priv);
157 162
163 batadv_dat_free(bat_priv);
164
158 free_percpu(bat_priv->bat_counters); 165 free_percpu(bat_priv->bat_counters);
159 166
160 atomic_set(&bat_priv->mesh_state, BATADV_MESH_INACTIVE); 167 atomic_set(&bat_priv->mesh_state, BATADV_MESH_INACTIVE);
161} 168}
162 169
163void batadv_inc_module_count(void)
164{
165 try_module_get(THIS_MODULE);
166}
167
168void batadv_dec_module_count(void)
169{
170 module_put(THIS_MODULE);
171}
172
173int batadv_is_my_mac(const uint8_t *addr) 170int batadv_is_my_mac(const uint8_t *addr)
174{ 171{
175 const struct batadv_hard_iface *hard_iface; 172 const struct batadv_hard_iface *hard_iface;
@@ -188,6 +185,42 @@ int batadv_is_my_mac(const uint8_t *addr)
188 return 0; 185 return 0;
189} 186}
190 187
188/**
189 * batadv_seq_print_text_primary_if_get - called from debugfs table printing
190 * function that requires the primary interface
191 * @seq: debugfs table seq_file struct
192 *
193 * Returns primary interface if found or NULL otherwise.
194 */
195struct batadv_hard_iface *
196batadv_seq_print_text_primary_if_get(struct seq_file *seq)
197{
198 struct net_device *net_dev = (struct net_device *)seq->private;
199 struct batadv_priv *bat_priv = netdev_priv(net_dev);
200 struct batadv_hard_iface *primary_if;
201
202 primary_if = batadv_primary_if_get_selected(bat_priv);
203
204 if (!primary_if) {
205 seq_printf(seq,
206 "BATMAN mesh %s disabled - please specify interfaces to enable it\n",
207 net_dev->name);
208 goto out;
209 }
210
211 if (primary_if->if_status == BATADV_IF_ACTIVE)
212 goto out;
213
214 seq_printf(seq,
215 "BATMAN mesh %s disabled - primary interface not active\n",
216 net_dev->name);
217 batadv_hardif_free_ref(primary_if);
218 primary_if = NULL;
219
220out:
221 return primary_if;
222}
223
191static int batadv_recv_unhandled_packet(struct sk_buff *skb, 224static int batadv_recv_unhandled_packet(struct sk_buff *skb,
192 struct batadv_hard_iface *recv_if) 225 struct batadv_hard_iface *recv_if)
193{ 226{
@@ -274,6 +307,8 @@ static void batadv_recv_handler_init(void)
274 307
275 /* batman icmp packet */ 308 /* batman icmp packet */
276 batadv_rx_handler[BATADV_ICMP] = batadv_recv_icmp_packet; 309 batadv_rx_handler[BATADV_ICMP] = batadv_recv_icmp_packet;
310 /* unicast with 4 addresses packet */
311 batadv_rx_handler[BATADV_UNICAST_4ADDR] = batadv_recv_unicast_packet;
277 /* unicast packet */ 312 /* unicast packet */
278 batadv_rx_handler[BATADV_UNICAST] = batadv_recv_unicast_packet; 313 batadv_rx_handler[BATADV_UNICAST] = batadv_recv_unicast_packet;
279 /* fragmented unicast packet */ 314 /* fragmented unicast packet */
diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h
index d57b746219de..8f149bb66817 100644
--- a/net/batman-adv/main.h
+++ b/net/batman-adv/main.h
@@ -44,6 +44,7 @@
44#define BATADV_TT_LOCAL_TIMEOUT 3600000 /* in milliseconds */ 44#define BATADV_TT_LOCAL_TIMEOUT 3600000 /* in milliseconds */
45#define BATADV_TT_CLIENT_ROAM_TIMEOUT 600000 /* in milliseconds */ 45#define BATADV_TT_CLIENT_ROAM_TIMEOUT 600000 /* in milliseconds */
46#define BATADV_TT_CLIENT_TEMP_TIMEOUT 600000 /* in milliseconds */ 46#define BATADV_TT_CLIENT_TEMP_TIMEOUT 600000 /* in milliseconds */
47#define BATADV_DAT_ENTRY_TIMEOUT (5*60000) /* 5 mins in milliseconds */
47/* sliding packet range of received originator messages in sequence numbers 48/* sliding packet range of received originator messages in sequence numbers
48 * (should be a multiple of our word size) 49 * (should be a multiple of our word size)
49 */ 50 */
@@ -73,6 +74,11 @@
73 74
74#define BATADV_LOG_BUF_LEN 8192 /* has to be a power of 2 */ 75#define BATADV_LOG_BUF_LEN 8192 /* has to be a power of 2 */
75 76
77/* msecs after which an ARP_REQUEST is sent in broadcast as fallback */
78#define ARP_REQ_DELAY 250
79/* numbers of originator to contact for any PUT/GET DHT operation */
80#define BATADV_DAT_CANDIDATES_NUM 3
81
76#define BATADV_VIS_INTERVAL 5000 /* 5 seconds */ 82#define BATADV_VIS_INTERVAL 5000 /* 5 seconds */
77 83
78/* how much worse secondary interfaces may be to be considered as bonding 84/* how much worse secondary interfaces may be to be considered as bonding
@@ -89,6 +95,7 @@
89#define BATADV_BLA_PERIOD_LENGTH 10000 /* 10 seconds */ 95#define BATADV_BLA_PERIOD_LENGTH 10000 /* 10 seconds */
90#define BATADV_BLA_BACKBONE_TIMEOUT (BATADV_BLA_PERIOD_LENGTH * 3) 96#define BATADV_BLA_BACKBONE_TIMEOUT (BATADV_BLA_PERIOD_LENGTH * 3)
91#define BATADV_BLA_CLAIM_TIMEOUT (BATADV_BLA_PERIOD_LENGTH * 10) 97#define BATADV_BLA_CLAIM_TIMEOUT (BATADV_BLA_PERIOD_LENGTH * 10)
98#define BATADV_BLA_WAIT_PERIODS 3
92 99
93#define BATADV_DUPLIST_SIZE 16 100#define BATADV_DUPLIST_SIZE 16
94#define BATADV_DUPLIST_TIMEOUT 500 /* 500 ms */ 101#define BATADV_DUPLIST_TIMEOUT 500 /* 500 ms */
@@ -117,6 +124,9 @@ enum batadv_uev_type {
117 124
118#define BATADV_GW_THRESHOLD 50 125#define BATADV_GW_THRESHOLD 50
119 126
127#define BATADV_DAT_CANDIDATE_NOT_FOUND 0
128#define BATADV_DAT_CANDIDATE_ORIG 1
129
120/* Debug Messages */ 130/* Debug Messages */
121#ifdef pr_fmt 131#ifdef pr_fmt
122#undef pr_fmt 132#undef pr_fmt
@@ -150,9 +160,9 @@ extern struct workqueue_struct *batadv_event_workqueue;
150 160
151int batadv_mesh_init(struct net_device *soft_iface); 161int batadv_mesh_init(struct net_device *soft_iface);
152void batadv_mesh_free(struct net_device *soft_iface); 162void batadv_mesh_free(struct net_device *soft_iface);
153void batadv_inc_module_count(void);
154void batadv_dec_module_count(void);
155int batadv_is_my_mac(const uint8_t *addr); 163int batadv_is_my_mac(const uint8_t *addr);
164struct batadv_hard_iface *
165batadv_seq_print_text_primary_if_get(struct seq_file *seq);
156int batadv_batman_skb_recv(struct sk_buff *skb, struct net_device *dev, 166int batadv_batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
157 struct packet_type *ptype, 167 struct packet_type *ptype,
158 struct net_device *orig_dev); 168 struct net_device *orig_dev);
@@ -165,13 +175,22 @@ int batadv_algo_register(struct batadv_algo_ops *bat_algo_ops);
165int batadv_algo_select(struct batadv_priv *bat_priv, char *name); 175int batadv_algo_select(struct batadv_priv *bat_priv, char *name);
166int batadv_algo_seq_print_text(struct seq_file *seq, void *offset); 176int batadv_algo_seq_print_text(struct seq_file *seq, void *offset);
167 177
168/* all messages related to routing / flooding / broadcasting / etc */ 178/**
179 * enum batadv_dbg_level - available log levels
180 * @BATADV_DBG_BATMAN: OGM and TQ computations related messages
181 * @BATADV_DBG_ROUTES: route added / changed / deleted
182 * @BATADV_DBG_TT: translation table messages
183 * @BATADV_DBG_BLA: bridge loop avoidance messages
184 * @BATADV_DBG_DAT: ARP snooping and DAT related messages
185 * @BATADV_DBG_ALL: the union of all the above log levels
186 */
169enum batadv_dbg_level { 187enum batadv_dbg_level {
170 BATADV_DBG_BATMAN = BIT(0), 188 BATADV_DBG_BATMAN = BIT(0),
171 BATADV_DBG_ROUTES = BIT(1), /* route added / changed / deleted */ 189 BATADV_DBG_ROUTES = BIT(1),
172 BATADV_DBG_TT = BIT(2), /* translation table operations */ 190 BATADV_DBG_TT = BIT(2),
173 BATADV_DBG_BLA = BIT(3), /* bridge loop avoidance */ 191 BATADV_DBG_BLA = BIT(3),
174 BATADV_DBG_ALL = 15, 192 BATADV_DBG_DAT = BIT(4),
193 BATADV_DBG_ALL = 31,
175}; 194};
176 195
177#ifdef CONFIG_BATMAN_ADV_DEBUG 196#ifdef CONFIG_BATMAN_ADV_DEBUG
diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c
index ac9bdf8f80a6..8c32cf1c2dec 100644
--- a/net/batman-adv/originator.c
+++ b/net/batman-adv/originator.c
@@ -18,6 +18,7 @@
18 */ 18 */
19 19
20#include "main.h" 20#include "main.h"
21#include "distributed-arp-table.h"
21#include "originator.h" 22#include "originator.h"
22#include "hash.h" 23#include "hash.h"
23#include "translation-table.h" 24#include "translation-table.h"
@@ -220,9 +221,9 @@ struct batadv_orig_node *batadv_get_orig_node(struct batadv_priv *bat_priv,
220 atomic_set(&orig_node->refcount, 2); 221 atomic_set(&orig_node->refcount, 2);
221 222
222 orig_node->tt_initialised = false; 223 orig_node->tt_initialised = false;
223 orig_node->tt_poss_change = false;
224 orig_node->bat_priv = bat_priv; 224 orig_node->bat_priv = bat_priv;
225 memcpy(orig_node->orig, addr, ETH_ALEN); 225 memcpy(orig_node->orig, addr, ETH_ALEN);
226 batadv_dat_init_orig_node_addr(orig_node);
226 orig_node->router = NULL; 227 orig_node->router = NULL;
227 orig_node->tt_crc = 0; 228 orig_node->tt_crc = 0;
228 atomic_set(&orig_node->last_ttvn, 0); 229 atomic_set(&orig_node->last_ttvn, 0);
@@ -415,23 +416,10 @@ int batadv_orig_seq_print_text(struct seq_file *seq, void *offset)
415 int last_seen_msecs; 416 int last_seen_msecs;
416 unsigned long last_seen_jiffies; 417 unsigned long last_seen_jiffies;
417 uint32_t i; 418 uint32_t i;
418 int ret = 0;
419 419
420 primary_if = batadv_primary_if_get_selected(bat_priv); 420 primary_if = batadv_seq_print_text_primary_if_get(seq);
421 421 if (!primary_if)
422 if (!primary_if) {
423 ret = seq_printf(seq,
424 "BATMAN mesh %s disabled - please specify interfaces to enable it\n",
425 net_dev->name);
426 goto out;
427 }
428
429 if (primary_if->if_status != BATADV_IF_ACTIVE) {
430 ret = seq_printf(seq,
431 "BATMAN mesh %s disabled - primary interface not active\n",
432 net_dev->name);
433 goto out; 422 goto out;
434 }
435 423
436 seq_printf(seq, "[B.A.T.M.A.N. adv %s, MainIF/MAC: %s/%pM (%s)]\n", 424 seq_printf(seq, "[B.A.T.M.A.N. adv %s, MainIF/MAC: %s/%pM (%s)]\n",
437 BATADV_SOURCE_VERSION, primary_if->net_dev->name, 425 BATADV_SOURCE_VERSION, primary_if->net_dev->name,
@@ -485,7 +473,7 @@ next:
485out: 473out:
486 if (primary_if) 474 if (primary_if)
487 batadv_hardif_free_ref(primary_if); 475 batadv_hardif_free_ref(primary_if);
488 return ret; 476 return 0;
489} 477}
490 478
491static int batadv_orig_node_add_if(struct batadv_orig_node *orig_node, 479static int batadv_orig_node_add_if(struct batadv_orig_node *orig_node,
diff --git a/net/batman-adv/packet.h b/net/batman-adv/packet.h
index 2d23a14c220e..df548ed196d3 100644
--- a/net/batman-adv/packet.h
+++ b/net/batman-adv/packet.h
@@ -23,14 +23,29 @@
23#define BATADV_ETH_P_BATMAN 0x4305 /* unofficial/not registered Ethertype */ 23#define BATADV_ETH_P_BATMAN 0x4305 /* unofficial/not registered Ethertype */
24 24
25enum batadv_packettype { 25enum batadv_packettype {
26 BATADV_IV_OGM = 0x01, 26 BATADV_IV_OGM = 0x01,
27 BATADV_ICMP = 0x02, 27 BATADV_ICMP = 0x02,
28 BATADV_UNICAST = 0x03, 28 BATADV_UNICAST = 0x03,
29 BATADV_BCAST = 0x04, 29 BATADV_BCAST = 0x04,
30 BATADV_VIS = 0x05, 30 BATADV_VIS = 0x05,
31 BATADV_UNICAST_FRAG = 0x06, 31 BATADV_UNICAST_FRAG = 0x06,
32 BATADV_TT_QUERY = 0x07, 32 BATADV_TT_QUERY = 0x07,
33 BATADV_ROAM_ADV = 0x08, 33 BATADV_ROAM_ADV = 0x08,
34 BATADV_UNICAST_4ADDR = 0x09,
35};
36
37/**
38 * enum batadv_subtype - packet subtype for unicast4addr
39 * @BATADV_P_DATA: user payload
40 * @BATADV_P_DAT_DHT_GET: DHT request message
41 * @BATADV_P_DAT_DHT_PUT: DHT store message
42 * @BATADV_P_DAT_CACHE_REPLY: ARP reply generated by DAT
43 */
44enum batadv_subtype {
45 BATADV_P_DATA = 0x01,
46 BATADV_P_DAT_DHT_GET = 0x02,
47 BATADV_P_DAT_DHT_PUT = 0x03,
48 BATADV_P_DAT_CACHE_REPLY = 0x04,
34}; 49};
35 50
36/* this file is included by batctl which needs these defines */ 51/* this file is included by batctl which needs these defines */
@@ -106,13 +121,16 @@ struct batadv_bla_claim_dst {
106 uint8_t magic[3]; /* FF:43:05 */ 121 uint8_t magic[3]; /* FF:43:05 */
107 uint8_t type; /* bla_claimframe */ 122 uint8_t type; /* bla_claimframe */
108 __be16 group; /* group id */ 123 __be16 group; /* group id */
109} __packed; 124};
110 125
111struct batadv_header { 126struct batadv_header {
112 uint8_t packet_type; 127 uint8_t packet_type;
113 uint8_t version; /* batman version field */ 128 uint8_t version; /* batman version field */
114 uint8_t ttl; 129 uint8_t ttl;
115} __packed; 130 /* the parent struct has to add a byte after the header to make
131 * everything 4 bytes aligned again
132 */
133};
116 134
117struct batadv_ogm_packet { 135struct batadv_ogm_packet {
118 struct batadv_header header; 136 struct batadv_header header;
@@ -137,7 +155,7 @@ struct batadv_icmp_packet {
137 __be16 seqno; 155 __be16 seqno;
138 uint8_t uid; 156 uint8_t uid;
139 uint8_t reserved; 157 uint8_t reserved;
140} __packed; 158};
141 159
142#define BATADV_RR_LEN 16 160#define BATADV_RR_LEN 16
143 161
@@ -153,13 +171,32 @@ struct batadv_icmp_packet_rr {
153 uint8_t uid; 171 uint8_t uid;
154 uint8_t rr_cur; 172 uint8_t rr_cur;
155 uint8_t rr[BATADV_RR_LEN][ETH_ALEN]; 173 uint8_t rr[BATADV_RR_LEN][ETH_ALEN];
156} __packed; 174};
157 175
158struct batadv_unicast_packet { 176struct batadv_unicast_packet {
159 struct batadv_header header; 177 struct batadv_header header;
160 uint8_t ttvn; /* destination translation table version number */ 178 uint8_t ttvn; /* destination translation table version number */
161 uint8_t dest[ETH_ALEN]; 179 uint8_t dest[ETH_ALEN];
162} __packed; 180 /* "4 bytes boundary + 2 bytes" long to make the payload after the
181 * following ethernet header again 4 bytes boundary aligned
182 */
183};
184
185/**
186 * struct batadv_unicast_4addr_packet - extended unicast packet
187 * @u: common unicast packet header
188 * @src: address of the source
189 * @subtype: packet subtype
190 */
191struct batadv_unicast_4addr_packet {
192 struct batadv_unicast_packet u;
193 uint8_t src[ETH_ALEN];
194 uint8_t subtype;
195 uint8_t reserved;
196 /* "4 bytes boundary + 2 bytes" long to make the payload after the
197 * following ethernet header again 4 bytes boundary aligned
198 */
199};
163 200
164struct batadv_unicast_frag_packet { 201struct batadv_unicast_frag_packet {
165 struct batadv_header header; 202 struct batadv_header header;
@@ -176,6 +213,9 @@ struct batadv_bcast_packet {
176 uint8_t reserved; 213 uint8_t reserved;
177 __be32 seqno; 214 __be32 seqno;
178 uint8_t orig[ETH_ALEN]; 215 uint8_t orig[ETH_ALEN];
216 /* "4 bytes boundary + 2 bytes" long to make the payload after the
217 * following ethernet header again 4 bytes boundary aligned
218 */
179} __packed; 219} __packed;
180 220
181struct batadv_vis_packet { 221struct batadv_vis_packet {
@@ -187,7 +227,7 @@ struct batadv_vis_packet {
187 uint8_t vis_orig[ETH_ALEN]; /* originator reporting its neighbors */ 227 uint8_t vis_orig[ETH_ALEN]; /* originator reporting its neighbors */
188 uint8_t target_orig[ETH_ALEN]; /* who should receive this packet */ 228 uint8_t target_orig[ETH_ALEN]; /* who should receive this packet */
189 uint8_t sender_orig[ETH_ALEN]; /* who sent or forwarded this packet */ 229 uint8_t sender_orig[ETH_ALEN]; /* who sent or forwarded this packet */
190} __packed; 230};
191 231
192struct batadv_tt_query_packet { 232struct batadv_tt_query_packet {
193 struct batadv_header header; 233 struct batadv_header header;
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
index 376b4cc6ca82..78d657264cbf 100644
--- a/net/batman-adv/routing.c
+++ b/net/batman-adv/routing.c
@@ -28,6 +28,7 @@
28#include "vis.h" 28#include "vis.h"
29#include "unicast.h" 29#include "unicast.h"
30#include "bridge_loop_avoidance.h" 30#include "bridge_loop_avoidance.h"
31#include "distributed-arp-table.h"
31 32
32static int batadv_route_unicast_packet(struct sk_buff *skb, 33static int batadv_route_unicast_packet(struct sk_buff *skb,
33 struct batadv_hard_iface *recv_if); 34 struct batadv_hard_iface *recv_if);
@@ -549,25 +550,18 @@ batadv_find_ifalter_router(struct batadv_orig_node *primary_orig,
549 if (tmp_neigh_node->if_incoming == recv_if) 550 if (tmp_neigh_node->if_incoming == recv_if)
550 continue; 551 continue;
551 552
552 if (!atomic_inc_not_zero(&tmp_neigh_node->refcount)) 553 if (router && tmp_neigh_node->tq_avg <= router->tq_avg)
553 continue; 554 continue;
554 555
555 /* if we don't have a router yet 556 if (!atomic_inc_not_zero(&tmp_neigh_node->refcount))
556 * or this one is better, choose it. 557 continue;
557 */
558 if ((!router) ||
559 (tmp_neigh_node->tq_avg > router->tq_avg)) {
560 /* decrement refcount of
561 * previously selected router
562 */
563 if (router)
564 batadv_neigh_node_free_ref(router);
565 558
566 router = tmp_neigh_node; 559 /* decrement refcount of previously selected router */
567 atomic_inc_not_zero(&router->refcount); 560 if (router)
568 } 561 batadv_neigh_node_free_ref(router);
569 562
570 batadv_neigh_node_free_ref(tmp_neigh_node); 563 /* we found a better router (or at least one valid router) */
564 router = tmp_neigh_node;
571 } 565 }
572 566
573 /* use the first candidate if nothing was found. */ 567 /* use the first candidate if nothing was found. */
@@ -687,21 +681,8 @@ int batadv_recv_roam_adv(struct sk_buff *skb, struct batadv_hard_iface *recv_if)
687 struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface); 681 struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface);
688 struct batadv_roam_adv_packet *roam_adv_packet; 682 struct batadv_roam_adv_packet *roam_adv_packet;
689 struct batadv_orig_node *orig_node; 683 struct batadv_orig_node *orig_node;
690 struct ethhdr *ethhdr;
691
692 /* drop packet if it has not necessary minimum size */
693 if (unlikely(!pskb_may_pull(skb,
694 sizeof(struct batadv_roam_adv_packet))))
695 goto out;
696
697 ethhdr = (struct ethhdr *)skb_mac_header(skb);
698
699 /* packet with unicast indication but broadcast recipient */
700 if (is_broadcast_ether_addr(ethhdr->h_dest))
701 goto out;
702 684
703 /* packet with broadcast sender address */ 685 if (batadv_check_unicast_packet(skb, sizeof(*roam_adv_packet)) < 0)
704 if (is_broadcast_ether_addr(ethhdr->h_source))
705 goto out; 686 goto out;
706 687
707 batadv_inc_counter(bat_priv, BATADV_CNT_TT_ROAM_ADV_RX); 688 batadv_inc_counter(bat_priv, BATADV_CNT_TT_ROAM_ADV_RX);
@@ -730,12 +711,6 @@ int batadv_recv_roam_adv(struct sk_buff *skb, struct batadv_hard_iface *recv_if)
730 BATADV_TT_CLIENT_ROAM, 711 BATADV_TT_CLIENT_ROAM,
731 atomic_read(&orig_node->last_ttvn) + 1); 712 atomic_read(&orig_node->last_ttvn) + 1);
732 713
733 /* Roaming phase starts: I have new information but the ttvn has not
734 * been incremented yet. This flag will make me check all the incoming
735 * packets for the correct destination.
736 */
737 bat_priv->tt.poss_change = true;
738
739 batadv_orig_node_free_ref(orig_node); 714 batadv_orig_node_free_ref(orig_node);
740out: 715out:
741 /* returning NET_RX_DROP will make the caller function kfree the skb */ 716 /* returning NET_RX_DROP will make the caller function kfree the skb */
@@ -918,80 +893,161 @@ out:
918 return ret; 893 return ret;
919} 894}
920 895
896/**
897 * batadv_reroute_unicast_packet - update the unicast header for re-routing
898 * @bat_priv: the bat priv with all the soft interface information
899 * @unicast_packet: the unicast header to be updated
900 * @dst_addr: the payload destination
901 *
902 * Search the translation table for dst_addr and update the unicast header with
903 * the new corresponding information (originator address where the destination
904 * client currently is and its known TTVN)
905 *
906 * Returns true if the packet header has been updated, false otherwise
907 */
908static bool
909batadv_reroute_unicast_packet(struct batadv_priv *bat_priv,
910 struct batadv_unicast_packet *unicast_packet,
911 uint8_t *dst_addr)
912{
913 struct batadv_orig_node *orig_node = NULL;
914 struct batadv_hard_iface *primary_if = NULL;
915 bool ret = false;
916 uint8_t *orig_addr, orig_ttvn;
917
918 if (batadv_is_my_client(bat_priv, dst_addr)) {
919 primary_if = batadv_primary_if_get_selected(bat_priv);
920 if (!primary_if)
921 goto out;
922 orig_addr = primary_if->net_dev->dev_addr;
923 orig_ttvn = (uint8_t)atomic_read(&bat_priv->tt.vn);
924 } else {
925 orig_node = batadv_transtable_search(bat_priv, NULL, dst_addr);
926 if (!orig_node)
927 goto out;
928
929 if (batadv_compare_eth(orig_node->orig, unicast_packet->dest))
930 goto out;
931
932 orig_addr = orig_node->orig;
933 orig_ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn);
934 }
935
936 /* update the packet header */
937 memcpy(unicast_packet->dest, orig_addr, ETH_ALEN);
938 unicast_packet->ttvn = orig_ttvn;
939
940 ret = true;
941out:
942 if (primary_if)
943 batadv_hardif_free_ref(primary_if);
944 if (orig_node)
945 batadv_orig_node_free_ref(orig_node);
946
947 return ret;
948}
949
921static int batadv_check_unicast_ttvn(struct batadv_priv *bat_priv, 950static int batadv_check_unicast_ttvn(struct batadv_priv *bat_priv,
922 struct sk_buff *skb) { 951 struct sk_buff *skb) {
923 uint8_t curr_ttvn; 952 uint8_t curr_ttvn, old_ttvn;
924 struct batadv_orig_node *orig_node; 953 struct batadv_orig_node *orig_node;
925 struct ethhdr *ethhdr; 954 struct ethhdr *ethhdr;
926 struct batadv_hard_iface *primary_if; 955 struct batadv_hard_iface *primary_if;
927 struct batadv_unicast_packet *unicast_packet; 956 struct batadv_unicast_packet *unicast_packet;
928 bool tt_poss_change;
929 int is_old_ttvn; 957 int is_old_ttvn;
930 958
931 /* I could need to modify it */ 959 /* check if there is enough data before accessing it */
932 if (skb_cow(skb, sizeof(struct batadv_unicast_packet)) < 0) 960 if (pskb_may_pull(skb, sizeof(*unicast_packet) + ETH_HLEN) < 0)
961 return 0;
962
963 /* create a copy of the skb (in case of for re-routing) to modify it. */
964 if (skb_cow(skb, sizeof(*unicast_packet)) < 0)
933 return 0; 965 return 0;
934 966
935 unicast_packet = (struct batadv_unicast_packet *)skb->data; 967 unicast_packet = (struct batadv_unicast_packet *)skb->data;
968 ethhdr = (struct ethhdr *)(skb->data + sizeof(*unicast_packet));
936 969
937 if (batadv_is_my_mac(unicast_packet->dest)) { 970 /* check if the destination client was served by this node and it is now
938 tt_poss_change = bat_priv->tt.poss_change; 971 * roaming. In this case, it means that the node has got a ROAM_ADV
939 curr_ttvn = (uint8_t)atomic_read(&bat_priv->tt.vn); 972 * message and that it knows the new destination in the mesh to re-route
940 } else { 973 * the packet to
974 */
975 if (batadv_tt_local_client_is_roaming(bat_priv, ethhdr->h_dest)) {
976 if (batadv_reroute_unicast_packet(bat_priv, unicast_packet,
977 ethhdr->h_dest))
978 net_ratelimited_function(batadv_dbg, BATADV_DBG_TT,
979 bat_priv,
980 "Rerouting unicast packet to %pM (dst=%pM): Local Roaming\n",
981 unicast_packet->dest,
982 ethhdr->h_dest);
983 /* at this point the mesh destination should have been
984 * substituted with the originator address found in the global
985 * table. If not, let the packet go untouched anyway because
986 * there is nothing the node can do
987 */
988 return 1;
989 }
990
991 /* retrieve the TTVN known by this node for the packet destination. This
992 * value is used later to check if the node which sent (or re-routed
993 * last time) the packet had an updated information or not
994 */
995 curr_ttvn = (uint8_t)atomic_read(&bat_priv->tt.vn);
996 if (!batadv_is_my_mac(unicast_packet->dest)) {
941 orig_node = batadv_orig_hash_find(bat_priv, 997 orig_node = batadv_orig_hash_find(bat_priv,
942 unicast_packet->dest); 998 unicast_packet->dest);
943 999 /* if it is not possible to find the orig_node representing the
1000 * destination, the packet can immediately be dropped as it will
1001 * not be possible to deliver it
1002 */
944 if (!orig_node) 1003 if (!orig_node)
945 return 0; 1004 return 0;
946 1005
947 curr_ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn); 1006 curr_ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn);
948 tt_poss_change = orig_node->tt_poss_change;
949 batadv_orig_node_free_ref(orig_node); 1007 batadv_orig_node_free_ref(orig_node);
950 } 1008 }
951 1009
952 /* Check whether I have to reroute the packet */ 1010 /* check if the TTVN contained in the packet is fresher than what the
1011 * node knows
1012 */
953 is_old_ttvn = batadv_seq_before(unicast_packet->ttvn, curr_ttvn); 1013 is_old_ttvn = batadv_seq_before(unicast_packet->ttvn, curr_ttvn);
954 if (is_old_ttvn || tt_poss_change) { 1014 if (!is_old_ttvn)
955 /* check if there is enough data before accessing it */ 1015 return 1;
956 if (pskb_may_pull(skb, sizeof(struct batadv_unicast_packet) +
957 ETH_HLEN) < 0)
958 return 0;
959 1016
960 ethhdr = (struct ethhdr *)(skb->data + sizeof(*unicast_packet)); 1017 old_ttvn = unicast_packet->ttvn;
1018 /* the packet was forged based on outdated network information. Its
1019 * destination can possibly be updated and forwarded towards the new
1020 * target host
1021 */
1022 if (batadv_reroute_unicast_packet(bat_priv, unicast_packet,
1023 ethhdr->h_dest)) {
1024 net_ratelimited_function(batadv_dbg, BATADV_DBG_TT, bat_priv,
1025 "Rerouting unicast packet to %pM (dst=%pM): TTVN mismatch old_ttvn=%u new_ttvn=%u\n",
1026 unicast_packet->dest, ethhdr->h_dest,
1027 old_ttvn, curr_ttvn);
1028 return 1;
1029 }
961 1030
962 /* we don't have an updated route for this client, so we should 1031 /* the packet has not been re-routed: either the destination is
963 * not try to reroute the packet!! 1032 * currently served by this node or there is no destination at all and
964 */ 1033 * it is possible to drop the packet
965 if (batadv_tt_global_client_is_roaming(bat_priv, 1034 */
966 ethhdr->h_dest)) 1035 if (!batadv_is_my_client(bat_priv, ethhdr->h_dest))
967 return 1; 1036 return 0;
968 1037
969 orig_node = batadv_transtable_search(bat_priv, NULL, 1038 /* update the header in order to let the packet be delivered to this
970 ethhdr->h_dest); 1039 * node's soft interface
971 1040 */
972 if (!orig_node) { 1041 primary_if = batadv_primary_if_get_selected(bat_priv);
973 if (!batadv_is_my_client(bat_priv, ethhdr->h_dest)) 1042 if (!primary_if)
974 return 0; 1043 return 0;
975 primary_if = batadv_primary_if_get_selected(bat_priv);
976 if (!primary_if)
977 return 0;
978 memcpy(unicast_packet->dest,
979 primary_if->net_dev->dev_addr, ETH_ALEN);
980 batadv_hardif_free_ref(primary_if);
981 } else {
982 memcpy(unicast_packet->dest, orig_node->orig,
983 ETH_ALEN);
984 curr_ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn);
985 batadv_orig_node_free_ref(orig_node);
986 }
987 1044
988 batadv_dbg(BATADV_DBG_ROUTES, bat_priv, 1045 memcpy(unicast_packet->dest, primary_if->net_dev->dev_addr, ETH_ALEN);
989 "TTVN mismatch (old_ttvn %u new_ttvn %u)! Rerouting unicast packet (for %pM) to %pM\n", 1046
990 unicast_packet->ttvn, curr_ttvn, ethhdr->h_dest, 1047 batadv_hardif_free_ref(primary_if);
991 unicast_packet->dest); 1048
1049 unicast_packet->ttvn = curr_ttvn;
992 1050
993 unicast_packet->ttvn = curr_ttvn;
994 }
995 return 1; 1051 return 1;
996} 1052}
997 1053
@@ -1000,7 +1056,19 @@ int batadv_recv_unicast_packet(struct sk_buff *skb,
1000{ 1056{
1001 struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface); 1057 struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface);
1002 struct batadv_unicast_packet *unicast_packet; 1058 struct batadv_unicast_packet *unicast_packet;
1059 struct batadv_unicast_4addr_packet *unicast_4addr_packet;
1060 uint8_t *orig_addr;
1061 struct batadv_orig_node *orig_node = NULL;
1003 int hdr_size = sizeof(*unicast_packet); 1062 int hdr_size = sizeof(*unicast_packet);
1063 bool is4addr;
1064
1065 unicast_packet = (struct batadv_unicast_packet *)skb->data;
1066 unicast_4addr_packet = (struct batadv_unicast_4addr_packet *)skb->data;
1067
1068 is4addr = unicast_packet->header.packet_type == BATADV_UNICAST_4ADDR;
1069 /* the caller function should have already pulled 2 bytes */
1070 if (is4addr)
1071 hdr_size = sizeof(*unicast_4addr_packet);
1004 1072
1005 if (batadv_check_unicast_packet(skb, hdr_size) < 0) 1073 if (batadv_check_unicast_packet(skb, hdr_size) < 0)
1006 return NET_RX_DROP; 1074 return NET_RX_DROP;
@@ -1008,12 +1076,28 @@ int batadv_recv_unicast_packet(struct sk_buff *skb,
1008 if (!batadv_check_unicast_ttvn(bat_priv, skb)) 1076 if (!batadv_check_unicast_ttvn(bat_priv, skb))
1009 return NET_RX_DROP; 1077 return NET_RX_DROP;
1010 1078
1011 unicast_packet = (struct batadv_unicast_packet *)skb->data;
1012
1013 /* packet for me */ 1079 /* packet for me */
1014 if (batadv_is_my_mac(unicast_packet->dest)) { 1080 if (batadv_is_my_mac(unicast_packet->dest)) {
1081 if (is4addr) {
1082 batadv_dat_inc_counter(bat_priv,
1083 unicast_4addr_packet->subtype);
1084 orig_addr = unicast_4addr_packet->src;
1085 orig_node = batadv_orig_hash_find(bat_priv, orig_addr);
1086 }
1087
1088 if (batadv_dat_snoop_incoming_arp_request(bat_priv, skb,
1089 hdr_size))
1090 goto rx_success;
1091 if (batadv_dat_snoop_incoming_arp_reply(bat_priv, skb,
1092 hdr_size))
1093 goto rx_success;
1094
1015 batadv_interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size, 1095 batadv_interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size,
1016 NULL); 1096 orig_node);
1097
1098rx_success:
1099 if (orig_node)
1100 batadv_orig_node_free_ref(orig_node);
1017 1101
1018 return NET_RX_SUCCESS; 1102 return NET_RX_SUCCESS;
1019 } 1103 }
@@ -1050,8 +1134,17 @@ int batadv_recv_ucast_frag_packet(struct sk_buff *skb,
1050 if (!new_skb) 1134 if (!new_skb)
1051 return NET_RX_SUCCESS; 1135 return NET_RX_SUCCESS;
1052 1136
1137 if (batadv_dat_snoop_incoming_arp_request(bat_priv, new_skb,
1138 hdr_size))
1139 goto rx_success;
1140 if (batadv_dat_snoop_incoming_arp_reply(bat_priv, new_skb,
1141 hdr_size))
1142 goto rx_success;
1143
1053 batadv_interface_rx(recv_if->soft_iface, new_skb, recv_if, 1144 batadv_interface_rx(recv_if->soft_iface, new_skb, recv_if,
1054 sizeof(struct batadv_unicast_packet), NULL); 1145 sizeof(struct batadv_unicast_packet), NULL);
1146
1147rx_success:
1055 return NET_RX_SUCCESS; 1148 return NET_RX_SUCCESS;
1056 } 1149 }
1057 1150
@@ -1143,9 +1236,16 @@ int batadv_recv_bcast_packet(struct sk_buff *skb,
1143 if (batadv_bla_is_backbone_gw(skb, orig_node, hdr_size)) 1236 if (batadv_bla_is_backbone_gw(skb, orig_node, hdr_size))
1144 goto out; 1237 goto out;
1145 1238
1239 if (batadv_dat_snoop_incoming_arp_request(bat_priv, skb, hdr_size))
1240 goto rx_success;
1241 if (batadv_dat_snoop_incoming_arp_reply(bat_priv, skb, hdr_size))
1242 goto rx_success;
1243
1146 /* broadcast for me */ 1244 /* broadcast for me */
1147 batadv_interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size, 1245 batadv_interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size,
1148 orig_node); 1246 orig_node);
1247
1248rx_success:
1149 ret = NET_RX_SUCCESS; 1249 ret = NET_RX_SUCCESS;
1150 goto out; 1250 goto out;
1151 1251
diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c
index 570a8bce0364..660d9bf7d219 100644
--- a/net/batman-adv/send.c
+++ b/net/batman-adv/send.c
@@ -18,6 +18,7 @@
18 */ 18 */
19 19
20#include "main.h" 20#include "main.h"
21#include "distributed-arp-table.h"
21#include "send.h" 22#include "send.h"
22#include "routing.h" 23#include "routing.h"
23#include "translation-table.h" 24#include "translation-table.h"
@@ -209,6 +210,9 @@ static void batadv_send_outstanding_bcast_packet(struct work_struct *work)
209 if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING) 210 if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING)
210 goto out; 211 goto out;
211 212
213 if (batadv_dat_drop_broadcast_packet(bat_priv, forw_packet))
214 goto out;
215
212 /* rebroadcast packet */ 216 /* rebroadcast packet */
213 rcu_read_lock(); 217 rcu_read_lock();
214 list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) { 218 list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
index ce0684a1fc83..54800c783f96 100644
--- a/net/batman-adv/soft-interface.c
+++ b/net/batman-adv/soft-interface.c
@@ -20,6 +20,7 @@
20#include "main.h" 20#include "main.h"
21#include "soft-interface.h" 21#include "soft-interface.h"
22#include "hard-interface.h" 22#include "hard-interface.h"
23#include "distributed-arp-table.h"
23#include "routing.h" 24#include "routing.h"
24#include "send.h" 25#include "send.h"
25#include "debugfs.h" 26#include "debugfs.h"
@@ -146,13 +147,16 @@ static int batadv_interface_tx(struct sk_buff *skb,
146 struct batadv_bcast_packet *bcast_packet; 147 struct batadv_bcast_packet *bcast_packet;
147 struct vlan_ethhdr *vhdr; 148 struct vlan_ethhdr *vhdr;
148 __be16 ethertype = __constant_htons(BATADV_ETH_P_BATMAN); 149 __be16 ethertype = __constant_htons(BATADV_ETH_P_BATMAN);
149 static const uint8_t stp_addr[ETH_ALEN] = {0x01, 0x80, 0xC2, 0x00, 0x00, 150 static const uint8_t stp_addr[ETH_ALEN] = {0x01, 0x80, 0xC2, 0x00,
150 0x00}; 151 0x00, 0x00};
152 static const uint8_t ectp_addr[ETH_ALEN] = {0xCF, 0x00, 0x00, 0x00,
153 0x00, 0x00};
151 unsigned int header_len = 0; 154 unsigned int header_len = 0;
152 int data_len = skb->len, ret; 155 int data_len = skb->len, ret;
153 short vid __maybe_unused = -1; 156 short vid __maybe_unused = -1;
154 bool do_bcast = false; 157 bool do_bcast = false;
155 uint32_t seqno; 158 uint32_t seqno;
159 unsigned long brd_delay = 1;
156 160
157 if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE) 161 if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE)
158 goto dropped; 162 goto dropped;
@@ -180,10 +184,16 @@ static int batadv_interface_tx(struct sk_buff *skb,
180 184
181 /* don't accept stp packets. STP does not help in meshes. 185 /* don't accept stp packets. STP does not help in meshes.
182 * better use the bridge loop avoidance ... 186 * better use the bridge loop avoidance ...
187 *
188 * The same goes for ECTP sent at least by some Cisco Switches,
189 * it might confuse the mesh when used with bridge loop avoidance.
183 */ 190 */
184 if (batadv_compare_eth(ethhdr->h_dest, stp_addr)) 191 if (batadv_compare_eth(ethhdr->h_dest, stp_addr))
185 goto dropped; 192 goto dropped;
186 193
194 if (batadv_compare_eth(ethhdr->h_dest, ectp_addr))
195 goto dropped;
196
187 if (is_multicast_ether_addr(ethhdr->h_dest)) { 197 if (is_multicast_ether_addr(ethhdr->h_dest)) {
188 do_bcast = true; 198 do_bcast = true;
189 199
@@ -216,6 +226,13 @@ static int batadv_interface_tx(struct sk_buff *skb,
216 if (!primary_if) 226 if (!primary_if)
217 goto dropped; 227 goto dropped;
218 228
229 /* in case of ARP request, we do not immediately broadcasti the
230 * packet, instead we first wait for DAT to try to retrieve the
231 * correct ARP entry
232 */
233 if (batadv_dat_snoop_outgoing_arp_request(bat_priv, skb))
234 brd_delay = msecs_to_jiffies(ARP_REQ_DELAY);
235
219 if (batadv_skb_head_push(skb, sizeof(*bcast_packet)) < 0) 236 if (batadv_skb_head_push(skb, sizeof(*bcast_packet)) < 0)
220 goto dropped; 237 goto dropped;
221 238
@@ -237,7 +254,7 @@ static int batadv_interface_tx(struct sk_buff *skb,
237 seqno = atomic_inc_return(&bat_priv->bcast_seqno); 254 seqno = atomic_inc_return(&bat_priv->bcast_seqno);
238 bcast_packet->seqno = htonl(seqno); 255 bcast_packet->seqno = htonl(seqno);
239 256
240 batadv_add_bcast_packet_to_list(bat_priv, skb, 1); 257 batadv_add_bcast_packet_to_list(bat_priv, skb, brd_delay);
241 258
242 /* a copy is stored in the bcast list, therefore removing 259 /* a copy is stored in the bcast list, therefore removing
243 * the original skb. 260 * the original skb.
@@ -252,7 +269,12 @@ static int batadv_interface_tx(struct sk_buff *skb,
252 goto dropped; 269 goto dropped;
253 } 270 }
254 271
255 ret = batadv_unicast_send_skb(skb, bat_priv); 272 if (batadv_dat_snoop_outgoing_arp_request(bat_priv, skb))
273 goto dropped;
274
275 batadv_dat_snoop_outgoing_arp_reply(bat_priv, skb);
276
277 ret = batadv_unicast_send_skb(bat_priv, skb);
256 if (ret != 0) 278 if (ret != 0)
257 goto dropped_freed; 279 goto dropped_freed;
258 } 280 }
@@ -347,7 +369,51 @@ out:
347 return; 369 return;
348} 370}
349 371
372/* batman-adv network devices have devices nesting below it and are a special
373 * "super class" of normal network devices; split their locks off into a
374 * separate class since they always nest.
375 */
376static struct lock_class_key batadv_netdev_xmit_lock_key;
377static struct lock_class_key batadv_netdev_addr_lock_key;
378
379/**
380 * batadv_set_lockdep_class_one - Set lockdep class for a single tx queue
381 * @dev: device which owns the tx queue
382 * @txq: tx queue to modify
383 * @_unused: always NULL
384 */
385static void batadv_set_lockdep_class_one(struct net_device *dev,
386 struct netdev_queue *txq,
387 void *_unused)
388{
389 lockdep_set_class(&txq->_xmit_lock, &batadv_netdev_xmit_lock_key);
390}
391
392/**
393 * batadv_set_lockdep_class - Set txq and addr_list lockdep class
394 * @dev: network device to modify
395 */
396static void batadv_set_lockdep_class(struct net_device *dev)
397{
398 lockdep_set_class(&dev->addr_list_lock, &batadv_netdev_addr_lock_key);
399 netdev_for_each_tx_queue(dev, batadv_set_lockdep_class_one, NULL);
400}
401
402/**
403 * batadv_softif_init - Late stage initialization of soft interface
404 * @dev: registered network device to modify
405 *
406 * Returns error code on failures
407 */
408static int batadv_softif_init(struct net_device *dev)
409{
410 batadv_set_lockdep_class(dev);
411
412 return 0;
413}
414
350static const struct net_device_ops batadv_netdev_ops = { 415static const struct net_device_ops batadv_netdev_ops = {
416 .ndo_init = batadv_softif_init,
351 .ndo_open = batadv_interface_open, 417 .ndo_open = batadv_interface_open,
352 .ndo_stop = batadv_interface_release, 418 .ndo_stop = batadv_interface_release,
353 .ndo_get_stats = batadv_interface_stats, 419 .ndo_get_stats = batadv_interface_stats,
@@ -414,6 +480,9 @@ struct net_device *batadv_softif_create(const char *name)
414 atomic_set(&bat_priv->aggregated_ogms, 1); 480 atomic_set(&bat_priv->aggregated_ogms, 1);
415 atomic_set(&bat_priv->bonding, 0); 481 atomic_set(&bat_priv->bonding, 0);
416 atomic_set(&bat_priv->bridge_loop_avoidance, 0); 482 atomic_set(&bat_priv->bridge_loop_avoidance, 0);
483#ifdef CONFIG_BATMAN_ADV_DAT
484 atomic_set(&bat_priv->distributed_arp_table, 1);
485#endif
417 atomic_set(&bat_priv->ap_isolation, 0); 486 atomic_set(&bat_priv->ap_isolation, 0);
418 atomic_set(&bat_priv->vis_mode, BATADV_VIS_TYPE_CLIENT_UPDATE); 487 atomic_set(&bat_priv->vis_mode, BATADV_VIS_TYPE_CLIENT_UPDATE);
419 atomic_set(&bat_priv->gw_mode, BATADV_GW_MODE_OFF); 488 atomic_set(&bat_priv->gw_mode, BATADV_GW_MODE_OFF);
@@ -436,7 +505,6 @@ struct net_device *batadv_softif_create(const char *name)
436#endif 505#endif
437 bat_priv->tt.last_changeset = NULL; 506 bat_priv->tt.last_changeset = NULL;
438 bat_priv->tt.last_changeset_len = 0; 507 bat_priv->tt.last_changeset_len = 0;
439 bat_priv->tt.poss_change = false;
440 508
441 bat_priv->primary_if = NULL; 509 bat_priv->primary_if = NULL;
442 bat_priv->num_ifaces = 0; 510 bat_priv->num_ifaces = 0;
@@ -556,6 +624,13 @@ static const struct {
556 { "tt_response_rx" }, 624 { "tt_response_rx" },
557 { "tt_roam_adv_tx" }, 625 { "tt_roam_adv_tx" },
558 { "tt_roam_adv_rx" }, 626 { "tt_roam_adv_rx" },
627#ifdef CONFIG_BATMAN_ADV_DAT
628 { "dat_get_tx" },
629 { "dat_get_rx" },
630 { "dat_put_tx" },
631 { "dat_put_rx" },
632 { "dat_cached_reply_tx" },
633#endif
559}; 634};
560 635
561static void batadv_get_strings(struct net_device *dev, uint32_t stringset, 636static void batadv_get_strings(struct net_device *dev, uint32_t stringset,
diff --git a/net/batman-adv/sysfs.c b/net/batman-adv/sysfs.c
index 66518c75c217..84a55cb19b0b 100644
--- a/net/batman-adv/sysfs.c
+++ b/net/batman-adv/sysfs.c
@@ -20,6 +20,7 @@
20#include "main.h" 20#include "main.h"
21#include "sysfs.h" 21#include "sysfs.h"
22#include "translation-table.h" 22#include "translation-table.h"
23#include "distributed-arp-table.h"
23#include "originator.h" 24#include "originator.h"
24#include "hard-interface.h" 25#include "hard-interface.h"
25#include "gateway_common.h" 26#include "gateway_common.h"
@@ -122,55 +123,6 @@ ssize_t batadv_show_##_name(struct kobject *kobj, \
122 batadv_store_##_name) 123 batadv_store_##_name)
123 124
124 125
125#define BATADV_ATTR_HIF_STORE_UINT(_name, _min, _max, _post_func) \
126ssize_t batadv_store_##_name(struct kobject *kobj, \
127 struct attribute *attr, char *buff, \
128 size_t count) \
129{ \
130 struct net_device *net_dev = batadv_kobj_to_netdev(kobj); \
131 struct batadv_hard_iface *hard_iface; \
132 ssize_t length; \
133 \
134 hard_iface = batadv_hardif_get_by_netdev(net_dev); \
135 if (!hard_iface) \
136 return 0; \
137 \
138 length = __batadv_store_uint_attr(buff, count, _min, _max, \
139 _post_func, attr, \
140 &hard_iface->_name, net_dev); \
141 \
142 batadv_hardif_free_ref(hard_iface); \
143 return length; \
144}
145
146#define BATADV_ATTR_HIF_SHOW_UINT(_name) \
147ssize_t batadv_show_##_name(struct kobject *kobj, \
148 struct attribute *attr, char *buff) \
149{ \
150 struct net_device *net_dev = batadv_kobj_to_netdev(kobj); \
151 struct batadv_hard_iface *hard_iface; \
152 ssize_t length; \
153 \
154 hard_iface = batadv_hardif_get_by_netdev(net_dev); \
155 if (!hard_iface) \
156 return 0; \
157 \
158 length = sprintf(buff, "%i\n", atomic_read(&hard_iface->_name));\
159 \
160 batadv_hardif_free_ref(hard_iface); \
161 return length; \
162}
163
164/* Use this, if you are going to set [name] in hard_iface to an
165 * unsigned integer value
166 */
167#define BATADV_ATTR_HIF_UINT(_name, _mode, _min, _max, _post_func) \
168 static BATADV_ATTR_HIF_STORE_UINT(_name, _min, _max, _post_func)\
169 static BATADV_ATTR_HIF_SHOW_UINT(_name) \
170 static BATADV_ATTR(_name, _mode, batadv_show_##_name, \
171 batadv_store_##_name)
172
173
174static int batadv_store_bool_attr(char *buff, size_t count, 126static int batadv_store_bool_attr(char *buff, size_t count,
175 struct net_device *net_dev, 127 struct net_device *net_dev,
176 const char *attr_name, atomic_t *attr) 128 const char *attr_name, atomic_t *attr)
@@ -469,6 +421,9 @@ BATADV_ATTR_SIF_BOOL(bonding, S_IRUGO | S_IWUSR, NULL);
469#ifdef CONFIG_BATMAN_ADV_BLA 421#ifdef CONFIG_BATMAN_ADV_BLA
470BATADV_ATTR_SIF_BOOL(bridge_loop_avoidance, S_IRUGO | S_IWUSR, NULL); 422BATADV_ATTR_SIF_BOOL(bridge_loop_avoidance, S_IRUGO | S_IWUSR, NULL);
471#endif 423#endif
424#ifdef CONFIG_BATMAN_ADV_DAT
425BATADV_ATTR_SIF_BOOL(distributed_arp_table, S_IRUGO | S_IWUSR, NULL);
426#endif
472BATADV_ATTR_SIF_BOOL(fragmentation, S_IRUGO | S_IWUSR, batadv_update_min_mtu); 427BATADV_ATTR_SIF_BOOL(fragmentation, S_IRUGO | S_IWUSR, batadv_update_min_mtu);
473BATADV_ATTR_SIF_BOOL(ap_isolation, S_IRUGO | S_IWUSR, NULL); 428BATADV_ATTR_SIF_BOOL(ap_isolation, S_IRUGO | S_IWUSR, NULL);
474static BATADV_ATTR(vis_mode, S_IRUGO | S_IWUSR, batadv_show_vis_mode, 429static BATADV_ATTR(vis_mode, S_IRUGO | S_IWUSR, batadv_show_vis_mode,
@@ -494,6 +449,9 @@ static struct batadv_attribute *batadv_mesh_attrs[] = {
494#ifdef CONFIG_BATMAN_ADV_BLA 449#ifdef CONFIG_BATMAN_ADV_BLA
495 &batadv_attr_bridge_loop_avoidance, 450 &batadv_attr_bridge_loop_avoidance,
496#endif 451#endif
452#ifdef CONFIG_BATMAN_ADV_DAT
453 &batadv_attr_distributed_arp_table,
454#endif
497 &batadv_attr_fragmentation, 455 &batadv_attr_fragmentation,
498 &batadv_attr_ap_isolation, 456 &batadv_attr_ap_isolation,
499 &batadv_attr_vis_mode, 457 &batadv_attr_vis_mode,
@@ -730,7 +688,7 @@ int batadv_throw_uevent(struct batadv_priv *bat_priv, enum batadv_uev_type type,
730 enum batadv_uev_action action, const char *data) 688 enum batadv_uev_action action, const char *data)
731{ 689{
732 int ret = -ENOMEM; 690 int ret = -ENOMEM;
733 struct batadv_hard_iface *primary_if = NULL; 691 struct batadv_hard_iface *primary_if;
734 struct kobject *bat_kobj; 692 struct kobject *bat_kobj;
735 char *uevent_env[4] = { NULL, NULL, NULL, NULL }; 693 char *uevent_env[4] = { NULL, NULL, NULL, NULL };
736 694
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index baae71585804..582f13405df9 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -238,92 +238,134 @@ static int batadv_tt_local_init(struct batadv_priv *bat_priv)
238 return 0; 238 return 0;
239} 239}
240 240
241static void batadv_tt_global_free(struct batadv_priv *bat_priv,
242 struct batadv_tt_global_entry *tt_global,
243 const char *message)
244{
245 batadv_dbg(BATADV_DBG_TT, bat_priv,
246 "Deleting global tt entry %pM: %s\n",
247 tt_global->common.addr, message);
248
249 batadv_hash_remove(bat_priv->tt.global_hash, batadv_compare_tt,
250 batadv_choose_orig, tt_global->common.addr);
251 batadv_tt_global_entry_free_ref(tt_global);
252
253}
254
241void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr, 255void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
242 int ifindex) 256 int ifindex)
243{ 257{
244 struct batadv_priv *bat_priv = netdev_priv(soft_iface); 258 struct batadv_priv *bat_priv = netdev_priv(soft_iface);
245 struct batadv_tt_local_entry *tt_local_entry = NULL; 259 struct batadv_tt_local_entry *tt_local;
246 struct batadv_tt_global_entry *tt_global_entry = NULL; 260 struct batadv_tt_global_entry *tt_global;
247 struct hlist_head *head; 261 struct hlist_head *head;
248 struct hlist_node *node; 262 struct hlist_node *node;
249 struct batadv_tt_orig_list_entry *orig_entry; 263 struct batadv_tt_orig_list_entry *orig_entry;
250 int hash_added; 264 int hash_added;
265 bool roamed_back = false;
251 266
252 tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr); 267 tt_local = batadv_tt_local_hash_find(bat_priv, addr);
268 tt_global = batadv_tt_global_hash_find(bat_priv, addr);
253 269
254 if (tt_local_entry) { 270 if (tt_local) {
255 tt_local_entry->last_seen = jiffies; 271 tt_local->last_seen = jiffies;
256 /* possibly unset the BATADV_TT_CLIENT_PENDING flag */ 272 if (tt_local->common.flags & BATADV_TT_CLIENT_PENDING) {
257 tt_local_entry->common.flags &= ~BATADV_TT_CLIENT_PENDING; 273 batadv_dbg(BATADV_DBG_TT, bat_priv,
258 goto out; 274 "Re-adding pending client %pM\n", addr);
275 /* whatever the reason why the PENDING flag was set,
276 * this is a client which was enqueued to be removed in
277 * this orig_interval. Since it popped up again, the
278 * flag can be reset like it was never enqueued
279 */
280 tt_local->common.flags &= ~BATADV_TT_CLIENT_PENDING;
281 goto add_event;
282 }
283
284 if (tt_local->common.flags & BATADV_TT_CLIENT_ROAM) {
285 batadv_dbg(BATADV_DBG_TT, bat_priv,
286 "Roaming client %pM came back to its original location\n",
287 addr);
288 /* the ROAM flag is set because this client roamed away
289 * and the node got a roaming_advertisement message. Now
290 * that the client popped up again at its original
291 * location such flag can be unset
292 */
293 tt_local->common.flags &= ~BATADV_TT_CLIENT_ROAM;
294 roamed_back = true;
295 }
296 goto check_roaming;
259 } 297 }
260 298
261 tt_local_entry = kmalloc(sizeof(*tt_local_entry), GFP_ATOMIC); 299 tt_local = kmalloc(sizeof(*tt_local), GFP_ATOMIC);
262 if (!tt_local_entry) 300 if (!tt_local)
263 goto out; 301 goto out;
264 302
265 batadv_dbg(BATADV_DBG_TT, bat_priv, 303 batadv_dbg(BATADV_DBG_TT, bat_priv,
266 "Creating new local tt entry: %pM (ttvn: %d)\n", addr, 304 "Creating new local tt entry: %pM (ttvn: %d)\n", addr,
267 (uint8_t)atomic_read(&bat_priv->tt.vn)); 305 (uint8_t)atomic_read(&bat_priv->tt.vn));
268 306
269 memcpy(tt_local_entry->common.addr, addr, ETH_ALEN); 307 memcpy(tt_local->common.addr, addr, ETH_ALEN);
270 tt_local_entry->common.flags = BATADV_NO_FLAGS; 308 tt_local->common.flags = BATADV_NO_FLAGS;
271 if (batadv_is_wifi_iface(ifindex)) 309 if (batadv_is_wifi_iface(ifindex))
272 tt_local_entry->common.flags |= BATADV_TT_CLIENT_WIFI; 310 tt_local->common.flags |= BATADV_TT_CLIENT_WIFI;
273 atomic_set(&tt_local_entry->common.refcount, 2); 311 atomic_set(&tt_local->common.refcount, 2);
274 tt_local_entry->last_seen = jiffies; 312 tt_local->last_seen = jiffies;
275 tt_local_entry->common.added_at = tt_local_entry->last_seen; 313 tt_local->common.added_at = tt_local->last_seen;
276 314
277 /* the batman interface mac address should never be purged */ 315 /* the batman interface mac address should never be purged */
278 if (batadv_compare_eth(addr, soft_iface->dev_addr)) 316 if (batadv_compare_eth(addr, soft_iface->dev_addr))
279 tt_local_entry->common.flags |= BATADV_TT_CLIENT_NOPURGE; 317 tt_local->common.flags |= BATADV_TT_CLIENT_NOPURGE;
280 318
281 /* The local entry has to be marked as NEW to avoid to send it in 319 /* The local entry has to be marked as NEW to avoid to send it in
282 * a full table response going out before the next ttvn increment 320 * a full table response going out before the next ttvn increment
283 * (consistency check) 321 * (consistency check)
284 */ 322 */
285 tt_local_entry->common.flags |= BATADV_TT_CLIENT_NEW; 323 tt_local->common.flags |= BATADV_TT_CLIENT_NEW;
286 324
287 hash_added = batadv_hash_add(bat_priv->tt.local_hash, batadv_compare_tt, 325 hash_added = batadv_hash_add(bat_priv->tt.local_hash, batadv_compare_tt,
288 batadv_choose_orig, 326 batadv_choose_orig, &tt_local->common,
289 &tt_local_entry->common, 327 &tt_local->common.hash_entry);
290 &tt_local_entry->common.hash_entry);
291 328
292 if (unlikely(hash_added != 0)) { 329 if (unlikely(hash_added != 0)) {
293 /* remove the reference for the hash */ 330 /* remove the reference for the hash */
294 batadv_tt_local_entry_free_ref(tt_local_entry); 331 batadv_tt_local_entry_free_ref(tt_local);
295 goto out; 332 goto out;
296 } 333 }
297 334
298 batadv_tt_local_event(bat_priv, addr, tt_local_entry->common.flags); 335add_event:
336 batadv_tt_local_event(bat_priv, addr, tt_local->common.flags);
299 337
300 /* remove address from global hash if present */ 338check_roaming:
301 tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr); 339 /* Check whether it is a roaming, but don't do anything if the roaming
302 340 * process has already been handled
303 /* Check whether it is a roaming! */ 341 */
304 if (tt_global_entry) { 342 if (tt_global && !(tt_global->common.flags & BATADV_TT_CLIENT_ROAM)) {
305 /* These node are probably going to update their tt table */ 343 /* These node are probably going to update their tt table */
306 head = &tt_global_entry->orig_list; 344 head = &tt_global->orig_list;
307 rcu_read_lock(); 345 rcu_read_lock();
308 hlist_for_each_entry_rcu(orig_entry, node, head, list) { 346 hlist_for_each_entry_rcu(orig_entry, node, head, list) {
309 orig_entry->orig_node->tt_poss_change = true; 347 batadv_send_roam_adv(bat_priv, tt_global->common.addr,
310
311 batadv_send_roam_adv(bat_priv,
312 tt_global_entry->common.addr,
313 orig_entry->orig_node); 348 orig_entry->orig_node);
314 } 349 }
315 rcu_read_unlock(); 350 rcu_read_unlock();
316 /* The global entry has to be marked as ROAMING and 351 if (roamed_back) {
317 * has to be kept for consistency purpose 352 batadv_tt_global_free(bat_priv, tt_global,
318 */ 353 "Roaming canceled");
319 tt_global_entry->common.flags |= BATADV_TT_CLIENT_ROAM; 354 tt_global = NULL;
320 tt_global_entry->roam_at = jiffies; 355 } else {
356 /* The global entry has to be marked as ROAMING and
357 * has to be kept for consistency purpose
358 */
359 tt_global->common.flags |= BATADV_TT_CLIENT_ROAM;
360 tt_global->roam_at = jiffies;
361 }
321 } 362 }
363
322out: 364out:
323 if (tt_local_entry) 365 if (tt_local)
324 batadv_tt_local_entry_free_ref(tt_local_entry); 366 batadv_tt_local_entry_free_ref(tt_local);
325 if (tt_global_entry) 367 if (tt_global)
326 batadv_tt_global_entry_free_ref(tt_global_entry); 368 batadv_tt_global_entry_free_ref(tt_global);
327} 369}
328 370
329static void batadv_tt_realloc_packet_buff(unsigned char **packet_buff, 371static void batadv_tt_realloc_packet_buff(unsigned char **packet_buff,
@@ -434,22 +476,10 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset)
434 struct hlist_node *node; 476 struct hlist_node *node;
435 struct hlist_head *head; 477 struct hlist_head *head;
436 uint32_t i; 478 uint32_t i;
437 int ret = 0;
438 479
439 primary_if = batadv_primary_if_get_selected(bat_priv); 480 primary_if = batadv_seq_print_text_primary_if_get(seq);
440 if (!primary_if) { 481 if (!primary_if)
441 ret = seq_printf(seq,
442 "BATMAN mesh %s disabled - please specify interfaces to enable it\n",
443 net_dev->name);
444 goto out;
445 }
446
447 if (primary_if->if_status != BATADV_IF_ACTIVE) {
448 ret = seq_printf(seq,
449 "BATMAN mesh %s disabled - primary interface not active\n",
450 net_dev->name);
451 goto out; 482 goto out;
452 }
453 483
454 seq_printf(seq, 484 seq_printf(seq,
455 "Locally retrieved addresses (from %s) announced via TT (TTVN: %u):\n", 485 "Locally retrieved addresses (from %s) announced via TT (TTVN: %u):\n",
@@ -479,7 +509,7 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset)
479out: 509out:
480 if (primary_if) 510 if (primary_if)
481 batadv_hardif_free_ref(primary_if); 511 batadv_hardif_free_ref(primary_if);
482 return ret; 512 return 0;
483} 513}
484 514
485static void 515static void
@@ -501,24 +531,57 @@ batadv_tt_local_set_pending(struct batadv_priv *bat_priv,
501 tt_local_entry->common.addr, message); 531 tt_local_entry->common.addr, message);
502} 532}
503 533
504void batadv_tt_local_remove(struct batadv_priv *bat_priv, const uint8_t *addr, 534/**
505 const char *message, bool roaming) 535 * batadv_tt_local_remove - logically remove an entry from the local table
536 * @bat_priv: the bat priv with all the soft interface information
537 * @addr: the MAC address of the client to remove
538 * @message: message to append to the log on deletion
539 * @roaming: true if the deletion is due to a roaming event
540 *
541 * Returns the flags assigned to the local entry before being deleted
542 */
543uint16_t batadv_tt_local_remove(struct batadv_priv *bat_priv,
544 const uint8_t *addr, const char *message,
545 bool roaming)
506{ 546{
507 struct batadv_tt_local_entry *tt_local_entry = NULL; 547 struct batadv_tt_local_entry *tt_local_entry;
508 uint16_t flags; 548 uint16_t flags, curr_flags = BATADV_NO_FLAGS;
509 549
510 tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr); 550 tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr);
511 if (!tt_local_entry) 551 if (!tt_local_entry)
512 goto out; 552 goto out;
513 553
554 curr_flags = tt_local_entry->common.flags;
555
514 flags = BATADV_TT_CLIENT_DEL; 556 flags = BATADV_TT_CLIENT_DEL;
515 if (roaming) 557 /* if this global entry addition is due to a roaming, the node has to
558 * mark the local entry as "roamed" in order to correctly reroute
559 * packets later
560 */
561 if (roaming) {
516 flags |= BATADV_TT_CLIENT_ROAM; 562 flags |= BATADV_TT_CLIENT_ROAM;
563 /* mark the local client as ROAMed */
564 tt_local_entry->common.flags |= BATADV_TT_CLIENT_ROAM;
565 }
566
567 if (!(tt_local_entry->common.flags & BATADV_TT_CLIENT_NEW)) {
568 batadv_tt_local_set_pending(bat_priv, tt_local_entry, flags,
569 message);
570 goto out;
571 }
572 /* if this client has been added right now, it is possible to
573 * immediately purge it
574 */
575 batadv_tt_local_event(bat_priv, tt_local_entry->common.addr,
576 curr_flags | BATADV_TT_CLIENT_DEL);
577 hlist_del_rcu(&tt_local_entry->common.hash_entry);
578 batadv_tt_local_entry_free_ref(tt_local_entry);
517 579
518 batadv_tt_local_set_pending(bat_priv, tt_local_entry, flags, message);
519out: 580out:
520 if (tt_local_entry) 581 if (tt_local_entry)
521 batadv_tt_local_entry_free_ref(tt_local_entry); 582 batadv_tt_local_entry_free_ref(tt_local_entry);
583
584 return curr_flags;
522} 585}
523 586
524static void batadv_tt_local_purge_list(struct batadv_priv *bat_priv, 587static void batadv_tt_local_purge_list(struct batadv_priv *bat_priv,
@@ -721,12 +784,23 @@ int batadv_tt_global_add(struct batadv_priv *bat_priv,
721 const unsigned char *tt_addr, uint8_t flags, 784 const unsigned char *tt_addr, uint8_t flags,
722 uint8_t ttvn) 785 uint8_t ttvn)
723{ 786{
724 struct batadv_tt_global_entry *tt_global_entry = NULL; 787 struct batadv_tt_global_entry *tt_global_entry;
788 struct batadv_tt_local_entry *tt_local_entry;
725 int ret = 0; 789 int ret = 0;
726 int hash_added; 790 int hash_added;
727 struct batadv_tt_common_entry *common; 791 struct batadv_tt_common_entry *common;
792 uint16_t local_flags;
728 793
729 tt_global_entry = batadv_tt_global_hash_find(bat_priv, tt_addr); 794 tt_global_entry = batadv_tt_global_hash_find(bat_priv, tt_addr);
795 tt_local_entry = batadv_tt_local_hash_find(bat_priv, tt_addr);
796
797 /* if the node already has a local client for this entry, it has to wait
798 * for a roaming advertisement instead of manually messing up the global
799 * table
800 */
801 if ((flags & BATADV_TT_CLIENT_TEMP) && tt_local_entry &&
802 !(tt_local_entry->common.flags & BATADV_TT_CLIENT_NEW))
803 goto out;
730 804
731 if (!tt_global_entry) { 805 if (!tt_global_entry) {
732 tt_global_entry = kzalloc(sizeof(*tt_global_entry), GFP_ATOMIC); 806 tt_global_entry = kzalloc(sizeof(*tt_global_entry), GFP_ATOMIC);
@@ -738,6 +812,12 @@ int batadv_tt_global_add(struct batadv_priv *bat_priv,
738 812
739 common->flags = flags; 813 common->flags = flags;
740 tt_global_entry->roam_at = 0; 814 tt_global_entry->roam_at = 0;
815 /* node must store current time in case of roaming. This is
816 * needed to purge this entry out on timeout (if nobody claims
817 * it)
818 */
819 if (flags & BATADV_TT_CLIENT_ROAM)
820 tt_global_entry->roam_at = jiffies;
741 atomic_set(&common->refcount, 2); 821 atomic_set(&common->refcount, 2);
742 common->added_at = jiffies; 822 common->added_at = jiffies;
743 823
@@ -755,19 +835,31 @@ int batadv_tt_global_add(struct batadv_priv *bat_priv,
755 goto out_remove; 835 goto out_remove;
756 } 836 }
757 } else { 837 } else {
838 common = &tt_global_entry->common;
758 /* If there is already a global entry, we can use this one for 839 /* If there is already a global entry, we can use this one for
759 * our processing. 840 * our processing.
760 * But if we are trying to add a temporary client we can exit 841 * But if we are trying to add a temporary client then here are
761 * directly because the temporary information should never 842 * two options at this point:
762 * override any already known client state (whatever it is) 843 * 1) the global client is not a temporary client: the global
844 * client has to be left as it is, temporary information
845 * should never override any already known client state
846 * 2) the global client is a temporary client: purge the
847 * originator list and add the new one orig_entry
763 */ 848 */
764 if (flags & BATADV_TT_CLIENT_TEMP) 849 if (flags & BATADV_TT_CLIENT_TEMP) {
765 goto out; 850 if (!(common->flags & BATADV_TT_CLIENT_TEMP))
851 goto out;
852 if (batadv_tt_global_entry_has_orig(tt_global_entry,
853 orig_node))
854 goto out_remove;
855 batadv_tt_global_del_orig_list(tt_global_entry);
856 goto add_orig_entry;
857 }
766 858
767 /* if the client was temporary added before receiving the first 859 /* if the client was temporary added before receiving the first
768 * OGM announcing it, we have to clear the TEMP flag 860 * OGM announcing it, we have to clear the TEMP flag
769 */ 861 */
770 tt_global_entry->common.flags &= ~BATADV_TT_CLIENT_TEMP; 862 common->flags &= ~BATADV_TT_CLIENT_TEMP;
771 863
772 /* the change can carry possible "attribute" flags like the 864 /* the change can carry possible "attribute" flags like the
773 * TT_CLIENT_WIFI, therefore they have to be copied in the 865 * TT_CLIENT_WIFI, therefore they have to be copied in the
@@ -782,28 +874,40 @@ int batadv_tt_global_add(struct batadv_priv *bat_priv,
782 * We should first delete the old originator before adding the 874 * We should first delete the old originator before adding the
783 * new one. 875 * new one.
784 */ 876 */
785 if (tt_global_entry->common.flags & BATADV_TT_CLIENT_ROAM) { 877 if (common->flags & BATADV_TT_CLIENT_ROAM) {
786 batadv_tt_global_del_orig_list(tt_global_entry); 878 batadv_tt_global_del_orig_list(tt_global_entry);
787 tt_global_entry->common.flags &= ~BATADV_TT_CLIENT_ROAM; 879 common->flags &= ~BATADV_TT_CLIENT_ROAM;
788 tt_global_entry->roam_at = 0; 880 tt_global_entry->roam_at = 0;
789 } 881 }
790 } 882 }
883add_orig_entry:
791 /* add the new orig_entry (if needed) or update it */ 884 /* add the new orig_entry (if needed) or update it */
792 batadv_tt_global_orig_entry_add(tt_global_entry, orig_node, ttvn); 885 batadv_tt_global_orig_entry_add(tt_global_entry, orig_node, ttvn);
793 886
794 batadv_dbg(BATADV_DBG_TT, bat_priv, 887 batadv_dbg(BATADV_DBG_TT, bat_priv,
795 "Creating new global tt entry: %pM (via %pM)\n", 888 "Creating new global tt entry: %pM (via %pM)\n",
796 tt_global_entry->common.addr, orig_node->orig); 889 common->addr, orig_node->orig);
890 ret = 1;
797 891
798out_remove: 892out_remove:
893
799 /* remove address from local hash if present */ 894 /* remove address from local hash if present */
800 batadv_tt_local_remove(bat_priv, tt_global_entry->common.addr, 895 local_flags = batadv_tt_local_remove(bat_priv, tt_addr,
801 "global tt received", 896 "global tt received",
802 flags & BATADV_TT_CLIENT_ROAM); 897 !!(flags & BATADV_TT_CLIENT_ROAM));
803 ret = 1; 898 tt_global_entry->common.flags |= local_flags & BATADV_TT_CLIENT_WIFI;
899
900 if (!(flags & BATADV_TT_CLIENT_ROAM))
901 /* this is a normal global add. Therefore the client is not in a
902 * roaming state anymore.
903 */
904 tt_global_entry->common.flags &= ~BATADV_TT_CLIENT_ROAM;
905
804out: 906out:
805 if (tt_global_entry) 907 if (tt_global_entry)
806 batadv_tt_global_entry_free_ref(tt_global_entry); 908 batadv_tt_global_entry_free_ref(tt_global_entry);
909 if (tt_local_entry)
910 batadv_tt_local_entry_free_ref(tt_local_entry);
807 return ret; 911 return ret;
808} 912}
809 913
@@ -848,22 +952,10 @@ int batadv_tt_global_seq_print_text(struct seq_file *seq, void *offset)
848 struct hlist_node *node; 952 struct hlist_node *node;
849 struct hlist_head *head; 953 struct hlist_head *head;
850 uint32_t i; 954 uint32_t i;
851 int ret = 0;
852 955
853 primary_if = batadv_primary_if_get_selected(bat_priv); 956 primary_if = batadv_seq_print_text_primary_if_get(seq);
854 if (!primary_if) { 957 if (!primary_if)
855 ret = seq_printf(seq,
856 "BATMAN mesh %s disabled - please specify interfaces to enable it\n",
857 net_dev->name);
858 goto out; 958 goto out;
859 }
860
861 if (primary_if->if_status != BATADV_IF_ACTIVE) {
862 ret = seq_printf(seq,
863 "BATMAN mesh %s disabled - primary interface not active\n",
864 net_dev->name);
865 goto out;
866 }
867 959
868 seq_printf(seq, 960 seq_printf(seq,
869 "Globally announced TT entries received via the mesh %s\n", 961 "Globally announced TT entries received via the mesh %s\n",
@@ -887,7 +979,7 @@ int batadv_tt_global_seq_print_text(struct seq_file *seq, void *offset)
887out: 979out:
888 if (primary_if) 980 if (primary_if)
889 batadv_hardif_free_ref(primary_if); 981 batadv_hardif_free_ref(primary_if);
890 return ret; 982 return 0;
891} 983}
892 984
893/* deletes the orig list of a tt_global_entry */ 985/* deletes the orig list of a tt_global_entry */
@@ -933,21 +1025,6 @@ batadv_tt_global_del_orig_entry(struct batadv_priv *bat_priv,
933 spin_unlock_bh(&tt_global_entry->list_lock); 1025 spin_unlock_bh(&tt_global_entry->list_lock);
934} 1026}
935 1027
936static void
937batadv_tt_global_del_struct(struct batadv_priv *bat_priv,
938 struct batadv_tt_global_entry *tt_global_entry,
939 const char *message)
940{
941 batadv_dbg(BATADV_DBG_TT, bat_priv,
942 "Deleting global tt entry %pM: %s\n",
943 tt_global_entry->common.addr, message);
944
945 batadv_hash_remove(bat_priv->tt.global_hash, batadv_compare_tt,
946 batadv_choose_orig, tt_global_entry->common.addr);
947 batadv_tt_global_entry_free_ref(tt_global_entry);
948
949}
950
951/* If the client is to be deleted, we check if it is the last origantor entry 1028/* If the client is to be deleted, we check if it is the last origantor entry
952 * within tt_global entry. If yes, we set the BATADV_TT_CLIENT_ROAM flag and the 1029 * within tt_global entry. If yes, we set the BATADV_TT_CLIENT_ROAM flag and the
953 * timer, otherwise we simply remove the originator scheduled for deletion. 1030 * timer, otherwise we simply remove the originator scheduled for deletion.
@@ -996,7 +1073,7 @@ static void batadv_tt_global_del(struct batadv_priv *bat_priv,
996 const unsigned char *addr, 1073 const unsigned char *addr,
997 const char *message, bool roaming) 1074 const char *message, bool roaming)
998{ 1075{
999 struct batadv_tt_global_entry *tt_global_entry = NULL; 1076 struct batadv_tt_global_entry *tt_global_entry;
1000 struct batadv_tt_local_entry *local_entry = NULL; 1077 struct batadv_tt_local_entry *local_entry = NULL;
1001 1078
1002 tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr); 1079 tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr);
@@ -1008,8 +1085,8 @@ static void batadv_tt_global_del(struct batadv_priv *bat_priv,
1008 orig_node, message); 1085 orig_node, message);
1009 1086
1010 if (hlist_empty(&tt_global_entry->orig_list)) 1087 if (hlist_empty(&tt_global_entry->orig_list))
1011 batadv_tt_global_del_struct(bat_priv, tt_global_entry, 1088 batadv_tt_global_free(bat_priv, tt_global_entry,
1012 message); 1089 message);
1013 1090
1014 goto out; 1091 goto out;
1015 } 1092 }
@@ -1032,7 +1109,7 @@ static void batadv_tt_global_del(struct batadv_priv *bat_priv,
1032 if (local_entry) { 1109 if (local_entry) {
1033 /* local entry exists, case 2: client roamed to us. */ 1110 /* local entry exists, case 2: client roamed to us. */
1034 batadv_tt_global_del_orig_list(tt_global_entry); 1111 batadv_tt_global_del_orig_list(tt_global_entry);
1035 batadv_tt_global_del_struct(bat_priv, tt_global_entry, message); 1112 batadv_tt_global_free(bat_priv, tt_global_entry, message);
1036 } else 1113 } else
1037 /* no local entry exists, case 1: check for roaming */ 1114 /* no local entry exists, case 1: check for roaming */
1038 batadv_tt_global_del_roaming(bat_priv, tt_global_entry, 1115 batadv_tt_global_del_roaming(bat_priv, tt_global_entry,
@@ -1211,7 +1288,8 @@ struct batadv_orig_node *batadv_transtable_search(struct batadv_priv *bat_priv,
1211 1288
1212 if (src && atomic_read(&bat_priv->ap_isolation)) { 1289 if (src && atomic_read(&bat_priv->ap_isolation)) {
1213 tt_local_entry = batadv_tt_local_hash_find(bat_priv, src); 1290 tt_local_entry = batadv_tt_local_hash_find(bat_priv, src);
1214 if (!tt_local_entry) 1291 if (!tt_local_entry ||
1292 (tt_local_entry->common.flags & BATADV_TT_CLIENT_PENDING))
1215 goto out; 1293 goto out;
1216 } 1294 }
1217 1295
@@ -1477,11 +1555,11 @@ batadv_tt_response_fill_table(uint16_t tt_len, uint8_t ttvn,
1477 tt_tot = tt_len / sizeof(struct batadv_tt_change); 1555 tt_tot = tt_len / sizeof(struct batadv_tt_change);
1478 1556
1479 len = tt_query_size + tt_len; 1557 len = tt_query_size + tt_len;
1480 skb = dev_alloc_skb(len + ETH_HLEN); 1558 skb = dev_alloc_skb(len + ETH_HLEN + NET_IP_ALIGN);
1481 if (!skb) 1559 if (!skb)
1482 goto out; 1560 goto out;
1483 1561
1484 skb_reserve(skb, ETH_HLEN); 1562 skb_reserve(skb, ETH_HLEN + NET_IP_ALIGN);
1485 tt_response = (struct batadv_tt_query_packet *)skb_put(skb, len); 1563 tt_response = (struct batadv_tt_query_packet *)skb_put(skb, len);
1486 tt_response->ttvn = ttvn; 1564 tt_response->ttvn = ttvn;
1487 1565
@@ -1543,11 +1621,11 @@ static int batadv_send_tt_request(struct batadv_priv *bat_priv,
1543 if (!tt_req_node) 1621 if (!tt_req_node)
1544 goto out; 1622 goto out;
1545 1623
1546 skb = dev_alloc_skb(sizeof(*tt_request) + ETH_HLEN); 1624 skb = dev_alloc_skb(sizeof(*tt_request) + ETH_HLEN + NET_IP_ALIGN);
1547 if (!skb) 1625 if (!skb)
1548 goto out; 1626 goto out;
1549 1627
1550 skb_reserve(skb, ETH_HLEN); 1628 skb_reserve(skb, ETH_HLEN + NET_IP_ALIGN);
1551 1629
1552 tt_req_len = sizeof(*tt_request); 1630 tt_req_len = sizeof(*tt_request);
1553 tt_request = (struct batadv_tt_query_packet *)skb_put(skb, tt_req_len); 1631 tt_request = (struct batadv_tt_query_packet *)skb_put(skb, tt_req_len);
@@ -1598,7 +1676,7 @@ static bool
1598batadv_send_other_tt_response(struct batadv_priv *bat_priv, 1676batadv_send_other_tt_response(struct batadv_priv *bat_priv,
1599 struct batadv_tt_query_packet *tt_request) 1677 struct batadv_tt_query_packet *tt_request)
1600{ 1678{
1601 struct batadv_orig_node *req_dst_orig_node = NULL; 1679 struct batadv_orig_node *req_dst_orig_node;
1602 struct batadv_orig_node *res_dst_orig_node = NULL; 1680 struct batadv_orig_node *res_dst_orig_node = NULL;
1603 struct batadv_neigh_node *neigh_node = NULL; 1681 struct batadv_neigh_node *neigh_node = NULL;
1604 struct batadv_hard_iface *primary_if = NULL; 1682 struct batadv_hard_iface *primary_if = NULL;
@@ -1658,11 +1736,11 @@ batadv_send_other_tt_response(struct batadv_priv *bat_priv,
1658 tt_tot = tt_len / sizeof(struct batadv_tt_change); 1736 tt_tot = tt_len / sizeof(struct batadv_tt_change);
1659 1737
1660 len = sizeof(*tt_response) + tt_len; 1738 len = sizeof(*tt_response) + tt_len;
1661 skb = dev_alloc_skb(len + ETH_HLEN); 1739 skb = dev_alloc_skb(len + ETH_HLEN + NET_IP_ALIGN);
1662 if (!skb) 1740 if (!skb)
1663 goto unlock; 1741 goto unlock;
1664 1742
1665 skb_reserve(skb, ETH_HLEN); 1743 skb_reserve(skb, ETH_HLEN + NET_IP_ALIGN);
1666 packet_pos = skb_put(skb, len); 1744 packet_pos = skb_put(skb, len);
1667 tt_response = (struct batadv_tt_query_packet *)packet_pos; 1745 tt_response = (struct batadv_tt_query_packet *)packet_pos;
1668 tt_response->ttvn = req_ttvn; 1746 tt_response->ttvn = req_ttvn;
@@ -1733,7 +1811,7 @@ static bool
1733batadv_send_my_tt_response(struct batadv_priv *bat_priv, 1811batadv_send_my_tt_response(struct batadv_priv *bat_priv,
1734 struct batadv_tt_query_packet *tt_request) 1812 struct batadv_tt_query_packet *tt_request)
1735{ 1813{
1736 struct batadv_orig_node *orig_node = NULL; 1814 struct batadv_orig_node *orig_node;
1737 struct batadv_neigh_node *neigh_node = NULL; 1815 struct batadv_neigh_node *neigh_node = NULL;
1738 struct batadv_hard_iface *primary_if = NULL; 1816 struct batadv_hard_iface *primary_if = NULL;
1739 uint8_t my_ttvn, req_ttvn, ttvn; 1817 uint8_t my_ttvn, req_ttvn, ttvn;
@@ -1785,11 +1863,11 @@ batadv_send_my_tt_response(struct batadv_priv *bat_priv,
1785 tt_tot = tt_len / sizeof(struct batadv_tt_change); 1863 tt_tot = tt_len / sizeof(struct batadv_tt_change);
1786 1864
1787 len = sizeof(*tt_response) + tt_len; 1865 len = sizeof(*tt_response) + tt_len;
1788 skb = dev_alloc_skb(len + ETH_HLEN); 1866 skb = dev_alloc_skb(len + ETH_HLEN + NET_IP_ALIGN);
1789 if (!skb) 1867 if (!skb)
1790 goto unlock; 1868 goto unlock;
1791 1869
1792 skb_reserve(skb, ETH_HLEN); 1870 skb_reserve(skb, ETH_HLEN + NET_IP_ALIGN);
1793 packet_pos = skb_put(skb, len); 1871 packet_pos = skb_put(skb, len);
1794 tt_response = (struct batadv_tt_query_packet *)packet_pos; 1872 tt_response = (struct batadv_tt_query_packet *)packet_pos;
1795 tt_response->ttvn = req_ttvn; 1873 tt_response->ttvn = req_ttvn;
@@ -1899,7 +1977,7 @@ static void _batadv_tt_update_changes(struct batadv_priv *bat_priv,
1899static void batadv_tt_fill_gtable(struct batadv_priv *bat_priv, 1977static void batadv_tt_fill_gtable(struct batadv_priv *bat_priv,
1900 struct batadv_tt_query_packet *tt_response) 1978 struct batadv_tt_query_packet *tt_response)
1901{ 1979{
1902 struct batadv_orig_node *orig_node = NULL; 1980 struct batadv_orig_node *orig_node;
1903 1981
1904 orig_node = batadv_orig_hash_find(bat_priv, tt_response->src); 1982 orig_node = batadv_orig_hash_find(bat_priv, tt_response->src);
1905 if (!orig_node) 1983 if (!orig_node)
@@ -1941,7 +2019,7 @@ static void batadv_tt_update_changes(struct batadv_priv *bat_priv,
1941 2019
1942bool batadv_is_my_client(struct batadv_priv *bat_priv, const uint8_t *addr) 2020bool batadv_is_my_client(struct batadv_priv *bat_priv, const uint8_t *addr)
1943{ 2021{
1944 struct batadv_tt_local_entry *tt_local_entry = NULL; 2022 struct batadv_tt_local_entry *tt_local_entry;
1945 bool ret = false; 2023 bool ret = false;
1946 2024
1947 tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr); 2025 tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr);
@@ -1950,7 +2028,8 @@ bool batadv_is_my_client(struct batadv_priv *bat_priv, const uint8_t *addr)
1950 /* Check if the client has been logically deleted (but is kept for 2028 /* Check if the client has been logically deleted (but is kept for
1951 * consistency purpose) 2029 * consistency purpose)
1952 */ 2030 */
1953 if (tt_local_entry->common.flags & BATADV_TT_CLIENT_PENDING) 2031 if ((tt_local_entry->common.flags & BATADV_TT_CLIENT_PENDING) ||
2032 (tt_local_entry->common.flags & BATADV_TT_CLIENT_ROAM))
1954 goto out; 2033 goto out;
1955 ret = true; 2034 ret = true;
1956out: 2035out:
@@ -2001,10 +2080,6 @@ void batadv_handle_tt_response(struct batadv_priv *bat_priv,
2001 2080
2002 /* Recalculate the CRC for this orig_node and store it */ 2081 /* Recalculate the CRC for this orig_node and store it */
2003 orig_node->tt_crc = batadv_tt_global_crc(bat_priv, orig_node); 2082 orig_node->tt_crc = batadv_tt_global_crc(bat_priv, orig_node);
2004 /* Roaming phase is over: tables are in sync again. I can
2005 * unset the flag
2006 */
2007 orig_node->tt_poss_change = false;
2008out: 2083out:
2009 if (orig_node) 2084 if (orig_node)
2010 batadv_orig_node_free_ref(orig_node); 2085 batadv_orig_node_free_ref(orig_node);
@@ -2123,11 +2198,11 @@ static void batadv_send_roam_adv(struct batadv_priv *bat_priv, uint8_t *client,
2123 if (!batadv_tt_check_roam_count(bat_priv, client)) 2198 if (!batadv_tt_check_roam_count(bat_priv, client))
2124 goto out; 2199 goto out;
2125 2200
2126 skb = dev_alloc_skb(sizeof(*roam_adv_packet) + ETH_HLEN); 2201 skb = dev_alloc_skb(sizeof(*roam_adv_packet) + ETH_HLEN + NET_IP_ALIGN);
2127 if (!skb) 2202 if (!skb)
2128 goto out; 2203 goto out;
2129 2204
2130 skb_reserve(skb, ETH_HLEN); 2205 skb_reserve(skb, ETH_HLEN + NET_IP_ALIGN);
2131 2206
2132 roam_adv_packet = (struct batadv_roam_adv_packet *)skb_put(skb, len); 2207 roam_adv_packet = (struct batadv_roam_adv_packet *)skb_put(skb, len);
2133 2208
@@ -2295,7 +2370,6 @@ static int batadv_tt_commit_changes(struct batadv_priv *bat_priv,
2295 batadv_dbg(BATADV_DBG_TT, bat_priv, 2370 batadv_dbg(BATADV_DBG_TT, bat_priv,
2296 "Local changes committed, updating to ttvn %u\n", 2371 "Local changes committed, updating to ttvn %u\n",
2297 (uint8_t)atomic_read(&bat_priv->tt.vn)); 2372 (uint8_t)atomic_read(&bat_priv->tt.vn));
2298 bat_priv->tt.poss_change = false;
2299 2373
2300 /* reset the sending counter */ 2374 /* reset the sending counter */
2301 atomic_set(&bat_priv->tt.ogm_append_cnt, BATADV_TT_OGM_APPEND_MAX); 2375 atomic_set(&bat_priv->tt.ogm_append_cnt, BATADV_TT_OGM_APPEND_MAX);
@@ -2407,11 +2481,6 @@ void batadv_tt_update_orig(struct batadv_priv *bat_priv,
2407 */ 2481 */
2408 if (orig_node->tt_crc != tt_crc) 2482 if (orig_node->tt_crc != tt_crc)
2409 goto request_table; 2483 goto request_table;
2410
2411 /* Roaming phase is over: tables are in sync again. I can
2412 * unset the flag
2413 */
2414 orig_node->tt_poss_change = false;
2415 } else { 2484 } else {
2416 /* if we missed more than one change or our tables are not 2485 /* if we missed more than one change or our tables are not
2417 * in sync anymore -> request fresh tt data 2486 * in sync anymore -> request fresh tt data
@@ -2444,12 +2513,38 @@ bool batadv_tt_global_client_is_roaming(struct batadv_priv *bat_priv,
2444 if (!tt_global_entry) 2513 if (!tt_global_entry)
2445 goto out; 2514 goto out;
2446 2515
2447 ret = tt_global_entry->common.flags & BATADV_TT_CLIENT_ROAM; 2516 ret = !!(tt_global_entry->common.flags & BATADV_TT_CLIENT_ROAM);
2448 batadv_tt_global_entry_free_ref(tt_global_entry); 2517 batadv_tt_global_entry_free_ref(tt_global_entry);
2449out: 2518out:
2450 return ret; 2519 return ret;
2451} 2520}
2452 2521
2522/**
2523 * batadv_tt_local_client_is_roaming - tells whether the client is roaming
2524 * @bat_priv: the bat priv with all the soft interface information
2525 * @addr: the MAC address of the local client to query
2526 *
2527 * Returns true if the local client is known to be roaming (it is not served by
2528 * this node anymore) or not. If yes, the client is still present in the table
2529 * to keep the latter consistent with the node TTVN
2530 */
2531bool batadv_tt_local_client_is_roaming(struct batadv_priv *bat_priv,
2532 uint8_t *addr)
2533{
2534 struct batadv_tt_local_entry *tt_local_entry;
2535 bool ret = false;
2536
2537 tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr);
2538 if (!tt_local_entry)
2539 goto out;
2540
2541 ret = tt_local_entry->common.flags & BATADV_TT_CLIENT_ROAM;
2542 batadv_tt_local_entry_free_ref(tt_local_entry);
2543out:
2544 return ret;
2545
2546}
2547
2453bool batadv_tt_add_temporary_global_entry(struct batadv_priv *bat_priv, 2548bool batadv_tt_add_temporary_global_entry(struct batadv_priv *bat_priv,
2454 struct batadv_orig_node *orig_node, 2549 struct batadv_orig_node *orig_node,
2455 const unsigned char *addr) 2550 const unsigned char *addr)
diff --git a/net/batman-adv/translation-table.h b/net/batman-adv/translation-table.h
index 811fffd4760c..46d4451a59ee 100644
--- a/net/batman-adv/translation-table.h
+++ b/net/batman-adv/translation-table.h
@@ -24,9 +24,9 @@ int batadv_tt_len(int changes_num);
24int batadv_tt_init(struct batadv_priv *bat_priv); 24int batadv_tt_init(struct batadv_priv *bat_priv);
25void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr, 25void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
26 int ifindex); 26 int ifindex);
27void batadv_tt_local_remove(struct batadv_priv *bat_priv, 27uint16_t batadv_tt_local_remove(struct batadv_priv *bat_priv,
28 const uint8_t *addr, const char *message, 28 const uint8_t *addr, const char *message,
29 bool roaming); 29 bool roaming);
30int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset); 30int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset);
31void batadv_tt_global_add_orig(struct batadv_priv *bat_priv, 31void batadv_tt_global_add_orig(struct batadv_priv *bat_priv,
32 struct batadv_orig_node *orig_node, 32 struct batadv_orig_node *orig_node,
@@ -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);
62bool batadv_tt_local_client_is_roaming(struct batadv_priv *bat_priv,
63 uint8_t *addr);
62bool batadv_tt_add_temporary_global_entry(struct batadv_priv *bat_priv, 64bool batadv_tt_add_temporary_global_entry(struct batadv_priv *bat_priv,
63 struct batadv_orig_node *orig_node, 65 struct batadv_orig_node *orig_node,
64 const unsigned char *addr); 66 const unsigned char *addr);
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index ac1e07a80454..7b3d0d7ef06a 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -28,20 +28,41 @@
28 (ETH_HLEN + max(sizeof(struct batadv_unicast_packet), \ 28 (ETH_HLEN + max(sizeof(struct batadv_unicast_packet), \
29 sizeof(struct batadv_bcast_packet))) 29 sizeof(struct batadv_bcast_packet)))
30 30
31#ifdef CONFIG_BATMAN_ADV_DAT
32
33/* batadv_dat_addr_t is the type used for all DHT addresses. If it is changed,
34 * BATADV_DAT_ADDR_MAX is changed as well.
35 *
36 * *Please be careful: batadv_dat_addr_t must be UNSIGNED*
37 */
38#define batadv_dat_addr_t uint16_t
39
40#endif /* CONFIG_BATMAN_ADV_DAT */
41
42/**
43 * struct batadv_hard_iface_bat_iv - per hard interface B.A.T.M.A.N. IV data
44 * @ogm_buff: buffer holding the OGM packet
45 * @ogm_buff_len: length of the OGM packet buffer
46 * @ogm_seqno: OGM sequence number - used to identify each OGM
47 */
48struct batadv_hard_iface_bat_iv {
49 unsigned char *ogm_buff;
50 int ogm_buff_len;
51 atomic_t ogm_seqno;
52};
53
31struct batadv_hard_iface { 54struct batadv_hard_iface {
32 struct list_head list; 55 struct list_head list;
33 int16_t if_num; 56 int16_t if_num;
34 char if_status; 57 char if_status;
35 struct net_device *net_dev; 58 struct net_device *net_dev;
36 atomic_t seqno;
37 atomic_t frag_seqno; 59 atomic_t frag_seqno;
38 unsigned char *packet_buff;
39 int packet_len;
40 struct kobject *hardif_obj; 60 struct kobject *hardif_obj;
41 atomic_t refcount; 61 atomic_t refcount;
42 struct packet_type batman_adv_ptype; 62 struct packet_type batman_adv_ptype;
43 struct net_device *soft_iface; 63 struct net_device *soft_iface;
44 struct rcu_head rcu; 64 struct rcu_head rcu;
65 struct batadv_hard_iface_bat_iv bat_iv;
45}; 66};
46 67
47/** 68/**
@@ -63,6 +84,9 @@ struct batadv_orig_node {
63 uint8_t orig[ETH_ALEN]; 84 uint8_t orig[ETH_ALEN];
64 uint8_t primary_addr[ETH_ALEN]; 85 uint8_t primary_addr[ETH_ALEN];
65 struct batadv_neigh_node __rcu *router; /* rcu protected pointer */ 86 struct batadv_neigh_node __rcu *router; /* rcu protected pointer */
87#ifdef CONFIG_BATMAN_ADV_DAT
88 batadv_dat_addr_t dat_addr;
89#endif
66 unsigned long *bcast_own; 90 unsigned long *bcast_own;
67 uint8_t *bcast_own_sum; 91 uint8_t *bcast_own_sum;
68 unsigned long last_seen; 92 unsigned long last_seen;
@@ -77,13 +101,6 @@ struct batadv_orig_node {
77 spinlock_t tt_buff_lock; /* protects tt_buff */ 101 spinlock_t tt_buff_lock; /* protects tt_buff */
78 atomic_t tt_size; 102 atomic_t tt_size;
79 bool tt_initialised; 103 bool tt_initialised;
80 /* The tt_poss_change flag is used to detect an ongoing roaming phase.
81 * If true, then I sent a Roaming_adv to this orig_node and I have to
82 * inspect every packet directed to it to check whether it is still
83 * the true destination or not. This flag will be reset to false as
84 * soon as I receive a new TTVN from this orig_node
85 */
86 bool tt_poss_change;
87 uint32_t last_real_seqno; 104 uint32_t last_real_seqno;
88 uint8_t last_ttl; 105 uint8_t last_ttl;
89 DECLARE_BITMAP(bcast_bits, BATADV_TQ_LOCAL_WINDOW_SIZE); 106 DECLARE_BITMAP(bcast_bits, BATADV_TQ_LOCAL_WINDOW_SIZE);
@@ -162,6 +179,13 @@ enum batadv_counters {
162 BATADV_CNT_TT_RESPONSE_RX, 179 BATADV_CNT_TT_RESPONSE_RX,
163 BATADV_CNT_TT_ROAM_ADV_TX, 180 BATADV_CNT_TT_ROAM_ADV_TX,
164 BATADV_CNT_TT_ROAM_ADV_RX, 181 BATADV_CNT_TT_ROAM_ADV_RX,
182#ifdef CONFIG_BATMAN_ADV_DAT
183 BATADV_CNT_DAT_GET_TX,
184 BATADV_CNT_DAT_GET_RX,
185 BATADV_CNT_DAT_PUT_TX,
186 BATADV_CNT_DAT_PUT_RX,
187 BATADV_CNT_DAT_CACHED_REPLY_TX,
188#endif
165 BATADV_CNT_NUM, 189 BATADV_CNT_NUM,
166}; 190};
167 191
@@ -181,7 +205,6 @@ struct batadv_priv_tt {
181 atomic_t vn; 205 atomic_t vn;
182 atomic_t ogm_append_cnt; 206 atomic_t ogm_append_cnt;
183 atomic_t local_changes; 207 atomic_t local_changes;
184 bool poss_change;
185 struct list_head changes_list; 208 struct list_head changes_list;
186 struct batadv_hashtable *local_hash; 209 struct batadv_hashtable *local_hash;
187 struct batadv_hashtable *global_hash; 210 struct batadv_hashtable *global_hash;
@@ -228,6 +251,20 @@ struct batadv_priv_vis {
228 struct batadv_vis_info *my_info; 251 struct batadv_vis_info *my_info;
229}; 252};
230 253
254/**
255 * struct batadv_priv_dat - per mesh interface DAT private data
256 * @addr: node DAT address
257 * @hash: hashtable representing the local ARP cache
258 * @work: work queue callback item for cache purging
259 */
260#ifdef CONFIG_BATMAN_ADV_DAT
261struct batadv_priv_dat {
262 batadv_dat_addr_t addr;
263 struct batadv_hashtable *hash;
264 struct delayed_work work;
265};
266#endif
267
231struct batadv_priv { 268struct batadv_priv {
232 atomic_t mesh_state; 269 atomic_t mesh_state;
233 struct net_device_stats stats; 270 struct net_device_stats stats;
@@ -237,6 +274,9 @@ struct batadv_priv {
237 atomic_t fragmentation; /* boolean */ 274 atomic_t fragmentation; /* boolean */
238 atomic_t ap_isolation; /* boolean */ 275 atomic_t ap_isolation; /* boolean */
239 atomic_t bridge_loop_avoidance; /* boolean */ 276 atomic_t bridge_loop_avoidance; /* boolean */
277#ifdef CONFIG_BATMAN_ADV_DAT
278 atomic_t distributed_arp_table; /* boolean */
279#endif
240 atomic_t vis_mode; /* VIS_TYPE_* */ 280 atomic_t vis_mode; /* VIS_TYPE_* */
241 atomic_t gw_mode; /* GW_MODE_* */ 281 atomic_t gw_mode; /* GW_MODE_* */
242 atomic_t gw_sel_class; /* uint */ 282 atomic_t gw_sel_class; /* uint */
@@ -255,7 +295,7 @@ struct batadv_priv {
255 struct hlist_head forw_bcast_list; 295 struct hlist_head forw_bcast_list;
256 struct batadv_hashtable *orig_hash; 296 struct batadv_hashtable *orig_hash;
257 spinlock_t forw_bat_list_lock; /* protects forw_bat_list */ 297 spinlock_t forw_bat_list_lock; /* protects forw_bat_list */
258 spinlock_t forw_bcast_list_lock; /* protects */ 298 spinlock_t forw_bcast_list_lock; /* protects forw_bcast_list */
259 struct delayed_work orig_work; 299 struct delayed_work orig_work;
260 struct batadv_hard_iface __rcu *primary_if; /* rcu protected pointer */ 300 struct batadv_hard_iface __rcu *primary_if; /* rcu protected pointer */
261 struct batadv_algo_ops *bat_algo_ops; 301 struct batadv_algo_ops *bat_algo_ops;
@@ -265,6 +305,9 @@ struct batadv_priv {
265 struct batadv_priv_gw gw; 305 struct batadv_priv_gw gw;
266 struct batadv_priv_tt tt; 306 struct batadv_priv_tt tt;
267 struct batadv_priv_vis vis; 307 struct batadv_priv_vis vis;
308#ifdef CONFIG_BATMAN_ADV_DAT
309 struct batadv_priv_dat dat;
310#endif
268}; 311};
269 312
270struct batadv_socket_client { 313struct batadv_socket_client {
@@ -318,6 +361,7 @@ struct batadv_backbone_gw {
318 struct hlist_node hash_entry; 361 struct hlist_node hash_entry;
319 struct batadv_priv *bat_priv; 362 struct batadv_priv *bat_priv;
320 unsigned long lasttime; /* last time we heard of this backbone gw */ 363 unsigned long lasttime; /* last time we heard of this backbone gw */
364 atomic_t wait_periods;
321 atomic_t request_sent; 365 atomic_t request_sent;
322 atomic_t refcount; 366 atomic_t refcount;
323 struct rcu_head rcu; 367 struct rcu_head rcu;
@@ -437,4 +481,36 @@ struct batadv_algo_ops {
437 void (*bat_ogm_emit)(struct batadv_forw_packet *forw_packet); 481 void (*bat_ogm_emit)(struct batadv_forw_packet *forw_packet);
438}; 482};
439 483
484/**
485 * struct batadv_dat_entry - it is a single entry of batman-adv ARP backend. It
486 * is used to stored ARP entries needed for the global DAT cache
487 * @ip: the IPv4 corresponding to this DAT/ARP entry
488 * @mac_addr: the MAC address associated to the stored IPv4
489 * @last_update: time in jiffies when this entry was refreshed last time
490 * @hash_entry: hlist node for batadv_priv_dat::hash
491 * @refcount: number of contexts the object is used
492 * @rcu: struct used for freeing in an RCU-safe manner
493 */
494struct batadv_dat_entry {
495 __be32 ip;
496 uint8_t mac_addr[ETH_ALEN];
497 unsigned long last_update;
498 struct hlist_node hash_entry;
499 atomic_t refcount;
500 struct rcu_head rcu;
501};
502
503/**
504 * struct batadv_dat_candidate - candidate destination for DAT operations
505 * @type: the type of the selected candidate. It can one of the following:
506 * - BATADV_DAT_CANDIDATE_NOT_FOUND
507 * - BATADV_DAT_CANDIDATE_ORIG
508 * @orig_node: if type is BATADV_DAT_CANDIDATE_ORIG this field points to the
509 * corresponding originator node structure
510 */
511struct batadv_dat_candidate {
512 int type;
513 struct batadv_orig_node *orig_node;
514};
515
440#endif /* _NET_BATMAN_ADV_TYPES_H_ */ 516#endif /* _NET_BATMAN_ADV_TYPES_H_ */
diff --git a/net/batman-adv/unicast.c b/net/batman-adv/unicast.c
index f39723281ca1..c9a1f6523c36 100644
--- a/net/batman-adv/unicast.c
+++ b/net/batman-adv/unicast.c
@@ -291,7 +291,111 @@ out:
291 return ret; 291 return ret;
292} 292}
293 293
294int batadv_unicast_send_skb(struct sk_buff *skb, struct batadv_priv *bat_priv) 294/**
295 * batadv_unicast_push_and_fill_skb - extends the buffer and initializes the
296 * common fields for unicast packets
297 * @skb: packet
298 * @hdr_size: amount of bytes to push at the beginning of the skb
299 * @orig_node: the destination node
300 *
301 * Returns false if the buffer extension was not possible or true otherwise
302 */
303static bool batadv_unicast_push_and_fill_skb(struct sk_buff *skb, int hdr_size,
304 struct batadv_orig_node *orig_node)
305{
306 struct batadv_unicast_packet *unicast_packet;
307 uint8_t ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn);
308
309 if (batadv_skb_head_push(skb, hdr_size) < 0)
310 return false;
311
312 unicast_packet = (struct batadv_unicast_packet *)skb->data;
313 unicast_packet->header.version = BATADV_COMPAT_VERSION;
314 /* batman packet type: unicast */
315 unicast_packet->header.packet_type = BATADV_UNICAST;
316 /* set unicast ttl */
317 unicast_packet->header.ttl = BATADV_TTL;
318 /* copy the destination for faster routing */
319 memcpy(unicast_packet->dest, orig_node->orig, ETH_ALEN);
320 /* set the destination tt version number */
321 unicast_packet->ttvn = ttvn;
322
323 return true;
324}
325
326/**
327 * batadv_unicast_prepare_skb - encapsulate an skb with a unicast header
328 * @skb: the skb containing the payload to encapsulate
329 * @orig_node: the destination node
330 *
331 * Returns false if the payload could not be encapsulated or true otherwise
332 */
333static bool batadv_unicast_prepare_skb(struct sk_buff *skb,
334 struct batadv_orig_node *orig_node)
335{
336 size_t uni_size = sizeof(struct batadv_unicast_packet);
337 return batadv_unicast_push_and_fill_skb(skb, uni_size, orig_node);
338}
339
340/**
341 * batadv_unicast_4addr_prepare_skb - encapsulate an skb with a unicast4addr
342 * header
343 * @bat_priv: the bat priv with all the soft interface information
344 * @skb: the skb containing the payload to encapsulate
345 * @orig_node: the destination node
346 * @packet_subtype: the batman 4addr packet subtype to use
347 *
348 * Returns false if the payload could not be encapsulated or true otherwise
349 */
350bool batadv_unicast_4addr_prepare_skb(struct batadv_priv *bat_priv,
351 struct sk_buff *skb,
352 struct batadv_orig_node *orig,
353 int packet_subtype)
354{
355 struct batadv_hard_iface *primary_if;
356 struct batadv_unicast_4addr_packet *unicast_4addr_packet;
357 bool ret = false;
358
359 primary_if = batadv_primary_if_get_selected(bat_priv);
360 if (!primary_if)
361 goto out;
362
363 /* pull the header space and fill the unicast_packet substructure.
364 * We can do that because the first member of the unicast_4addr_packet
365 * is of type struct unicast_packet
366 */
367 if (!batadv_unicast_push_and_fill_skb(skb,
368 sizeof(*unicast_4addr_packet),
369 orig))
370 goto out;
371
372 unicast_4addr_packet = (struct batadv_unicast_4addr_packet *)skb->data;
373 unicast_4addr_packet->u.header.packet_type = BATADV_UNICAST_4ADDR;
374 memcpy(unicast_4addr_packet->src, primary_if->net_dev->dev_addr,
375 ETH_ALEN);
376 unicast_4addr_packet->subtype = packet_subtype;
377 unicast_4addr_packet->reserved = 0;
378
379 ret = true;
380out:
381 if (primary_if)
382 batadv_hardif_free_ref(primary_if);
383 return ret;
384}
385
386/**
387 * batadv_unicast_generic_send_skb - send an skb as unicast
388 * @bat_priv: the bat priv with all the soft interface information
389 * @skb: payload to send
390 * @packet_type: the batman unicast packet type to use
391 * @packet_subtype: the batman packet subtype. It is ignored if packet_type is
392 * not BATADV_UNICAT_4ADDR
393 *
394 * Returns 1 in case of error or 0 otherwise
395 */
396int batadv_unicast_generic_send_skb(struct batadv_priv *bat_priv,
397 struct sk_buff *skb, int packet_type,
398 int packet_subtype)
295{ 399{
296 struct ethhdr *ethhdr = (struct ethhdr *)skb->data; 400 struct ethhdr *ethhdr = (struct ethhdr *)skb->data;
297 struct batadv_unicast_packet *unicast_packet; 401 struct batadv_unicast_packet *unicast_packet;
@@ -324,21 +428,23 @@ find_router:
324 if (!neigh_node) 428 if (!neigh_node)
325 goto out; 429 goto out;
326 430
327 if (batadv_skb_head_push(skb, sizeof(*unicast_packet)) < 0) 431 switch (packet_type) {
432 case BATADV_UNICAST:
433 batadv_unicast_prepare_skb(skb, orig_node);
434 break;
435 case BATADV_UNICAST_4ADDR:
436 batadv_unicast_4addr_prepare_skb(bat_priv, skb, orig_node,
437 packet_subtype);
438 break;
439 default:
440 /* this function supports UNICAST and UNICAST_4ADDR only. It
441 * should never be invoked with any other packet type
442 */
328 goto out; 443 goto out;
444 }
329 445
330 unicast_packet = (struct batadv_unicast_packet *)skb->data; 446 unicast_packet = (struct batadv_unicast_packet *)skb->data;
331 447
332 unicast_packet->header.version = BATADV_COMPAT_VERSION;
333 /* batman packet type: unicast */
334 unicast_packet->header.packet_type = BATADV_UNICAST;
335 /* set unicast ttl */
336 unicast_packet->header.ttl = BATADV_TTL;
337 /* copy the destination for faster routing */
338 memcpy(unicast_packet->dest, orig_node->orig, ETH_ALEN);
339 /* set the destination tt version number */
340 unicast_packet->ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn);
341
342 /* inform the destination node that we are still missing a correct route 448 /* inform the destination node that we are still missing a correct route
343 * for this client. The destination will receive this packet and will 449 * for this client. The destination will receive this packet and will
344 * try to reroute it because the ttvn contained in the header is less 450 * try to reroute it because the ttvn contained in the header is less
@@ -348,7 +454,9 @@ find_router:
348 unicast_packet->ttvn = unicast_packet->ttvn - 1; 454 unicast_packet->ttvn = unicast_packet->ttvn - 1;
349 455
350 dev_mtu = neigh_node->if_incoming->net_dev->mtu; 456 dev_mtu = neigh_node->if_incoming->net_dev->mtu;
351 if (atomic_read(&bat_priv->fragmentation) && 457 /* fragmentation mechanism only works for UNICAST (now) */
458 if (packet_type == BATADV_UNICAST &&
459 atomic_read(&bat_priv->fragmentation) &&
352 data_len + sizeof(*unicast_packet) > dev_mtu) { 460 data_len + sizeof(*unicast_packet) > dev_mtu) {
353 /* send frag skb decreases ttl */ 461 /* send frag skb decreases ttl */
354 unicast_packet->header.ttl++; 462 unicast_packet->header.ttl++;
@@ -360,7 +468,6 @@ find_router:
360 468
361 batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); 469 batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
362 ret = 0; 470 ret = 0;
363 goto out;
364 471
365out: 472out:
366 if (neigh_node) 473 if (neigh_node)
diff --git a/net/batman-adv/unicast.h b/net/batman-adv/unicast.h
index 1c46e2eb1ef9..61abba58bd8f 100644
--- a/net/batman-adv/unicast.h
+++ b/net/batman-adv/unicast.h
@@ -29,10 +29,44 @@ int batadv_frag_reassemble_skb(struct sk_buff *skb,
29 struct batadv_priv *bat_priv, 29 struct batadv_priv *bat_priv,
30 struct sk_buff **new_skb); 30 struct sk_buff **new_skb);
31void batadv_frag_list_free(struct list_head *head); 31void batadv_frag_list_free(struct list_head *head);
32int batadv_unicast_send_skb(struct sk_buff *skb, struct batadv_priv *bat_priv);
33int batadv_frag_send_skb(struct sk_buff *skb, struct batadv_priv *bat_priv, 32int batadv_frag_send_skb(struct sk_buff *skb, struct batadv_priv *bat_priv,
34 struct batadv_hard_iface *hard_iface, 33 struct batadv_hard_iface *hard_iface,
35 const uint8_t dstaddr[]); 34 const uint8_t dstaddr[]);
35bool batadv_unicast_4addr_prepare_skb(struct batadv_priv *bat_priv,
36 struct sk_buff *skb,
37 struct batadv_orig_node *orig_node,
38 int packet_subtype);
39int batadv_unicast_generic_send_skb(struct batadv_priv *bat_priv,
40 struct sk_buff *skb, int packet_type,
41 int packet_subtype);
42
43
44/**
45 * batadv_unicast_send_skb - send the skb encapsulated in a unicast packet
46 * @bat_priv: the bat priv with all the soft interface information
47 * @skb: the payload to send
48 */
49static inline int batadv_unicast_send_skb(struct batadv_priv *bat_priv,
50 struct sk_buff *skb)
51{
52 return batadv_unicast_generic_send_skb(bat_priv, skb, BATADV_UNICAST,
53 0);
54}
55
56/**
57 * batadv_unicast_send_skb - send the skb encapsulated in a unicast4addr packet
58 * @bat_priv: the bat priv with all the soft interface information
59 * @skb: the payload to send
60 * @packet_subtype: the batman 4addr packet subtype to use
61 */
62static inline int batadv_unicast_4addr_send_skb(struct batadv_priv *bat_priv,
63 struct sk_buff *skb,
64 int packet_subtype)
65{
66 return batadv_unicast_generic_send_skb(bat_priv, skb,
67 BATADV_UNICAST_4ADDR,
68 packet_subtype);
69}
36 70
37static inline int batadv_frag_can_reassemble(const struct sk_buff *skb, int mtu) 71static inline int batadv_frag_can_reassemble(const struct sk_buff *skb, int mtu)
38{ 72{
diff --git a/net/batman-adv/vis.c b/net/batman-adv/vis.c
index 5abd1454fb07..ad14a6c91d6a 100644
--- a/net/batman-adv/vis.c
+++ b/net/batman-adv/vis.c
@@ -396,12 +396,12 @@ batadv_add_packet(struct batadv_priv *bat_priv,
396 return NULL; 396 return NULL;
397 397
398 len = sizeof(*packet) + vis_info_len; 398 len = sizeof(*packet) + vis_info_len;
399 info->skb_packet = dev_alloc_skb(len + ETH_HLEN); 399 info->skb_packet = dev_alloc_skb(len + ETH_HLEN + NET_IP_ALIGN);
400 if (!info->skb_packet) { 400 if (!info->skb_packet) {
401 kfree(info); 401 kfree(info);
402 return NULL; 402 return NULL;
403 } 403 }
404 skb_reserve(info->skb_packet, ETH_HLEN); 404 skb_reserve(info->skb_packet, ETH_HLEN + NET_IP_ALIGN);
405 packet = (struct batadv_vis_packet *)skb_put(info->skb_packet, len); 405 packet = (struct batadv_vis_packet *)skb_put(info->skb_packet, len);
406 406
407 kref_init(&info->refcount); 407 kref_init(&info->refcount);
@@ -873,12 +873,13 @@ int batadv_vis_init(struct batadv_priv *bat_priv)
873 if (!bat_priv->vis.my_info) 873 if (!bat_priv->vis.my_info)
874 goto err; 874 goto err;
875 875
876 len = sizeof(*packet) + BATADV_MAX_VIS_PACKET_SIZE + ETH_HLEN; 876 len = sizeof(*packet) + BATADV_MAX_VIS_PACKET_SIZE;
877 len += ETH_HLEN + NET_IP_ALIGN;
877 bat_priv->vis.my_info->skb_packet = dev_alloc_skb(len); 878 bat_priv->vis.my_info->skb_packet = dev_alloc_skb(len);
878 if (!bat_priv->vis.my_info->skb_packet) 879 if (!bat_priv->vis.my_info->skb_packet)
879 goto free_info; 880 goto free_info;
880 881
881 skb_reserve(bat_priv->vis.my_info->skb_packet, ETH_HLEN); 882 skb_reserve(bat_priv->vis.my_info->skb_packet, ETH_HLEN + NET_IP_ALIGN);
882 tmp_skb = bat_priv->vis.my_info->skb_packet; 883 tmp_skb = bat_priv->vis.my_info->skb_packet;
883 packet = (struct batadv_vis_packet *)skb_put(tmp_skb, sizeof(*packet)); 884 packet = (struct batadv_vis_packet *)skb_put(tmp_skb, sizeof(*packet));
884 885