aboutsummaryrefslogtreecommitdiffstats
path: root/net/batman-adv
diff options
context:
space:
mode:
Diffstat (limited to 'net/batman-adv')
-rw-r--r--net/batman-adv/Makefile3
-rw-r--r--net/batman-adv/bat_iv_ogm.c111
-rw-r--r--net/batman-adv/bridge_loop_avoidance.c64
-rw-r--r--net/batman-adv/bridge_loop_avoidance.h10
-rw-r--r--net/batman-adv/debugfs.c9
-rw-r--r--net/batman-adv/distributed-arp-table.c231
-rw-r--r--net/batman-adv/distributed-arp-table.h5
-rw-r--r--net/batman-adv/fragmentation.c491
-rw-r--r--net/batman-adv/fragmentation.h50
-rw-r--r--net/batman-adv/gateway_client.c235
-rw-r--r--net/batman-adv/gateway_client.h2
-rw-r--r--net/batman-adv/gateway_common.c230
-rw-r--r--net/batman-adv/gateway_common.h14
-rw-r--r--net/batman-adv/hard-interface.c33
-rw-r--r--net/batman-adv/icmp_socket.c22
-rw-r--r--net/batman-adv/main.c685
-rw-r--r--net/batman-adv/main.h62
-rw-r--r--net/batman-adv/network-coding.c63
-rw-r--r--net/batman-adv/network-coding.h5
-rw-r--r--net/batman-adv/originator.c127
-rw-r--r--net/batman-adv/originator.h7
-rw-r--r--net/batman-adv/packet.h349
-rw-r--r--net/batman-adv/routing.c426
-rw-r--r--net/batman-adv/routing.h10
-rw-r--r--net/batman-adv/send.c239
-rw-r--r--net/batman-adv/send.h53
-rw-r--r--net/batman-adv/soft-interface.c261
-rw-r--r--net/batman-adv/soft-interface.h4
-rw-r--r--net/batman-adv/sysfs.c274
-rw-r--r--net/batman-adv/sysfs.h10
-rw-r--r--net/batman-adv/translation-table.c1867
-rw-r--r--net/batman-adv/translation-table.h43
-rw-r--r--net/batman-adv/types.h327
-rw-r--r--net/batman-adv/unicast.c491
-rw-r--r--net/batman-adv/unicast.h92
-rw-r--r--net/batman-adv/vis.c938
-rw-r--r--net/batman-adv/vis.h36
37 files changed, 4696 insertions, 3183 deletions
diff --git a/net/batman-adv/Makefile b/net/batman-adv/Makefile
index 489bb36f1b94..4f4aabbd8eab 100644
--- a/net/batman-adv/Makefile
+++ b/net/batman-adv/Makefile
@@ -24,6 +24,7 @@ batman-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-$(CONFIG_BATMAN_ADV_DAT) += distributed-arp-table.o
27batman-adv-y += fragmentation.o
27batman-adv-y += gateway_client.o 28batman-adv-y += gateway_client.o
28batman-adv-y += gateway_common.o 29batman-adv-y += gateway_common.o
29batman-adv-y += hard-interface.o 30batman-adv-y += hard-interface.o
@@ -37,5 +38,3 @@ batman-adv-y += send.o
37batman-adv-y += soft-interface.o 38batman-adv-y += soft-interface.o
38batman-adv-y += sysfs.o 39batman-adv-y += sysfs.o
39batman-adv-y += translation-table.o 40batman-adv-y += translation-table.o
40batman-adv-y += unicast.o
41batman-adv-y += vis.o
diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c
index 0a8a80cd4bf1..97b42d3c4bef 100644
--- a/net/batman-adv/bat_iv_ogm.c
+++ b/net/batman-adv/bat_iv_ogm.c
@@ -135,9 +135,8 @@ static int batadv_iv_ogm_iface_enable(struct batadv_hard_iface *hard_iface)
135 batadv_ogm_packet->header.version = BATADV_COMPAT_VERSION; 135 batadv_ogm_packet->header.version = BATADV_COMPAT_VERSION;
136 batadv_ogm_packet->header.ttl = 2; 136 batadv_ogm_packet->header.ttl = 2;
137 batadv_ogm_packet->flags = BATADV_NO_FLAGS; 137 batadv_ogm_packet->flags = BATADV_NO_FLAGS;
138 batadv_ogm_packet->reserved = 0;
138 batadv_ogm_packet->tq = BATADV_TQ_MAX_VALUE; 139 batadv_ogm_packet->tq = BATADV_TQ_MAX_VALUE;
139 batadv_ogm_packet->tt_num_changes = 0;
140 batadv_ogm_packet->ttvn = 0;
141 140
142 res = 0; 141 res = 0;
143 142
@@ -207,12 +206,12 @@ static uint8_t batadv_hop_penalty(uint8_t tq,
207 206
208/* is there another aggregated packet here? */ 207/* is there another aggregated packet here? */
209static int batadv_iv_ogm_aggr_packet(int buff_pos, int packet_len, 208static int batadv_iv_ogm_aggr_packet(int buff_pos, int packet_len,
210 int tt_num_changes) 209 __be16 tvlv_len)
211{ 210{
212 int next_buff_pos = 0; 211 int next_buff_pos = 0;
213 212
214 next_buff_pos += buff_pos + BATADV_OGM_HLEN; 213 next_buff_pos += buff_pos + BATADV_OGM_HLEN;
215 next_buff_pos += batadv_tt_len(tt_num_changes); 214 next_buff_pos += ntohs(tvlv_len);
216 215
217 return (next_buff_pos <= packet_len) && 216 return (next_buff_pos <= packet_len) &&
218 (next_buff_pos <= BATADV_MAX_AGGREGATION_BYTES); 217 (next_buff_pos <= BATADV_MAX_AGGREGATION_BYTES);
@@ -240,7 +239,7 @@ static void batadv_iv_ogm_send_to_if(struct batadv_forw_packet *forw_packet,
240 239
241 /* adjust all flags and log packets */ 240 /* adjust all flags and log packets */
242 while (batadv_iv_ogm_aggr_packet(buff_pos, forw_packet->packet_len, 241 while (batadv_iv_ogm_aggr_packet(buff_pos, forw_packet->packet_len,
243 batadv_ogm_packet->tt_num_changes)) { 242 batadv_ogm_packet->tvlv_len)) {
244 /* we might have aggregated direct link packets with an 243 /* we might have aggregated direct link packets with an
245 * ordinary base packet 244 * ordinary base packet
246 */ 245 */
@@ -256,18 +255,18 @@ static void batadv_iv_ogm_send_to_if(struct batadv_forw_packet *forw_packet,
256 fwd_str = "Sending own"; 255 fwd_str = "Sending own";
257 256
258 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, 257 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
259 "%s %spacket (originator %pM, seqno %u, TQ %d, TTL %d, IDF %s, ttvn %d) on interface %s [%pM]\n", 258 "%s %spacket (originator %pM, seqno %u, TQ %d, TTL %d, IDF %s) on interface %s [%pM]\n",
260 fwd_str, (packet_num > 0 ? "aggregated " : ""), 259 fwd_str, (packet_num > 0 ? "aggregated " : ""),
261 batadv_ogm_packet->orig, 260 batadv_ogm_packet->orig,
262 ntohl(batadv_ogm_packet->seqno), 261 ntohl(batadv_ogm_packet->seqno),
263 batadv_ogm_packet->tq, batadv_ogm_packet->header.ttl, 262 batadv_ogm_packet->tq, batadv_ogm_packet->header.ttl,
264 (batadv_ogm_packet->flags & BATADV_DIRECTLINK ? 263 (batadv_ogm_packet->flags & BATADV_DIRECTLINK ?
265 "on" : "off"), 264 "on" : "off"),
266 batadv_ogm_packet->ttvn, hard_iface->net_dev->name, 265 hard_iface->net_dev->name,
267 hard_iface->net_dev->dev_addr); 266 hard_iface->net_dev->dev_addr);
268 267
269 buff_pos += BATADV_OGM_HLEN; 268 buff_pos += BATADV_OGM_HLEN;
270 buff_pos += batadv_tt_len(batadv_ogm_packet->tt_num_changes); 269 buff_pos += ntohs(batadv_ogm_packet->tvlv_len);
271 packet_num++; 270 packet_num++;
272 packet_pos = forw_packet->skb->data + buff_pos; 271 packet_pos = forw_packet->skb->data + buff_pos;
273 batadv_ogm_packet = (struct batadv_ogm_packet *)packet_pos; 272 batadv_ogm_packet = (struct batadv_ogm_packet *)packet_pos;
@@ -601,7 +600,7 @@ static void batadv_iv_ogm_forward(struct batadv_orig_node *orig_node,
601 struct batadv_hard_iface *if_incoming) 600 struct batadv_hard_iface *if_incoming)
602{ 601{
603 struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface); 602 struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
604 uint8_t tt_num_changes; 603 uint16_t tvlv_len;
605 604
606 if (batadv_ogm_packet->header.ttl <= 1) { 605 if (batadv_ogm_packet->header.ttl <= 1) {
607 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, "ttl exceeded\n"); 606 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, "ttl exceeded\n");
@@ -621,7 +620,7 @@ static void batadv_iv_ogm_forward(struct batadv_orig_node *orig_node,
621 return; 620 return;
622 } 621 }
623 622
624 tt_num_changes = batadv_ogm_packet->tt_num_changes; 623 tvlv_len = ntohs(batadv_ogm_packet->tvlv_len);
625 624
626 batadv_ogm_packet->header.ttl--; 625 batadv_ogm_packet->header.ttl--;
627 memcpy(batadv_ogm_packet->prev_sender, ethhdr->h_source, ETH_ALEN); 626 memcpy(batadv_ogm_packet->prev_sender, ethhdr->h_source, ETH_ALEN);
@@ -642,7 +641,7 @@ static void batadv_iv_ogm_forward(struct batadv_orig_node *orig_node,
642 batadv_ogm_packet->flags &= ~BATADV_DIRECTLINK; 641 batadv_ogm_packet->flags &= ~BATADV_DIRECTLINK;
643 642
644 batadv_iv_ogm_queue_add(bat_priv, (unsigned char *)batadv_ogm_packet, 643 batadv_iv_ogm_queue_add(bat_priv, (unsigned char *)batadv_ogm_packet,
645 BATADV_OGM_HLEN + batadv_tt_len(tt_num_changes), 644 BATADV_OGM_HLEN + tvlv_len,
646 if_incoming, 0, batadv_iv_ogm_fwd_send_time()); 645 if_incoming, 0, batadv_iv_ogm_fwd_send_time());
647} 646}
648 647
@@ -688,43 +687,29 @@ static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
688 struct batadv_ogm_packet *batadv_ogm_packet; 687 struct batadv_ogm_packet *batadv_ogm_packet;
689 struct batadv_hard_iface *primary_if; 688 struct batadv_hard_iface *primary_if;
690 int *ogm_buff_len = &hard_iface->bat_iv.ogm_buff_len; 689 int *ogm_buff_len = &hard_iface->bat_iv.ogm_buff_len;
691 int vis_server, tt_num_changes = 0;
692 uint32_t seqno; 690 uint32_t seqno;
693 uint8_t bandwidth; 691 uint16_t tvlv_len = 0;
694 692
695 vis_server = atomic_read(&bat_priv->vis_mode);
696 primary_if = batadv_primary_if_get_selected(bat_priv); 693 primary_if = batadv_primary_if_get_selected(bat_priv);
697 694
698 if (hard_iface == primary_if) 695 if (hard_iface == primary_if) {
699 tt_num_changes = batadv_tt_append_diff(bat_priv, ogm_buff, 696 /* tt changes have to be committed before the tvlv data is
700 ogm_buff_len, 697 * appended as it may alter the tt tvlv container
701 BATADV_OGM_HLEN); 698 */
699 batadv_tt_local_commit_changes(bat_priv);
700 tvlv_len = batadv_tvlv_container_ogm_append(bat_priv, ogm_buff,
701 ogm_buff_len,
702 BATADV_OGM_HLEN);
703 }
702 704
703 batadv_ogm_packet = (struct batadv_ogm_packet *)(*ogm_buff); 705 batadv_ogm_packet = (struct batadv_ogm_packet *)(*ogm_buff);
706 batadv_ogm_packet->tvlv_len = htons(tvlv_len);
704 707
705 /* change sequence number to network order */ 708 /* change sequence number to network order */
706 seqno = (uint32_t)atomic_read(&hard_iface->bat_iv.ogm_seqno); 709 seqno = (uint32_t)atomic_read(&hard_iface->bat_iv.ogm_seqno);
707 batadv_ogm_packet->seqno = htonl(seqno); 710 batadv_ogm_packet->seqno = htonl(seqno);
708 atomic_inc(&hard_iface->bat_iv.ogm_seqno); 711 atomic_inc(&hard_iface->bat_iv.ogm_seqno);
709 712
710 batadv_ogm_packet->ttvn = atomic_read(&bat_priv->tt.vn);
711 batadv_ogm_packet->tt_crc = htons(bat_priv->tt.local_crc);
712 if (tt_num_changes >= 0)
713 batadv_ogm_packet->tt_num_changes = tt_num_changes;
714
715 if (vis_server == BATADV_VIS_TYPE_SERVER_SYNC)
716 batadv_ogm_packet->flags |= BATADV_VIS_SERVER;
717 else
718 batadv_ogm_packet->flags &= ~BATADV_VIS_SERVER;
719
720 if (hard_iface == primary_if &&
721 atomic_read(&bat_priv->gw_mode) == BATADV_GW_MODE_SERVER) {
722 bandwidth = (uint8_t)atomic_read(&bat_priv->gw_bandwidth);
723 batadv_ogm_packet->gw_flags = bandwidth;
724 } else {
725 batadv_ogm_packet->gw_flags = BATADV_NO_FLAGS;
726 }
727
728 batadv_iv_ogm_slide_own_bcast_window(hard_iface); 713 batadv_iv_ogm_slide_own_bcast_window(hard_iface);
729 batadv_iv_ogm_queue_add(bat_priv, hard_iface->bat_iv.ogm_buff, 714 batadv_iv_ogm_queue_add(bat_priv, hard_iface->bat_iv.ogm_buff,
730 hard_iface->bat_iv.ogm_buff_len, hard_iface, 1, 715 hard_iface->bat_iv.ogm_buff_len, hard_iface, 1,
@@ -798,7 +783,6 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv,
798 783
799 rcu_read_unlock(); 784 rcu_read_unlock();
800 785
801 orig_node->flags = batadv_ogm_packet->flags;
802 neigh_node->last_seen = jiffies; 786 neigh_node->last_seen = jiffies;
803 787
804 spin_lock_bh(&neigh_node->lq_update_lock); 788 spin_lock_bh(&neigh_node->lq_update_lock);
@@ -820,11 +804,11 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv,
820 */ 804 */
821 router = batadv_orig_node_get_router(orig_node); 805 router = batadv_orig_node_get_router(orig_node);
822 if (router == neigh_node) 806 if (router == neigh_node)
823 goto update_tt; 807 goto out;
824 808
825 /* if this neighbor does not offer a better TQ we won't consider it */ 809 /* if this neighbor does not offer a better TQ we won't consider it */
826 if (router && (router->tq_avg > neigh_node->tq_avg)) 810 if (router && (router->tq_avg > neigh_node->tq_avg))
827 goto update_tt; 811 goto out;
828 812
829 /* if the TQ is the same and the link not more symmetric we 813 /* if the TQ is the same and the link not more symmetric we
830 * won't consider it either 814 * won't consider it either
@@ -843,35 +827,10 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv,
843 spin_unlock_bh(&orig_node_tmp->ogm_cnt_lock); 827 spin_unlock_bh(&orig_node_tmp->ogm_cnt_lock);
844 828
845 if (sum_orig >= sum_neigh) 829 if (sum_orig >= sum_neigh)
846 goto update_tt; 830 goto out;
847 } 831 }
848 832
849 batadv_update_route(bat_priv, orig_node, neigh_node); 833 batadv_update_route(bat_priv, orig_node, neigh_node);
850
851update_tt:
852 /* I have to check for transtable changes only if the OGM has been
853 * sent through a primary interface
854 */
855 if (((batadv_ogm_packet->orig != ethhdr->h_source) &&
856 (batadv_ogm_packet->header.ttl > 2)) ||
857 (batadv_ogm_packet->flags & BATADV_PRIMARIES_FIRST_HOP))
858 batadv_tt_update_orig(bat_priv, orig_node, tt_buff,
859 batadv_ogm_packet->tt_num_changes,
860 batadv_ogm_packet->ttvn,
861 ntohs(batadv_ogm_packet->tt_crc));
862
863 if (orig_node->gw_flags != batadv_ogm_packet->gw_flags)
864 batadv_gw_node_update(bat_priv, orig_node,
865 batadv_ogm_packet->gw_flags);
866
867 orig_node->gw_flags = batadv_ogm_packet->gw_flags;
868
869 /* restart gateway selection if fast or late switching was enabled */
870 if ((orig_node->gw_flags) &&
871 (atomic_read(&bat_priv->gw_mode) == BATADV_GW_MODE_CLIENT) &&
872 (atomic_read(&bat_priv->gw_sel_class) > 2))
873 batadv_gw_check_election(bat_priv, orig_node);
874
875 goto out; 834 goto out;
876 835
877unlock: 836unlock:
@@ -1122,13 +1081,11 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr,
1122 is_single_hop_neigh = true; 1081 is_single_hop_neigh = true;
1123 1082
1124 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, 1083 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1125 "Received BATMAN packet via NB: %pM, IF: %s [%pM] (from OG: %pM, via prev OG: %pM, seqno %u, ttvn %u, crc %#.4x, changes %u, tq %d, TTL %d, V %d, IDF %d)\n", 1084 "Received BATMAN packet via NB: %pM, IF: %s [%pM] (from OG: %pM, via prev OG: %pM, seqno %u, tq %d, TTL %d, V %d, IDF %d)\n",
1126 ethhdr->h_source, if_incoming->net_dev->name, 1085 ethhdr->h_source, if_incoming->net_dev->name,
1127 if_incoming->net_dev->dev_addr, batadv_ogm_packet->orig, 1086 if_incoming->net_dev->dev_addr, batadv_ogm_packet->orig,
1128 batadv_ogm_packet->prev_sender, 1087 batadv_ogm_packet->prev_sender,
1129 ntohl(batadv_ogm_packet->seqno), batadv_ogm_packet->ttvn, 1088 ntohl(batadv_ogm_packet->seqno), batadv_ogm_packet->tq,
1130 ntohs(batadv_ogm_packet->tt_crc),
1131 batadv_ogm_packet->tt_num_changes, batadv_ogm_packet->tq,
1132 batadv_ogm_packet->header.ttl, 1089 batadv_ogm_packet->header.ttl,
1133 batadv_ogm_packet->header.version, has_directlink_flag); 1090 batadv_ogm_packet->header.version, has_directlink_flag);
1134 1091
@@ -1254,6 +1211,8 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr,
1254 goto out; 1211 goto out;
1255 } 1212 }
1256 1213
1214 batadv_tvlv_ogm_receive(bat_priv, batadv_ogm_packet, orig_node);
1215
1257 /* if sender is a direct neighbor the sender mac equals 1216 /* if sender is a direct neighbor the sender mac equals
1258 * originator mac 1217 * originator mac
1259 */ 1218 */
@@ -1350,9 +1309,9 @@ static int batadv_iv_ogm_receive(struct sk_buff *skb,
1350 struct batadv_ogm_packet *batadv_ogm_packet; 1309 struct batadv_ogm_packet *batadv_ogm_packet;
1351 struct ethhdr *ethhdr; 1310 struct ethhdr *ethhdr;
1352 int buff_pos = 0, packet_len; 1311 int buff_pos = 0, packet_len;
1353 unsigned char *tt_buff, *packet_buff; 1312 unsigned char *tvlv_buff, *packet_buff;
1354 bool ret;
1355 uint8_t *packet_pos; 1313 uint8_t *packet_pos;
1314 bool ret;
1356 1315
1357 ret = batadv_check_management_packet(skb, if_incoming, BATADV_OGM_HLEN); 1316 ret = batadv_check_management_packet(skb, if_incoming, BATADV_OGM_HLEN);
1358 if (!ret) 1317 if (!ret)
@@ -1375,14 +1334,14 @@ static int batadv_iv_ogm_receive(struct sk_buff *skb,
1375 1334
1376 /* unpack the aggregated packets and process them one by one */ 1335 /* unpack the aggregated packets and process them one by one */
1377 while (batadv_iv_ogm_aggr_packet(buff_pos, packet_len, 1336 while (batadv_iv_ogm_aggr_packet(buff_pos, packet_len,
1378 batadv_ogm_packet->tt_num_changes)) { 1337 batadv_ogm_packet->tvlv_len)) {
1379 tt_buff = packet_buff + buff_pos + BATADV_OGM_HLEN; 1338 tvlv_buff = packet_buff + buff_pos + BATADV_OGM_HLEN;
1380 1339
1381 batadv_iv_ogm_process(ethhdr, batadv_ogm_packet, tt_buff, 1340 batadv_iv_ogm_process(ethhdr, batadv_ogm_packet,
1382 if_incoming); 1341 tvlv_buff, if_incoming);
1383 1342
1384 buff_pos += BATADV_OGM_HLEN; 1343 buff_pos += BATADV_OGM_HLEN;
1385 buff_pos += batadv_tt_len(batadv_ogm_packet->tt_num_changes); 1344 buff_pos += ntohs(batadv_ogm_packet->tvlv_len);
1386 1345
1387 packet_pos = packet_buff + buff_pos; 1346 packet_pos = packet_buff + buff_pos;
1388 batadv_ogm_packet = (struct batadv_ogm_packet *)packet_pos; 1347 batadv_ogm_packet = (struct batadv_ogm_packet *)packet_pos;
diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c
index 264de88db320..28eb5e6d0a02 100644
--- a/net/batman-adv/bridge_loop_avoidance.c
+++ b/net/batman-adv/bridge_loop_avoidance.c
@@ -411,10 +411,10 @@ batadv_bla_get_backbone_gw(struct batadv_priv *bat_priv, uint8_t *orig,
411 return NULL; 411 return NULL;
412 } 412 }
413 413
414 /* this is a gateway now, remove any tt entries */ 414 /* this is a gateway now, remove any TT entry on this VLAN */
415 orig_node = batadv_orig_hash_find(bat_priv, orig); 415 orig_node = batadv_orig_hash_find(bat_priv, orig);
416 if (orig_node) { 416 if (orig_node) {
417 batadv_tt_global_del_orig(bat_priv, orig_node, 417 batadv_tt_global_del_orig(bat_priv, orig_node, vid,
418 "became a backbone gateway"); 418 "became a backbone gateway");
419 batadv_orig_node_free_ref(orig_node); 419 batadv_orig_node_free_ref(orig_node);
420 } 420 }
@@ -858,30 +858,28 @@ static int batadv_bla_process_claim(struct batadv_priv *bat_priv,
858 struct batadv_hard_iface *primary_if, 858 struct batadv_hard_iface *primary_if,
859 struct sk_buff *skb) 859 struct sk_buff *skb)
860{ 860{
861 struct ethhdr *ethhdr; 861 struct batadv_bla_claim_dst *bla_dst;
862 uint8_t *hw_src, *hw_dst;
862 struct vlan_ethhdr *vhdr; 863 struct vlan_ethhdr *vhdr;
864 struct ethhdr *ethhdr;
863 struct arphdr *arphdr; 865 struct arphdr *arphdr;
864 uint8_t *hw_src, *hw_dst; 866 unsigned short vid;
865 struct batadv_bla_claim_dst *bla_dst; 867 __be16 proto;
866 uint16_t proto;
867 int headlen; 868 int headlen;
868 unsigned short vid = BATADV_NO_FLAGS;
869 int ret; 869 int ret;
870 870
871 vid = batadv_get_vid(skb, 0);
871 ethhdr = eth_hdr(skb); 872 ethhdr = eth_hdr(skb);
872 873
873 if (ntohs(ethhdr->h_proto) == ETH_P_8021Q) { 874 proto = ethhdr->h_proto;
875 headlen = ETH_HLEN;
876 if (vid & BATADV_VLAN_HAS_TAG) {
874 vhdr = (struct vlan_ethhdr *)ethhdr; 877 vhdr = (struct vlan_ethhdr *)ethhdr;
875 vid = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK; 878 proto = vhdr->h_vlan_encapsulated_proto;
876 vid |= BATADV_VLAN_HAS_TAG; 879 headlen += VLAN_HLEN;
877 proto = ntohs(vhdr->h_vlan_encapsulated_proto);
878 headlen = sizeof(*vhdr);
879 } else {
880 proto = ntohs(ethhdr->h_proto);
881 headlen = ETH_HLEN;
882 } 880 }
883 881
884 if (proto != ETH_P_ARP) 882 if (proto != htons(ETH_P_ARP))
885 return 0; /* not a claim frame */ 883 return 0; /* not a claim frame */
886 884
887 /* this must be a ARP frame. check if it is a claim. */ 885 /* this must be a ARP frame. check if it is a claim. */
@@ -1317,12 +1315,14 @@ out:
1317 1315
1318/* @bat_priv: the bat priv with all the soft interface information 1316/* @bat_priv: the bat priv with all the soft interface information
1319 * @orig: originator mac address 1317 * @orig: originator mac address
1318 * @vid: VLAN identifier
1320 * 1319 *
1321 * check if the originator is a gateway for any VLAN ID. 1320 * Check if the originator is a gateway for the VLAN identified by vid.
1322 * 1321 *
1323 * returns 1 if it is found, 0 otherwise 1322 * Returns true if orig is a backbone for this vid, false otherwise.
1324 */ 1323 */
1325int batadv_bla_is_backbone_gw_orig(struct batadv_priv *bat_priv, uint8_t *orig) 1324bool batadv_bla_is_backbone_gw_orig(struct batadv_priv *bat_priv, uint8_t *orig,
1325 unsigned short vid)
1326{ 1326{
1327 struct batadv_hashtable *hash = bat_priv->bla.backbone_hash; 1327 struct batadv_hashtable *hash = bat_priv->bla.backbone_hash;
1328 struct hlist_head *head; 1328 struct hlist_head *head;
@@ -1330,25 +1330,26 @@ int batadv_bla_is_backbone_gw_orig(struct batadv_priv *bat_priv, uint8_t *orig)
1330 int i; 1330 int i;
1331 1331
1332 if (!atomic_read(&bat_priv->bridge_loop_avoidance)) 1332 if (!atomic_read(&bat_priv->bridge_loop_avoidance))
1333 return 0; 1333 return false;
1334 1334
1335 if (!hash) 1335 if (!hash)
1336 return 0; 1336 return false;
1337 1337
1338 for (i = 0; i < hash->size; i++) { 1338 for (i = 0; i < hash->size; i++) {
1339 head = &hash->table[i]; 1339 head = &hash->table[i];
1340 1340
1341 rcu_read_lock(); 1341 rcu_read_lock();
1342 hlist_for_each_entry_rcu(backbone_gw, head, hash_entry) { 1342 hlist_for_each_entry_rcu(backbone_gw, head, hash_entry) {
1343 if (batadv_compare_eth(backbone_gw->orig, orig)) { 1343 if (batadv_compare_eth(backbone_gw->orig, orig) &&
1344 backbone_gw->vid == vid) {
1344 rcu_read_unlock(); 1345 rcu_read_unlock();
1345 return 1; 1346 return true;
1346 } 1347 }
1347 } 1348 }
1348 rcu_read_unlock(); 1349 rcu_read_unlock();
1349 } 1350 }
1350 1351
1351 return 0; 1352 return false;
1352} 1353}
1353 1354
1354 1355
@@ -1365,10 +1366,8 @@ int batadv_bla_is_backbone_gw_orig(struct batadv_priv *bat_priv, uint8_t *orig)
1365int batadv_bla_is_backbone_gw(struct sk_buff *skb, 1366int batadv_bla_is_backbone_gw(struct sk_buff *skb,
1366 struct batadv_orig_node *orig_node, int hdr_size) 1367 struct batadv_orig_node *orig_node, int hdr_size)
1367{ 1368{
1368 struct ethhdr *ethhdr;
1369 struct vlan_ethhdr *vhdr;
1370 struct batadv_bla_backbone_gw *backbone_gw; 1369 struct batadv_bla_backbone_gw *backbone_gw;
1371 unsigned short vid = BATADV_NO_FLAGS; 1370 unsigned short vid;
1372 1371
1373 if (!atomic_read(&orig_node->bat_priv->bridge_loop_avoidance)) 1372 if (!atomic_read(&orig_node->bat_priv->bridge_loop_avoidance))
1374 return 0; 1373 return 0;
@@ -1377,16 +1376,7 @@ int batadv_bla_is_backbone_gw(struct sk_buff *skb,
1377 if (!pskb_may_pull(skb, hdr_size + ETH_HLEN)) 1376 if (!pskb_may_pull(skb, hdr_size + ETH_HLEN))
1378 return 0; 1377 return 0;
1379 1378
1380 ethhdr = (struct ethhdr *)(((uint8_t *)skb->data) + hdr_size); 1379 vid = batadv_get_vid(skb, hdr_size);
1381
1382 if (ntohs(ethhdr->h_proto) == ETH_P_8021Q) {
1383 if (!pskb_may_pull(skb, hdr_size + sizeof(struct vlan_ethhdr)))
1384 return 0;
1385
1386 vhdr = (struct vlan_ethhdr *)(skb->data + hdr_size);
1387 vid = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK;
1388 vid |= BATADV_VLAN_HAS_TAG;
1389 }
1390 1380
1391 /* see if this originator is a backbone gw for this VLAN */ 1381 /* see if this originator is a backbone gw for this VLAN */
1392 backbone_gw = batadv_backbone_hash_find(orig_node->bat_priv, 1382 backbone_gw = batadv_backbone_hash_find(orig_node->bat_priv,
diff --git a/net/batman-adv/bridge_loop_avoidance.h b/net/batman-adv/bridge_loop_avoidance.h
index 4b102e71e5bd..da173e760e77 100644
--- a/net/batman-adv/bridge_loop_avoidance.h
+++ b/net/batman-adv/bridge_loop_avoidance.h
@@ -30,7 +30,8 @@ int batadv_bla_is_backbone_gw(struct sk_buff *skb,
30int batadv_bla_claim_table_seq_print_text(struct seq_file *seq, void *offset); 30int batadv_bla_claim_table_seq_print_text(struct seq_file *seq, void *offset);
31int batadv_bla_backbone_table_seq_print_text(struct seq_file *seq, 31int batadv_bla_backbone_table_seq_print_text(struct seq_file *seq,
32 void *offset); 32 void *offset);
33int batadv_bla_is_backbone_gw_orig(struct batadv_priv *bat_priv, uint8_t *orig); 33bool batadv_bla_is_backbone_gw_orig(struct batadv_priv *bat_priv, uint8_t *orig,
34 unsigned short vid);
34int batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv, 35int batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv,
35 struct sk_buff *skb); 36 struct sk_buff *skb);
36void batadv_bla_update_orig_address(struct batadv_priv *bat_priv, 37void batadv_bla_update_orig_address(struct batadv_priv *bat_priv,
@@ -74,10 +75,11 @@ static inline int batadv_bla_backbone_table_seq_print_text(struct seq_file *seq,
74 return 0; 75 return 0;
75} 76}
76 77
77static inline int batadv_bla_is_backbone_gw_orig(struct batadv_priv *bat_priv, 78static inline bool batadv_bla_is_backbone_gw_orig(struct batadv_priv *bat_priv,
78 uint8_t *orig) 79 uint8_t *orig,
80 unsigned short vid)
79{ 81{
80 return 0; 82 return false;
81} 83}
82 84
83static inline int 85static inline int
diff --git a/net/batman-adv/debugfs.c b/net/batman-adv/debugfs.c
index f186a55b23c3..049a7a2ac5b6 100644
--- a/net/batman-adv/debugfs.c
+++ b/net/batman-adv/debugfs.c
@@ -28,7 +28,6 @@
28#include "gateway_common.h" 28#include "gateway_common.h"
29#include "gateway_client.h" 29#include "gateway_client.h"
30#include "soft-interface.h" 30#include "soft-interface.h"
31#include "vis.h"
32#include "icmp_socket.h" 31#include "icmp_socket.h"
33#include "bridge_loop_avoidance.h" 32#include "bridge_loop_avoidance.h"
34#include "distributed-arp-table.h" 33#include "distributed-arp-table.h"
@@ -300,12 +299,6 @@ static int batadv_transtable_local_open(struct inode *inode, struct file *file)
300 return single_open(file, batadv_tt_local_seq_print_text, net_dev); 299 return single_open(file, batadv_tt_local_seq_print_text, net_dev);
301} 300}
302 301
303static int batadv_vis_data_open(struct inode *inode, struct file *file)
304{
305 struct net_device *net_dev = (struct net_device *)inode->i_private;
306 return single_open(file, batadv_vis_seq_print_text, net_dev);
307}
308
309struct batadv_debuginfo { 302struct batadv_debuginfo {
310 struct attribute attr; 303 struct attribute attr;
311 const struct file_operations fops; 304 const struct file_operations fops;
@@ -356,7 +349,6 @@ static BATADV_DEBUGINFO(dat_cache, S_IRUGO, batadv_dat_cache_open);
356#endif 349#endif
357static BATADV_DEBUGINFO(transtable_local, S_IRUGO, 350static BATADV_DEBUGINFO(transtable_local, S_IRUGO,
358 batadv_transtable_local_open); 351 batadv_transtable_local_open);
359static BATADV_DEBUGINFO(vis_data, S_IRUGO, batadv_vis_data_open);
360#ifdef CONFIG_BATMAN_ADV_NC 352#ifdef CONFIG_BATMAN_ADV_NC
361static BATADV_DEBUGINFO(nc_nodes, S_IRUGO, batadv_nc_nodes_open); 353static BATADV_DEBUGINFO(nc_nodes, S_IRUGO, batadv_nc_nodes_open);
362#endif 354#endif
@@ -373,7 +365,6 @@ static struct batadv_debuginfo *batadv_mesh_debuginfos[] = {
373 &batadv_debuginfo_dat_cache, 365 &batadv_debuginfo_dat_cache,
374#endif 366#endif
375 &batadv_debuginfo_transtable_local, 367 &batadv_debuginfo_transtable_local,
376 &batadv_debuginfo_vis_data,
377#ifdef CONFIG_BATMAN_ADV_NC 368#ifdef CONFIG_BATMAN_ADV_NC
378 &batadv_debuginfo_nc_nodes, 369 &batadv_debuginfo_nc_nodes,
379#endif 370#endif
diff --git a/net/batman-adv/distributed-arp-table.c b/net/batman-adv/distributed-arp-table.c
index 06345d401588..6c8c3934bd7b 100644
--- a/net/batman-adv/distributed-arp-table.c
+++ b/net/batman-adv/distributed-arp-table.c
@@ -19,6 +19,7 @@
19 19
20#include <linux/if_ether.h> 20#include <linux/if_ether.h>
21#include <linux/if_arp.h> 21#include <linux/if_arp.h>
22#include <linux/if_vlan.h>
22#include <net/arp.h> 23#include <net/arp.h>
23 24
24#include "main.h" 25#include "main.h"
@@ -29,7 +30,6 @@
29#include "send.h" 30#include "send.h"
30#include "types.h" 31#include "types.h"
31#include "translation-table.h" 32#include "translation-table.h"
32#include "unicast.h"
33 33
34static void batadv_dat_purge(struct work_struct *work); 34static void batadv_dat_purge(struct work_struct *work);
35 35
@@ -206,15 +206,11 @@ static __be32 batadv_arp_ip_dst(struct sk_buff *skb, int hdr_size)
206 */ 206 */
207static uint32_t batadv_hash_dat(const void *data, uint32_t size) 207static uint32_t batadv_hash_dat(const void *data, uint32_t size)
208{ 208{
209 const unsigned char *key = data;
210 uint32_t hash = 0; 209 uint32_t hash = 0;
211 size_t i; 210 const struct batadv_dat_entry *dat = data;
212 211
213 for (i = 0; i < 4; i++) { 212 hash = batadv_hash_bytes(hash, &dat->ip, sizeof(dat->ip));
214 hash += key[i]; 213 hash = batadv_hash_bytes(hash, &dat->vid, sizeof(dat->vid));
215 hash += (hash << 10);
216 hash ^= (hash >> 6);
217 }
218 214
219 hash += (hash << 3); 215 hash += (hash << 3);
220 hash ^= (hash >> 11); 216 hash ^= (hash >> 11);
@@ -228,21 +224,26 @@ static uint32_t batadv_hash_dat(const void *data, uint32_t size)
228 * table 224 * table
229 * @bat_priv: the bat priv with all the soft interface information 225 * @bat_priv: the bat priv with all the soft interface information
230 * @ip: search key 226 * @ip: search key
227 * @vid: VLAN identifier
231 * 228 *
232 * Returns the dat_entry if found, NULL otherwise. 229 * Returns the dat_entry if found, NULL otherwise.
233 */ 230 */
234static struct batadv_dat_entry * 231static struct batadv_dat_entry *
235batadv_dat_entry_hash_find(struct batadv_priv *bat_priv, __be32 ip) 232batadv_dat_entry_hash_find(struct batadv_priv *bat_priv, __be32 ip,
233 unsigned short vid)
236{ 234{
237 struct hlist_head *head; 235 struct hlist_head *head;
238 struct batadv_dat_entry *dat_entry, *dat_entry_tmp = NULL; 236 struct batadv_dat_entry to_find, *dat_entry, *dat_entry_tmp = NULL;
239 struct batadv_hashtable *hash = bat_priv->dat.hash; 237 struct batadv_hashtable *hash = bat_priv->dat.hash;
240 uint32_t index; 238 uint32_t index;
241 239
242 if (!hash) 240 if (!hash)
243 return NULL; 241 return NULL;
244 242
245 index = batadv_hash_dat(&ip, hash->size); 243 to_find.ip = ip;
244 to_find.vid = vid;
245
246 index = batadv_hash_dat(&to_find, hash->size);
246 head = &hash->table[index]; 247 head = &hash->table[index];
247 248
248 rcu_read_lock(); 249 rcu_read_lock();
@@ -266,22 +267,24 @@ batadv_dat_entry_hash_find(struct batadv_priv *bat_priv, __be32 ip)
266 * @bat_priv: the bat priv with all the soft interface information 267 * @bat_priv: the bat priv with all the soft interface information
267 * @ip: ipv4 to add/edit 268 * @ip: ipv4 to add/edit
268 * @mac_addr: mac address to assign to the given ipv4 269 * @mac_addr: mac address to assign to the given ipv4
270 * @vid: VLAN identifier
269 */ 271 */
270static void batadv_dat_entry_add(struct batadv_priv *bat_priv, __be32 ip, 272static void batadv_dat_entry_add(struct batadv_priv *bat_priv, __be32 ip,
271 uint8_t *mac_addr) 273 uint8_t *mac_addr, unsigned short vid)
272{ 274{
273 struct batadv_dat_entry *dat_entry; 275 struct batadv_dat_entry *dat_entry;
274 int hash_added; 276 int hash_added;
275 277
276 dat_entry = batadv_dat_entry_hash_find(bat_priv, ip); 278 dat_entry = batadv_dat_entry_hash_find(bat_priv, ip, vid);
277 /* if this entry is already known, just update it */ 279 /* if this entry is already known, just update it */
278 if (dat_entry) { 280 if (dat_entry) {
279 if (!batadv_compare_eth(dat_entry->mac_addr, mac_addr)) 281 if (!batadv_compare_eth(dat_entry->mac_addr, mac_addr))
280 memcpy(dat_entry->mac_addr, mac_addr, ETH_ALEN); 282 memcpy(dat_entry->mac_addr, mac_addr, ETH_ALEN);
281 dat_entry->last_update = jiffies; 283 dat_entry->last_update = jiffies;
282 batadv_dbg(BATADV_DBG_DAT, bat_priv, 284 batadv_dbg(BATADV_DBG_DAT, bat_priv,
283 "Entry updated: %pI4 %pM\n", &dat_entry->ip, 285 "Entry updated: %pI4 %pM (vid: %d)\n",
284 dat_entry->mac_addr); 286 &dat_entry->ip, dat_entry->mac_addr,
287 BATADV_PRINT_VID(vid));
285 goto out; 288 goto out;
286 } 289 }
287 290
@@ -290,12 +293,13 @@ static void batadv_dat_entry_add(struct batadv_priv *bat_priv, __be32 ip,
290 goto out; 293 goto out;
291 294
292 dat_entry->ip = ip; 295 dat_entry->ip = ip;
296 dat_entry->vid = vid;
293 memcpy(dat_entry->mac_addr, mac_addr, ETH_ALEN); 297 memcpy(dat_entry->mac_addr, mac_addr, ETH_ALEN);
294 dat_entry->last_update = jiffies; 298 dat_entry->last_update = jiffies;
295 atomic_set(&dat_entry->refcount, 2); 299 atomic_set(&dat_entry->refcount, 2);
296 300
297 hash_added = batadv_hash_add(bat_priv->dat.hash, batadv_compare_dat, 301 hash_added = batadv_hash_add(bat_priv->dat.hash, batadv_compare_dat,
298 batadv_hash_dat, &dat_entry->ip, 302 batadv_hash_dat, dat_entry,
299 &dat_entry->hash_entry); 303 &dat_entry->hash_entry);
300 304
301 if (unlikely(hash_added != 0)) { 305 if (unlikely(hash_added != 0)) {
@@ -304,8 +308,8 @@ static void batadv_dat_entry_add(struct batadv_priv *bat_priv, __be32 ip,
304 goto out; 308 goto out;
305 } 309 }
306 310
307 batadv_dbg(BATADV_DBG_DAT, bat_priv, "New entry added: %pI4 %pM\n", 311 batadv_dbg(BATADV_DBG_DAT, bat_priv, "New entry added: %pI4 %pM (vid: %d)\n",
308 &dat_entry->ip, dat_entry->mac_addr); 312 &dat_entry->ip, dat_entry->mac_addr, BATADV_PRINT_VID(vid));
309 313
310out: 314out:
311 if (dat_entry) 315 if (dat_entry)
@@ -419,6 +423,10 @@ static bool batadv_is_orig_node_eligible(struct batadv_dat_candidate *res,
419 bool ret = false; 423 bool ret = false;
420 int j; 424 int j;
421 425
426 /* check if orig node candidate is running DAT */
427 if (!(candidate->capabilities & BATADV_ORIG_CAPA_HAS_DAT))
428 goto out;
429
422 /* Check if this node has already been selected... */ 430 /* Check if this node has already been selected... */
423 for (j = 0; j < select; j++) 431 for (j = 0; j < select; j++)
424 if (res[j].orig_node == candidate) 432 if (res[j].orig_node == candidate)
@@ -588,9 +596,9 @@ static bool batadv_dat_send_data(struct batadv_priv *bat_priv,
588 goto free_orig; 596 goto free_orig;
589 597
590 tmp_skb = pskb_copy(skb, GFP_ATOMIC); 598 tmp_skb = pskb_copy(skb, GFP_ATOMIC);
591 if (!batadv_unicast_4addr_prepare_skb(bat_priv, tmp_skb, 599 if (!batadv_send_skb_prepare_unicast_4addr(bat_priv, tmp_skb,
592 cand[i].orig_node, 600 cand[i].orig_node,
593 packet_subtype)) { 601 packet_subtype)) {
594 kfree_skb(tmp_skb); 602 kfree_skb(tmp_skb);
595 goto free_neigh; 603 goto free_neigh;
596 } 604 }
@@ -626,6 +634,59 @@ out:
626} 634}
627 635
628/** 636/**
637 * batadv_dat_tvlv_container_update - update the dat tvlv container after dat
638 * setting change
639 * @bat_priv: the bat priv with all the soft interface information
640 */
641static void batadv_dat_tvlv_container_update(struct batadv_priv *bat_priv)
642{
643 char dat_mode;
644
645 dat_mode = atomic_read(&bat_priv->distributed_arp_table);
646
647 switch (dat_mode) {
648 case 0:
649 batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_DAT, 1);
650 break;
651 case 1:
652 batadv_tvlv_container_register(bat_priv, BATADV_TVLV_DAT, 1,
653 NULL, 0);
654 break;
655 }
656}
657
658/**
659 * batadv_dat_status_update - update the dat tvlv container after dat
660 * setting change
661 * @net_dev: the soft interface net device
662 */
663void batadv_dat_status_update(struct net_device *net_dev)
664{
665 struct batadv_priv *bat_priv = netdev_priv(net_dev);
666 batadv_dat_tvlv_container_update(bat_priv);
667}
668
669/**
670 * batadv_gw_tvlv_ogm_handler_v1 - process incoming dat tvlv container
671 * @bat_priv: the bat priv with all the soft interface information
672 * @orig: the orig_node of the ogm
673 * @flags: flags indicating the tvlv state (see batadv_tvlv_handler_flags)
674 * @tvlv_value: tvlv buffer containing the gateway data
675 * @tvlv_value_len: tvlv buffer length
676 */
677static void batadv_dat_tvlv_ogm_handler_v1(struct batadv_priv *bat_priv,
678 struct batadv_orig_node *orig,
679 uint8_t flags,
680 void *tvlv_value,
681 uint16_t tvlv_value_len)
682{
683 if (flags & BATADV_TVLV_HANDLER_OGM_CIFNOTFND)
684 orig->capabilities &= ~BATADV_ORIG_CAPA_HAS_DAT;
685 else
686 orig->capabilities |= BATADV_ORIG_CAPA_HAS_DAT;
687}
688
689/**
629 * batadv_dat_hash_free - free the local DAT hash table 690 * batadv_dat_hash_free - free the local DAT hash table
630 * @bat_priv: the bat priv with all the soft interface information 691 * @bat_priv: the bat priv with all the soft interface information
631 */ 692 */
@@ -657,6 +718,10 @@ int batadv_dat_init(struct batadv_priv *bat_priv)
657 718
658 batadv_dat_start_timer(bat_priv); 719 batadv_dat_start_timer(bat_priv);
659 720
721 batadv_tvlv_handler_register(bat_priv, batadv_dat_tvlv_ogm_handler_v1,
722 NULL, BATADV_TVLV_DAT, 1,
723 BATADV_TVLV_HANDLER_OGM_CIFNOTFND);
724 batadv_dat_tvlv_container_update(bat_priv);
660 return 0; 725 return 0;
661} 726}
662 727
@@ -666,6 +731,9 @@ int batadv_dat_init(struct batadv_priv *bat_priv)
666 */ 731 */
667void batadv_dat_free(struct batadv_priv *bat_priv) 732void batadv_dat_free(struct batadv_priv *bat_priv)
668{ 733{
734 batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_DAT, 1);
735 batadv_tvlv_handler_unregister(bat_priv, BATADV_TVLV_DAT, 1);
736
669 cancel_delayed_work_sync(&bat_priv->dat.work); 737 cancel_delayed_work_sync(&bat_priv->dat.work);
670 738
671 batadv_dat_hash_free(bat_priv); 739 batadv_dat_hash_free(bat_priv);
@@ -693,8 +761,8 @@ int batadv_dat_cache_seq_print_text(struct seq_file *seq, void *offset)
693 goto out; 761 goto out;
694 762
695 seq_printf(seq, "Distributed ARP Table (%s):\n", net_dev->name); 763 seq_printf(seq, "Distributed ARP Table (%s):\n", net_dev->name);
696 seq_printf(seq, " %-7s %-13s %5s\n", "IPv4", "MAC", 764 seq_printf(seq, " %-7s %-9s %4s %11s\n", "IPv4",
697 "last-seen"); 765 "MAC", "VID", "last-seen");
698 766
699 for (i = 0; i < hash->size; i++) { 767 for (i = 0; i < hash->size; i++) {
700 head = &hash->table[i]; 768 head = &hash->table[i];
@@ -707,8 +775,9 @@ int batadv_dat_cache_seq_print_text(struct seq_file *seq, void *offset)
707 last_seen_msecs = last_seen_msecs % 60000; 775 last_seen_msecs = last_seen_msecs % 60000;
708 last_seen_secs = last_seen_msecs / 1000; 776 last_seen_secs = last_seen_msecs / 1000;
709 777
710 seq_printf(seq, " * %15pI4 %14pM %6i:%02i\n", 778 seq_printf(seq, " * %15pI4 %14pM %4i %6i:%02i\n",
711 &dat_entry->ip, dat_entry->mac_addr, 779 &dat_entry->ip, dat_entry->mac_addr,
780 BATADV_PRINT_VID(dat_entry->vid),
712 last_seen_mins, last_seen_secs); 781 last_seen_mins, last_seen_secs);
713 } 782 }
714 rcu_read_unlock(); 783 rcu_read_unlock();
@@ -795,6 +864,31 @@ out:
795} 864}
796 865
797/** 866/**
867 * batadv_dat_get_vid - extract the VLAN identifier from skb if any
868 * @skb: the buffer containing the packet to extract the VID from
869 * @hdr_size: the size of the batman-adv header encapsulating the packet
870 *
871 * If the packet embedded in the skb is vlan tagged this function returns the
872 * VID with the BATADV_VLAN_HAS_TAG flag. Otherwise BATADV_NO_FLAGS is returned.
873 */
874static unsigned short batadv_dat_get_vid(struct sk_buff *skb, int *hdr_size)
875{
876 unsigned short vid;
877
878 vid = batadv_get_vid(skb, *hdr_size);
879
880 /* ARP parsing functions jump forward of hdr_size + ETH_HLEN.
881 * If the header contained in the packet is a VLAN one (which is longer)
882 * hdr_size is updated so that the functions will still skip the
883 * correct amount of bytes.
884 */
885 if (vid & BATADV_VLAN_HAS_TAG)
886 *hdr_size += VLAN_HLEN;
887
888 return vid;
889}
890
891/**
798 * batadv_dat_snoop_outgoing_arp_request - snoop the ARP request and try to 892 * batadv_dat_snoop_outgoing_arp_request - snoop the ARP request and try to
799 * answer using DAT 893 * answer using DAT
800 * @bat_priv: the bat priv with all the soft interface information 894 * @bat_priv: the bat priv with all the soft interface information
@@ -813,26 +907,31 @@ bool batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv,
813 bool ret = false; 907 bool ret = false;
814 struct batadv_dat_entry *dat_entry = NULL; 908 struct batadv_dat_entry *dat_entry = NULL;
815 struct sk_buff *skb_new; 909 struct sk_buff *skb_new;
910 int hdr_size = 0;
911 unsigned short vid;
816 912
817 if (!atomic_read(&bat_priv->distributed_arp_table)) 913 if (!atomic_read(&bat_priv->distributed_arp_table))
818 goto out; 914 goto out;
819 915
820 type = batadv_arp_get_type(bat_priv, skb, 0); 916 vid = batadv_dat_get_vid(skb, &hdr_size);
917
918 type = batadv_arp_get_type(bat_priv, skb, hdr_size);
821 /* If the node gets an ARP_REQUEST it has to send a DHT_GET unicast 919 /* If the node gets an ARP_REQUEST it has to send a DHT_GET unicast
822 * message to the selected DHT candidates 920 * message to the selected DHT candidates
823 */ 921 */
824 if (type != ARPOP_REQUEST) 922 if (type != ARPOP_REQUEST)
825 goto out; 923 goto out;
826 924
827 batadv_dbg_arp(bat_priv, skb, type, 0, "Parsing outgoing ARP REQUEST"); 925 batadv_dbg_arp(bat_priv, skb, type, hdr_size,
926 "Parsing outgoing ARP REQUEST");
828 927
829 ip_src = batadv_arp_ip_src(skb, 0); 928 ip_src = batadv_arp_ip_src(skb, hdr_size);
830 hw_src = batadv_arp_hw_src(skb, 0); 929 hw_src = batadv_arp_hw_src(skb, hdr_size);
831 ip_dst = batadv_arp_ip_dst(skb, 0); 930 ip_dst = batadv_arp_ip_dst(skb, hdr_size);
832 931
833 batadv_dat_entry_add(bat_priv, ip_src, hw_src); 932 batadv_dat_entry_add(bat_priv, ip_src, hw_src, vid);
834 933
835 dat_entry = batadv_dat_entry_hash_find(bat_priv, ip_dst); 934 dat_entry = batadv_dat_entry_hash_find(bat_priv, ip_dst, vid);
836 if (dat_entry) { 935 if (dat_entry) {
837 /* If the ARP request is destined for a local client the local 936 /* If the ARP request is destined for a local client the local
838 * client will answer itself. DAT would only generate a 937 * client will answer itself. DAT would only generate a
@@ -842,7 +941,8 @@ bool batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv,
842 * additional DAT answer may trigger kernel warnings about 941 * additional DAT answer may trigger kernel warnings about
843 * a packet coming from the wrong port. 942 * a packet coming from the wrong port.
844 */ 943 */
845 if (batadv_is_my_client(bat_priv, dat_entry->mac_addr)) { 944 if (batadv_is_my_client(bat_priv, dat_entry->mac_addr,
945 BATADV_NO_FLAGS)) {
846 ret = true; 946 ret = true;
847 goto out; 947 goto out;
848 } 948 }
@@ -853,11 +953,15 @@ bool batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv,
853 if (!skb_new) 953 if (!skb_new)
854 goto out; 954 goto out;
855 955
956 if (vid & BATADV_VLAN_HAS_TAG)
957 skb_new = vlan_insert_tag(skb_new, htons(ETH_P_8021Q),
958 vid & VLAN_VID_MASK);
959
856 skb_reset_mac_header(skb_new); 960 skb_reset_mac_header(skb_new);
857 skb_new->protocol = eth_type_trans(skb_new, 961 skb_new->protocol = eth_type_trans(skb_new,
858 bat_priv->soft_iface); 962 bat_priv->soft_iface);
859 bat_priv->stats.rx_packets++; 963 bat_priv->stats.rx_packets++;
860 bat_priv->stats.rx_bytes += skb->len + ETH_HLEN; 964 bat_priv->stats.rx_bytes += skb->len + ETH_HLEN + hdr_size;
861 bat_priv->soft_iface->last_rx = jiffies; 965 bat_priv->soft_iface->last_rx = jiffies;
862 966
863 netif_rx(skb_new); 967 netif_rx(skb_new);
@@ -892,11 +996,14 @@ bool batadv_dat_snoop_incoming_arp_request(struct batadv_priv *bat_priv,
892 struct sk_buff *skb_new; 996 struct sk_buff *skb_new;
893 struct batadv_dat_entry *dat_entry = NULL; 997 struct batadv_dat_entry *dat_entry = NULL;
894 bool ret = false; 998 bool ret = false;
999 unsigned short vid;
895 int err; 1000 int err;
896 1001
897 if (!atomic_read(&bat_priv->distributed_arp_table)) 1002 if (!atomic_read(&bat_priv->distributed_arp_table))
898 goto out; 1003 goto out;
899 1004
1005 vid = batadv_dat_get_vid(skb, &hdr_size);
1006
900 type = batadv_arp_get_type(bat_priv, skb, hdr_size); 1007 type = batadv_arp_get_type(bat_priv, skb, hdr_size);
901 if (type != ARPOP_REQUEST) 1008 if (type != ARPOP_REQUEST)
902 goto out; 1009 goto out;
@@ -908,9 +1015,9 @@ bool batadv_dat_snoop_incoming_arp_request(struct batadv_priv *bat_priv,
908 batadv_dbg_arp(bat_priv, skb, type, hdr_size, 1015 batadv_dbg_arp(bat_priv, skb, type, hdr_size,
909 "Parsing incoming ARP REQUEST"); 1016 "Parsing incoming ARP REQUEST");
910 1017
911 batadv_dat_entry_add(bat_priv, ip_src, hw_src); 1018 batadv_dat_entry_add(bat_priv, ip_src, hw_src, vid);
912 1019
913 dat_entry = batadv_dat_entry_hash_find(bat_priv, ip_dst); 1020 dat_entry = batadv_dat_entry_hash_find(bat_priv, ip_dst, vid);
914 if (!dat_entry) 1021 if (!dat_entry)
915 goto out; 1022 goto out;
916 1023
@@ -921,17 +1028,22 @@ bool batadv_dat_snoop_incoming_arp_request(struct batadv_priv *bat_priv,
921 if (!skb_new) 1028 if (!skb_new)
922 goto out; 1029 goto out;
923 1030
1031 if (vid & BATADV_VLAN_HAS_TAG)
1032 skb_new = vlan_insert_tag(skb_new, htons(ETH_P_8021Q),
1033 vid & VLAN_VID_MASK);
1034
924 /* To preserve backwards compatibility, the node has choose the outgoing 1035 /* To preserve backwards compatibility, the node has choose the outgoing
925 * format based on the incoming request packet type. The assumption is 1036 * format based on the incoming request packet type. The assumption is
926 * that a node not using the 4addr packet format doesn't support it. 1037 * that a node not using the 4addr packet format doesn't support it.
927 */ 1038 */
928 if (hdr_size == sizeof(struct batadv_unicast_4addr_packet)) 1039 if (hdr_size == sizeof(struct batadv_unicast_4addr_packet))
929 err = batadv_unicast_4addr_send_skb(bat_priv, skb_new, 1040 err = batadv_send_skb_via_tt_4addr(bat_priv, skb_new,
930 BATADV_P_DAT_CACHE_REPLY); 1041 BATADV_P_DAT_CACHE_REPLY,
1042 vid);
931 else 1043 else
932 err = batadv_unicast_send_skb(bat_priv, skb_new); 1044 err = batadv_send_skb_via_tt(bat_priv, skb_new, vid);
933 1045
934 if (!err) { 1046 if (err != NET_XMIT_DROP) {
935 batadv_inc_counter(bat_priv, BATADV_CNT_DAT_CACHED_REPLY_TX); 1047 batadv_inc_counter(bat_priv, BATADV_CNT_DAT_CACHED_REPLY_TX);
936 ret = true; 1048 ret = true;
937 } 1049 }
@@ -954,23 +1066,28 @@ void batadv_dat_snoop_outgoing_arp_reply(struct batadv_priv *bat_priv,
954 uint16_t type; 1066 uint16_t type;
955 __be32 ip_src, ip_dst; 1067 __be32 ip_src, ip_dst;
956 uint8_t *hw_src, *hw_dst; 1068 uint8_t *hw_src, *hw_dst;
1069 int hdr_size = 0;
1070 unsigned short vid;
957 1071
958 if (!atomic_read(&bat_priv->distributed_arp_table)) 1072 if (!atomic_read(&bat_priv->distributed_arp_table))
959 return; 1073 return;
960 1074
961 type = batadv_arp_get_type(bat_priv, skb, 0); 1075 vid = batadv_dat_get_vid(skb, &hdr_size);
1076
1077 type = batadv_arp_get_type(bat_priv, skb, hdr_size);
962 if (type != ARPOP_REPLY) 1078 if (type != ARPOP_REPLY)
963 return; 1079 return;
964 1080
965 batadv_dbg_arp(bat_priv, skb, type, 0, "Parsing outgoing ARP REPLY"); 1081 batadv_dbg_arp(bat_priv, skb, type, hdr_size,
1082 "Parsing outgoing ARP REPLY");
966 1083
967 hw_src = batadv_arp_hw_src(skb, 0); 1084 hw_src = batadv_arp_hw_src(skb, hdr_size);
968 ip_src = batadv_arp_ip_src(skb, 0); 1085 ip_src = batadv_arp_ip_src(skb, hdr_size);
969 hw_dst = batadv_arp_hw_dst(skb, 0); 1086 hw_dst = batadv_arp_hw_dst(skb, hdr_size);
970 ip_dst = batadv_arp_ip_dst(skb, 0); 1087 ip_dst = batadv_arp_ip_dst(skb, hdr_size);
971 1088
972 batadv_dat_entry_add(bat_priv, ip_src, hw_src); 1089 batadv_dat_entry_add(bat_priv, ip_src, hw_src, vid);
973 batadv_dat_entry_add(bat_priv, ip_dst, hw_dst); 1090 batadv_dat_entry_add(bat_priv, ip_dst, hw_dst, vid);
974 1091
975 /* Send the ARP reply to the candidates for both the IP addresses that 1092 /* Send the ARP reply to the candidates for both the IP addresses that
976 * the node obtained from the ARP reply 1093 * the node obtained from the ARP reply
@@ -992,10 +1109,13 @@ bool batadv_dat_snoop_incoming_arp_reply(struct batadv_priv *bat_priv,
992 __be32 ip_src, ip_dst; 1109 __be32 ip_src, ip_dst;
993 uint8_t *hw_src, *hw_dst; 1110 uint8_t *hw_src, *hw_dst;
994 bool ret = false; 1111 bool ret = false;
1112 unsigned short vid;
995 1113
996 if (!atomic_read(&bat_priv->distributed_arp_table)) 1114 if (!atomic_read(&bat_priv->distributed_arp_table))
997 goto out; 1115 goto out;
998 1116
1117 vid = batadv_dat_get_vid(skb, &hdr_size);
1118
999 type = batadv_arp_get_type(bat_priv, skb, hdr_size); 1119 type = batadv_arp_get_type(bat_priv, skb, hdr_size);
1000 if (type != ARPOP_REPLY) 1120 if (type != ARPOP_REPLY)
1001 goto out; 1121 goto out;
@@ -1011,13 +1131,13 @@ bool batadv_dat_snoop_incoming_arp_reply(struct batadv_priv *bat_priv,
1011 /* Update our internal cache with both the IP addresses the node got 1131 /* Update our internal cache with both the IP addresses the node got
1012 * within the ARP reply 1132 * within the ARP reply
1013 */ 1133 */
1014 batadv_dat_entry_add(bat_priv, ip_src, hw_src); 1134 batadv_dat_entry_add(bat_priv, ip_src, hw_src, vid);
1015 batadv_dat_entry_add(bat_priv, ip_dst, hw_dst); 1135 batadv_dat_entry_add(bat_priv, ip_dst, hw_dst, vid);
1016 1136
1017 /* if this REPLY is directed to a client of mine, let's deliver the 1137 /* if this REPLY is directed to a client of mine, let's deliver the
1018 * packet to the interface 1138 * packet to the interface
1019 */ 1139 */
1020 ret = !batadv_is_my_client(bat_priv, hw_dst); 1140 ret = !batadv_is_my_client(bat_priv, hw_dst, vid);
1021out: 1141out:
1022 if (ret) 1142 if (ret)
1023 kfree_skb(skb); 1143 kfree_skb(skb);
@@ -1040,7 +1160,8 @@ bool batadv_dat_drop_broadcast_packet(struct batadv_priv *bat_priv,
1040 __be32 ip_dst; 1160 __be32 ip_dst;
1041 struct batadv_dat_entry *dat_entry = NULL; 1161 struct batadv_dat_entry *dat_entry = NULL;
1042 bool ret = false; 1162 bool ret = false;
1043 const size_t bcast_len = sizeof(struct batadv_bcast_packet); 1163 int hdr_size = sizeof(struct batadv_bcast_packet);
1164 unsigned short vid;
1044 1165
1045 if (!atomic_read(&bat_priv->distributed_arp_table)) 1166 if (!atomic_read(&bat_priv->distributed_arp_table))
1046 goto out; 1167 goto out;
@@ -1051,12 +1172,14 @@ bool batadv_dat_drop_broadcast_packet(struct batadv_priv *bat_priv,
1051 if (forw_packet->num_packets) 1172 if (forw_packet->num_packets)
1052 goto out; 1173 goto out;
1053 1174
1054 type = batadv_arp_get_type(bat_priv, forw_packet->skb, bcast_len); 1175 vid = batadv_dat_get_vid(forw_packet->skb, &hdr_size);
1176
1177 type = batadv_arp_get_type(bat_priv, forw_packet->skb, hdr_size);
1055 if (type != ARPOP_REQUEST) 1178 if (type != ARPOP_REQUEST)
1056 goto out; 1179 goto out;
1057 1180
1058 ip_dst = batadv_arp_ip_dst(forw_packet->skb, bcast_len); 1181 ip_dst = batadv_arp_ip_dst(forw_packet->skb, hdr_size);
1059 dat_entry = batadv_dat_entry_hash_find(bat_priv, ip_dst); 1182 dat_entry = batadv_dat_entry_hash_find(bat_priv, ip_dst, vid);
1060 /* check if the node already got this entry */ 1183 /* check if the node already got this entry */
1061 if (!dat_entry) { 1184 if (!dat_entry) {
1062 batadv_dbg(BATADV_DBG_DAT, bat_priv, 1185 batadv_dbg(BATADV_DBG_DAT, bat_priv,
diff --git a/net/batman-adv/distributed-arp-table.h b/net/batman-adv/distributed-arp-table.h
index 125c8c6fcfad..60d853beb8d8 100644
--- a/net/batman-adv/distributed-arp-table.h
+++ b/net/batman-adv/distributed-arp-table.h
@@ -29,6 +29,7 @@
29 29
30#define BATADV_DAT_ADDR_MAX ((batadv_dat_addr_t)~(batadv_dat_addr_t)0) 30#define BATADV_DAT_ADDR_MAX ((batadv_dat_addr_t)~(batadv_dat_addr_t)0)
31 31
32void batadv_dat_status_update(struct net_device *net_dev);
32bool batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv, 33bool batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv,
33 struct sk_buff *skb); 34 struct sk_buff *skb);
34bool batadv_dat_snoop_incoming_arp_request(struct batadv_priv *bat_priv, 35bool batadv_dat_snoop_incoming_arp_request(struct batadv_priv *bat_priv,
@@ -98,6 +99,10 @@ static inline void batadv_dat_inc_counter(struct batadv_priv *bat_priv,
98 99
99#else 100#else
100 101
102static inline void batadv_dat_status_update(struct net_device *net_dev)
103{
104}
105
101static inline bool 106static inline bool
102batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv, 107batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv,
103 struct sk_buff *skb) 108 struct sk_buff *skb)
diff --git a/net/batman-adv/fragmentation.c b/net/batman-adv/fragmentation.c
new file mode 100644
index 000000000000..271d321b3a04
--- /dev/null
+++ b/net/batman-adv/fragmentation.c
@@ -0,0 +1,491 @@
1/* Copyright (C) 2013 B.A.T.M.A.N. contributors:
2 *
3 * Martin Hundebøll <martin@hundeboll.net>
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 "main.h"
21#include "fragmentation.h"
22#include "send.h"
23#include "originator.h"
24#include "routing.h"
25#include "hard-interface.h"
26#include "soft-interface.h"
27
28
29/**
30 * batadv_frag_clear_chain - delete entries in the fragment buffer chain
31 * @head: head of chain with entries.
32 *
33 * Free fragments in the passed hlist. Should be called with appropriate lock.
34 */
35static void batadv_frag_clear_chain(struct hlist_head *head)
36{
37 struct batadv_frag_list_entry *entry;
38 struct hlist_node *node;
39
40 hlist_for_each_entry_safe(entry, node, head, list) {
41 hlist_del(&entry->list);
42 kfree_skb(entry->skb);
43 kfree(entry);
44 }
45}
46
47/**
48 * batadv_frag_purge_orig - free fragments associated to an orig
49 * @orig_node: originator to free fragments from
50 * @check_cb: optional function to tell if an entry should be purged
51 */
52void batadv_frag_purge_orig(struct batadv_orig_node *orig_node,
53 bool (*check_cb)(struct batadv_frag_table_entry *))
54{
55 struct batadv_frag_table_entry *chain;
56 uint8_t i;
57
58 for (i = 0; i < BATADV_FRAG_BUFFER_COUNT; i++) {
59 chain = &orig_node->fragments[i];
60 spin_lock_bh(&orig_node->fragments[i].lock);
61
62 if (!check_cb || check_cb(chain)) {
63 batadv_frag_clear_chain(&orig_node->fragments[i].head);
64 orig_node->fragments[i].size = 0;
65 }
66
67 spin_unlock_bh(&orig_node->fragments[i].lock);
68 }
69}
70
71/**
72 * batadv_frag_size_limit - maximum possible size of packet to be fragmented
73 *
74 * Returns the maximum size of payload that can be fragmented.
75 */
76static int batadv_frag_size_limit(void)
77{
78 int limit = BATADV_FRAG_MAX_FRAG_SIZE;
79
80 limit -= sizeof(struct batadv_frag_packet);
81 limit *= BATADV_FRAG_MAX_FRAGMENTS;
82
83 return limit;
84}
85
86/**
87 * batadv_frag_init_chain - check and prepare fragment chain for new fragment
88 * @chain: chain in fragments table to init
89 * @seqno: sequence number of the received fragment
90 *
91 * Make chain ready for a fragment with sequence number "seqno". Delete existing
92 * entries if they have an "old" sequence number.
93 *
94 * Caller must hold chain->lock.
95 *
96 * Returns true if chain is empty and caller can just insert the new fragment
97 * without searching for the right position.
98 */
99static bool batadv_frag_init_chain(struct batadv_frag_table_entry *chain,
100 uint16_t seqno)
101{
102 if (chain->seqno == seqno)
103 return false;
104
105 if (!hlist_empty(&chain->head))
106 batadv_frag_clear_chain(&chain->head);
107
108 chain->size = 0;
109 chain->seqno = seqno;
110
111 return true;
112}
113
114/**
115 * batadv_frag_insert_packet - insert a fragment into a fragment chain
116 * @orig_node: originator that the fragment was received from
117 * @skb: skb to insert
118 * @chain_out: list head to attach complete chains of fragments to
119 *
120 * Insert a new fragment into the reverse ordered chain in the right table
121 * entry. The hash table entry is cleared if "old" fragments exist in it.
122 *
123 * Returns true if skb is buffered, false on error. If the chain has all the
124 * fragments needed to merge the packet, the chain is moved to the passed head
125 * to avoid locking the chain in the table.
126 */
127static bool batadv_frag_insert_packet(struct batadv_orig_node *orig_node,
128 struct sk_buff *skb,
129 struct hlist_head *chain_out)
130{
131 struct batadv_frag_table_entry *chain;
132 struct batadv_frag_list_entry *frag_entry_new = NULL, *frag_entry_curr;
133 struct batadv_frag_packet *frag_packet;
134 uint8_t bucket;
135 uint16_t seqno, hdr_size = sizeof(struct batadv_frag_packet);
136 bool ret = false;
137
138 /* Linearize packet to avoid linearizing 16 packets in a row when doing
139 * the later merge. Non-linear merge should be added to remove this
140 * linearization.
141 */
142 if (skb_linearize(skb) < 0)
143 goto err;
144
145 frag_packet = (struct batadv_frag_packet *)skb->data;
146 seqno = ntohs(frag_packet->seqno);
147 bucket = seqno % BATADV_FRAG_BUFFER_COUNT;
148
149 frag_entry_new = kmalloc(sizeof(*frag_entry_new), GFP_ATOMIC);
150 if (!frag_entry_new)
151 goto err;
152
153 frag_entry_new->skb = skb;
154 frag_entry_new->no = frag_packet->no;
155
156 /* Select entry in the "chain table" and delete any prior fragments
157 * with another sequence number. batadv_frag_init_chain() returns true,
158 * if the list is empty at return.
159 */
160 chain = &orig_node->fragments[bucket];
161 spin_lock_bh(&chain->lock);
162 if (batadv_frag_init_chain(chain, seqno)) {
163 hlist_add_head(&frag_entry_new->list, &chain->head);
164 chain->size = skb->len - hdr_size;
165 chain->timestamp = jiffies;
166 ret = true;
167 goto out;
168 }
169
170 /* Find the position for the new fragment. */
171 hlist_for_each_entry(frag_entry_curr, &chain->head, list) {
172 /* Drop packet if fragment already exists. */
173 if (frag_entry_curr->no == frag_entry_new->no)
174 goto err_unlock;
175
176 /* Order fragments from highest to lowest. */
177 if (frag_entry_curr->no < frag_entry_new->no) {
178 hlist_add_before(&frag_entry_new->list,
179 &frag_entry_curr->list);
180 chain->size += skb->len - hdr_size;
181 chain->timestamp = jiffies;
182 ret = true;
183 goto out;
184 }
185 }
186
187 /* Reached the end of the list, so insert after 'frag_entry_curr'. */
188 if (likely(frag_entry_curr)) {
189 hlist_add_after(&frag_entry_curr->list, &frag_entry_new->list);
190 chain->size += skb->len - hdr_size;
191 chain->timestamp = jiffies;
192 ret = true;
193 }
194
195out:
196 if (chain->size > batadv_frag_size_limit() ||
197 ntohs(frag_packet->total_size) > batadv_frag_size_limit()) {
198 /* Clear chain if total size of either the list or the packet
199 * exceeds the maximum size of one merged packet.
200 */
201 batadv_frag_clear_chain(&chain->head);
202 chain->size = 0;
203 } else if (ntohs(frag_packet->total_size) == chain->size) {
204 /* All fragments received. Hand over chain to caller. */
205 hlist_move_list(&chain->head, chain_out);
206 chain->size = 0;
207 }
208
209err_unlock:
210 spin_unlock_bh(&chain->lock);
211
212err:
213 if (!ret)
214 kfree(frag_entry_new);
215
216 return ret;
217}
218
219/**
220 * batadv_frag_merge_packets - merge a chain of fragments
221 * @chain: head of chain with fragments
222 * @skb: packet with total size of skb after merging
223 *
224 * Expand the first skb in the chain and copy the content of the remaining
225 * skb's into the expanded one. After doing so, clear the chain.
226 *
227 * Returns the merged skb or NULL on error.
228 */
229static struct sk_buff *
230batadv_frag_merge_packets(struct hlist_head *chain, struct sk_buff *skb)
231{
232 struct batadv_frag_packet *packet;
233 struct batadv_frag_list_entry *entry;
234 struct sk_buff *skb_out = NULL;
235 int size, hdr_size = sizeof(struct batadv_frag_packet);
236
237 /* Make sure incoming skb has non-bogus data. */
238 packet = (struct batadv_frag_packet *)skb->data;
239 size = ntohs(packet->total_size);
240 if (size > batadv_frag_size_limit())
241 goto free;
242
243 /* Remove first entry, as this is the destination for the rest of the
244 * fragments.
245 */
246 entry = hlist_entry(chain->first, struct batadv_frag_list_entry, list);
247 hlist_del(&entry->list);
248 skb_out = entry->skb;
249 kfree(entry);
250
251 /* Make room for the rest of the fragments. */
252 if (pskb_expand_head(skb_out, 0, size - skb->len, GFP_ATOMIC) < 0) {
253 kfree_skb(skb_out);
254 skb_out = NULL;
255 goto free;
256 }
257
258 /* Move the existing MAC header to just before the payload. (Override
259 * the fragment header.)
260 */
261 skb_pull_rcsum(skb_out, hdr_size);
262 memmove(skb_out->data - ETH_HLEN, skb_mac_header(skb_out), ETH_HLEN);
263 skb_set_mac_header(skb_out, -ETH_HLEN);
264 skb_reset_network_header(skb_out);
265 skb_reset_transport_header(skb_out);
266
267 /* Copy the payload of the each fragment into the last skb */
268 hlist_for_each_entry(entry, chain, list) {
269 size = entry->skb->len - hdr_size;
270 memcpy(skb_put(skb_out, size), entry->skb->data + hdr_size,
271 size);
272 }
273
274free:
275 /* Locking is not needed, because 'chain' is not part of any orig. */
276 batadv_frag_clear_chain(chain);
277 return skb_out;
278}
279
280/**
281 * batadv_frag_skb_buffer - buffer fragment for later merge
282 * @skb: skb to buffer
283 * @orig_node_src: originator that the skb is received from
284 *
285 * Add fragment to buffer and merge fragments if possible.
286 *
287 * There are three possible outcomes: 1) Packet is merged: Return true and
288 * set *skb to merged packet; 2) Packet is buffered: Return true and set *skb
289 * to NULL; 3) Error: Return false and leave skb as is.
290 */
291bool batadv_frag_skb_buffer(struct sk_buff **skb,
292 struct batadv_orig_node *orig_node_src)
293{
294 struct sk_buff *skb_out = NULL;
295 struct hlist_head head = HLIST_HEAD_INIT;
296 bool ret = false;
297
298 /* Add packet to buffer and table entry if merge is possible. */
299 if (!batadv_frag_insert_packet(orig_node_src, *skb, &head))
300 goto out_err;
301
302 /* Leave if more fragments are needed to merge. */
303 if (hlist_empty(&head))
304 goto out;
305
306 skb_out = batadv_frag_merge_packets(&head, *skb);
307 if (!skb_out)
308 goto out_err;
309
310out:
311 *skb = skb_out;
312 ret = true;
313out_err:
314 return ret;
315}
316
317/**
318 * batadv_frag_skb_fwd - forward fragments that would exceed MTU when merged
319 * @skb: skb to forward
320 * @recv_if: interface that the skb is received on
321 * @orig_node_src: originator that the skb is received from
322 *
323 * Look up the next-hop of the fragments payload and check if the merged packet
324 * will exceed the MTU towards the next-hop. If so, the fragment is forwarded
325 * without merging it.
326 *
327 * Returns true if the fragment is consumed/forwarded, false otherwise.
328 */
329bool batadv_frag_skb_fwd(struct sk_buff *skb,
330 struct batadv_hard_iface *recv_if,
331 struct batadv_orig_node *orig_node_src)
332{
333 struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface);
334 struct batadv_orig_node *orig_node_dst = NULL;
335 struct batadv_neigh_node *neigh_node = NULL;
336 struct batadv_frag_packet *packet;
337 uint16_t total_size;
338 bool ret = false;
339
340 packet = (struct batadv_frag_packet *)skb->data;
341 orig_node_dst = batadv_orig_hash_find(bat_priv, packet->dest);
342 if (!orig_node_dst)
343 goto out;
344
345 neigh_node = batadv_find_router(bat_priv, orig_node_dst, recv_if);
346 if (!neigh_node)
347 goto out;
348
349 /* Forward the fragment, if the merged packet would be too big to
350 * be assembled.
351 */
352 total_size = ntohs(packet->total_size);
353 if (total_size > neigh_node->if_incoming->net_dev->mtu) {
354 batadv_inc_counter(bat_priv, BATADV_CNT_FRAG_FWD);
355 batadv_add_counter(bat_priv, BATADV_CNT_FRAG_FWD_BYTES,
356 skb->len + ETH_HLEN);
357
358 packet->header.ttl--;
359 batadv_send_skb_packet(skb, neigh_node->if_incoming,
360 neigh_node->addr);
361 ret = true;
362 }
363
364out:
365 if (orig_node_dst)
366 batadv_orig_node_free_ref(orig_node_dst);
367 if (neigh_node)
368 batadv_neigh_node_free_ref(neigh_node);
369 return ret;
370}
371
372/**
373 * batadv_frag_create - create a fragment from skb
374 * @skb: skb to create fragment from
375 * @frag_head: header to use in new fragment
376 * @mtu: size of new fragment
377 *
378 * Split the passed skb into two fragments: A new one with size matching the
379 * passed mtu and the old one with the rest. The new skb contains data from the
380 * tail of the old skb.
381 *
382 * Returns the new fragment, NULL on error.
383 */
384static struct sk_buff *batadv_frag_create(struct sk_buff *skb,
385 struct batadv_frag_packet *frag_head,
386 unsigned int mtu)
387{
388 struct sk_buff *skb_fragment;
389 unsigned header_size = sizeof(*frag_head);
390 unsigned fragment_size = mtu - header_size;
391
392 skb_fragment = netdev_alloc_skb(NULL, mtu + ETH_HLEN);
393 if (!skb_fragment)
394 goto err;
395
396 skb->priority = TC_PRIO_CONTROL;
397
398 /* Eat the last mtu-bytes of the skb */
399 skb_reserve(skb_fragment, header_size + ETH_HLEN);
400 skb_split(skb, skb_fragment, skb->len - fragment_size);
401
402 /* Add the header */
403 skb_push(skb_fragment, header_size);
404 memcpy(skb_fragment->data, frag_head, header_size);
405
406err:
407 return skb_fragment;
408}
409
410/**
411 * batadv_frag_send_packet - create up to 16 fragments from the passed skb
412 * @skb: skb to create fragments from
413 * @orig_node: final destination of the created fragments
414 * @neigh_node: next-hop of the created fragments
415 *
416 * Returns true on success, false otherwise.
417 */
418bool batadv_frag_send_packet(struct sk_buff *skb,
419 struct batadv_orig_node *orig_node,
420 struct batadv_neigh_node *neigh_node)
421{
422 struct batadv_priv *bat_priv;
423 struct batadv_hard_iface *primary_if;
424 struct batadv_frag_packet frag_header;
425 struct sk_buff *skb_fragment;
426 unsigned mtu = neigh_node->if_incoming->net_dev->mtu;
427 unsigned header_size = sizeof(frag_header);
428 unsigned max_fragment_size, max_packet_size;
429
430 /* To avoid merge and refragmentation at next-hops we never send
431 * fragments larger than BATADV_FRAG_MAX_FRAG_SIZE
432 */
433 mtu = min_t(unsigned, mtu, BATADV_FRAG_MAX_FRAG_SIZE);
434 max_fragment_size = (mtu - header_size - ETH_HLEN);
435 max_packet_size = max_fragment_size * BATADV_FRAG_MAX_FRAGMENTS;
436
437 /* Don't even try to fragment, if we need more than 16 fragments */
438 if (skb->len > max_packet_size)
439 goto out_err;
440
441 bat_priv = orig_node->bat_priv;
442 primary_if = batadv_primary_if_get_selected(bat_priv);
443 if (!primary_if)
444 goto out_err;
445
446 /* Create one header to be copied to all fragments */
447 frag_header.header.packet_type = BATADV_UNICAST_FRAG;
448 frag_header.header.version = BATADV_COMPAT_VERSION;
449 frag_header.header.ttl = BATADV_TTL;
450 frag_header.seqno = htons(atomic_inc_return(&bat_priv->frag_seqno));
451 frag_header.reserved = 0;
452 frag_header.no = 0;
453 frag_header.total_size = htons(skb->len);
454 memcpy(frag_header.orig, primary_if->net_dev->dev_addr, ETH_ALEN);
455 memcpy(frag_header.dest, orig_node->orig, ETH_ALEN);
456
457 /* Eat and send fragments from the tail of skb */
458 while (skb->len > max_fragment_size) {
459 skb_fragment = batadv_frag_create(skb, &frag_header, mtu);
460 if (!skb_fragment)
461 goto out_err;
462
463 batadv_inc_counter(bat_priv, BATADV_CNT_FRAG_TX);
464 batadv_add_counter(bat_priv, BATADV_CNT_FRAG_TX_BYTES,
465 skb_fragment->len + ETH_HLEN);
466 batadv_send_skb_packet(skb_fragment, neigh_node->if_incoming,
467 neigh_node->addr);
468 frag_header.no++;
469
470 /* The initial check in this function should cover this case */
471 if (frag_header.no == BATADV_FRAG_MAX_FRAGMENTS - 1)
472 goto out_err;
473 }
474
475 /* Make room for the fragment header. */
476 if (batadv_skb_head_push(skb, header_size) < 0 ||
477 pskb_expand_head(skb, header_size + ETH_HLEN, 0, GFP_ATOMIC) < 0)
478 goto out_err;
479
480 memcpy(skb->data, &frag_header, header_size);
481
482 /* Send the last fragment */
483 batadv_inc_counter(bat_priv, BATADV_CNT_FRAG_TX);
484 batadv_add_counter(bat_priv, BATADV_CNT_FRAG_TX_BYTES,
485 skb->len + ETH_HLEN);
486 batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
487
488 return true;
489out_err:
490 return false;
491}
diff --git a/net/batman-adv/fragmentation.h b/net/batman-adv/fragmentation.h
new file mode 100644
index 000000000000..ca029e2676e7
--- /dev/null
+++ b/net/batman-adv/fragmentation.h
@@ -0,0 +1,50 @@
1/* Copyright (C) 2013 B.A.T.M.A.N. contributors:
2 *
3 * Martin Hundebøll <martin@hundeboll.net>
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_FRAGMENTATION_H_
21#define _NET_BATMAN_ADV_FRAGMENTATION_H_
22
23void batadv_frag_purge_orig(struct batadv_orig_node *orig,
24 bool (*check_cb)(struct batadv_frag_table_entry *));
25bool batadv_frag_skb_fwd(struct sk_buff *skb,
26 struct batadv_hard_iface *recv_if,
27 struct batadv_orig_node *orig_node_src);
28bool batadv_frag_skb_buffer(struct sk_buff **skb,
29 struct batadv_orig_node *orig_node);
30bool batadv_frag_send_packet(struct sk_buff *skb,
31 struct batadv_orig_node *orig_node,
32 struct batadv_neigh_node *neigh_node);
33
34/**
35 * batadv_frag_check_entry - check if a list of fragments has timed out
36 * @frags_entry: table entry to check
37 *
38 * Returns true if the frags entry has timed out, false otherwise.
39 */
40static inline bool
41batadv_frag_check_entry(struct batadv_frag_table_entry *frags_entry)
42{
43 if (!hlist_empty(&frags_entry->head) &&
44 batadv_has_timed_out(frags_entry->timestamp, BATADV_FRAG_TIMEOUT))
45 return true;
46 else
47 return false;
48}
49
50#endif /* _NET_BATMAN_ADV_FRAGMENTATION_H_ */
diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c
index 1ce4b8763ef2..20fa053b7f57 100644
--- a/net/batman-adv/gateway_client.c
+++ b/net/batman-adv/gateway_client.c
@@ -118,7 +118,6 @@ batadv_gw_get_best_gw_node(struct batadv_priv *bat_priv)
118 uint32_t max_gw_factor = 0, tmp_gw_factor = 0; 118 uint32_t max_gw_factor = 0, tmp_gw_factor = 0;
119 uint32_t gw_divisor; 119 uint32_t gw_divisor;
120 uint8_t max_tq = 0; 120 uint8_t max_tq = 0;
121 int down, up;
122 uint8_t tq_avg; 121 uint8_t tq_avg;
123 struct batadv_orig_node *orig_node; 122 struct batadv_orig_node *orig_node;
124 123
@@ -142,10 +141,9 @@ batadv_gw_get_best_gw_node(struct batadv_priv *bat_priv)
142 141
143 switch (atomic_read(&bat_priv->gw_sel_class)) { 142 switch (atomic_read(&bat_priv->gw_sel_class)) {
144 case 1: /* fast connection */ 143 case 1: /* fast connection */
145 batadv_gw_bandwidth_to_kbit(orig_node->gw_flags, 144 tmp_gw_factor = tq_avg * tq_avg;
146 &down, &up); 145 tmp_gw_factor *= gw_node->bandwidth_down;
147 146 tmp_gw_factor *= 100 * 100;
148 tmp_gw_factor = tq_avg * tq_avg * down * 100 * 100;
149 tmp_gw_factor /= gw_divisor; 147 tmp_gw_factor /= gw_divisor;
150 148
151 if ((tmp_gw_factor > max_gw_factor) || 149 if ((tmp_gw_factor > max_gw_factor) ||
@@ -223,11 +221,6 @@ void batadv_gw_election(struct batadv_priv *bat_priv)
223 struct batadv_neigh_node *router = NULL; 221 struct batadv_neigh_node *router = NULL;
224 char gw_addr[18] = { '\0' }; 222 char gw_addr[18] = { '\0' };
225 223
226 /* The batman daemon checks here if we already passed a full originator
227 * cycle in order to make sure we don't choose the first gateway we
228 * hear about. This check is based on the daemon's uptime which we
229 * don't have.
230 */
231 if (atomic_read(&bat_priv->gw_mode) != BATADV_GW_MODE_CLIENT) 224 if (atomic_read(&bat_priv->gw_mode) != BATADV_GW_MODE_CLIENT)
232 goto out; 225 goto out;
233 226
@@ -258,16 +251,22 @@ void batadv_gw_election(struct batadv_priv *bat_priv)
258 NULL); 251 NULL);
259 } else if ((!curr_gw) && (next_gw)) { 252 } else if ((!curr_gw) && (next_gw)) {
260 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, 253 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
261 "Adding route to gateway %pM (gw_flags: %i, tq: %i)\n", 254 "Adding route to gateway %pM (bandwidth: %u.%u/%u.%u MBit, tq: %i)\n",
262 next_gw->orig_node->orig, 255 next_gw->orig_node->orig,
263 next_gw->orig_node->gw_flags, router->tq_avg); 256 next_gw->bandwidth_down / 10,
257 next_gw->bandwidth_down % 10,
258 next_gw->bandwidth_up / 10,
259 next_gw->bandwidth_up % 10, router->tq_avg);
264 batadv_throw_uevent(bat_priv, BATADV_UEV_GW, BATADV_UEV_ADD, 260 batadv_throw_uevent(bat_priv, BATADV_UEV_GW, BATADV_UEV_ADD,
265 gw_addr); 261 gw_addr);
266 } else { 262 } else {
267 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, 263 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
268 "Changing route to gateway %pM (gw_flags: %i, tq: %i)\n", 264 "Changing route to gateway %pM (bandwidth: %u.%u/%u.%u MBit, tq: %i)\n",
269 next_gw->orig_node->orig, 265 next_gw->orig_node->orig,
270 next_gw->orig_node->gw_flags, router->tq_avg); 266 next_gw->bandwidth_down / 10,
267 next_gw->bandwidth_down % 10,
268 next_gw->bandwidth_up / 10,
269 next_gw->bandwidth_up % 10, router->tq_avg);
271 batadv_throw_uevent(bat_priv, BATADV_UEV_GW, BATADV_UEV_CHANGE, 270 batadv_throw_uevent(bat_priv, BATADV_UEV_GW, BATADV_UEV_CHANGE,
272 gw_addr); 271 gw_addr);
273 } 272 }
@@ -337,12 +336,20 @@ out:
337 return; 336 return;
338} 337}
339 338
339/**
340 * batadv_gw_node_add - add gateway node to list of available gateways
341 * @bat_priv: the bat priv with all the soft interface information
342 * @orig_node: originator announcing gateway capabilities
343 * @gateway: announced bandwidth information
344 */
340static void batadv_gw_node_add(struct batadv_priv *bat_priv, 345static void batadv_gw_node_add(struct batadv_priv *bat_priv,
341 struct batadv_orig_node *orig_node, 346 struct batadv_orig_node *orig_node,
342 uint8_t new_gwflags) 347 struct batadv_tvlv_gateway_data *gateway)
343{ 348{
344 struct batadv_gw_node *gw_node; 349 struct batadv_gw_node *gw_node;
345 int down, up; 350
351 if (gateway->bandwidth_down == 0)
352 return;
346 353
347 gw_node = kzalloc(sizeof(*gw_node), GFP_ATOMIC); 354 gw_node = kzalloc(sizeof(*gw_node), GFP_ATOMIC);
348 if (!gw_node) 355 if (!gw_node)
@@ -356,73 +363,116 @@ static void batadv_gw_node_add(struct batadv_priv *bat_priv,
356 hlist_add_head_rcu(&gw_node->list, &bat_priv->gw.list); 363 hlist_add_head_rcu(&gw_node->list, &bat_priv->gw.list);
357 spin_unlock_bh(&bat_priv->gw.list_lock); 364 spin_unlock_bh(&bat_priv->gw.list_lock);
358 365
359 batadv_gw_bandwidth_to_kbit(new_gwflags, &down, &up);
360 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, 366 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
361 "Found new gateway %pM -> gw_class: %i - %i%s/%i%s\n", 367 "Found new gateway %pM -> gw bandwidth: %u.%u/%u.%u MBit\n",
362 orig_node->orig, new_gwflags, 368 orig_node->orig,
363 (down > 2048 ? down / 1024 : down), 369 ntohl(gateway->bandwidth_down) / 10,
364 (down > 2048 ? "MBit" : "KBit"), 370 ntohl(gateway->bandwidth_down) % 10,
365 (up > 2048 ? up / 1024 : up), 371 ntohl(gateway->bandwidth_up) / 10,
366 (up > 2048 ? "MBit" : "KBit")); 372 ntohl(gateway->bandwidth_up) % 10);
367} 373}
368 374
369void batadv_gw_node_update(struct batadv_priv *bat_priv, 375/**
370 struct batadv_orig_node *orig_node, 376 * batadv_gw_node_get - retrieve gateway node from list of available gateways
371 uint8_t new_gwflags) 377 * @bat_priv: the bat priv with all the soft interface information
378 * @orig_node: originator announcing gateway capabilities
379 *
380 * Returns gateway node if found or NULL otherwise.
381 */
382static struct batadv_gw_node *
383batadv_gw_node_get(struct batadv_priv *bat_priv,
384 struct batadv_orig_node *orig_node)
372{ 385{
373 struct batadv_gw_node *gw_node, *curr_gw; 386 struct batadv_gw_node *gw_node_tmp, *gw_node = NULL;
374
375 /* Note: We don't need a NULL check here, since curr_gw never gets
376 * dereferenced. If curr_gw is NULL we also should not exit as we may
377 * have this gateway in our list (duplication check!) even though we
378 * have no currently selected gateway.
379 */
380 curr_gw = batadv_gw_get_selected_gw_node(bat_priv);
381 387
382 rcu_read_lock(); 388 rcu_read_lock();
383 hlist_for_each_entry_rcu(gw_node, &bat_priv->gw.list, list) { 389 hlist_for_each_entry_rcu(gw_node_tmp, &bat_priv->gw.list, list) {
384 if (gw_node->orig_node != orig_node) 390 if (gw_node_tmp->orig_node != orig_node)
385 continue; 391 continue;
386 392
387 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, 393 if (gw_node_tmp->deleted)
388 "Gateway class of originator %pM changed from %i to %i\n", 394 continue;
389 orig_node->orig, gw_node->orig_node->gw_flags,
390 new_gwflags);
391 395
392 gw_node->deleted = 0; 396 if (!atomic_inc_not_zero(&gw_node_tmp->refcount))
397 continue;
393 398
394 if (new_gwflags == BATADV_NO_FLAGS) { 399 gw_node = gw_node_tmp;
395 gw_node->deleted = jiffies; 400 break;
396 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, 401 }
397 "Gateway %pM removed from gateway list\n", 402 rcu_read_unlock();
398 orig_node->orig);
399 403
400 if (gw_node == curr_gw) 404 return gw_node;
401 goto deselect; 405}
402 }
403 406
404 goto unlock; 407/**
408 * batadv_gw_node_update - update list of available gateways with changed
409 * bandwidth information
410 * @bat_priv: the bat priv with all the soft interface information
411 * @orig_node: originator announcing gateway capabilities
412 * @gateway: announced bandwidth information
413 */
414void batadv_gw_node_update(struct batadv_priv *bat_priv,
415 struct batadv_orig_node *orig_node,
416 struct batadv_tvlv_gateway_data *gateway)
417{
418 struct batadv_gw_node *gw_node, *curr_gw = NULL;
419
420 gw_node = batadv_gw_node_get(bat_priv, orig_node);
421 if (!gw_node) {
422 batadv_gw_node_add(bat_priv, orig_node, gateway);
423 goto out;
405 } 424 }
406 425
407 if (new_gwflags == BATADV_NO_FLAGS) 426 if ((gw_node->bandwidth_down == ntohl(gateway->bandwidth_down)) &&
408 goto unlock; 427 (gw_node->bandwidth_up == ntohl(gateway->bandwidth_up)))
428 goto out;
409 429
410 batadv_gw_node_add(bat_priv, orig_node, new_gwflags); 430 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
411 goto unlock; 431 "Gateway bandwidth of originator %pM changed from %u.%u/%u.%u MBit to %u.%u/%u.%u MBit\n",
432 orig_node->orig,
433 gw_node->bandwidth_down / 10,
434 gw_node->bandwidth_down % 10,
435 gw_node->bandwidth_up / 10,
436 gw_node->bandwidth_up % 10,
437 ntohl(gateway->bandwidth_down) / 10,
438 ntohl(gateway->bandwidth_down) % 10,
439 ntohl(gateway->bandwidth_up) / 10,
440 ntohl(gateway->bandwidth_up) % 10);
441
442 gw_node->bandwidth_down = ntohl(gateway->bandwidth_down);
443 gw_node->bandwidth_up = ntohl(gateway->bandwidth_up);
444
445 gw_node->deleted = 0;
446 if (ntohl(gateway->bandwidth_down) == 0) {
447 gw_node->deleted = jiffies;
448 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
449 "Gateway %pM removed from gateway list\n",
450 orig_node->orig);
412 451
413deselect: 452 /* Note: We don't need a NULL check here, since curr_gw never
414 batadv_gw_deselect(bat_priv); 453 * gets dereferenced.
415unlock: 454 */
416 rcu_read_unlock(); 455 curr_gw = batadv_gw_get_selected_gw_node(bat_priv);
456 if (gw_node == curr_gw)
457 batadv_gw_deselect(bat_priv);
458 }
417 459
460out:
418 if (curr_gw) 461 if (curr_gw)
419 batadv_gw_node_free_ref(curr_gw); 462 batadv_gw_node_free_ref(curr_gw);
463 if (gw_node)
464 batadv_gw_node_free_ref(gw_node);
420} 465}
421 466
422void batadv_gw_node_delete(struct batadv_priv *bat_priv, 467void batadv_gw_node_delete(struct batadv_priv *bat_priv,
423 struct batadv_orig_node *orig_node) 468 struct batadv_orig_node *orig_node)
424{ 469{
425 batadv_gw_node_update(bat_priv, orig_node, 0); 470 struct batadv_tvlv_gateway_data gateway;
471
472 gateway.bandwidth_down = 0;
473 gateway.bandwidth_up = 0;
474
475 batadv_gw_node_update(bat_priv, orig_node, &gateway);
426} 476}
427 477
428void batadv_gw_node_purge(struct batadv_priv *bat_priv) 478void batadv_gw_node_purge(struct batadv_priv *bat_priv)
@@ -467,9 +517,7 @@ static int batadv_write_buffer_text(struct batadv_priv *bat_priv,
467{ 517{
468 struct batadv_gw_node *curr_gw; 518 struct batadv_gw_node *curr_gw;
469 struct batadv_neigh_node *router; 519 struct batadv_neigh_node *router;
470 int down, up, ret = -1; 520 int ret = -1;
471
472 batadv_gw_bandwidth_to_kbit(gw_node->orig_node->gw_flags, &down, &up);
473 521
474 router = batadv_orig_node_get_router(gw_node->orig_node); 522 router = batadv_orig_node_get_router(gw_node->orig_node);
475 if (!router) 523 if (!router)
@@ -477,16 +525,15 @@ static int batadv_write_buffer_text(struct batadv_priv *bat_priv,
477 525
478 curr_gw = batadv_gw_get_selected_gw_node(bat_priv); 526 curr_gw = batadv_gw_get_selected_gw_node(bat_priv);
479 527
480 ret = seq_printf(seq, "%s %pM (%3i) %pM [%10s]: %3i - %i%s/%i%s\n", 528 ret = seq_printf(seq, "%s %pM (%3i) %pM [%10s]: %u.%u/%u.%u MBit\n",
481 (curr_gw == gw_node ? "=>" : " "), 529 (curr_gw == gw_node ? "=>" : " "),
482 gw_node->orig_node->orig, 530 gw_node->orig_node->orig,
483 router->tq_avg, router->addr, 531 router->tq_avg, router->addr,
484 router->if_incoming->net_dev->name, 532 router->if_incoming->net_dev->name,
485 gw_node->orig_node->gw_flags, 533 gw_node->bandwidth_down / 10,
486 (down > 2048 ? down / 1024 : down), 534 gw_node->bandwidth_down % 10,
487 (down > 2048 ? "MBit" : "KBit"), 535 gw_node->bandwidth_up / 10,
488 (up > 2048 ? up / 1024 : up), 536 gw_node->bandwidth_up % 10);
489 (up > 2048 ? "MBit" : "KBit"));
490 537
491 batadv_neigh_node_free_ref(router); 538 batadv_neigh_node_free_ref(router);
492 if (curr_gw) 539 if (curr_gw)
@@ -508,7 +555,7 @@ int batadv_gw_client_seq_print_text(struct seq_file *seq, void *offset)
508 goto out; 555 goto out;
509 556
510 seq_printf(seq, 557 seq_printf(seq,
511 " %-12s (%s/%i) %17s [%10s]: gw_class ... [B.A.T.M.A.N. adv %s, MainIF/MAC: %s/%pM (%s)]\n", 558 " %-12s (%s/%i) %17s [%10s]: advertised uplink bandwidth ... [B.A.T.M.A.N. adv %s, MainIF/MAC: %s/%pM (%s)]\n",
512 "Gateway", "#", BATADV_TQ_MAX_VALUE, "Nexthop", "outgoingIF", 559 "Gateway", "#", BATADV_TQ_MAX_VALUE, "Nexthop", "outgoingIF",
513 BATADV_SOURCE_VERSION, primary_if->net_dev->name, 560 BATADV_SOURCE_VERSION, primary_if->net_dev->name,
514 primary_if->net_dev->dev_addr, net_dev->name); 561 primary_if->net_dev->dev_addr, net_dev->name);
@@ -603,24 +650,29 @@ bool batadv_gw_is_dhcp_target(struct sk_buff *skb, unsigned int *header_len)
603 struct iphdr *iphdr; 650 struct iphdr *iphdr;
604 struct ipv6hdr *ipv6hdr; 651 struct ipv6hdr *ipv6hdr;
605 struct udphdr *udphdr; 652 struct udphdr *udphdr;
653 struct vlan_ethhdr *vhdr;
654 __be16 proto;
606 655
607 /* check for ethernet header */ 656 /* check for ethernet header */
608 if (!pskb_may_pull(skb, *header_len + ETH_HLEN)) 657 if (!pskb_may_pull(skb, *header_len + ETH_HLEN))
609 return false; 658 return false;
610 ethhdr = (struct ethhdr *)skb->data; 659 ethhdr = (struct ethhdr *)skb->data;
660 proto = ethhdr->h_proto;
611 *header_len += ETH_HLEN; 661 *header_len += ETH_HLEN;
612 662
613 /* check for initial vlan header */ 663 /* check for initial vlan header */
614 if (ntohs(ethhdr->h_proto) == ETH_P_8021Q) { 664 if (proto == htons(ETH_P_8021Q)) {
615 if (!pskb_may_pull(skb, *header_len + VLAN_HLEN)) 665 if (!pskb_may_pull(skb, *header_len + VLAN_HLEN))
616 return false; 666 return false;
617 ethhdr = (struct ethhdr *)(skb->data + VLAN_HLEN); 667
668 vhdr = (struct vlan_ethhdr *)skb->data;
669 proto = vhdr->h_vlan_encapsulated_proto;
618 *header_len += VLAN_HLEN; 670 *header_len += VLAN_HLEN;
619 } 671 }
620 672
621 /* check for ip header */ 673 /* check for ip header */
622 switch (ntohs(ethhdr->h_proto)) { 674 switch (proto) {
623 case ETH_P_IP: 675 case htons(ETH_P_IP):
624 if (!pskb_may_pull(skb, *header_len + sizeof(*iphdr))) 676 if (!pskb_may_pull(skb, *header_len + sizeof(*iphdr)))
625 return false; 677 return false;
626 iphdr = (struct iphdr *)(skb->data + *header_len); 678 iphdr = (struct iphdr *)(skb->data + *header_len);
@@ -631,7 +683,7 @@ bool batadv_gw_is_dhcp_target(struct sk_buff *skb, unsigned int *header_len)
631 return false; 683 return false;
632 684
633 break; 685 break;
634 case ETH_P_IPV6: 686 case htons(ETH_P_IPV6):
635 if (!pskb_may_pull(skb, *header_len + sizeof(*ipv6hdr))) 687 if (!pskb_may_pull(skb, *header_len + sizeof(*ipv6hdr)))
636 return false; 688 return false;
637 ipv6hdr = (struct ipv6hdr *)(skb->data + *header_len); 689 ipv6hdr = (struct ipv6hdr *)(skb->data + *header_len);
@@ -658,28 +710,44 @@ bool batadv_gw_is_dhcp_target(struct sk_buff *skb, unsigned int *header_len)
658 *header_len += sizeof(*udphdr); 710 *header_len += sizeof(*udphdr);
659 711
660 /* check for bootp port */ 712 /* check for bootp port */
661 if ((ntohs(ethhdr->h_proto) == ETH_P_IP) && 713 if ((proto == htons(ETH_P_IP)) &&
662 (ntohs(udphdr->dest) != 67)) 714 (udphdr->dest != htons(67)))
663 return false; 715 return false;
664 716
665 if ((ntohs(ethhdr->h_proto) == ETH_P_IPV6) && 717 if ((proto == htons(ETH_P_IPV6)) &&
666 (ntohs(udphdr->dest) != 547)) 718 (udphdr->dest != htons(547)))
667 return false; 719 return false;
668 720
669 return true; 721 return true;
670} 722}
671 723
672/* this call might reallocate skb data */ 724/**
725 * batadv_gw_out_of_range - check if the dhcp request destination is the best gw
726 * @bat_priv: the bat priv with all the soft interface information
727 * @skb: the outgoing packet
728 *
729 * Check if the skb is a DHCP request and if it is sent to the current best GW
730 * server. Due to topology changes it may be the case that the GW server
731 * previously selected is not the best one anymore.
732 *
733 * Returns true if the packet destination is unicast and it is not the best gw,
734 * false otherwise.
735 *
736 * This call might reallocate skb data.
737 */
673bool batadv_gw_out_of_range(struct batadv_priv *bat_priv, 738bool batadv_gw_out_of_range(struct batadv_priv *bat_priv,
674 struct sk_buff *skb) 739 struct sk_buff *skb)
675{ 740{
676 struct batadv_neigh_node *neigh_curr = NULL, *neigh_old = NULL; 741 struct batadv_neigh_node *neigh_curr = NULL, *neigh_old = NULL;
677 struct batadv_orig_node *orig_dst_node = NULL; 742 struct batadv_orig_node *orig_dst_node = NULL;
678 struct batadv_gw_node *curr_gw = NULL; 743 struct batadv_gw_node *gw_node = NULL, *curr_gw = NULL;
679 struct ethhdr *ethhdr; 744 struct ethhdr *ethhdr;
680 bool ret, out_of_range = false; 745 bool ret, out_of_range = false;
681 unsigned int header_len = 0; 746 unsigned int header_len = 0;
682 uint8_t curr_tq_avg; 747 uint8_t curr_tq_avg;
748 unsigned short vid;
749
750 vid = batadv_get_vid(skb, 0);
683 751
684 ret = batadv_gw_is_dhcp_target(skb, &header_len); 752 ret = batadv_gw_is_dhcp_target(skb, &header_len);
685 if (!ret) 753 if (!ret)
@@ -687,11 +755,12 @@ bool batadv_gw_out_of_range(struct batadv_priv *bat_priv,
687 755
688 ethhdr = (struct ethhdr *)skb->data; 756 ethhdr = (struct ethhdr *)skb->data;
689 orig_dst_node = batadv_transtable_search(bat_priv, ethhdr->h_source, 757 orig_dst_node = batadv_transtable_search(bat_priv, ethhdr->h_source,
690 ethhdr->h_dest); 758 ethhdr->h_dest, vid);
691 if (!orig_dst_node) 759 if (!orig_dst_node)
692 goto out; 760 goto out;
693 761
694 if (!orig_dst_node->gw_flags) 762 gw_node = batadv_gw_node_get(bat_priv, orig_dst_node);
763 if (!gw_node->bandwidth_down == 0)
695 goto out; 764 goto out;
696 765
697 ret = batadv_is_type_dhcprequest(skb, header_len); 766 ret = batadv_is_type_dhcprequest(skb, header_len);
@@ -742,6 +811,8 @@ out:
742 batadv_orig_node_free_ref(orig_dst_node); 811 batadv_orig_node_free_ref(orig_dst_node);
743 if (curr_gw) 812 if (curr_gw)
744 batadv_gw_node_free_ref(curr_gw); 813 batadv_gw_node_free_ref(curr_gw);
814 if (gw_node)
815 batadv_gw_node_free_ref(gw_node);
745 if (neigh_old) 816 if (neigh_old)
746 batadv_neigh_node_free_ref(neigh_old); 817 batadv_neigh_node_free_ref(neigh_old);
747 if (neigh_curr) 818 if (neigh_curr)
diff --git a/net/batman-adv/gateway_client.h b/net/batman-adv/gateway_client.h
index ceef4ebe8bcd..d95c2d23195e 100644
--- a/net/batman-adv/gateway_client.h
+++ b/net/batman-adv/gateway_client.h
@@ -29,7 +29,7 @@ void batadv_gw_check_election(struct batadv_priv *bat_priv,
29 struct batadv_orig_node *orig_node); 29 struct batadv_orig_node *orig_node);
30void batadv_gw_node_update(struct batadv_priv *bat_priv, 30void batadv_gw_node_update(struct batadv_priv *bat_priv,
31 struct batadv_orig_node *orig_node, 31 struct batadv_orig_node *orig_node,
32 uint8_t new_gwflags); 32 struct batadv_tvlv_gateway_data *gateway);
33void batadv_gw_node_delete(struct batadv_priv *bat_priv, 33void batadv_gw_node_delete(struct batadv_priv *bat_priv,
34 struct batadv_orig_node *orig_node); 34 struct batadv_orig_node *orig_node);
35void batadv_gw_node_purge(struct batadv_priv *bat_priv); 35void batadv_gw_node_purge(struct batadv_priv *bat_priv);
diff --git a/net/batman-adv/gateway_common.c b/net/batman-adv/gateway_common.c
index 84bb2b18d711..b211b0f9cb78 100644
--- a/net/batman-adv/gateway_common.c
+++ b/net/batman-adv/gateway_common.c
@@ -21,64 +21,23 @@
21#include "gateway_common.h" 21#include "gateway_common.h"
22#include "gateway_client.h" 22#include "gateway_client.h"
23 23
24/* calculates the gateway class from kbit */ 24/**
25static void batadv_kbit_to_gw_bandwidth(int down, int up, long *gw_srv_class) 25 * batadv_parse_gw_bandwidth - parse supplied string buffer to extract download
26{ 26 * and upload bandwidth information
27 int mdown = 0, tdown, tup, difference; 27 * @net_dev: the soft interface net device
28 uint8_t sbit, part; 28 * @buff: string buffer to parse
29 29 * @down: pointer holding the returned download bandwidth information
30 *gw_srv_class = 0; 30 * @up: pointer holding the returned upload bandwidth information
31 difference = 0x0FFFFFFF; 31 *
32 32 * Returns false on parse error and true otherwise.
33 /* test all downspeeds */ 33 */
34 for (sbit = 0; sbit < 2; sbit++) {
35 for (part = 0; part < 16; part++) {
36 tdown = 32 * (sbit + 2) * (1 << part);
37
38 if (abs(tdown - down) < difference) {
39 *gw_srv_class = (sbit << 7) + (part << 3);
40 difference = abs(tdown - down);
41 mdown = tdown;
42 }
43 }
44 }
45
46 /* test all upspeeds */
47 difference = 0x0FFFFFFF;
48
49 for (part = 0; part < 8; part++) {
50 tup = ((part + 1) * (mdown)) / 8;
51
52 if (abs(tup - up) < difference) {
53 *gw_srv_class = (*gw_srv_class & 0xF8) | part;
54 difference = abs(tup - up);
55 }
56 }
57}
58
59/* returns the up and downspeeds in kbit, calculated from the class */
60void batadv_gw_bandwidth_to_kbit(uint8_t gw_srv_class, int *down, int *up)
61{
62 int sbit = (gw_srv_class & 0x80) >> 7;
63 int dpart = (gw_srv_class & 0x78) >> 3;
64 int upart = (gw_srv_class & 0x07);
65
66 if (!gw_srv_class) {
67 *down = 0;
68 *up = 0;
69 return;
70 }
71
72 *down = 32 * (sbit + 2) * (1 << dpart);
73 *up = ((upart + 1) * (*down)) / 8;
74}
75
76static bool batadv_parse_gw_bandwidth(struct net_device *net_dev, char *buff, 34static bool batadv_parse_gw_bandwidth(struct net_device *net_dev, char *buff,
77 int *up, int *down) 35 uint32_t *down, uint32_t *up)
78{ 36{
79 int ret, multi = 1; 37 enum batadv_bandwidth_units bw_unit_type = BATADV_BW_UNIT_KBIT;
80 char *slash_ptr, *tmp_ptr; 38 char *slash_ptr, *tmp_ptr;
81 long ldown, lup; 39 long ldown, lup;
40 int ret;
82 41
83 slash_ptr = strchr(buff, '/'); 42 slash_ptr = strchr(buff, '/');
84 if (slash_ptr) 43 if (slash_ptr)
@@ -88,10 +47,10 @@ static bool batadv_parse_gw_bandwidth(struct net_device *net_dev, char *buff,
88 tmp_ptr = buff + strlen(buff) - 4; 47 tmp_ptr = buff + strlen(buff) - 4;
89 48
90 if (strnicmp(tmp_ptr, "mbit", 4) == 0) 49 if (strnicmp(tmp_ptr, "mbit", 4) == 0)
91 multi = 1024; 50 bw_unit_type = BATADV_BW_UNIT_MBIT;
92 51
93 if ((strnicmp(tmp_ptr, "kbit", 4) == 0) || 52 if ((strnicmp(tmp_ptr, "kbit", 4) == 0) ||
94 (multi > 1)) 53 (bw_unit_type == BATADV_BW_UNIT_MBIT))
95 *tmp_ptr = '\0'; 54 *tmp_ptr = '\0';
96 } 55 }
97 56
@@ -103,20 +62,28 @@ static bool batadv_parse_gw_bandwidth(struct net_device *net_dev, char *buff,
103 return false; 62 return false;
104 } 63 }
105 64
106 *down = ldown * multi; 65 switch (bw_unit_type) {
66 case BATADV_BW_UNIT_MBIT:
67 *down = ldown * 10;
68 break;
69 case BATADV_BW_UNIT_KBIT:
70 default:
71 *down = ldown / 100;
72 break;
73 }
107 74
108 /* we also got some upload info */ 75 /* we also got some upload info */
109 if (slash_ptr) { 76 if (slash_ptr) {
110 multi = 1; 77 bw_unit_type = BATADV_BW_UNIT_KBIT;
111 78
112 if (strlen(slash_ptr + 1) > 4) { 79 if (strlen(slash_ptr + 1) > 4) {
113 tmp_ptr = slash_ptr + 1 - 4 + strlen(slash_ptr + 1); 80 tmp_ptr = slash_ptr + 1 - 4 + strlen(slash_ptr + 1);
114 81
115 if (strnicmp(tmp_ptr, "mbit", 4) == 0) 82 if (strnicmp(tmp_ptr, "mbit", 4) == 0)
116 multi = 1024; 83 bw_unit_type = BATADV_BW_UNIT_MBIT;
117 84
118 if ((strnicmp(tmp_ptr, "kbit", 4) == 0) || 85 if ((strnicmp(tmp_ptr, "kbit", 4) == 0) ||
119 (multi > 1)) 86 (bw_unit_type == BATADV_BW_UNIT_MBIT))
120 *tmp_ptr = '\0'; 87 *tmp_ptr = '\0';
121 } 88 }
122 89
@@ -128,52 +95,149 @@ static bool batadv_parse_gw_bandwidth(struct net_device *net_dev, char *buff,
128 return false; 95 return false;
129 } 96 }
130 97
131 *up = lup * multi; 98 switch (bw_unit_type) {
99 case BATADV_BW_UNIT_MBIT:
100 *up = lup * 10;
101 break;
102 case BATADV_BW_UNIT_KBIT:
103 default:
104 *up = lup / 100;
105 break;
106 }
132 } 107 }
133 108
134 return true; 109 return true;
135} 110}
136 111
112/**
113 * batadv_gw_tvlv_container_update - update the gw tvlv container after gateway
114 * setting change
115 * @bat_priv: the bat priv with all the soft interface information
116 */
117void batadv_gw_tvlv_container_update(struct batadv_priv *bat_priv)
118{
119 struct batadv_tvlv_gateway_data gw;
120 uint32_t down, up;
121 char gw_mode;
122
123 gw_mode = atomic_read(&bat_priv->gw_mode);
124
125 switch (gw_mode) {
126 case BATADV_GW_MODE_OFF:
127 case BATADV_GW_MODE_CLIENT:
128 batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_GW, 1);
129 break;
130 case BATADV_GW_MODE_SERVER:
131 down = atomic_read(&bat_priv->gw.bandwidth_down);
132 up = atomic_read(&bat_priv->gw.bandwidth_up);
133 gw.bandwidth_down = htonl(down);
134 gw.bandwidth_up = htonl(up);
135 batadv_tvlv_container_register(bat_priv, BATADV_TVLV_GW, 1,
136 &gw, sizeof(gw));
137 break;
138 }
139}
140
137ssize_t batadv_gw_bandwidth_set(struct net_device *net_dev, char *buff, 141ssize_t batadv_gw_bandwidth_set(struct net_device *net_dev, char *buff,
138 size_t count) 142 size_t count)
139{ 143{
140 struct batadv_priv *bat_priv = netdev_priv(net_dev); 144 struct batadv_priv *bat_priv = netdev_priv(net_dev);
141 long gw_bandwidth_tmp = 0; 145 uint32_t down_curr, up_curr, down_new = 0, up_new = 0;
142 int up = 0, down = 0;
143 bool ret; 146 bool ret;
144 147
145 ret = batadv_parse_gw_bandwidth(net_dev, buff, &up, &down); 148 down_curr = (unsigned int)atomic_read(&bat_priv->gw.bandwidth_down);
149 up_curr = (unsigned int)atomic_read(&bat_priv->gw.bandwidth_up);
150
151 ret = batadv_parse_gw_bandwidth(net_dev, buff, &down_new, &up_new);
146 if (!ret) 152 if (!ret)
147 goto end; 153 goto end;
148 154
149 if ((!down) || (down < 256)) 155 if (!down_new)
150 down = 2000; 156 down_new = 1;
151
152 if (!up)
153 up = down / 5;
154 157
155 batadv_kbit_to_gw_bandwidth(down, up, &gw_bandwidth_tmp); 158 if (!up_new)
159 up_new = down_new / 5;
156 160
157 /* the gw bandwidth we guessed above might not match the given 161 if (!up_new)
158 * speeds, hence we need to calculate it back to show the number 162 up_new = 1;
159 * that is going to be propagated
160 */
161 batadv_gw_bandwidth_to_kbit((uint8_t)gw_bandwidth_tmp, &down, &up);
162 163
163 if (atomic_read(&bat_priv->gw_bandwidth) == gw_bandwidth_tmp) 164 if ((down_curr == down_new) && (up_curr == up_new))
164 return count; 165 return count;
165 166
166 batadv_gw_deselect(bat_priv); 167 batadv_gw_deselect(bat_priv);
167 batadv_info(net_dev, 168 batadv_info(net_dev,
168 "Changing gateway bandwidth from: '%i' to: '%ld' (propagating: %d%s/%d%s)\n", 169 "Changing gateway bandwidth from: '%u.%u/%u.%u MBit' to: '%u.%u/%u.%u MBit'\n",
169 atomic_read(&bat_priv->gw_bandwidth), gw_bandwidth_tmp, 170 down_curr / 10, down_curr % 10, up_curr / 10, up_curr % 10,
170 (down > 2048 ? down / 1024 : down), 171 down_new / 10, down_new % 10, up_new / 10, up_new % 10);
171 (down > 2048 ? "MBit" : "KBit"),
172 (up > 2048 ? up / 1024 : up),
173 (up > 2048 ? "MBit" : "KBit"));
174 172
175 atomic_set(&bat_priv->gw_bandwidth, gw_bandwidth_tmp); 173 atomic_set(&bat_priv->gw.bandwidth_down, down_new);
174 atomic_set(&bat_priv->gw.bandwidth_up, up_new);
175 batadv_gw_tvlv_container_update(bat_priv);
176 176
177end: 177end:
178 return count; 178 return count;
179} 179}
180
181/**
182 * batadv_gw_tvlv_ogm_handler_v1 - process incoming gateway tvlv container
183 * @bat_priv: the bat priv with all the soft interface information
184 * @orig: the orig_node of the ogm
185 * @flags: flags indicating the tvlv state (see batadv_tvlv_handler_flags)
186 * @tvlv_value: tvlv buffer containing the gateway data
187 * @tvlv_value_len: tvlv buffer length
188 */
189static void batadv_gw_tvlv_ogm_handler_v1(struct batadv_priv *bat_priv,
190 struct batadv_orig_node *orig,
191 uint8_t flags,
192 void *tvlv_value,
193 uint16_t tvlv_value_len)
194{
195 struct batadv_tvlv_gateway_data gateway, *gateway_ptr;
196
197 /* only fetch the tvlv value if the handler wasn't called via the
198 * CIFNOTFND flag and if there is data to fetch
199 */
200 if ((flags & BATADV_TVLV_HANDLER_OGM_CIFNOTFND) ||
201 (tvlv_value_len < sizeof(gateway))) {
202 gateway.bandwidth_down = 0;
203 gateway.bandwidth_up = 0;
204 } else {
205 gateway_ptr = tvlv_value;
206 gateway.bandwidth_down = gateway_ptr->bandwidth_down;
207 gateway.bandwidth_up = gateway_ptr->bandwidth_up;
208 if ((gateway.bandwidth_down == 0) ||
209 (gateway.bandwidth_up == 0)) {
210 gateway.bandwidth_down = 0;
211 gateway.bandwidth_up = 0;
212 }
213 }
214
215 batadv_gw_node_update(bat_priv, orig, &gateway);
216
217 /* restart gateway selection if fast or late switching was enabled */
218 if ((gateway.bandwidth_down != 0) &&
219 (atomic_read(&bat_priv->gw_mode) == BATADV_GW_MODE_CLIENT) &&
220 (atomic_read(&bat_priv->gw_sel_class) > 2))
221 batadv_gw_check_election(bat_priv, orig);
222}
223
224/**
225 * batadv_gw_init - initialise the gateway handling internals
226 * @bat_priv: the bat priv with all the soft interface information
227 */
228void batadv_gw_init(struct batadv_priv *bat_priv)
229{
230 batadv_tvlv_handler_register(bat_priv, batadv_gw_tvlv_ogm_handler_v1,
231 NULL, BATADV_TVLV_GW, 1,
232 BATADV_TVLV_HANDLER_OGM_CIFNOTFND);
233}
234
235/**
236 * batadv_gw_free - free the gateway handling internals
237 * @bat_priv: the bat priv with all the soft interface information
238 */
239void batadv_gw_free(struct batadv_priv *bat_priv)
240{
241 batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_GW, 1);
242 batadv_tvlv_handler_unregister(bat_priv, BATADV_TVLV_GW, 1);
243}
diff --git a/net/batman-adv/gateway_common.h b/net/batman-adv/gateway_common.h
index 509b2bf8c2f4..56384a4cd18c 100644
--- a/net/batman-adv/gateway_common.h
+++ b/net/batman-adv/gateway_common.h
@@ -26,12 +26,24 @@ enum batadv_gw_modes {
26 BATADV_GW_MODE_SERVER, 26 BATADV_GW_MODE_SERVER,
27}; 27};
28 28
29/**
30 * enum batadv_bandwidth_units - bandwidth unit types
31 * @BATADV_BW_UNIT_KBIT: unit type kbit
32 * @BATADV_BW_UNIT_MBIT: unit type mbit
33 */
34enum batadv_bandwidth_units {
35 BATADV_BW_UNIT_KBIT,
36 BATADV_BW_UNIT_MBIT,
37};
38
29#define BATADV_GW_MODE_OFF_NAME "off" 39#define BATADV_GW_MODE_OFF_NAME "off"
30#define BATADV_GW_MODE_CLIENT_NAME "client" 40#define BATADV_GW_MODE_CLIENT_NAME "client"
31#define BATADV_GW_MODE_SERVER_NAME "server" 41#define BATADV_GW_MODE_SERVER_NAME "server"
32 42
33void batadv_gw_bandwidth_to_kbit(uint8_t gw_class, int *down, int *up);
34ssize_t batadv_gw_bandwidth_set(struct net_device *net_dev, char *buff, 43ssize_t batadv_gw_bandwidth_set(struct net_device *net_dev, char *buff,
35 size_t count); 44 size_t count);
45void batadv_gw_tvlv_container_update(struct batadv_priv *bat_priv);
46void batadv_gw_init(struct batadv_priv *bat_priv);
47void batadv_gw_free(struct batadv_priv *bat_priv);
36 48
37#endif /* _NET_BATMAN_ADV_GATEWAY_COMMON_H_ */ 49#endif /* _NET_BATMAN_ADV_GATEWAY_COMMON_H_ */
diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c
index c478e6bcf89b..c5f871f218c6 100644
--- a/net/batman-adv/hard-interface.c
+++ b/net/batman-adv/hard-interface.c
@@ -194,22 +194,13 @@ out:
194static void batadv_primary_if_update_addr(struct batadv_priv *bat_priv, 194static void batadv_primary_if_update_addr(struct batadv_priv *bat_priv,
195 struct batadv_hard_iface *oldif) 195 struct batadv_hard_iface *oldif)
196{ 196{
197 struct batadv_vis_packet *vis_packet;
198 struct batadv_hard_iface *primary_if; 197 struct batadv_hard_iface *primary_if;
199 struct sk_buff *skb;
200 198
201 primary_if = batadv_primary_if_get_selected(bat_priv); 199 primary_if = batadv_primary_if_get_selected(bat_priv);
202 if (!primary_if) 200 if (!primary_if)
203 goto out; 201 goto out;
204 202
205 batadv_dat_init_own_addr(bat_priv, primary_if); 203 batadv_dat_init_own_addr(bat_priv, primary_if);
206
207 skb = bat_priv->vis.my_info->skb_packet;
208 vis_packet = (struct batadv_vis_packet *)skb->data;
209 memcpy(vis_packet->vis_orig, primary_if->net_dev->dev_addr, ETH_ALEN);
210 memcpy(vis_packet->sender_orig,
211 primary_if->net_dev->dev_addr, ETH_ALEN);
212
213 batadv_bla_update_orig_address(bat_priv, primary_if, oldif); 204 batadv_bla_update_orig_address(bat_priv, primary_if, oldif);
214out: 205out:
215 if (primary_if) 206 if (primary_if)
@@ -278,9 +269,10 @@ int batadv_hardif_min_mtu(struct net_device *soft_iface)
278 const struct batadv_priv *bat_priv = netdev_priv(soft_iface); 269 const struct batadv_priv *bat_priv = netdev_priv(soft_iface);
279 const struct batadv_hard_iface *hard_iface; 270 const struct batadv_hard_iface *hard_iface;
280 /* allow big frames if all devices are capable to do so 271 /* allow big frames if all devices are capable to do so
281 * (have MTU > 1500 + BAT_HEADER_LEN) 272 * (have MTU > 1500 + batadv_max_header_len())
282 */ 273 */
283 int min_mtu = ETH_DATA_LEN; 274 int min_mtu = ETH_DATA_LEN;
275 int max_header_len = batadv_max_header_len();
284 276
285 if (atomic_read(&bat_priv->fragmentation)) 277 if (atomic_read(&bat_priv->fragmentation))
286 goto out; 278 goto out;
@@ -294,8 +286,7 @@ int batadv_hardif_min_mtu(struct net_device *soft_iface)
294 if (hard_iface->soft_iface != soft_iface) 286 if (hard_iface->soft_iface != soft_iface)
295 continue; 287 continue;
296 288
297 min_mtu = min_t(int, 289 min_mtu = min_t(int, hard_iface->net_dev->mtu - max_header_len,
298 hard_iface->net_dev->mtu - BATADV_HEADER_LEN,
299 min_mtu); 290 min_mtu);
300 } 291 }
301 rcu_read_unlock(); 292 rcu_read_unlock();
@@ -388,7 +379,8 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface,
388{ 379{
389 struct batadv_priv *bat_priv; 380 struct batadv_priv *bat_priv;
390 struct net_device *soft_iface, *master; 381 struct net_device *soft_iface, *master;
391 __be16 ethertype = __constant_htons(ETH_P_BATMAN); 382 __be16 ethertype = htons(ETH_P_BATMAN);
383 int max_header_len = batadv_max_header_len();
392 int ret; 384 int ret;
393 385
394 if (hard_iface->if_status != BATADV_IF_NOT_IN_USE) 386 if (hard_iface->if_status != BATADV_IF_NOT_IN_USE)
@@ -453,23 +445,22 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface,
453 hard_iface->batman_adv_ptype.dev = hard_iface->net_dev; 445 hard_iface->batman_adv_ptype.dev = hard_iface->net_dev;
454 dev_add_pack(&hard_iface->batman_adv_ptype); 446 dev_add_pack(&hard_iface->batman_adv_ptype);
455 447
456 atomic_set(&hard_iface->frag_seqno, 1);
457 batadv_info(hard_iface->soft_iface, "Adding interface: %s\n", 448 batadv_info(hard_iface->soft_iface, "Adding interface: %s\n",
458 hard_iface->net_dev->name); 449 hard_iface->net_dev->name);
459 450
460 if (atomic_read(&bat_priv->fragmentation) && 451 if (atomic_read(&bat_priv->fragmentation) &&
461 hard_iface->net_dev->mtu < ETH_DATA_LEN + BATADV_HEADER_LEN) 452 hard_iface->net_dev->mtu < ETH_DATA_LEN + max_header_len)
462 batadv_info(hard_iface->soft_iface, 453 batadv_info(hard_iface->soft_iface,
463 "The MTU of interface %s is too small (%i) to handle the transport of batman-adv packets. Packets going over this interface will be fragmented on layer2 which could impact the performance. Setting the MTU to %zi would solve the problem.\n", 454 "The MTU of interface %s is too small (%i) to handle the transport of batman-adv packets. Packets going over this interface will be fragmented on layer2 which could impact the performance. Setting the MTU to %i would solve the problem.\n",
464 hard_iface->net_dev->name, hard_iface->net_dev->mtu, 455 hard_iface->net_dev->name, hard_iface->net_dev->mtu,
465 ETH_DATA_LEN + BATADV_HEADER_LEN); 456 ETH_DATA_LEN + max_header_len);
466 457
467 if (!atomic_read(&bat_priv->fragmentation) && 458 if (!atomic_read(&bat_priv->fragmentation) &&
468 hard_iface->net_dev->mtu < ETH_DATA_LEN + BATADV_HEADER_LEN) 459 hard_iface->net_dev->mtu < ETH_DATA_LEN + max_header_len)
469 batadv_info(hard_iface->soft_iface, 460 batadv_info(hard_iface->soft_iface,
470 "The MTU of interface %s is too small (%i) to handle the transport of batman-adv packets. If you experience problems getting traffic through try increasing the MTU to %zi.\n", 461 "The MTU of interface %s is too small (%i) to handle the transport of batman-adv packets. If you experience problems getting traffic through try increasing the MTU to %i.\n",
471 hard_iface->net_dev->name, hard_iface->net_dev->mtu, 462 hard_iface->net_dev->name, hard_iface->net_dev->mtu,
472 ETH_DATA_LEN + BATADV_HEADER_LEN); 463 ETH_DATA_LEN + max_header_len);
473 464
474 if (batadv_hardif_is_iface_up(hard_iface)) 465 if (batadv_hardif_is_iface_up(hard_iface))
475 batadv_hardif_activate_interface(hard_iface); 466 batadv_hardif_activate_interface(hard_iface);
@@ -652,6 +643,8 @@ static int batadv_hard_if_event(struct notifier_block *this,
652 643
653 if (batadv_softif_is_valid(net_dev) && event == NETDEV_REGISTER) { 644 if (batadv_softif_is_valid(net_dev) && event == NETDEV_REGISTER) {
654 batadv_sysfs_add_meshif(net_dev); 645 batadv_sysfs_add_meshif(net_dev);
646 bat_priv = netdev_priv(net_dev);
647 batadv_softif_create_vlan(bat_priv, BATADV_NO_FLAGS);
655 return NOTIFY_DONE; 648 return NOTIFY_DONE;
656 } 649 }
657 650
diff --git a/net/batman-adv/icmp_socket.c b/net/batman-adv/icmp_socket.c
index 5a99bb4b6b82..82ac6472fa6f 100644
--- a/net/batman-adv/icmp_socket.c
+++ b/net/batman-adv/icmp_socket.c
@@ -192,25 +192,25 @@ static ssize_t batadv_socket_write(struct file *file, const char __user *buff,
192 goto free_skb; 192 goto free_skb;
193 } 193 }
194 194
195 if (icmp_packet->header.packet_type != BATADV_ICMP) { 195 if (icmp_packet->icmph.header.packet_type != BATADV_ICMP) {
196 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, 196 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
197 "Error - can't send packet from char device: got bogus packet type (expected: BAT_ICMP)\n"); 197 "Error - can't send packet from char device: got bogus packet type (expected: BAT_ICMP)\n");
198 len = -EINVAL; 198 len = -EINVAL;
199 goto free_skb; 199 goto free_skb;
200 } 200 }
201 201
202 if (icmp_packet->msg_type != BATADV_ECHO_REQUEST) { 202 if (icmp_packet->icmph.msg_type != BATADV_ECHO_REQUEST) {
203 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, 203 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
204 "Error - can't send packet from char device: got bogus message type (expected: ECHO_REQUEST)\n"); 204 "Error - can't send packet from char device: got bogus message type (expected: ECHO_REQUEST)\n");
205 len = -EINVAL; 205 len = -EINVAL;
206 goto free_skb; 206 goto free_skb;
207 } 207 }
208 208
209 icmp_packet->uid = socket_client->index; 209 icmp_packet->icmph.uid = socket_client->index;
210 210
211 if (icmp_packet->header.version != BATADV_COMPAT_VERSION) { 211 if (icmp_packet->icmph.header.version != BATADV_COMPAT_VERSION) {
212 icmp_packet->msg_type = BATADV_PARAMETER_PROBLEM; 212 icmp_packet->icmph.msg_type = BATADV_PARAMETER_PROBLEM;
213 icmp_packet->header.version = BATADV_COMPAT_VERSION; 213 icmp_packet->icmph.header.version = BATADV_COMPAT_VERSION;
214 batadv_socket_add_packet(socket_client, icmp_packet, 214 batadv_socket_add_packet(socket_client, icmp_packet,
215 packet_len); 215 packet_len);
216 goto free_skb; 216 goto free_skb;
@@ -219,7 +219,7 @@ static ssize_t batadv_socket_write(struct file *file, const char __user *buff,
219 if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE) 219 if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE)
220 goto dst_unreach; 220 goto dst_unreach;
221 221
222 orig_node = batadv_orig_hash_find(bat_priv, icmp_packet->dst); 222 orig_node = batadv_orig_hash_find(bat_priv, icmp_packet->icmph.dst);
223 if (!orig_node) 223 if (!orig_node)
224 goto dst_unreach; 224 goto dst_unreach;
225 225
@@ -233,7 +233,7 @@ static ssize_t batadv_socket_write(struct file *file, const char __user *buff,
233 if (neigh_node->if_incoming->if_status != BATADV_IF_ACTIVE) 233 if (neigh_node->if_incoming->if_status != BATADV_IF_ACTIVE)
234 goto dst_unreach; 234 goto dst_unreach;
235 235
236 memcpy(icmp_packet->orig, 236 memcpy(icmp_packet->icmph.orig,
237 primary_if->net_dev->dev_addr, ETH_ALEN); 237 primary_if->net_dev->dev_addr, ETH_ALEN);
238 238
239 if (packet_len == sizeof(struct batadv_icmp_packet_rr)) 239 if (packet_len == sizeof(struct batadv_icmp_packet_rr))
@@ -244,7 +244,7 @@ static ssize_t batadv_socket_write(struct file *file, const char __user *buff,
244 goto out; 244 goto out;
245 245
246dst_unreach: 246dst_unreach:
247 icmp_packet->msg_type = BATADV_DESTINATION_UNREACHABLE; 247 icmp_packet->icmph.msg_type = BATADV_DESTINATION_UNREACHABLE;
248 batadv_socket_add_packet(socket_client, icmp_packet, packet_len); 248 batadv_socket_add_packet(socket_client, icmp_packet, packet_len);
249free_skb: 249free_skb:
250 kfree_skb(skb); 250 kfree_skb(skb);
@@ -318,7 +318,7 @@ static void batadv_socket_add_packet(struct batadv_socket_client *socket_client,
318 /* while waiting for the lock the socket_client could have been 318 /* while waiting for the lock the socket_client could have been
319 * deleted 319 * deleted
320 */ 320 */
321 if (!batadv_socket_client_hash[icmp_packet->uid]) { 321 if (!batadv_socket_client_hash[icmp_packet->icmph.uid]) {
322 spin_unlock_bh(&socket_client->lock); 322 spin_unlock_bh(&socket_client->lock);
323 kfree(socket_packet); 323 kfree(socket_packet);
324 return; 324 return;
@@ -347,7 +347,7 @@ void batadv_socket_receive_packet(struct batadv_icmp_packet_rr *icmp_packet,
347{ 347{
348 struct batadv_socket_client *hash; 348 struct batadv_socket_client *hash;
349 349
350 hash = batadv_socket_client_hash[icmp_packet->uid]; 350 hash = batadv_socket_client_hash[icmp_packet->icmph.uid];
351 if (hash) 351 if (hash)
352 batadv_socket_add_packet(hash, icmp_packet, icmp_len); 352 batadv_socket_add_packet(hash, icmp_packet, icmp_len);
353} 353}
diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c
index 1356af660b5b..3159a148c1ac 100644
--- a/net/batman-adv/main.c
+++ b/net/batman-adv/main.c
@@ -36,10 +36,11 @@
36#include "gateway_client.h" 36#include "gateway_client.h"
37#include "bridge_loop_avoidance.h" 37#include "bridge_loop_avoidance.h"
38#include "distributed-arp-table.h" 38#include "distributed-arp-table.h"
39#include "vis.h" 39#include "gateway_common.h"
40#include "hash.h" 40#include "hash.h"
41#include "bat_algo.h" 41#include "bat_algo.h"
42#include "network-coding.h" 42#include "network-coding.h"
43#include "fragmentation.h"
43 44
44 45
45/* List manipulations on hardif_list have to be rtnl_lock()'ed, 46/* List manipulations on hardif_list have to be rtnl_lock()'ed,
@@ -109,9 +110,11 @@ int batadv_mesh_init(struct net_device *soft_iface)
109 spin_lock_init(&bat_priv->tt.req_list_lock); 110 spin_lock_init(&bat_priv->tt.req_list_lock);
110 spin_lock_init(&bat_priv->tt.roam_list_lock); 111 spin_lock_init(&bat_priv->tt.roam_list_lock);
111 spin_lock_init(&bat_priv->tt.last_changeset_lock); 112 spin_lock_init(&bat_priv->tt.last_changeset_lock);
113 spin_lock_init(&bat_priv->tt.commit_lock);
112 spin_lock_init(&bat_priv->gw.list_lock); 114 spin_lock_init(&bat_priv->gw.list_lock);
113 spin_lock_init(&bat_priv->vis.hash_lock); 115 spin_lock_init(&bat_priv->tvlv.container_list_lock);
114 spin_lock_init(&bat_priv->vis.list_lock); 116 spin_lock_init(&bat_priv->tvlv.handler_list_lock);
117 spin_lock_init(&bat_priv->softif_vlan_list_lock);
115 118
116 INIT_HLIST_HEAD(&bat_priv->forw_bat_list); 119 INIT_HLIST_HEAD(&bat_priv->forw_bat_list);
117 INIT_HLIST_HEAD(&bat_priv->forw_bcast_list); 120 INIT_HLIST_HEAD(&bat_priv->forw_bcast_list);
@@ -119,6 +122,9 @@ int batadv_mesh_init(struct net_device *soft_iface)
119 INIT_LIST_HEAD(&bat_priv->tt.changes_list); 122 INIT_LIST_HEAD(&bat_priv->tt.changes_list);
120 INIT_LIST_HEAD(&bat_priv->tt.req_list); 123 INIT_LIST_HEAD(&bat_priv->tt.req_list);
121 INIT_LIST_HEAD(&bat_priv->tt.roam_list); 124 INIT_LIST_HEAD(&bat_priv->tt.roam_list);
125 INIT_HLIST_HEAD(&bat_priv->tvlv.container_list);
126 INIT_HLIST_HEAD(&bat_priv->tvlv.handler_list);
127 INIT_HLIST_HEAD(&bat_priv->softif_vlan_list);
122 128
123 ret = batadv_originator_init(bat_priv); 129 ret = batadv_originator_init(bat_priv);
124 if (ret < 0) 130 if (ret < 0)
@@ -128,13 +134,6 @@ int batadv_mesh_init(struct net_device *soft_iface)
128 if (ret < 0) 134 if (ret < 0)
129 goto err; 135 goto err;
130 136
131 batadv_tt_local_add(soft_iface, soft_iface->dev_addr,
132 BATADV_NULL_IFINDEX);
133
134 ret = batadv_vis_init(bat_priv);
135 if (ret < 0)
136 goto err;
137
138 ret = batadv_bla_init(bat_priv); 137 ret = batadv_bla_init(bat_priv);
139 if (ret < 0) 138 if (ret < 0)
140 goto err; 139 goto err;
@@ -147,6 +146,8 @@ int batadv_mesh_init(struct net_device *soft_iface)
147 if (ret < 0) 146 if (ret < 0)
148 goto err; 147 goto err;
149 148
149 batadv_gw_init(bat_priv);
150
150 atomic_set(&bat_priv->gw.reselect, 0); 151 atomic_set(&bat_priv->gw.reselect, 0);
151 atomic_set(&bat_priv->mesh_state, BATADV_MESH_ACTIVE); 152 atomic_set(&bat_priv->mesh_state, BATADV_MESH_ACTIVE);
152 153
@@ -165,8 +166,6 @@ void batadv_mesh_free(struct net_device *soft_iface)
165 166
166 batadv_purge_outstanding_packets(bat_priv, NULL); 167 batadv_purge_outstanding_packets(bat_priv, NULL);
167 168
168 batadv_vis_quit(bat_priv);
169
170 batadv_gw_node_purge(bat_priv); 169 batadv_gw_node_purge(bat_priv);
171 batadv_nc_mesh_free(bat_priv); 170 batadv_nc_mesh_free(bat_priv);
172 batadv_dat_free(bat_priv); 171 batadv_dat_free(bat_priv);
@@ -185,6 +184,8 @@ void batadv_mesh_free(struct net_device *soft_iface)
185 */ 184 */
186 batadv_originator_free(bat_priv); 185 batadv_originator_free(bat_priv);
187 186
187 batadv_gw_free(bat_priv);
188
188 free_percpu(bat_priv->bat_counters); 189 free_percpu(bat_priv->bat_counters);
189 bat_priv->bat_counters = NULL; 190 bat_priv->bat_counters = NULL;
190 191
@@ -255,6 +256,31 @@ out:
255} 256}
256 257
257/** 258/**
259 * batadv_max_header_len - calculate maximum encapsulation overhead for a
260 * payload packet
261 *
262 * Return the maximum encapsulation overhead in bytes.
263 */
264int batadv_max_header_len(void)
265{
266 int header_len = 0;
267
268 header_len = max_t(int, header_len,
269 sizeof(struct batadv_unicast_packet));
270 header_len = max_t(int, header_len,
271 sizeof(struct batadv_unicast_4addr_packet));
272 header_len = max_t(int, header_len,
273 sizeof(struct batadv_bcast_packet));
274
275#ifdef CONFIG_BATMAN_ADV_NC
276 header_len = max_t(int, header_len,
277 sizeof(struct batadv_coded_packet));
278#endif
279
280 return header_len;
281}
282
283/**
258 * batadv_skb_set_priority - sets skb priority according to packet content 284 * batadv_skb_set_priority - sets skb priority according to packet content
259 * @skb: the packet to be sent 285 * @skb: the packet to be sent
260 * @offset: offset to the packet content 286 * @offset: offset to the packet content
@@ -392,22 +418,31 @@ static void batadv_recv_handler_init(void)
392 for (i = 0; i < ARRAY_SIZE(batadv_rx_handler); i++) 418 for (i = 0; i < ARRAY_SIZE(batadv_rx_handler); i++)
393 batadv_rx_handler[i] = batadv_recv_unhandled_packet; 419 batadv_rx_handler[i] = batadv_recv_unhandled_packet;
394 420
395 /* batman icmp packet */ 421 for (i = BATADV_UNICAST_MIN; i <= BATADV_UNICAST_MAX; i++)
396 batadv_rx_handler[BATADV_ICMP] = batadv_recv_icmp_packet; 422 batadv_rx_handler[i] = batadv_recv_unhandled_unicast_packet;
423
424 /* compile time checks for struct member offsets */
425 BUILD_BUG_ON(offsetof(struct batadv_unicast_4addr_packet, src) != 10);
426 BUILD_BUG_ON(offsetof(struct batadv_unicast_packet, dest) != 4);
427 BUILD_BUG_ON(offsetof(struct batadv_unicast_tvlv_packet, dst) != 4);
428 BUILD_BUG_ON(offsetof(struct batadv_frag_packet, dest) != 4);
429 BUILD_BUG_ON(offsetof(struct batadv_icmp_packet, icmph.dst) != 4);
430 BUILD_BUG_ON(offsetof(struct batadv_icmp_packet_rr, icmph.dst) != 4);
431
432 /* broadcast packet */
433 batadv_rx_handler[BATADV_BCAST] = batadv_recv_bcast_packet;
434
435 /* unicast packets ... */
397 /* unicast with 4 addresses packet */ 436 /* unicast with 4 addresses packet */
398 batadv_rx_handler[BATADV_UNICAST_4ADDR] = batadv_recv_unicast_packet; 437 batadv_rx_handler[BATADV_UNICAST_4ADDR] = batadv_recv_unicast_packet;
399 /* unicast packet */ 438 /* unicast packet */
400 batadv_rx_handler[BATADV_UNICAST] = batadv_recv_unicast_packet; 439 batadv_rx_handler[BATADV_UNICAST] = batadv_recv_unicast_packet;
401 /* fragmented unicast packet */ 440 /* unicast tvlv packet */
402 batadv_rx_handler[BATADV_UNICAST_FRAG] = batadv_recv_ucast_frag_packet; 441 batadv_rx_handler[BATADV_UNICAST_TVLV] = batadv_recv_unicast_tvlv;
403 /* broadcast packet */ 442 /* batman icmp packet */
404 batadv_rx_handler[BATADV_BCAST] = batadv_recv_bcast_packet; 443 batadv_rx_handler[BATADV_ICMP] = batadv_recv_icmp_packet;
405 /* vis packet */ 444 /* Fragmented packets */
406 batadv_rx_handler[BATADV_VIS] = batadv_recv_vis_packet; 445 batadv_rx_handler[BATADV_UNICAST_FRAG] = batadv_recv_frag_packet;
407 /* Translation table query (request or response) */
408 batadv_rx_handler[BATADV_TT_QUERY] = batadv_recv_tt_query;
409 /* Roaming advertisement */
410 batadv_rx_handler[BATADV_ROAM_ADV] = batadv_recv_roam_adv;
411} 446}
412 447
413int 448int
@@ -415,7 +450,12 @@ batadv_recv_handler_register(uint8_t packet_type,
415 int (*recv_handler)(struct sk_buff *, 450 int (*recv_handler)(struct sk_buff *,
416 struct batadv_hard_iface *)) 451 struct batadv_hard_iface *))
417{ 452{
418 if (batadv_rx_handler[packet_type] != &batadv_recv_unhandled_packet) 453 int (*curr)(struct sk_buff *,
454 struct batadv_hard_iface *);
455 curr = batadv_rx_handler[packet_type];
456
457 if ((curr != batadv_recv_unhandled_packet) &&
458 (curr != batadv_recv_unhandled_unicast_packet))
419 return -EBUSY; 459 return -EBUSY;
420 460
421 batadv_rx_handler[packet_type] = recv_handler; 461 batadv_rx_handler[packet_type] = recv_handler;
@@ -536,6 +576,601 @@ __be32 batadv_skb_crc32(struct sk_buff *skb, u8 *payload_ptr)
536 return htonl(crc); 576 return htonl(crc);
537} 577}
538 578
579/**
580 * batadv_tvlv_handler_free_ref - decrement the tvlv handler refcounter and
581 * possibly free it
582 * @tvlv_handler: the tvlv handler to free
583 */
584static void
585batadv_tvlv_handler_free_ref(struct batadv_tvlv_handler *tvlv_handler)
586{
587 if (atomic_dec_and_test(&tvlv_handler->refcount))
588 kfree_rcu(tvlv_handler, rcu);
589}
590
591/**
592 * batadv_tvlv_handler_get - retrieve tvlv handler from the tvlv handler list
593 * based on the provided type and version (both need to match)
594 * @bat_priv: the bat priv with all the soft interface information
595 * @type: tvlv handler type to look for
596 * @version: tvlv handler version to look for
597 *
598 * Returns tvlv handler if found or NULL otherwise.
599 */
600static struct batadv_tvlv_handler
601*batadv_tvlv_handler_get(struct batadv_priv *bat_priv,
602 uint8_t type, uint8_t version)
603{
604 struct batadv_tvlv_handler *tvlv_handler_tmp, *tvlv_handler = NULL;
605
606 rcu_read_lock();
607 hlist_for_each_entry_rcu(tvlv_handler_tmp,
608 &bat_priv->tvlv.handler_list, list) {
609 if (tvlv_handler_tmp->type != type)
610 continue;
611
612 if (tvlv_handler_tmp->version != version)
613 continue;
614
615 if (!atomic_inc_not_zero(&tvlv_handler_tmp->refcount))
616 continue;
617
618 tvlv_handler = tvlv_handler_tmp;
619 break;
620 }
621 rcu_read_unlock();
622
623 return tvlv_handler;
624}
625
626/**
627 * batadv_tvlv_container_free_ref - decrement the tvlv container refcounter and
628 * possibly free it
629 * @tvlv_handler: the tvlv container to free
630 */
631static void batadv_tvlv_container_free_ref(struct batadv_tvlv_container *tvlv)
632{
633 if (atomic_dec_and_test(&tvlv->refcount))
634 kfree(tvlv);
635}
636
637/**
638 * batadv_tvlv_container_get - retrieve tvlv container from the tvlv container
639 * list based on the provided type and version (both need to match)
640 * @bat_priv: the bat priv with all the soft interface information
641 * @type: tvlv container type to look for
642 * @version: tvlv container version to look for
643 *
644 * Has to be called with the appropriate locks being acquired
645 * (tvlv.container_list_lock).
646 *
647 * Returns tvlv container if found or NULL otherwise.
648 */
649static struct batadv_tvlv_container
650*batadv_tvlv_container_get(struct batadv_priv *bat_priv,
651 uint8_t type, uint8_t version)
652{
653 struct batadv_tvlv_container *tvlv_tmp, *tvlv = NULL;
654
655 hlist_for_each_entry(tvlv_tmp, &bat_priv->tvlv.container_list, list) {
656 if (tvlv_tmp->tvlv_hdr.type != type)
657 continue;
658
659 if (tvlv_tmp->tvlv_hdr.version != version)
660 continue;
661
662 if (!atomic_inc_not_zero(&tvlv_tmp->refcount))
663 continue;
664
665 tvlv = tvlv_tmp;
666 break;
667 }
668
669 return tvlv;
670}
671
672/**
673 * batadv_tvlv_container_list_size - calculate the size of the tvlv container
674 * list entries
675 * @bat_priv: the bat priv with all the soft interface information
676 *
677 * Has to be called with the appropriate locks being acquired
678 * (tvlv.container_list_lock).
679 *
680 * Returns size of all currently registered tvlv containers in bytes.
681 */
682static uint16_t batadv_tvlv_container_list_size(struct batadv_priv *bat_priv)
683{
684 struct batadv_tvlv_container *tvlv;
685 uint16_t tvlv_len = 0;
686
687 hlist_for_each_entry(tvlv, &bat_priv->tvlv.container_list, list) {
688 tvlv_len += sizeof(struct batadv_tvlv_hdr);
689 tvlv_len += ntohs(tvlv->tvlv_hdr.len);
690 }
691
692 return tvlv_len;
693}
694
695/**
696 * batadv_tvlv_container_remove - remove tvlv container from the tvlv container
697 * list
698 * @tvlv: the to be removed tvlv container
699 *
700 * Has to be called with the appropriate locks being acquired
701 * (tvlv.container_list_lock).
702 */
703static void batadv_tvlv_container_remove(struct batadv_tvlv_container *tvlv)
704{
705 if (!tvlv)
706 return;
707
708 hlist_del(&tvlv->list);
709
710 /* first call to decrement the counter, second call to free */
711 batadv_tvlv_container_free_ref(tvlv);
712 batadv_tvlv_container_free_ref(tvlv);
713}
714
715/**
716 * batadv_tvlv_container_unregister - unregister tvlv container based on the
717 * provided type and version (both need to match)
718 * @bat_priv: the bat priv with all the soft interface information
719 * @type: tvlv container type to unregister
720 * @version: tvlv container type to unregister
721 */
722void batadv_tvlv_container_unregister(struct batadv_priv *bat_priv,
723 uint8_t type, uint8_t version)
724{
725 struct batadv_tvlv_container *tvlv;
726
727 spin_lock_bh(&bat_priv->tvlv.container_list_lock);
728 tvlv = batadv_tvlv_container_get(bat_priv, type, version);
729 batadv_tvlv_container_remove(tvlv);
730 spin_unlock_bh(&bat_priv->tvlv.container_list_lock);
731}
732
733/**
734 * batadv_tvlv_container_register - register tvlv type, version and content
735 * to be propagated with each (primary interface) OGM
736 * @bat_priv: the bat priv with all the soft interface information
737 * @type: tvlv container type
738 * @version: tvlv container version
739 * @tvlv_value: tvlv container content
740 * @tvlv_value_len: tvlv container content length
741 *
742 * If a container of the same type and version was already registered the new
743 * content is going to replace the old one.
744 */
745void batadv_tvlv_container_register(struct batadv_priv *bat_priv,
746 uint8_t type, uint8_t version,
747 void *tvlv_value, uint16_t tvlv_value_len)
748{
749 struct batadv_tvlv_container *tvlv_old, *tvlv_new;
750
751 if (!tvlv_value)
752 tvlv_value_len = 0;
753
754 tvlv_new = kzalloc(sizeof(*tvlv_new) + tvlv_value_len, GFP_ATOMIC);
755 if (!tvlv_new)
756 return;
757
758 tvlv_new->tvlv_hdr.version = version;
759 tvlv_new->tvlv_hdr.type = type;
760 tvlv_new->tvlv_hdr.len = htons(tvlv_value_len);
761
762 memcpy(tvlv_new + 1, tvlv_value, ntohs(tvlv_new->tvlv_hdr.len));
763 INIT_HLIST_NODE(&tvlv_new->list);
764 atomic_set(&tvlv_new->refcount, 1);
765
766 spin_lock_bh(&bat_priv->tvlv.container_list_lock);
767 tvlv_old = batadv_tvlv_container_get(bat_priv, type, version);
768 batadv_tvlv_container_remove(tvlv_old);
769 hlist_add_head(&tvlv_new->list, &bat_priv->tvlv.container_list);
770 spin_unlock_bh(&bat_priv->tvlv.container_list_lock);
771}
772
773/**
774 * batadv_tvlv_realloc_packet_buff - reallocate packet buffer to accomodate
775 * requested packet size
776 * @packet_buff: packet buffer
777 * @packet_buff_len: packet buffer size
778 * @packet_min_len: requested packet minimum size
779 * @additional_packet_len: requested additional packet size on top of minimum
780 * size
781 *
782 * Returns true of the packet buffer could be changed to the requested size,
783 * false otherwise.
784 */
785static bool batadv_tvlv_realloc_packet_buff(unsigned char **packet_buff,
786 int *packet_buff_len,
787 int min_packet_len,
788 int additional_packet_len)
789{
790 unsigned char *new_buff;
791
792 new_buff = kmalloc(min_packet_len + additional_packet_len, GFP_ATOMIC);
793
794 /* keep old buffer if kmalloc should fail */
795 if (new_buff) {
796 memcpy(new_buff, *packet_buff, min_packet_len);
797 kfree(*packet_buff);
798 *packet_buff = new_buff;
799 *packet_buff_len = min_packet_len + additional_packet_len;
800 return true;
801 }
802
803 return false;
804}
805
806/**
807 * batadv_tvlv_container_ogm_append - append tvlv container content to given
808 * OGM packet buffer
809 * @bat_priv: the bat priv with all the soft interface information
810 * @packet_buff: ogm packet buffer
811 * @packet_buff_len: ogm packet buffer size including ogm header and tvlv
812 * content
813 * @packet_min_len: ogm header size to be preserved for the OGM itself
814 *
815 * The ogm packet might be enlarged or shrunk depending on the current size
816 * and the size of the to-be-appended tvlv containers.
817 *
818 * Returns size of all appended tvlv containers in bytes.
819 */
820uint16_t batadv_tvlv_container_ogm_append(struct batadv_priv *bat_priv,
821 unsigned char **packet_buff,
822 int *packet_buff_len,
823 int packet_min_len)
824{
825 struct batadv_tvlv_container *tvlv;
826 struct batadv_tvlv_hdr *tvlv_hdr;
827 uint16_t tvlv_value_len;
828 void *tvlv_value;
829 bool ret;
830
831 spin_lock_bh(&bat_priv->tvlv.container_list_lock);
832 tvlv_value_len = batadv_tvlv_container_list_size(bat_priv);
833
834 ret = batadv_tvlv_realloc_packet_buff(packet_buff, packet_buff_len,
835 packet_min_len, tvlv_value_len);
836
837 if (!ret)
838 goto end;
839
840 if (!tvlv_value_len)
841 goto end;
842
843 tvlv_value = (*packet_buff) + packet_min_len;
844
845 hlist_for_each_entry(tvlv, &bat_priv->tvlv.container_list, list) {
846 tvlv_hdr = tvlv_value;
847 tvlv_hdr->type = tvlv->tvlv_hdr.type;
848 tvlv_hdr->version = tvlv->tvlv_hdr.version;
849 tvlv_hdr->len = tvlv->tvlv_hdr.len;
850 tvlv_value = tvlv_hdr + 1;
851 memcpy(tvlv_value, tvlv + 1, ntohs(tvlv->tvlv_hdr.len));
852 tvlv_value = (uint8_t *)tvlv_value + ntohs(tvlv->tvlv_hdr.len);
853 }
854
855end:
856 spin_unlock_bh(&bat_priv->tvlv.container_list_lock);
857 return tvlv_value_len;
858}
859
860/**
861 * batadv_tvlv_call_handler - parse the given tvlv buffer to call the
862 * appropriate handlers
863 * @bat_priv: the bat priv with all the soft interface information
864 * @tvlv_handler: tvlv callback function handling the tvlv content
865 * @ogm_source: flag indicating wether the tvlv is an ogm or a unicast packet
866 * @orig_node: orig node emitting the ogm packet
867 * @src: source mac address of the unicast packet
868 * @dst: destination mac address of the unicast packet
869 * @tvlv_value: tvlv content
870 * @tvlv_value_len: tvlv content length
871 *
872 * Returns success if handler was not found or the return value of the handler
873 * callback.
874 */
875static int batadv_tvlv_call_handler(struct batadv_priv *bat_priv,
876 struct batadv_tvlv_handler *tvlv_handler,
877 bool ogm_source,
878 struct batadv_orig_node *orig_node,
879 uint8_t *src, uint8_t *dst,
880 void *tvlv_value, uint16_t tvlv_value_len)
881{
882 if (!tvlv_handler)
883 return NET_RX_SUCCESS;
884
885 if (ogm_source) {
886 if (!tvlv_handler->ogm_handler)
887 return NET_RX_SUCCESS;
888
889 if (!orig_node)
890 return NET_RX_SUCCESS;
891
892 tvlv_handler->ogm_handler(bat_priv, orig_node,
893 BATADV_NO_FLAGS,
894 tvlv_value, tvlv_value_len);
895 tvlv_handler->flags |= BATADV_TVLV_HANDLER_OGM_CALLED;
896 } else {
897 if (!src)
898 return NET_RX_SUCCESS;
899
900 if (!dst)
901 return NET_RX_SUCCESS;
902
903 if (!tvlv_handler->unicast_handler)
904 return NET_RX_SUCCESS;
905
906 return tvlv_handler->unicast_handler(bat_priv, src,
907 dst, tvlv_value,
908 tvlv_value_len);
909 }
910
911 return NET_RX_SUCCESS;
912}
913
914/**
915 * batadv_tvlv_containers_process - parse the given tvlv buffer to call the
916 * appropriate handlers
917 * @bat_priv: the bat priv with all the soft interface information
918 * @ogm_source: flag indicating wether the tvlv is an ogm or a unicast packet
919 * @orig_node: orig node emitting the ogm packet
920 * @src: source mac address of the unicast packet
921 * @dst: destination mac address of the unicast packet
922 * @tvlv_value: tvlv content
923 * @tvlv_value_len: tvlv content length
924 *
925 * Returns success when processing an OGM or the return value of all called
926 * handler callbacks.
927 */
928int batadv_tvlv_containers_process(struct batadv_priv *bat_priv,
929 bool ogm_source,
930 struct batadv_orig_node *orig_node,
931 uint8_t *src, uint8_t *dst,
932 void *tvlv_value, uint16_t tvlv_value_len)
933{
934 struct batadv_tvlv_handler *tvlv_handler;
935 struct batadv_tvlv_hdr *tvlv_hdr;
936 uint16_t tvlv_value_cont_len;
937 uint8_t cifnotfound = BATADV_TVLV_HANDLER_OGM_CIFNOTFND;
938 int ret = NET_RX_SUCCESS;
939
940 while (tvlv_value_len >= sizeof(*tvlv_hdr)) {
941 tvlv_hdr = tvlv_value;
942 tvlv_value_cont_len = ntohs(tvlv_hdr->len);
943 tvlv_value = tvlv_hdr + 1;
944 tvlv_value_len -= sizeof(*tvlv_hdr);
945
946 if (tvlv_value_cont_len > tvlv_value_len)
947 break;
948
949 tvlv_handler = batadv_tvlv_handler_get(bat_priv,
950 tvlv_hdr->type,
951 tvlv_hdr->version);
952
953 ret |= batadv_tvlv_call_handler(bat_priv, tvlv_handler,
954 ogm_source, orig_node,
955 src, dst, tvlv_value,
956 tvlv_value_cont_len);
957 if (tvlv_handler)
958 batadv_tvlv_handler_free_ref(tvlv_handler);
959 tvlv_value = (uint8_t *)tvlv_value + tvlv_value_cont_len;
960 tvlv_value_len -= tvlv_value_cont_len;
961 }
962
963 if (!ogm_source)
964 return ret;
965
966 rcu_read_lock();
967 hlist_for_each_entry_rcu(tvlv_handler,
968 &bat_priv->tvlv.handler_list, list) {
969 if ((tvlv_handler->flags & BATADV_TVLV_HANDLER_OGM_CIFNOTFND) &&
970 !(tvlv_handler->flags & BATADV_TVLV_HANDLER_OGM_CALLED))
971 tvlv_handler->ogm_handler(bat_priv, orig_node,
972 cifnotfound, NULL, 0);
973
974 tvlv_handler->flags &= ~BATADV_TVLV_HANDLER_OGM_CALLED;
975 }
976 rcu_read_unlock();
977
978 return NET_RX_SUCCESS;
979}
980
981/**
982 * batadv_tvlv_ogm_receive - process an incoming ogm and call the appropriate
983 * handlers
984 * @bat_priv: the bat priv with all the soft interface information
985 * @batadv_ogm_packet: ogm packet containing the tvlv containers
986 * @orig_node: orig node emitting the ogm packet
987 */
988void batadv_tvlv_ogm_receive(struct batadv_priv *bat_priv,
989 struct batadv_ogm_packet *batadv_ogm_packet,
990 struct batadv_orig_node *orig_node)
991{
992 void *tvlv_value;
993 uint16_t tvlv_value_len;
994
995 if (!batadv_ogm_packet)
996 return;
997
998 tvlv_value_len = ntohs(batadv_ogm_packet->tvlv_len);
999 if (!tvlv_value_len)
1000 return;
1001
1002 tvlv_value = batadv_ogm_packet + 1;
1003
1004 batadv_tvlv_containers_process(bat_priv, true, orig_node, NULL, NULL,
1005 tvlv_value, tvlv_value_len);
1006}
1007
1008/**
1009 * batadv_tvlv_handler_register - register tvlv handler based on the provided
1010 * type and version (both need to match) for ogm tvlv payload and/or unicast
1011 * payload
1012 * @bat_priv: the bat priv with all the soft interface information
1013 * @optr: ogm tvlv handler callback function. This function receives the orig
1014 * node, flags and the tvlv content as argument to process.
1015 * @uptr: unicast tvlv handler callback function. This function receives the
1016 * source & destination of the unicast packet as well as the tvlv content
1017 * to process.
1018 * @type: tvlv handler type to be registered
1019 * @version: tvlv handler version to be registered
1020 * @flags: flags to enable or disable TVLV API behavior
1021 */
1022void batadv_tvlv_handler_register(struct batadv_priv *bat_priv,
1023 void (*optr)(struct batadv_priv *bat_priv,
1024 struct batadv_orig_node *orig,
1025 uint8_t flags,
1026 void *tvlv_value,
1027 uint16_t tvlv_value_len),
1028 int (*uptr)(struct batadv_priv *bat_priv,
1029 uint8_t *src, uint8_t *dst,
1030 void *tvlv_value,
1031 uint16_t tvlv_value_len),
1032 uint8_t type, uint8_t version, uint8_t flags)
1033{
1034 struct batadv_tvlv_handler *tvlv_handler;
1035
1036 tvlv_handler = batadv_tvlv_handler_get(bat_priv, type, version);
1037 if (tvlv_handler) {
1038 batadv_tvlv_handler_free_ref(tvlv_handler);
1039 return;
1040 }
1041
1042 tvlv_handler = kzalloc(sizeof(*tvlv_handler), GFP_ATOMIC);
1043 if (!tvlv_handler)
1044 return;
1045
1046 tvlv_handler->ogm_handler = optr;
1047 tvlv_handler->unicast_handler = uptr;
1048 tvlv_handler->type = type;
1049 tvlv_handler->version = version;
1050 tvlv_handler->flags = flags;
1051 atomic_set(&tvlv_handler->refcount, 1);
1052 INIT_HLIST_NODE(&tvlv_handler->list);
1053
1054 spin_lock_bh(&bat_priv->tvlv.handler_list_lock);
1055 hlist_add_head_rcu(&tvlv_handler->list, &bat_priv->tvlv.handler_list);
1056 spin_unlock_bh(&bat_priv->tvlv.handler_list_lock);
1057}
1058
1059/**
1060 * batadv_tvlv_handler_unregister - unregister tvlv handler based on the
1061 * provided type and version (both need to match)
1062 * @bat_priv: the bat priv with all the soft interface information
1063 * @type: tvlv handler type to be unregistered
1064 * @version: tvlv handler version to be unregistered
1065 */
1066void batadv_tvlv_handler_unregister(struct batadv_priv *bat_priv,
1067 uint8_t type, uint8_t version)
1068{
1069 struct batadv_tvlv_handler *tvlv_handler;
1070
1071 tvlv_handler = batadv_tvlv_handler_get(bat_priv, type, version);
1072 if (!tvlv_handler)
1073 return;
1074
1075 batadv_tvlv_handler_free_ref(tvlv_handler);
1076 spin_lock_bh(&bat_priv->tvlv.handler_list_lock);
1077 hlist_del_rcu(&tvlv_handler->list);
1078 spin_unlock_bh(&bat_priv->tvlv.handler_list_lock);
1079 batadv_tvlv_handler_free_ref(tvlv_handler);
1080}
1081
1082/**
1083 * batadv_tvlv_unicast_send - send a unicast packet with tvlv payload to the
1084 * specified host
1085 * @bat_priv: the bat priv with all the soft interface information
1086 * @src: source mac address of the unicast packet
1087 * @dst: destination mac address of the unicast packet
1088 * @type: tvlv type
1089 * @version: tvlv version
1090 * @tvlv_value: tvlv content
1091 * @tvlv_value_len: tvlv content length
1092 */
1093void batadv_tvlv_unicast_send(struct batadv_priv *bat_priv, uint8_t *src,
1094 uint8_t *dst, uint8_t type, uint8_t version,
1095 void *tvlv_value, uint16_t tvlv_value_len)
1096{
1097 struct batadv_unicast_tvlv_packet *unicast_tvlv_packet;
1098 struct batadv_tvlv_hdr *tvlv_hdr;
1099 struct batadv_orig_node *orig_node;
1100 struct sk_buff *skb = NULL;
1101 unsigned char *tvlv_buff;
1102 unsigned int tvlv_len;
1103 ssize_t hdr_len = sizeof(*unicast_tvlv_packet);
1104 bool ret = false;
1105
1106 orig_node = batadv_orig_hash_find(bat_priv, dst);
1107 if (!orig_node)
1108 goto out;
1109
1110 tvlv_len = sizeof(*tvlv_hdr) + tvlv_value_len;
1111
1112 skb = netdev_alloc_skb_ip_align(NULL, ETH_HLEN + hdr_len + tvlv_len);
1113 if (!skb)
1114 goto out;
1115
1116 skb->priority = TC_PRIO_CONTROL;
1117 skb_reserve(skb, ETH_HLEN);
1118 tvlv_buff = skb_put(skb, sizeof(*unicast_tvlv_packet) + tvlv_len);
1119 unicast_tvlv_packet = (struct batadv_unicast_tvlv_packet *)tvlv_buff;
1120 unicast_tvlv_packet->header.packet_type = BATADV_UNICAST_TVLV;
1121 unicast_tvlv_packet->header.version = BATADV_COMPAT_VERSION;
1122 unicast_tvlv_packet->header.ttl = BATADV_TTL;
1123 unicast_tvlv_packet->reserved = 0;
1124 unicast_tvlv_packet->tvlv_len = htons(tvlv_len);
1125 unicast_tvlv_packet->align = 0;
1126 memcpy(unicast_tvlv_packet->src, src, ETH_ALEN);
1127 memcpy(unicast_tvlv_packet->dst, dst, ETH_ALEN);
1128
1129 tvlv_buff = (unsigned char *)(unicast_tvlv_packet + 1);
1130 tvlv_hdr = (struct batadv_tvlv_hdr *)tvlv_buff;
1131 tvlv_hdr->version = version;
1132 tvlv_hdr->type = type;
1133 tvlv_hdr->len = htons(tvlv_value_len);
1134 tvlv_buff += sizeof(*tvlv_hdr);
1135 memcpy(tvlv_buff, tvlv_value, tvlv_value_len);
1136
1137 if (batadv_send_skb_to_orig(skb, orig_node, NULL) != NET_XMIT_DROP)
1138 ret = true;
1139
1140out:
1141 if (skb && !ret)
1142 kfree_skb(skb);
1143 if (orig_node)
1144 batadv_orig_node_free_ref(orig_node);
1145}
1146
1147/**
1148 * batadv_get_vid - extract the VLAN identifier from skb if any
1149 * @skb: the buffer containing the packet
1150 * @header_len: length of the batman header preceding the ethernet header
1151 *
1152 * If the packet embedded in the skb is vlan tagged this function returns the
1153 * VID with the BATADV_VLAN_HAS_TAG flag. Otherwise BATADV_NO_FLAGS is returned.
1154 */
1155unsigned short batadv_get_vid(struct sk_buff *skb, size_t header_len)
1156{
1157 struct ethhdr *ethhdr = (struct ethhdr *)(skb->data + header_len);
1158 struct vlan_ethhdr *vhdr;
1159 unsigned short vid;
1160
1161 if (ethhdr->h_proto != htons(ETH_P_8021Q))
1162 return BATADV_NO_FLAGS;
1163
1164 if (!pskb_may_pull(skb, header_len + VLAN_ETH_HLEN))
1165 return BATADV_NO_FLAGS;
1166
1167 vhdr = (struct vlan_ethhdr *)(skb->data + header_len);
1168 vid = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK;
1169 vid |= BATADV_VLAN_HAS_TAG;
1170
1171 return vid;
1172}
1173
539static int batadv_param_set_ra(const char *val, const struct kernel_param *kp) 1174static int batadv_param_set_ra(const char *val, const struct kernel_param *kp)
540{ 1175{
541 struct batadv_algo_ops *bat_algo_ops; 1176 struct batadv_algo_ops *bat_algo_ops;
diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h
index 24675523930f..d7dfafe45f29 100644
--- a/net/batman-adv/main.h
+++ b/net/batman-adv/main.h
@@ -20,8 +20,8 @@
20#ifndef _NET_BATMAN_ADV_MAIN_H_ 20#ifndef _NET_BATMAN_ADV_MAIN_H_
21#define _NET_BATMAN_ADV_MAIN_H_ 21#define _NET_BATMAN_ADV_MAIN_H_
22 22
23#define BATADV_DRIVER_AUTHOR "Marek Lindner <lindner_marek@yahoo.de>, " \ 23#define BATADV_DRIVER_AUTHOR "Marek Lindner <mareklindner@neomailbox.ch>, " \
24 "Simon Wunderlich <siwu@hrz.tu-chemnitz.de>" 24 "Simon Wunderlich <sw@simonwunderlich.de>"
25#define BATADV_DRIVER_DESC "B.A.T.M.A.N. advanced" 25#define BATADV_DRIVER_DESC "B.A.T.M.A.N. advanced"
26#define BATADV_DRIVER_DEVICE "batman-adv" 26#define BATADV_DRIVER_DEVICE "batman-adv"
27 27
@@ -86,8 +86,6 @@
86/* numbers of originator to contact for any PUT/GET DHT operation */ 86/* numbers of originator to contact for any PUT/GET DHT operation */
87#define BATADV_DAT_CANDIDATES_NUM 3 87#define BATADV_DAT_CANDIDATES_NUM 3
88 88
89#define BATADV_VIS_INTERVAL 5000 /* 5 seconds */
90
91/* how much worse secondary interfaces may be to be considered as bonding 89/* how much worse secondary interfaces may be to be considered as bonding
92 * candidates 90 * candidates
93 */ 91 */
@@ -133,6 +131,15 @@ enum batadv_uev_type {
133 131
134#define BATADV_GW_THRESHOLD 50 132#define BATADV_GW_THRESHOLD 50
135 133
134/* Number of fragment chains for each orig_node */
135#define BATADV_FRAG_BUFFER_COUNT 8
136/* Maximum number of fragments for one packet */
137#define BATADV_FRAG_MAX_FRAGMENTS 16
138/* Maxumim size of each fragment */
139#define BATADV_FRAG_MAX_FRAG_SIZE 1400
140/* Time to keep fragments while waiting for rest of the fragments */
141#define BATADV_FRAG_TIMEOUT 10000
142
136#define BATADV_DAT_CANDIDATE_NOT_FOUND 0 143#define BATADV_DAT_CANDIDATE_NOT_FOUND 0
137#define BATADV_DAT_CANDIDATE_ORIG 1 144#define BATADV_DAT_CANDIDATE_ORIG 1
138 145
@@ -160,15 +167,9 @@ enum batadv_uev_type {
160#include <net/rtnetlink.h> 167#include <net/rtnetlink.h>
161#include <linux/jiffies.h> 168#include <linux/jiffies.h>
162#include <linux/seq_file.h> 169#include <linux/seq_file.h>
163#include "types.h" 170#include <linux/if_vlan.h>
164 171
165/** 172#include "types.h"
166 * batadv_vlan_flags - flags for the four MSB of any vlan ID field
167 * @BATADV_VLAN_HAS_TAG: whether the field contains a valid vlan tag or not
168 */
169enum batadv_vlan_flags {
170 BATADV_VLAN_HAS_TAG = BIT(15),
171};
172 173
173#define BATADV_PRINT_VID(vid) (vid & BATADV_VLAN_HAS_TAG ? \ 174#define BATADV_PRINT_VID(vid) (vid & BATADV_VLAN_HAS_TAG ? \
174 (int)(vid & VLAN_VID_MASK) : -1) 175 (int)(vid & VLAN_VID_MASK) : -1)
@@ -184,6 +185,7 @@ void batadv_mesh_free(struct net_device *soft_iface);
184int batadv_is_my_mac(struct batadv_priv *bat_priv, const uint8_t *addr); 185int batadv_is_my_mac(struct batadv_priv *bat_priv, const uint8_t *addr);
185struct batadv_hard_iface * 186struct batadv_hard_iface *
186batadv_seq_print_text_primary_if_get(struct seq_file *seq); 187batadv_seq_print_text_primary_if_get(struct seq_file *seq);
188int batadv_max_header_len(void);
187void batadv_skb_set_priority(struct sk_buff *skb, int offset); 189void batadv_skb_set_priority(struct sk_buff *skb, int offset);
188int batadv_batman_skb_recv(struct sk_buff *skb, struct net_device *dev, 190int batadv_batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
189 struct packet_type *ptype, 191 struct packet_type *ptype,
@@ -326,4 +328,40 @@ static inline uint64_t batadv_sum_counter(struct batadv_priv *bat_priv,
326 */ 328 */
327#define BATADV_SKB_CB(__skb) ((struct batadv_skb_cb *)&((__skb)->cb[0])) 329#define BATADV_SKB_CB(__skb) ((struct batadv_skb_cb *)&((__skb)->cb[0]))
328 330
331void batadv_tvlv_container_register(struct batadv_priv *bat_priv,
332 uint8_t type, uint8_t version,
333 void *tvlv_value, uint16_t tvlv_value_len);
334uint16_t batadv_tvlv_container_ogm_append(struct batadv_priv *bat_priv,
335 unsigned char **packet_buff,
336 int *packet_buff_len,
337 int packet_min_len);
338void batadv_tvlv_ogm_receive(struct batadv_priv *bat_priv,
339 struct batadv_ogm_packet *batadv_ogm_packet,
340 struct batadv_orig_node *orig_node);
341void batadv_tvlv_container_unregister(struct batadv_priv *bat_priv,
342 uint8_t type, uint8_t version);
343
344void batadv_tvlv_handler_register(struct batadv_priv *bat_priv,
345 void (*optr)(struct batadv_priv *bat_priv,
346 struct batadv_orig_node *orig,
347 uint8_t flags,
348 void *tvlv_value,
349 uint16_t tvlv_value_len),
350 int (*uptr)(struct batadv_priv *bat_priv,
351 uint8_t *src, uint8_t *dst,
352 void *tvlv_value,
353 uint16_t tvlv_value_len),
354 uint8_t type, uint8_t version, uint8_t flags);
355void batadv_tvlv_handler_unregister(struct batadv_priv *bat_priv,
356 uint8_t type, uint8_t version);
357int batadv_tvlv_containers_process(struct batadv_priv *bat_priv,
358 bool ogm_source,
359 struct batadv_orig_node *orig_node,
360 uint8_t *src, uint8_t *dst,
361 void *tvlv_buff, uint16_t tvlv_buff_len);
362void batadv_tvlv_unicast_send(struct batadv_priv *bat_priv, uint8_t *src,
363 uint8_t *dst, uint8_t type, uint8_t version,
364 void *tvlv_value, uint16_t tvlv_value_len);
365unsigned short batadv_get_vid(struct sk_buff *skb, size_t header_len);
366
329#endif /* _NET_BATMAN_ADV_MAIN_H_ */ 367#endif /* _NET_BATMAN_ADV_MAIN_H_ */
diff --git a/net/batman-adv/network-coding.c b/net/batman-adv/network-coding.c
index 4ecc0b6bf8ab..23f611bedb0f 100644
--- a/net/batman-adv/network-coding.c
+++ b/net/batman-adv/network-coding.c
@@ -59,6 +59,59 @@ static void batadv_nc_start_timer(struct batadv_priv *bat_priv)
59} 59}
60 60
61/** 61/**
62 * batadv_nc_tvlv_container_update - update the network coding tvlv container
63 * after network coding setting change
64 * @bat_priv: the bat priv with all the soft interface information
65 */
66static void batadv_nc_tvlv_container_update(struct batadv_priv *bat_priv)
67{
68 char nc_mode;
69
70 nc_mode = atomic_read(&bat_priv->network_coding);
71
72 switch (nc_mode) {
73 case 0:
74 batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_NC, 1);
75 break;
76 case 1:
77 batadv_tvlv_container_register(bat_priv, BATADV_TVLV_NC, 1,
78 NULL, 0);
79 break;
80 }
81}
82
83/**
84 * batadv_nc_status_update - update the network coding tvlv container after
85 * network coding setting change
86 * @net_dev: the soft interface net device
87 */
88void batadv_nc_status_update(struct net_device *net_dev)
89{
90 struct batadv_priv *bat_priv = netdev_priv(net_dev);
91 batadv_nc_tvlv_container_update(bat_priv);
92}
93
94/**
95 * batadv_nc_tvlv_ogm_handler_v1 - process incoming nc tvlv container
96 * @bat_priv: the bat priv with all the soft interface information
97 * @orig: the orig_node of the ogm
98 * @flags: flags indicating the tvlv state (see batadv_tvlv_handler_flags)
99 * @tvlv_value: tvlv buffer containing the gateway data
100 * @tvlv_value_len: tvlv buffer length
101 */
102static void batadv_nc_tvlv_ogm_handler_v1(struct batadv_priv *bat_priv,
103 struct batadv_orig_node *orig,
104 uint8_t flags,
105 void *tvlv_value,
106 uint16_t tvlv_value_len)
107{
108 if (flags & BATADV_TVLV_HANDLER_OGM_CIFNOTFND)
109 orig->capabilities &= ~BATADV_ORIG_CAPA_HAS_NC;
110 else
111 orig->capabilities |= BATADV_ORIG_CAPA_HAS_NC;
112}
113
114/**
62 * batadv_nc_mesh_init - initialise coding hash table and start house keeping 115 * batadv_nc_mesh_init - initialise coding hash table and start house keeping
63 * @bat_priv: the bat priv with all the soft interface information 116 * @bat_priv: the bat priv with all the soft interface information
64 */ 117 */
@@ -87,6 +140,10 @@ int batadv_nc_mesh_init(struct batadv_priv *bat_priv)
87 INIT_DELAYED_WORK(&bat_priv->nc.work, batadv_nc_worker); 140 INIT_DELAYED_WORK(&bat_priv->nc.work, batadv_nc_worker);
88 batadv_nc_start_timer(bat_priv); 141 batadv_nc_start_timer(bat_priv);
89 142
143 batadv_tvlv_handler_register(bat_priv, batadv_nc_tvlv_ogm_handler_v1,
144 NULL, BATADV_TVLV_NC, 1,
145 BATADV_TVLV_HANDLER_OGM_CIFNOTFND);
146 batadv_nc_tvlv_container_update(bat_priv);
90 return 0; 147 return 0;
91 148
92err: 149err:
@@ -802,6 +859,10 @@ void batadv_nc_update_nc_node(struct batadv_priv *bat_priv,
802 if (!atomic_read(&bat_priv->network_coding)) 859 if (!atomic_read(&bat_priv->network_coding))
803 goto out; 860 goto out;
804 861
862 /* check if orig node is network coding enabled */
863 if (!(orig_node->capabilities & BATADV_ORIG_CAPA_HAS_NC))
864 goto out;
865
805 /* accept ogms from 'good' neighbors and single hop neighbors */ 866 /* accept ogms from 'good' neighbors and single hop neighbors */
806 if (!batadv_can_nc_with_orig(bat_priv, orig_node, ogm_packet) && 867 if (!batadv_can_nc_with_orig(bat_priv, orig_node, ogm_packet) &&
807 !is_single_hop_neigh) 868 !is_single_hop_neigh)
@@ -1735,6 +1796,8 @@ free_nc_packet:
1735 */ 1796 */
1736void batadv_nc_mesh_free(struct batadv_priv *bat_priv) 1797void batadv_nc_mesh_free(struct batadv_priv *bat_priv)
1737{ 1798{
1799 batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_NC, 1);
1800 batadv_tvlv_handler_unregister(bat_priv, BATADV_TVLV_NC, 1);
1738 cancel_delayed_work_sync(&bat_priv->nc.work); 1801 cancel_delayed_work_sync(&bat_priv->nc.work);
1739 1802
1740 batadv_nc_purge_paths(bat_priv, bat_priv->nc.coding_hash, NULL); 1803 batadv_nc_purge_paths(bat_priv, bat_priv->nc.coding_hash, NULL);
diff --git a/net/batman-adv/network-coding.h b/net/batman-adv/network-coding.h
index ddfa618e80bf..d4fd315b5261 100644
--- a/net/batman-adv/network-coding.h
+++ b/net/batman-adv/network-coding.h
@@ -22,6 +22,7 @@
22 22
23#ifdef CONFIG_BATMAN_ADV_NC 23#ifdef CONFIG_BATMAN_ADV_NC
24 24
25void batadv_nc_status_update(struct net_device *net_dev);
25int batadv_nc_init(void); 26int batadv_nc_init(void);
26int batadv_nc_mesh_init(struct batadv_priv *bat_priv); 27int batadv_nc_mesh_init(struct batadv_priv *bat_priv);
27void batadv_nc_mesh_free(struct batadv_priv *bat_priv); 28void batadv_nc_mesh_free(struct batadv_priv *bat_priv);
@@ -47,6 +48,10 @@ int batadv_nc_init_debugfs(struct batadv_priv *bat_priv);
47 48
48#else /* ifdef CONFIG_BATMAN_ADV_NC */ 49#else /* ifdef CONFIG_BATMAN_ADV_NC */
49 50
51static inline void batadv_nc_status_update(struct net_device *net_dev)
52{
53}
54
50static inline int batadv_nc_init(void) 55static inline int batadv_nc_init(void)
51{ 56{
52 return 0; 57 return 0;
diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c
index f50553a7de62..ee1d84724205 100644
--- a/net/batman-adv/originator.c
+++ b/net/batman-adv/originator.c
@@ -25,10 +25,10 @@
25#include "routing.h" 25#include "routing.h"
26#include "gateway_client.h" 26#include "gateway_client.h"
27#include "hard-interface.h" 27#include "hard-interface.h"
28#include "unicast.h"
29#include "soft-interface.h" 28#include "soft-interface.h"
30#include "bridge_loop_avoidance.h" 29#include "bridge_loop_avoidance.h"
31#include "network-coding.h" 30#include "network-coding.h"
31#include "fragmentation.h"
32 32
33/* hash class keys */ 33/* hash class keys */
34static struct lock_class_key batadv_orig_hash_lock_class_key; 34static struct lock_class_key batadv_orig_hash_lock_class_key;
@@ -44,6 +44,88 @@ static int batadv_compare_orig(const struct hlist_node *node, const void *data2)
44 return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0); 44 return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0);
45} 45}
46 46
47/**
48 * batadv_orig_node_vlan_get - get an orig_node_vlan object
49 * @orig_node: the originator serving the VLAN
50 * @vid: the VLAN identifier
51 *
52 * Returns the vlan object identified by vid and belonging to orig_node or NULL
53 * if it does not exist.
54 */
55struct batadv_orig_node_vlan *
56batadv_orig_node_vlan_get(struct batadv_orig_node *orig_node,
57 unsigned short vid)
58{
59 struct batadv_orig_node_vlan *vlan = NULL, *tmp;
60
61 rcu_read_lock();
62 list_for_each_entry_rcu(tmp, &orig_node->vlan_list, list) {
63 if (tmp->vid != vid)
64 continue;
65
66 if (!atomic_inc_not_zero(&tmp->refcount))
67 continue;
68
69 vlan = tmp;
70
71 break;
72 }
73 rcu_read_unlock();
74
75 return vlan;
76}
77
78/**
79 * batadv_orig_node_vlan_new - search and possibly create an orig_node_vlan
80 * object
81 * @orig_node: the originator serving the VLAN
82 * @vid: the VLAN identifier
83 *
84 * Returns NULL in case of failure or the vlan object identified by vid and
85 * belonging to orig_node otherwise. The object is created and added to the list
86 * if it does not exist.
87 *
88 * The object is returned with refcounter increased by 1.
89 */
90struct batadv_orig_node_vlan *
91batadv_orig_node_vlan_new(struct batadv_orig_node *orig_node,
92 unsigned short vid)
93{
94 struct batadv_orig_node_vlan *vlan;
95
96 spin_lock_bh(&orig_node->vlan_list_lock);
97
98 /* first look if an object for this vid already exists */
99 vlan = batadv_orig_node_vlan_get(orig_node, vid);
100 if (vlan)
101 goto out;
102
103 vlan = kzalloc(sizeof(*vlan), GFP_ATOMIC);
104 if (!vlan)
105 goto out;
106
107 atomic_set(&vlan->refcount, 2);
108 vlan->vid = vid;
109
110 list_add_rcu(&vlan->list, &orig_node->vlan_list);
111
112out:
113 spin_unlock_bh(&orig_node->vlan_list_lock);
114
115 return vlan;
116}
117
118/**
119 * batadv_orig_node_vlan_free_ref - decrement the refcounter and possibly free
120 * the originator-vlan object
121 * @orig_vlan: the originator-vlan object to release
122 */
123void batadv_orig_node_vlan_free_ref(struct batadv_orig_node_vlan *orig_vlan)
124{
125 if (atomic_dec_and_test(&orig_vlan->refcount))
126 kfree_rcu(orig_vlan, rcu);
127}
128
47int batadv_originator_init(struct batadv_priv *bat_priv) 129int batadv_originator_init(struct batadv_priv *bat_priv)
48{ 130{
49 if (bat_priv->orig_hash) 131 if (bat_priv->orig_hash)
@@ -146,8 +228,9 @@ static void batadv_orig_node_free_rcu(struct rcu_head *rcu)
146 /* Free nc_nodes */ 228 /* Free nc_nodes */
147 batadv_nc_purge_orig(orig_node->bat_priv, orig_node, NULL); 229 batadv_nc_purge_orig(orig_node->bat_priv, orig_node, NULL);
148 230
149 batadv_frag_list_free(&orig_node->frag_list); 231 batadv_frag_purge_orig(orig_node, NULL);
150 batadv_tt_global_del_orig(orig_node->bat_priv, orig_node, 232
233 batadv_tt_global_del_orig(orig_node->bat_priv, orig_node, -1,
151 "originator timed out"); 234 "originator timed out");
152 235
153 kfree(orig_node->tt_buff); 236 kfree(orig_node->tt_buff);
@@ -217,7 +300,8 @@ struct batadv_orig_node *batadv_get_orig_node(struct batadv_priv *bat_priv,
217 const uint8_t *addr) 300 const uint8_t *addr)
218{ 301{
219 struct batadv_orig_node *orig_node; 302 struct batadv_orig_node *orig_node;
220 int size; 303 struct batadv_orig_node_vlan *vlan;
304 int size, i;
221 int hash_added; 305 int hash_added;
222 unsigned long reset_time; 306 unsigned long reset_time;
223 307
@@ -234,10 +318,13 @@ struct batadv_orig_node *batadv_get_orig_node(struct batadv_priv *bat_priv,
234 318
235 INIT_HLIST_HEAD(&orig_node->neigh_list); 319 INIT_HLIST_HEAD(&orig_node->neigh_list);
236 INIT_LIST_HEAD(&orig_node->bond_list); 320 INIT_LIST_HEAD(&orig_node->bond_list);
321 INIT_LIST_HEAD(&orig_node->vlan_list);
237 spin_lock_init(&orig_node->ogm_cnt_lock); 322 spin_lock_init(&orig_node->ogm_cnt_lock);
238 spin_lock_init(&orig_node->bcast_seqno_lock); 323 spin_lock_init(&orig_node->bcast_seqno_lock);
239 spin_lock_init(&orig_node->neigh_list_lock); 324 spin_lock_init(&orig_node->neigh_list_lock);
240 spin_lock_init(&orig_node->tt_buff_lock); 325 spin_lock_init(&orig_node->tt_buff_lock);
326 spin_lock_init(&orig_node->tt_lock);
327 spin_lock_init(&orig_node->vlan_list_lock);
241 328
242 batadv_nc_init_orig(orig_node); 329 batadv_nc_init_orig(orig_node);
243 330
@@ -249,28 +336,39 @@ struct batadv_orig_node *batadv_get_orig_node(struct batadv_priv *bat_priv,
249 memcpy(orig_node->orig, addr, ETH_ALEN); 336 memcpy(orig_node->orig, addr, ETH_ALEN);
250 batadv_dat_init_orig_node_addr(orig_node); 337 batadv_dat_init_orig_node_addr(orig_node);
251 orig_node->router = NULL; 338 orig_node->router = NULL;
252 orig_node->tt_crc = 0;
253 atomic_set(&orig_node->last_ttvn, 0); 339 atomic_set(&orig_node->last_ttvn, 0);
254 orig_node->tt_buff = NULL; 340 orig_node->tt_buff = NULL;
255 orig_node->tt_buff_len = 0; 341 orig_node->tt_buff_len = 0;
256 atomic_set(&orig_node->tt_size, 0);
257 reset_time = jiffies - 1 - msecs_to_jiffies(BATADV_RESET_PROTECTION_MS); 342 reset_time = jiffies - 1 - msecs_to_jiffies(BATADV_RESET_PROTECTION_MS);
258 orig_node->bcast_seqno_reset = reset_time; 343 orig_node->bcast_seqno_reset = reset_time;
259 orig_node->batman_seqno_reset = reset_time; 344 orig_node->batman_seqno_reset = reset_time;
260 345
261 atomic_set(&orig_node->bond_candidates, 0); 346 atomic_set(&orig_node->bond_candidates, 0);
262 347
348 /* create a vlan object for the "untagged" LAN */
349 vlan = batadv_orig_node_vlan_new(orig_node, BATADV_NO_FLAGS);
350 if (!vlan)
351 goto free_orig_node;
352 /* batadv_orig_node_vlan_new() increases the refcounter.
353 * Immediately release vlan since it is not needed anymore in this
354 * context
355 */
356 batadv_orig_node_vlan_free_ref(vlan);
357
263 size = bat_priv->num_ifaces * sizeof(unsigned long) * BATADV_NUM_WORDS; 358 size = bat_priv->num_ifaces * sizeof(unsigned long) * BATADV_NUM_WORDS;
264 359
265 orig_node->bcast_own = kzalloc(size, GFP_ATOMIC); 360 orig_node->bcast_own = kzalloc(size, GFP_ATOMIC);
266 if (!orig_node->bcast_own) 361 if (!orig_node->bcast_own)
267 goto free_orig_node; 362 goto free_vlan;
268 363
269 size = bat_priv->num_ifaces * sizeof(uint8_t); 364 size = bat_priv->num_ifaces * sizeof(uint8_t);
270 orig_node->bcast_own_sum = kzalloc(size, GFP_ATOMIC); 365 orig_node->bcast_own_sum = kzalloc(size, GFP_ATOMIC);
271 366
272 INIT_LIST_HEAD(&orig_node->frag_list); 367 for (i = 0; i < BATADV_FRAG_BUFFER_COUNT; i++) {
273 orig_node->last_frag_packet = 0; 368 INIT_HLIST_HEAD(&orig_node->fragments[i].head);
369 spin_lock_init(&orig_node->fragments[i].lock);
370 orig_node->fragments[i].size = 0;
371 }
274 372
275 if (!orig_node->bcast_own_sum) 373 if (!orig_node->bcast_own_sum)
276 goto free_bcast_own; 374 goto free_bcast_own;
@@ -286,6 +384,8 @@ free_bcast_own_sum:
286 kfree(orig_node->bcast_own_sum); 384 kfree(orig_node->bcast_own_sum);
287free_bcast_own: 385free_bcast_own:
288 kfree(orig_node->bcast_own); 386 kfree(orig_node->bcast_own);
387free_vlan:
388 batadv_orig_node_vlan_free_ref(vlan);
289free_orig_node: 389free_orig_node:
290 kfree(orig_node); 390 kfree(orig_node);
291 return NULL; 391 return NULL;
@@ -388,17 +488,14 @@ static void _batadv_purge_orig(struct batadv_priv *bat_priv)
388 hlist_for_each_entry_safe(orig_node, node_tmp, 488 hlist_for_each_entry_safe(orig_node, node_tmp,
389 head, hash_entry) { 489 head, hash_entry) {
390 if (batadv_purge_orig_node(bat_priv, orig_node)) { 490 if (batadv_purge_orig_node(bat_priv, orig_node)) {
391 if (orig_node->gw_flags) 491 batadv_gw_node_delete(bat_priv, orig_node);
392 batadv_gw_node_delete(bat_priv,
393 orig_node);
394 hlist_del_rcu(&orig_node->hash_entry); 492 hlist_del_rcu(&orig_node->hash_entry);
395 batadv_orig_node_free_ref(orig_node); 493 batadv_orig_node_free_ref(orig_node);
396 continue; 494 continue;
397 } 495 }
398 496
399 if (batadv_has_timed_out(orig_node->last_frag_packet, 497 batadv_frag_purge_orig(orig_node,
400 BATADV_FRAG_TIMEOUT)) 498 batadv_frag_check_entry);
401 batadv_frag_list_free(&orig_node->frag_list);
402 } 499 }
403 spin_unlock_bh(list_lock); 500 spin_unlock_bh(list_lock);
404 } 501 }
diff --git a/net/batman-adv/originator.h b/net/batman-adv/originator.h
index 7887b84a9af4..cc6d686cfe6d 100644
--- a/net/batman-adv/originator.h
+++ b/net/batman-adv/originator.h
@@ -40,6 +40,13 @@ int batadv_orig_hash_add_if(struct batadv_hard_iface *hard_iface,
40 int max_if_num); 40 int max_if_num);
41int batadv_orig_hash_del_if(struct batadv_hard_iface *hard_iface, 41int batadv_orig_hash_del_if(struct batadv_hard_iface *hard_iface,
42 int max_if_num); 42 int max_if_num);
43struct batadv_orig_node_vlan *
44batadv_orig_node_vlan_new(struct batadv_orig_node *orig_node,
45 unsigned short vid);
46struct batadv_orig_node_vlan *
47batadv_orig_node_vlan_get(struct batadv_orig_node *orig_node,
48 unsigned short vid);
49void batadv_orig_node_vlan_free_ref(struct batadv_orig_node_vlan *orig_vlan);
43 50
44 51
45/* hashfunction to choose an entry in a hash table of given size 52/* hashfunction to choose an entry in a hash table of given size
diff --git a/net/batman-adv/packet.h b/net/batman-adv/packet.h
index a51ccfc39da4..9fbcaacc345a 100644
--- a/net/batman-adv/packet.h
+++ b/net/batman-adv/packet.h
@@ -20,17 +20,34 @@
20#ifndef _NET_BATMAN_ADV_PACKET_H_ 20#ifndef _NET_BATMAN_ADV_PACKET_H_
21#define _NET_BATMAN_ADV_PACKET_H_ 21#define _NET_BATMAN_ADV_PACKET_H_
22 22
23/**
24 * enum batadv_packettype - types for batman-adv encapsulated packets
25 * @BATADV_IV_OGM: originator messages for B.A.T.M.A.N. IV
26 * @BATADV_BCAST: broadcast packets carrying broadcast payload
27 * @BATADV_CODED: network coded packets
28 *
29 * @BATADV_UNICAST: unicast packets carrying unicast payload traffic
30 * @BATADV_UNICAST_FRAG: unicast packets carrying a fragment of the original
31 * payload packet
32 * @BATADV_UNICAST_4ADDR: unicast packet including the originator address of
33 * the sender
34 * @BATADV_ICMP: unicast packet like IP ICMP used for ping or traceroute
35 * @BATADV_UNICAST_TVLV: unicast packet carrying TVLV containers
36 */
23enum batadv_packettype { 37enum batadv_packettype {
24 BATADV_IV_OGM = 0x01, 38 /* 0x00 - 0x3f: local packets or special rules for handling */
25 BATADV_ICMP = 0x02, 39 BATADV_IV_OGM = 0x00,
26 BATADV_UNICAST = 0x03, 40 BATADV_BCAST = 0x01,
27 BATADV_BCAST = 0x04, 41 BATADV_CODED = 0x02,
28 BATADV_VIS = 0x05, 42 /* 0x40 - 0x7f: unicast */
29 BATADV_UNICAST_FRAG = 0x06, 43#define BATADV_UNICAST_MIN 0x40
30 BATADV_TT_QUERY = 0x07, 44 BATADV_UNICAST = 0x40,
31 BATADV_ROAM_ADV = 0x08, 45 BATADV_UNICAST_FRAG = 0x41,
32 BATADV_UNICAST_4ADDR = 0x09, 46 BATADV_UNICAST_4ADDR = 0x42,
33 BATADV_CODED = 0x0a, 47 BATADV_ICMP = 0x43,
48 BATADV_UNICAST_TVLV = 0x44,
49#define BATADV_UNICAST_MAX 0x7f
50 /* 0x80 - 0xff: reserved */
34}; 51};
35 52
36/** 53/**
@@ -48,13 +65,21 @@ enum batadv_subtype {
48}; 65};
49 66
50/* this file is included by batctl which needs these defines */ 67/* this file is included by batctl which needs these defines */
51#define BATADV_COMPAT_VERSION 14 68#define BATADV_COMPAT_VERSION 15
52 69
70/**
71 * enum batadv_iv_flags - flags used in B.A.T.M.A.N. IV OGM packets
72 * @BATADV_NOT_BEST_NEXT_HOP: flag is set when ogm packet is forwarded and was
73 * previously received from someone else than the best neighbor.
74 * @BATADV_PRIMARIES_FIRST_HOP: flag is set when the primary interface address
75 * is used, and the packet travels its first hop.
76 * @BATADV_DIRECTLINK: flag is for the first hop or if rebroadcasted from a
77 * one hop neighbor on the interface where it was originally received.
78 */
53enum batadv_iv_flags { 79enum batadv_iv_flags {
54 BATADV_NOT_BEST_NEXT_HOP = BIT(3), 80 BATADV_NOT_BEST_NEXT_HOP = BIT(0),
55 BATADV_PRIMARIES_FIRST_HOP = BIT(4), 81 BATADV_PRIMARIES_FIRST_HOP = BIT(1),
56 BATADV_VIS_SERVER = BIT(5), 82 BATADV_DIRECTLINK = BIT(2),
57 BATADV_DIRECTLINK = BIT(6),
58}; 83};
59 84
60/* ICMP message types */ 85/* ICMP message types */
@@ -66,29 +91,21 @@ enum batadv_icmp_packettype {
66 BATADV_PARAMETER_PROBLEM = 12, 91 BATADV_PARAMETER_PROBLEM = 12,
67}; 92};
68 93
69/* vis defines */ 94/* tt data subtypes */
70enum batadv_vis_packettype { 95#define BATADV_TT_DATA_TYPE_MASK 0x0F
71 BATADV_VIS_TYPE_SERVER_SYNC = 0,
72 BATADV_VIS_TYPE_CLIENT_UPDATE = 1,
73};
74
75/* fragmentation defines */
76enum batadv_unicast_frag_flags {
77 BATADV_UNI_FRAG_HEAD = BIT(0),
78 BATADV_UNI_FRAG_LARGETAIL = BIT(1),
79};
80 96
81/* TT_QUERY subtypes */ 97/**
82#define BATADV_TT_QUERY_TYPE_MASK 0x3 98 * enum batadv_tt_data_flags - flags for tt data tvlv
83 99 * @BATADV_TT_OGM_DIFF: TT diff propagated through OGM
84enum batadv_tt_query_packettype { 100 * @BATADV_TT_REQUEST: TT request message
85 BATADV_TT_REQUEST = 0, 101 * @BATADV_TT_RESPONSE: TT response message
86 BATADV_TT_RESPONSE = 1, 102 * @BATADV_TT_FULL_TABLE: contains full table to replace existing table
87}; 103 */
88 104enum batadv_tt_data_flags {
89/* TT_QUERY flags */ 105 BATADV_TT_OGM_DIFF = BIT(0),
90enum batadv_tt_query_flags { 106 BATADV_TT_REQUEST = BIT(1),
91 BATADV_TT_FULL_TABLE = BIT(2), 107 BATADV_TT_RESPONSE = BIT(2),
108 BATADV_TT_FULL_TABLE = BIT(4),
92}; 109};
93 110
94/* BATADV_TT_CLIENT flags. 111/* BATADV_TT_CLIENT flags.
@@ -99,10 +116,18 @@ enum batadv_tt_client_flags {
99 BATADV_TT_CLIENT_DEL = BIT(0), 116 BATADV_TT_CLIENT_DEL = BIT(0),
100 BATADV_TT_CLIENT_ROAM = BIT(1), 117 BATADV_TT_CLIENT_ROAM = BIT(1),
101 BATADV_TT_CLIENT_WIFI = BIT(2), 118 BATADV_TT_CLIENT_WIFI = BIT(2),
102 BATADV_TT_CLIENT_TEMP = BIT(3),
103 BATADV_TT_CLIENT_NOPURGE = BIT(8), 119 BATADV_TT_CLIENT_NOPURGE = BIT(8),
104 BATADV_TT_CLIENT_NEW = BIT(9), 120 BATADV_TT_CLIENT_NEW = BIT(9),
105 BATADV_TT_CLIENT_PENDING = BIT(10), 121 BATADV_TT_CLIENT_PENDING = BIT(10),
122 BATADV_TT_CLIENT_TEMP = BIT(11),
123};
124
125/**
126 * batadv_vlan_flags - flags for the four MSB of any vlan ID field
127 * @BATADV_VLAN_HAS_TAG: whether the field contains a valid vlan tag or not
128 */
129enum batadv_vlan_flags {
130 BATADV_VLAN_HAS_TAG = BIT(15),
106}; 131};
107 132
108/* claim frame types for the bridge loop avoidance */ 133/* claim frame types for the bridge loop avoidance */
@@ -113,6 +138,22 @@ enum batadv_bla_claimframe {
113 BATADV_CLAIM_TYPE_REQUEST = 0x03, 138 BATADV_CLAIM_TYPE_REQUEST = 0x03,
114}; 139};
115 140
141/**
142 * enum batadv_tvlv_type - tvlv type definitions
143 * @BATADV_TVLV_GW: gateway tvlv
144 * @BATADV_TVLV_DAT: distributed arp table tvlv
145 * @BATADV_TVLV_NC: network coding tvlv
146 * @BATADV_TVLV_TT: translation table tvlv
147 * @BATADV_TVLV_ROAM: roaming advertisement tvlv
148 */
149enum batadv_tvlv_type {
150 BATADV_TVLV_GW = 0x01,
151 BATADV_TVLV_DAT = 0x02,
152 BATADV_TVLV_NC = 0x03,
153 BATADV_TVLV_TT = 0x04,
154 BATADV_TVLV_ROAM = 0x05,
155};
156
116/* the destination hardware field in the ARP frame is used to 157/* the destination hardware field in the ARP frame is used to
117 * transport the claim type and the group id 158 * transport the claim type and the group id
118 */ 159 */
@@ -131,44 +172,69 @@ struct batadv_header {
131 */ 172 */
132}; 173};
133 174
175/**
176 * struct batadv_ogm_packet - ogm (routing protocol) packet
177 * @header: common batman packet header
178 * @flags: contains routing relevant flags - see enum batadv_iv_flags
179 * @tvlv_len: length of tvlv data following the ogm header
180 */
134struct batadv_ogm_packet { 181struct batadv_ogm_packet {
135 struct batadv_header header; 182 struct batadv_header header;
136 uint8_t flags; /* 0x40: DIRECTLINK flag, 0x20 VIS_SERVER flag... */ 183 uint8_t flags;
137 __be32 seqno; 184 __be32 seqno;
138 uint8_t orig[ETH_ALEN]; 185 uint8_t orig[ETH_ALEN];
139 uint8_t prev_sender[ETH_ALEN]; 186 uint8_t prev_sender[ETH_ALEN];
140 uint8_t gw_flags; /* flags related to gateway class */ 187 uint8_t reserved;
141 uint8_t tq; 188 uint8_t tq;
142 uint8_t tt_num_changes; 189 __be16 tvlv_len;
143 uint8_t ttvn; /* translation table version number */ 190 /* __packed is not needed as the struct size is divisible by 4,
144 __be16 tt_crc; 191 * and the largest data type in this struct has a size of 4.
145} __packed; 192 */
193};
146 194
147#define BATADV_OGM_HLEN sizeof(struct batadv_ogm_packet) 195#define BATADV_OGM_HLEN sizeof(struct batadv_ogm_packet)
148 196
149struct batadv_icmp_packet { 197/**
198 * batadv_icmp_header - common ICMP header
199 * @header: common batman header
200 * @msg_type: ICMP packet type
201 * @dst: address of the destination node
202 * @orig: address of the source node
203 * @uid: local ICMP socket identifier
204 */
205struct batadv_icmp_header {
150 struct batadv_header header; 206 struct batadv_header header;
151 uint8_t msg_type; /* see ICMP message types above */ 207 uint8_t msg_type; /* see ICMP message types above */
152 uint8_t dst[ETH_ALEN]; 208 uint8_t dst[ETH_ALEN];
153 uint8_t orig[ETH_ALEN]; 209 uint8_t orig[ETH_ALEN];
154 __be16 seqno;
155 uint8_t uid; 210 uint8_t uid;
211};
212
213/**
214 * batadv_icmp_packet - ICMP packet
215 * @icmph: common ICMP header
216 * @reserved: not used - useful for alignment
217 * @seqno: ICMP sequence number
218 */
219struct batadv_icmp_packet {
220 struct batadv_icmp_header icmph;
156 uint8_t reserved; 221 uint8_t reserved;
222 __be16 seqno;
157}; 223};
158 224
159#define BATADV_RR_LEN 16 225#define BATADV_RR_LEN 16
160 226
161/* icmp_packet_rr must start with all fields from imcp_packet 227/**
162 * as this is assumed by code that handles ICMP packets 228 * batadv_icmp_packet_rr - ICMP RouteRecord packet
229 * @icmph: common ICMP header
230 * @rr_cur: number of entries the rr array
231 * @seqno: ICMP sequence number
232 * @rr: route record array
163 */ 233 */
164struct batadv_icmp_packet_rr { 234struct batadv_icmp_packet_rr {
165 struct batadv_header header; 235 struct batadv_icmp_header icmph;
166 uint8_t msg_type; /* see ICMP message types above */
167 uint8_t dst[ETH_ALEN];
168 uint8_t orig[ETH_ALEN];
169 __be16 seqno;
170 uint8_t uid;
171 uint8_t rr_cur; 236 uint8_t rr_cur;
237 __be16 seqno;
172 uint8_t rr[BATADV_RR_LEN][ETH_ALEN]; 238 uint8_t rr[BATADV_RR_LEN][ETH_ALEN];
173}; 239};
174 240
@@ -209,15 +275,32 @@ struct batadv_unicast_4addr_packet {
209 */ 275 */
210}; 276};
211 277
212struct batadv_unicast_frag_packet { 278/**
213 struct batadv_header header; 279 * struct batadv_frag_packet - fragmented packet
214 uint8_t ttvn; /* destination translation table version number */ 280 * @header: common batman packet header with type, compatversion, and ttl
215 uint8_t dest[ETH_ALEN]; 281 * @dest: final destination used when routing fragments
216 uint8_t flags; 282 * @orig: originator of the fragment used when merging the packet
217 uint8_t align; 283 * @no: fragment number within this sequence
218 uint8_t orig[ETH_ALEN]; 284 * @reserved: reserved byte for alignment
219 __be16 seqno; 285 * @seqno: sequence identification
220} __packed; 286 * @total_size: size of the merged packet
287 */
288struct batadv_frag_packet {
289 struct batadv_header header;
290#if defined(__BIG_ENDIAN_BITFIELD)
291 uint8_t no:4;
292 uint8_t reserved:4;
293#elif defined(__LITTLE_ENDIAN_BITFIELD)
294 uint8_t reserved:4;
295 uint8_t no:4;
296#else
297#error "unknown bitfield endianess"
298#endif
299 uint8_t dest[ETH_ALEN];
300 uint8_t orig[ETH_ALEN];
301 __be16 seqno;
302 __be16 total_size;
303};
221 304
222struct batadv_bcast_packet { 305struct batadv_bcast_packet {
223 struct batadv_header header; 306 struct batadv_header header;
@@ -231,54 +314,6 @@ struct batadv_bcast_packet {
231 314
232#pragma pack() 315#pragma pack()
233 316
234struct batadv_vis_packet {
235 struct batadv_header header;
236 uint8_t vis_type; /* which type of vis-participant sent this? */
237 __be32 seqno; /* sequence number */
238 uint8_t entries; /* number of entries behind this struct */
239 uint8_t reserved;
240 uint8_t vis_orig[ETH_ALEN]; /* originator reporting its neighbors */
241 uint8_t target_orig[ETH_ALEN]; /* who should receive this packet */
242 uint8_t sender_orig[ETH_ALEN]; /* who sent or forwarded this packet */
243};
244
245struct batadv_tt_query_packet {
246 struct batadv_header header;
247 /* the flag field is a combination of:
248 * - TT_REQUEST or TT_RESPONSE
249 * - TT_FULL_TABLE
250 */
251 uint8_t flags;
252 uint8_t dst[ETH_ALEN];
253 uint8_t src[ETH_ALEN];
254 /* the ttvn field is:
255 * if TT_REQUEST: ttvn that triggered the
256 * request
257 * if TT_RESPONSE: new ttvn for the src
258 * orig_node
259 */
260 uint8_t ttvn;
261 /* tt_data field is:
262 * if TT_REQUEST: crc associated with the
263 * ttvn
264 * if TT_RESPONSE: table_size
265 */
266 __be16 tt_data;
267} __packed;
268
269struct batadv_roam_adv_packet {
270 struct batadv_header header;
271 uint8_t reserved;
272 uint8_t dst[ETH_ALEN];
273 uint8_t src[ETH_ALEN];
274 uint8_t client[ETH_ALEN];
275} __packed;
276
277struct batadv_tt_change {
278 uint8_t flags;
279 uint8_t addr[ETH_ALEN];
280} __packed;
281
282/** 317/**
283 * struct batadv_coded_packet - network coded packet 318 * struct batadv_coded_packet - network coded packet
284 * @header: common batman packet header and ttl of first included packet 319 * @header: common batman packet header and ttl of first included packet
@@ -311,4 +346,96 @@ struct batadv_coded_packet {
311 __be16 coded_len; 346 __be16 coded_len;
312}; 347};
313 348
349/**
350 * struct batadv_unicast_tvlv - generic unicast packet with tvlv payload
351 * @header: common batman packet header
352 * @reserved: reserved field (for packet alignment)
353 * @src: address of the source
354 * @dst: address of the destination
355 * @tvlv_len: length of tvlv data following the unicast tvlv header
356 * @align: 2 bytes to align the header to a 4 byte boundry
357 */
358struct batadv_unicast_tvlv_packet {
359 struct batadv_header header;
360 uint8_t reserved;
361 uint8_t dst[ETH_ALEN];
362 uint8_t src[ETH_ALEN];
363 __be16 tvlv_len;
364 uint16_t align;
365};
366
367/**
368 * struct batadv_tvlv_hdr - base tvlv header struct
369 * @type: tvlv container type (see batadv_tvlv_type)
370 * @version: tvlv container version
371 * @len: tvlv container length
372 */
373struct batadv_tvlv_hdr {
374 uint8_t type;
375 uint8_t version;
376 __be16 len;
377};
378
379/**
380 * struct batadv_tvlv_gateway_data - gateway data propagated through gw tvlv
381 * container
382 * @bandwidth_down: advertised uplink download bandwidth
383 * @bandwidth_up: advertised uplink upload bandwidth
384 */
385struct batadv_tvlv_gateway_data {
386 __be32 bandwidth_down;
387 __be32 bandwidth_up;
388};
389
390/**
391 * struct batadv_tvlv_tt_data - tt data propagated through the tt tvlv container
392 * @flags: translation table flags (see batadv_tt_data_flags)
393 * @ttvn: translation table version number
394 * @vlan_num: number of announced VLANs. In the TVLV this struct is followed by
395 * one batadv_tvlv_tt_vlan_data object per announced vlan
396 */
397struct batadv_tvlv_tt_data {
398 uint8_t flags;
399 uint8_t ttvn;
400 __be16 num_vlan;
401};
402
403/**
404 * struct batadv_tvlv_tt_vlan_data - vlan specific tt data propagated through
405 * the tt tvlv container
406 * @crc: crc32 checksum of the entries belonging to this vlan
407 * @vid: vlan identifier
408 * @reserved: unused, useful for alignment purposes
409 */
410struct batadv_tvlv_tt_vlan_data {
411 __be32 crc;
412 __be16 vid;
413 uint16_t reserved;
414};
415
416/**
417 * struct batadv_tvlv_tt_change - translation table diff data
418 * @flags: status indicators concerning the non-mesh client (see
419 * batadv_tt_client_flags)
420 * @reserved: reserved field
421 * @addr: mac address of non-mesh client that triggered this tt change
422 * @vid: VLAN identifier
423 */
424struct batadv_tvlv_tt_change {
425 uint8_t flags;
426 uint8_t reserved;
427 uint8_t addr[ETH_ALEN];
428 __be16 vid;
429};
430
431/**
432 * struct batadv_tvlv_roam_adv - roaming advertisement
433 * @client: mac address of roaming client
434 * @vid: VLAN identifier
435 */
436struct batadv_tvlv_roam_adv {
437 uint8_t client[ETH_ALEN];
438 __be16 vid;
439};
440
314#endif /* _NET_BATMAN_ADV_PACKET_H_ */ 441#endif /* _NET_BATMAN_ADV_PACKET_H_ */
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
index 0439395d7ba5..4bcf22129ffe 100644
--- a/net/batman-adv/routing.c
+++ b/net/batman-adv/routing.c
@@ -25,11 +25,12 @@
25#include "icmp_socket.h" 25#include "icmp_socket.h"
26#include "translation-table.h" 26#include "translation-table.h"
27#include "originator.h" 27#include "originator.h"
28#include "vis.h"
29#include "unicast.h"
30#include "bridge_loop_avoidance.h" 28#include "bridge_loop_avoidance.h"
31#include "distributed-arp-table.h" 29#include "distributed-arp-table.h"
32#include "network-coding.h" 30#include "network-coding.h"
31#include "fragmentation.h"
32
33#include <linux/if_vlan.h>
33 34
34static int batadv_route_unicast_packet(struct sk_buff *skb, 35static int batadv_route_unicast_packet(struct sk_buff *skb,
35 struct batadv_hard_iface *recv_if); 36 struct batadv_hard_iface *recv_if);
@@ -46,7 +47,7 @@ static void _batadv_update_route(struct batadv_priv *bat_priv,
46 if ((curr_router) && (!neigh_node)) { 47 if ((curr_router) && (!neigh_node)) {
47 batadv_dbg(BATADV_DBG_ROUTES, bat_priv, 48 batadv_dbg(BATADV_DBG_ROUTES, bat_priv,
48 "Deleting route towards: %pM\n", orig_node->orig); 49 "Deleting route towards: %pM\n", orig_node->orig);
49 batadv_tt_global_del_orig(bat_priv, orig_node, 50 batadv_tt_global_del_orig(bat_priv, orig_node, -1,
50 "Deleted route towards originator"); 51 "Deleted route towards originator");
51 52
52 /* route added */ 53 /* route added */
@@ -259,7 +260,7 @@ static int batadv_recv_my_icmp_packet(struct batadv_priv *bat_priv,
259 icmp_packet = (struct batadv_icmp_packet_rr *)skb->data; 260 icmp_packet = (struct batadv_icmp_packet_rr *)skb->data;
260 261
261 /* add data to device queue */ 262 /* add data to device queue */
262 if (icmp_packet->msg_type != BATADV_ECHO_REQUEST) { 263 if (icmp_packet->icmph.msg_type != BATADV_ECHO_REQUEST) {
263 batadv_socket_receive_packet(icmp_packet, icmp_len); 264 batadv_socket_receive_packet(icmp_packet, icmp_len);
264 goto out; 265 goto out;
265 } 266 }
@@ -270,7 +271,7 @@ static int batadv_recv_my_icmp_packet(struct batadv_priv *bat_priv,
270 271
271 /* answer echo request (ping) */ 272 /* answer echo request (ping) */
272 /* get routing information */ 273 /* get routing information */
273 orig_node = batadv_orig_hash_find(bat_priv, icmp_packet->orig); 274 orig_node = batadv_orig_hash_find(bat_priv, icmp_packet->icmph.orig);
274 if (!orig_node) 275 if (!orig_node)
275 goto out; 276 goto out;
276 277
@@ -280,10 +281,11 @@ static int batadv_recv_my_icmp_packet(struct batadv_priv *bat_priv,
280 281
281 icmp_packet = (struct batadv_icmp_packet_rr *)skb->data; 282 icmp_packet = (struct batadv_icmp_packet_rr *)skb->data;
282 283
283 memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN); 284 memcpy(icmp_packet->icmph.dst, icmp_packet->icmph.orig, ETH_ALEN);
284 memcpy(icmp_packet->orig, primary_if->net_dev->dev_addr, ETH_ALEN); 285 memcpy(icmp_packet->icmph.orig, primary_if->net_dev->dev_addr,
285 icmp_packet->msg_type = BATADV_ECHO_REPLY; 286 ETH_ALEN);
286 icmp_packet->header.ttl = BATADV_TTL; 287 icmp_packet->icmph.msg_type = BATADV_ECHO_REPLY;
288 icmp_packet->icmph.header.ttl = BATADV_TTL;
287 289
288 if (batadv_send_skb_to_orig(skb, orig_node, NULL) != NET_XMIT_DROP) 290 if (batadv_send_skb_to_orig(skb, orig_node, NULL) != NET_XMIT_DROP)
289 ret = NET_RX_SUCCESS; 291 ret = NET_RX_SUCCESS;
@@ -307,9 +309,9 @@ static int batadv_recv_icmp_ttl_exceeded(struct batadv_priv *bat_priv,
307 icmp_packet = (struct batadv_icmp_packet *)skb->data; 309 icmp_packet = (struct batadv_icmp_packet *)skb->data;
308 310
309 /* send TTL exceeded if packet is an echo request (traceroute) */ 311 /* send TTL exceeded if packet is an echo request (traceroute) */
310 if (icmp_packet->msg_type != BATADV_ECHO_REQUEST) { 312 if (icmp_packet->icmph.msg_type != BATADV_ECHO_REQUEST) {
311 pr_debug("Warning - can't forward icmp packet from %pM to %pM: ttl exceeded\n", 313 pr_debug("Warning - can't forward icmp packet from %pM to %pM: ttl exceeded\n",
312 icmp_packet->orig, icmp_packet->dst); 314 icmp_packet->icmph.orig, icmp_packet->icmph.dst);
313 goto out; 315 goto out;
314 } 316 }
315 317
@@ -318,7 +320,7 @@ static int batadv_recv_icmp_ttl_exceeded(struct batadv_priv *bat_priv,
318 goto out; 320 goto out;
319 321
320 /* get routing information */ 322 /* get routing information */
321 orig_node = batadv_orig_hash_find(bat_priv, icmp_packet->orig); 323 orig_node = batadv_orig_hash_find(bat_priv, icmp_packet->icmph.orig);
322 if (!orig_node) 324 if (!orig_node)
323 goto out; 325 goto out;
324 326
@@ -328,10 +330,11 @@ static int batadv_recv_icmp_ttl_exceeded(struct batadv_priv *bat_priv,
328 330
329 icmp_packet = (struct batadv_icmp_packet *)skb->data; 331 icmp_packet = (struct batadv_icmp_packet *)skb->data;
330 332
331 memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN); 333 memcpy(icmp_packet->icmph.dst, icmp_packet->icmph.orig, ETH_ALEN);
332 memcpy(icmp_packet->orig, primary_if->net_dev->dev_addr, ETH_ALEN); 334 memcpy(icmp_packet->icmph.orig, primary_if->net_dev->dev_addr,
333 icmp_packet->msg_type = BATADV_TTL_EXCEEDED; 335 ETH_ALEN);
334 icmp_packet->header.ttl = BATADV_TTL; 336 icmp_packet->icmph.msg_type = BATADV_TTL_EXCEEDED;
337 icmp_packet->icmph.header.ttl = BATADV_TTL;
335 338
336 if (batadv_send_skb_to_orig(skb, orig_node, NULL) != NET_XMIT_DROP) 339 if (batadv_send_skb_to_orig(skb, orig_node, NULL) != NET_XMIT_DROP)
337 ret = NET_RX_SUCCESS; 340 ret = NET_RX_SUCCESS;
@@ -380,7 +383,9 @@ int batadv_recv_icmp_packet(struct sk_buff *skb,
380 icmp_packet = (struct batadv_icmp_packet_rr *)skb->data; 383 icmp_packet = (struct batadv_icmp_packet_rr *)skb->data;
381 384
382 /* add record route information if not full */ 385 /* add record route information if not full */
383 if ((hdr_size == sizeof(struct batadv_icmp_packet_rr)) && 386 if ((icmp_packet->icmph.msg_type == BATADV_ECHO_REPLY ||
387 icmp_packet->icmph.msg_type == BATADV_ECHO_REQUEST) &&
388 (hdr_size == sizeof(struct batadv_icmp_packet_rr)) &&
384 (icmp_packet->rr_cur < BATADV_RR_LEN)) { 389 (icmp_packet->rr_cur < BATADV_RR_LEN)) {
385 memcpy(&(icmp_packet->rr[icmp_packet->rr_cur]), 390 memcpy(&(icmp_packet->rr[icmp_packet->rr_cur]),
386 ethhdr->h_dest, ETH_ALEN); 391 ethhdr->h_dest, ETH_ALEN);
@@ -388,15 +393,15 @@ int batadv_recv_icmp_packet(struct sk_buff *skb,
388 } 393 }
389 394
390 /* packet for me */ 395 /* packet for me */
391 if (batadv_is_my_mac(bat_priv, icmp_packet->dst)) 396 if (batadv_is_my_mac(bat_priv, icmp_packet->icmph.dst))
392 return batadv_recv_my_icmp_packet(bat_priv, skb, hdr_size); 397 return batadv_recv_my_icmp_packet(bat_priv, skb, hdr_size);
393 398
394 /* TTL exceeded */ 399 /* TTL exceeded */
395 if (icmp_packet->header.ttl < 2) 400 if (icmp_packet->icmph.header.ttl < 2)
396 return batadv_recv_icmp_ttl_exceeded(bat_priv, skb); 401 return batadv_recv_icmp_ttl_exceeded(bat_priv, skb);
397 402
398 /* get routing information */ 403 /* get routing information */
399 orig_node = batadv_orig_hash_find(bat_priv, icmp_packet->dst); 404 orig_node = batadv_orig_hash_find(bat_priv, icmp_packet->icmph.dst);
400 if (!orig_node) 405 if (!orig_node)
401 goto out; 406 goto out;
402 407
@@ -407,7 +412,7 @@ int batadv_recv_icmp_packet(struct sk_buff *skb,
407 icmp_packet = (struct batadv_icmp_packet_rr *)skb->data; 412 icmp_packet = (struct batadv_icmp_packet_rr *)skb->data;
408 413
409 /* decrement ttl */ 414 /* decrement ttl */
410 icmp_packet->header.ttl--; 415 icmp_packet->icmph.header.ttl--;
411 416
412 /* route it */ 417 /* route it */
413 if (batadv_send_skb_to_orig(skb, orig_node, recv_if) != NET_XMIT_DROP) 418 if (batadv_send_skb_to_orig(skb, orig_node, recv_if) != NET_XMIT_DROP)
@@ -557,126 +562,6 @@ static int batadv_check_unicast_packet(struct batadv_priv *bat_priv,
557 return 0; 562 return 0;
558} 563}
559 564
560int batadv_recv_tt_query(struct sk_buff *skb, struct batadv_hard_iface *recv_if)
561{
562 struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface);
563 struct batadv_tt_query_packet *tt_query;
564 uint16_t tt_size;
565 int hdr_size = sizeof(*tt_query);
566 char tt_flag;
567 size_t packet_size;
568
569 if (batadv_check_unicast_packet(bat_priv, skb, hdr_size) < 0)
570 return NET_RX_DROP;
571
572 /* I could need to modify it */
573 if (skb_cow(skb, sizeof(struct batadv_tt_query_packet)) < 0)
574 goto out;
575
576 tt_query = (struct batadv_tt_query_packet *)skb->data;
577
578 switch (tt_query->flags & BATADV_TT_QUERY_TYPE_MASK) {
579 case BATADV_TT_REQUEST:
580 batadv_inc_counter(bat_priv, BATADV_CNT_TT_REQUEST_RX);
581
582 /* If we cannot provide an answer the tt_request is
583 * forwarded
584 */
585 if (!batadv_send_tt_response(bat_priv, tt_query)) {
586 if (tt_query->flags & BATADV_TT_FULL_TABLE)
587 tt_flag = 'F';
588 else
589 tt_flag = '.';
590
591 batadv_dbg(BATADV_DBG_TT, bat_priv,
592 "Routing TT_REQUEST to %pM [%c]\n",
593 tt_query->dst,
594 tt_flag);
595 return batadv_route_unicast_packet(skb, recv_if);
596 }
597 break;
598 case BATADV_TT_RESPONSE:
599 batadv_inc_counter(bat_priv, BATADV_CNT_TT_RESPONSE_RX);
600
601 if (batadv_is_my_mac(bat_priv, tt_query->dst)) {
602 /* packet needs to be linearized to access the TT
603 * changes
604 */
605 if (skb_linearize(skb) < 0)
606 goto out;
607 /* skb_linearize() possibly changed skb->data */
608 tt_query = (struct batadv_tt_query_packet *)skb->data;
609
610 tt_size = batadv_tt_len(ntohs(tt_query->tt_data));
611
612 /* Ensure we have all the claimed data */
613 packet_size = sizeof(struct batadv_tt_query_packet);
614 packet_size += tt_size;
615 if (unlikely(skb_headlen(skb) < packet_size))
616 goto out;
617
618 batadv_handle_tt_response(bat_priv, tt_query);
619 } else {
620 if (tt_query->flags & BATADV_TT_FULL_TABLE)
621 tt_flag = 'F';
622 else
623 tt_flag = '.';
624 batadv_dbg(BATADV_DBG_TT, bat_priv,
625 "Routing TT_RESPONSE to %pM [%c]\n",
626 tt_query->dst,
627 tt_flag);
628 return batadv_route_unicast_packet(skb, recv_if);
629 }
630 break;
631 }
632
633out:
634 /* returning NET_RX_DROP will make the caller function kfree the skb */
635 return NET_RX_DROP;
636}
637
638int batadv_recv_roam_adv(struct sk_buff *skb, struct batadv_hard_iface *recv_if)
639{
640 struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface);
641 struct batadv_roam_adv_packet *roam_adv_packet;
642 struct batadv_orig_node *orig_node;
643
644 if (batadv_check_unicast_packet(bat_priv, skb,
645 sizeof(*roam_adv_packet)) < 0)
646 goto out;
647
648 batadv_inc_counter(bat_priv, BATADV_CNT_TT_ROAM_ADV_RX);
649
650 roam_adv_packet = (struct batadv_roam_adv_packet *)skb->data;
651
652 if (!batadv_is_my_mac(bat_priv, roam_adv_packet->dst))
653 return batadv_route_unicast_packet(skb, recv_if);
654
655 /* check if it is a backbone gateway. we don't accept
656 * roaming advertisement from it, as it has the same
657 * entries as we have.
658 */
659 if (batadv_bla_is_backbone_gw_orig(bat_priv, roam_adv_packet->src))
660 goto out;
661
662 orig_node = batadv_orig_hash_find(bat_priv, roam_adv_packet->src);
663 if (!orig_node)
664 goto out;
665
666 batadv_dbg(BATADV_DBG_TT, bat_priv,
667 "Received ROAMING_ADV from %pM (client %pM)\n",
668 roam_adv_packet->src, roam_adv_packet->client);
669
670 batadv_tt_global_add(bat_priv, orig_node, roam_adv_packet->client,
671 BATADV_TT_CLIENT_ROAM,
672 atomic_read(&orig_node->last_ttvn) + 1);
673
674 batadv_orig_node_free_ref(orig_node);
675out:
676 /* returning NET_RX_DROP will make the caller function kfree the skb */
677 return NET_RX_DROP;
678}
679
680/* find a suitable router for this originator, and use 565/* find a suitable router for this originator, and use
681 * bonding if possible. increases the found neighbors 566 * bonding if possible. increases the found neighbors
682 * refcount. 567 * refcount.
@@ -772,11 +657,9 @@ static int batadv_route_unicast_packet(struct sk_buff *skb,
772{ 657{
773 struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface); 658 struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface);
774 struct batadv_orig_node *orig_node = NULL; 659 struct batadv_orig_node *orig_node = NULL;
775 struct batadv_neigh_node *neigh_node = NULL;
776 struct batadv_unicast_packet *unicast_packet; 660 struct batadv_unicast_packet *unicast_packet;
777 struct ethhdr *ethhdr = eth_hdr(skb); 661 struct ethhdr *ethhdr = eth_hdr(skb);
778 int res, hdr_len, ret = NET_RX_DROP; 662 int res, hdr_len, ret = NET_RX_DROP;
779 struct sk_buff *new_skb;
780 663
781 unicast_packet = (struct batadv_unicast_packet *)skb->data; 664 unicast_packet = (struct batadv_unicast_packet *)skb->data;
782 665
@@ -793,46 +676,12 @@ static int batadv_route_unicast_packet(struct sk_buff *skb,
793 if (!orig_node) 676 if (!orig_node)
794 goto out; 677 goto out;
795 678
796 /* find_router() increases neigh_nodes refcount if found. */
797 neigh_node = batadv_find_router(bat_priv, orig_node, recv_if);
798
799 if (!neigh_node)
800 goto out;
801
802 /* create a copy of the skb, if needed, to modify it. */ 679 /* create a copy of the skb, if needed, to modify it. */
803 if (skb_cow(skb, ETH_HLEN) < 0) 680 if (skb_cow(skb, ETH_HLEN) < 0)
804 goto out; 681 goto out;
805 682
806 unicast_packet = (struct batadv_unicast_packet *)skb->data;
807
808 if (unicast_packet->header.packet_type == BATADV_UNICAST &&
809 atomic_read(&bat_priv->fragmentation) &&
810 skb->len > neigh_node->if_incoming->net_dev->mtu) {
811 ret = batadv_frag_send_skb(skb, bat_priv,
812 neigh_node->if_incoming,
813 neigh_node->addr);
814 goto out;
815 }
816
817 if (unicast_packet->header.packet_type == BATADV_UNICAST_FRAG &&
818 batadv_frag_can_reassemble(skb,
819 neigh_node->if_incoming->net_dev->mtu)) {
820 ret = batadv_frag_reassemble_skb(skb, bat_priv, &new_skb);
821
822 if (ret == NET_RX_DROP)
823 goto out;
824
825 /* packet was buffered for late merge */
826 if (!new_skb) {
827 ret = NET_RX_SUCCESS;
828 goto out;
829 }
830
831 skb = new_skb;
832 unicast_packet = (struct batadv_unicast_packet *)skb->data;
833 }
834
835 /* decrement ttl */ 683 /* decrement ttl */
684 unicast_packet = (struct batadv_unicast_packet *)skb->data;
836 unicast_packet->header.ttl--; 685 unicast_packet->header.ttl--;
837 686
838 switch (unicast_packet->header.packet_type) { 687 switch (unicast_packet->header.packet_type) {
@@ -867,8 +716,6 @@ static int batadv_route_unicast_packet(struct sk_buff *skb,
867 } 716 }
868 717
869out: 718out:
870 if (neigh_node)
871 batadv_neigh_node_free_ref(neigh_node);
872 if (orig_node) 719 if (orig_node)
873 batadv_orig_node_free_ref(orig_node); 720 batadv_orig_node_free_ref(orig_node);
874 return ret; 721 return ret;
@@ -879,6 +726,7 @@ out:
879 * @bat_priv: the bat priv with all the soft interface information 726 * @bat_priv: the bat priv with all the soft interface information
880 * @unicast_packet: the unicast header to be updated 727 * @unicast_packet: the unicast header to be updated
881 * @dst_addr: the payload destination 728 * @dst_addr: the payload destination
729 * @vid: VLAN identifier
882 * 730 *
883 * Search the translation table for dst_addr and update the unicast header with 731 * Search the translation table for dst_addr and update the unicast header with
884 * the new corresponding information (originator address where the destination 732 * the new corresponding information (originator address where the destination
@@ -889,21 +737,22 @@ out:
889static bool 737static bool
890batadv_reroute_unicast_packet(struct batadv_priv *bat_priv, 738batadv_reroute_unicast_packet(struct batadv_priv *bat_priv,
891 struct batadv_unicast_packet *unicast_packet, 739 struct batadv_unicast_packet *unicast_packet,
892 uint8_t *dst_addr) 740 uint8_t *dst_addr, unsigned short vid)
893{ 741{
894 struct batadv_orig_node *orig_node = NULL; 742 struct batadv_orig_node *orig_node = NULL;
895 struct batadv_hard_iface *primary_if = NULL; 743 struct batadv_hard_iface *primary_if = NULL;
896 bool ret = false; 744 bool ret = false;
897 uint8_t *orig_addr, orig_ttvn; 745 uint8_t *orig_addr, orig_ttvn;
898 746
899 if (batadv_is_my_client(bat_priv, dst_addr)) { 747 if (batadv_is_my_client(bat_priv, dst_addr, vid)) {
900 primary_if = batadv_primary_if_get_selected(bat_priv); 748 primary_if = batadv_primary_if_get_selected(bat_priv);
901 if (!primary_if) 749 if (!primary_if)
902 goto out; 750 goto out;
903 orig_addr = primary_if->net_dev->dev_addr; 751 orig_addr = primary_if->net_dev->dev_addr;
904 orig_ttvn = (uint8_t)atomic_read(&bat_priv->tt.vn); 752 orig_ttvn = (uint8_t)atomic_read(&bat_priv->tt.vn);
905 } else { 753 } else {
906 orig_node = batadv_transtable_search(bat_priv, NULL, dst_addr); 754 orig_node = batadv_transtable_search(bat_priv, NULL, dst_addr,
755 vid);
907 if (!orig_node) 756 if (!orig_node)
908 goto out; 757 goto out;
909 758
@@ -930,11 +779,12 @@ out:
930 779
931static int batadv_check_unicast_ttvn(struct batadv_priv *bat_priv, 780static int batadv_check_unicast_ttvn(struct batadv_priv *bat_priv,
932 struct sk_buff *skb, int hdr_len) { 781 struct sk_buff *skb, int hdr_len) {
933 uint8_t curr_ttvn, old_ttvn; 782 struct batadv_unicast_packet *unicast_packet;
783 struct batadv_hard_iface *primary_if;
934 struct batadv_orig_node *orig_node; 784 struct batadv_orig_node *orig_node;
785 uint8_t curr_ttvn, old_ttvn;
935 struct ethhdr *ethhdr; 786 struct ethhdr *ethhdr;
936 struct batadv_hard_iface *primary_if; 787 unsigned short vid;
937 struct batadv_unicast_packet *unicast_packet;
938 int is_old_ttvn; 788 int is_old_ttvn;
939 789
940 /* check if there is enough data before accessing it */ 790 /* check if there is enough data before accessing it */
@@ -946,6 +796,7 @@ static int batadv_check_unicast_ttvn(struct batadv_priv *bat_priv,
946 return 0; 796 return 0;
947 797
948 unicast_packet = (struct batadv_unicast_packet *)skb->data; 798 unicast_packet = (struct batadv_unicast_packet *)skb->data;
799 vid = batadv_get_vid(skb, hdr_len);
949 ethhdr = (struct ethhdr *)(skb->data + hdr_len); 800 ethhdr = (struct ethhdr *)(skb->data + hdr_len);
950 801
951 /* check if the destination client was served by this node and it is now 802 /* check if the destination client was served by this node and it is now
@@ -953,9 +804,9 @@ static int batadv_check_unicast_ttvn(struct batadv_priv *bat_priv,
953 * message and that it knows the new destination in the mesh to re-route 804 * message and that it knows the new destination in the mesh to re-route
954 * the packet to 805 * the packet to
955 */ 806 */
956 if (batadv_tt_local_client_is_roaming(bat_priv, ethhdr->h_dest)) { 807 if (batadv_tt_local_client_is_roaming(bat_priv, ethhdr->h_dest, vid)) {
957 if (batadv_reroute_unicast_packet(bat_priv, unicast_packet, 808 if (batadv_reroute_unicast_packet(bat_priv, unicast_packet,
958 ethhdr->h_dest)) 809 ethhdr->h_dest, vid))
959 net_ratelimited_function(batadv_dbg, BATADV_DBG_TT, 810 net_ratelimited_function(batadv_dbg, BATADV_DBG_TT,
960 bat_priv, 811 bat_priv,
961 "Rerouting unicast packet to %pM (dst=%pM): Local Roaming\n", 812 "Rerouting unicast packet to %pM (dst=%pM): Local Roaming\n",
@@ -1001,7 +852,7 @@ static int batadv_check_unicast_ttvn(struct batadv_priv *bat_priv,
1001 * target host 852 * target host
1002 */ 853 */
1003 if (batadv_reroute_unicast_packet(bat_priv, unicast_packet, 854 if (batadv_reroute_unicast_packet(bat_priv, unicast_packet,
1004 ethhdr->h_dest)) { 855 ethhdr->h_dest, vid)) {
1005 net_ratelimited_function(batadv_dbg, BATADV_DBG_TT, bat_priv, 856 net_ratelimited_function(batadv_dbg, BATADV_DBG_TT, bat_priv,
1006 "Rerouting unicast packet to %pM (dst=%pM): TTVN mismatch old_ttvn=%u new_ttvn=%u\n", 857 "Rerouting unicast packet to %pM (dst=%pM): TTVN mismatch old_ttvn=%u new_ttvn=%u\n",
1007 unicast_packet->dest, ethhdr->h_dest, 858 unicast_packet->dest, ethhdr->h_dest,
@@ -1013,7 +864,7 @@ static int batadv_check_unicast_ttvn(struct batadv_priv *bat_priv,
1013 * currently served by this node or there is no destination at all and 864 * currently served by this node or there is no destination at all and
1014 * it is possible to drop the packet 865 * it is possible to drop the packet
1015 */ 866 */
1016 if (!batadv_is_my_client(bat_priv, ethhdr->h_dest)) 867 if (!batadv_is_my_client(bat_priv, ethhdr->h_dest, vid))
1017 return 0; 868 return 0;
1018 869
1019 /* update the header in order to let the packet be delivered to this 870 /* update the header in order to let the packet be delivered to this
@@ -1032,6 +883,34 @@ static int batadv_check_unicast_ttvn(struct batadv_priv *bat_priv,
1032 return 1; 883 return 1;
1033} 884}
1034 885
886/**
887 * batadv_recv_unhandled_unicast_packet - receive and process packets which
888 * are in the unicast number space but not yet known to the implementation
889 * @skb: unicast tvlv packet to process
890 * @recv_if: pointer to interface this packet was received on
891 *
892 * Returns NET_RX_SUCCESS if the packet has been consumed or NET_RX_DROP
893 * otherwise.
894 */
895int batadv_recv_unhandled_unicast_packet(struct sk_buff *skb,
896 struct batadv_hard_iface *recv_if)
897{
898 struct batadv_unicast_packet *unicast_packet;
899 struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface);
900 int check, hdr_size = sizeof(*unicast_packet);
901
902 check = batadv_check_unicast_packet(bat_priv, skb, hdr_size);
903 if (check < 0)
904 return NET_RX_DROP;
905
906 /* we don't know about this type, drop it. */
907 unicast_packet = (struct batadv_unicast_packet *)skb->data;
908 if (batadv_is_my_mac(bat_priv, unicast_packet->dest))
909 return NET_RX_DROP;
910
911 return batadv_route_unicast_packet(skb, recv_if);
912}
913
1035int batadv_recv_unicast_packet(struct sk_buff *skb, 914int batadv_recv_unicast_packet(struct sk_buff *skb,
1036 struct batadv_hard_iface *recv_if) 915 struct batadv_hard_iface *recv_if)
1037{ 916{
@@ -1094,51 +973,112 @@ rx_success:
1094 return batadv_route_unicast_packet(skb, recv_if); 973 return batadv_route_unicast_packet(skb, recv_if);
1095} 974}
1096 975
1097int batadv_recv_ucast_frag_packet(struct sk_buff *skb, 976/**
1098 struct batadv_hard_iface *recv_if) 977 * batadv_recv_unicast_tvlv - receive and process unicast tvlv packets
978 * @skb: unicast tvlv packet to process
979 * @recv_if: pointer to interface this packet was received on
980 * @dst_addr: the payload destination
981 *
982 * Returns NET_RX_SUCCESS if the packet has been consumed or NET_RX_DROP
983 * otherwise.
984 */
985int batadv_recv_unicast_tvlv(struct sk_buff *skb,
986 struct batadv_hard_iface *recv_if)
1099{ 987{
1100 struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface); 988 struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface);
1101 struct batadv_unicast_frag_packet *unicast_packet; 989 struct batadv_unicast_tvlv_packet *unicast_tvlv_packet;
1102 int hdr_size = sizeof(*unicast_packet); 990 unsigned char *tvlv_buff;
1103 struct sk_buff *new_skb = NULL; 991 uint16_t tvlv_buff_len;
1104 int ret; 992 int hdr_size = sizeof(*unicast_tvlv_packet);
993 int ret = NET_RX_DROP;
1105 994
1106 if (batadv_check_unicast_packet(bat_priv, skb, hdr_size) < 0) 995 if (batadv_check_unicast_packet(bat_priv, skb, hdr_size) < 0)
1107 return NET_RX_DROP; 996 return NET_RX_DROP;
1108 997
1109 if (!batadv_check_unicast_ttvn(bat_priv, skb, hdr_size)) 998 /* the header is likely to be modified while forwarding */
999 if (skb_cow(skb, hdr_size) < 0)
1110 return NET_RX_DROP; 1000 return NET_RX_DROP;
1111 1001
1112 unicast_packet = (struct batadv_unicast_frag_packet *)skb->data; 1002 /* packet needs to be linearized to access the tvlv content */
1003 if (skb_linearize(skb) < 0)
1004 return NET_RX_DROP;
1113 1005
1114 /* packet for me */ 1006 unicast_tvlv_packet = (struct batadv_unicast_tvlv_packet *)skb->data;
1115 if (batadv_is_my_mac(bat_priv, unicast_packet->dest)) {
1116 ret = batadv_frag_reassemble_skb(skb, bat_priv, &new_skb);
1117 1007
1118 if (ret == NET_RX_DROP) 1008 tvlv_buff = (unsigned char *)(skb->data + hdr_size);
1119 return NET_RX_DROP; 1009 tvlv_buff_len = ntohs(unicast_tvlv_packet->tvlv_len);
1120 1010
1121 /* packet was buffered for late merge */ 1011 if (tvlv_buff_len > skb->len - hdr_size)
1122 if (!new_skb) 1012 return NET_RX_DROP;
1123 return NET_RX_SUCCESS;
1124 1013
1125 if (batadv_dat_snoop_incoming_arp_request(bat_priv, new_skb, 1014 ret = batadv_tvlv_containers_process(bat_priv, false, NULL,
1126 hdr_size)) 1015 unicast_tvlv_packet->src,
1127 goto rx_success; 1016 unicast_tvlv_packet->dst,
1128 if (batadv_dat_snoop_incoming_arp_reply(bat_priv, new_skb, 1017 tvlv_buff, tvlv_buff_len);
1129 hdr_size))
1130 goto rx_success;
1131 1018
1132 batadv_interface_rx(recv_if->soft_iface, new_skb, recv_if, 1019 if (ret != NET_RX_SUCCESS)
1133 sizeof(struct batadv_unicast_packet), NULL); 1020 ret = batadv_route_unicast_packet(skb, recv_if);
1134 1021
1135rx_success: 1022 return ret;
1136 return NET_RX_SUCCESS; 1023}
1024
1025/**
1026 * batadv_recv_frag_packet - process received fragment
1027 * @skb: the received fragment
1028 * @recv_if: interface that the skb is received on
1029 *
1030 * This function does one of the three following things: 1) Forward fragment, if
1031 * the assembled packet will exceed our MTU; 2) Buffer fragment, if we till
1032 * lack further fragments; 3) Merge fragments, if we have all needed parts.
1033 *
1034 * Return NET_RX_DROP if the skb is not consumed, NET_RX_SUCCESS otherwise.
1035 */
1036int batadv_recv_frag_packet(struct sk_buff *skb,
1037 struct batadv_hard_iface *recv_if)
1038{
1039 struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface);
1040 struct batadv_orig_node *orig_node_src = NULL;
1041 struct batadv_frag_packet *frag_packet;
1042 int ret = NET_RX_DROP;
1043
1044 if (batadv_check_unicast_packet(bat_priv, skb,
1045 sizeof(*frag_packet)) < 0)
1046 goto out;
1047
1048 frag_packet = (struct batadv_frag_packet *)skb->data;
1049 orig_node_src = batadv_orig_hash_find(bat_priv, frag_packet->orig);
1050 if (!orig_node_src)
1051 goto out;
1052
1053 /* Route the fragment if it is not for us and too big to be merged. */
1054 if (!batadv_is_my_mac(bat_priv, frag_packet->dest) &&
1055 batadv_frag_skb_fwd(skb, recv_if, orig_node_src)) {
1056 ret = NET_RX_SUCCESS;
1057 goto out;
1137 } 1058 }
1138 1059
1139 return batadv_route_unicast_packet(skb, recv_if); 1060 batadv_inc_counter(bat_priv, BATADV_CNT_FRAG_RX);
1140} 1061 batadv_add_counter(bat_priv, BATADV_CNT_FRAG_RX_BYTES, skb->len);
1141 1062
1063 /* Add fragment to buffer and merge if possible. */
1064 if (!batadv_frag_skb_buffer(&skb, orig_node_src))
1065 goto out;
1066
1067 /* Deliver merged packet to the appropriate handler, if it was
1068 * merged
1069 */
1070 if (skb)
1071 batadv_batman_skb_recv(skb, recv_if->net_dev,
1072 &recv_if->batman_adv_ptype, NULL);
1073
1074 ret = NET_RX_SUCCESS;
1075
1076out:
1077 if (orig_node_src)
1078 batadv_orig_node_free_ref(orig_node_src);
1079
1080 return ret;
1081}
1142 1082
1143int batadv_recv_bcast_packet(struct sk_buff *skb, 1083int batadv_recv_bcast_packet(struct sk_buff *skb,
1144 struct batadv_hard_iface *recv_if) 1084 struct batadv_hard_iface *recv_if)
@@ -1240,53 +1180,3 @@ out:
1240 batadv_orig_node_free_ref(orig_node); 1180 batadv_orig_node_free_ref(orig_node);
1241 return ret; 1181 return ret;
1242} 1182}
1243
1244int batadv_recv_vis_packet(struct sk_buff *skb,
1245 struct batadv_hard_iface *recv_if)
1246{
1247 struct batadv_vis_packet *vis_packet;
1248 struct ethhdr *ethhdr;
1249 struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface);
1250 int hdr_size = sizeof(*vis_packet);
1251
1252 /* keep skb linear */
1253 if (skb_linearize(skb) < 0)
1254 return NET_RX_DROP;
1255
1256 if (unlikely(!pskb_may_pull(skb, hdr_size)))
1257 return NET_RX_DROP;
1258
1259 vis_packet = (struct batadv_vis_packet *)skb->data;
1260 ethhdr = eth_hdr(skb);
1261
1262 /* not for me */
1263 if (!batadv_is_my_mac(bat_priv, ethhdr->h_dest))
1264 return NET_RX_DROP;
1265
1266 /* ignore own packets */
1267 if (batadv_is_my_mac(bat_priv, vis_packet->vis_orig))
1268 return NET_RX_DROP;
1269
1270 if (batadv_is_my_mac(bat_priv, vis_packet->sender_orig))
1271 return NET_RX_DROP;
1272
1273 switch (vis_packet->vis_type) {
1274 case BATADV_VIS_TYPE_SERVER_SYNC:
1275 batadv_receive_server_sync_packet(bat_priv, vis_packet,
1276 skb_headlen(skb));
1277 break;
1278
1279 case BATADV_VIS_TYPE_CLIENT_UPDATE:
1280 batadv_receive_client_update_packet(bat_priv, vis_packet,
1281 skb_headlen(skb));
1282 break;
1283
1284 default: /* ignore unknown packet */
1285 break;
1286 }
1287
1288 /* We take a copy of the data in the packet, so we should
1289 * always free the skbuf.
1290 */
1291 return NET_RX_DROP;
1292}
diff --git a/net/batman-adv/routing.h b/net/batman-adv/routing.h
index 72a29bde2010..55d637a90621 100644
--- a/net/batman-adv/routing.h
+++ b/net/batman-adv/routing.h
@@ -30,16 +30,18 @@ int batadv_recv_icmp_packet(struct sk_buff *skb,
30 struct batadv_hard_iface *recv_if); 30 struct batadv_hard_iface *recv_if);
31int batadv_recv_unicast_packet(struct sk_buff *skb, 31int batadv_recv_unicast_packet(struct sk_buff *skb,
32 struct batadv_hard_iface *recv_if); 32 struct batadv_hard_iface *recv_if);
33int batadv_recv_ucast_frag_packet(struct sk_buff *skb, 33int batadv_recv_frag_packet(struct sk_buff *skb,
34 struct batadv_hard_iface *recv_if); 34 struct batadv_hard_iface *iface);
35int batadv_recv_bcast_packet(struct sk_buff *skb, 35int batadv_recv_bcast_packet(struct sk_buff *skb,
36 struct batadv_hard_iface *recv_if); 36 struct batadv_hard_iface *recv_if);
37int batadv_recv_vis_packet(struct sk_buff *skb,
38 struct batadv_hard_iface *recv_if);
39int batadv_recv_tt_query(struct sk_buff *skb, 37int batadv_recv_tt_query(struct sk_buff *skb,
40 struct batadv_hard_iface *recv_if); 38 struct batadv_hard_iface *recv_if);
41int batadv_recv_roam_adv(struct sk_buff *skb, 39int batadv_recv_roam_adv(struct sk_buff *skb,
42 struct batadv_hard_iface *recv_if); 40 struct batadv_hard_iface *recv_if);
41int batadv_recv_unicast_tvlv(struct sk_buff *skb,
42 struct batadv_hard_iface *recv_if);
43int batadv_recv_unhandled_unicast_packet(struct sk_buff *skb,
44 struct batadv_hard_iface *recv_if);
43struct batadv_neigh_node * 45struct batadv_neigh_node *
44batadv_find_router(struct batadv_priv *bat_priv, 46batadv_find_router(struct batadv_priv *bat_priv,
45 struct batadv_orig_node *orig_node, 47 struct batadv_orig_node *orig_node,
diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c
index 0266edd0fa7f..c83be5ebaa28 100644
--- a/net/batman-adv/send.c
+++ b/net/batman-adv/send.c
@@ -24,12 +24,11 @@
24#include "translation-table.h" 24#include "translation-table.h"
25#include "soft-interface.h" 25#include "soft-interface.h"
26#include "hard-interface.h" 26#include "hard-interface.h"
27#include "vis.h"
28#include "gateway_common.h" 27#include "gateway_common.h"
28#include "gateway_client.h"
29#include "originator.h" 29#include "originator.h"
30#include "network-coding.h" 30#include "network-coding.h"
31 31#include "fragmentation.h"
32#include <linux/if_ether.h>
33 32
34static void batadv_send_outstanding_bcast_packet(struct work_struct *work); 33static void batadv_send_outstanding_bcast_packet(struct work_struct *work);
35 34
@@ -64,10 +63,10 @@ int batadv_send_skb_packet(struct sk_buff *skb,
64 ethhdr = eth_hdr(skb); 63 ethhdr = eth_hdr(skb);
65 memcpy(ethhdr->h_source, hard_iface->net_dev->dev_addr, ETH_ALEN); 64 memcpy(ethhdr->h_source, hard_iface->net_dev->dev_addr, ETH_ALEN);
66 memcpy(ethhdr->h_dest, dst_addr, ETH_ALEN); 65 memcpy(ethhdr->h_dest, dst_addr, ETH_ALEN);
67 ethhdr->h_proto = __constant_htons(ETH_P_BATMAN); 66 ethhdr->h_proto = htons(ETH_P_BATMAN);
68 67
69 skb_set_network_header(skb, ETH_HLEN); 68 skb_set_network_header(skb, ETH_HLEN);
70 skb->protocol = __constant_htons(ETH_P_BATMAN); 69 skb->protocol = htons(ETH_P_BATMAN);
71 70
72 skb->dev = hard_iface->net_dev; 71 skb->dev = hard_iface->net_dev;
73 72
@@ -109,7 +108,19 @@ int batadv_send_skb_to_orig(struct sk_buff *skb,
109 /* batadv_find_router() increases neigh_nodes refcount if found. */ 108 /* batadv_find_router() increases neigh_nodes refcount if found. */
110 neigh_node = batadv_find_router(bat_priv, orig_node, recv_if); 109 neigh_node = batadv_find_router(bat_priv, orig_node, recv_if);
111 if (!neigh_node) 110 if (!neigh_node)
112 return ret; 111 goto out;
112
113 /* Check if the skb is too large to send in one piece and fragment
114 * it if needed.
115 */
116 if (atomic_read(&bat_priv->fragmentation) &&
117 skb->len > neigh_node->if_incoming->net_dev->mtu) {
118 /* Fragment and send packet. */
119 if (batadv_frag_send_packet(skb, orig_node, neigh_node))
120 ret = NET_XMIT_SUCCESS;
121
122 goto out;
123 }
113 124
114 /* try to network code the packet, if it is received on an interface 125 /* try to network code the packet, if it is received on an interface
115 * (i.e. being forwarded). If the packet originates from this node or if 126 * (i.e. being forwarded). If the packet originates from this node or if
@@ -123,11 +134,225 @@ int batadv_send_skb_to_orig(struct sk_buff *skb,
123 ret = NET_XMIT_SUCCESS; 134 ret = NET_XMIT_SUCCESS;
124 } 135 }
125 136
126 batadv_neigh_node_free_ref(neigh_node); 137out:
138 if (neigh_node)
139 batadv_neigh_node_free_ref(neigh_node);
140
141 return ret;
142}
143
144/**
145 * batadv_send_skb_push_fill_unicast - extend the buffer and initialize the
146 * common fields for unicast packets
147 * @skb: the skb carrying the unicast header to initialize
148 * @hdr_size: amount of bytes to push at the beginning of the skb
149 * @orig_node: the destination node
150 *
151 * Returns false if the buffer extension was not possible or true otherwise.
152 */
153static bool
154batadv_send_skb_push_fill_unicast(struct sk_buff *skb, int hdr_size,
155 struct batadv_orig_node *orig_node)
156{
157 struct batadv_unicast_packet *unicast_packet;
158 uint8_t ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn);
159
160 if (batadv_skb_head_push(skb, hdr_size) < 0)
161 return false;
162
163 unicast_packet = (struct batadv_unicast_packet *)skb->data;
164 unicast_packet->header.version = BATADV_COMPAT_VERSION;
165 /* batman packet type: unicast */
166 unicast_packet->header.packet_type = BATADV_UNICAST;
167 /* set unicast ttl */
168 unicast_packet->header.ttl = BATADV_TTL;
169 /* copy the destination for faster routing */
170 memcpy(unicast_packet->dest, orig_node->orig, ETH_ALEN);
171 /* set the destination tt version number */
172 unicast_packet->ttvn = ttvn;
173
174 return true;
175}
176
177/**
178 * batadv_send_skb_prepare_unicast - encapsulate an skb with a unicast header
179 * @skb: the skb containing the payload to encapsulate
180 * @orig_node: the destination node
181 *
182 * Returns false if the payload could not be encapsulated or true otherwise.
183 */
184static bool batadv_send_skb_prepare_unicast(struct sk_buff *skb,
185 struct batadv_orig_node *orig_node)
186{
187 size_t uni_size = sizeof(struct batadv_unicast_packet);
188
189 return batadv_send_skb_push_fill_unicast(skb, uni_size, orig_node);
190}
191
192/**
193 * batadv_send_skb_prepare_unicast_4addr - encapsulate an skb with a
194 * unicast 4addr header
195 * @bat_priv: the bat priv with all the soft interface information
196 * @skb: the skb containing the payload to encapsulate
197 * @orig_node: the destination node
198 * @packet_subtype: the unicast 4addr packet subtype to use
199 *
200 * Returns false if the payload could not be encapsulated or true otherwise.
201 */
202bool batadv_send_skb_prepare_unicast_4addr(struct batadv_priv *bat_priv,
203 struct sk_buff *skb,
204 struct batadv_orig_node *orig,
205 int packet_subtype)
206{
207 struct batadv_hard_iface *primary_if;
208 struct batadv_unicast_4addr_packet *uc_4addr_packet;
209 bool ret = false;
210
211 primary_if = batadv_primary_if_get_selected(bat_priv);
212 if (!primary_if)
213 goto out;
214
215 /* Pull the header space and fill the unicast_packet substructure.
216 * We can do that because the first member of the uc_4addr_packet
217 * is of type struct unicast_packet
218 */
219 if (!batadv_send_skb_push_fill_unicast(skb, sizeof(*uc_4addr_packet),
220 orig))
221 goto out;
222
223 uc_4addr_packet = (struct batadv_unicast_4addr_packet *)skb->data;
224 uc_4addr_packet->u.header.packet_type = BATADV_UNICAST_4ADDR;
225 memcpy(uc_4addr_packet->src, primary_if->net_dev->dev_addr, ETH_ALEN);
226 uc_4addr_packet->subtype = packet_subtype;
227 uc_4addr_packet->reserved = 0;
228
229 ret = true;
230out:
231 if (primary_if)
232 batadv_hardif_free_ref(primary_if);
233 return ret;
234}
235
236/**
237 * batadv_send_skb_unicast - encapsulate and send an skb via unicast
238 * @bat_priv: the bat priv with all the soft interface information
239 * @skb: payload to send
240 * @packet_type: the batman unicast packet type to use
241 * @packet_subtype: the unicast 4addr packet subtype (only relevant for unicast
242 * 4addr packets)
243 * @orig_node: the originator to send the packet to
244 * @vid: the vid to be used to search the translation table
245 *
246 * Wrap the given skb into a batman-adv unicast or unicast-4addr header
247 * depending on whether BATADV_UNICAST or BATADV_UNICAST_4ADDR was supplied
248 * as packet_type. Then send this frame to the given orig_node and release a
249 * reference to this orig_node.
250 *
251 * Returns NET_XMIT_DROP in case of error or NET_XMIT_SUCCESS otherwise.
252 */
253static int batadv_send_skb_unicast(struct batadv_priv *bat_priv,
254 struct sk_buff *skb, int packet_type,
255 int packet_subtype,
256 struct batadv_orig_node *orig_node,
257 unsigned short vid)
258{
259 struct ethhdr *ethhdr = (struct ethhdr *)skb->data;
260 struct batadv_unicast_packet *unicast_packet;
261 int ret = NET_XMIT_DROP;
262
263 if (!orig_node)
264 goto out;
265
266 switch (packet_type) {
267 case BATADV_UNICAST:
268 if (!batadv_send_skb_prepare_unicast(skb, orig_node))
269 goto out;
270 break;
271 case BATADV_UNICAST_4ADDR:
272 if (!batadv_send_skb_prepare_unicast_4addr(bat_priv, skb,
273 orig_node,
274 packet_subtype))
275 goto out;
276 break;
277 default:
278 /* this function supports UNICAST and UNICAST_4ADDR only. It
279 * should never be invoked with any other packet type
280 */
281 goto out;
282 }
283
284 unicast_packet = (struct batadv_unicast_packet *)skb->data;
285
286 /* inform the destination node that we are still missing a correct route
287 * for this client. The destination will receive this packet and will
288 * try to reroute it because the ttvn contained in the header is less
289 * than the current one
290 */
291 if (batadv_tt_global_client_is_roaming(bat_priv, ethhdr->h_dest, vid))
292 unicast_packet->ttvn = unicast_packet->ttvn - 1;
127 293
294 if (batadv_send_skb_to_orig(skb, orig_node, NULL) != NET_XMIT_DROP)
295 ret = NET_XMIT_SUCCESS;
296
297out:
298 if (orig_node)
299 batadv_orig_node_free_ref(orig_node);
300 if (ret == NET_XMIT_DROP)
301 kfree_skb(skb);
128 return ret; 302 return ret;
129} 303}
130 304
305/**
306 * batadv_send_skb_via_tt_generic - send an skb via TT lookup
307 * @bat_priv: the bat priv with all the soft interface information
308 * @skb: payload to send
309 * @packet_type: the batman unicast packet type to use
310 * @packet_subtype: the unicast 4addr packet subtype (only relevant for unicast
311 * 4addr packets)
312 * @vid: the vid to be used to search the translation table
313 *
314 * Look up the recipient node for the destination address in the ethernet
315 * header via the translation table. Wrap the given skb into a batman-adv
316 * unicast or unicast-4addr header depending on whether BATADV_UNICAST or
317 * BATADV_UNICAST_4ADDR was supplied as packet_type. Then send this frame
318 * to the according destination node.
319 *
320 * Returns NET_XMIT_DROP in case of error or NET_XMIT_SUCCESS otherwise.
321 */
322int batadv_send_skb_via_tt_generic(struct batadv_priv *bat_priv,
323 struct sk_buff *skb, int packet_type,
324 int packet_subtype, unsigned short vid)
325{
326 struct ethhdr *ethhdr = (struct ethhdr *)skb->data;
327 struct batadv_orig_node *orig_node;
328
329 orig_node = batadv_transtable_search(bat_priv, ethhdr->h_source,
330 ethhdr->h_dest, vid);
331 return batadv_send_skb_unicast(bat_priv, skb, packet_type,
332 packet_subtype, orig_node, vid);
333}
334
335/**
336 * batadv_send_skb_via_gw - send an skb via gateway lookup
337 * @bat_priv: the bat priv with all the soft interface information
338 * @skb: payload to send
339 * @vid: the vid to be used to search the translation table
340 *
341 * Look up the currently selected gateway. Wrap the given skb into a batman-adv
342 * unicast header and send this frame to this gateway node.
343 *
344 * Returns NET_XMIT_DROP in case of error or NET_XMIT_SUCCESS otherwise.
345 */
346int batadv_send_skb_via_gw(struct batadv_priv *bat_priv, struct sk_buff *skb,
347 unsigned short vid)
348{
349 struct batadv_orig_node *orig_node;
350
351 orig_node = batadv_gw_get_selected_orig(bat_priv);
352 return batadv_send_skb_unicast(bat_priv, skb, BATADV_UNICAST, 0,
353 orig_node, vid);
354}
355
131void batadv_schedule_bat_ogm(struct batadv_hard_iface *hard_iface) 356void batadv_schedule_bat_ogm(struct batadv_hard_iface *hard_iface)
132{ 357{
133 struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface); 358 struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
diff --git a/net/batman-adv/send.h b/net/batman-adv/send.h
index e7b17880fca4..aa2e2537a739 100644
--- a/net/batman-adv/send.h
+++ b/net/batman-adv/send.h
@@ -34,5 +34,58 @@ void batadv_send_outstanding_bat_ogm_packet(struct work_struct *work);
34void 34void
35batadv_purge_outstanding_packets(struct batadv_priv *bat_priv, 35batadv_purge_outstanding_packets(struct batadv_priv *bat_priv,
36 const struct batadv_hard_iface *hard_iface); 36 const struct batadv_hard_iface *hard_iface);
37bool batadv_send_skb_prepare_unicast_4addr(struct batadv_priv *bat_priv,
38 struct sk_buff *skb,
39 struct batadv_orig_node *orig_node,
40 int packet_subtype);
41int batadv_send_skb_via_tt_generic(struct batadv_priv *bat_priv,
42 struct sk_buff *skb, int packet_type,
43 int packet_subtype, unsigned short vid);
44int batadv_send_skb_via_gw(struct batadv_priv *bat_priv, struct sk_buff *skb,
45 unsigned short vid);
46
47/**
48 * batadv_send_skb_via_tt - send an skb via TT lookup
49 * @bat_priv: the bat priv with all the soft interface information
50 * @skb: the payload to send
51 * @vid: the vid to be used to search the translation table
52 *
53 * Look up the recipient node for the destination address in the ethernet
54 * header via the translation table. Wrap the given skb into a batman-adv
55 * unicast header. Then send this frame to the according destination node.
56 *
57 * Returns NET_XMIT_DROP in case of error or NET_XMIT_SUCCESS otherwise.
58 */
59static inline int batadv_send_skb_via_tt(struct batadv_priv *bat_priv,
60 struct sk_buff *skb,
61 unsigned short vid)
62{
63 return batadv_send_skb_via_tt_generic(bat_priv, skb, BATADV_UNICAST, 0,
64 vid);
65}
66
67/**
68 * batadv_send_skb_via_tt_4addr - send an skb via TT lookup
69 * @bat_priv: the bat priv with all the soft interface information
70 * @skb: the payload to send
71 * @packet_subtype: the unicast 4addr packet subtype to use
72 * @vid: the vid to be used to search the translation table
73 *
74 * Look up the recipient node for the destination address in the ethernet
75 * header via the translation table. Wrap the given skb into a batman-adv
76 * unicast-4addr header. Then send this frame to the according destination
77 * node.
78 *
79 * Returns NET_XMIT_DROP in case of error or NET_XMIT_SUCCESS otherwise.
80 */
81static inline int batadv_send_skb_via_tt_4addr(struct batadv_priv *bat_priv,
82 struct sk_buff *skb,
83 int packet_subtype,
84 unsigned short vid)
85{
86 return batadv_send_skb_via_tt_generic(bat_priv, skb,
87 BATADV_UNICAST_4ADDR,
88 packet_subtype, vid);
89}
37 90
38#endif /* _NET_BATMAN_ADV_SEND_H_ */ 91#endif /* _NET_BATMAN_ADV_SEND_H_ */
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
index 813db4e64602..e70f530d8568 100644
--- a/net/batman-adv/soft-interface.c
+++ b/net/batman-adv/soft-interface.c
@@ -34,8 +34,6 @@
34#include <linux/ethtool.h> 34#include <linux/ethtool.h>
35#include <linux/etherdevice.h> 35#include <linux/etherdevice.h>
36#include <linux/if_vlan.h> 36#include <linux/if_vlan.h>
37#include <linux/if_ether.h>
38#include "unicast.h"
39#include "bridge_loop_avoidance.h" 37#include "bridge_loop_avoidance.h"
40#include "network-coding.h" 38#include "network-coding.h"
41 39
@@ -120,9 +118,10 @@ static int batadv_interface_set_mac_addr(struct net_device *dev, void *p)
120 118
121 /* only modify transtable if it has been initialized before */ 119 /* only modify transtable if it has been initialized before */
122 if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_ACTIVE) { 120 if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_ACTIVE) {
123 batadv_tt_local_remove(bat_priv, old_addr, 121 batadv_tt_local_remove(bat_priv, old_addr, BATADV_NO_FLAGS,
124 "mac address changed", false); 122 "mac address changed", false);
125 batadv_tt_local_add(dev, addr->sa_data, BATADV_NULL_IFINDEX); 123 batadv_tt_local_add(dev, addr->sa_data, BATADV_NO_FLAGS,
124 BATADV_NULL_IFINDEX);
126 } 125 }
127 126
128 return 0; 127 return 0;
@@ -139,36 +138,48 @@ static int batadv_interface_change_mtu(struct net_device *dev, int new_mtu)
139 return 0; 138 return 0;
140} 139}
141 140
141/**
142 * batadv_interface_set_rx_mode - set the rx mode of a device
143 * @dev: registered network device to modify
144 *
145 * We do not actually need to set any rx filters for the virtual batman
146 * soft interface. However a dummy handler enables a user to set static
147 * multicast listeners for instance.
148 */
149static void batadv_interface_set_rx_mode(struct net_device *dev)
150{
151}
152
142static int batadv_interface_tx(struct sk_buff *skb, 153static int batadv_interface_tx(struct sk_buff *skb,
143 struct net_device *soft_iface) 154 struct net_device *soft_iface)
144{ 155{
145 struct ethhdr *ethhdr = (struct ethhdr *)skb->data; 156 struct ethhdr *ethhdr;
146 struct batadv_priv *bat_priv = netdev_priv(soft_iface); 157 struct batadv_priv *bat_priv = netdev_priv(soft_iface);
147 struct batadv_hard_iface *primary_if = NULL; 158 struct batadv_hard_iface *primary_if = NULL;
148 struct batadv_bcast_packet *bcast_packet; 159 struct batadv_bcast_packet *bcast_packet;
149 struct vlan_ethhdr *vhdr; 160 __be16 ethertype = htons(ETH_P_BATMAN);
150 __be16 ethertype = __constant_htons(ETH_P_BATMAN);
151 static const uint8_t stp_addr[ETH_ALEN] = {0x01, 0x80, 0xC2, 0x00, 161 static const uint8_t stp_addr[ETH_ALEN] = {0x01, 0x80, 0xC2, 0x00,
152 0x00, 0x00}; 162 0x00, 0x00};
153 static const uint8_t ectp_addr[ETH_ALEN] = {0xCF, 0x00, 0x00, 0x00, 163 static const uint8_t ectp_addr[ETH_ALEN] = {0xCF, 0x00, 0x00, 0x00,
154 0x00, 0x00}; 164 0x00, 0x00};
165 struct vlan_ethhdr *vhdr;
155 unsigned int header_len = 0; 166 unsigned int header_len = 0;
156 int data_len = skb->len, ret; 167 int data_len = skb->len, ret;
157 unsigned short vid __maybe_unused = BATADV_NO_FLAGS; 168 unsigned long brd_delay = 1;
158 bool do_bcast = false; 169 bool do_bcast = false;
170 unsigned short vid;
159 uint32_t seqno; 171 uint32_t seqno;
160 unsigned long brd_delay = 1;
161 172
162 if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE) 173 if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE)
163 goto dropped; 174 goto dropped;
164 175
165 soft_iface->trans_start = jiffies; 176 soft_iface->trans_start = jiffies;
177 vid = batadv_get_vid(skb, 0);
178 ethhdr = (struct ethhdr *)skb->data;
166 179
167 switch (ntohs(ethhdr->h_proto)) { 180 switch (ntohs(ethhdr->h_proto)) {
168 case ETH_P_8021Q: 181 case ETH_P_8021Q:
169 vhdr = (struct vlan_ethhdr *)skb->data; 182 vhdr = (struct vlan_ethhdr *)skb->data;
170 vid = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK;
171 vid |= BATADV_VLAN_HAS_TAG;
172 183
173 if (vhdr->h_vlan_encapsulated_proto != ethertype) 184 if (vhdr->h_vlan_encapsulated_proto != ethertype)
174 break; 185 break;
@@ -186,7 +197,8 @@ static int batadv_interface_tx(struct sk_buff *skb,
186 197
187 /* Register the client MAC in the transtable */ 198 /* Register the client MAC in the transtable */
188 if (!is_multicast_ether_addr(ethhdr->h_source)) 199 if (!is_multicast_ether_addr(ethhdr->h_source))
189 batadv_tt_local_add(soft_iface, ethhdr->h_source, skb->skb_iif); 200 batadv_tt_local_add(soft_iface, ethhdr->h_source, vid,
201 skb->skb_iif);
190 202
191 /* don't accept stp packets. STP does not help in meshes. 203 /* don't accept stp packets. STP does not help in meshes.
192 * better use the bridge loop avoidance ... 204 * better use the bridge loop avoidance ...
@@ -286,8 +298,12 @@ static int batadv_interface_tx(struct sk_buff *skb,
286 298
287 batadv_dat_snoop_outgoing_arp_reply(bat_priv, skb); 299 batadv_dat_snoop_outgoing_arp_reply(bat_priv, skb);
288 300
289 ret = batadv_unicast_send_skb(bat_priv, skb); 301 if (is_multicast_ether_addr(ethhdr->h_dest))
290 if (ret != 0) 302 ret = batadv_send_skb_via_gw(bat_priv, skb, vid);
303 else
304 ret = batadv_send_skb_via_tt(bat_priv, skb, vid);
305
306 if (ret == NET_XMIT_DROP)
291 goto dropped_freed; 307 goto dropped_freed;
292 } 308 }
293 309
@@ -309,12 +325,12 @@ void batadv_interface_rx(struct net_device *soft_iface,
309 struct sk_buff *skb, struct batadv_hard_iface *recv_if, 325 struct sk_buff *skb, struct batadv_hard_iface *recv_if,
310 int hdr_size, struct batadv_orig_node *orig_node) 326 int hdr_size, struct batadv_orig_node *orig_node)
311{ 327{
328 struct batadv_header *batadv_header = (struct batadv_header *)skb->data;
312 struct batadv_priv *bat_priv = netdev_priv(soft_iface); 329 struct batadv_priv *bat_priv = netdev_priv(soft_iface);
313 struct ethhdr *ethhdr; 330 __be16 ethertype = htons(ETH_P_BATMAN);
314 struct vlan_ethhdr *vhdr; 331 struct vlan_ethhdr *vhdr;
315 struct batadv_header *batadv_header = (struct batadv_header *)skb->data; 332 struct ethhdr *ethhdr;
316 unsigned short vid __maybe_unused = BATADV_NO_FLAGS; 333 unsigned short vid;
317 __be16 ethertype = __constant_htons(ETH_P_BATMAN);
318 bool is_bcast; 334 bool is_bcast;
319 335
320 is_bcast = (batadv_header->packet_type == BATADV_BCAST); 336 is_bcast = (batadv_header->packet_type == BATADV_BCAST);
@@ -326,13 +342,12 @@ void batadv_interface_rx(struct net_device *soft_iface,
326 skb_pull_rcsum(skb, hdr_size); 342 skb_pull_rcsum(skb, hdr_size);
327 skb_reset_mac_header(skb); 343 skb_reset_mac_header(skb);
328 344
345 vid = batadv_get_vid(skb, hdr_size);
329 ethhdr = eth_hdr(skb); 346 ethhdr = eth_hdr(skb);
330 347
331 switch (ntohs(ethhdr->h_proto)) { 348 switch (ntohs(ethhdr->h_proto)) {
332 case ETH_P_8021Q: 349 case ETH_P_8021Q:
333 vhdr = (struct vlan_ethhdr *)skb->data; 350 vhdr = (struct vlan_ethhdr *)skb->data;
334 vid = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK;
335 vid |= BATADV_VLAN_HAS_TAG;
336 351
337 if (vhdr->h_vlan_encapsulated_proto != ethertype) 352 if (vhdr->h_vlan_encapsulated_proto != ethertype)
338 break; 353 break;
@@ -368,9 +383,10 @@ void batadv_interface_rx(struct net_device *soft_iface,
368 383
369 if (orig_node) 384 if (orig_node)
370 batadv_tt_add_temporary_global_entry(bat_priv, orig_node, 385 batadv_tt_add_temporary_global_entry(bat_priv, orig_node,
371 ethhdr->h_source); 386 ethhdr->h_source, vid);
372 387
373 if (batadv_is_ap_isolated(bat_priv, ethhdr->h_source, ethhdr->h_dest)) 388 if (batadv_is_ap_isolated(bat_priv, ethhdr->h_source, ethhdr->h_dest,
389 vid))
374 goto dropped; 390 goto dropped;
375 391
376 netif_rx(skb); 392 netif_rx(skb);
@@ -382,6 +398,177 @@ out:
382 return; 398 return;
383} 399}
384 400
401/**
402 * batadv_softif_vlan_free_ref - decrease the vlan object refcounter and
403 * possibly free it
404 * @softif_vlan: the vlan object to release
405 */
406void batadv_softif_vlan_free_ref(struct batadv_softif_vlan *softif_vlan)
407{
408 if (atomic_dec_and_test(&softif_vlan->refcount))
409 kfree_rcu(softif_vlan, rcu);
410}
411
412/**
413 * batadv_softif_vlan_get - get the vlan object for a specific vid
414 * @bat_priv: the bat priv with all the soft interface information
415 * @vid: the identifier of the vlan object to retrieve
416 *
417 * Returns the private data of the vlan matching the vid passed as argument or
418 * NULL otherwise. The refcounter of the returned object is incremented by 1.
419 */
420struct batadv_softif_vlan *batadv_softif_vlan_get(struct batadv_priv *bat_priv,
421 unsigned short vid)
422{
423 struct batadv_softif_vlan *vlan_tmp, *vlan = NULL;
424
425 rcu_read_lock();
426 hlist_for_each_entry_rcu(vlan_tmp, &bat_priv->softif_vlan_list, list) {
427 if (vlan_tmp->vid != vid)
428 continue;
429
430 if (!atomic_inc_not_zero(&vlan_tmp->refcount))
431 continue;
432
433 vlan = vlan_tmp;
434 break;
435 }
436 rcu_read_unlock();
437
438 return vlan;
439}
440
441/**
442 * batadv_create_vlan - allocate the needed resources for a new vlan
443 * @bat_priv: the bat priv with all the soft interface information
444 * @vid: the VLAN identifier
445 *
446 * Returns 0 on success, a negative error otherwise.
447 */
448int batadv_softif_create_vlan(struct batadv_priv *bat_priv, unsigned short vid)
449{
450 struct batadv_softif_vlan *vlan;
451 int err;
452
453 vlan = batadv_softif_vlan_get(bat_priv, vid);
454 if (vlan) {
455 batadv_softif_vlan_free_ref(vlan);
456 return -EEXIST;
457 }
458
459 vlan = kzalloc(sizeof(*vlan), GFP_ATOMIC);
460 if (!vlan)
461 return -ENOMEM;
462
463 vlan->vid = vid;
464 atomic_set(&vlan->refcount, 1);
465
466 atomic_set(&vlan->ap_isolation, 0);
467
468 err = batadv_sysfs_add_vlan(bat_priv->soft_iface, vlan);
469 if (err) {
470 kfree(vlan);
471 return err;
472 }
473
474 /* add a new TT local entry. This one will be marked with the NOPURGE
475 * flag
476 */
477 batadv_tt_local_add(bat_priv->soft_iface,
478 bat_priv->soft_iface->dev_addr, vid,
479 BATADV_NULL_IFINDEX);
480
481 spin_lock_bh(&bat_priv->softif_vlan_list_lock);
482 hlist_add_head_rcu(&vlan->list, &bat_priv->softif_vlan_list);
483 spin_unlock_bh(&bat_priv->softif_vlan_list_lock);
484
485 return 0;
486}
487
488/**
489 * batadv_softif_destroy_vlan - remove and destroy a softif_vlan object
490 * @bat_priv: the bat priv with all the soft interface information
491 * @vlan: the object to remove
492 */
493static void batadv_softif_destroy_vlan(struct batadv_priv *bat_priv,
494 struct batadv_softif_vlan *vlan)
495{
496 spin_lock_bh(&bat_priv->softif_vlan_list_lock);
497 hlist_del_rcu(&vlan->list);
498 spin_unlock_bh(&bat_priv->softif_vlan_list_lock);
499
500 batadv_sysfs_del_vlan(bat_priv, vlan);
501
502 /* explicitly remove the associated TT local entry because it is marked
503 * with the NOPURGE flag
504 */
505 batadv_tt_local_remove(bat_priv, bat_priv->soft_iface->dev_addr,
506 vlan->vid, "vlan interface destroyed", false);
507
508 batadv_softif_vlan_free_ref(vlan);
509}
510
511/**
512 * batadv_interface_add_vid - ndo_add_vid API implementation
513 * @dev: the netdev of the mesh interface
514 * @vid: identifier of the new vlan
515 *
516 * Set up all the internal structures for handling the new vlan on top of the
517 * mesh interface
518 *
519 * Returns 0 on success or a negative error code in case of failure.
520 */
521static int batadv_interface_add_vid(struct net_device *dev, __be16 proto,
522 unsigned short vid)
523{
524 struct batadv_priv *bat_priv = netdev_priv(dev);
525
526 /* only 802.1Q vlans are supported.
527 * batman-adv does not know how to handle other types
528 */
529 if (proto != htons(ETH_P_8021Q))
530 return -EINVAL;
531
532 vid |= BATADV_VLAN_HAS_TAG;
533
534 return batadv_softif_create_vlan(bat_priv, vid);
535}
536
537/**
538 * batadv_interface_kill_vid - ndo_kill_vid API implementation
539 * @dev: the netdev of the mesh interface
540 * @vid: identifier of the deleted vlan
541 *
542 * Destroy all the internal structures used to handle the vlan identified by vid
543 * on top of the mesh interface
544 *
545 * Returns 0 on success, -EINVAL if the specified prototype is not ETH_P_8021Q
546 * or -ENOENT if the specified vlan id wasn't registered.
547 */
548static int batadv_interface_kill_vid(struct net_device *dev, __be16 proto,
549 unsigned short vid)
550{
551 struct batadv_priv *bat_priv = netdev_priv(dev);
552 struct batadv_softif_vlan *vlan;
553
554 /* only 802.1Q vlans are supported. batman-adv does not know how to
555 * handle other types
556 */
557 if (proto != htons(ETH_P_8021Q))
558 return -EINVAL;
559
560 vlan = batadv_softif_vlan_get(bat_priv, vid | BATADV_VLAN_HAS_TAG);
561 if (!vlan)
562 return -ENOENT;
563
564 batadv_softif_destroy_vlan(bat_priv, vlan);
565
566 /* finally free the vlan object */
567 batadv_softif_vlan_free_ref(vlan);
568
569 return 0;
570}
571
385/* batman-adv network devices have devices nesting below it and are a special 572/* batman-adv network devices have devices nesting below it and are a special
386 * "super class" of normal network devices; split their locks off into a 573 * "super class" of normal network devices; split their locks off into a
387 * separate class since they always nest. 574 * separate class since they always nest.
@@ -421,6 +608,7 @@ static void batadv_set_lockdep_class(struct net_device *dev)
421 */ 608 */
422static void batadv_softif_destroy_finish(struct work_struct *work) 609static void batadv_softif_destroy_finish(struct work_struct *work)
423{ 610{
611 struct batadv_softif_vlan *vlan;
424 struct batadv_priv *bat_priv; 612 struct batadv_priv *bat_priv;
425 struct net_device *soft_iface; 613 struct net_device *soft_iface;
426 614
@@ -428,6 +616,13 @@ static void batadv_softif_destroy_finish(struct work_struct *work)
428 cleanup_work); 616 cleanup_work);
429 soft_iface = bat_priv->soft_iface; 617 soft_iface = bat_priv->soft_iface;
430 618
619 /* destroy the "untagged" VLAN */
620 vlan = batadv_softif_vlan_get(bat_priv, BATADV_NO_FLAGS);
621 if (vlan) {
622 batadv_softif_destroy_vlan(bat_priv, vlan);
623 batadv_softif_vlan_free_ref(vlan);
624 }
625
431 batadv_sysfs_del_meshif(soft_iface); 626 batadv_sysfs_del_meshif(soft_iface);
432 627
433 rtnl_lock(); 628 rtnl_lock();
@@ -444,6 +639,7 @@ static void batadv_softif_destroy_finish(struct work_struct *work)
444static int batadv_softif_init_late(struct net_device *dev) 639static int batadv_softif_init_late(struct net_device *dev)
445{ 640{
446 struct batadv_priv *bat_priv; 641 struct batadv_priv *bat_priv;
642 uint32_t random_seqno;
447 int ret; 643 int ret;
448 size_t cnt_len = sizeof(uint64_t) * BATADV_CNT_NUM; 644 size_t cnt_len = sizeof(uint64_t) * BATADV_CNT_NUM;
449 645
@@ -468,11 +664,10 @@ static int batadv_softif_init_late(struct net_device *dev)
468#ifdef CONFIG_BATMAN_ADV_DAT 664#ifdef CONFIG_BATMAN_ADV_DAT
469 atomic_set(&bat_priv->distributed_arp_table, 1); 665 atomic_set(&bat_priv->distributed_arp_table, 1);
470#endif 666#endif
471 atomic_set(&bat_priv->ap_isolation, 0);
472 atomic_set(&bat_priv->vis_mode, BATADV_VIS_TYPE_CLIENT_UPDATE);
473 atomic_set(&bat_priv->gw_mode, BATADV_GW_MODE_OFF); 667 atomic_set(&bat_priv->gw_mode, BATADV_GW_MODE_OFF);
474 atomic_set(&bat_priv->gw_sel_class, 20); 668 atomic_set(&bat_priv->gw_sel_class, 20);
475 atomic_set(&bat_priv->gw_bandwidth, 41); 669 atomic_set(&bat_priv->gw.bandwidth_down, 100);
670 atomic_set(&bat_priv->gw.bandwidth_up, 20);
476 atomic_set(&bat_priv->orig_interval, 1000); 671 atomic_set(&bat_priv->orig_interval, 1000);
477 atomic_set(&bat_priv->hop_penalty, 30); 672 atomic_set(&bat_priv->hop_penalty, 30);
478#ifdef CONFIG_BATMAN_ADV_DEBUG 673#ifdef CONFIG_BATMAN_ADV_DEBUG
@@ -493,6 +688,10 @@ static int batadv_softif_init_late(struct net_device *dev)
493 bat_priv->tt.last_changeset = NULL; 688 bat_priv->tt.last_changeset = NULL;
494 bat_priv->tt.last_changeset_len = 0; 689 bat_priv->tt.last_changeset_len = 0;
495 690
691 /* randomize initial seqno to avoid collision */
692 get_random_bytes(&random_seqno, sizeof(random_seqno));
693 atomic_set(&bat_priv->frag_seqno, random_seqno);
694
496 bat_priv->primary_if = NULL; 695 bat_priv->primary_if = NULL;
497 bat_priv->num_ifaces = 0; 696 bat_priv->num_ifaces = 0;
498 697
@@ -578,8 +777,11 @@ static const struct net_device_ops batadv_netdev_ops = {
578 .ndo_open = batadv_interface_open, 777 .ndo_open = batadv_interface_open,
579 .ndo_stop = batadv_interface_release, 778 .ndo_stop = batadv_interface_release,
580 .ndo_get_stats = batadv_interface_stats, 779 .ndo_get_stats = batadv_interface_stats,
780 .ndo_vlan_rx_add_vid = batadv_interface_add_vid,
781 .ndo_vlan_rx_kill_vid = batadv_interface_kill_vid,
581 .ndo_set_mac_address = batadv_interface_set_mac_addr, 782 .ndo_set_mac_address = batadv_interface_set_mac_addr,
582 .ndo_change_mtu = batadv_interface_change_mtu, 783 .ndo_change_mtu = batadv_interface_change_mtu,
784 .ndo_set_rx_mode = batadv_interface_set_rx_mode,
583 .ndo_start_xmit = batadv_interface_tx, 785 .ndo_start_xmit = batadv_interface_tx,
584 .ndo_validate_addr = eth_validate_addr, 786 .ndo_validate_addr = eth_validate_addr,
585 .ndo_add_slave = batadv_softif_slave_add, 787 .ndo_add_slave = batadv_softif_slave_add,
@@ -616,6 +818,7 @@ static void batadv_softif_init_early(struct net_device *dev)
616 818
617 dev->netdev_ops = &batadv_netdev_ops; 819 dev->netdev_ops = &batadv_netdev_ops;
618 dev->destructor = batadv_softif_free; 820 dev->destructor = batadv_softif_free;
821 dev->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
619 dev->tx_queue_len = 0; 822 dev->tx_queue_len = 0;
620 823
621 /* can't call min_mtu, because the needed variables 824 /* can't call min_mtu, because the needed variables
@@ -623,7 +826,7 @@ static void batadv_softif_init_early(struct net_device *dev)
623 */ 826 */
624 dev->mtu = ETH_DATA_LEN; 827 dev->mtu = ETH_DATA_LEN;
625 /* reserve more space in the skbuff for our header */ 828 /* reserve more space in the skbuff for our header */
626 dev->hard_header_len = BATADV_HEADER_LEN; 829 dev->hard_header_len = batadv_max_header_len();
627 830
628 /* generate random address */ 831 /* generate random address */
629 eth_hw_addr_random(dev); 832 eth_hw_addr_random(dev);
@@ -760,6 +963,12 @@ static const struct {
760 { "mgmt_tx_bytes" }, 963 { "mgmt_tx_bytes" },
761 { "mgmt_rx" }, 964 { "mgmt_rx" },
762 { "mgmt_rx_bytes" }, 965 { "mgmt_rx_bytes" },
966 { "frag_tx" },
967 { "frag_tx_bytes" },
968 { "frag_rx" },
969 { "frag_rx_bytes" },
970 { "frag_fwd" },
971 { "frag_fwd_bytes" },
763 { "tt_request_tx" }, 972 { "tt_request_tx" },
764 { "tt_request_rx" }, 973 { "tt_request_rx" },
765 { "tt_response_tx" }, 974 { "tt_response_tx" },
diff --git a/net/batman-adv/soft-interface.h b/net/batman-adv/soft-interface.h
index 2f2472c2ea0d..06fc91ff5a02 100644
--- a/net/batman-adv/soft-interface.h
+++ b/net/batman-adv/soft-interface.h
@@ -28,5 +28,9 @@ struct net_device *batadv_softif_create(const char *name);
28void batadv_softif_destroy_sysfs(struct net_device *soft_iface); 28void batadv_softif_destroy_sysfs(struct net_device *soft_iface);
29int batadv_softif_is_valid(const struct net_device *net_dev); 29int batadv_softif_is_valid(const struct net_device *net_dev);
30extern struct rtnl_link_ops batadv_link_ops; 30extern struct rtnl_link_ops batadv_link_ops;
31int batadv_softif_create_vlan(struct batadv_priv *bat_priv, unsigned short vid);
32void batadv_softif_vlan_free_ref(struct batadv_softif_vlan *softif_vlan);
33struct batadv_softif_vlan *batadv_softif_vlan_get(struct batadv_priv *bat_priv,
34 unsigned short vid);
31 35
32#endif /* _NET_BATMAN_ADV_SOFT_INTERFACE_H_ */ 36#endif /* _NET_BATMAN_ADV_SOFT_INTERFACE_H_ */
diff --git a/net/batman-adv/sysfs.c b/net/batman-adv/sysfs.c
index 4114b961bc2c..6335433310af 100644
--- a/net/batman-adv/sysfs.c
+++ b/net/batman-adv/sysfs.c
@@ -21,11 +21,12 @@
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 "distributed-arp-table.h"
24#include "network-coding.h"
24#include "originator.h" 25#include "originator.h"
25#include "hard-interface.h" 26#include "hard-interface.h"
27#include "soft-interface.h"
26#include "gateway_common.h" 28#include "gateway_common.h"
27#include "gateway_client.h" 29#include "gateway_client.h"
28#include "vis.h"
29 30
30static struct net_device *batadv_kobj_to_netdev(struct kobject *obj) 31static struct net_device *batadv_kobj_to_netdev(struct kobject *obj)
31{ 32{
@@ -39,6 +40,53 @@ static struct batadv_priv *batadv_kobj_to_batpriv(struct kobject *obj)
39 return netdev_priv(net_dev); 40 return netdev_priv(net_dev);
40} 41}
41 42
43/**
44 * batadv_vlan_kobj_to_batpriv - convert a vlan kobj in the associated batpriv
45 * @obj: kobject to covert
46 *
47 * Returns the associated batadv_priv struct.
48 */
49static struct batadv_priv *batadv_vlan_kobj_to_batpriv(struct kobject *obj)
50{
51 /* VLAN specific attributes are located in the root sysfs folder if they
52 * refer to the untagged VLAN..
53 */
54 if (!strcmp(BATADV_SYSFS_IF_MESH_SUBDIR, obj->name))
55 return batadv_kobj_to_batpriv(obj);
56
57 /* ..while the attributes for the tagged vlans are located in
58 * the in the corresponding "vlan%VID" subfolder
59 */
60 return batadv_kobj_to_batpriv(obj->parent);
61}
62
63/**
64 * batadv_kobj_to_vlan - convert a kobj in the associated softif_vlan struct
65 * @obj: kobject to covert
66 *
67 * Returns the associated softif_vlan struct if found, NULL otherwise.
68 */
69static struct batadv_softif_vlan *
70batadv_kobj_to_vlan(struct batadv_priv *bat_priv, struct kobject *obj)
71{
72 struct batadv_softif_vlan *vlan_tmp, *vlan = NULL;
73
74 rcu_read_lock();
75 hlist_for_each_entry_rcu(vlan_tmp, &bat_priv->softif_vlan_list, list) {
76 if (vlan_tmp->kobj != obj)
77 continue;
78
79 if (!atomic_inc_not_zero(&vlan_tmp->refcount))
80 continue;
81
82 vlan = vlan_tmp;
83 break;
84 }
85 rcu_read_unlock();
86
87 return vlan;
88}
89
42#define BATADV_UEV_TYPE_VAR "BATTYPE=" 90#define BATADV_UEV_TYPE_VAR "BATTYPE="
43#define BATADV_UEV_ACTION_VAR "BATACTION=" 91#define BATADV_UEV_ACTION_VAR "BATACTION="
44#define BATADV_UEV_DATA_VAR "BATDATA=" 92#define BATADV_UEV_DATA_VAR "BATDATA="
@@ -53,6 +101,15 @@ static char *batadv_uev_type_str[] = {
53 "gw" 101 "gw"
54}; 102};
55 103
104/* Use this, if you have customized show and store functions for vlan attrs */
105#define BATADV_ATTR_VLAN(_name, _mode, _show, _store) \
106struct batadv_attribute batadv_attr_vlan_##_name = { \
107 .attr = {.name = __stringify(_name), \
108 .mode = _mode }, \
109 .show = _show, \
110 .store = _store, \
111};
112
56/* Use this, if you have customized show and store functions */ 113/* Use this, if you have customized show and store functions */
57#define BATADV_ATTR(_name, _mode, _show, _store) \ 114#define BATADV_ATTR(_name, _mode, _show, _store) \
58struct batadv_attribute batadv_attr_##_name = { \ 115struct batadv_attribute batadv_attr_##_name = { \
@@ -122,6 +179,41 @@ ssize_t batadv_show_##_name(struct kobject *kobj, \
122 static BATADV_ATTR(_name, _mode, batadv_show_##_name, \ 179 static BATADV_ATTR(_name, _mode, batadv_show_##_name, \
123 batadv_store_##_name) 180 batadv_store_##_name)
124 181
182#define BATADV_ATTR_VLAN_STORE_BOOL(_name, _post_func) \
183ssize_t batadv_store_vlan_##_name(struct kobject *kobj, \
184 struct attribute *attr, char *buff, \
185 size_t count) \
186{ \
187 struct batadv_priv *bat_priv = batadv_vlan_kobj_to_batpriv(kobj);\
188 struct batadv_softif_vlan *vlan = batadv_kobj_to_vlan(bat_priv, \
189 kobj); \
190 size_t res = __batadv_store_bool_attr(buff, count, _post_func, \
191 attr, &vlan->_name, \
192 bat_priv->soft_iface); \
193 batadv_softif_vlan_free_ref(vlan); \
194 return res; \
195}
196
197#define BATADV_ATTR_VLAN_SHOW_BOOL(_name) \
198ssize_t batadv_show_vlan_##_name(struct kobject *kobj, \
199 struct attribute *attr, char *buff) \
200{ \
201 struct batadv_priv *bat_priv = batadv_vlan_kobj_to_batpriv(kobj);\
202 struct batadv_softif_vlan *vlan = batadv_kobj_to_vlan(bat_priv, \
203 kobj); \
204 size_t res = sprintf(buff, "%s\n", \
205 atomic_read(&vlan->_name) == 0 ? \
206 "disabled" : "enabled"); \
207 batadv_softif_vlan_free_ref(vlan); \
208 return res; \
209}
210
211/* Use this, if you are going to turn a [name] in the vlan struct on or off */
212#define BATADV_ATTR_VLAN_BOOL(_name, _mode, _post_func) \
213 static BATADV_ATTR_VLAN_STORE_BOOL(_name, _post_func) \
214 static BATADV_ATTR_VLAN_SHOW_BOOL(_name) \
215 static BATADV_ATTR_VLAN(_name, _mode, batadv_show_vlan_##_name, \
216 batadv_store_vlan_##_name)
125 217
126static int batadv_store_bool_attr(char *buff, size_t count, 218static int batadv_store_bool_attr(char *buff, size_t count,
127 struct net_device *net_dev, 219 struct net_device *net_dev,
@@ -230,74 +322,6 @@ __batadv_store_uint_attr(const char *buff, size_t count,
230 return ret; 322 return ret;
231} 323}
232 324
233static ssize_t batadv_show_vis_mode(struct kobject *kobj,
234 struct attribute *attr, char *buff)
235{
236 struct batadv_priv *bat_priv = batadv_kobj_to_batpriv(kobj);
237 int vis_mode = atomic_read(&bat_priv->vis_mode);
238 const char *mode;
239
240 if (vis_mode == BATADV_VIS_TYPE_CLIENT_UPDATE)
241 mode = "client";
242 else
243 mode = "server";
244
245 return sprintf(buff, "%s\n", mode);
246}
247
248static ssize_t batadv_store_vis_mode(struct kobject *kobj,
249 struct attribute *attr, char *buff,
250 size_t count)
251{
252 struct net_device *net_dev = batadv_kobj_to_netdev(kobj);
253 struct batadv_priv *bat_priv = netdev_priv(net_dev);
254 unsigned long val;
255 int ret, vis_mode_tmp = -1;
256 const char *old_mode, *new_mode;
257
258 ret = kstrtoul(buff, 10, &val);
259
260 if (((count == 2) && (!ret) &&
261 (val == BATADV_VIS_TYPE_CLIENT_UPDATE)) ||
262 (strncmp(buff, "client", 6) == 0) ||
263 (strncmp(buff, "off", 3) == 0))
264 vis_mode_tmp = BATADV_VIS_TYPE_CLIENT_UPDATE;
265
266 if (((count == 2) && (!ret) &&
267 (val == BATADV_VIS_TYPE_SERVER_SYNC)) ||
268 (strncmp(buff, "server", 6) == 0))
269 vis_mode_tmp = BATADV_VIS_TYPE_SERVER_SYNC;
270
271 if (vis_mode_tmp < 0) {
272 if (buff[count - 1] == '\n')
273 buff[count - 1] = '\0';
274
275 batadv_info(net_dev,
276 "Invalid parameter for 'vis mode' setting received: %s\n",
277 buff);
278 return -EINVAL;
279 }
280
281 if (atomic_read(&bat_priv->vis_mode) == vis_mode_tmp)
282 return count;
283
284 if (atomic_read(&bat_priv->vis_mode) == BATADV_VIS_TYPE_CLIENT_UPDATE)
285 old_mode = "client";
286 else
287 old_mode = "server";
288
289 if (vis_mode_tmp == BATADV_VIS_TYPE_CLIENT_UPDATE)
290 new_mode = "client";
291 else
292 new_mode = "server";
293
294 batadv_info(net_dev, "Changing vis mode from: %s to: %s\n", old_mode,
295 new_mode);
296
297 atomic_set(&bat_priv->vis_mode, (unsigned int)vis_mode_tmp);
298 return count;
299}
300
301static ssize_t batadv_show_bat_algo(struct kobject *kobj, 325static ssize_t batadv_show_bat_algo(struct kobject *kobj,
302 struct attribute *attr, char *buff) 326 struct attribute *attr, char *buff)
303{ 327{
@@ -390,6 +414,7 @@ static ssize_t batadv_store_gw_mode(struct kobject *kobj,
390 */ 414 */
391 batadv_gw_check_client_stop(bat_priv); 415 batadv_gw_check_client_stop(bat_priv);
392 atomic_set(&bat_priv->gw_mode, (unsigned int)gw_mode_tmp); 416 atomic_set(&bat_priv->gw_mode, (unsigned int)gw_mode_tmp);
417 batadv_gw_tvlv_container_update(bat_priv);
393 return count; 418 return count;
394} 419}
395 420
@@ -397,15 +422,13 @@ static ssize_t batadv_show_gw_bwidth(struct kobject *kobj,
397 struct attribute *attr, char *buff) 422 struct attribute *attr, char *buff)
398{ 423{
399 struct batadv_priv *bat_priv = batadv_kobj_to_batpriv(kobj); 424 struct batadv_priv *bat_priv = batadv_kobj_to_batpriv(kobj);
400 int down, up; 425 uint32_t down, up;
401 int gw_bandwidth = atomic_read(&bat_priv->gw_bandwidth); 426
402 427 down = atomic_read(&bat_priv->gw.bandwidth_down);
403 batadv_gw_bandwidth_to_kbit(gw_bandwidth, &down, &up); 428 up = atomic_read(&bat_priv->gw.bandwidth_up);
404 return sprintf(buff, "%i%s/%i%s\n", 429
405 (down > 2048 ? down / 1024 : down), 430 return sprintf(buff, "%u.%u/%u.%u MBit\n", down / 10,
406 (down > 2048 ? "MBit" : "KBit"), 431 down % 10, up / 10, up % 10);
407 (up > 2048 ? up / 1024 : up),
408 (up > 2048 ? "MBit" : "KBit"));
409} 432}
410 433
411static ssize_t batadv_store_gw_bwidth(struct kobject *kobj, 434static ssize_t batadv_store_gw_bwidth(struct kobject *kobj,
@@ -426,12 +449,10 @@ BATADV_ATTR_SIF_BOOL(bonding, S_IRUGO | S_IWUSR, NULL);
426BATADV_ATTR_SIF_BOOL(bridge_loop_avoidance, S_IRUGO | S_IWUSR, NULL); 449BATADV_ATTR_SIF_BOOL(bridge_loop_avoidance, S_IRUGO | S_IWUSR, NULL);
427#endif 450#endif
428#ifdef CONFIG_BATMAN_ADV_DAT 451#ifdef CONFIG_BATMAN_ADV_DAT
429BATADV_ATTR_SIF_BOOL(distributed_arp_table, S_IRUGO | S_IWUSR, NULL); 452BATADV_ATTR_SIF_BOOL(distributed_arp_table, S_IRUGO | S_IWUSR,
453 batadv_dat_status_update);
430#endif 454#endif
431BATADV_ATTR_SIF_BOOL(fragmentation, S_IRUGO | S_IWUSR, batadv_update_min_mtu); 455BATADV_ATTR_SIF_BOOL(fragmentation, S_IRUGO | S_IWUSR, batadv_update_min_mtu);
432BATADV_ATTR_SIF_BOOL(ap_isolation, S_IRUGO | S_IWUSR, NULL);
433static BATADV_ATTR(vis_mode, S_IRUGO | S_IWUSR, batadv_show_vis_mode,
434 batadv_store_vis_mode);
435static BATADV_ATTR(routing_algo, S_IRUGO, batadv_show_bat_algo, NULL); 456static BATADV_ATTR(routing_algo, S_IRUGO, batadv_show_bat_algo, NULL);
436static BATADV_ATTR(gw_mode, S_IRUGO | S_IWUSR, batadv_show_gw_mode, 457static BATADV_ATTR(gw_mode, S_IRUGO | S_IWUSR, batadv_show_gw_mode,
437 batadv_store_gw_mode); 458 batadv_store_gw_mode);
@@ -447,7 +468,8 @@ static BATADV_ATTR(gw_bandwidth, S_IRUGO | S_IWUSR, batadv_show_gw_bwidth,
447BATADV_ATTR_SIF_UINT(log_level, S_IRUGO | S_IWUSR, 0, BATADV_DBG_ALL, NULL); 468BATADV_ATTR_SIF_UINT(log_level, S_IRUGO | S_IWUSR, 0, BATADV_DBG_ALL, NULL);
448#endif 469#endif
449#ifdef CONFIG_BATMAN_ADV_NC 470#ifdef CONFIG_BATMAN_ADV_NC
450BATADV_ATTR_SIF_BOOL(network_coding, S_IRUGO | S_IWUSR, NULL); 471BATADV_ATTR_SIF_BOOL(network_coding, S_IRUGO | S_IWUSR,
472 batadv_nc_status_update);
451#endif 473#endif
452 474
453static struct batadv_attribute *batadv_mesh_attrs[] = { 475static struct batadv_attribute *batadv_mesh_attrs[] = {
@@ -460,8 +482,6 @@ static struct batadv_attribute *batadv_mesh_attrs[] = {
460 &batadv_attr_distributed_arp_table, 482 &batadv_attr_distributed_arp_table,
461#endif 483#endif
462 &batadv_attr_fragmentation, 484 &batadv_attr_fragmentation,
463 &batadv_attr_ap_isolation,
464 &batadv_attr_vis_mode,
465 &batadv_attr_routing_algo, 485 &batadv_attr_routing_algo,
466 &batadv_attr_gw_mode, 486 &batadv_attr_gw_mode,
467 &batadv_attr_orig_interval, 487 &batadv_attr_orig_interval,
@@ -477,6 +497,16 @@ static struct batadv_attribute *batadv_mesh_attrs[] = {
477 NULL, 497 NULL,
478}; 498};
479 499
500BATADV_ATTR_VLAN_BOOL(ap_isolation, S_IRUGO | S_IWUSR, NULL);
501
502/**
503 * batadv_vlan_attrs - array of vlan specific sysfs attributes
504 */
505static struct batadv_attribute *batadv_vlan_attrs[] = {
506 &batadv_attr_vlan_ap_isolation,
507 NULL,
508};
509
480int batadv_sysfs_add_meshif(struct net_device *dev) 510int batadv_sysfs_add_meshif(struct net_device *dev)
481{ 511{
482 struct kobject *batif_kobject = &dev->dev.kobj; 512 struct kobject *batif_kobject = &dev->dev.kobj;
@@ -527,6 +557,80 @@ void batadv_sysfs_del_meshif(struct net_device *dev)
527 bat_priv->mesh_obj = NULL; 557 bat_priv->mesh_obj = NULL;
528} 558}
529 559
560/**
561 * batadv_sysfs_add_vlan - add all the needed sysfs objects for the new vlan
562 * @dev: netdev of the mesh interface
563 * @vlan: private data of the newly added VLAN interface
564 *
565 * Returns 0 on success and -ENOMEM if any of the structure allocations fails.
566 */
567int batadv_sysfs_add_vlan(struct net_device *dev,
568 struct batadv_softif_vlan *vlan)
569{
570 char vlan_subdir[sizeof(BATADV_SYSFS_VLAN_SUBDIR_PREFIX) + 5];
571 struct batadv_priv *bat_priv = netdev_priv(dev);
572 struct batadv_attribute **bat_attr;
573 int err;
574
575 if (vlan->vid & BATADV_VLAN_HAS_TAG) {
576 sprintf(vlan_subdir, BATADV_SYSFS_VLAN_SUBDIR_PREFIX "%hu",
577 vlan->vid & VLAN_VID_MASK);
578
579 vlan->kobj = kobject_create_and_add(vlan_subdir,
580 bat_priv->mesh_obj);
581 if (!vlan->kobj) {
582 batadv_err(dev, "Can't add sysfs directory: %s/%s\n",
583 dev->name, vlan_subdir);
584 goto out;
585 }
586 } else {
587 /* the untagged LAN uses the root folder to store its "VLAN
588 * specific attributes"
589 */
590 vlan->kobj = bat_priv->mesh_obj;
591 kobject_get(bat_priv->mesh_obj);
592 }
593
594 for (bat_attr = batadv_vlan_attrs; *bat_attr; ++bat_attr) {
595 err = sysfs_create_file(vlan->kobj,
596 &((*bat_attr)->attr));
597 if (err) {
598 batadv_err(dev, "Can't add sysfs file: %s/%s/%s\n",
599 dev->name, vlan_subdir,
600 ((*bat_attr)->attr).name);
601 goto rem_attr;
602 }
603 }
604
605 return 0;
606
607rem_attr:
608 for (bat_attr = batadv_vlan_attrs; *bat_attr; ++bat_attr)
609 sysfs_remove_file(vlan->kobj, &((*bat_attr)->attr));
610
611 kobject_put(vlan->kobj);
612 vlan->kobj = NULL;
613out:
614 return -ENOMEM;
615}
616
617/**
618 * batadv_sysfs_del_vlan - remove all the sysfs objects for a given VLAN
619 * @bat_priv: the bat priv with all the soft interface information
620 * @vlan: the private data of the VLAN to destroy
621 */
622void batadv_sysfs_del_vlan(struct batadv_priv *bat_priv,
623 struct batadv_softif_vlan *vlan)
624{
625 struct batadv_attribute **bat_attr;
626
627 for (bat_attr = batadv_vlan_attrs; *bat_attr; ++bat_attr)
628 sysfs_remove_file(vlan->kobj, &((*bat_attr)->attr));
629
630 kobject_put(vlan->kobj);
631 vlan->kobj = NULL;
632}
633
530static ssize_t batadv_show_mesh_iface(struct kobject *kobj, 634static ssize_t batadv_show_mesh_iface(struct kobject *kobj,
531 struct attribute *attr, char *buff) 635 struct attribute *attr, char *buff)
532{ 636{
diff --git a/net/batman-adv/sysfs.h b/net/batman-adv/sysfs.h
index 479acf4c16f4..c7d725de50ad 100644
--- a/net/batman-adv/sysfs.h
+++ b/net/batman-adv/sysfs.h
@@ -22,6 +22,12 @@
22 22
23#define BATADV_SYSFS_IF_MESH_SUBDIR "mesh" 23#define BATADV_SYSFS_IF_MESH_SUBDIR "mesh"
24#define BATADV_SYSFS_IF_BAT_SUBDIR "batman_adv" 24#define BATADV_SYSFS_IF_BAT_SUBDIR "batman_adv"
25/**
26 * BATADV_SYSFS_VLAN_SUBDIR_PREFIX - prefix of the subfolder that will be
27 * created in the sysfs hierarchy for each VLAN interface. The subfolder will
28 * be named "BATADV_SYSFS_VLAN_SUBDIR_PREFIX%vid".
29 */
30#define BATADV_SYSFS_VLAN_SUBDIR_PREFIX "vlan"
25 31
26struct batadv_attribute { 32struct batadv_attribute {
27 struct attribute attr; 33 struct attribute attr;
@@ -36,6 +42,10 @@ void batadv_sysfs_del_meshif(struct net_device *dev);
36int batadv_sysfs_add_hardif(struct kobject **hardif_obj, 42int batadv_sysfs_add_hardif(struct kobject **hardif_obj,
37 struct net_device *dev); 43 struct net_device *dev);
38void batadv_sysfs_del_hardif(struct kobject **hardif_obj); 44void batadv_sysfs_del_hardif(struct kobject **hardif_obj);
45int batadv_sysfs_add_vlan(struct net_device *dev,
46 struct batadv_softif_vlan *vlan);
47void batadv_sysfs_del_vlan(struct batadv_priv *bat_priv,
48 struct batadv_softif_vlan *vlan);
39int batadv_throw_uevent(struct batadv_priv *bat_priv, enum batadv_uev_type type, 49int batadv_throw_uevent(struct batadv_priv *bat_priv, enum batadv_uev_type type,
40 enum batadv_uev_action action, const char *data); 50 enum batadv_uev_action action, const char *data);
41 51
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index 34510f38708f..7731eaed737d 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -27,13 +27,14 @@
27#include "routing.h" 27#include "routing.h"
28#include "bridge_loop_avoidance.h" 28#include "bridge_loop_avoidance.h"
29 29
30#include <linux/crc16.h> 30#include <linux/crc32c.h>
31 31
32/* hash class keys */ 32/* hash class keys */
33static struct lock_class_key batadv_tt_local_hash_lock_class_key; 33static struct lock_class_key batadv_tt_local_hash_lock_class_key;
34static struct lock_class_key batadv_tt_global_hash_lock_class_key; 34static struct lock_class_key batadv_tt_global_hash_lock_class_key;
35 35
36static void batadv_send_roam_adv(struct batadv_priv *bat_priv, uint8_t *client, 36static void batadv_send_roam_adv(struct batadv_priv *bat_priv, uint8_t *client,
37 unsigned short vid,
37 struct batadv_orig_node *orig_node); 38 struct batadv_orig_node *orig_node);
38static void batadv_tt_purge(struct work_struct *work); 39static void batadv_tt_purge(struct work_struct *work);
39static void 40static void
@@ -41,7 +42,8 @@ batadv_tt_global_del_orig_list(struct batadv_tt_global_entry *tt_global_entry);
41static void batadv_tt_global_del(struct batadv_priv *bat_priv, 42static void batadv_tt_global_del(struct batadv_priv *bat_priv,
42 struct batadv_orig_node *orig_node, 43 struct batadv_orig_node *orig_node,
43 const unsigned char *addr, 44 const unsigned char *addr,
44 const char *message, bool roaming); 45 unsigned short vid, const char *message,
46 bool roaming);
45 47
46/* returns 1 if they are the same mac addr */ 48/* returns 1 if they are the same mac addr */
47static int batadv_compare_tt(const struct hlist_node *node, const void *data2) 49static int batadv_compare_tt(const struct hlist_node *node, const void *data2)
@@ -52,43 +54,93 @@ static int batadv_compare_tt(const struct hlist_node *node, const void *data2)
52 return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0); 54 return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0);
53} 55}
54 56
57/**
58 * batadv_choose_tt - return the index of the tt entry in the hash table
59 * @data: pointer to the tt_common_entry object to map
60 * @size: the size of the hash table
61 *
62 * Returns the hash index where the object represented by 'data' should be
63 * stored at.
64 */
65static inline uint32_t batadv_choose_tt(const void *data, uint32_t size)
66{
67 struct batadv_tt_common_entry *tt;
68 uint32_t hash = 0;
69
70 tt = (struct batadv_tt_common_entry *)data;
71 hash = batadv_hash_bytes(hash, &tt->addr, ETH_ALEN);
72 hash = batadv_hash_bytes(hash, &tt->vid, sizeof(tt->vid));
73
74 hash += (hash << 3);
75 hash ^= (hash >> 11);
76 hash += (hash << 15);
77
78 return hash % size;
79}
80
81/**
82 * batadv_tt_hash_find - look for a client in the given hash table
83 * @hash: the hash table to search
84 * @addr: the mac address of the client to look for
85 * @vid: VLAN identifier
86 *
87 * Returns a pointer to the tt_common struct belonging to the searched client if
88 * found, NULL otherwise.
89 */
55static struct batadv_tt_common_entry * 90static struct batadv_tt_common_entry *
56batadv_tt_hash_find(struct batadv_hashtable *hash, const void *data) 91batadv_tt_hash_find(struct batadv_hashtable *hash, const uint8_t *addr,
92 unsigned short vid)
57{ 93{
58 struct hlist_head *head; 94 struct hlist_head *head;
59 struct batadv_tt_common_entry *tt_common_entry; 95 struct batadv_tt_common_entry to_search, *tt, *tt_tmp = NULL;
60 struct batadv_tt_common_entry *tt_common_entry_tmp = NULL;
61 uint32_t index; 96 uint32_t index;
62 97
63 if (!hash) 98 if (!hash)
64 return NULL; 99 return NULL;
65 100
66 index = batadv_choose_orig(data, hash->size); 101 memcpy(to_search.addr, addr, ETH_ALEN);
102 to_search.vid = vid;
103
104 index = batadv_choose_tt(&to_search, hash->size);
67 head = &hash->table[index]; 105 head = &hash->table[index];
68 106
69 rcu_read_lock(); 107 rcu_read_lock();
70 hlist_for_each_entry_rcu(tt_common_entry, head, hash_entry) { 108 hlist_for_each_entry_rcu(tt, head, hash_entry) {
71 if (!batadv_compare_eth(tt_common_entry, data)) 109 if (!batadv_compare_eth(tt, addr))
110 continue;
111
112 if (tt->vid != vid)
72 continue; 113 continue;
73 114
74 if (!atomic_inc_not_zero(&tt_common_entry->refcount)) 115 if (!atomic_inc_not_zero(&tt->refcount))
75 continue; 116 continue;
76 117
77 tt_common_entry_tmp = tt_common_entry; 118 tt_tmp = tt;
78 break; 119 break;
79 } 120 }
80 rcu_read_unlock(); 121 rcu_read_unlock();
81 122
82 return tt_common_entry_tmp; 123 return tt_tmp;
83} 124}
84 125
126/**
127 * batadv_tt_local_hash_find - search the local table for a given client
128 * @bat_priv: the bat priv with all the soft interface information
129 * @addr: the mac address of the client to look for
130 * @vid: VLAN identifier
131 *
132 * Returns a pointer to the corresponding tt_local_entry struct if the client is
133 * found, NULL otherwise.
134 */
85static struct batadv_tt_local_entry * 135static struct batadv_tt_local_entry *
86batadv_tt_local_hash_find(struct batadv_priv *bat_priv, const void *data) 136batadv_tt_local_hash_find(struct batadv_priv *bat_priv, const uint8_t *addr,
137 unsigned short vid)
87{ 138{
88 struct batadv_tt_common_entry *tt_common_entry; 139 struct batadv_tt_common_entry *tt_common_entry;
89 struct batadv_tt_local_entry *tt_local_entry = NULL; 140 struct batadv_tt_local_entry *tt_local_entry = NULL;
90 141
91 tt_common_entry = batadv_tt_hash_find(bat_priv->tt.local_hash, data); 142 tt_common_entry = batadv_tt_hash_find(bat_priv->tt.local_hash, addr,
143 vid);
92 if (tt_common_entry) 144 if (tt_common_entry)
93 tt_local_entry = container_of(tt_common_entry, 145 tt_local_entry = container_of(tt_common_entry,
94 struct batadv_tt_local_entry, 146 struct batadv_tt_local_entry,
@@ -96,13 +148,24 @@ batadv_tt_local_hash_find(struct batadv_priv *bat_priv, const void *data)
96 return tt_local_entry; 148 return tt_local_entry;
97} 149}
98 150
151/**
152 * batadv_tt_global_hash_find - search the global table for a given client
153 * @bat_priv: the bat priv with all the soft interface information
154 * @addr: the mac address of the client to look for
155 * @vid: VLAN identifier
156 *
157 * Returns a pointer to the corresponding tt_global_entry struct if the client
158 * is found, NULL otherwise.
159 */
99static struct batadv_tt_global_entry * 160static struct batadv_tt_global_entry *
100batadv_tt_global_hash_find(struct batadv_priv *bat_priv, const void *data) 161batadv_tt_global_hash_find(struct batadv_priv *bat_priv, const uint8_t *addr,
162 unsigned short vid)
101{ 163{
102 struct batadv_tt_common_entry *tt_common_entry; 164 struct batadv_tt_common_entry *tt_common_entry;
103 struct batadv_tt_global_entry *tt_global_entry = NULL; 165 struct batadv_tt_global_entry *tt_global_entry = NULL;
104 166
105 tt_common_entry = batadv_tt_hash_find(bat_priv->tt.global_hash, data); 167 tt_common_entry = batadv_tt_hash_find(bat_priv->tt.global_hash, addr,
168 vid);
106 if (tt_common_entry) 169 if (tt_common_entry)
107 tt_global_entry = container_of(tt_common_entry, 170 tt_global_entry = container_of(tt_common_entry,
108 struct batadv_tt_global_entry, 171 struct batadv_tt_global_entry,
@@ -117,25 +180,17 @@ batadv_tt_local_entry_free_ref(struct batadv_tt_local_entry *tt_local_entry)
117 kfree_rcu(tt_local_entry, common.rcu); 180 kfree_rcu(tt_local_entry, common.rcu);
118} 181}
119 182
120static void batadv_tt_global_entry_free_rcu(struct rcu_head *rcu) 183/**
121{ 184 * batadv_tt_global_entry_free_ref - decrement the refcounter for a
122 struct batadv_tt_common_entry *tt_common_entry; 185 * tt_global_entry and possibly free it
123 struct batadv_tt_global_entry *tt_global_entry; 186 * @tt_global_entry: the object to free
124 187 */
125 tt_common_entry = container_of(rcu, struct batadv_tt_common_entry, rcu);
126 tt_global_entry = container_of(tt_common_entry,
127 struct batadv_tt_global_entry, common);
128
129 kfree(tt_global_entry);
130}
131
132static void 188static void
133batadv_tt_global_entry_free_ref(struct batadv_tt_global_entry *tt_global_entry) 189batadv_tt_global_entry_free_ref(struct batadv_tt_global_entry *tt_global_entry)
134{ 190{
135 if (atomic_dec_and_test(&tt_global_entry->common.refcount)) { 191 if (atomic_dec_and_test(&tt_global_entry->common.refcount)) {
136 batadv_tt_global_del_orig_list(tt_global_entry); 192 batadv_tt_global_del_orig_list(tt_global_entry);
137 call_rcu(&tt_global_entry->common.rcu, 193 kfree_rcu(tt_global_entry, common.rcu);
138 batadv_tt_global_entry_free_rcu);
139 } 194 }
140} 195}
141 196
@@ -153,13 +208,107 @@ static void batadv_tt_orig_list_entry_free_rcu(struct rcu_head *rcu)
153 kfree(orig_entry); 208 kfree(orig_entry);
154} 209}
155 210
211/**
212 * batadv_tt_local_size_mod - change the size by v of the local table identified
213 * by vid
214 * @bat_priv: the bat priv with all the soft interface information
215 * @vid: the VLAN identifier of the sub-table to change
216 * @v: the amount to sum to the local table size
217 */
218static void batadv_tt_local_size_mod(struct batadv_priv *bat_priv,
219 unsigned short vid, int v)
220{
221 struct batadv_softif_vlan *vlan;
222
223 vlan = batadv_softif_vlan_get(bat_priv, vid);
224 if (!vlan)
225 return;
226
227 atomic_add(v, &vlan->tt.num_entries);
228
229 batadv_softif_vlan_free_ref(vlan);
230}
231
232/**
233 * batadv_tt_local_size_inc - increase by one the local table size for the given
234 * vid
235 * @bat_priv: the bat priv with all the soft interface information
236 * @vid: the VLAN identifier
237 */
238static void batadv_tt_local_size_inc(struct batadv_priv *bat_priv,
239 unsigned short vid)
240{
241 batadv_tt_local_size_mod(bat_priv, vid, 1);
242}
243
244/**
245 * batadv_tt_local_size_dec - decrease by one the local table size for the given
246 * vid
247 * @bat_priv: the bat priv with all the soft interface information
248 * @vid: the VLAN identifier
249 */
250static void batadv_tt_local_size_dec(struct batadv_priv *bat_priv,
251 unsigned short vid)
252{
253 batadv_tt_local_size_mod(bat_priv, vid, -1);
254}
255
256/**
257 * batadv_tt_global_size_mod - change the size by v of the local table
258 * identified by vid
259 * @bat_priv: the bat priv with all the soft interface information
260 * @vid: the VLAN identifier
261 * @v: the amount to sum to the global table size
262 */
263static void batadv_tt_global_size_mod(struct batadv_orig_node *orig_node,
264 unsigned short vid, int v)
265{
266 struct batadv_orig_node_vlan *vlan;
267
268 vlan = batadv_orig_node_vlan_new(orig_node, vid);
269 if (!vlan)
270 return;
271
272 if (atomic_add_return(v, &vlan->tt.num_entries) == 0) {
273 spin_lock_bh(&orig_node->vlan_list_lock);
274 list_del_rcu(&vlan->list);
275 spin_unlock_bh(&orig_node->vlan_list_lock);
276 batadv_orig_node_vlan_free_ref(vlan);
277 }
278
279 batadv_orig_node_vlan_free_ref(vlan);
280}
281
282/**
283 * batadv_tt_global_size_inc - increase by one the global table size for the
284 * given vid
285 * @orig_node: the originator which global table size has to be decreased
286 * @vid: the vlan identifier
287 */
288static void batadv_tt_global_size_inc(struct batadv_orig_node *orig_node,
289 unsigned short vid)
290{
291 batadv_tt_global_size_mod(orig_node, vid, 1);
292}
293
294/**
295 * batadv_tt_global_size_dec - decrease by one the global table size for the
296 * given vid
297 * @orig_node: the originator which global table size has to be decreased
298 * @vid: the vlan identifier
299 */
300static void batadv_tt_global_size_dec(struct batadv_orig_node *orig_node,
301 unsigned short vid)
302{
303 batadv_tt_global_size_mod(orig_node, vid, -1);
304}
305
156static void 306static void
157batadv_tt_orig_list_entry_free_ref(struct batadv_tt_orig_list_entry *orig_entry) 307batadv_tt_orig_list_entry_free_ref(struct batadv_tt_orig_list_entry *orig_entry)
158{ 308{
159 if (!atomic_dec_and_test(&orig_entry->refcount)) 309 if (!atomic_dec_and_test(&orig_entry->refcount))
160 return; 310 return;
161 /* to avoid race conditions, immediately decrease the tt counter */ 311
162 atomic_dec(&orig_entry->orig_node->tt_size);
163 call_rcu(&orig_entry->rcu, batadv_tt_orig_list_entry_free_rcu); 312 call_rcu(&orig_entry->rcu, batadv_tt_orig_list_entry_free_rcu);
164} 313}
165 314
@@ -180,12 +329,13 @@ static void batadv_tt_local_event(struct batadv_priv *bat_priv,
180 bool del_op_requested, del_op_entry; 329 bool del_op_requested, del_op_entry;
181 330
182 tt_change_node = kmalloc(sizeof(*tt_change_node), GFP_ATOMIC); 331 tt_change_node = kmalloc(sizeof(*tt_change_node), GFP_ATOMIC);
183
184 if (!tt_change_node) 332 if (!tt_change_node)
185 return; 333 return;
186 334
187 tt_change_node->change.flags = flags; 335 tt_change_node->change.flags = flags;
336 tt_change_node->change.reserved = 0;
188 memcpy(tt_change_node->change.addr, common->addr, ETH_ALEN); 337 memcpy(tt_change_node->change.addr, common->addr, ETH_ALEN);
338 tt_change_node->change.vid = htons(common->vid);
189 339
190 del_op_requested = flags & BATADV_TT_CLIENT_DEL; 340 del_op_requested = flags & BATADV_TT_CLIENT_DEL;
191 341
@@ -229,9 +379,26 @@ unlock:
229 atomic_inc(&bat_priv->tt.local_changes); 379 atomic_inc(&bat_priv->tt.local_changes);
230} 380}
231 381
232int batadv_tt_len(int changes_num) 382/**
383 * batadv_tt_len - compute length in bytes of given number of tt changes
384 * @changes_num: number of tt changes
385 *
386 * Returns computed length in bytes.
387 */
388static int batadv_tt_len(int changes_num)
233{ 389{
234 return changes_num * sizeof(struct batadv_tt_change); 390 return changes_num * sizeof(struct batadv_tvlv_tt_change);
391}
392
393/**
394 * batadv_tt_entries - compute the number of entries fitting in tt_len bytes
395 * @tt_len: available space
396 *
397 * Returns the number of entries.
398 */
399static uint16_t batadv_tt_entries(uint16_t tt_len)
400{
401 return tt_len / batadv_tt_len(1);
235} 402}
236 403
237static int batadv_tt_local_init(struct batadv_priv *bat_priv) 404static int batadv_tt_local_init(struct batadv_priv *bat_priv)
@@ -255,16 +422,26 @@ static void batadv_tt_global_free(struct batadv_priv *bat_priv,
255 const char *message) 422 const char *message)
256{ 423{
257 batadv_dbg(BATADV_DBG_TT, bat_priv, 424 batadv_dbg(BATADV_DBG_TT, bat_priv,
258 "Deleting global tt entry %pM: %s\n", 425 "Deleting global tt entry %pM (vid: %d): %s\n",
259 tt_global->common.addr, message); 426 tt_global->common.addr,
427 BATADV_PRINT_VID(tt_global->common.vid), message);
260 428
261 batadv_hash_remove(bat_priv->tt.global_hash, batadv_compare_tt, 429 batadv_hash_remove(bat_priv->tt.global_hash, batadv_compare_tt,
262 batadv_choose_orig, tt_global->common.addr); 430 batadv_choose_tt, &tt_global->common);
263 batadv_tt_global_entry_free_ref(tt_global); 431 batadv_tt_global_entry_free_ref(tt_global);
264} 432}
265 433
434/**
435 * batadv_tt_local_add - add a new client to the local table or update an
436 * existing client
437 * @soft_iface: netdev struct of the mesh interface
438 * @addr: the mac address of the client to add
439 * @vid: VLAN identifier
440 * @ifindex: index of the interface where the client is connected to (useful to
441 * identify wireless clients)
442 */
266void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr, 443void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
267 int ifindex) 444 unsigned short vid, int ifindex)
268{ 445{
269 struct batadv_priv *bat_priv = netdev_priv(soft_iface); 446 struct batadv_priv *bat_priv = netdev_priv(soft_iface);
270 struct batadv_tt_local_entry *tt_local; 447 struct batadv_tt_local_entry *tt_local;
@@ -274,14 +451,15 @@ void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
274 int hash_added; 451 int hash_added;
275 bool roamed_back = false; 452 bool roamed_back = false;
276 453
277 tt_local = batadv_tt_local_hash_find(bat_priv, addr); 454 tt_local = batadv_tt_local_hash_find(bat_priv, addr, vid);
278 tt_global = batadv_tt_global_hash_find(bat_priv, addr); 455 tt_global = batadv_tt_global_hash_find(bat_priv, addr, vid);
279 456
280 if (tt_local) { 457 if (tt_local) {
281 tt_local->last_seen = jiffies; 458 tt_local->last_seen = jiffies;
282 if (tt_local->common.flags & BATADV_TT_CLIENT_PENDING) { 459 if (tt_local->common.flags & BATADV_TT_CLIENT_PENDING) {
283 batadv_dbg(BATADV_DBG_TT, bat_priv, 460 batadv_dbg(BATADV_DBG_TT, bat_priv,
284 "Re-adding pending client %pM\n", addr); 461 "Re-adding pending client %pM (vid: %d)\n",
462 addr, BATADV_PRINT_VID(vid));
285 /* whatever the reason why the PENDING flag was set, 463 /* whatever the reason why the PENDING flag was set,
286 * this is a client which was enqueued to be removed in 464 * this is a client which was enqueued to be removed in
287 * this orig_interval. Since it popped up again, the 465 * this orig_interval. Since it popped up again, the
@@ -293,8 +471,8 @@ void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
293 471
294 if (tt_local->common.flags & BATADV_TT_CLIENT_ROAM) { 472 if (tt_local->common.flags & BATADV_TT_CLIENT_ROAM) {
295 batadv_dbg(BATADV_DBG_TT, bat_priv, 473 batadv_dbg(BATADV_DBG_TT, bat_priv,
296 "Roaming client %pM came back to its original location\n", 474 "Roaming client %pM (vid: %d) came back to its original location\n",
297 addr); 475 addr, BATADV_PRINT_VID(vid));
298 /* the ROAM flag is set because this client roamed away 476 /* the ROAM flag is set because this client roamed away
299 * and the node got a roaming_advertisement message. Now 477 * and the node got a roaming_advertisement message. Now
300 * that the client popped up again at its original 478 * that the client popped up again at its original
@@ -311,7 +489,8 @@ void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
311 goto out; 489 goto out;
312 490
313 batadv_dbg(BATADV_DBG_TT, bat_priv, 491 batadv_dbg(BATADV_DBG_TT, bat_priv,
314 "Creating new local tt entry: %pM (ttvn: %d)\n", addr, 492 "Creating new local tt entry: %pM (vid: %d, ttvn: %d)\n",
493 addr, BATADV_PRINT_VID(vid),
315 (uint8_t)atomic_read(&bat_priv->tt.vn)); 494 (uint8_t)atomic_read(&bat_priv->tt.vn));
316 495
317 memcpy(tt_local->common.addr, addr, ETH_ALEN); 496 memcpy(tt_local->common.addr, addr, ETH_ALEN);
@@ -320,6 +499,7 @@ void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
320 * (consistency check) 499 * (consistency check)
321 */ 500 */
322 tt_local->common.flags = BATADV_TT_CLIENT_NEW; 501 tt_local->common.flags = BATADV_TT_CLIENT_NEW;
502 tt_local->common.vid = vid;
323 if (batadv_is_wifi_iface(ifindex)) 503 if (batadv_is_wifi_iface(ifindex))
324 tt_local->common.flags |= BATADV_TT_CLIENT_WIFI; 504 tt_local->common.flags |= BATADV_TT_CLIENT_WIFI;
325 atomic_set(&tt_local->common.refcount, 2); 505 atomic_set(&tt_local->common.refcount, 2);
@@ -331,7 +511,7 @@ void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
331 tt_local->common.flags |= BATADV_TT_CLIENT_NOPURGE; 511 tt_local->common.flags |= BATADV_TT_CLIENT_NOPURGE;
332 512
333 hash_added = batadv_hash_add(bat_priv->tt.local_hash, batadv_compare_tt, 513 hash_added = batadv_hash_add(bat_priv->tt.local_hash, batadv_compare_tt,
334 batadv_choose_orig, &tt_local->common, 514 batadv_choose_tt, &tt_local->common,
335 &tt_local->common.hash_entry); 515 &tt_local->common.hash_entry);
336 516
337 if (unlikely(hash_added != 0)) { 517 if (unlikely(hash_added != 0)) {
@@ -353,6 +533,7 @@ check_roaming:
353 rcu_read_lock(); 533 rcu_read_lock();
354 hlist_for_each_entry_rcu(orig_entry, head, list) { 534 hlist_for_each_entry_rcu(orig_entry, head, list) {
355 batadv_send_roam_adv(bat_priv, tt_global->common.addr, 535 batadv_send_roam_adv(bat_priv, tt_global->common.addr,
536 tt_global->common.vid,
356 orig_entry->orig_node); 537 orig_entry->orig_node);
357 } 538 }
358 rcu_read_unlock(); 539 rcu_read_unlock();
@@ -376,71 +557,192 @@ out:
376 batadv_tt_global_entry_free_ref(tt_global); 557 batadv_tt_global_entry_free_ref(tt_global);
377} 558}
378 559
379static void batadv_tt_realloc_packet_buff(unsigned char **packet_buff, 560/**
380 int *packet_buff_len, 561 * batadv_tt_prepare_tvlv_global_data - prepare the TVLV TT header to send
381 int min_packet_len, 562 * within a TT Response directed to another node
382 int new_packet_len) 563 * @orig_node: originator for which the TT data has to be prepared
564 * @tt_data: uninitialised pointer to the address of the TVLV buffer
565 * @tt_change: uninitialised pointer to the address of the area where the TT
566 * changed can be stored
567 * @tt_len: pointer to the length to reserve to the tt_change. if -1 this
568 * function reserves the amount of space needed to send the entire global TT
569 * table. In case of success the value is updated with the real amount of
570 * reserved bytes
571
572 * Allocate the needed amount of memory for the entire TT TVLV and write its
573 * header made up by one tvlv_tt_data object and a series of tvlv_tt_vlan_data
574 * objects, one per active VLAN served by the originator node.
575 *
576 * Return the size of the allocated buffer or 0 in case of failure.
577 */
578static uint16_t
579batadv_tt_prepare_tvlv_global_data(struct batadv_orig_node *orig_node,
580 struct batadv_tvlv_tt_data **tt_data,
581 struct batadv_tvlv_tt_change **tt_change,
582 int32_t *tt_len)
383{ 583{
384 unsigned char *new_buff; 584 uint16_t num_vlan = 0, num_entries = 0, change_offset, tvlv_len;
585 struct batadv_tvlv_tt_vlan_data *tt_vlan;
586 struct batadv_orig_node_vlan *vlan;
587 uint8_t *tt_change_ptr;
588
589 rcu_read_lock();
590 list_for_each_entry_rcu(vlan, &orig_node->vlan_list, list) {
591 num_vlan++;
592 num_entries += atomic_read(&vlan->tt.num_entries);
593 }
594
595 change_offset = sizeof(**tt_data);
596 change_offset += num_vlan * sizeof(*tt_vlan);
385 597
386 new_buff = kmalloc(new_packet_len, GFP_ATOMIC); 598 /* if tt_len is negative, allocate the space needed by the full table */
599 if (*tt_len < 0)
600 *tt_len = batadv_tt_len(num_entries);
387 601
388 /* keep old buffer if kmalloc should fail */ 602 tvlv_len = *tt_len;
389 if (new_buff) { 603 tvlv_len += change_offset;
390 memcpy(new_buff, *packet_buff, min_packet_len); 604
391 kfree(*packet_buff); 605 *tt_data = kmalloc(tvlv_len, GFP_ATOMIC);
392 *packet_buff = new_buff; 606 if (!*tt_data) {
393 *packet_buff_len = new_packet_len; 607 *tt_len = 0;
608 goto out;
394 } 609 }
610
611 (*tt_data)->flags = BATADV_NO_FLAGS;
612 (*tt_data)->ttvn = atomic_read(&orig_node->last_ttvn);
613 (*tt_data)->num_vlan = htons(num_vlan);
614
615 tt_vlan = (struct batadv_tvlv_tt_vlan_data *)(*tt_data + 1);
616 list_for_each_entry_rcu(vlan, &orig_node->vlan_list, list) {
617 tt_vlan->vid = htons(vlan->vid);
618 tt_vlan->crc = htonl(vlan->tt.crc);
619
620 tt_vlan++;
621 }
622
623 tt_change_ptr = (uint8_t *)*tt_data + change_offset;
624 *tt_change = (struct batadv_tvlv_tt_change *)tt_change_ptr;
625
626out:
627 rcu_read_unlock();
628 return tvlv_len;
395} 629}
396 630
397static void batadv_tt_prepare_packet_buff(struct batadv_priv *bat_priv, 631/**
398 unsigned char **packet_buff, 632 * batadv_tt_prepare_tvlv_local_data - allocate and prepare the TT TVLV for this
399 int *packet_buff_len, 633 * node
400 int min_packet_len) 634 * @bat_priv: the bat priv with all the soft interface information
401{ 635 * @tt_data: uninitialised pointer to the address of the TVLV buffer
402 int req_len; 636 * @tt_change: uninitialised pointer to the address of the area where the TT
637 * changes can be stored
638 * @tt_len: pointer to the length to reserve to the tt_change. if -1 this
639 * function reserves the amount of space needed to send the entire local TT
640 * table. In case of success the value is updated with the real amount of
641 * reserved bytes
642 *
643 * Allocate the needed amount of memory for the entire TT TVLV and write its
644 * header made up by one tvlv_tt_data object and a series of tvlv_tt_vlan_data
645 * objects, one per active VLAN.
646 *
647 * Return the size of the allocated buffer or 0 in case of failure.
648 */
649static uint16_t
650batadv_tt_prepare_tvlv_local_data(struct batadv_priv *bat_priv,
651 struct batadv_tvlv_tt_data **tt_data,
652 struct batadv_tvlv_tt_change **tt_change,
653 int32_t *tt_len)
654{
655 struct batadv_tvlv_tt_vlan_data *tt_vlan;
656 struct batadv_softif_vlan *vlan;
657 uint16_t num_vlan = 0, num_entries = 0, tvlv_len;
658 uint8_t *tt_change_ptr;
659 int change_offset;
403 660
404 req_len = min_packet_len; 661 rcu_read_lock();
405 req_len += batadv_tt_len(atomic_read(&bat_priv->tt.local_changes)); 662 hlist_for_each_entry_rcu(vlan, &bat_priv->softif_vlan_list, list) {
663 num_vlan++;
664 num_entries += atomic_read(&vlan->tt.num_entries);
665 }
406 666
407 /* if we have too many changes for one packet don't send any 667 change_offset = sizeof(**tt_data);
408 * and wait for the tt table request which will be fragmented 668 change_offset += num_vlan * sizeof(*tt_vlan);
409 */
410 if (req_len > bat_priv->soft_iface->mtu)
411 req_len = min_packet_len;
412 669
413 batadv_tt_realloc_packet_buff(packet_buff, packet_buff_len, 670 /* if tt_len is negative, allocate the space needed by the full table */
414 min_packet_len, req_len); 671 if (*tt_len < 0)
672 *tt_len = batadv_tt_len(num_entries);
673
674 tvlv_len = *tt_len;
675 tvlv_len += change_offset;
676
677 *tt_data = kmalloc(tvlv_len, GFP_ATOMIC);
678 if (!*tt_data) {
679 tvlv_len = 0;
680 goto out;
681 }
682
683 (*tt_data)->flags = BATADV_NO_FLAGS;
684 (*tt_data)->ttvn = atomic_read(&bat_priv->tt.vn);
685 (*tt_data)->num_vlan = htons(num_vlan);
686
687 tt_vlan = (struct batadv_tvlv_tt_vlan_data *)(*tt_data + 1);
688 hlist_for_each_entry_rcu(vlan, &bat_priv->softif_vlan_list, list) {
689 tt_vlan->vid = htons(vlan->vid);
690 tt_vlan->crc = htonl(vlan->tt.crc);
691
692 tt_vlan++;
693 }
694
695 tt_change_ptr = (uint8_t *)*tt_data + change_offset;
696 *tt_change = (struct batadv_tvlv_tt_change *)tt_change_ptr;
697
698out:
699 rcu_read_unlock();
700 return tvlv_len;
415} 701}
416 702
417static int batadv_tt_changes_fill_buff(struct batadv_priv *bat_priv, 703/**
418 unsigned char **packet_buff, 704 * batadv_tt_tvlv_container_update - update the translation table tvlv container
419 int *packet_buff_len, 705 * after local tt changes have been committed
420 int min_packet_len) 706 * @bat_priv: the bat priv with all the soft interface information
707 */
708static void batadv_tt_tvlv_container_update(struct batadv_priv *bat_priv)
421{ 709{
422 struct batadv_tt_change_node *entry, *safe; 710 struct batadv_tt_change_node *entry, *safe;
423 int count = 0, tot_changes = 0, new_len; 711 struct batadv_tvlv_tt_data *tt_data;
424 unsigned char *tt_buff; 712 struct batadv_tvlv_tt_change *tt_change;
713 int tt_diff_len, tt_change_len = 0;
714 int tt_diff_entries_num = 0, tt_diff_entries_count = 0;
715 uint16_t tvlv_len;
716
717 tt_diff_entries_num = atomic_read(&bat_priv->tt.local_changes);
718 tt_diff_len = batadv_tt_len(tt_diff_entries_num);
719
720 /* if we have too many changes for one packet don't send any
721 * and wait for the tt table request which will be fragmented
722 */
723 if (tt_diff_len > bat_priv->soft_iface->mtu)
724 tt_diff_len = 0;
425 725
426 batadv_tt_prepare_packet_buff(bat_priv, packet_buff, 726 tvlv_len = batadv_tt_prepare_tvlv_local_data(bat_priv, &tt_data,
427 packet_buff_len, min_packet_len); 727 &tt_change, &tt_diff_len);
728 if (!tvlv_len)
729 return;
428 730
429 new_len = *packet_buff_len - min_packet_len; 731 tt_data->flags = BATADV_TT_OGM_DIFF;
430 tt_buff = *packet_buff + min_packet_len;
431 732
432 if (new_len > 0) 733 if (tt_diff_len == 0)
433 tot_changes = new_len / batadv_tt_len(1); 734 goto container_register;
434 735
435 spin_lock_bh(&bat_priv->tt.changes_list_lock); 736 spin_lock_bh(&bat_priv->tt.changes_list_lock);
436 atomic_set(&bat_priv->tt.local_changes, 0); 737 atomic_set(&bat_priv->tt.local_changes, 0);
437 738
438 list_for_each_entry_safe(entry, safe, &bat_priv->tt.changes_list, 739 list_for_each_entry_safe(entry, safe, &bat_priv->tt.changes_list,
439 list) { 740 list) {
440 if (count < tot_changes) { 741 if (tt_diff_entries_count < tt_diff_entries_num) {
441 memcpy(tt_buff + batadv_tt_len(count), 742 memcpy(tt_change + tt_diff_entries_count,
442 &entry->change, sizeof(struct batadv_tt_change)); 743 &entry->change,
443 count++; 744 sizeof(struct batadv_tvlv_tt_change));
745 tt_diff_entries_count++;
444 } 746 }
445 list_del(&entry->list); 747 list_del(&entry->list);
446 kfree(entry); 748 kfree(entry);
@@ -452,20 +754,25 @@ static int batadv_tt_changes_fill_buff(struct batadv_priv *bat_priv,
452 kfree(bat_priv->tt.last_changeset); 754 kfree(bat_priv->tt.last_changeset);
453 bat_priv->tt.last_changeset_len = 0; 755 bat_priv->tt.last_changeset_len = 0;
454 bat_priv->tt.last_changeset = NULL; 756 bat_priv->tt.last_changeset = NULL;
757 tt_change_len = batadv_tt_len(tt_diff_entries_count);
455 /* check whether this new OGM has no changes due to size problems */ 758 /* check whether this new OGM has no changes due to size problems */
456 if (new_len > 0) { 759 if (tt_diff_entries_count > 0) {
457 /* if kmalloc() fails we will reply with the full table 760 /* if kmalloc() fails we will reply with the full table
458 * instead of providing the diff 761 * instead of providing the diff
459 */ 762 */
460 bat_priv->tt.last_changeset = kmalloc(new_len, GFP_ATOMIC); 763 bat_priv->tt.last_changeset = kzalloc(tt_diff_len, GFP_ATOMIC);
461 if (bat_priv->tt.last_changeset) { 764 if (bat_priv->tt.last_changeset) {
462 memcpy(bat_priv->tt.last_changeset, tt_buff, new_len); 765 memcpy(bat_priv->tt.last_changeset,
463 bat_priv->tt.last_changeset_len = new_len; 766 tt_change, tt_change_len);
767 bat_priv->tt.last_changeset_len = tt_diff_len;
464 } 768 }
465 } 769 }
466 spin_unlock_bh(&bat_priv->tt.last_changeset_lock); 770 spin_unlock_bh(&bat_priv->tt.last_changeset_lock);
467 771
468 return count; 772container_register:
773 batadv_tvlv_container_register(bat_priv, BATADV_TVLV_TT, 1, tt_data,
774 tvlv_len);
775 kfree(tt_data);
469} 776}
470 777
471int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset) 778int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset)
@@ -476,7 +783,9 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset)
476 struct batadv_tt_common_entry *tt_common_entry; 783 struct batadv_tt_common_entry *tt_common_entry;
477 struct batadv_tt_local_entry *tt_local; 784 struct batadv_tt_local_entry *tt_local;
478 struct batadv_hard_iface *primary_if; 785 struct batadv_hard_iface *primary_if;
786 struct batadv_softif_vlan *vlan;
479 struct hlist_head *head; 787 struct hlist_head *head;
788 unsigned short vid;
480 uint32_t i; 789 uint32_t i;
481 int last_seen_secs; 790 int last_seen_secs;
482 int last_seen_msecs; 791 int last_seen_msecs;
@@ -489,11 +798,10 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset)
489 goto out; 798 goto out;
490 799
491 seq_printf(seq, 800 seq_printf(seq,
492 "Locally retrieved addresses (from %s) announced via TT (TTVN: %u CRC: %#.4x):\n", 801 "Locally retrieved addresses (from %s) announced via TT (TTVN: %u):\n",
493 net_dev->name, (uint8_t)atomic_read(&bat_priv->tt.vn), 802 net_dev->name, (uint8_t)atomic_read(&bat_priv->tt.vn));
494 bat_priv->tt.local_crc); 803 seq_printf(seq, " %-13s %s %-7s %-9s (%-10s)\n", "Client", "VID",
495 seq_printf(seq, " %-13s %-7s %-10s\n", "Client", "Flags", 804 "Flags", "Last seen", "CRC");
496 "Last seen");
497 805
498 for (i = 0; i < hash->size; i++) { 806 for (i = 0; i < hash->size; i++) {
499 head = &hash->table[i]; 807 head = &hash->table[i];
@@ -504,6 +812,7 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset)
504 tt_local = container_of(tt_common_entry, 812 tt_local = container_of(tt_common_entry,
505 struct batadv_tt_local_entry, 813 struct batadv_tt_local_entry,
506 common); 814 common);
815 vid = tt_common_entry->vid;
507 last_seen_jiffies = jiffies - tt_local->last_seen; 816 last_seen_jiffies = jiffies - tt_local->last_seen;
508 last_seen_msecs = jiffies_to_msecs(last_seen_jiffies); 817 last_seen_msecs = jiffies_to_msecs(last_seen_jiffies);
509 last_seen_secs = last_seen_msecs / 1000; 818 last_seen_secs = last_seen_msecs / 1000;
@@ -511,8 +820,17 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset)
511 820
512 no_purge = tt_common_entry->flags & np_flag; 821 no_purge = tt_common_entry->flags & np_flag;
513 822
514 seq_printf(seq, " * %pM [%c%c%c%c%c] %3u.%03u\n", 823 vlan = batadv_softif_vlan_get(bat_priv, vid);
824 if (!vlan) {
825 seq_printf(seq, "Cannot retrieve VLAN %d\n",
826 BATADV_PRINT_VID(vid));
827 continue;
828 }
829
830 seq_printf(seq,
831 " * %pM %4i [%c%c%c%c%c] %3u.%03u (%#.8x)\n",
515 tt_common_entry->addr, 832 tt_common_entry->addr,
833 BATADV_PRINT_VID(tt_common_entry->vid),
516 (tt_common_entry->flags & 834 (tt_common_entry->flags &
517 BATADV_TT_CLIENT_ROAM ? 'R' : '.'), 835 BATADV_TT_CLIENT_ROAM ? 'R' : '.'),
518 no_purge ? 'P' : '.', 836 no_purge ? 'P' : '.',
@@ -523,7 +841,10 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset)
523 (tt_common_entry->flags & 841 (tt_common_entry->flags &
524 BATADV_TT_CLIENT_WIFI ? 'W' : '.'), 842 BATADV_TT_CLIENT_WIFI ? 'W' : '.'),
525 no_purge ? 0 : last_seen_secs, 843 no_purge ? 0 : last_seen_secs,
526 no_purge ? 0 : last_seen_msecs); 844 no_purge ? 0 : last_seen_msecs,
845 vlan->tt.crc);
846
847 batadv_softif_vlan_free_ref(vlan);
527 } 848 }
528 rcu_read_unlock(); 849 rcu_read_unlock();
529 } 850 }
@@ -547,27 +868,29 @@ batadv_tt_local_set_pending(struct batadv_priv *bat_priv,
547 tt_local_entry->common.flags |= BATADV_TT_CLIENT_PENDING; 868 tt_local_entry->common.flags |= BATADV_TT_CLIENT_PENDING;
548 869
549 batadv_dbg(BATADV_DBG_TT, bat_priv, 870 batadv_dbg(BATADV_DBG_TT, bat_priv,
550 "Local tt entry (%pM) pending to be removed: %s\n", 871 "Local tt entry (%pM, vid: %d) pending to be removed: %s\n",
551 tt_local_entry->common.addr, message); 872 tt_local_entry->common.addr,
873 BATADV_PRINT_VID(tt_local_entry->common.vid), message);
552} 874}
553 875
554/** 876/**
555 * batadv_tt_local_remove - logically remove an entry from the local table 877 * batadv_tt_local_remove - logically remove an entry from the local table
556 * @bat_priv: the bat priv with all the soft interface information 878 * @bat_priv: the bat priv with all the soft interface information
557 * @addr: the MAC address of the client to remove 879 * @addr: the MAC address of the client to remove
880 * @vid: VLAN identifier
558 * @message: message to append to the log on deletion 881 * @message: message to append to the log on deletion
559 * @roaming: true if the deletion is due to a roaming event 882 * @roaming: true if the deletion is due to a roaming event
560 * 883 *
561 * Returns the flags assigned to the local entry before being deleted 884 * Returns the flags assigned to the local entry before being deleted
562 */ 885 */
563uint16_t batadv_tt_local_remove(struct batadv_priv *bat_priv, 886uint16_t batadv_tt_local_remove(struct batadv_priv *bat_priv,
564 const uint8_t *addr, const char *message, 887 const uint8_t *addr, unsigned short vid,
565 bool roaming) 888 const char *message, bool roaming)
566{ 889{
567 struct batadv_tt_local_entry *tt_local_entry; 890 struct batadv_tt_local_entry *tt_local_entry;
568 uint16_t flags, curr_flags = BATADV_NO_FLAGS; 891 uint16_t flags, curr_flags = BATADV_NO_FLAGS;
569 892
570 tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr); 893 tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr, vid);
571 if (!tt_local_entry) 894 if (!tt_local_entry)
572 goto out; 895 goto out;
573 896
@@ -784,7 +1107,7 @@ batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry *tt_global,
784 1107
785 INIT_HLIST_NODE(&orig_entry->list); 1108 INIT_HLIST_NODE(&orig_entry->list);
786 atomic_inc(&orig_node->refcount); 1109 atomic_inc(&orig_node->refcount);
787 atomic_inc(&orig_node->tt_size); 1110 batadv_tt_global_size_inc(orig_node, tt_global->common.vid);
788 orig_entry->orig_node = orig_node; 1111 orig_entry->orig_node = orig_node;
789 orig_entry->ttvn = ttvn; 1112 orig_entry->ttvn = ttvn;
790 atomic_set(&orig_entry->refcount, 2); 1113 atomic_set(&orig_entry->refcount, 2);
@@ -803,6 +1126,7 @@ out:
803 * @bat_priv: the bat priv with all the soft interface information 1126 * @bat_priv: the bat priv with all the soft interface information
804 * @orig_node: the originator announcing the client 1127 * @orig_node: the originator announcing the client
805 * @tt_addr: the mac address of the non-mesh client 1128 * @tt_addr: the mac address of the non-mesh client
1129 * @vid: VLAN identifier
806 * @flags: TT flags that have to be set for this non-mesh client 1130 * @flags: TT flags that have to be set for this non-mesh client
807 * @ttvn: the tt version number ever announcing this non-mesh client 1131 * @ttvn: the tt version number ever announcing this non-mesh client
808 * 1132 *
@@ -813,21 +1137,28 @@ out:
813 * If a TT local entry exists for this non-mesh client remove it. 1137 * If a TT local entry exists for this non-mesh client remove it.
814 * 1138 *
815 * The caller must hold orig_node refcount. 1139 * The caller must hold orig_node refcount.
1140 *
1141 * Return true if the new entry has been added, false otherwise
816 */ 1142 */
817int batadv_tt_global_add(struct batadv_priv *bat_priv, 1143static bool batadv_tt_global_add(struct batadv_priv *bat_priv,
818 struct batadv_orig_node *orig_node, 1144 struct batadv_orig_node *orig_node,
819 const unsigned char *tt_addr, uint16_t flags, 1145 const unsigned char *tt_addr,
820 uint8_t ttvn) 1146 unsigned short vid, uint16_t flags,
1147 uint8_t ttvn)
821{ 1148{
822 struct batadv_tt_global_entry *tt_global_entry; 1149 struct batadv_tt_global_entry *tt_global_entry;
823 struct batadv_tt_local_entry *tt_local_entry; 1150 struct batadv_tt_local_entry *tt_local_entry;
824 int ret = 0; 1151 bool ret = false;
825 int hash_added; 1152 int hash_added;
826 struct batadv_tt_common_entry *common; 1153 struct batadv_tt_common_entry *common;
827 uint16_t local_flags; 1154 uint16_t local_flags;
828 1155
829 tt_global_entry = batadv_tt_global_hash_find(bat_priv, tt_addr); 1156 /* ignore global entries from backbone nodes */
830 tt_local_entry = batadv_tt_local_hash_find(bat_priv, tt_addr); 1157 if (batadv_bla_is_backbone_gw_orig(bat_priv, orig_node->orig, vid))
1158 return true;
1159
1160 tt_global_entry = batadv_tt_global_hash_find(bat_priv, tt_addr, vid);
1161 tt_local_entry = batadv_tt_local_hash_find(bat_priv, tt_addr, vid);
831 1162
832 /* if the node already has a local client for this entry, it has to wait 1163 /* if the node already has a local client for this entry, it has to wait
833 * for a roaming advertisement instead of manually messing up the global 1164 * for a roaming advertisement instead of manually messing up the global
@@ -844,6 +1175,7 @@ int batadv_tt_global_add(struct batadv_priv *bat_priv,
844 1175
845 common = &tt_global_entry->common; 1176 common = &tt_global_entry->common;
846 memcpy(common->addr, tt_addr, ETH_ALEN); 1177 memcpy(common->addr, tt_addr, ETH_ALEN);
1178 common->vid = vid;
847 1179
848 common->flags = flags; 1180 common->flags = flags;
849 tt_global_entry->roam_at = 0; 1181 tt_global_entry->roam_at = 0;
@@ -861,7 +1193,7 @@ int batadv_tt_global_add(struct batadv_priv *bat_priv,
861 1193
862 hash_added = batadv_hash_add(bat_priv->tt.global_hash, 1194 hash_added = batadv_hash_add(bat_priv->tt.global_hash,
863 batadv_compare_tt, 1195 batadv_compare_tt,
864 batadv_choose_orig, common, 1196 batadv_choose_tt, common,
865 &common->hash_entry); 1197 &common->hash_entry);
866 1198
867 if (unlikely(hash_added != 0)) { 1199 if (unlikely(hash_added != 0)) {
@@ -920,14 +1252,15 @@ add_orig_entry:
920 batadv_tt_global_orig_entry_add(tt_global_entry, orig_node, ttvn); 1252 batadv_tt_global_orig_entry_add(tt_global_entry, orig_node, ttvn);
921 1253
922 batadv_dbg(BATADV_DBG_TT, bat_priv, 1254 batadv_dbg(BATADV_DBG_TT, bat_priv,
923 "Creating new global tt entry: %pM (via %pM)\n", 1255 "Creating new global tt entry: %pM (vid: %d, via %pM)\n",
924 common->addr, orig_node->orig); 1256 common->addr, BATADV_PRINT_VID(common->vid),
925 ret = 1; 1257 orig_node->orig);
1258 ret = true;
926 1259
927out_remove: 1260out_remove:
928 1261
929 /* remove address from local hash if present */ 1262 /* remove address from local hash if present */
930 local_flags = batadv_tt_local_remove(bat_priv, tt_addr, 1263 local_flags = batadv_tt_local_remove(bat_priv, tt_addr, vid,
931 "global tt received", 1264 "global tt received",
932 flags & BATADV_TT_CLIENT_ROAM); 1265 flags & BATADV_TT_CLIENT_ROAM);
933 tt_global_entry->common.flags |= local_flags & BATADV_TT_CLIENT_WIFI; 1266 tt_global_entry->common.flags |= local_flags & BATADV_TT_CLIENT_WIFI;
@@ -988,42 +1321,71 @@ static void
988batadv_tt_global_print_entry(struct batadv_tt_global_entry *tt_global_entry, 1321batadv_tt_global_print_entry(struct batadv_tt_global_entry *tt_global_entry,
989 struct seq_file *seq) 1322 struct seq_file *seq)
990{ 1323{
991 struct hlist_head *head;
992 struct batadv_tt_orig_list_entry *orig_entry, *best_entry; 1324 struct batadv_tt_orig_list_entry *orig_entry, *best_entry;
993 struct batadv_tt_common_entry *tt_common_entry; 1325 struct batadv_tt_common_entry *tt_common_entry;
994 uint16_t flags; 1326 struct batadv_orig_node_vlan *vlan;
1327 struct hlist_head *head;
995 uint8_t last_ttvn; 1328 uint8_t last_ttvn;
1329 uint16_t flags;
996 1330
997 tt_common_entry = &tt_global_entry->common; 1331 tt_common_entry = &tt_global_entry->common;
998 flags = tt_common_entry->flags; 1332 flags = tt_common_entry->flags;
999 1333
1000 best_entry = batadv_transtable_best_orig(tt_global_entry); 1334 best_entry = batadv_transtable_best_orig(tt_global_entry);
1001 if (best_entry) { 1335 if (best_entry) {
1336 vlan = batadv_orig_node_vlan_get(best_entry->orig_node,
1337 tt_common_entry->vid);
1338 if (!vlan) {
1339 seq_printf(seq,
1340 " * Cannot retrieve VLAN %d for originator %pM\n",
1341 BATADV_PRINT_VID(tt_common_entry->vid),
1342 best_entry->orig_node->orig);
1343 goto print_list;
1344 }
1345
1002 last_ttvn = atomic_read(&best_entry->orig_node->last_ttvn); 1346 last_ttvn = atomic_read(&best_entry->orig_node->last_ttvn);
1003 seq_printf(seq, 1347 seq_printf(seq,
1004 " %c %pM (%3u) via %pM (%3u) (%#.4x) [%c%c%c]\n", 1348 " %c %pM %4i (%3u) via %pM (%3u) (%#.8x) [%c%c%c]\n",
1005 '*', tt_global_entry->common.addr, 1349 '*', tt_global_entry->common.addr,
1350 BATADV_PRINT_VID(tt_global_entry->common.vid),
1006 best_entry->ttvn, best_entry->orig_node->orig, 1351 best_entry->ttvn, best_entry->orig_node->orig,
1007 last_ttvn, best_entry->orig_node->tt_crc, 1352 last_ttvn, vlan->tt.crc,
1008 (flags & BATADV_TT_CLIENT_ROAM ? 'R' : '.'), 1353 (flags & BATADV_TT_CLIENT_ROAM ? 'R' : '.'),
1009 (flags & BATADV_TT_CLIENT_WIFI ? 'W' : '.'), 1354 (flags & BATADV_TT_CLIENT_WIFI ? 'W' : '.'),
1010 (flags & BATADV_TT_CLIENT_TEMP ? 'T' : '.')); 1355 (flags & BATADV_TT_CLIENT_TEMP ? 'T' : '.'));
1356
1357 batadv_orig_node_vlan_free_ref(vlan);
1011 } 1358 }
1012 1359
1360print_list:
1013 head = &tt_global_entry->orig_list; 1361 head = &tt_global_entry->orig_list;
1014 1362
1015 hlist_for_each_entry_rcu(orig_entry, head, list) { 1363 hlist_for_each_entry_rcu(orig_entry, head, list) {
1016 if (best_entry == orig_entry) 1364 if (best_entry == orig_entry)
1017 continue; 1365 continue;
1018 1366
1367 vlan = batadv_orig_node_vlan_get(orig_entry->orig_node,
1368 tt_common_entry->vid);
1369 if (!vlan) {
1370 seq_printf(seq,
1371 " + Cannot retrieve VLAN %d for originator %pM\n",
1372 BATADV_PRINT_VID(tt_common_entry->vid),
1373 orig_entry->orig_node->orig);
1374 continue;
1375 }
1376
1019 last_ttvn = atomic_read(&orig_entry->orig_node->last_ttvn); 1377 last_ttvn = atomic_read(&orig_entry->orig_node->last_ttvn);
1020 seq_printf(seq, " %c %pM (%3u) via %pM (%3u) [%c%c%c]\n", 1378 seq_printf(seq,
1379 " %c %pM %4d (%3u) via %pM (%3u) (%#.8x) [%c%c%c]\n",
1021 '+', tt_global_entry->common.addr, 1380 '+', tt_global_entry->common.addr,
1381 BATADV_PRINT_VID(tt_global_entry->common.vid),
1022 orig_entry->ttvn, orig_entry->orig_node->orig, 1382 orig_entry->ttvn, orig_entry->orig_node->orig,
1023 last_ttvn, 1383 last_ttvn, vlan->tt.crc,
1024 (flags & BATADV_TT_CLIENT_ROAM ? 'R' : '.'), 1384 (flags & BATADV_TT_CLIENT_ROAM ? 'R' : '.'),
1025 (flags & BATADV_TT_CLIENT_WIFI ? 'W' : '.'), 1385 (flags & BATADV_TT_CLIENT_WIFI ? 'W' : '.'),
1026 (flags & BATADV_TT_CLIENT_TEMP ? 'T' : '.')); 1386 (flags & BATADV_TT_CLIENT_TEMP ? 'T' : '.'));
1387
1388 batadv_orig_node_vlan_free_ref(vlan);
1027 } 1389 }
1028} 1390}
1029 1391
@@ -1045,9 +1407,9 @@ int batadv_tt_global_seq_print_text(struct seq_file *seq, void *offset)
1045 seq_printf(seq, 1407 seq_printf(seq,
1046 "Globally announced TT entries received via the mesh %s\n", 1408 "Globally announced TT entries received via the mesh %s\n",
1047 net_dev->name); 1409 net_dev->name);
1048 seq_printf(seq, " %-13s %s %-15s %s (%-6s) %s\n", 1410 seq_printf(seq, " %-13s %s %s %-15s %s (%-10s) %s\n",
1049 "Client", "(TTVN)", "Originator", "(Curr TTVN)", "CRC", 1411 "Client", "VID", "(TTVN)", "Originator", "(Curr TTVN)",
1050 "Flags"); 1412 "CRC", "Flags");
1051 1413
1052 for (i = 0; i < hash->size; i++) { 1414 for (i = 0; i < hash->size; i++) {
1053 head = &hash->table[i]; 1415 head = &hash->table[i];
@@ -1080,6 +1442,8 @@ batadv_tt_global_del_orig_list(struct batadv_tt_global_entry *tt_global_entry)
1080 head = &tt_global_entry->orig_list; 1442 head = &tt_global_entry->orig_list;
1081 hlist_for_each_entry_safe(orig_entry, safe, head, list) { 1443 hlist_for_each_entry_safe(orig_entry, safe, head, list) {
1082 hlist_del_rcu(&orig_entry->list); 1444 hlist_del_rcu(&orig_entry->list);
1445 batadv_tt_global_size_dec(orig_entry->orig_node,
1446 tt_global_entry->common.vid);
1083 batadv_tt_orig_list_entry_free_ref(orig_entry); 1447 batadv_tt_orig_list_entry_free_ref(orig_entry);
1084 } 1448 }
1085 spin_unlock_bh(&tt_global_entry->list_lock); 1449 spin_unlock_bh(&tt_global_entry->list_lock);
@@ -1094,16 +1458,21 @@ batadv_tt_global_del_orig_entry(struct batadv_priv *bat_priv,
1094 struct hlist_head *head; 1458 struct hlist_head *head;
1095 struct hlist_node *safe; 1459 struct hlist_node *safe;
1096 struct batadv_tt_orig_list_entry *orig_entry; 1460 struct batadv_tt_orig_list_entry *orig_entry;
1461 unsigned short vid;
1097 1462
1098 spin_lock_bh(&tt_global_entry->list_lock); 1463 spin_lock_bh(&tt_global_entry->list_lock);
1099 head = &tt_global_entry->orig_list; 1464 head = &tt_global_entry->orig_list;
1100 hlist_for_each_entry_safe(orig_entry, safe, head, list) { 1465 hlist_for_each_entry_safe(orig_entry, safe, head, list) {
1101 if (orig_entry->orig_node == orig_node) { 1466 if (orig_entry->orig_node == orig_node) {
1467 vid = tt_global_entry->common.vid;
1102 batadv_dbg(BATADV_DBG_TT, bat_priv, 1468 batadv_dbg(BATADV_DBG_TT, bat_priv,
1103 "Deleting %pM from global tt entry %pM: %s\n", 1469 "Deleting %pM from global tt entry %pM (vid: %d): %s\n",
1104 orig_node->orig, 1470 orig_node->orig,
1105 tt_global_entry->common.addr, message); 1471 tt_global_entry->common.addr,
1472 BATADV_PRINT_VID(vid), message);
1106 hlist_del_rcu(&orig_entry->list); 1473 hlist_del_rcu(&orig_entry->list);
1474 batadv_tt_global_size_dec(orig_node,
1475 tt_global_entry->common.vid);
1107 batadv_tt_orig_list_entry_free_ref(orig_entry); 1476 batadv_tt_orig_list_entry_free_ref(orig_entry);
1108 } 1477 }
1109 } 1478 }
@@ -1150,17 +1519,25 @@ batadv_tt_global_del_roaming(struct batadv_priv *bat_priv,
1150 orig_node, message); 1519 orig_node, message);
1151} 1520}
1152 1521
1153 1522/**
1154 1523 * batadv_tt_global_del - remove a client from the global table
1524 * @bat_priv: the bat priv with all the soft interface information
1525 * @orig_node: an originator serving this client
1526 * @addr: the mac address of the client
1527 * @vid: VLAN identifier
1528 * @message: a message explaining the reason for deleting the client to print
1529 * for debugging purpose
1530 * @roaming: true if the deletion has been triggered by a roaming event
1531 */
1155static void batadv_tt_global_del(struct batadv_priv *bat_priv, 1532static void batadv_tt_global_del(struct batadv_priv *bat_priv,
1156 struct batadv_orig_node *orig_node, 1533 struct batadv_orig_node *orig_node,
1157 const unsigned char *addr, 1534 const unsigned char *addr, unsigned short vid,
1158 const char *message, bool roaming) 1535 const char *message, bool roaming)
1159{ 1536{
1160 struct batadv_tt_global_entry *tt_global_entry; 1537 struct batadv_tt_global_entry *tt_global_entry;
1161 struct batadv_tt_local_entry *local_entry = NULL; 1538 struct batadv_tt_local_entry *local_entry = NULL;
1162 1539
1163 tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr); 1540 tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr, vid);
1164 if (!tt_global_entry) 1541 if (!tt_global_entry)
1165 goto out; 1542 goto out;
1166 1543
@@ -1189,7 +1566,8 @@ static void batadv_tt_global_del(struct batadv_priv *bat_priv,
1189 * the global entry, since it is useless now. 1566 * the global entry, since it is useless now.
1190 */ 1567 */
1191 local_entry = batadv_tt_local_hash_find(bat_priv, 1568 local_entry = batadv_tt_local_hash_find(bat_priv,
1192 tt_global_entry->common.addr); 1569 tt_global_entry->common.addr,
1570 vid);
1193 if (local_entry) { 1571 if (local_entry) {
1194 /* local entry exists, case 2: client roamed to us. */ 1572 /* local entry exists, case 2: client roamed to us. */
1195 batadv_tt_global_del_orig_list(tt_global_entry); 1573 batadv_tt_global_del_orig_list(tt_global_entry);
@@ -1207,8 +1585,18 @@ out:
1207 batadv_tt_local_entry_free_ref(local_entry); 1585 batadv_tt_local_entry_free_ref(local_entry);
1208} 1586}
1209 1587
1588/**
1589 * batadv_tt_global_del_orig - remove all the TT global entries belonging to the
1590 * given originator matching the provided vid
1591 * @bat_priv: the bat priv with all the soft interface information
1592 * @orig_node: the originator owning the entries to remove
1593 * @match_vid: the VLAN identifier to match. If negative all the entries will be
1594 * removed
1595 * @message: debug message to print as "reason"
1596 */
1210void batadv_tt_global_del_orig(struct batadv_priv *bat_priv, 1597void batadv_tt_global_del_orig(struct batadv_priv *bat_priv,
1211 struct batadv_orig_node *orig_node, 1598 struct batadv_orig_node *orig_node,
1599 int32_t match_vid,
1212 const char *message) 1600 const char *message)
1213{ 1601{
1214 struct batadv_tt_global_entry *tt_global; 1602 struct batadv_tt_global_entry *tt_global;
@@ -1218,6 +1606,7 @@ void batadv_tt_global_del_orig(struct batadv_priv *bat_priv,
1218 struct hlist_node *safe; 1606 struct hlist_node *safe;
1219 struct hlist_head *head; 1607 struct hlist_head *head;
1220 spinlock_t *list_lock; /* protects write access to the hash lists */ 1608 spinlock_t *list_lock; /* protects write access to the hash lists */
1609 unsigned short vid;
1221 1610
1222 if (!hash) 1611 if (!hash)
1223 return; 1612 return;
@@ -1229,6 +1618,10 @@ void batadv_tt_global_del_orig(struct batadv_priv *bat_priv,
1229 spin_lock_bh(list_lock); 1618 spin_lock_bh(list_lock);
1230 hlist_for_each_entry_safe(tt_common_entry, safe, 1619 hlist_for_each_entry_safe(tt_common_entry, safe,
1231 head, hash_entry) { 1620 head, hash_entry) {
1621 /* remove only matching entries */
1622 if (match_vid >= 0 && tt_common_entry->vid != match_vid)
1623 continue;
1624
1232 tt_global = container_of(tt_common_entry, 1625 tt_global = container_of(tt_common_entry,
1233 struct batadv_tt_global_entry, 1626 struct batadv_tt_global_entry,
1234 common); 1627 common);
@@ -1237,9 +1630,11 @@ void batadv_tt_global_del_orig(struct batadv_priv *bat_priv,
1237 orig_node, message); 1630 orig_node, message);
1238 1631
1239 if (hlist_empty(&tt_global->orig_list)) { 1632 if (hlist_empty(&tt_global->orig_list)) {
1633 vid = tt_global->common.vid;
1240 batadv_dbg(BATADV_DBG_TT, bat_priv, 1634 batadv_dbg(BATADV_DBG_TT, bat_priv,
1241 "Deleting global tt entry %pM: %s\n", 1635 "Deleting global tt entry %pM (vid: %d): %s\n",
1242 tt_global->common.addr, message); 1636 tt_global->common.addr,
1637 BATADV_PRINT_VID(vid), message);
1243 hlist_del_rcu(&tt_common_entry->hash_entry); 1638 hlist_del_rcu(&tt_common_entry->hash_entry);
1244 batadv_tt_global_entry_free_ref(tt_global); 1639 batadv_tt_global_entry_free_ref(tt_global);
1245 } 1640 }
@@ -1297,8 +1692,10 @@ static void batadv_tt_global_purge(struct batadv_priv *bat_priv)
1297 continue; 1692 continue;
1298 1693
1299 batadv_dbg(BATADV_DBG_TT, bat_priv, 1694 batadv_dbg(BATADV_DBG_TT, bat_priv,
1300 "Deleting global tt entry (%pM): %s\n", 1695 "Deleting global tt entry %pM (vid: %d): %s\n",
1301 tt_global->common.addr, msg); 1696 tt_global->common.addr,
1697 BATADV_PRINT_VID(tt_global->common.vid),
1698 msg);
1302 1699
1303 hlist_del_rcu(&tt_common->hash_entry); 1700 hlist_del_rcu(&tt_common->hash_entry);
1304 1701
@@ -1357,23 +1754,49 @@ _batadv_is_ap_isolated(struct batadv_tt_local_entry *tt_local_entry,
1357 return ret; 1754 return ret;
1358} 1755}
1359 1756
1757/**
1758 * batadv_transtable_search - get the mesh destination for a given client
1759 * @bat_priv: the bat priv with all the soft interface information
1760 * @src: mac address of the source client
1761 * @addr: mac address of the destination client
1762 * @vid: VLAN identifier
1763 *
1764 * Returns a pointer to the originator that was selected as destination in the
1765 * mesh for contacting the client 'addr', NULL otherwise.
1766 * In case of multiple originators serving the same client, the function returns
1767 * the best one (best in terms of metric towards the destination node).
1768 *
1769 * If the two clients are AP isolated the function returns NULL.
1770 */
1360struct batadv_orig_node *batadv_transtable_search(struct batadv_priv *bat_priv, 1771struct batadv_orig_node *batadv_transtable_search(struct batadv_priv *bat_priv,
1361 const uint8_t *src, 1772 const uint8_t *src,
1362 const uint8_t *addr) 1773 const uint8_t *addr,
1774 unsigned short vid)
1363{ 1775{
1364 struct batadv_tt_local_entry *tt_local_entry = NULL; 1776 struct batadv_tt_local_entry *tt_local_entry = NULL;
1365 struct batadv_tt_global_entry *tt_global_entry = NULL; 1777 struct batadv_tt_global_entry *tt_global_entry = NULL;
1366 struct batadv_orig_node *orig_node = NULL; 1778 struct batadv_orig_node *orig_node = NULL;
1367 struct batadv_tt_orig_list_entry *best_entry; 1779 struct batadv_tt_orig_list_entry *best_entry;
1780 bool ap_isolation_enabled = false;
1781 struct batadv_softif_vlan *vlan;
1368 1782
1369 if (src && atomic_read(&bat_priv->ap_isolation)) { 1783 /* if the AP isolation is requested on a VLAN, then check for its
1370 tt_local_entry = batadv_tt_local_hash_find(bat_priv, src); 1784 * setting in the proper VLAN private data structure
1785 */
1786 vlan = batadv_softif_vlan_get(bat_priv, vid);
1787 if (vlan) {
1788 ap_isolation_enabled = atomic_read(&vlan->ap_isolation);
1789 batadv_softif_vlan_free_ref(vlan);
1790 }
1791
1792 if (src && ap_isolation_enabled) {
1793 tt_local_entry = batadv_tt_local_hash_find(bat_priv, src, vid);
1371 if (!tt_local_entry || 1794 if (!tt_local_entry ||
1372 (tt_local_entry->common.flags & BATADV_TT_CLIENT_PENDING)) 1795 (tt_local_entry->common.flags & BATADV_TT_CLIENT_PENDING))
1373 goto out; 1796 goto out;
1374 } 1797 }
1375 1798
1376 tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr); 1799 tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr, vid);
1377 if (!tt_global_entry) 1800 if (!tt_global_entry)
1378 goto out; 1801 goto out;
1379 1802
@@ -1402,17 +1825,39 @@ out:
1402 return orig_node; 1825 return orig_node;
1403} 1826}
1404 1827
1405/* Calculates the checksum of the local table of a given orig_node */ 1828/**
1406static uint16_t batadv_tt_global_crc(struct batadv_priv *bat_priv, 1829 * batadv_tt_global_crc - calculates the checksum of the local table belonging
1407 struct batadv_orig_node *orig_node) 1830 * to the given orig_node
1831 * @bat_priv: the bat priv with all the soft interface information
1832 * @orig_node: originator for which the CRC should be computed
1833 * @vid: VLAN identifier for which the CRC32 has to be computed
1834 *
1835 * This function computes the checksum for the global table corresponding to a
1836 * specific originator. In particular, the checksum is computed as follows: For
1837 * each client connected to the originator the CRC32C of the MAC address and the
1838 * VID is computed and then all the CRC32Cs of the various clients are xor'ed
1839 * together.
1840 *
1841 * The idea behind is that CRC32C should be used as much as possible in order to
1842 * produce a unique hash of the table, but since the order which is used to feed
1843 * the CRC32C function affects the result and since every node in the network
1844 * probably sorts the clients differently, the hash function cannot be directly
1845 * computed over the entire table. Hence the CRC32C is used only on
1846 * the single client entry, while all the results are then xor'ed together
1847 * because the XOR operation can combine them all while trying to reduce the
1848 * noise as much as possible.
1849 *
1850 * Returns the checksum of the global table of a given originator.
1851 */
1852static uint32_t batadv_tt_global_crc(struct batadv_priv *bat_priv,
1853 struct batadv_orig_node *orig_node,
1854 unsigned short vid)
1408{ 1855{
1409 uint16_t total = 0, total_one;
1410 struct batadv_hashtable *hash = bat_priv->tt.global_hash; 1856 struct batadv_hashtable *hash = bat_priv->tt.global_hash;
1411 struct batadv_tt_common_entry *tt_common; 1857 struct batadv_tt_common_entry *tt_common;
1412 struct batadv_tt_global_entry *tt_global; 1858 struct batadv_tt_global_entry *tt_global;
1413 struct hlist_head *head; 1859 struct hlist_head *head;
1414 uint32_t i; 1860 uint32_t i, crc_tmp, crc = 0;
1415 int j;
1416 1861
1417 for (i = 0; i < hash->size; i++) { 1862 for (i = 0; i < hash->size; i++) {
1418 head = &hash->table[i]; 1863 head = &hash->table[i];
@@ -1422,6 +1867,12 @@ static uint16_t batadv_tt_global_crc(struct batadv_priv *bat_priv,
1422 tt_global = container_of(tt_common, 1867 tt_global = container_of(tt_common,
1423 struct batadv_tt_global_entry, 1868 struct batadv_tt_global_entry,
1424 common); 1869 common);
1870 /* compute the CRC only for entries belonging to the
1871 * VLAN identified by the vid passed as parameter
1872 */
1873 if (tt_common->vid != vid)
1874 continue;
1875
1425 /* Roaming clients are in the global table for 1876 /* Roaming clients are in the global table for
1426 * consistency only. They don't have to be 1877 * consistency only. They don't have to be
1427 * taken into account while computing the 1878 * taken into account while computing the
@@ -1443,48 +1894,59 @@ static uint16_t batadv_tt_global_crc(struct batadv_priv *bat_priv,
1443 orig_node)) 1894 orig_node))
1444 continue; 1895 continue;
1445 1896
1446 total_one = 0; 1897 crc_tmp = crc32c(0, &tt_common->vid,
1447 for (j = 0; j < ETH_ALEN; j++) 1898 sizeof(tt_common->vid));
1448 total_one = crc16_byte(total_one, 1899 crc ^= crc32c(crc_tmp, tt_common->addr, ETH_ALEN);
1449 tt_common->addr[j]);
1450 total ^= total_one;
1451 } 1900 }
1452 rcu_read_unlock(); 1901 rcu_read_unlock();
1453 } 1902 }
1454 1903
1455 return total; 1904 return crc;
1456} 1905}
1457 1906
1458/* Calculates the checksum of the local table */ 1907/**
1459static uint16_t batadv_tt_local_crc(struct batadv_priv *bat_priv) 1908 * batadv_tt_local_crc - calculates the checksum of the local table
1909 * @bat_priv: the bat priv with all the soft interface information
1910 * @vid: VLAN identifier for which the CRC32 has to be computed
1911 *
1912 * For details about the computation, please refer to the documentation for
1913 * batadv_tt_global_crc().
1914 *
1915 * Returns the checksum of the local table
1916 */
1917static uint32_t batadv_tt_local_crc(struct batadv_priv *bat_priv,
1918 unsigned short vid)
1460{ 1919{
1461 uint16_t total = 0, total_one;
1462 struct batadv_hashtable *hash = bat_priv->tt.local_hash; 1920 struct batadv_hashtable *hash = bat_priv->tt.local_hash;
1463 struct batadv_tt_common_entry *tt_common; 1921 struct batadv_tt_common_entry *tt_common;
1464 struct hlist_head *head; 1922 struct hlist_head *head;
1465 uint32_t i; 1923 uint32_t i, crc_tmp, crc = 0;
1466 int j;
1467 1924
1468 for (i = 0; i < hash->size; i++) { 1925 for (i = 0; i < hash->size; i++) {
1469 head = &hash->table[i]; 1926 head = &hash->table[i];
1470 1927
1471 rcu_read_lock(); 1928 rcu_read_lock();
1472 hlist_for_each_entry_rcu(tt_common, head, hash_entry) { 1929 hlist_for_each_entry_rcu(tt_common, head, hash_entry) {
1930 /* compute the CRC only for entries belonging to the
1931 * VLAN identified by vid
1932 */
1933 if (tt_common->vid != vid)
1934 continue;
1935
1473 /* not yet committed clients have not to be taken into 1936 /* not yet committed clients have not to be taken into
1474 * account while computing the CRC 1937 * account while computing the CRC
1475 */ 1938 */
1476 if (tt_common->flags & BATADV_TT_CLIENT_NEW) 1939 if (tt_common->flags & BATADV_TT_CLIENT_NEW)
1477 continue; 1940 continue;
1478 total_one = 0; 1941
1479 for (j = 0; j < ETH_ALEN; j++) 1942 crc_tmp = crc32c(0, &tt_common->vid,
1480 total_one = crc16_byte(total_one, 1943 sizeof(tt_common->vid));
1481 tt_common->addr[j]); 1944 crc ^= crc32c(crc_tmp, tt_common->addr, ETH_ALEN);
1482 total ^= total_one;
1483 } 1945 }
1484 rcu_read_unlock(); 1946 rcu_read_unlock();
1485 } 1947 }
1486 1948
1487 return total; 1949 return crc;
1488} 1950}
1489 1951
1490static void batadv_tt_req_list_free(struct batadv_priv *bat_priv) 1952static void batadv_tt_req_list_free(struct batadv_priv *bat_priv)
@@ -1503,11 +1965,9 @@ static void batadv_tt_req_list_free(struct batadv_priv *bat_priv)
1503 1965
1504static void batadv_tt_save_orig_buffer(struct batadv_priv *bat_priv, 1966static void batadv_tt_save_orig_buffer(struct batadv_priv *bat_priv,
1505 struct batadv_orig_node *orig_node, 1967 struct batadv_orig_node *orig_node,
1506 const unsigned char *tt_buff, 1968 const void *tt_buff,
1507 uint8_t tt_num_changes) 1969 uint16_t tt_buff_len)
1508{ 1970{
1509 uint16_t tt_buff_len = batadv_tt_len(tt_num_changes);
1510
1511 /* Replace the old buffer only if I received something in the 1971 /* Replace the old buffer only if I received something in the
1512 * last OGM (the OGM could carry no changes) 1972 * last OGM (the OGM could carry no changes)
1513 */ 1973 */
@@ -1569,9 +2029,14 @@ unlock:
1569 return tt_req_node; 2029 return tt_req_node;
1570} 2030}
1571 2031
1572/* data_ptr is useless here, but has to be kept to respect the prototype */ 2032/**
1573static int batadv_tt_local_valid_entry(const void *entry_ptr, 2033 * batadv_tt_local_valid - verify that given tt entry is a valid one
1574 const void *data_ptr) 2034 * @entry_ptr: to be checked local tt entry
2035 * @data_ptr: not used but definition required to satisfy the callback prototype
2036 *
2037 * Returns 1 if the entry is a valid, 0 otherwise.
2038 */
2039static int batadv_tt_local_valid(const void *entry_ptr, const void *data_ptr)
1575{ 2040{
1576 const struct batadv_tt_common_entry *tt_common_entry = entry_ptr; 2041 const struct batadv_tt_common_entry *tt_common_entry = entry_ptr;
1577 2042
@@ -1598,41 +2063,30 @@ static int batadv_tt_global_valid(const void *entry_ptr,
1598 return batadv_tt_global_entry_has_orig(tt_global_entry, orig_node); 2063 return batadv_tt_global_entry_has_orig(tt_global_entry, orig_node);
1599} 2064}
1600 2065
1601static struct sk_buff * 2066/**
1602batadv_tt_response_fill_table(uint16_t tt_len, uint8_t ttvn, 2067 * batadv_tt_tvlv_generate - fill the tvlv buff with the tt entries from the
1603 struct batadv_hashtable *hash, 2068 * specified tt hash
1604 struct batadv_priv *bat_priv, 2069 * @bat_priv: the bat priv with all the soft interface information
1605 int (*valid_cb)(const void *, const void *), 2070 * @hash: hash table containing the tt entries
1606 void *cb_data) 2071 * @tt_len: expected tvlv tt data buffer length in number of bytes
2072 * @tvlv_buff: pointer to the buffer to fill with the TT data
2073 * @valid_cb: function to filter tt change entries
2074 * @cb_data: data passed to the filter function as argument
2075 */
2076static void batadv_tt_tvlv_generate(struct batadv_priv *bat_priv,
2077 struct batadv_hashtable *hash,
2078 void *tvlv_buff, uint16_t tt_len,
2079 int (*valid_cb)(const void *, const void *),
2080 void *cb_data)
1607{ 2081{
1608 struct batadv_tt_common_entry *tt_common_entry; 2082 struct batadv_tt_common_entry *tt_common_entry;
1609 struct batadv_tt_query_packet *tt_response; 2083 struct batadv_tvlv_tt_change *tt_change;
1610 struct batadv_tt_change *tt_change;
1611 struct hlist_head *head; 2084 struct hlist_head *head;
1612 struct sk_buff *skb = NULL; 2085 uint16_t tt_tot, tt_num_entries = 0;
1613 uint16_t tt_tot, tt_count;
1614 ssize_t tt_query_size = sizeof(struct batadv_tt_query_packet);
1615 uint32_t i; 2086 uint32_t i;
1616 size_t len;
1617
1618 if (tt_query_size + tt_len > bat_priv->soft_iface->mtu) {
1619 tt_len = bat_priv->soft_iface->mtu - tt_query_size;
1620 tt_len -= tt_len % sizeof(struct batadv_tt_change);
1621 }
1622 tt_tot = tt_len / sizeof(struct batadv_tt_change);
1623
1624 len = tt_query_size + tt_len;
1625 skb = netdev_alloc_skb_ip_align(NULL, len + ETH_HLEN);
1626 if (!skb)
1627 goto out;
1628 2087
1629 skb->priority = TC_PRIO_CONTROL; 2088 tt_tot = batadv_tt_entries(tt_len);
1630 skb_reserve(skb, ETH_HLEN); 2089 tt_change = (struct batadv_tvlv_tt_change *)tvlv_buff;
1631 tt_response = (struct batadv_tt_query_packet *)skb_put(skb, len);
1632 tt_response->ttvn = ttvn;
1633
1634 tt_change = (struct batadv_tt_change *)(skb->data + tt_query_size);
1635 tt_count = 0;
1636 2090
1637 rcu_read_lock(); 2091 rcu_read_lock();
1638 for (i = 0; i < hash->size; i++) { 2092 for (i = 0; i < hash->size; i++) {
@@ -1640,7 +2094,7 @@ batadv_tt_response_fill_table(uint16_t tt_len, uint8_t ttvn,
1640 2094
1641 hlist_for_each_entry_rcu(tt_common_entry, 2095 hlist_for_each_entry_rcu(tt_common_entry,
1642 head, hash_entry) { 2096 head, hash_entry) {
1643 if (tt_count == tt_tot) 2097 if (tt_tot == tt_num_entries)
1644 break; 2098 break;
1645 2099
1646 if ((valid_cb) && (!valid_cb(tt_common_entry, cb_data))) 2100 if ((valid_cb) && (!valid_cb(tt_common_entry, cb_data)))
@@ -1649,33 +2103,123 @@ batadv_tt_response_fill_table(uint16_t tt_len, uint8_t ttvn,
1649 memcpy(tt_change->addr, tt_common_entry->addr, 2103 memcpy(tt_change->addr, tt_common_entry->addr,
1650 ETH_ALEN); 2104 ETH_ALEN);
1651 tt_change->flags = tt_common_entry->flags; 2105 tt_change->flags = tt_common_entry->flags;
2106 tt_change->vid = htons(tt_common_entry->vid);
2107 tt_change->reserved = 0;
1652 2108
1653 tt_count++; 2109 tt_num_entries++;
1654 tt_change++; 2110 tt_change++;
1655 } 2111 }
1656 } 2112 }
1657 rcu_read_unlock(); 2113 rcu_read_unlock();
2114}
1658 2115
1659 /* store in the message the number of entries we have successfully 2116/**
1660 * copied 2117 * batadv_tt_global_check_crc - check if all the CRCs are correct
1661 */ 2118 * @orig_node: originator for which the CRCs have to be checked
1662 tt_response->tt_data = htons(tt_count); 2119 * @tt_vlan: pointer to the first tvlv VLAN entry
2120 * @num_vlan: number of tvlv VLAN entries
2121 * @create: if true, create VLAN objects if not found
2122 *
2123 * Return true if all the received CRCs match the locally stored ones, false
2124 * otherwise
2125 */
2126static bool batadv_tt_global_check_crc(struct batadv_orig_node *orig_node,
2127 struct batadv_tvlv_tt_vlan_data *tt_vlan,
2128 uint16_t num_vlan)
2129{
2130 struct batadv_tvlv_tt_vlan_data *tt_vlan_tmp;
2131 struct batadv_orig_node_vlan *vlan;
2132 int i;
1663 2133
1664out: 2134 /* check if each received CRC matches the locally stored one */
1665 return skb; 2135 for (i = 0; i < num_vlan; i++) {
2136 tt_vlan_tmp = tt_vlan + i;
2137
2138 /* if orig_node is a backbone node for this VLAN, don't check
2139 * the CRC as we ignore all the global entries over it
2140 */
2141 if (batadv_bla_is_backbone_gw_orig(orig_node->bat_priv,
2142 orig_node->orig,
2143 ntohs(tt_vlan_tmp->vid)))
2144 continue;
2145
2146 vlan = batadv_orig_node_vlan_get(orig_node,
2147 ntohs(tt_vlan_tmp->vid));
2148 if (!vlan)
2149 return false;
2150
2151 if (vlan->tt.crc != ntohl(tt_vlan_tmp->crc))
2152 return false;
2153 }
2154
2155 return true;
1666} 2156}
1667 2157
2158/**
2159 * batadv_tt_local_update_crc - update all the local CRCs
2160 * @bat_priv: the bat priv with all the soft interface information
2161 */
2162static void batadv_tt_local_update_crc(struct batadv_priv *bat_priv)
2163{
2164 struct batadv_softif_vlan *vlan;
2165
2166 /* recompute the global CRC for each VLAN */
2167 rcu_read_lock();
2168 hlist_for_each_entry_rcu(vlan, &bat_priv->softif_vlan_list, list) {
2169 vlan->tt.crc = batadv_tt_local_crc(bat_priv, vlan->vid);
2170 }
2171 rcu_read_unlock();
2172}
2173
2174/**
2175 * batadv_tt_global_update_crc - update all the global CRCs for this orig_node
2176 * @bat_priv: the bat priv with all the soft interface information
2177 * @orig_node: the orig_node for which the CRCs have to be updated
2178 */
2179static void batadv_tt_global_update_crc(struct batadv_priv *bat_priv,
2180 struct batadv_orig_node *orig_node)
2181{
2182 struct batadv_orig_node_vlan *vlan;
2183 uint32_t crc;
2184
2185 /* recompute the global CRC for each VLAN */
2186 rcu_read_lock();
2187 list_for_each_entry_rcu(vlan, &orig_node->vlan_list, list) {
2188 /* if orig_node is a backbone node for this VLAN, don't compute
2189 * the CRC as we ignore all the global entries over it
2190 */
2191 if (batadv_bla_is_backbone_gw_orig(bat_priv, orig_node->orig,
2192 vlan->vid))
2193 continue;
2194
2195 crc = batadv_tt_global_crc(bat_priv, orig_node, vlan->vid);
2196 vlan->tt.crc = crc;
2197 }
2198 rcu_read_unlock();
2199}
2200
2201/**
2202 * batadv_send_tt_request - send a TT Request message to a given node
2203 * @bat_priv: the bat priv with all the soft interface information
2204 * @dst_orig_node: the destination of the message
2205 * @ttvn: the version number that the source of the message is looking for
2206 * @tt_vlan: pointer to the first tvlv VLAN object to request
2207 * @num_vlan: number of tvlv VLAN entries
2208 * @full_table: ask for the entire translation table if true, while only for the
2209 * last TT diff otherwise
2210 */
1668static int batadv_send_tt_request(struct batadv_priv *bat_priv, 2211static int batadv_send_tt_request(struct batadv_priv *bat_priv,
1669 struct batadv_orig_node *dst_orig_node, 2212 struct batadv_orig_node *dst_orig_node,
1670 uint8_t ttvn, uint16_t tt_crc, 2213 uint8_t ttvn,
1671 bool full_table) 2214 struct batadv_tvlv_tt_vlan_data *tt_vlan,
2215 uint16_t num_vlan, bool full_table)
1672{ 2216{
1673 struct sk_buff *skb = NULL; 2217 struct batadv_tvlv_tt_data *tvlv_tt_data = NULL;
1674 struct batadv_tt_query_packet *tt_request;
1675 struct batadv_hard_iface *primary_if;
1676 struct batadv_tt_req_node *tt_req_node = NULL; 2218 struct batadv_tt_req_node *tt_req_node = NULL;
1677 int ret = 1; 2219 struct batadv_tvlv_tt_vlan_data *tt_vlan_req;
1678 size_t tt_req_len; 2220 struct batadv_hard_iface *primary_if;
2221 bool ret = false;
2222 int i, size;
1679 2223
1680 primary_if = batadv_primary_if_get_selected(bat_priv); 2224 primary_if = batadv_primary_if_get_selected(bat_priv);
1681 if (!primary_if) 2225 if (!primary_if)
@@ -1688,157 +2232,162 @@ static int batadv_send_tt_request(struct batadv_priv *bat_priv,
1688 if (!tt_req_node) 2232 if (!tt_req_node)
1689 goto out; 2233 goto out;
1690 2234
1691 skb = netdev_alloc_skb_ip_align(NULL, sizeof(*tt_request) + ETH_HLEN); 2235 size = sizeof(*tvlv_tt_data) + sizeof(*tt_vlan_req) * num_vlan;
1692 if (!skb) 2236 tvlv_tt_data = kzalloc(size, GFP_ATOMIC);
2237 if (!tvlv_tt_data)
1693 goto out; 2238 goto out;
1694 2239
1695 skb->priority = TC_PRIO_CONTROL; 2240 tvlv_tt_data->flags = BATADV_TT_REQUEST;
1696 skb_reserve(skb, ETH_HLEN); 2241 tvlv_tt_data->ttvn = ttvn;
2242 tvlv_tt_data->num_vlan = htons(num_vlan);
1697 2243
1698 tt_req_len = sizeof(*tt_request); 2244 /* send all the CRCs within the request. This is needed by intermediate
1699 tt_request = (struct batadv_tt_query_packet *)skb_put(skb, tt_req_len); 2245 * nodes to ensure they have the correct table before replying
2246 */
2247 tt_vlan_req = (struct batadv_tvlv_tt_vlan_data *)(tvlv_tt_data + 1);
2248 for (i = 0; i < num_vlan; i++) {
2249 tt_vlan_req->vid = tt_vlan->vid;
2250 tt_vlan_req->crc = tt_vlan->crc;
1700 2251
1701 tt_request->header.packet_type = BATADV_TT_QUERY; 2252 tt_vlan_req++;
1702 tt_request->header.version = BATADV_COMPAT_VERSION; 2253 tt_vlan++;
1703 memcpy(tt_request->src, primary_if->net_dev->dev_addr, ETH_ALEN); 2254 }
1704 memcpy(tt_request->dst, dst_orig_node->orig, ETH_ALEN);
1705 tt_request->header.ttl = BATADV_TTL;
1706 tt_request->ttvn = ttvn;
1707 tt_request->tt_data = htons(tt_crc);
1708 tt_request->flags = BATADV_TT_REQUEST;
1709 2255
1710 if (full_table) 2256 if (full_table)
1711 tt_request->flags |= BATADV_TT_FULL_TABLE; 2257 tvlv_tt_data->flags |= BATADV_TT_FULL_TABLE;
1712 2258
1713 batadv_dbg(BATADV_DBG_TT, bat_priv, "Sending TT_REQUEST to %pM [%c]\n", 2259 batadv_dbg(BATADV_DBG_TT, bat_priv, "Sending TT_REQUEST to %pM [%c]\n",
1714 dst_orig_node->orig, (full_table ? 'F' : '.')); 2260 dst_orig_node->orig, full_table ? 'F' : '.');
1715 2261
1716 batadv_inc_counter(bat_priv, BATADV_CNT_TT_REQUEST_TX); 2262 batadv_inc_counter(bat_priv, BATADV_CNT_TT_REQUEST_TX);
1717 2263 batadv_tvlv_unicast_send(bat_priv, primary_if->net_dev->dev_addr,
1718 if (batadv_send_skb_to_orig(skb, dst_orig_node, NULL) != NET_XMIT_DROP) 2264 dst_orig_node->orig, BATADV_TVLV_TT, 1,
1719 ret = 0; 2265 tvlv_tt_data, size);
2266 ret = true;
1720 2267
1721out: 2268out:
1722 if (primary_if) 2269 if (primary_if)
1723 batadv_hardif_free_ref(primary_if); 2270 batadv_hardif_free_ref(primary_if);
1724 if (ret)
1725 kfree_skb(skb);
1726 if (ret && tt_req_node) { 2271 if (ret && tt_req_node) {
1727 spin_lock_bh(&bat_priv->tt.req_list_lock); 2272 spin_lock_bh(&bat_priv->tt.req_list_lock);
1728 list_del(&tt_req_node->list); 2273 list_del(&tt_req_node->list);
1729 spin_unlock_bh(&bat_priv->tt.req_list_lock); 2274 spin_unlock_bh(&bat_priv->tt.req_list_lock);
1730 kfree(tt_req_node); 2275 kfree(tt_req_node);
1731 } 2276 }
2277 kfree(tvlv_tt_data);
1732 return ret; 2278 return ret;
1733} 2279}
1734 2280
1735static bool 2281/**
1736batadv_send_other_tt_response(struct batadv_priv *bat_priv, 2282 * batadv_send_other_tt_response - send reply to tt request concerning another
1737 struct batadv_tt_query_packet *tt_request) 2283 * node's translation table
2284 * @bat_priv: the bat priv with all the soft interface information
2285 * @tt_data: tt data containing the tt request information
2286 * @req_src: mac address of tt request sender
2287 * @req_dst: mac address of tt request recipient
2288 *
2289 * Returns true if tt request reply was sent, false otherwise.
2290 */
2291static bool batadv_send_other_tt_response(struct batadv_priv *bat_priv,
2292 struct batadv_tvlv_tt_data *tt_data,
2293 uint8_t *req_src, uint8_t *req_dst)
1738{ 2294{
1739 struct batadv_orig_node *req_dst_orig_node; 2295 struct batadv_orig_node *req_dst_orig_node;
1740 struct batadv_orig_node *res_dst_orig_node = NULL; 2296 struct batadv_orig_node *res_dst_orig_node = NULL;
1741 uint8_t orig_ttvn, req_ttvn, ttvn; 2297 struct batadv_tvlv_tt_change *tt_change;
1742 int res, ret = false; 2298 struct batadv_tvlv_tt_data *tvlv_tt_data = NULL;
1743 unsigned char *tt_buff; 2299 struct batadv_tvlv_tt_vlan_data *tt_vlan;
1744 bool full_table; 2300 bool ret = false, full_table;
1745 uint16_t tt_len, tt_tot; 2301 uint8_t orig_ttvn, req_ttvn;
1746 struct sk_buff *skb = NULL; 2302 uint16_t tvlv_len;
1747 struct batadv_tt_query_packet *tt_response; 2303 int32_t tt_len;
1748 uint8_t *packet_pos;
1749 size_t len;
1750 2304
1751 batadv_dbg(BATADV_DBG_TT, bat_priv, 2305 batadv_dbg(BATADV_DBG_TT, bat_priv,
1752 "Received TT_REQUEST from %pM for ttvn: %u (%pM) [%c]\n", 2306 "Received TT_REQUEST from %pM for ttvn: %u (%pM) [%c]\n",
1753 tt_request->src, tt_request->ttvn, tt_request->dst, 2307 req_src, tt_data->ttvn, req_dst,
1754 (tt_request->flags & BATADV_TT_FULL_TABLE ? 'F' : '.')); 2308 (tt_data->flags & BATADV_TT_FULL_TABLE ? 'F' : '.'));
1755 2309
1756 /* Let's get the orig node of the REAL destination */ 2310 /* Let's get the orig node of the REAL destination */
1757 req_dst_orig_node = batadv_orig_hash_find(bat_priv, tt_request->dst); 2311 req_dst_orig_node = batadv_orig_hash_find(bat_priv, req_dst);
1758 if (!req_dst_orig_node) 2312 if (!req_dst_orig_node)
1759 goto out; 2313 goto out;
1760 2314
1761 res_dst_orig_node = batadv_orig_hash_find(bat_priv, tt_request->src); 2315 res_dst_orig_node = batadv_orig_hash_find(bat_priv, req_src);
1762 if (!res_dst_orig_node) 2316 if (!res_dst_orig_node)
1763 goto out; 2317 goto out;
1764 2318
1765 orig_ttvn = (uint8_t)atomic_read(&req_dst_orig_node->last_ttvn); 2319 orig_ttvn = (uint8_t)atomic_read(&req_dst_orig_node->last_ttvn);
1766 req_ttvn = tt_request->ttvn; 2320 req_ttvn = tt_data->ttvn;
1767 2321
1768 /* I don't have the requested data */ 2322 tt_vlan = (struct batadv_tvlv_tt_vlan_data *)(tt_data + 1);
2323 /* this node doesn't have the requested data */
1769 if (orig_ttvn != req_ttvn || 2324 if (orig_ttvn != req_ttvn ||
1770 tt_request->tt_data != htons(req_dst_orig_node->tt_crc)) 2325 !batadv_tt_global_check_crc(req_dst_orig_node, tt_vlan,
2326 ntohs(tt_data->num_vlan)))
1771 goto out; 2327 goto out;
1772 2328
1773 /* If the full table has been explicitly requested */ 2329 /* If the full table has been explicitly requested */
1774 if (tt_request->flags & BATADV_TT_FULL_TABLE || 2330 if (tt_data->flags & BATADV_TT_FULL_TABLE ||
1775 !req_dst_orig_node->tt_buff) 2331 !req_dst_orig_node->tt_buff)
1776 full_table = true; 2332 full_table = true;
1777 else 2333 else
1778 full_table = false; 2334 full_table = false;
1779 2335
1780 /* In this version, fragmentation is not implemented, then 2336 /* TT fragmentation hasn't been implemented yet, so send as many
1781 * I'll send only one packet with as much TT entries as I can 2337 * TT entries fit a single packet as possible only
1782 */ 2338 */
1783 if (!full_table) { 2339 if (!full_table) {
1784 spin_lock_bh(&req_dst_orig_node->tt_buff_lock); 2340 spin_lock_bh(&req_dst_orig_node->tt_buff_lock);
1785 tt_len = req_dst_orig_node->tt_buff_len; 2341 tt_len = req_dst_orig_node->tt_buff_len;
1786 tt_tot = tt_len / sizeof(struct batadv_tt_change);
1787 2342
1788 len = sizeof(*tt_response) + tt_len; 2343 tvlv_len = batadv_tt_prepare_tvlv_global_data(req_dst_orig_node,
1789 skb = netdev_alloc_skb_ip_align(NULL, len + ETH_HLEN); 2344 &tvlv_tt_data,
1790 if (!skb) 2345 &tt_change,
2346 &tt_len);
2347 if (!tt_len)
1791 goto unlock; 2348 goto unlock;
1792 2349
1793 skb->priority = TC_PRIO_CONTROL;
1794 skb_reserve(skb, ETH_HLEN);
1795 packet_pos = skb_put(skb, len);
1796 tt_response = (struct batadv_tt_query_packet *)packet_pos;
1797 tt_response->ttvn = req_ttvn;
1798 tt_response->tt_data = htons(tt_tot);
1799
1800 tt_buff = skb->data + sizeof(*tt_response);
1801 /* Copy the last orig_node's OGM buffer */ 2350 /* Copy the last orig_node's OGM buffer */
1802 memcpy(tt_buff, req_dst_orig_node->tt_buff, 2351 memcpy(tt_change, req_dst_orig_node->tt_buff,
1803 req_dst_orig_node->tt_buff_len); 2352 req_dst_orig_node->tt_buff_len);
1804
1805 spin_unlock_bh(&req_dst_orig_node->tt_buff_lock); 2353 spin_unlock_bh(&req_dst_orig_node->tt_buff_lock);
1806 } else { 2354 } else {
1807 tt_len = (uint16_t)atomic_read(&req_dst_orig_node->tt_size); 2355 /* allocate the tvlv, put the tt_data and all the tt_vlan_data
1808 tt_len *= sizeof(struct batadv_tt_change); 2356 * in the initial part
1809 ttvn = (uint8_t)atomic_read(&req_dst_orig_node->last_ttvn); 2357 */
1810 2358 tt_len = -1;
1811 skb = batadv_tt_response_fill_table(tt_len, ttvn, 2359 tvlv_len = batadv_tt_prepare_tvlv_global_data(req_dst_orig_node,
1812 bat_priv->tt.global_hash, 2360 &tvlv_tt_data,
1813 bat_priv, 2361 &tt_change,
1814 batadv_tt_global_valid, 2362 &tt_len);
1815 req_dst_orig_node); 2363 if (!tt_len)
1816 if (!skb)
1817 goto out; 2364 goto out;
1818 2365
1819 tt_response = (struct batadv_tt_query_packet *)skb->data; 2366 /* fill the rest of the tvlv with the real TT entries */
2367 batadv_tt_tvlv_generate(bat_priv, bat_priv->tt.global_hash,
2368 tt_change, tt_len,
2369 batadv_tt_global_valid,
2370 req_dst_orig_node);
1820 } 2371 }
1821 2372
1822 tt_response->header.packet_type = BATADV_TT_QUERY; 2373 tvlv_tt_data->flags = BATADV_TT_RESPONSE;
1823 tt_response->header.version = BATADV_COMPAT_VERSION; 2374 tvlv_tt_data->ttvn = req_ttvn;
1824 tt_response->header.ttl = BATADV_TTL;
1825 memcpy(tt_response->src, req_dst_orig_node->orig, ETH_ALEN);
1826 memcpy(tt_response->dst, tt_request->src, ETH_ALEN);
1827 tt_response->flags = BATADV_TT_RESPONSE;
1828 2375
1829 if (full_table) 2376 if (full_table)
1830 tt_response->flags |= BATADV_TT_FULL_TABLE; 2377 tvlv_tt_data->flags |= BATADV_TT_FULL_TABLE;
1831 2378
1832 batadv_dbg(BATADV_DBG_TT, bat_priv, 2379 batadv_dbg(BATADV_DBG_TT, bat_priv,
1833 "Sending TT_RESPONSE %pM for %pM (ttvn: %u)\n", 2380 "Sending TT_RESPONSE %pM for %pM [%c] (ttvn: %u)\n",
1834 res_dst_orig_node->orig, req_dst_orig_node->orig, req_ttvn); 2381 res_dst_orig_node->orig, req_dst_orig_node->orig,
2382 full_table ? 'F' : '.', req_ttvn);
1835 2383
1836 batadv_inc_counter(bat_priv, BATADV_CNT_TT_RESPONSE_TX); 2384 batadv_inc_counter(bat_priv, BATADV_CNT_TT_RESPONSE_TX);
1837 2385
1838 res = batadv_send_skb_to_orig(skb, res_dst_orig_node, NULL); 2386 batadv_tvlv_unicast_send(bat_priv, req_dst_orig_node->orig,
1839 if (res != NET_XMIT_DROP) 2387 req_src, BATADV_TVLV_TT, 1, tvlv_tt_data,
1840 ret = true; 2388 tvlv_len);
1841 2389
2390 ret = true;
1842 goto out; 2391 goto out;
1843 2392
1844unlock: 2393unlock:
@@ -1849,37 +2398,43 @@ out:
1849 batadv_orig_node_free_ref(res_dst_orig_node); 2398 batadv_orig_node_free_ref(res_dst_orig_node);
1850 if (req_dst_orig_node) 2399 if (req_dst_orig_node)
1851 batadv_orig_node_free_ref(req_dst_orig_node); 2400 batadv_orig_node_free_ref(req_dst_orig_node);
1852 if (!ret) 2401 kfree(tvlv_tt_data);
1853 kfree_skb(skb);
1854 return ret; 2402 return ret;
1855} 2403}
1856 2404
1857static bool 2405/**
1858batadv_send_my_tt_response(struct batadv_priv *bat_priv, 2406 * batadv_send_my_tt_response - send reply to tt request concerning this node's
1859 struct batadv_tt_query_packet *tt_request) 2407 * translation table
2408 * @bat_priv: the bat priv with all the soft interface information
2409 * @tt_data: tt data containing the tt request information
2410 * @req_src: mac address of tt request sender
2411 *
2412 * Returns true if tt request reply was sent, false otherwise.
2413 */
2414static bool batadv_send_my_tt_response(struct batadv_priv *bat_priv,
2415 struct batadv_tvlv_tt_data *tt_data,
2416 uint8_t *req_src)
1860{ 2417{
1861 struct batadv_orig_node *orig_node; 2418 struct batadv_tvlv_tt_data *tvlv_tt_data = NULL;
1862 struct batadv_hard_iface *primary_if = NULL; 2419 struct batadv_hard_iface *primary_if = NULL;
1863 uint8_t my_ttvn, req_ttvn, ttvn; 2420 struct batadv_tvlv_tt_change *tt_change;
1864 int ret = false; 2421 struct batadv_orig_node *orig_node;
1865 unsigned char *tt_buff; 2422 uint8_t my_ttvn, req_ttvn;
2423 uint16_t tvlv_len;
1866 bool full_table; 2424 bool full_table;
1867 uint16_t tt_len, tt_tot; 2425 int32_t tt_len;
1868 struct sk_buff *skb = NULL;
1869 struct batadv_tt_query_packet *tt_response;
1870 uint8_t *packet_pos;
1871 size_t len;
1872 2426
1873 batadv_dbg(BATADV_DBG_TT, bat_priv, 2427 batadv_dbg(BATADV_DBG_TT, bat_priv,
1874 "Received TT_REQUEST from %pM for ttvn: %u (me) [%c]\n", 2428 "Received TT_REQUEST from %pM for ttvn: %u (me) [%c]\n",
1875 tt_request->src, tt_request->ttvn, 2429 req_src, tt_data->ttvn,
1876 (tt_request->flags & BATADV_TT_FULL_TABLE ? 'F' : '.')); 2430 (tt_data->flags & BATADV_TT_FULL_TABLE ? 'F' : '.'));
1877 2431
2432 spin_lock_bh(&bat_priv->tt.commit_lock);
1878 2433
1879 my_ttvn = (uint8_t)atomic_read(&bat_priv->tt.vn); 2434 my_ttvn = (uint8_t)atomic_read(&bat_priv->tt.vn);
1880 req_ttvn = tt_request->ttvn; 2435 req_ttvn = tt_data->ttvn;
1881 2436
1882 orig_node = batadv_orig_hash_find(bat_priv, tt_request->src); 2437 orig_node = batadv_orig_hash_find(bat_priv, req_src);
1883 if (!orig_node) 2438 if (!orig_node)
1884 goto out; 2439 goto out;
1885 2440
@@ -1890,103 +2445,104 @@ batadv_send_my_tt_response(struct batadv_priv *bat_priv,
1890 /* If the full table has been explicitly requested or the gap 2445 /* If the full table has been explicitly requested or the gap
1891 * is too big send the whole local translation table 2446 * is too big send the whole local translation table
1892 */ 2447 */
1893 if (tt_request->flags & BATADV_TT_FULL_TABLE || my_ttvn != req_ttvn || 2448 if (tt_data->flags & BATADV_TT_FULL_TABLE || my_ttvn != req_ttvn ||
1894 !bat_priv->tt.last_changeset) 2449 !bat_priv->tt.last_changeset)
1895 full_table = true; 2450 full_table = true;
1896 else 2451 else
1897 full_table = false; 2452 full_table = false;
1898 2453
1899 /* In this version, fragmentation is not implemented, then 2454 /* TT fragmentation hasn't been implemented yet, so send as many
1900 * I'll send only one packet with as much TT entries as I can 2455 * TT entries fit a single packet as possible only
1901 */ 2456 */
1902 if (!full_table) { 2457 if (!full_table) {
1903 spin_lock_bh(&bat_priv->tt.last_changeset_lock); 2458 spin_lock_bh(&bat_priv->tt.last_changeset_lock);
1904 tt_len = bat_priv->tt.last_changeset_len;
1905 tt_tot = tt_len / sizeof(struct batadv_tt_change);
1906 2459
1907 len = sizeof(*tt_response) + tt_len; 2460 tt_len = bat_priv->tt.last_changeset_len;
1908 skb = netdev_alloc_skb_ip_align(NULL, len + ETH_HLEN); 2461 tvlv_len = batadv_tt_prepare_tvlv_local_data(bat_priv,
1909 if (!skb) 2462 &tvlv_tt_data,
2463 &tt_change,
2464 &tt_len);
2465 if (!tt_len)
1910 goto unlock; 2466 goto unlock;
1911 2467
1912 skb->priority = TC_PRIO_CONTROL; 2468 /* Copy the last orig_node's OGM buffer */
1913 skb_reserve(skb, ETH_HLEN); 2469 memcpy(tt_change, bat_priv->tt.last_changeset,
1914 packet_pos = skb_put(skb, len);
1915 tt_response = (struct batadv_tt_query_packet *)packet_pos;
1916 tt_response->ttvn = req_ttvn;
1917 tt_response->tt_data = htons(tt_tot);
1918
1919 tt_buff = skb->data + sizeof(*tt_response);
1920 memcpy(tt_buff, bat_priv->tt.last_changeset,
1921 bat_priv->tt.last_changeset_len); 2470 bat_priv->tt.last_changeset_len);
1922 spin_unlock_bh(&bat_priv->tt.last_changeset_lock); 2471 spin_unlock_bh(&bat_priv->tt.last_changeset_lock);
1923 } else { 2472 } else {
1924 tt_len = (uint16_t)atomic_read(&bat_priv->tt.local_entry_num); 2473 req_ttvn = (uint8_t)atomic_read(&bat_priv->tt.vn);
1925 tt_len *= sizeof(struct batadv_tt_change); 2474
1926 ttvn = (uint8_t)atomic_read(&bat_priv->tt.vn); 2475 /* allocate the tvlv, put the tt_data and all the tt_vlan_data
1927 2476 * in the initial part
1928 skb = batadv_tt_response_fill_table(tt_len, ttvn, 2477 */
1929 bat_priv->tt.local_hash, 2478 tt_len = -1;
1930 bat_priv, 2479 tvlv_len = batadv_tt_prepare_tvlv_local_data(bat_priv,
1931 batadv_tt_local_valid_entry, 2480 &tvlv_tt_data,
1932 NULL); 2481 &tt_change,
1933 if (!skb) 2482 &tt_len);
2483 if (!tt_len)
1934 goto out; 2484 goto out;
1935 2485
1936 tt_response = (struct batadv_tt_query_packet *)skb->data; 2486 /* fill the rest of the tvlv with the real TT entries */
2487 batadv_tt_tvlv_generate(bat_priv, bat_priv->tt.local_hash,
2488 tt_change, tt_len,
2489 batadv_tt_local_valid, NULL);
1937 } 2490 }
1938 2491
1939 tt_response->header.packet_type = BATADV_TT_QUERY; 2492 tvlv_tt_data->flags = BATADV_TT_RESPONSE;
1940 tt_response->header.version = BATADV_COMPAT_VERSION; 2493 tvlv_tt_data->ttvn = req_ttvn;
1941 tt_response->header.ttl = BATADV_TTL;
1942 memcpy(tt_response->src, primary_if->net_dev->dev_addr, ETH_ALEN);
1943 memcpy(tt_response->dst, tt_request->src, ETH_ALEN);
1944 tt_response->flags = BATADV_TT_RESPONSE;
1945 2494
1946 if (full_table) 2495 if (full_table)
1947 tt_response->flags |= BATADV_TT_FULL_TABLE; 2496 tvlv_tt_data->flags |= BATADV_TT_FULL_TABLE;
1948 2497
1949 batadv_dbg(BATADV_DBG_TT, bat_priv, 2498 batadv_dbg(BATADV_DBG_TT, bat_priv,
1950 "Sending TT_RESPONSE to %pM [%c]\n", 2499 "Sending TT_RESPONSE to %pM [%c] (ttvn: %u)\n",
1951 orig_node->orig, 2500 orig_node->orig, full_table ? 'F' : '.', req_ttvn);
1952 (tt_response->flags & BATADV_TT_FULL_TABLE ? 'F' : '.'));
1953 2501
1954 batadv_inc_counter(bat_priv, BATADV_CNT_TT_RESPONSE_TX); 2502 batadv_inc_counter(bat_priv, BATADV_CNT_TT_RESPONSE_TX);
1955 2503
1956 if (batadv_send_skb_to_orig(skb, orig_node, NULL) != NET_XMIT_DROP) 2504 batadv_tvlv_unicast_send(bat_priv, primary_if->net_dev->dev_addr,
1957 ret = true; 2505 req_src, BATADV_TVLV_TT, 1, tvlv_tt_data,
2506 tvlv_len);
2507
1958 goto out; 2508 goto out;
1959 2509
1960unlock: 2510unlock:
1961 spin_unlock_bh(&bat_priv->tt.last_changeset_lock); 2511 spin_unlock_bh(&bat_priv->tt.last_changeset_lock);
1962out: 2512out:
2513 spin_unlock_bh(&bat_priv->tt.commit_lock);
1963 if (orig_node) 2514 if (orig_node)
1964 batadv_orig_node_free_ref(orig_node); 2515 batadv_orig_node_free_ref(orig_node);
1965 if (primary_if) 2516 if (primary_if)
1966 batadv_hardif_free_ref(primary_if); 2517 batadv_hardif_free_ref(primary_if);
1967 if (!ret) 2518 kfree(tvlv_tt_data);
1968 kfree_skb(skb); 2519 /* The packet was for this host, so it doesn't need to be re-routed */
1969 /* This packet was for me, so it doesn't need to be re-routed */
1970 return true; 2520 return true;
1971} 2521}
1972 2522
1973bool batadv_send_tt_response(struct batadv_priv *bat_priv, 2523/**
1974 struct batadv_tt_query_packet *tt_request) 2524 * batadv_send_tt_response - send reply to tt request
2525 * @bat_priv: the bat priv with all the soft interface information
2526 * @tt_data: tt data containing the tt request information
2527 * @req_src: mac address of tt request sender
2528 * @req_dst: mac address of tt request recipient
2529 *
2530 * Returns true if tt request reply was sent, false otherwise.
2531 */
2532static bool batadv_send_tt_response(struct batadv_priv *bat_priv,
2533 struct batadv_tvlv_tt_data *tt_data,
2534 uint8_t *req_src, uint8_t *req_dst)
1975{ 2535{
1976 if (batadv_is_my_mac(bat_priv, tt_request->dst)) { 2536 if (batadv_is_my_mac(bat_priv, req_dst))
1977 /* don't answer backbone gws! */ 2537 return batadv_send_my_tt_response(bat_priv, tt_data, req_src);
1978 if (batadv_bla_is_backbone_gw_orig(bat_priv, tt_request->src)) 2538 else
1979 return true; 2539 return batadv_send_other_tt_response(bat_priv, tt_data,
1980 2540 req_src, req_dst);
1981 return batadv_send_my_tt_response(bat_priv, tt_request);
1982 } else {
1983 return batadv_send_other_tt_response(bat_priv, tt_request);
1984 }
1985} 2541}
1986 2542
1987static void _batadv_tt_update_changes(struct batadv_priv *bat_priv, 2543static void _batadv_tt_update_changes(struct batadv_priv *bat_priv,
1988 struct batadv_orig_node *orig_node, 2544 struct batadv_orig_node *orig_node,
1989 struct batadv_tt_change *tt_change, 2545 struct batadv_tvlv_tt_change *tt_change,
1990 uint16_t tt_num_changes, uint8_t ttvn) 2546 uint16_t tt_num_changes, uint8_t ttvn)
1991{ 2547{
1992 int i; 2548 int i;
@@ -1997,11 +2553,13 @@ static void _batadv_tt_update_changes(struct batadv_priv *bat_priv,
1997 roams = (tt_change + i)->flags & BATADV_TT_CLIENT_ROAM; 2553 roams = (tt_change + i)->flags & BATADV_TT_CLIENT_ROAM;
1998 batadv_tt_global_del(bat_priv, orig_node, 2554 batadv_tt_global_del(bat_priv, orig_node,
1999 (tt_change + i)->addr, 2555 (tt_change + i)->addr,
2556 ntohs((tt_change + i)->vid),
2000 "tt removed by changes", 2557 "tt removed by changes",
2001 roams); 2558 roams);
2002 } else { 2559 } else {
2003 if (!batadv_tt_global_add(bat_priv, orig_node, 2560 if (!batadv_tt_global_add(bat_priv, orig_node,
2004 (tt_change + i)->addr, 2561 (tt_change + i)->addr,
2562 ntohs((tt_change + i)->vid),
2005 (tt_change + i)->flags, ttvn)) 2563 (tt_change + i)->flags, ttvn))
2006 /* In case of problem while storing a 2564 /* In case of problem while storing a
2007 * global_entry, we stop the updating 2565 * global_entry, we stop the updating
@@ -2016,21 +2574,22 @@ static void _batadv_tt_update_changes(struct batadv_priv *bat_priv,
2016} 2574}
2017 2575
2018static void batadv_tt_fill_gtable(struct batadv_priv *bat_priv, 2576static void batadv_tt_fill_gtable(struct batadv_priv *bat_priv,
2019 struct batadv_tt_query_packet *tt_response) 2577 struct batadv_tvlv_tt_change *tt_change,
2578 uint8_t ttvn, uint8_t *resp_src,
2579 uint16_t num_entries)
2020{ 2580{
2021 struct batadv_orig_node *orig_node; 2581 struct batadv_orig_node *orig_node;
2022 2582
2023 orig_node = batadv_orig_hash_find(bat_priv, tt_response->src); 2583 orig_node = batadv_orig_hash_find(bat_priv, resp_src);
2024 if (!orig_node) 2584 if (!orig_node)
2025 goto out; 2585 goto out;
2026 2586
2027 /* Purge the old table first.. */ 2587 /* Purge the old table first.. */
2028 batadv_tt_global_del_orig(bat_priv, orig_node, "Received full table"); 2588 batadv_tt_global_del_orig(bat_priv, orig_node, -1,
2589 "Received full table");
2029 2590
2030 _batadv_tt_update_changes(bat_priv, orig_node, 2591 _batadv_tt_update_changes(bat_priv, orig_node, tt_change, num_entries,
2031 (struct batadv_tt_change *)(tt_response + 1), 2592 ttvn);
2032 ntohs(tt_response->tt_data),
2033 tt_response->ttvn);
2034 2593
2035 spin_lock_bh(&orig_node->tt_buff_lock); 2594 spin_lock_bh(&orig_node->tt_buff_lock);
2036 kfree(orig_node->tt_buff); 2595 kfree(orig_node->tt_buff);
@@ -2038,7 +2597,7 @@ static void batadv_tt_fill_gtable(struct batadv_priv *bat_priv,
2038 orig_node->tt_buff = NULL; 2597 orig_node->tt_buff = NULL;
2039 spin_unlock_bh(&orig_node->tt_buff_lock); 2598 spin_unlock_bh(&orig_node->tt_buff_lock);
2040 2599
2041 atomic_set(&orig_node->last_ttvn, tt_response->ttvn); 2600 atomic_set(&orig_node->last_ttvn, ttvn);
2042 2601
2043out: 2602out:
2044 if (orig_node) 2603 if (orig_node)
@@ -2048,22 +2607,31 @@ out:
2048static void batadv_tt_update_changes(struct batadv_priv *bat_priv, 2607static void batadv_tt_update_changes(struct batadv_priv *bat_priv,
2049 struct batadv_orig_node *orig_node, 2608 struct batadv_orig_node *orig_node,
2050 uint16_t tt_num_changes, uint8_t ttvn, 2609 uint16_t tt_num_changes, uint8_t ttvn,
2051 struct batadv_tt_change *tt_change) 2610 struct batadv_tvlv_tt_change *tt_change)
2052{ 2611{
2053 _batadv_tt_update_changes(bat_priv, orig_node, tt_change, 2612 _batadv_tt_update_changes(bat_priv, orig_node, tt_change,
2054 tt_num_changes, ttvn); 2613 tt_num_changes, ttvn);
2055 2614
2056 batadv_tt_save_orig_buffer(bat_priv, orig_node, 2615 batadv_tt_save_orig_buffer(bat_priv, orig_node, tt_change,
2057 (unsigned char *)tt_change, tt_num_changes); 2616 batadv_tt_len(tt_num_changes));
2058 atomic_set(&orig_node->last_ttvn, ttvn); 2617 atomic_set(&orig_node->last_ttvn, ttvn);
2059} 2618}
2060 2619
2061bool batadv_is_my_client(struct batadv_priv *bat_priv, const uint8_t *addr) 2620/**
2621 * batadv_is_my_client - check if a client is served by the local node
2622 * @bat_priv: the bat priv with all the soft interface information
2623 * @addr: the mac adress of the client to check
2624 * @vid: VLAN identifier
2625 *
2626 * Returns true if the client is served by this node, false otherwise.
2627 */
2628bool batadv_is_my_client(struct batadv_priv *bat_priv, const uint8_t *addr,
2629 unsigned short vid)
2062{ 2630{
2063 struct batadv_tt_local_entry *tt_local_entry; 2631 struct batadv_tt_local_entry *tt_local_entry;
2064 bool ret = false; 2632 bool ret = false;
2065 2633
2066 tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr); 2634 tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr, vid);
2067 if (!tt_local_entry) 2635 if (!tt_local_entry)
2068 goto out; 2636 goto out;
2069 /* Check if the client has been logically deleted (but is kept for 2637 /* Check if the client has been logically deleted (but is kept for
@@ -2079,72 +2647,68 @@ out:
2079 return ret; 2647 return ret;
2080} 2648}
2081 2649
2082void batadv_handle_tt_response(struct batadv_priv *bat_priv, 2650/**
2083 struct batadv_tt_query_packet *tt_response) 2651 * batadv_handle_tt_response - process incoming tt reply
2652 * @bat_priv: the bat priv with all the soft interface information
2653 * @tt_data: tt data containing the tt request information
2654 * @resp_src: mac address of tt reply sender
2655 * @num_entries: number of tt change entries appended to the tt data
2656 */
2657static void batadv_handle_tt_response(struct batadv_priv *bat_priv,
2658 struct batadv_tvlv_tt_data *tt_data,
2659 uint8_t *resp_src, uint16_t num_entries)
2084{ 2660{
2085 struct batadv_tt_req_node *node, *safe; 2661 struct batadv_tt_req_node *node, *safe;
2086 struct batadv_orig_node *orig_node = NULL; 2662 struct batadv_orig_node *orig_node = NULL;
2087 struct batadv_tt_change *tt_change; 2663 struct batadv_tvlv_tt_change *tt_change;
2664 uint8_t *tvlv_ptr = (uint8_t *)tt_data;
2665 uint16_t change_offset;
2088 2666
2089 batadv_dbg(BATADV_DBG_TT, bat_priv, 2667 batadv_dbg(BATADV_DBG_TT, bat_priv,
2090 "Received TT_RESPONSE from %pM for ttvn %d t_size: %d [%c]\n", 2668 "Received TT_RESPONSE from %pM for ttvn %d t_size: %d [%c]\n",
2091 tt_response->src, tt_response->ttvn, 2669 resp_src, tt_data->ttvn, num_entries,
2092 ntohs(tt_response->tt_data), 2670 (tt_data->flags & BATADV_TT_FULL_TABLE ? 'F' : '.'));
2093 (tt_response->flags & BATADV_TT_FULL_TABLE ? 'F' : '.'));
2094
2095 /* we should have never asked a backbone gw */
2096 if (batadv_bla_is_backbone_gw_orig(bat_priv, tt_response->src))
2097 goto out;
2098 2671
2099 orig_node = batadv_orig_hash_find(bat_priv, tt_response->src); 2672 orig_node = batadv_orig_hash_find(bat_priv, resp_src);
2100 if (!orig_node) 2673 if (!orig_node)
2101 goto out; 2674 goto out;
2102 2675
2103 if (tt_response->flags & BATADV_TT_FULL_TABLE) { 2676 spin_lock_bh(&orig_node->tt_lock);
2104 batadv_tt_fill_gtable(bat_priv, tt_response); 2677
2678 change_offset = sizeof(struct batadv_tvlv_tt_vlan_data);
2679 change_offset *= ntohs(tt_data->num_vlan);
2680 change_offset += sizeof(*tt_data);
2681 tvlv_ptr += change_offset;
2682
2683 tt_change = (struct batadv_tvlv_tt_change *)tvlv_ptr;
2684 if (tt_data->flags & BATADV_TT_FULL_TABLE) {
2685 batadv_tt_fill_gtable(bat_priv, tt_change, tt_data->ttvn,
2686 resp_src, num_entries);
2105 } else { 2687 } else {
2106 tt_change = (struct batadv_tt_change *)(tt_response + 1); 2688 batadv_tt_update_changes(bat_priv, orig_node, num_entries,
2107 batadv_tt_update_changes(bat_priv, orig_node, 2689 tt_data->ttvn, tt_change);
2108 ntohs(tt_response->tt_data),
2109 tt_response->ttvn, tt_change);
2110 } 2690 }
2111 2691
2692 /* Recalculate the CRC for this orig_node and store it */
2693 batadv_tt_global_update_crc(bat_priv, orig_node);
2694
2695 spin_unlock_bh(&orig_node->tt_lock);
2696
2112 /* Delete the tt_req_node from pending tt_requests list */ 2697 /* Delete the tt_req_node from pending tt_requests list */
2113 spin_lock_bh(&bat_priv->tt.req_list_lock); 2698 spin_lock_bh(&bat_priv->tt.req_list_lock);
2114 list_for_each_entry_safe(node, safe, &bat_priv->tt.req_list, list) { 2699 list_for_each_entry_safe(node, safe, &bat_priv->tt.req_list, list) {
2115 if (!batadv_compare_eth(node->addr, tt_response->src)) 2700 if (!batadv_compare_eth(node->addr, resp_src))
2116 continue; 2701 continue;
2117 list_del(&node->list); 2702 list_del(&node->list);
2118 kfree(node); 2703 kfree(node);
2119 } 2704 }
2120 spin_unlock_bh(&bat_priv->tt.req_list_lock);
2121 2705
2122 /* Recalculate the CRC for this orig_node and store it */ 2706 spin_unlock_bh(&bat_priv->tt.req_list_lock);
2123 orig_node->tt_crc = batadv_tt_global_crc(bat_priv, orig_node);
2124out: 2707out:
2125 if (orig_node) 2708 if (orig_node)
2126 batadv_orig_node_free_ref(orig_node); 2709 batadv_orig_node_free_ref(orig_node);
2127} 2710}
2128 2711
2129int batadv_tt_init(struct batadv_priv *bat_priv)
2130{
2131 int ret;
2132
2133 ret = batadv_tt_local_init(bat_priv);
2134 if (ret < 0)
2135 return ret;
2136
2137 ret = batadv_tt_global_init(bat_priv);
2138 if (ret < 0)
2139 return ret;
2140
2141 INIT_DELAYED_WORK(&bat_priv->tt.work, batadv_tt_purge);
2142 queue_delayed_work(batadv_event_workqueue, &bat_priv->tt.work,
2143 msecs_to_jiffies(BATADV_TT_WORK_PERIOD));
2144
2145 return 1;
2146}
2147
2148static void batadv_tt_roam_list_free(struct batadv_priv *bat_priv) 2712static void batadv_tt_roam_list_free(struct batadv_priv *bat_priv)
2149{ 2713{
2150 struct batadv_tt_roam_node *node, *safe; 2714 struct batadv_tt_roam_node *node, *safe;
@@ -2225,14 +2789,28 @@ unlock:
2225 return ret; 2789 return ret;
2226} 2790}
2227 2791
2792/**
2793 * batadv_send_roam_adv - send a roaming advertisement message
2794 * @bat_priv: the bat priv with all the soft interface information
2795 * @client: mac address of the roaming client
2796 * @vid: VLAN identifier
2797 * @orig_node: message destination
2798 *
2799 * Send a ROAMING_ADV message to the node which was previously serving this
2800 * client. This is done to inform the node that from now on all traffic destined
2801 * for this particular roamed client has to be forwarded to the sender of the
2802 * roaming message.
2803 */
2228static void batadv_send_roam_adv(struct batadv_priv *bat_priv, uint8_t *client, 2804static void batadv_send_roam_adv(struct batadv_priv *bat_priv, uint8_t *client,
2805 unsigned short vid,
2229 struct batadv_orig_node *orig_node) 2806 struct batadv_orig_node *orig_node)
2230{ 2807{
2231 struct sk_buff *skb = NULL;
2232 struct batadv_roam_adv_packet *roam_adv_packet;
2233 int ret = 1;
2234 struct batadv_hard_iface *primary_if; 2808 struct batadv_hard_iface *primary_if;
2235 size_t len = sizeof(*roam_adv_packet); 2809 struct batadv_tvlv_roam_adv tvlv_roam;
2810
2811 primary_if = batadv_primary_if_get_selected(bat_priv);
2812 if (!primary_if)
2813 goto out;
2236 2814
2237 /* before going on we have to check whether the client has 2815 /* before going on we have to check whether the client has
2238 * already roamed to us too many times 2816 * already roamed to us too many times
@@ -2240,40 +2818,22 @@ static void batadv_send_roam_adv(struct batadv_priv *bat_priv, uint8_t *client,
2240 if (!batadv_tt_check_roam_count(bat_priv, client)) 2818 if (!batadv_tt_check_roam_count(bat_priv, client))
2241 goto out; 2819 goto out;
2242 2820
2243 skb = netdev_alloc_skb_ip_align(NULL, len + ETH_HLEN);
2244 if (!skb)
2245 goto out;
2246
2247 skb->priority = TC_PRIO_CONTROL;
2248 skb_reserve(skb, ETH_HLEN);
2249
2250 roam_adv_packet = (struct batadv_roam_adv_packet *)skb_put(skb, len);
2251
2252 roam_adv_packet->header.packet_type = BATADV_ROAM_ADV;
2253 roam_adv_packet->header.version = BATADV_COMPAT_VERSION;
2254 roam_adv_packet->header.ttl = BATADV_TTL;
2255 roam_adv_packet->reserved = 0;
2256 primary_if = batadv_primary_if_get_selected(bat_priv);
2257 if (!primary_if)
2258 goto out;
2259 memcpy(roam_adv_packet->src, primary_if->net_dev->dev_addr, ETH_ALEN);
2260 batadv_hardif_free_ref(primary_if);
2261 memcpy(roam_adv_packet->dst, orig_node->orig, ETH_ALEN);
2262 memcpy(roam_adv_packet->client, client, ETH_ALEN);
2263
2264 batadv_dbg(BATADV_DBG_TT, bat_priv, 2821 batadv_dbg(BATADV_DBG_TT, bat_priv,
2265 "Sending ROAMING_ADV to %pM (client %pM)\n", 2822 "Sending ROAMING_ADV to %pM (client %pM, vid: %d)\n",
2266 orig_node->orig, client); 2823 orig_node->orig, client, BATADV_PRINT_VID(vid));
2267 2824
2268 batadv_inc_counter(bat_priv, BATADV_CNT_TT_ROAM_ADV_TX); 2825 batadv_inc_counter(bat_priv, BATADV_CNT_TT_ROAM_ADV_TX);
2269 2826
2270 if (batadv_send_skb_to_orig(skb, orig_node, NULL) != NET_XMIT_DROP) 2827 memcpy(tvlv_roam.client, client, sizeof(tvlv_roam.client));
2271 ret = 0; 2828 tvlv_roam.vid = htons(vid);
2829
2830 batadv_tvlv_unicast_send(bat_priv, primary_if->net_dev->dev_addr,
2831 orig_node->orig, BATADV_TVLV_ROAM, 1,
2832 &tvlv_roam, sizeof(tvlv_roam));
2272 2833
2273out: 2834out:
2274 if (ret && skb) 2835 if (primary_if)
2275 kfree_skb(skb); 2836 batadv_hardif_free_ref(primary_if);
2276 return;
2277} 2837}
2278 2838
2279static void batadv_tt_purge(struct work_struct *work) 2839static void batadv_tt_purge(struct work_struct *work)
@@ -2297,6 +2857,9 @@ static void batadv_tt_purge(struct work_struct *work)
2297 2857
2298void batadv_tt_free(struct batadv_priv *bat_priv) 2858void batadv_tt_free(struct batadv_priv *bat_priv)
2299{ 2859{
2860 batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_TT, 1);
2861 batadv_tvlv_handler_unregister(bat_priv, BATADV_TVLV_TT, 1);
2862
2300 cancel_delayed_work_sync(&bat_priv->tt.work); 2863 cancel_delayed_work_sync(&bat_priv->tt.work);
2301 2864
2302 batadv_tt_local_table_free(bat_priv); 2865 batadv_tt_local_table_free(bat_priv);
@@ -2308,19 +2871,25 @@ void batadv_tt_free(struct batadv_priv *bat_priv)
2308 kfree(bat_priv->tt.last_changeset); 2871 kfree(bat_priv->tt.last_changeset);
2309} 2872}
2310 2873
2311/* This function will enable or disable the specified flags for all the entries 2874/**
2312 * in the given hash table and returns the number of modified entries 2875 * batadv_tt_local_set_flags - set or unset the specified flags on the local
2876 * table and possibly count them in the TT size
2877 * @bat_priv: the bat priv with all the soft interface information
2878 * @flags: the flag to switch
2879 * @enable: whether to set or unset the flag
2880 * @count: whether to increase the TT size by the number of changed entries
2313 */ 2881 */
2314static uint16_t batadv_tt_set_flags(struct batadv_hashtable *hash, 2882static void batadv_tt_local_set_flags(struct batadv_priv *bat_priv,
2315 uint16_t flags, bool enable) 2883 uint16_t flags, bool enable, bool count)
2316{ 2884{
2317 uint32_t i; 2885 struct batadv_hashtable *hash = bat_priv->tt.local_hash;
2886 struct batadv_tt_common_entry *tt_common_entry;
2318 uint16_t changed_num = 0; 2887 uint16_t changed_num = 0;
2319 struct hlist_head *head; 2888 struct hlist_head *head;
2320 struct batadv_tt_common_entry *tt_common_entry; 2889 uint32_t i;
2321 2890
2322 if (!hash) 2891 if (!hash)
2323 goto out; 2892 return;
2324 2893
2325 for (i = 0; i < hash->size; i++) { 2894 for (i = 0; i < hash->size; i++) {
2326 head = &hash->table[i]; 2895 head = &hash->table[i];
@@ -2338,11 +2907,15 @@ static uint16_t batadv_tt_set_flags(struct batadv_hashtable *hash,
2338 tt_common_entry->flags &= ~flags; 2907 tt_common_entry->flags &= ~flags;
2339 } 2908 }
2340 changed_num++; 2909 changed_num++;
2910
2911 if (!count)
2912 continue;
2913
2914 batadv_tt_local_size_inc(bat_priv,
2915 tt_common_entry->vid);
2341 } 2916 }
2342 rcu_read_unlock(); 2917 rcu_read_unlock();
2343 } 2918 }
2344out:
2345 return changed_num;
2346} 2919}
2347 2920
2348/* Purge out all the tt local entries marked with BATADV_TT_CLIENT_PENDING */ 2921/* Purge out all the tt local entries marked with BATADV_TT_CLIENT_PENDING */
@@ -2370,10 +2943,11 @@ static void batadv_tt_local_purge_pending_clients(struct batadv_priv *bat_priv)
2370 continue; 2943 continue;
2371 2944
2372 batadv_dbg(BATADV_DBG_TT, bat_priv, 2945 batadv_dbg(BATADV_DBG_TT, bat_priv,
2373 "Deleting local tt entry (%pM): pending\n", 2946 "Deleting local tt entry (%pM, vid: %d): pending\n",
2374 tt_common->addr); 2947 tt_common->addr,
2948 BATADV_PRINT_VID(tt_common->vid));
2375 2949
2376 atomic_dec(&bat_priv->tt.local_entry_num); 2950 batadv_tt_local_size_dec(bat_priv, tt_common->vid);
2377 hlist_del_rcu(&tt_common->hash_entry); 2951 hlist_del_rcu(&tt_common->hash_entry);
2378 tt_local = container_of(tt_common, 2952 tt_local = container_of(tt_common,
2379 struct batadv_tt_local_entry, 2953 struct batadv_tt_local_entry,
@@ -2384,22 +2958,25 @@ static void batadv_tt_local_purge_pending_clients(struct batadv_priv *bat_priv)
2384 } 2958 }
2385} 2959}
2386 2960
2387static int batadv_tt_commit_changes(struct batadv_priv *bat_priv, 2961/**
2388 unsigned char **packet_buff, 2962 * batadv_tt_local_commit_changes - commit all pending local tt changes which
2389 int *packet_buff_len, int packet_min_len) 2963 * have been queued in the time since the last commit
2964 * @bat_priv: the bat priv with all the soft interface information
2965 */
2966void batadv_tt_local_commit_changes(struct batadv_priv *bat_priv)
2390{ 2967{
2391 uint16_t changed_num = 0; 2968 spin_lock_bh(&bat_priv->tt.commit_lock);
2392 2969
2393 if (atomic_read(&bat_priv->tt.local_changes) < 1) 2970 if (atomic_read(&bat_priv->tt.local_changes) < 1) {
2394 return -ENOENT; 2971 if (!batadv_atomic_dec_not_zero(&bat_priv->tt.ogm_append_cnt))
2972 batadv_tt_tvlv_container_update(bat_priv);
2973 goto out;
2974 }
2395 2975
2396 changed_num = batadv_tt_set_flags(bat_priv->tt.local_hash, 2976 batadv_tt_local_set_flags(bat_priv, BATADV_TT_CLIENT_NEW, false, true);
2397 BATADV_TT_CLIENT_NEW, false);
2398 2977
2399 /* all reset entries have to be counted as local entries */
2400 atomic_add(changed_num, &bat_priv->tt.local_entry_num);
2401 batadv_tt_local_purge_pending_clients(bat_priv); 2978 batadv_tt_local_purge_pending_clients(bat_priv);
2402 bat_priv->tt.local_crc = batadv_tt_local_crc(bat_priv); 2979 batadv_tt_local_update_crc(bat_priv);
2403 2980
2404 /* Increment the TTVN only once per OGM interval */ 2981 /* Increment the TTVN only once per OGM interval */
2405 atomic_inc(&bat_priv->tt.vn); 2982 atomic_inc(&bat_priv->tt.vn);
@@ -2409,49 +2986,29 @@ static int batadv_tt_commit_changes(struct batadv_priv *bat_priv,
2409 2986
2410 /* reset the sending counter */ 2987 /* reset the sending counter */
2411 atomic_set(&bat_priv->tt.ogm_append_cnt, BATADV_TT_OGM_APPEND_MAX); 2988 atomic_set(&bat_priv->tt.ogm_append_cnt, BATADV_TT_OGM_APPEND_MAX);
2989 batadv_tt_tvlv_container_update(bat_priv);
2412 2990
2413 return batadv_tt_changes_fill_buff(bat_priv, packet_buff, 2991out:
2414 packet_buff_len, packet_min_len); 2992 spin_unlock_bh(&bat_priv->tt.commit_lock);
2415}
2416
2417/* when calling this function (hard_iface == primary_if) has to be true */
2418int batadv_tt_append_diff(struct batadv_priv *bat_priv,
2419 unsigned char **packet_buff, int *packet_buff_len,
2420 int packet_min_len)
2421{
2422 int tt_num_changes;
2423
2424 /* if at least one change happened */
2425 tt_num_changes = batadv_tt_commit_changes(bat_priv, packet_buff,
2426 packet_buff_len,
2427 packet_min_len);
2428
2429 /* if the changes have been sent often enough */
2430 if ((tt_num_changes < 0) &&
2431 (!batadv_atomic_dec_not_zero(&bat_priv->tt.ogm_append_cnt))) {
2432 batadv_tt_realloc_packet_buff(packet_buff, packet_buff_len,
2433 packet_min_len, packet_min_len);
2434 tt_num_changes = 0;
2435 }
2436
2437 return tt_num_changes;
2438} 2993}
2439 2994
2440bool batadv_is_ap_isolated(struct batadv_priv *bat_priv, uint8_t *src, 2995bool batadv_is_ap_isolated(struct batadv_priv *bat_priv, uint8_t *src,
2441 uint8_t *dst) 2996 uint8_t *dst, unsigned short vid)
2442{ 2997{
2443 struct batadv_tt_local_entry *tt_local_entry = NULL; 2998 struct batadv_tt_local_entry *tt_local_entry = NULL;
2444 struct batadv_tt_global_entry *tt_global_entry = NULL; 2999 struct batadv_tt_global_entry *tt_global_entry = NULL;
3000 struct batadv_softif_vlan *vlan;
2445 bool ret = false; 3001 bool ret = false;
2446 3002
2447 if (!atomic_read(&bat_priv->ap_isolation)) 3003 vlan = batadv_softif_vlan_get(bat_priv, vid);
3004 if (!vlan || !atomic_read(&vlan->ap_isolation))
2448 goto out; 3005 goto out;
2449 3006
2450 tt_local_entry = batadv_tt_local_hash_find(bat_priv, dst); 3007 tt_local_entry = batadv_tt_local_hash_find(bat_priv, dst, vid);
2451 if (!tt_local_entry) 3008 if (!tt_local_entry)
2452 goto out; 3009 goto out;
2453 3010
2454 tt_global_entry = batadv_tt_global_hash_find(bat_priv, src); 3011 tt_global_entry = batadv_tt_global_hash_find(bat_priv, src, vid);
2455 if (!tt_global_entry) 3012 if (!tt_global_entry)
2456 goto out; 3013 goto out;
2457 3014
@@ -2461,6 +3018,8 @@ bool batadv_is_ap_isolated(struct batadv_priv *bat_priv, uint8_t *src,
2461 ret = true; 3018 ret = true;
2462 3019
2463out: 3020out:
3021 if (vlan)
3022 batadv_softif_vlan_free_ref(vlan);
2464 if (tt_global_entry) 3023 if (tt_global_entry)
2465 batadv_tt_global_entry_free_ref(tt_global_entry); 3024 batadv_tt_global_entry_free_ref(tt_global_entry);
2466 if (tt_local_entry) 3025 if (tt_local_entry)
@@ -2468,19 +3027,29 @@ out:
2468 return ret; 3027 return ret;
2469} 3028}
2470 3029
2471void batadv_tt_update_orig(struct batadv_priv *bat_priv, 3030/**
2472 struct batadv_orig_node *orig_node, 3031 * batadv_tt_update_orig - update global translation table with new tt
2473 const unsigned char *tt_buff, uint8_t tt_num_changes, 3032 * information received via ogms
2474 uint8_t ttvn, uint16_t tt_crc) 3033 * @bat_priv: the bat priv with all the soft interface information
3034 * @orig: the orig_node of the ogm
3035 * @tt_vlan: pointer to the first tvlv VLAN entry
3036 * @tt_num_vlan: number of tvlv VLAN entries
3037 * @tt_change: pointer to the first entry in the TT buffer
3038 * @tt_num_changes: number of tt changes inside the tt buffer
3039 * @ttvn: translation table version number of this changeset
3040 * @tt_crc: crc32 checksum of orig node's translation table
3041 */
3042static void batadv_tt_update_orig(struct batadv_priv *bat_priv,
3043 struct batadv_orig_node *orig_node,
3044 const void *tt_buff, uint16_t tt_num_vlan,
3045 struct batadv_tvlv_tt_change *tt_change,
3046 uint16_t tt_num_changes, uint8_t ttvn)
2475{ 3047{
2476 uint8_t orig_ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn); 3048 uint8_t orig_ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn);
3049 struct batadv_tvlv_tt_vlan_data *tt_vlan;
2477 bool full_table = true; 3050 bool full_table = true;
2478 struct batadv_tt_change *tt_change;
2479
2480 /* don't care about a backbone gateways updates. */
2481 if (batadv_bla_is_backbone_gw_orig(bat_priv, orig_node->orig))
2482 return;
2483 3051
3052 tt_vlan = (struct batadv_tvlv_tt_vlan_data *)tt_buff;
2484 /* orig table not initialised AND first diff is in the OGM OR the ttvn 3053 /* orig table not initialised AND first diff is in the OGM OR the ttvn
2485 * increased by one -> we can apply the attached changes 3054 * increased by one -> we can apply the attached changes
2486 */ 3055 */
@@ -2496,7 +3065,9 @@ void batadv_tt_update_orig(struct batadv_priv *bat_priv,
2496 goto request_table; 3065 goto request_table;
2497 } 3066 }
2498 3067
2499 tt_change = (struct batadv_tt_change *)tt_buff; 3068 spin_lock_bh(&orig_node->tt_lock);
3069
3070 tt_change = (struct batadv_tvlv_tt_change *)tt_buff;
2500 batadv_tt_update_changes(bat_priv, orig_node, tt_num_changes, 3071 batadv_tt_update_changes(bat_priv, orig_node, tt_num_changes,
2501 ttvn, tt_change); 3072 ttvn, tt_change);
2502 3073
@@ -2504,7 +3075,9 @@ void batadv_tt_update_orig(struct batadv_priv *bat_priv,
2504 * prefer to recompute it to spot any possible inconsistency 3075 * prefer to recompute it to spot any possible inconsistency
2505 * in the global table 3076 * in the global table
2506 */ 3077 */
2507 orig_node->tt_crc = batadv_tt_global_crc(bat_priv, orig_node); 3078 batadv_tt_global_update_crc(bat_priv, orig_node);
3079
3080 spin_unlock_bh(&orig_node->tt_lock);
2508 3081
2509 /* The ttvn alone is not enough to guarantee consistency 3082 /* The ttvn alone is not enough to guarantee consistency
2510 * because a single value could represent different states 3083 * because a single value could represent different states
@@ -2515,37 +3088,46 @@ void batadv_tt_update_orig(struct batadv_priv *bat_priv,
2515 * checking the CRC value is mandatory to detect the 3088 * checking the CRC value is mandatory to detect the
2516 * inconsistency 3089 * inconsistency
2517 */ 3090 */
2518 if (orig_node->tt_crc != tt_crc) 3091 if (!batadv_tt_global_check_crc(orig_node, tt_vlan,
3092 tt_num_vlan))
2519 goto request_table; 3093 goto request_table;
2520 } else { 3094 } else {
2521 /* if we missed more than one change or our tables are not 3095 /* if we missed more than one change or our tables are not
2522 * in sync anymore -> request fresh tt data 3096 * in sync anymore -> request fresh tt data
2523 */ 3097 */
2524 if (!orig_node->tt_initialised || ttvn != orig_ttvn || 3098 if (!orig_node->tt_initialised || ttvn != orig_ttvn ||
2525 orig_node->tt_crc != tt_crc) { 3099 !batadv_tt_global_check_crc(orig_node, tt_vlan,
3100 tt_num_vlan)) {
2526request_table: 3101request_table:
2527 batadv_dbg(BATADV_DBG_TT, bat_priv, 3102 batadv_dbg(BATADV_DBG_TT, bat_priv,
2528 "TT inconsistency for %pM. Need to retrieve the correct information (ttvn: %u last_ttvn: %u crc: %#.4x last_crc: %#.4x num_changes: %u)\n", 3103 "TT inconsistency for %pM. Need to retrieve the correct information (ttvn: %u last_ttvn: %u num_changes: %u)\n",
2529 orig_node->orig, ttvn, orig_ttvn, tt_crc, 3104 orig_node->orig, ttvn, orig_ttvn,
2530 orig_node->tt_crc, tt_num_changes); 3105 tt_num_changes);
2531 batadv_send_tt_request(bat_priv, orig_node, ttvn, 3106 batadv_send_tt_request(bat_priv, orig_node, ttvn,
2532 tt_crc, full_table); 3107 tt_vlan, tt_num_vlan,
3108 full_table);
2533 return; 3109 return;
2534 } 3110 }
2535 } 3111 }
2536} 3112}
2537 3113
2538/* returns true whether we know that the client has moved from its old 3114/**
2539 * originator to another one. This entry is kept is still kept for consistency 3115 * batadv_tt_global_client_is_roaming - check if a client is marked as roaming
2540 * purposes 3116 * @bat_priv: the bat priv with all the soft interface information
3117 * @addr: the mac address of the client to check
3118 * @vid: VLAN identifier
3119 *
3120 * Returns true if we know that the client has moved from its old originator
3121 * to another one. This entry is still kept for consistency purposes and will be
3122 * deleted later by a DEL or because of timeout
2541 */ 3123 */
2542bool batadv_tt_global_client_is_roaming(struct batadv_priv *bat_priv, 3124bool batadv_tt_global_client_is_roaming(struct batadv_priv *bat_priv,
2543 uint8_t *addr) 3125 uint8_t *addr, unsigned short vid)
2544{ 3126{
2545 struct batadv_tt_global_entry *tt_global_entry; 3127 struct batadv_tt_global_entry *tt_global_entry;
2546 bool ret = false; 3128 bool ret = false;
2547 3129
2548 tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr); 3130 tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr, vid);
2549 if (!tt_global_entry) 3131 if (!tt_global_entry)
2550 goto out; 3132 goto out;
2551 3133
@@ -2558,19 +3140,20 @@ out:
2558/** 3140/**
2559 * batadv_tt_local_client_is_roaming - tells whether the client is roaming 3141 * batadv_tt_local_client_is_roaming - tells whether the client is roaming
2560 * @bat_priv: the bat priv with all the soft interface information 3142 * @bat_priv: the bat priv with all the soft interface information
2561 * @addr: the MAC address of the local client to query 3143 * @addr: the mac address of the local client to query
3144 * @vid: VLAN identifier
2562 * 3145 *
2563 * Returns true if the local client is known to be roaming (it is not served by 3146 * Returns true if the local client is known to be roaming (it is not served by
2564 * this node anymore) or not. If yes, the client is still present in the table 3147 * this node anymore) or not. If yes, the client is still present in the table
2565 * to keep the latter consistent with the node TTVN 3148 * to keep the latter consistent with the node TTVN
2566 */ 3149 */
2567bool batadv_tt_local_client_is_roaming(struct batadv_priv *bat_priv, 3150bool batadv_tt_local_client_is_roaming(struct batadv_priv *bat_priv,
2568 uint8_t *addr) 3151 uint8_t *addr, unsigned short vid)
2569{ 3152{
2570 struct batadv_tt_local_entry *tt_local_entry; 3153 struct batadv_tt_local_entry *tt_local_entry;
2571 bool ret = false; 3154 bool ret = false;
2572 3155
2573 tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr); 3156 tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr, vid);
2574 if (!tt_local_entry) 3157 if (!tt_local_entry)
2575 goto out; 3158 goto out;
2576 3159
@@ -2582,26 +3165,224 @@ out:
2582 3165
2583bool batadv_tt_add_temporary_global_entry(struct batadv_priv *bat_priv, 3166bool batadv_tt_add_temporary_global_entry(struct batadv_priv *bat_priv,
2584 struct batadv_orig_node *orig_node, 3167 struct batadv_orig_node *orig_node,
2585 const unsigned char *addr) 3168 const unsigned char *addr,
3169 unsigned short vid)
2586{ 3170{
2587 bool ret = false; 3171 bool ret = false;
2588 3172
2589 /* if the originator is a backbone node (meaning it belongs to the same 3173 if (!batadv_tt_global_add(bat_priv, orig_node, addr, vid,
2590 * LAN of this node) the temporary client must not be added because to
2591 * reach such destination the node must use the LAN instead of the mesh
2592 */
2593 if (batadv_bla_is_backbone_gw_orig(bat_priv, orig_node->orig))
2594 goto out;
2595
2596 if (!batadv_tt_global_add(bat_priv, orig_node, addr,
2597 BATADV_TT_CLIENT_TEMP, 3174 BATADV_TT_CLIENT_TEMP,
2598 atomic_read(&orig_node->last_ttvn))) 3175 atomic_read(&orig_node->last_ttvn)))
2599 goto out; 3176 goto out;
2600 3177
2601 batadv_dbg(BATADV_DBG_TT, bat_priv, 3178 batadv_dbg(BATADV_DBG_TT, bat_priv,
2602 "Added temporary global client (addr: %pM orig: %pM)\n", 3179 "Added temporary global client (addr: %pM, vid: %d, orig: %pM)\n",
2603 addr, orig_node->orig); 3180 addr, BATADV_PRINT_VID(vid), orig_node->orig);
2604 ret = true; 3181 ret = true;
2605out: 3182out:
2606 return ret; 3183 return ret;
2607} 3184}
3185
3186/**
3187 * batadv_tt_tvlv_ogm_handler_v1 - process incoming tt tvlv container
3188 * @bat_priv: the bat priv with all the soft interface information
3189 * @orig: the orig_node of the ogm
3190 * @flags: flags indicating the tvlv state (see batadv_tvlv_handler_flags)
3191 * @tvlv_value: tvlv buffer containing the gateway data
3192 * @tvlv_value_len: tvlv buffer length
3193 */
3194static void batadv_tt_tvlv_ogm_handler_v1(struct batadv_priv *bat_priv,
3195 struct batadv_orig_node *orig,
3196 uint8_t flags, void *tvlv_value,
3197 uint16_t tvlv_value_len)
3198{
3199 struct batadv_tvlv_tt_vlan_data *tt_vlan;
3200 struct batadv_tvlv_tt_change *tt_change;
3201 struct batadv_tvlv_tt_data *tt_data;
3202 uint16_t num_entries, num_vlan;
3203
3204 if (tvlv_value_len < sizeof(*tt_data))
3205 return;
3206
3207 tt_data = (struct batadv_tvlv_tt_data *)tvlv_value;
3208 tvlv_value_len -= sizeof(*tt_data);
3209
3210 num_vlan = ntohs(tt_data->num_vlan);
3211
3212 if (tvlv_value_len < sizeof(*tt_vlan) * num_vlan)
3213 return;
3214
3215 tt_vlan = (struct batadv_tvlv_tt_vlan_data *)(tt_data + 1);
3216 tt_change = (struct batadv_tvlv_tt_change *)(tt_vlan + num_vlan);
3217 tvlv_value_len -= sizeof(*tt_vlan) * num_vlan;
3218
3219 num_entries = batadv_tt_entries(tvlv_value_len);
3220
3221 batadv_tt_update_orig(bat_priv, orig, tt_vlan, num_vlan, tt_change,
3222 num_entries, tt_data->ttvn);
3223}
3224
3225/**
3226 * batadv_tt_tvlv_unicast_handler_v1 - process incoming (unicast) tt tvlv
3227 * container
3228 * @bat_priv: the bat priv with all the soft interface information
3229 * @src: mac address of tt tvlv sender
3230 * @dst: mac address of tt tvlv recipient
3231 * @tvlv_value: tvlv buffer containing the tt data
3232 * @tvlv_value_len: tvlv buffer length
3233 *
3234 * Returns NET_RX_DROP if the tt tvlv is to be re-routed, NET_RX_SUCCESS
3235 * otherwise.
3236 */
3237static int batadv_tt_tvlv_unicast_handler_v1(struct batadv_priv *bat_priv,
3238 uint8_t *src, uint8_t *dst,
3239 void *tvlv_value,
3240 uint16_t tvlv_value_len)
3241{
3242 struct batadv_tvlv_tt_data *tt_data;
3243 uint16_t tt_vlan_len, tt_num_entries;
3244 char tt_flag;
3245 bool ret;
3246
3247 if (tvlv_value_len < sizeof(*tt_data))
3248 return NET_RX_SUCCESS;
3249
3250 tt_data = (struct batadv_tvlv_tt_data *)tvlv_value;
3251 tvlv_value_len -= sizeof(*tt_data);
3252
3253 tt_vlan_len = sizeof(struct batadv_tvlv_tt_vlan_data);
3254 tt_vlan_len *= ntohs(tt_data->num_vlan);
3255
3256 if (tvlv_value_len < tt_vlan_len)
3257 return NET_RX_SUCCESS;
3258
3259 tvlv_value_len -= tt_vlan_len;
3260 tt_num_entries = batadv_tt_entries(tvlv_value_len);
3261
3262 switch (tt_data->flags & BATADV_TT_DATA_TYPE_MASK) {
3263 case BATADV_TT_REQUEST:
3264 batadv_inc_counter(bat_priv, BATADV_CNT_TT_REQUEST_RX);
3265
3266 /* If this node cannot provide a TT response the tt_request is
3267 * forwarded
3268 */
3269 ret = batadv_send_tt_response(bat_priv, tt_data, src, dst);
3270 if (!ret) {
3271 if (tt_data->flags & BATADV_TT_FULL_TABLE)
3272 tt_flag = 'F';
3273 else
3274 tt_flag = '.';
3275
3276 batadv_dbg(BATADV_DBG_TT, bat_priv,
3277 "Routing TT_REQUEST to %pM [%c]\n",
3278 dst, tt_flag);
3279 /* tvlv API will re-route the packet */
3280 return NET_RX_DROP;
3281 }
3282 break;
3283 case BATADV_TT_RESPONSE:
3284 batadv_inc_counter(bat_priv, BATADV_CNT_TT_RESPONSE_RX);
3285
3286 if (batadv_is_my_mac(bat_priv, dst)) {
3287 batadv_handle_tt_response(bat_priv, tt_data,
3288 src, tt_num_entries);
3289 return NET_RX_SUCCESS;
3290 }
3291
3292 if (tt_data->flags & BATADV_TT_FULL_TABLE)
3293 tt_flag = 'F';
3294 else
3295 tt_flag = '.';
3296
3297 batadv_dbg(BATADV_DBG_TT, bat_priv,
3298 "Routing TT_RESPONSE to %pM [%c]\n", dst, tt_flag);
3299
3300 /* tvlv API will re-route the packet */
3301 return NET_RX_DROP;
3302 }
3303
3304 return NET_RX_SUCCESS;
3305}
3306
3307/**
3308 * batadv_roam_tvlv_unicast_handler_v1 - process incoming tt roam tvlv container
3309 * @bat_priv: the bat priv with all the soft interface information
3310 * @src: mac address of tt tvlv sender
3311 * @dst: mac address of tt tvlv recipient
3312 * @tvlv_value: tvlv buffer containing the tt data
3313 * @tvlv_value_len: tvlv buffer length
3314 *
3315 * Returns NET_RX_DROP if the tt roam tvlv is to be re-routed, NET_RX_SUCCESS
3316 * otherwise.
3317 */
3318static int batadv_roam_tvlv_unicast_handler_v1(struct batadv_priv *bat_priv,
3319 uint8_t *src, uint8_t *dst,
3320 void *tvlv_value,
3321 uint16_t tvlv_value_len)
3322{
3323 struct batadv_tvlv_roam_adv *roaming_adv;
3324 struct batadv_orig_node *orig_node = NULL;
3325
3326 /* If this node is not the intended recipient of the
3327 * roaming advertisement the packet is forwarded
3328 * (the tvlv API will re-route the packet).
3329 */
3330 if (!batadv_is_my_mac(bat_priv, dst))
3331 return NET_RX_DROP;
3332
3333 if (tvlv_value_len < sizeof(*roaming_adv))
3334 goto out;
3335
3336 orig_node = batadv_orig_hash_find(bat_priv, src);
3337 if (!orig_node)
3338 goto out;
3339
3340 batadv_inc_counter(bat_priv, BATADV_CNT_TT_ROAM_ADV_RX);
3341 roaming_adv = (struct batadv_tvlv_roam_adv *)tvlv_value;
3342
3343 batadv_dbg(BATADV_DBG_TT, bat_priv,
3344 "Received ROAMING_ADV from %pM (client %pM)\n",
3345 src, roaming_adv->client);
3346
3347 batadv_tt_global_add(bat_priv, orig_node, roaming_adv->client,
3348 ntohs(roaming_adv->vid), BATADV_TT_CLIENT_ROAM,
3349 atomic_read(&orig_node->last_ttvn) + 1);
3350
3351out:
3352 if (orig_node)
3353 batadv_orig_node_free_ref(orig_node);
3354 return NET_RX_SUCCESS;
3355}
3356
3357/**
3358 * batadv_tt_init - initialise the translation table internals
3359 * @bat_priv: the bat priv with all the soft interface information
3360 *
3361 * Return 0 on success or negative error number in case of failure.
3362 */
3363int batadv_tt_init(struct batadv_priv *bat_priv)
3364{
3365 int ret;
3366
3367 ret = batadv_tt_local_init(bat_priv);
3368 if (ret < 0)
3369 return ret;
3370
3371 ret = batadv_tt_global_init(bat_priv);
3372 if (ret < 0)
3373 return ret;
3374
3375 batadv_tvlv_handler_register(bat_priv, batadv_tt_tvlv_ogm_handler_v1,
3376 batadv_tt_tvlv_unicast_handler_v1,
3377 BATADV_TVLV_TT, 1, BATADV_NO_FLAGS);
3378
3379 batadv_tvlv_handler_register(bat_priv, NULL,
3380 batadv_roam_tvlv_unicast_handler_v1,
3381 BATADV_TVLV_ROAM, 1, BATADV_NO_FLAGS);
3382
3383 INIT_DELAYED_WORK(&bat_priv->tt.work, batadv_tt_purge);
3384 queue_delayed_work(batadv_event_workqueue, &bat_priv->tt.work,
3385 msecs_to_jiffies(BATADV_TT_WORK_PERIOD));
3386
3387 return 1;
3388}
diff --git a/net/batman-adv/translation-table.h b/net/batman-adv/translation-table.h
index 659a3bb759ce..dc6db4e00a43 100644
--- a/net/batman-adv/translation-table.h
+++ b/net/batman-adv/translation-table.h
@@ -20,49 +20,34 @@
20#ifndef _NET_BATMAN_ADV_TRANSLATION_TABLE_H_ 20#ifndef _NET_BATMAN_ADV_TRANSLATION_TABLE_H_
21#define _NET_BATMAN_ADV_TRANSLATION_TABLE_H_ 21#define _NET_BATMAN_ADV_TRANSLATION_TABLE_H_
22 22
23int batadv_tt_len(int changes_num);
24int batadv_tt_init(struct batadv_priv *bat_priv); 23int batadv_tt_init(struct batadv_priv *bat_priv);
25void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr, 24void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
26 int ifindex); 25 unsigned short vid, int ifindex);
27uint16_t batadv_tt_local_remove(struct batadv_priv *bat_priv, 26uint16_t batadv_tt_local_remove(struct batadv_priv *bat_priv,
28 const uint8_t *addr, const char *message, 27 const uint8_t *addr, unsigned short vid,
29 bool roaming); 28 const char *message, bool roaming);
30int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset); 29int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset);
31void batadv_tt_global_add_orig(struct batadv_priv *bat_priv,
32 struct batadv_orig_node *orig_node,
33 const unsigned char *tt_buff, int tt_buff_len);
34int batadv_tt_global_add(struct batadv_priv *bat_priv,
35 struct batadv_orig_node *orig_node,
36 const unsigned char *addr, uint16_t flags,
37 uint8_t ttvn);
38int batadv_tt_global_seq_print_text(struct seq_file *seq, void *offset); 30int batadv_tt_global_seq_print_text(struct seq_file *seq, void *offset);
39void batadv_tt_global_del_orig(struct batadv_priv *bat_priv, 31void batadv_tt_global_del_orig(struct batadv_priv *bat_priv,
40 struct batadv_orig_node *orig_node, 32 struct batadv_orig_node *orig_node,
41 const char *message); 33 int32_t match_vid, const char *message);
42struct batadv_orig_node *batadv_transtable_search(struct batadv_priv *bat_priv, 34struct batadv_orig_node *batadv_transtable_search(struct batadv_priv *bat_priv,
43 const uint8_t *src, 35 const uint8_t *src,
44 const uint8_t *addr); 36 const uint8_t *addr,
37 unsigned short vid);
45void batadv_tt_free(struct batadv_priv *bat_priv); 38void batadv_tt_free(struct batadv_priv *bat_priv);
46bool batadv_send_tt_response(struct batadv_priv *bat_priv, 39bool batadv_is_my_client(struct batadv_priv *bat_priv, const uint8_t *addr,
47 struct batadv_tt_query_packet *tt_request); 40 unsigned short vid);
48bool batadv_is_my_client(struct batadv_priv *bat_priv, const uint8_t *addr);
49void batadv_handle_tt_response(struct batadv_priv *bat_priv,
50 struct batadv_tt_query_packet *tt_response);
51bool batadv_is_ap_isolated(struct batadv_priv *bat_priv, uint8_t *src, 41bool batadv_is_ap_isolated(struct batadv_priv *bat_priv, uint8_t *src,
52 uint8_t *dst); 42 uint8_t *dst, unsigned short vid);
53void batadv_tt_update_orig(struct batadv_priv *bat_priv, 43void batadv_tt_local_commit_changes(struct batadv_priv *bat_priv);
54 struct batadv_orig_node *orig_node,
55 const unsigned char *tt_buff, uint8_t tt_num_changes,
56 uint8_t ttvn, uint16_t tt_crc);
57int batadv_tt_append_diff(struct batadv_priv *bat_priv,
58 unsigned char **packet_buff, int *packet_buff_len,
59 int packet_min_len);
60bool batadv_tt_global_client_is_roaming(struct batadv_priv *bat_priv, 44bool batadv_tt_global_client_is_roaming(struct batadv_priv *bat_priv,
61 uint8_t *addr); 45 uint8_t *addr, unsigned short vid);
62bool batadv_tt_local_client_is_roaming(struct batadv_priv *bat_priv, 46bool batadv_tt_local_client_is_roaming(struct batadv_priv *bat_priv,
63 uint8_t *addr); 47 uint8_t *addr, unsigned short vid);
64bool batadv_tt_add_temporary_global_entry(struct batadv_priv *bat_priv, 48bool batadv_tt_add_temporary_global_entry(struct batadv_priv *bat_priv,
65 struct batadv_orig_node *orig_node, 49 struct batadv_orig_node *orig_node,
66 const unsigned char *addr); 50 const unsigned char *addr,
51 unsigned short vid);
67 52
68#endif /* _NET_BATMAN_ADV_TRANSLATION_TABLE_H_ */ 53#endif /* _NET_BATMAN_ADV_TRANSLATION_TABLE_H_ */
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index b2c94e139319..ff53933b5a59 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -24,13 +24,6 @@
24#include "bitarray.h" 24#include "bitarray.h"
25#include <linux/kernel.h> 25#include <linux/kernel.h>
26 26
27/**
28 * Maximum overhead for the encapsulation for a payload packet
29 */
30#define BATADV_HEADER_LEN \
31 (ETH_HLEN + max(sizeof(struct batadv_unicast_packet), \
32 sizeof(struct batadv_bcast_packet)))
33
34#ifdef CONFIG_BATMAN_ADV_DAT 27#ifdef CONFIG_BATMAN_ADV_DAT
35 28
36/* batadv_dat_addr_t is the type used for all DHT addresses. If it is changed, 29/* batadv_dat_addr_t is the type used for all DHT addresses. If it is changed,
@@ -60,7 +53,6 @@ struct batadv_hard_iface_bat_iv {
60 * @if_num: identificator of the interface 53 * @if_num: identificator of the interface
61 * @if_status: status of the interface for batman-adv 54 * @if_status: status of the interface for batman-adv
62 * @net_dev: pointer to the net_device 55 * @net_dev: pointer to the net_device
63 * @frag_seqno: last fragment sequence number sent by this interface
64 * @num_bcasts: number of payload re-broadcasts on this interface (ARQ) 56 * @num_bcasts: number of payload re-broadcasts on this interface (ARQ)
65 * @hardif_obj: kobject of the per interface sysfs "mesh" directory 57 * @hardif_obj: kobject of the per interface sysfs "mesh" directory
66 * @refcount: number of contexts the object is used 58 * @refcount: number of contexts the object is used
@@ -76,7 +68,6 @@ struct batadv_hard_iface {
76 int16_t if_num; 68 int16_t if_num;
77 char if_status; 69 char if_status;
78 struct net_device *net_dev; 70 struct net_device *net_dev;
79 atomic_t frag_seqno;
80 uint8_t num_bcasts; 71 uint8_t num_bcasts;
81 struct kobject *hardif_obj; 72 struct kobject *hardif_obj;
82 atomic_t refcount; 73 atomic_t refcount;
@@ -88,6 +79,60 @@ struct batadv_hard_iface {
88}; 79};
89 80
90/** 81/**
82 * struct batadv_frag_table_entry - head in the fragment buffer table
83 * @head: head of list with fragments
84 * @lock: lock to protect the list of fragments
85 * @timestamp: time (jiffie) of last received fragment
86 * @seqno: sequence number of the fragments in the list
87 * @size: accumulated size of packets in list
88 */
89struct batadv_frag_table_entry {
90 struct hlist_head head;
91 spinlock_t lock; /* protects head */
92 unsigned long timestamp;
93 uint16_t seqno;
94 uint16_t size;
95};
96
97/**
98 * struct batadv_frag_list_entry - entry in a list of fragments
99 * @list: list node information
100 * @skb: fragment
101 * @no: fragment number in the set
102 */
103struct batadv_frag_list_entry {
104 struct hlist_node list;
105 struct sk_buff *skb;
106 uint8_t no;
107};
108
109/**
110 * struct batadv_vlan_tt - VLAN specific TT attributes
111 * @crc: CRC32 checksum of the entries belonging to this vlan
112 * @num_entries: number of TT entries for this VLAN
113 */
114struct batadv_vlan_tt {
115 uint32_t crc;
116 atomic_t num_entries;
117};
118
119/**
120 * batadv_orig_node_vlan - VLAN specific data per orig_node
121 * @vid: the VLAN identifier
122 * @tt: VLAN specific TT attributes
123 * @list: list node for orig_node::vlan_list
124 * @refcount: number of context where this object is currently in use
125 * @rcu: struct used for freeing in a RCU-safe manner
126 */
127struct batadv_orig_node_vlan {
128 unsigned short vid;
129 struct batadv_vlan_tt tt;
130 struct list_head list;
131 atomic_t refcount;
132 struct rcu_head rcu;
133};
134
135/**
91 * struct batadv_orig_node - structure for orig_list maintaining nodes of mesh 136 * struct batadv_orig_node - structure for orig_list maintaining nodes of mesh
92 * @orig: originator ethernet address 137 * @orig: originator ethernet address
93 * @primary_addr: hosts primary interface address 138 * @primary_addr: hosts primary interface address
@@ -99,17 +144,18 @@ struct batadv_hard_iface {
99 * @last_seen: time when last packet from this node was received 144 * @last_seen: time when last packet from this node was received
100 * @bcast_seqno_reset: time when the broadcast seqno window was reset 145 * @bcast_seqno_reset: time when the broadcast seqno window was reset
101 * @batman_seqno_reset: time when the batman seqno window was reset 146 * @batman_seqno_reset: time when the batman seqno window was reset
102 * @gw_flags: flags related to gateway class 147 * @capabilities: announced capabilities of this originator
103 * @flags: for now only VIS_SERVER flag
104 * @last_ttvn: last seen translation table version number 148 * @last_ttvn: last seen translation table version number
105 * @tt_crc: CRC of the translation table
106 * @tt_buff: last tt changeset this node received from the orig node 149 * @tt_buff: last tt changeset this node received from the orig node
107 * @tt_buff_len: length of the last tt changeset this node received from the 150 * @tt_buff_len: length of the last tt changeset this node received from the
108 * orig node 151 * orig node
109 * @tt_buff_lock: lock that protects tt_buff and tt_buff_len 152 * @tt_buff_lock: lock that protects tt_buff and tt_buff_len
110 * @tt_size: number of global TT entries announced by the orig node
111 * @tt_initialised: bool keeping track of whether or not this node have received 153 * @tt_initialised: bool keeping track of whether or not this node have received
112 * any translation table information from the orig node yet 154 * any translation table information from the orig node yet
155 * @tt_lock: prevents from updating the table while reading it. Table update is
156 * made up by two operations (data structure update and metdata -CRC/TTVN-
157 * recalculation) and they have to be executed atomically in order to avoid
158 * another thread to read the table/metadata between those.
113 * @last_real_seqno: last and best known sequence number 159 * @last_real_seqno: last and best known sequence number
114 * @last_ttl: ttl of last received packet 160 * @last_ttl: ttl of last received packet
115 * @bcast_bits: bitfield containing the info which payload broadcast originated 161 * @bcast_bits: bitfield containing the info which payload broadcast originated
@@ -117,9 +163,6 @@ struct batadv_hard_iface {
117 * last_bcast_seqno) 163 * last_bcast_seqno)
118 * @last_bcast_seqno: last broadcast sequence number received by this host 164 * @last_bcast_seqno: last broadcast sequence number received by this host
119 * @neigh_list: list of potential next hop neighbor towards this orig node 165 * @neigh_list: list of potential next hop neighbor towards this orig node
120 * @frag_list: fragmentation buffer list for fragment re-assembly
121 * @last_frag_packet: time when last fragmented packet from this node was
122 * received
123 * @neigh_list_lock: lock protecting neigh_list, router and bonding_list 166 * @neigh_list_lock: lock protecting neigh_list, router and bonding_list
124 * @hash_entry: hlist node for batadv_priv::orig_hash 167 * @hash_entry: hlist node for batadv_priv::orig_hash
125 * @bat_priv: pointer to soft_iface this orig node belongs to 168 * @bat_priv: pointer to soft_iface this orig node belongs to
@@ -134,6 +177,10 @@ struct batadv_hard_iface {
134 * @out_coding_list: list of nodes that can hear this orig 177 * @out_coding_list: list of nodes that can hear this orig
135 * @in_coding_list_lock: protects in_coding_list 178 * @in_coding_list_lock: protects in_coding_list
136 * @out_coding_list_lock: protects out_coding_list 179 * @out_coding_list_lock: protects out_coding_list
180 * @fragments: array with heads for fragment chains
181 * @vlan_list: a list of orig_node_vlan structs, one per VLAN served by the
182 * originator represented by this object
183 * @vlan_list_lock: lock protecting vlan_list
137 */ 184 */
138struct batadv_orig_node { 185struct batadv_orig_node {
139 uint8_t orig[ETH_ALEN]; 186 uint8_t orig[ETH_ALEN];
@@ -147,22 +194,19 @@ struct batadv_orig_node {
147 unsigned long last_seen; 194 unsigned long last_seen;
148 unsigned long bcast_seqno_reset; 195 unsigned long bcast_seqno_reset;
149 unsigned long batman_seqno_reset; 196 unsigned long batman_seqno_reset;
150 uint8_t gw_flags; 197 uint8_t capabilities;
151 uint8_t flags;
152 atomic_t last_ttvn; 198 atomic_t last_ttvn;
153 uint16_t tt_crc;
154 unsigned char *tt_buff; 199 unsigned char *tt_buff;
155 int16_t tt_buff_len; 200 int16_t tt_buff_len;
156 spinlock_t tt_buff_lock; /* protects tt_buff & tt_buff_len */ 201 spinlock_t tt_buff_lock; /* protects tt_buff & tt_buff_len */
157 atomic_t tt_size;
158 bool tt_initialised; 202 bool tt_initialised;
203 /* prevents from changing the table while reading it */
204 spinlock_t tt_lock;
159 uint32_t last_real_seqno; 205 uint32_t last_real_seqno;
160 uint8_t last_ttl; 206 uint8_t last_ttl;
161 DECLARE_BITMAP(bcast_bits, BATADV_TQ_LOCAL_WINDOW_SIZE); 207 DECLARE_BITMAP(bcast_bits, BATADV_TQ_LOCAL_WINDOW_SIZE);
162 uint32_t last_bcast_seqno; 208 uint32_t last_bcast_seqno;
163 struct hlist_head neigh_list; 209 struct hlist_head neigh_list;
164 struct list_head frag_list;
165 unsigned long last_frag_packet;
166 /* neigh_list_lock protects: neigh_list, router & bonding_list */ 210 /* neigh_list_lock protects: neigh_list, router & bonding_list */
167 spinlock_t neigh_list_lock; 211 spinlock_t neigh_list_lock;
168 struct hlist_node hash_entry; 212 struct hlist_node hash_entry;
@@ -183,12 +227,27 @@ struct batadv_orig_node {
183 spinlock_t in_coding_list_lock; /* Protects in_coding_list */ 227 spinlock_t in_coding_list_lock; /* Protects in_coding_list */
184 spinlock_t out_coding_list_lock; /* Protects out_coding_list */ 228 spinlock_t out_coding_list_lock; /* Protects out_coding_list */
185#endif 229#endif
230 struct batadv_frag_table_entry fragments[BATADV_FRAG_BUFFER_COUNT];
231 struct list_head vlan_list;
232 spinlock_t vlan_list_lock; /* protects vlan_list */
233};
234
235/**
236 * enum batadv_orig_capabilities - orig node capabilities
237 * @BATADV_ORIG_CAPA_HAS_DAT: orig node has distributed arp table enabled
238 * @BATADV_ORIG_CAPA_HAS_NC: orig node has network coding enabled
239 */
240enum batadv_orig_capabilities {
241 BATADV_ORIG_CAPA_HAS_DAT = BIT(0),
242 BATADV_ORIG_CAPA_HAS_NC = BIT(1),
186}; 243};
187 244
188/** 245/**
189 * struct batadv_gw_node - structure for orig nodes announcing gw capabilities 246 * struct batadv_gw_node - structure for orig nodes announcing gw capabilities
190 * @list: list node for batadv_priv_gw::list 247 * @list: list node for batadv_priv_gw::list
191 * @orig_node: pointer to corresponding orig node 248 * @orig_node: pointer to corresponding orig node
249 * @bandwidth_down: advertised uplink download bandwidth
250 * @bandwidth_up: advertised uplink upload bandwidth
192 * @deleted: this struct is scheduled for deletion 251 * @deleted: this struct is scheduled for deletion
193 * @refcount: number of contexts the object is used 252 * @refcount: number of contexts the object is used
194 * @rcu: struct used for freeing in an RCU-safe manner 253 * @rcu: struct used for freeing in an RCU-safe manner
@@ -196,6 +255,8 @@ struct batadv_orig_node {
196struct batadv_gw_node { 255struct batadv_gw_node {
197 struct hlist_node list; 256 struct hlist_node list;
198 struct batadv_orig_node *orig_node; 257 struct batadv_orig_node *orig_node;
258 uint32_t bandwidth_down;
259 uint32_t bandwidth_up;
199 unsigned long deleted; 260 unsigned long deleted;
200 atomic_t refcount; 261 atomic_t refcount;
201 struct rcu_head rcu; 262 struct rcu_head rcu;
@@ -265,6 +326,12 @@ struct batadv_bcast_duplist_entry {
265 * @BATADV_CNT_MGMT_TX_BYTES: transmitted routing protocol traffic bytes counter 326 * @BATADV_CNT_MGMT_TX_BYTES: transmitted routing protocol traffic bytes counter
266 * @BATADV_CNT_MGMT_RX: received routing protocol traffic packet counter 327 * @BATADV_CNT_MGMT_RX: received routing protocol traffic packet counter
267 * @BATADV_CNT_MGMT_RX_BYTES: received routing protocol traffic bytes counter 328 * @BATADV_CNT_MGMT_RX_BYTES: received routing protocol traffic bytes counter
329 * @BATADV_CNT_FRAG_TX: transmitted fragment traffic packet counter
330 * @BATADV_CNT_FRAG_TX_BYTES: transmitted fragment traffic bytes counter
331 * @BATADV_CNT_FRAG_RX: received fragment traffic packet counter
332 * @BATADV_CNT_FRAG_RX_BYTES: received fragment traffic bytes counter
333 * @BATADV_CNT_FRAG_FWD: forwarded fragment traffic packet counter
334 * @BATADV_CNT_FRAG_FWD_BYTES: forwarded fragment traffic bytes counter
268 * @BATADV_CNT_TT_REQUEST_TX: transmitted tt req traffic packet counter 335 * @BATADV_CNT_TT_REQUEST_TX: transmitted tt req traffic packet counter
269 * @BATADV_CNT_TT_REQUEST_RX: received tt req traffic packet counter 336 * @BATADV_CNT_TT_REQUEST_RX: received tt req traffic packet counter
270 * @BATADV_CNT_TT_RESPONSE_TX: transmitted tt resp traffic packet counter 337 * @BATADV_CNT_TT_RESPONSE_TX: transmitted tt resp traffic packet counter
@@ -302,6 +369,12 @@ enum batadv_counters {
302 BATADV_CNT_MGMT_TX_BYTES, 369 BATADV_CNT_MGMT_TX_BYTES,
303 BATADV_CNT_MGMT_RX, 370 BATADV_CNT_MGMT_RX,
304 BATADV_CNT_MGMT_RX_BYTES, 371 BATADV_CNT_MGMT_RX_BYTES,
372 BATADV_CNT_FRAG_TX,
373 BATADV_CNT_FRAG_TX_BYTES,
374 BATADV_CNT_FRAG_RX,
375 BATADV_CNT_FRAG_RX_BYTES,
376 BATADV_CNT_FRAG_FWD,
377 BATADV_CNT_FRAG_FWD_BYTES,
305 BATADV_CNT_TT_REQUEST_TX, 378 BATADV_CNT_TT_REQUEST_TX,
306 BATADV_CNT_TT_REQUEST_RX, 379 BATADV_CNT_TT_REQUEST_RX,
307 BATADV_CNT_TT_RESPONSE_TX, 380 BATADV_CNT_TT_RESPONSE_TX,
@@ -343,11 +416,14 @@ enum batadv_counters {
343 * @changes_list_lock: lock protecting changes_list 416 * @changes_list_lock: lock protecting changes_list
344 * @req_list_lock: lock protecting req_list 417 * @req_list_lock: lock protecting req_list
345 * @roam_list_lock: lock protecting roam_list 418 * @roam_list_lock: lock protecting roam_list
346 * @local_entry_num: number of entries in the local hash table
347 * @local_crc: Checksum of the local table, recomputed before sending a new OGM
348 * @last_changeset: last tt changeset this host has generated 419 * @last_changeset: last tt changeset this host has generated
349 * @last_changeset_len: length of last tt changeset this host has generated 420 * @last_changeset_len: length of last tt changeset this host has generated
350 * @last_changeset_lock: lock protecting last_changeset & last_changeset_len 421 * @last_changeset_lock: lock protecting last_changeset & last_changeset_len
422 * @commit_lock: prevents from executing a local TT commit while reading the
423 * local table. The local TT commit is made up by two operations (data
424 * structure update and metdata -CRC/TTVN- recalculation) and they have to be
425 * executed atomically in order to avoid another thread to read the
426 * table/metadata between those.
351 * @work: work queue callback item for translation table purging 427 * @work: work queue callback item for translation table purging
352 */ 428 */
353struct batadv_priv_tt { 429struct batadv_priv_tt {
@@ -362,12 +438,12 @@ struct batadv_priv_tt {
362 spinlock_t changes_list_lock; /* protects changes */ 438 spinlock_t changes_list_lock; /* protects changes */
363 spinlock_t req_list_lock; /* protects req_list */ 439 spinlock_t req_list_lock; /* protects req_list */
364 spinlock_t roam_list_lock; /* protects roam_list */ 440 spinlock_t roam_list_lock; /* protects roam_list */
365 atomic_t local_entry_num;
366 uint16_t local_crc;
367 unsigned char *last_changeset; 441 unsigned char *last_changeset;
368 int16_t last_changeset_len; 442 int16_t last_changeset_len;
369 /* protects last_changeset & last_changeset_len */ 443 /* protects last_changeset & last_changeset_len */
370 spinlock_t last_changeset_lock; 444 spinlock_t last_changeset_lock;
445 /* prevents from executing a commit while reading the table */
446 spinlock_t commit_lock;
371 struct delayed_work work; 447 struct delayed_work work;
372}; 448};
373 449
@@ -420,31 +496,31 @@ struct batadv_priv_debug_log {
420 * @list: list of available gateway nodes 496 * @list: list of available gateway nodes
421 * @list_lock: lock protecting gw_list & curr_gw 497 * @list_lock: lock protecting gw_list & curr_gw
422 * @curr_gw: pointer to currently selected gateway node 498 * @curr_gw: pointer to currently selected gateway node
499 * @bandwidth_down: advertised uplink download bandwidth (if gw_mode server)
500 * @bandwidth_up: advertised uplink upload bandwidth (if gw_mode server)
423 * @reselect: bool indicating a gateway re-selection is in progress 501 * @reselect: bool indicating a gateway re-selection is in progress
424 */ 502 */
425struct batadv_priv_gw { 503struct batadv_priv_gw {
426 struct hlist_head list; 504 struct hlist_head list;
427 spinlock_t list_lock; /* protects gw_list & curr_gw */ 505 spinlock_t list_lock; /* protects gw_list & curr_gw */
428 struct batadv_gw_node __rcu *curr_gw; /* rcu protected pointer */ 506 struct batadv_gw_node __rcu *curr_gw; /* rcu protected pointer */
507 atomic_t bandwidth_down;
508 atomic_t bandwidth_up;
429 atomic_t reselect; 509 atomic_t reselect;
430}; 510};
431 511
432/** 512/**
433 * struct batadv_priv_vis - per mesh interface vis data 513 * struct batadv_priv_tvlv - per mesh interface tvlv data
434 * @send_list: list of batadv_vis_info packets to sent 514 * @container_list: list of registered tvlv containers to be sent with each OGM
435 * @hash: hash table containing vis data from other nodes in the network 515 * @handler_list: list of the various tvlv content handlers
436 * @hash_lock: lock protecting the hash table 516 * @container_list_lock: protects tvlv container list access
437 * @list_lock: lock protecting my_info::recv_list 517 * @handler_list_lock: protects handler list access
438 * @work: work queue callback item for vis packet sending
439 * @my_info: holds this node's vis data sent on a regular basis
440 */ 518 */
441struct batadv_priv_vis { 519struct batadv_priv_tvlv {
442 struct list_head send_list; 520 struct hlist_head container_list;
443 struct batadv_hashtable *hash; 521 struct hlist_head handler_list;
444 spinlock_t hash_lock; /* protects hash */ 522 spinlock_t container_list_lock; /* protects container_list */
445 spinlock_t list_lock; /* protects my_info::recv_list */ 523 spinlock_t handler_list_lock; /* protects handler_list */
446 struct delayed_work work;
447 struct batadv_vis_info *my_info;
448}; 524};
449 525
450/** 526/**
@@ -491,6 +567,26 @@ struct batadv_priv_nc {
491}; 567};
492 568
493/** 569/**
570 * struct batadv_softif_vlan - per VLAN attributes set
571 * @vid: VLAN identifier
572 * @kobj: kobject for sysfs vlan subdirectory
573 * @ap_isolation: AP isolation state
574 * @tt: TT private attributes (VLAN specific)
575 * @list: list node for bat_priv::softif_vlan_list
576 * @refcount: number of context where this object is currently in use
577 * @rcu: struct used for freeing in a RCU-safe manner
578 */
579struct batadv_softif_vlan {
580 unsigned short vid;
581 struct kobject *kobj;
582 atomic_t ap_isolation; /* boolean */
583 struct batadv_vlan_tt tt;
584 struct hlist_node list;
585 atomic_t refcount;
586 struct rcu_head rcu;
587};
588
589/**
494 * struct batadv_priv - per mesh interface data 590 * struct batadv_priv - per mesh interface data
495 * @mesh_state: current status of the mesh (inactive/active/deactivating) 591 * @mesh_state: current status of the mesh (inactive/active/deactivating)
496 * @soft_iface: net device which holds this struct as private data 592 * @soft_iface: net device which holds this struct as private data
@@ -499,15 +595,13 @@ struct batadv_priv_nc {
499 * @aggregated_ogms: bool indicating whether OGM aggregation is enabled 595 * @aggregated_ogms: bool indicating whether OGM aggregation is enabled
500 * @bonding: bool indicating whether traffic bonding is enabled 596 * @bonding: bool indicating whether traffic bonding is enabled
501 * @fragmentation: bool indicating whether traffic fragmentation is enabled 597 * @fragmentation: bool indicating whether traffic fragmentation is enabled
502 * @ap_isolation: bool indicating whether ap isolation is enabled 598 * @frag_seqno: incremental counter to identify chains of egress fragments
503 * @bridge_loop_avoidance: bool indicating whether bridge loop avoidance is 599 * @bridge_loop_avoidance: bool indicating whether bridge loop avoidance is
504 * enabled 600 * enabled
505 * @distributed_arp_table: bool indicating whether distributed ARP table is 601 * @distributed_arp_table: bool indicating whether distributed ARP table is
506 * enabled 602 * enabled
507 * @vis_mode: vis operation: client or server (see batadv_vis_packettype)
508 * @gw_mode: gateway operation: off, client or server (see batadv_gw_modes) 603 * @gw_mode: gateway operation: off, client or server (see batadv_gw_modes)
509 * @gw_sel_class: gateway selection class (applies if gw_mode client) 604 * @gw_sel_class: gateway selection class (applies if gw_mode client)
510 * @gw_bandwidth: gateway announced bandwidth (applies if gw_mode server)
511 * @orig_interval: OGM broadcast interval in milliseconds 605 * @orig_interval: OGM broadcast interval in milliseconds
512 * @hop_penalty: penalty which will be applied to an OGM's tq-field on every hop 606 * @hop_penalty: penalty which will be applied to an OGM's tq-field on every hop
513 * @log_level: configured log level (see batadv_dbg_level) 607 * @log_level: configured log level (see batadv_dbg_level)
@@ -527,11 +621,14 @@ struct batadv_priv_nc {
527 * @primary_if: one of the hard interfaces assigned to this mesh interface 621 * @primary_if: one of the hard interfaces assigned to this mesh interface
528 * becomes the primary interface 622 * becomes the primary interface
529 * @bat_algo_ops: routing algorithm used by this mesh interface 623 * @bat_algo_ops: routing algorithm used by this mesh interface
624 * @softif_vlan_list: a list of softif_vlan structs, one per VLAN created on top
625 * of the mesh interface represented by this object
626 * @softif_vlan_list_lock: lock protecting softif_vlan_list
530 * @bla: bridge loope avoidance data 627 * @bla: bridge loope avoidance data
531 * @debug_log: holding debug logging relevant data 628 * @debug_log: holding debug logging relevant data
532 * @gw: gateway data 629 * @gw: gateway data
533 * @tt: translation table data 630 * @tt: translation table data
534 * @vis: vis data 631 * @tvlv: type-version-length-value data
535 * @dat: distributed arp table data 632 * @dat: distributed arp table data
536 * @network_coding: bool indicating whether network coding is enabled 633 * @network_coding: bool indicating whether network coding is enabled
537 * @batadv_priv_nc: network coding data 634 * @batadv_priv_nc: network coding data
@@ -544,17 +641,15 @@ struct batadv_priv {
544 atomic_t aggregated_ogms; 641 atomic_t aggregated_ogms;
545 atomic_t bonding; 642 atomic_t bonding;
546 atomic_t fragmentation; 643 atomic_t fragmentation;
547 atomic_t ap_isolation; 644 atomic_t frag_seqno;
548#ifdef CONFIG_BATMAN_ADV_BLA 645#ifdef CONFIG_BATMAN_ADV_BLA
549 atomic_t bridge_loop_avoidance; 646 atomic_t bridge_loop_avoidance;
550#endif 647#endif
551#ifdef CONFIG_BATMAN_ADV_DAT 648#ifdef CONFIG_BATMAN_ADV_DAT
552 atomic_t distributed_arp_table; 649 atomic_t distributed_arp_table;
553#endif 650#endif
554 atomic_t vis_mode;
555 atomic_t gw_mode; 651 atomic_t gw_mode;
556 atomic_t gw_sel_class; 652 atomic_t gw_sel_class;
557 atomic_t gw_bandwidth;
558 atomic_t orig_interval; 653 atomic_t orig_interval;
559 atomic_t hop_penalty; 654 atomic_t hop_penalty;
560#ifdef CONFIG_BATMAN_ADV_DEBUG 655#ifdef CONFIG_BATMAN_ADV_DEBUG
@@ -575,6 +670,8 @@ struct batadv_priv {
575 struct work_struct cleanup_work; 670 struct work_struct cleanup_work;
576 struct batadv_hard_iface __rcu *primary_if; /* rcu protected pointer */ 671 struct batadv_hard_iface __rcu *primary_if; /* rcu protected pointer */
577 struct batadv_algo_ops *bat_algo_ops; 672 struct batadv_algo_ops *bat_algo_ops;
673 struct hlist_head softif_vlan_list;
674 spinlock_t softif_vlan_list_lock; /* protects softif_vlan_list */
578#ifdef CONFIG_BATMAN_ADV_BLA 675#ifdef CONFIG_BATMAN_ADV_BLA
579 struct batadv_priv_bla bla; 676 struct batadv_priv_bla bla;
580#endif 677#endif
@@ -583,7 +680,7 @@ struct batadv_priv {
583#endif 680#endif
584 struct batadv_priv_gw gw; 681 struct batadv_priv_gw gw;
585 struct batadv_priv_tt tt; 682 struct batadv_priv_tt tt;
586 struct batadv_priv_vis vis; 683 struct batadv_priv_tvlv tvlv;
587#ifdef CONFIG_BATMAN_ADV_DAT 684#ifdef CONFIG_BATMAN_ADV_DAT
588 struct batadv_priv_dat dat; 685 struct batadv_priv_dat dat;
589#endif 686#endif
@@ -677,6 +774,7 @@ struct batadv_bla_claim {
677/** 774/**
678 * struct batadv_tt_common_entry - tt local & tt global common data 775 * struct batadv_tt_common_entry - tt local & tt global common data
679 * @addr: mac address of non-mesh client 776 * @addr: mac address of non-mesh client
777 * @vid: VLAN identifier
680 * @hash_entry: hlist node for batadv_priv_tt::local_hash or for 778 * @hash_entry: hlist node for batadv_priv_tt::local_hash or for
681 * batadv_priv_tt::global_hash 779 * batadv_priv_tt::global_hash
682 * @flags: various state handling flags (see batadv_tt_client_flags) 780 * @flags: various state handling flags (see batadv_tt_client_flags)
@@ -686,6 +784,7 @@ struct batadv_bla_claim {
686 */ 784 */
687struct batadv_tt_common_entry { 785struct batadv_tt_common_entry {
688 uint8_t addr[ETH_ALEN]; 786 uint8_t addr[ETH_ALEN];
787 unsigned short vid;
689 struct hlist_node hash_entry; 788 struct hlist_node hash_entry;
690 uint16_t flags; 789 uint16_t flags;
691 unsigned long added_at; 790 unsigned long added_at;
@@ -740,7 +839,7 @@ struct batadv_tt_orig_list_entry {
740 */ 839 */
741struct batadv_tt_change_node { 840struct batadv_tt_change_node {
742 struct list_head list; 841 struct list_head list;
743 struct batadv_tt_change change; 842 struct batadv_tvlv_tt_change change;
744}; 843};
745 844
746/** 845/**
@@ -866,78 +965,6 @@ struct batadv_forw_packet {
866}; 965};
867 966
868/** 967/**
869 * struct batadv_frag_packet_list_entry - storage for fragment packet
870 * @list: list node for orig_node::frag_list
871 * @seqno: sequence number of the fragment
872 * @skb: fragment's skb buffer
873 */
874struct batadv_frag_packet_list_entry {
875 struct list_head list;
876 uint16_t seqno;
877 struct sk_buff *skb;
878};
879
880/**
881 * struct batadv_vis_info - local data for vis information
882 * @first_seen: timestamp used for purging stale vis info entries
883 * @recv_list: List of server-neighbors we have received this packet from. This
884 * packet should not be re-forward to them again. List elements are struct
885 * batadv_vis_recvlist_node
886 * @send_list: list of packets to be forwarded
887 * @refcount: number of contexts the object is used
888 * @hash_entry: hlist node for batadv_priv_vis::hash
889 * @bat_priv: pointer to soft_iface this orig node belongs to
890 * @skb_packet: contains the vis packet
891 */
892struct batadv_vis_info {
893 unsigned long first_seen;
894 struct list_head recv_list;
895 struct list_head send_list;
896 struct kref refcount;
897 struct hlist_node hash_entry;
898 struct batadv_priv *bat_priv;
899 struct sk_buff *skb_packet;
900} __packed;
901
902/**
903 * struct batadv_vis_info_entry - contains link information for vis
904 * @src: source MAC of the link, all zero for local TT entry
905 * @dst: destination MAC of the link, client mac address for local TT entry
906 * @quality: transmission quality of the link, or 0 for local TT entry
907 */
908struct batadv_vis_info_entry {
909 uint8_t src[ETH_ALEN];
910 uint8_t dest[ETH_ALEN];
911 uint8_t quality;
912} __packed;
913
914/**
915 * struct batadv_vis_recvlist_node - list entry for batadv_vis_info::recv_list
916 * @list: list node for batadv_vis_info::recv_list
917 * @mac: MAC address of the originator from where the vis_info was received
918 */
919struct batadv_vis_recvlist_node {
920 struct list_head list;
921 uint8_t mac[ETH_ALEN];
922};
923
924/**
925 * struct batadv_vis_if_list_entry - auxiliary data for vis data generation
926 * @addr: MAC address of the interface
927 * @primary: true if this interface is the primary interface
928 * @list: list node the interface list
929 *
930 * While scanning for vis-entries of a particular vis-originator
931 * this list collects its interfaces to create a subgraph/cluster
932 * out of them later
933 */
934struct batadv_vis_if_list_entry {
935 uint8_t addr[ETH_ALEN];
936 bool primary;
937 struct hlist_node list;
938};
939
940/**
941 * struct batadv_algo_ops - mesh algorithm callbacks 968 * struct batadv_algo_ops - mesh algorithm callbacks
942 * @list: list node for the batadv_algo_list 969 * @list: list node for the batadv_algo_list
943 * @name: name of the algorithm 970 * @name: name of the algorithm
@@ -965,6 +992,7 @@ struct batadv_algo_ops {
965 * is used to stored ARP entries needed for the global DAT cache 992 * is used to stored ARP entries needed for the global DAT cache
966 * @ip: the IPv4 corresponding to this DAT/ARP entry 993 * @ip: the IPv4 corresponding to this DAT/ARP entry
967 * @mac_addr: the MAC address associated to the stored IPv4 994 * @mac_addr: the MAC address associated to the stored IPv4
995 * @vid: the vlan ID associated to this entry
968 * @last_update: time in jiffies when this entry was refreshed last time 996 * @last_update: time in jiffies when this entry was refreshed last time
969 * @hash_entry: hlist node for batadv_priv_dat::hash 997 * @hash_entry: hlist node for batadv_priv_dat::hash
970 * @refcount: number of contexts the object is used 998 * @refcount: number of contexts the object is used
@@ -973,6 +1001,7 @@ struct batadv_algo_ops {
973struct batadv_dat_entry { 1001struct batadv_dat_entry {
974 __be32 ip; 1002 __be32 ip;
975 uint8_t mac_addr[ETH_ALEN]; 1003 uint8_t mac_addr[ETH_ALEN];
1004 unsigned short vid;
976 unsigned long last_update; 1005 unsigned long last_update;
977 struct hlist_node hash_entry; 1006 struct hlist_node hash_entry;
978 atomic_t refcount; 1007 atomic_t refcount;
@@ -992,4 +1021,60 @@ struct batadv_dat_candidate {
992 struct batadv_orig_node *orig_node; 1021 struct batadv_orig_node *orig_node;
993}; 1022};
994 1023
1024/**
1025 * struct batadv_tvlv_container - container for tvlv appended to OGMs
1026 * @list: hlist node for batadv_priv_tvlv::container_list
1027 * @tvlv_hdr: tvlv header information needed to construct the tvlv
1028 * @value_len: length of the buffer following this struct which contains
1029 * the actual tvlv payload
1030 * @refcount: number of contexts the object is used
1031 */
1032struct batadv_tvlv_container {
1033 struct hlist_node list;
1034 struct batadv_tvlv_hdr tvlv_hdr;
1035 atomic_t refcount;
1036};
1037
1038/**
1039 * struct batadv_tvlv_handler - handler for specific tvlv type and version
1040 * @list: hlist node for batadv_priv_tvlv::handler_list
1041 * @ogm_handler: handler callback which is given the tvlv payload to process on
1042 * incoming OGM packets
1043 * @unicast_handler: handler callback which is given the tvlv payload to process
1044 * on incoming unicast tvlv packets
1045 * @type: tvlv type this handler feels responsible for
1046 * @version: tvlv version this handler feels responsible for
1047 * @flags: tvlv handler flags
1048 * @refcount: number of contexts the object is used
1049 * @rcu: struct used for freeing in an RCU-safe manner
1050 */
1051struct batadv_tvlv_handler {
1052 struct hlist_node list;
1053 void (*ogm_handler)(struct batadv_priv *bat_priv,
1054 struct batadv_orig_node *orig,
1055 uint8_t flags,
1056 void *tvlv_value, uint16_t tvlv_value_len);
1057 int (*unicast_handler)(struct batadv_priv *bat_priv,
1058 uint8_t *src, uint8_t *dst,
1059 void *tvlv_value, uint16_t tvlv_value_len);
1060 uint8_t type;
1061 uint8_t version;
1062 uint8_t flags;
1063 atomic_t refcount;
1064 struct rcu_head rcu;
1065};
1066
1067/**
1068 * enum batadv_tvlv_handler_flags - tvlv handler flags definitions
1069 * @BATADV_TVLV_HANDLER_OGM_CIFNOTFND: tvlv ogm processing function will call
1070 * this handler even if its type was not found (with no data)
1071 * @BATADV_TVLV_HANDLER_OGM_CALLED: interval tvlv handling flag - the API marks
1072 * a handler as being called, so it won't be called if the
1073 * BATADV_TVLV_HANDLER_OGM_CIFNOTFND flag was set
1074 */
1075enum batadv_tvlv_handler_flags {
1076 BATADV_TVLV_HANDLER_OGM_CIFNOTFND = BIT(1),
1077 BATADV_TVLV_HANDLER_OGM_CALLED = BIT(2),
1078};
1079
995#endif /* _NET_BATMAN_ADV_TYPES_H_ */ 1080#endif /* _NET_BATMAN_ADV_TYPES_H_ */
diff --git a/net/batman-adv/unicast.c b/net/batman-adv/unicast.c
deleted file mode 100644
index 48b31d33ce6b..000000000000
--- a/net/batman-adv/unicast.c
+++ /dev/null
@@ -1,491 +0,0 @@
1/* Copyright (C) 2010-2013 B.A.T.M.A.N. contributors:
2 *
3 * Andreas Langer
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 "main.h"
21#include "unicast.h"
22#include "send.h"
23#include "soft-interface.h"
24#include "gateway_client.h"
25#include "originator.h"
26#include "hash.h"
27#include "translation-table.h"
28#include "routing.h"
29#include "hard-interface.h"
30
31
32static struct sk_buff *
33batadv_frag_merge_packet(struct list_head *head,
34 struct batadv_frag_packet_list_entry *tfp,
35 struct sk_buff *skb)
36{
37 struct batadv_unicast_frag_packet *up;
38 struct sk_buff *tmp_skb;
39 struct batadv_unicast_packet *unicast_packet;
40 int hdr_len = sizeof(*unicast_packet);
41 int uni_diff = sizeof(*up) - hdr_len;
42 uint8_t *packet_pos;
43
44 up = (struct batadv_unicast_frag_packet *)skb->data;
45 /* set skb to the first part and tmp_skb to the second part */
46 if (up->flags & BATADV_UNI_FRAG_HEAD) {
47 tmp_skb = tfp->skb;
48 } else {
49 tmp_skb = skb;
50 skb = tfp->skb;
51 }
52
53 if (skb_linearize(skb) < 0 || skb_linearize(tmp_skb) < 0)
54 goto err;
55
56 skb_pull(tmp_skb, sizeof(*up));
57 if (pskb_expand_head(skb, 0, tmp_skb->len, GFP_ATOMIC) < 0)
58 goto err;
59
60 /* move free entry to end */
61 tfp->skb = NULL;
62 tfp->seqno = 0;
63 list_move_tail(&tfp->list, head);
64
65 memcpy(skb_put(skb, tmp_skb->len), tmp_skb->data, tmp_skb->len);
66 kfree_skb(tmp_skb);
67
68 memmove(skb->data + uni_diff, skb->data, hdr_len);
69 packet_pos = skb_pull(skb, uni_diff);
70 unicast_packet = (struct batadv_unicast_packet *)packet_pos;
71 unicast_packet->header.packet_type = BATADV_UNICAST;
72
73 return skb;
74
75err:
76 /* free buffered skb, skb will be freed later */
77 kfree_skb(tfp->skb);
78 return NULL;
79}
80
81static void batadv_frag_create_entry(struct list_head *head,
82 struct sk_buff *skb)
83{
84 struct batadv_frag_packet_list_entry *tfp;
85 struct batadv_unicast_frag_packet *up;
86
87 up = (struct batadv_unicast_frag_packet *)skb->data;
88
89 /* free and oldest packets stand at the end */
90 tfp = list_entry((head)->prev, typeof(*tfp), list);
91 kfree_skb(tfp->skb);
92
93 tfp->seqno = ntohs(up->seqno);
94 tfp->skb = skb;
95 list_move(&tfp->list, head);
96 return;
97}
98
99static int batadv_frag_create_buffer(struct list_head *head)
100{
101 int i;
102 struct batadv_frag_packet_list_entry *tfp;
103
104 for (i = 0; i < BATADV_FRAG_BUFFER_SIZE; i++) {
105 tfp = kmalloc(sizeof(*tfp), GFP_ATOMIC);
106 if (!tfp) {
107 batadv_frag_list_free(head);
108 return -ENOMEM;
109 }
110 tfp->skb = NULL;
111 tfp->seqno = 0;
112 INIT_LIST_HEAD(&tfp->list);
113 list_add(&tfp->list, head);
114 }
115
116 return 0;
117}
118
119static struct batadv_frag_packet_list_entry *
120batadv_frag_search_packet(struct list_head *head,
121 const struct batadv_unicast_frag_packet *up)
122{
123 struct batadv_frag_packet_list_entry *tfp;
124 struct batadv_unicast_frag_packet *tmp_up = NULL;
125 bool is_head_tmp, is_head;
126 uint16_t search_seqno;
127
128 if (up->flags & BATADV_UNI_FRAG_HEAD)
129 search_seqno = ntohs(up->seqno)+1;
130 else
131 search_seqno = ntohs(up->seqno)-1;
132
133 is_head = up->flags & BATADV_UNI_FRAG_HEAD;
134
135 list_for_each_entry(tfp, head, list) {
136 if (!tfp->skb)
137 continue;
138
139 if (tfp->seqno == ntohs(up->seqno))
140 goto mov_tail;
141
142 tmp_up = (struct batadv_unicast_frag_packet *)tfp->skb->data;
143
144 if (tfp->seqno == search_seqno) {
145 is_head_tmp = tmp_up->flags & BATADV_UNI_FRAG_HEAD;
146 if (is_head_tmp != is_head)
147 return tfp;
148 else
149 goto mov_tail;
150 }
151 }
152 return NULL;
153
154mov_tail:
155 list_move_tail(&tfp->list, head);
156 return NULL;
157}
158
159void batadv_frag_list_free(struct list_head *head)
160{
161 struct batadv_frag_packet_list_entry *pf, *tmp_pf;
162
163 if (!list_empty(head)) {
164 list_for_each_entry_safe(pf, tmp_pf, head, list) {
165 kfree_skb(pf->skb);
166 list_del(&pf->list);
167 kfree(pf);
168 }
169 }
170 return;
171}
172
173/* frag_reassemble_skb():
174 * returns NET_RX_DROP if the operation failed - skb is left intact
175 * returns NET_RX_SUCCESS if the fragment was buffered (skb_new will be NULL)
176 * or the skb could be reassembled (skb_new will point to the new packet and
177 * skb was freed)
178 */
179int batadv_frag_reassemble_skb(struct sk_buff *skb,
180 struct batadv_priv *bat_priv,
181 struct sk_buff **new_skb)
182{
183 struct batadv_orig_node *orig_node;
184 struct batadv_frag_packet_list_entry *tmp_frag_entry;
185 int ret = NET_RX_DROP;
186 struct batadv_unicast_frag_packet *unicast_packet;
187
188 unicast_packet = (struct batadv_unicast_frag_packet *)skb->data;
189 *new_skb = NULL;
190
191 orig_node = batadv_orig_hash_find(bat_priv, unicast_packet->orig);
192 if (!orig_node)
193 goto out;
194
195 orig_node->last_frag_packet = jiffies;
196
197 if (list_empty(&orig_node->frag_list) &&
198 batadv_frag_create_buffer(&orig_node->frag_list)) {
199 pr_debug("couldn't create frag buffer\n");
200 goto out;
201 }
202
203 tmp_frag_entry = batadv_frag_search_packet(&orig_node->frag_list,
204 unicast_packet);
205
206 if (!tmp_frag_entry) {
207 batadv_frag_create_entry(&orig_node->frag_list, skb);
208 ret = NET_RX_SUCCESS;
209 goto out;
210 }
211
212 *new_skb = batadv_frag_merge_packet(&orig_node->frag_list,
213 tmp_frag_entry, skb);
214 /* if not, merge failed */
215 if (*new_skb)
216 ret = NET_RX_SUCCESS;
217
218out:
219 if (orig_node)
220 batadv_orig_node_free_ref(orig_node);
221 return ret;
222}
223
224int batadv_frag_send_skb(struct sk_buff *skb, struct batadv_priv *bat_priv,
225 struct batadv_hard_iface *hard_iface,
226 const uint8_t dstaddr[])
227{
228 struct batadv_unicast_packet tmp_uc, *unicast_packet;
229 struct batadv_hard_iface *primary_if;
230 struct sk_buff *frag_skb;
231 struct batadv_unicast_frag_packet *frag1, *frag2;
232 int uc_hdr_len = sizeof(*unicast_packet);
233 int ucf_hdr_len = sizeof(*frag1);
234 int data_len = skb->len - uc_hdr_len;
235 int large_tail = 0, ret = NET_RX_DROP;
236 uint16_t seqno;
237
238 primary_if = batadv_primary_if_get_selected(bat_priv);
239 if (!primary_if)
240 goto dropped;
241
242 frag_skb = dev_alloc_skb(data_len - (data_len / 2) + ucf_hdr_len);
243 if (!frag_skb)
244 goto dropped;
245
246 skb->priority = TC_PRIO_CONTROL;
247 skb_reserve(frag_skb, ucf_hdr_len);
248
249 unicast_packet = (struct batadv_unicast_packet *)skb->data;
250 memcpy(&tmp_uc, unicast_packet, uc_hdr_len);
251 skb_split(skb, frag_skb, data_len / 2 + uc_hdr_len);
252
253 if (batadv_skb_head_push(skb, ucf_hdr_len - uc_hdr_len) < 0 ||
254 batadv_skb_head_push(frag_skb, ucf_hdr_len) < 0)
255 goto drop_frag;
256
257 frag1 = (struct batadv_unicast_frag_packet *)skb->data;
258 frag2 = (struct batadv_unicast_frag_packet *)frag_skb->data;
259
260 memcpy(frag1, &tmp_uc, sizeof(tmp_uc));
261
262 frag1->header.ttl--;
263 frag1->header.version = BATADV_COMPAT_VERSION;
264 frag1->header.packet_type = BATADV_UNICAST_FRAG;
265
266 memcpy(frag1->orig, primary_if->net_dev->dev_addr, ETH_ALEN);
267 memcpy(frag2, frag1, sizeof(*frag2));
268
269 if (data_len & 1)
270 large_tail = BATADV_UNI_FRAG_LARGETAIL;
271
272 frag1->flags = BATADV_UNI_FRAG_HEAD | large_tail;
273 frag2->flags = large_tail;
274
275 seqno = atomic_add_return(2, &hard_iface->frag_seqno);
276 frag1->seqno = htons(seqno - 1);
277 frag2->seqno = htons(seqno);
278
279 batadv_send_skb_packet(skb, hard_iface, dstaddr);
280 batadv_send_skb_packet(frag_skb, hard_iface, dstaddr);
281 ret = NET_RX_SUCCESS;
282 goto out;
283
284drop_frag:
285 kfree_skb(frag_skb);
286dropped:
287 kfree_skb(skb);
288out:
289 if (primary_if)
290 batadv_hardif_free_ref(primary_if);
291 return ret;
292}
293
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 *
333 * This call might reallocate skb data.
334 */
335static bool batadv_unicast_prepare_skb(struct sk_buff *skb,
336 struct batadv_orig_node *orig_node)
337{
338 size_t uni_size = sizeof(struct batadv_unicast_packet);
339 return batadv_unicast_push_and_fill_skb(skb, uni_size, orig_node);
340}
341
342/**
343 * batadv_unicast_4addr_prepare_skb - encapsulate an skb with a unicast4addr
344 * header
345 * @bat_priv: the bat priv with all the soft interface information
346 * @skb: the skb containing the payload to encapsulate
347 * @orig_node: the destination node
348 * @packet_subtype: the batman 4addr packet subtype to use
349 *
350 * Returns false if the payload could not be encapsulated or true otherwise.
351 *
352 * This call might reallocate skb data.
353 */
354bool batadv_unicast_4addr_prepare_skb(struct batadv_priv *bat_priv,
355 struct sk_buff *skb,
356 struct batadv_orig_node *orig,
357 int packet_subtype)
358{
359 struct batadv_hard_iface *primary_if;
360 struct batadv_unicast_4addr_packet *unicast_4addr_packet;
361 bool ret = false;
362
363 primary_if = batadv_primary_if_get_selected(bat_priv);
364 if (!primary_if)
365 goto out;
366
367 /* pull the header space and fill the unicast_packet substructure.
368 * We can do that because the first member of the unicast_4addr_packet
369 * is of type struct unicast_packet
370 */
371 if (!batadv_unicast_push_and_fill_skb(skb,
372 sizeof(*unicast_4addr_packet),
373 orig))
374 goto out;
375
376 unicast_4addr_packet = (struct batadv_unicast_4addr_packet *)skb->data;
377 unicast_4addr_packet->u.header.packet_type = BATADV_UNICAST_4ADDR;
378 memcpy(unicast_4addr_packet->src, primary_if->net_dev->dev_addr,
379 ETH_ALEN);
380 unicast_4addr_packet->subtype = packet_subtype;
381 unicast_4addr_packet->reserved = 0;
382
383 ret = true;
384out:
385 if (primary_if)
386 batadv_hardif_free_ref(primary_if);
387 return ret;
388}
389
390/**
391 * batadv_unicast_generic_send_skb - send an skb as unicast
392 * @bat_priv: the bat priv with all the soft interface information
393 * @skb: payload to send
394 * @packet_type: the batman unicast packet type to use
395 * @packet_subtype: the batman packet subtype. It is ignored if packet_type is
396 * not BATADV_UNICAT_4ADDR
397 *
398 * Returns 1 in case of error or 0 otherwise
399 */
400int batadv_unicast_generic_send_skb(struct batadv_priv *bat_priv,
401 struct sk_buff *skb, int packet_type,
402 int packet_subtype)
403{
404 struct ethhdr *ethhdr = (struct ethhdr *)skb->data;
405 struct batadv_unicast_packet *unicast_packet;
406 struct batadv_orig_node *orig_node;
407 struct batadv_neigh_node *neigh_node;
408 int data_len = skb->len;
409 int ret = NET_RX_DROP;
410 unsigned int dev_mtu, header_len;
411
412 /* get routing information */
413 if (is_multicast_ether_addr(ethhdr->h_dest)) {
414 orig_node = batadv_gw_get_selected_orig(bat_priv);
415 if (orig_node)
416 goto find_router;
417 }
418
419 /* check for tt host - increases orig_node refcount.
420 * returns NULL in case of AP isolation
421 */
422 orig_node = batadv_transtable_search(bat_priv, ethhdr->h_source,
423 ethhdr->h_dest);
424
425find_router:
426 /* find_router():
427 * - if orig_node is NULL it returns NULL
428 * - increases neigh_nodes refcount if found.
429 */
430 neigh_node = batadv_find_router(bat_priv, orig_node, NULL);
431
432 if (!neigh_node)
433 goto out;
434
435 switch (packet_type) {
436 case BATADV_UNICAST:
437 if (!batadv_unicast_prepare_skb(skb, orig_node))
438 goto out;
439
440 header_len = sizeof(struct batadv_unicast_packet);
441 break;
442 case BATADV_UNICAST_4ADDR:
443 if (!batadv_unicast_4addr_prepare_skb(bat_priv, skb, orig_node,
444 packet_subtype))
445 goto out;
446
447 header_len = sizeof(struct batadv_unicast_4addr_packet);
448 break;
449 default:
450 /* this function supports UNICAST and UNICAST_4ADDR only. It
451 * should never be invoked with any other packet type
452 */
453 goto out;
454 }
455
456 ethhdr = (struct ethhdr *)(skb->data + header_len);
457 unicast_packet = (struct batadv_unicast_packet *)skb->data;
458
459 /* inform the destination node that we are still missing a correct route
460 * for this client. The destination will receive this packet and will
461 * try to reroute it because the ttvn contained in the header is less
462 * than the current one
463 */
464 if (batadv_tt_global_client_is_roaming(bat_priv, ethhdr->h_dest))
465 unicast_packet->ttvn = unicast_packet->ttvn - 1;
466
467 dev_mtu = neigh_node->if_incoming->net_dev->mtu;
468 /* fragmentation mechanism only works for UNICAST (now) */
469 if (packet_type == BATADV_UNICAST &&
470 atomic_read(&bat_priv->fragmentation) &&
471 data_len + sizeof(*unicast_packet) > dev_mtu) {
472 /* send frag skb decreases ttl */
473 unicast_packet->header.ttl++;
474 ret = batadv_frag_send_skb(skb, bat_priv,
475 neigh_node->if_incoming,
476 neigh_node->addr);
477 goto out;
478 }
479
480 if (batadv_send_skb_to_orig(skb, orig_node, NULL) != NET_XMIT_DROP)
481 ret = 0;
482
483out:
484 if (neigh_node)
485 batadv_neigh_node_free_ref(neigh_node);
486 if (orig_node)
487 batadv_orig_node_free_ref(orig_node);
488 if (ret == NET_RX_DROP)
489 kfree_skb(skb);
490 return ret;
491}
diff --git a/net/batman-adv/unicast.h b/net/batman-adv/unicast.h
deleted file mode 100644
index 429cf8a4a31e..000000000000
--- a/net/batman-adv/unicast.h
+++ /dev/null
@@ -1,92 +0,0 @@
1/* Copyright (C) 2010-2013 B.A.T.M.A.N. contributors:
2 *
3 * Andreas Langer
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_UNICAST_H_
21#define _NET_BATMAN_ADV_UNICAST_H_
22
23#include "packet.h"
24
25#define BATADV_FRAG_TIMEOUT 10000 /* purge frag list entries after time in ms */
26#define BATADV_FRAG_BUFFER_SIZE 6 /* number of list elements in buffer */
27
28int batadv_frag_reassemble_skb(struct sk_buff *skb,
29 struct batadv_priv *bat_priv,
30 struct sk_buff **new_skb);
31void batadv_frag_list_free(struct list_head *head);
32int batadv_frag_send_skb(struct sk_buff *skb, struct batadv_priv *bat_priv,
33 struct batadv_hard_iface *hard_iface,
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}
70
71static inline int batadv_frag_can_reassemble(const struct sk_buff *skb, int mtu)
72{
73 const struct batadv_unicast_frag_packet *unicast_packet;
74 int uneven_correction = 0;
75 unsigned int merged_size;
76
77 unicast_packet = (struct batadv_unicast_frag_packet *)skb->data;
78
79 if (unicast_packet->flags & BATADV_UNI_FRAG_LARGETAIL) {
80 if (unicast_packet->flags & BATADV_UNI_FRAG_HEAD)
81 uneven_correction = 1;
82 else
83 uneven_correction = -1;
84 }
85
86 merged_size = (skb->len - sizeof(*unicast_packet)) * 2;
87 merged_size += sizeof(struct batadv_unicast_packet) + uneven_correction;
88
89 return merged_size <= mtu;
90}
91
92#endif /* _NET_BATMAN_ADV_UNICAST_H_ */
diff --git a/net/batman-adv/vis.c b/net/batman-adv/vis.c
deleted file mode 100644
index d8ea31a58457..000000000000
--- a/net/batman-adv/vis.c
+++ /dev/null
@@ -1,938 +0,0 @@
1/* Copyright (C) 2008-2013 B.A.T.M.A.N. contributors:
2 *
3 * Simon Wunderlich
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 "main.h"
21#include "send.h"
22#include "translation-table.h"
23#include "vis.h"
24#include "soft-interface.h"
25#include "hard-interface.h"
26#include "hash.h"
27#include "originator.h"
28
29#define BATADV_MAX_VIS_PACKET_SIZE 1000
30
31/* hash class keys */
32static struct lock_class_key batadv_vis_hash_lock_class_key;
33
34/* free the info */
35static void batadv_free_info(struct kref *ref)
36{
37 struct batadv_vis_info *info;
38 struct batadv_priv *bat_priv;
39 struct batadv_vis_recvlist_node *entry, *tmp;
40
41 info = container_of(ref, struct batadv_vis_info, refcount);
42 bat_priv = info->bat_priv;
43
44 list_del_init(&info->send_list);
45 spin_lock_bh(&bat_priv->vis.list_lock);
46 list_for_each_entry_safe(entry, tmp, &info->recv_list, list) {
47 list_del(&entry->list);
48 kfree(entry);
49 }
50
51 spin_unlock_bh(&bat_priv->vis.list_lock);
52 kfree_skb(info->skb_packet);
53 kfree(info);
54}
55
56/* Compare two vis packets, used by the hashing algorithm */
57static int batadv_vis_info_cmp(const struct hlist_node *node, const void *data2)
58{
59 const struct batadv_vis_info *d1, *d2;
60 const struct batadv_vis_packet *p1, *p2;
61
62 d1 = container_of(node, struct batadv_vis_info, hash_entry);
63 d2 = data2;
64 p1 = (struct batadv_vis_packet *)d1->skb_packet->data;
65 p2 = (struct batadv_vis_packet *)d2->skb_packet->data;
66 return batadv_compare_eth(p1->vis_orig, p2->vis_orig);
67}
68
69/* hash function to choose an entry in a hash table of given size
70 * hash algorithm from http://en.wikipedia.org/wiki/Hash_table
71 */
72static uint32_t batadv_vis_info_choose(const void *data, uint32_t size)
73{
74 const struct batadv_vis_info *vis_info = data;
75 const struct batadv_vis_packet *packet;
76 const unsigned char *key;
77 uint32_t hash = 0;
78 size_t i;
79
80 packet = (struct batadv_vis_packet *)vis_info->skb_packet->data;
81 key = packet->vis_orig;
82 for (i = 0; i < ETH_ALEN; i++) {
83 hash += key[i];
84 hash += (hash << 10);
85 hash ^= (hash >> 6);
86 }
87
88 hash += (hash << 3);
89 hash ^= (hash >> 11);
90 hash += (hash << 15);
91
92 return hash % size;
93}
94
95static struct batadv_vis_info *
96batadv_vis_hash_find(struct batadv_priv *bat_priv, const void *data)
97{
98 struct batadv_hashtable *hash = bat_priv->vis.hash;
99 struct hlist_head *head;
100 struct batadv_vis_info *vis_info, *vis_info_tmp = NULL;
101 uint32_t index;
102
103 if (!hash)
104 return NULL;
105
106 index = batadv_vis_info_choose(data, hash->size);
107 head = &hash->table[index];
108
109 rcu_read_lock();
110 hlist_for_each_entry_rcu(vis_info, head, hash_entry) {
111 if (!batadv_vis_info_cmp(&vis_info->hash_entry, data))
112 continue;
113
114 vis_info_tmp = vis_info;
115 break;
116 }
117 rcu_read_unlock();
118
119 return vis_info_tmp;
120}
121
122/* insert interface to the list of interfaces of one originator, if it
123 * does not already exist in the list
124 */
125static void batadv_vis_data_insert_interface(const uint8_t *interface,
126 struct hlist_head *if_list,
127 bool primary)
128{
129 struct batadv_vis_if_list_entry *entry;
130
131 hlist_for_each_entry(entry, if_list, list) {
132 if (batadv_compare_eth(entry->addr, interface))
133 return;
134 }
135
136 /* it's a new address, add it to the list */
137 entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
138 if (!entry)
139 return;
140 memcpy(entry->addr, interface, ETH_ALEN);
141 entry->primary = primary;
142 hlist_add_head(&entry->list, if_list);
143}
144
145static void batadv_vis_data_read_prim_sec(struct seq_file *seq,
146 const struct hlist_head *if_list)
147{
148 struct batadv_vis_if_list_entry *entry;
149
150 hlist_for_each_entry(entry, if_list, list) {
151 if (entry->primary)
152 seq_puts(seq, "PRIMARY, ");
153 else
154 seq_printf(seq, "SEC %pM, ", entry->addr);
155 }
156}
157
158/* read an entry */
159static ssize_t
160batadv_vis_data_read_entry(struct seq_file *seq,
161 const struct batadv_vis_info_entry *entry,
162 const uint8_t *src, bool primary)
163{
164 if (primary && entry->quality == 0)
165 return seq_printf(seq, "TT %pM, ", entry->dest);
166 else if (batadv_compare_eth(entry->src, src))
167 return seq_printf(seq, "TQ %pM %d, ", entry->dest,
168 entry->quality);
169
170 return 0;
171}
172
173static void
174batadv_vis_data_insert_interfaces(struct hlist_head *list,
175 struct batadv_vis_packet *packet,
176 struct batadv_vis_info_entry *entries)
177{
178 int i;
179
180 for (i = 0; i < packet->entries; i++) {
181 if (entries[i].quality == 0)
182 continue;
183
184 if (batadv_compare_eth(entries[i].src, packet->vis_orig))
185 continue;
186
187 batadv_vis_data_insert_interface(entries[i].src, list, false);
188 }
189}
190
191static void batadv_vis_data_read_entries(struct seq_file *seq,
192 struct hlist_head *list,
193 struct batadv_vis_packet *packet,
194 struct batadv_vis_info_entry *entries)
195{
196 int i;
197 struct batadv_vis_if_list_entry *entry;
198
199 hlist_for_each_entry(entry, list, list) {
200 seq_printf(seq, "%pM,", entry->addr);
201
202 for (i = 0; i < packet->entries; i++)
203 batadv_vis_data_read_entry(seq, &entries[i],
204 entry->addr, entry->primary);
205
206 /* add primary/secondary records */
207 if (batadv_compare_eth(entry->addr, packet->vis_orig))
208 batadv_vis_data_read_prim_sec(seq, list);
209
210 seq_puts(seq, "\n");
211 }
212}
213
214static void batadv_vis_seq_print_text_bucket(struct seq_file *seq,
215 const struct hlist_head *head)
216{
217 struct batadv_vis_info *info;
218 struct batadv_vis_packet *packet;
219 uint8_t *entries_pos;
220 struct batadv_vis_info_entry *entries;
221 struct batadv_vis_if_list_entry *entry;
222 struct hlist_node *n;
223
224 HLIST_HEAD(vis_if_list);
225
226 hlist_for_each_entry_rcu(info, head, hash_entry) {
227 packet = (struct batadv_vis_packet *)info->skb_packet->data;
228 entries_pos = (uint8_t *)packet + sizeof(*packet);
229 entries = (struct batadv_vis_info_entry *)entries_pos;
230
231 batadv_vis_data_insert_interface(packet->vis_orig, &vis_if_list,
232 true);
233 batadv_vis_data_insert_interfaces(&vis_if_list, packet,
234 entries);
235 batadv_vis_data_read_entries(seq, &vis_if_list, packet,
236 entries);
237
238 hlist_for_each_entry_safe(entry, n, &vis_if_list, list) {
239 hlist_del(&entry->list);
240 kfree(entry);
241 }
242 }
243}
244
245int batadv_vis_seq_print_text(struct seq_file *seq, void *offset)
246{
247 struct batadv_hard_iface *primary_if;
248 struct hlist_head *head;
249 struct net_device *net_dev = (struct net_device *)seq->private;
250 struct batadv_priv *bat_priv = netdev_priv(net_dev);
251 struct batadv_hashtable *hash = bat_priv->vis.hash;
252 uint32_t i;
253 int ret = 0;
254 int vis_server = atomic_read(&bat_priv->vis_mode);
255
256 primary_if = batadv_primary_if_get_selected(bat_priv);
257 if (!primary_if)
258 goto out;
259
260 if (vis_server == BATADV_VIS_TYPE_CLIENT_UPDATE)
261 goto out;
262
263 spin_lock_bh(&bat_priv->vis.hash_lock);
264 for (i = 0; i < hash->size; i++) {
265 head = &hash->table[i];
266 batadv_vis_seq_print_text_bucket(seq, head);
267 }
268 spin_unlock_bh(&bat_priv->vis.hash_lock);
269
270out:
271 if (primary_if)
272 batadv_hardif_free_ref(primary_if);
273 return ret;
274}
275
276/* add the info packet to the send list, if it was not
277 * already linked in.
278 */
279static void batadv_send_list_add(struct batadv_priv *bat_priv,
280 struct batadv_vis_info *info)
281{
282 if (list_empty(&info->send_list)) {
283 kref_get(&info->refcount);
284 list_add_tail(&info->send_list, &bat_priv->vis.send_list);
285 }
286}
287
288/* delete the info packet from the send list, if it was
289 * linked in.
290 */
291static void batadv_send_list_del(struct batadv_vis_info *info)
292{
293 if (!list_empty(&info->send_list)) {
294 list_del_init(&info->send_list);
295 kref_put(&info->refcount, batadv_free_info);
296 }
297}
298
299/* tries to add one entry to the receive list. */
300static void batadv_recv_list_add(struct batadv_priv *bat_priv,
301 struct list_head *recv_list, const char *mac)
302{
303 struct batadv_vis_recvlist_node *entry;
304
305 entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
306 if (!entry)
307 return;
308
309 memcpy(entry->mac, mac, ETH_ALEN);
310 spin_lock_bh(&bat_priv->vis.list_lock);
311 list_add_tail(&entry->list, recv_list);
312 spin_unlock_bh(&bat_priv->vis.list_lock);
313}
314
315/* returns 1 if this mac is in the recv_list */
316static int batadv_recv_list_is_in(struct batadv_priv *bat_priv,
317 const struct list_head *recv_list,
318 const char *mac)
319{
320 const struct batadv_vis_recvlist_node *entry;
321
322 spin_lock_bh(&bat_priv->vis.list_lock);
323 list_for_each_entry(entry, recv_list, list) {
324 if (batadv_compare_eth(entry->mac, mac)) {
325 spin_unlock_bh(&bat_priv->vis.list_lock);
326 return 1;
327 }
328 }
329 spin_unlock_bh(&bat_priv->vis.list_lock);
330 return 0;
331}
332
333/* try to add the packet to the vis_hash. return NULL if invalid (e.g. too old,
334 * broken.. ). vis hash must be locked outside. is_new is set when the packet
335 * is newer than old entries in the hash.
336 */
337static struct batadv_vis_info *
338batadv_add_packet(struct batadv_priv *bat_priv,
339 struct batadv_vis_packet *vis_packet, int vis_info_len,
340 int *is_new, int make_broadcast)
341{
342 struct batadv_vis_info *info, *old_info;
343 struct batadv_vis_packet *search_packet, *old_packet;
344 struct batadv_vis_info search_elem;
345 struct batadv_vis_packet *packet;
346 struct sk_buff *tmp_skb;
347 int hash_added;
348 size_t len;
349 size_t max_entries;
350
351 *is_new = 0;
352 /* sanity check */
353 if (!bat_priv->vis.hash)
354 return NULL;
355
356 /* see if the packet is already in vis_hash */
357 search_elem.skb_packet = dev_alloc_skb(sizeof(*search_packet));
358 if (!search_elem.skb_packet)
359 return NULL;
360 len = sizeof(*search_packet);
361 tmp_skb = search_elem.skb_packet;
362 search_packet = (struct batadv_vis_packet *)skb_put(tmp_skb, len);
363
364 memcpy(search_packet->vis_orig, vis_packet->vis_orig, ETH_ALEN);
365 old_info = batadv_vis_hash_find(bat_priv, &search_elem);
366 kfree_skb(search_elem.skb_packet);
367
368 if (old_info) {
369 tmp_skb = old_info->skb_packet;
370 old_packet = (struct batadv_vis_packet *)tmp_skb->data;
371 if (!batadv_seq_after(ntohl(vis_packet->seqno),
372 ntohl(old_packet->seqno))) {
373 if (old_packet->seqno == vis_packet->seqno) {
374 batadv_recv_list_add(bat_priv,
375 &old_info->recv_list,
376 vis_packet->sender_orig);
377 return old_info;
378 } else {
379 /* newer packet is already in hash. */
380 return NULL;
381 }
382 }
383 /* remove old entry */
384 batadv_hash_remove(bat_priv->vis.hash, batadv_vis_info_cmp,
385 batadv_vis_info_choose, old_info);
386 batadv_send_list_del(old_info);
387 kref_put(&old_info->refcount, batadv_free_info);
388 }
389
390 info = kmalloc(sizeof(*info), GFP_ATOMIC);
391 if (!info)
392 return NULL;
393
394 len = sizeof(*packet) + vis_info_len;
395 info->skb_packet = netdev_alloc_skb_ip_align(NULL, len + ETH_HLEN);
396 if (!info->skb_packet) {
397 kfree(info);
398 return NULL;
399 }
400 info->skb_packet->priority = TC_PRIO_CONTROL;
401 skb_reserve(info->skb_packet, ETH_HLEN);
402 packet = (struct batadv_vis_packet *)skb_put(info->skb_packet, len);
403
404 kref_init(&info->refcount);
405 INIT_LIST_HEAD(&info->send_list);
406 INIT_LIST_HEAD(&info->recv_list);
407 info->first_seen = jiffies;
408 info->bat_priv = bat_priv;
409 memcpy(packet, vis_packet, len);
410
411 /* initialize and add new packet. */
412 *is_new = 1;
413
414 /* Make it a broadcast packet, if required */
415 if (make_broadcast)
416 memcpy(packet->target_orig, batadv_broadcast_addr, ETH_ALEN);
417
418 /* repair if entries is longer than packet. */
419 max_entries = vis_info_len / sizeof(struct batadv_vis_info_entry);
420 if (packet->entries > max_entries)
421 packet->entries = max_entries;
422
423 batadv_recv_list_add(bat_priv, &info->recv_list, packet->sender_orig);
424
425 /* try to add it */
426 hash_added = batadv_hash_add(bat_priv->vis.hash, batadv_vis_info_cmp,
427 batadv_vis_info_choose, info,
428 &info->hash_entry);
429 if (hash_added != 0) {
430 /* did not work (for some reason) */
431 kref_put(&info->refcount, batadv_free_info);
432 info = NULL;
433 }
434
435 return info;
436}
437
438/* handle the server sync packet, forward if needed. */
439void batadv_receive_server_sync_packet(struct batadv_priv *bat_priv,
440 struct batadv_vis_packet *vis_packet,
441 int vis_info_len)
442{
443 struct batadv_vis_info *info;
444 int is_new, make_broadcast;
445 int vis_server = atomic_read(&bat_priv->vis_mode);
446
447 make_broadcast = (vis_server == BATADV_VIS_TYPE_SERVER_SYNC);
448
449 spin_lock_bh(&bat_priv->vis.hash_lock);
450 info = batadv_add_packet(bat_priv, vis_packet, vis_info_len,
451 &is_new, make_broadcast);
452 if (!info)
453 goto end;
454
455 /* only if we are server ourselves and packet is newer than the one in
456 * hash.
457 */
458 if (vis_server == BATADV_VIS_TYPE_SERVER_SYNC && is_new)
459 batadv_send_list_add(bat_priv, info);
460end:
461 spin_unlock_bh(&bat_priv->vis.hash_lock);
462}
463
464/* handle an incoming client update packet and schedule forward if needed. */
465void batadv_receive_client_update_packet(struct batadv_priv *bat_priv,
466 struct batadv_vis_packet *vis_packet,
467 int vis_info_len)
468{
469 struct batadv_vis_info *info;
470 struct batadv_vis_packet *packet;
471 int is_new;
472 int vis_server = atomic_read(&bat_priv->vis_mode);
473 int are_target = 0;
474
475 /* clients shall not broadcast. */
476 if (is_broadcast_ether_addr(vis_packet->target_orig))
477 return;
478
479 /* Are we the target for this VIS packet? */
480 if (vis_server == BATADV_VIS_TYPE_SERVER_SYNC &&
481 batadv_is_my_mac(bat_priv, vis_packet->target_orig))
482 are_target = 1;
483
484 spin_lock_bh(&bat_priv->vis.hash_lock);
485 info = batadv_add_packet(bat_priv, vis_packet, vis_info_len,
486 &is_new, are_target);
487
488 if (!info)
489 goto end;
490 /* note that outdated packets will be dropped at this point. */
491
492 packet = (struct batadv_vis_packet *)info->skb_packet->data;
493
494 /* send only if we're the target server or ... */
495 if (are_target && is_new) {
496 packet->vis_type = BATADV_VIS_TYPE_SERVER_SYNC; /* upgrade! */
497 batadv_send_list_add(bat_priv, info);
498
499 /* ... we're not the recipient (and thus need to forward). */
500 } else if (!batadv_is_my_mac(bat_priv, packet->target_orig)) {
501 batadv_send_list_add(bat_priv, info);
502 }
503
504end:
505 spin_unlock_bh(&bat_priv->vis.hash_lock);
506}
507
508/* Walk the originators and find the VIS server with the best tq. Set the packet
509 * address to its address and return the best_tq.
510 *
511 * Must be called with the originator hash locked
512 */
513static int batadv_find_best_vis_server(struct batadv_priv *bat_priv,
514 struct batadv_vis_info *info)
515{
516 struct batadv_hashtable *hash = bat_priv->orig_hash;
517 struct batadv_neigh_node *router;
518 struct hlist_head *head;
519 struct batadv_orig_node *orig_node;
520 struct batadv_vis_packet *packet;
521 int best_tq = -1;
522 uint32_t i;
523
524 packet = (struct batadv_vis_packet *)info->skb_packet->data;
525
526 for (i = 0; i < hash->size; i++) {
527 head = &hash->table[i];
528
529 rcu_read_lock();
530 hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
531 router = batadv_orig_node_get_router(orig_node);
532 if (!router)
533 continue;
534
535 if ((orig_node->flags & BATADV_VIS_SERVER) &&
536 (router->tq_avg > best_tq)) {
537 best_tq = router->tq_avg;
538 memcpy(packet->target_orig, orig_node->orig,
539 ETH_ALEN);
540 }
541 batadv_neigh_node_free_ref(router);
542 }
543 rcu_read_unlock();
544 }
545
546 return best_tq;
547}
548
549/* Return true if the vis packet is full. */
550static bool batadv_vis_packet_full(const struct batadv_vis_info *info)
551{
552 const struct batadv_vis_packet *packet;
553 size_t num;
554
555 packet = (struct batadv_vis_packet *)info->skb_packet->data;
556 num = BATADV_MAX_VIS_PACKET_SIZE / sizeof(struct batadv_vis_info_entry);
557
558 if (num < packet->entries + 1)
559 return true;
560 return false;
561}
562
563/* generates a packet of own vis data,
564 * returns 0 on success, -1 if no packet could be generated
565 */
566static int batadv_generate_vis_packet(struct batadv_priv *bat_priv)
567{
568 struct batadv_hashtable *hash = bat_priv->orig_hash;
569 struct hlist_head *head;
570 struct batadv_orig_node *orig_node;
571 struct batadv_neigh_node *router;
572 struct batadv_vis_info *info = bat_priv->vis.my_info;
573 struct batadv_vis_packet *packet;
574 struct batadv_vis_info_entry *entry;
575 struct batadv_tt_common_entry *tt_common_entry;
576 uint8_t *packet_pos;
577 int best_tq = -1;
578 uint32_t i;
579
580 info->first_seen = jiffies;
581 packet = (struct batadv_vis_packet *)info->skb_packet->data;
582 packet->vis_type = atomic_read(&bat_priv->vis_mode);
583
584 memcpy(packet->target_orig, batadv_broadcast_addr, ETH_ALEN);
585 packet->header.ttl = BATADV_TTL;
586 packet->seqno = htonl(ntohl(packet->seqno) + 1);
587 packet->entries = 0;
588 packet->reserved = 0;
589 skb_trim(info->skb_packet, sizeof(*packet));
590
591 if (packet->vis_type == BATADV_VIS_TYPE_CLIENT_UPDATE) {
592 best_tq = batadv_find_best_vis_server(bat_priv, info);
593
594 if (best_tq < 0)
595 return best_tq;
596 }
597
598 for (i = 0; i < hash->size; i++) {
599 head = &hash->table[i];
600
601 rcu_read_lock();
602 hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
603 router = batadv_orig_node_get_router(orig_node);
604 if (!router)
605 continue;
606
607 if (!batadv_compare_eth(router->addr, orig_node->orig))
608 goto next;
609
610 if (router->if_incoming->if_status != BATADV_IF_ACTIVE)
611 goto next;
612
613 if (router->tq_avg < 1)
614 goto next;
615
616 /* fill one entry into buffer. */
617 packet_pos = skb_put(info->skb_packet, sizeof(*entry));
618 entry = (struct batadv_vis_info_entry *)packet_pos;
619 memcpy(entry->src,
620 router->if_incoming->net_dev->dev_addr,
621 ETH_ALEN);
622 memcpy(entry->dest, orig_node->orig, ETH_ALEN);
623 entry->quality = router->tq_avg;
624 packet->entries++;
625
626next:
627 batadv_neigh_node_free_ref(router);
628
629 if (batadv_vis_packet_full(info))
630 goto unlock;
631 }
632 rcu_read_unlock();
633 }
634
635 hash = bat_priv->tt.local_hash;
636
637 for (i = 0; i < hash->size; i++) {
638 head = &hash->table[i];
639
640 rcu_read_lock();
641 hlist_for_each_entry_rcu(tt_common_entry, head,
642 hash_entry) {
643 packet_pos = skb_put(info->skb_packet, sizeof(*entry));
644 entry = (struct batadv_vis_info_entry *)packet_pos;
645 memset(entry->src, 0, ETH_ALEN);
646 memcpy(entry->dest, tt_common_entry->addr, ETH_ALEN);
647 entry->quality = 0; /* 0 means TT */
648 packet->entries++;
649
650 if (batadv_vis_packet_full(info))
651 goto unlock;
652 }
653 rcu_read_unlock();
654 }
655
656 return 0;
657
658unlock:
659 rcu_read_unlock();
660 return 0;
661}
662
663/* free old vis packets. Must be called with this vis_hash_lock
664 * held
665 */
666static void batadv_purge_vis_packets(struct batadv_priv *bat_priv)
667{
668 uint32_t i;
669 struct batadv_hashtable *hash = bat_priv->vis.hash;
670 struct hlist_node *node_tmp;
671 struct hlist_head *head;
672 struct batadv_vis_info *info;
673
674 for (i = 0; i < hash->size; i++) {
675 head = &hash->table[i];
676
677 hlist_for_each_entry_safe(info, node_tmp,
678 head, hash_entry) {
679 /* never purge own data. */
680 if (info == bat_priv->vis.my_info)
681 continue;
682
683 if (batadv_has_timed_out(info->first_seen,
684 BATADV_VIS_TIMEOUT)) {
685 hlist_del(&info->hash_entry);
686 batadv_send_list_del(info);
687 kref_put(&info->refcount, batadv_free_info);
688 }
689 }
690 }
691}
692
693static void batadv_broadcast_vis_packet(struct batadv_priv *bat_priv,
694 struct batadv_vis_info *info)
695{
696 struct batadv_hashtable *hash = bat_priv->orig_hash;
697 struct hlist_head *head;
698 struct batadv_orig_node *orig_node;
699 struct batadv_vis_packet *packet;
700 struct sk_buff *skb;
701 uint32_t i, res;
702
703
704 packet = (struct batadv_vis_packet *)info->skb_packet->data;
705
706 /* send to all routers in range. */
707 for (i = 0; i < hash->size; i++) {
708 head = &hash->table[i];
709
710 rcu_read_lock();
711 hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
712 /* if it's a vis server and reachable, send it. */
713 if (!(orig_node->flags & BATADV_VIS_SERVER))
714 continue;
715
716 /* don't send it if we already received the packet from
717 * this node.
718 */
719 if (batadv_recv_list_is_in(bat_priv, &info->recv_list,
720 orig_node->orig))
721 continue;
722
723 memcpy(packet->target_orig, orig_node->orig, ETH_ALEN);
724 skb = skb_clone(info->skb_packet, GFP_ATOMIC);
725 if (!skb)
726 continue;
727
728 res = batadv_send_skb_to_orig(skb, orig_node, NULL);
729 if (res == NET_XMIT_DROP)
730 kfree_skb(skb);
731 }
732 rcu_read_unlock();
733 }
734}
735
736static void batadv_unicast_vis_packet(struct batadv_priv *bat_priv,
737 struct batadv_vis_info *info)
738{
739 struct batadv_orig_node *orig_node;
740 struct sk_buff *skb;
741 struct batadv_vis_packet *packet;
742
743 packet = (struct batadv_vis_packet *)info->skb_packet->data;
744
745 orig_node = batadv_orig_hash_find(bat_priv, packet->target_orig);
746 if (!orig_node)
747 goto out;
748
749 skb = skb_clone(info->skb_packet, GFP_ATOMIC);
750 if (!skb)
751 goto out;
752
753 if (batadv_send_skb_to_orig(skb, orig_node, NULL) == NET_XMIT_DROP)
754 kfree_skb(skb);
755
756out:
757 if (orig_node)
758 batadv_orig_node_free_ref(orig_node);
759}
760
761/* only send one vis packet. called from batadv_send_vis_packets() */
762static void batadv_send_vis_packet(struct batadv_priv *bat_priv,
763 struct batadv_vis_info *info)
764{
765 struct batadv_hard_iface *primary_if;
766 struct batadv_vis_packet *packet;
767
768 primary_if = batadv_primary_if_get_selected(bat_priv);
769 if (!primary_if)
770 goto out;
771
772 packet = (struct batadv_vis_packet *)info->skb_packet->data;
773 if (packet->header.ttl < 2) {
774 pr_debug("Error - can't send vis packet: ttl exceeded\n");
775 goto out;
776 }
777
778 memcpy(packet->sender_orig, primary_if->net_dev->dev_addr, ETH_ALEN);
779 packet->header.ttl--;
780
781 if (is_broadcast_ether_addr(packet->target_orig))
782 batadv_broadcast_vis_packet(bat_priv, info);
783 else
784 batadv_unicast_vis_packet(bat_priv, info);
785 packet->header.ttl++; /* restore TTL */
786
787out:
788 if (primary_if)
789 batadv_hardif_free_ref(primary_if);
790}
791
792/* called from timer; send (and maybe generate) vis packet. */
793static void batadv_send_vis_packets(struct work_struct *work)
794{
795 struct delayed_work *delayed_work;
796 struct batadv_priv *bat_priv;
797 struct batadv_priv_vis *priv_vis;
798 struct batadv_vis_info *info;
799
800 delayed_work = container_of(work, struct delayed_work, work);
801 priv_vis = container_of(delayed_work, struct batadv_priv_vis, work);
802 bat_priv = container_of(priv_vis, struct batadv_priv, vis);
803 spin_lock_bh(&bat_priv->vis.hash_lock);
804 batadv_purge_vis_packets(bat_priv);
805
806 if (batadv_generate_vis_packet(bat_priv) == 0) {
807 /* schedule if generation was successful */
808 batadv_send_list_add(bat_priv, bat_priv->vis.my_info);
809 }
810
811 while (!list_empty(&bat_priv->vis.send_list)) {
812 info = list_first_entry(&bat_priv->vis.send_list,
813 typeof(*info), send_list);
814
815 kref_get(&info->refcount);
816 spin_unlock_bh(&bat_priv->vis.hash_lock);
817
818 batadv_send_vis_packet(bat_priv, info);
819
820 spin_lock_bh(&bat_priv->vis.hash_lock);
821 batadv_send_list_del(info);
822 kref_put(&info->refcount, batadv_free_info);
823 }
824 spin_unlock_bh(&bat_priv->vis.hash_lock);
825
826 queue_delayed_work(batadv_event_workqueue, &bat_priv->vis.work,
827 msecs_to_jiffies(BATADV_VIS_INTERVAL));
828}
829
830/* init the vis server. this may only be called when if_list is already
831 * initialized (e.g. bat0 is initialized, interfaces have been added)
832 */
833int batadv_vis_init(struct batadv_priv *bat_priv)
834{
835 struct batadv_vis_packet *packet;
836 int hash_added;
837 unsigned int len;
838 unsigned long first_seen;
839 struct sk_buff *tmp_skb;
840
841 if (bat_priv->vis.hash)
842 return 0;
843
844 spin_lock_bh(&bat_priv->vis.hash_lock);
845
846 bat_priv->vis.hash = batadv_hash_new(256);
847 if (!bat_priv->vis.hash) {
848 pr_err("Can't initialize vis_hash\n");
849 goto err;
850 }
851
852 batadv_hash_set_lock_class(bat_priv->vis.hash,
853 &batadv_vis_hash_lock_class_key);
854
855 bat_priv->vis.my_info = kmalloc(BATADV_MAX_VIS_PACKET_SIZE, GFP_ATOMIC);
856 if (!bat_priv->vis.my_info)
857 goto err;
858
859 len = sizeof(*packet) + BATADV_MAX_VIS_PACKET_SIZE + ETH_HLEN;
860 bat_priv->vis.my_info->skb_packet = netdev_alloc_skb_ip_align(NULL,
861 len);
862 if (!bat_priv->vis.my_info->skb_packet)
863 goto free_info;
864
865 bat_priv->vis.my_info->skb_packet->priority = TC_PRIO_CONTROL;
866 skb_reserve(bat_priv->vis.my_info->skb_packet, ETH_HLEN);
867 tmp_skb = bat_priv->vis.my_info->skb_packet;
868 packet = (struct batadv_vis_packet *)skb_put(tmp_skb, sizeof(*packet));
869
870 /* prefill the vis info */
871 first_seen = jiffies - msecs_to_jiffies(BATADV_VIS_INTERVAL);
872 bat_priv->vis.my_info->first_seen = first_seen;
873 INIT_LIST_HEAD(&bat_priv->vis.my_info->recv_list);
874 INIT_LIST_HEAD(&bat_priv->vis.my_info->send_list);
875 kref_init(&bat_priv->vis.my_info->refcount);
876 bat_priv->vis.my_info->bat_priv = bat_priv;
877 packet->header.version = BATADV_COMPAT_VERSION;
878 packet->header.packet_type = BATADV_VIS;
879 packet->header.ttl = BATADV_TTL;
880 packet->seqno = 0;
881 packet->reserved = 0;
882 packet->entries = 0;
883
884 INIT_LIST_HEAD(&bat_priv->vis.send_list);
885
886 hash_added = batadv_hash_add(bat_priv->vis.hash, batadv_vis_info_cmp,
887 batadv_vis_info_choose,
888 bat_priv->vis.my_info,
889 &bat_priv->vis.my_info->hash_entry);
890 if (hash_added != 0) {
891 pr_err("Can't add own vis packet into hash\n");
892 /* not in hash, need to remove it manually. */
893 kref_put(&bat_priv->vis.my_info->refcount, batadv_free_info);
894 goto err;
895 }
896
897 spin_unlock_bh(&bat_priv->vis.hash_lock);
898
899 INIT_DELAYED_WORK(&bat_priv->vis.work, batadv_send_vis_packets);
900 queue_delayed_work(batadv_event_workqueue, &bat_priv->vis.work,
901 msecs_to_jiffies(BATADV_VIS_INTERVAL));
902
903 return 0;
904
905free_info:
906 kfree(bat_priv->vis.my_info);
907 bat_priv->vis.my_info = NULL;
908err:
909 spin_unlock_bh(&bat_priv->vis.hash_lock);
910 batadv_vis_quit(bat_priv);
911 return -ENOMEM;
912}
913
914/* Decrease the reference count on a hash item info */
915static void batadv_free_info_ref(struct hlist_node *node, void *arg)
916{
917 struct batadv_vis_info *info;
918
919 info = container_of(node, struct batadv_vis_info, hash_entry);
920 batadv_send_list_del(info);
921 kref_put(&info->refcount, batadv_free_info);
922}
923
924/* shutdown vis-server */
925void batadv_vis_quit(struct batadv_priv *bat_priv)
926{
927 if (!bat_priv->vis.hash)
928 return;
929
930 cancel_delayed_work_sync(&bat_priv->vis.work);
931
932 spin_lock_bh(&bat_priv->vis.hash_lock);
933 /* properly remove, kill timers ... */
934 batadv_hash_delete(bat_priv->vis.hash, batadv_free_info_ref, NULL);
935 bat_priv->vis.hash = NULL;
936 bat_priv->vis.my_info = NULL;
937 spin_unlock_bh(&bat_priv->vis.hash_lock);
938}
diff --git a/net/batman-adv/vis.h b/net/batman-adv/vis.h
deleted file mode 100644
index ad92b0e3c230..000000000000
--- a/net/batman-adv/vis.h
+++ /dev/null
@@ -1,36 +0,0 @@
1/* Copyright (C) 2008-2013 B.A.T.M.A.N. contributors:
2 *
3 * Simon Wunderlich, Marek Lindner
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_VIS_H_
21#define _NET_BATMAN_ADV_VIS_H_
22
23/* timeout of vis packets in milliseconds */
24#define BATADV_VIS_TIMEOUT 200000
25
26int batadv_vis_seq_print_text(struct seq_file *seq, void *offset);
27void batadv_receive_server_sync_packet(struct batadv_priv *bat_priv,
28 struct batadv_vis_packet *vis_packet,
29 int vis_info_len);
30void batadv_receive_client_update_packet(struct batadv_priv *bat_priv,
31 struct batadv_vis_packet *vis_packet,
32 int vis_info_len);
33int batadv_vis_init(struct batadv_priv *bat_priv);
34void batadv_vis_quit(struct batadv_priv *bat_priv);
35
36#endif /* _NET_BATMAN_ADV_VIS_H_ */