aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Hundebøll <martin@hundeboll.net>2013-05-23 10:53:01 -0400
committerAntonio Quartulli <antonio@meshcoding.com>2013-10-12 05:58:33 -0400
commitf097e25dbe9144447f46b6b61ca3da1a2ba432d4 (patch)
tree72ead8362929e5f60de67f2a15b716fd73265d32
parent2c598663e84c8c8edbbac568e9e94e1fac410c3c (diff)
batman-adv: Remove old fragmentation code
Remove the existing fragmentation code before adding the new version and delete unicast.{h,c}. batadv_unicast_send_skb() is moved to send.c and renamed to batadv_send_skb_unicast(). fragmentation entry in sysfs (bat_priv->fragmentation) is kept for use in the new fragmentation code. BATADV_UNICAST_FRAG packet type is renamed to BATADV_FRAG for use in the new fragmentation code. Signed-off-by: Martin Hundebøll <martin@hundeboll.net> Signed-off-by: Marek Lindner <lindner_marek@yahoo.de> Signed-off-by: Antonio Quartulli <antonio@meshcoding.com>
-rw-r--r--net/batman-adv/Makefile1
-rw-r--r--net/batman-adv/distributed-arp-table.c11
-rw-r--r--net/batman-adv/hard-interface.c1
-rw-r--r--net/batman-adv/main.c4
-rw-r--r--net/batman-adv/originator.c9
-rw-r--r--net/batman-adv/packet.h16
-rw-r--r--net/batman-adv/routing.c86
-rw-r--r--net/batman-adv/routing.h2
-rw-r--r--net/batman-adv/send.c174
-rw-r--r--net/batman-adv/send.h40
-rw-r--r--net/batman-adv/soft-interface.c4
-rw-r--r--net/batman-adv/types.h19
-rw-r--r--net/batman-adv/unicast.c491
-rw-r--r--net/batman-adv/unicast.h92
14 files changed, 221 insertions, 729 deletions
diff --git a/net/batman-adv/Makefile b/net/batman-adv/Makefile
index 8ddbfe66d637..f9b465b00555 100644
--- a/net/batman-adv/Makefile
+++ b/net/batman-adv/Makefile
@@ -37,4 +37,3 @@ batman-adv-y += send.o
37batman-adv-y += soft-interface.o 37batman-adv-y += soft-interface.o
38batman-adv-y += sysfs.o 38batman-adv-y += sysfs.o
39batman-adv-y += translation-table.o 39batman-adv-y += translation-table.o
40batman-adv-y += unicast.o
diff --git a/net/batman-adv/distributed-arp-table.c b/net/batman-adv/distributed-arp-table.c
index f07ec320dc01..99da41290f82 100644
--- a/net/batman-adv/distributed-arp-table.c
+++ b/net/batman-adv/distributed-arp-table.c
@@ -29,7 +29,6 @@
29#include "send.h" 29#include "send.h"
30#include "types.h" 30#include "types.h"
31#include "translation-table.h" 31#include "translation-table.h"
32#include "unicast.h"
33 32
34static void batadv_dat_purge(struct work_struct *work); 33static void batadv_dat_purge(struct work_struct *work);
35 34
@@ -592,9 +591,9 @@ static bool batadv_dat_send_data(struct batadv_priv *bat_priv,
592 goto free_orig; 591 goto free_orig;
593 592
594 tmp_skb = pskb_copy(skb, GFP_ATOMIC); 593 tmp_skb = pskb_copy(skb, GFP_ATOMIC);
595 if (!batadv_unicast_4addr_prepare_skb(bat_priv, tmp_skb, 594 if (!batadv_send_skb_prepare_unicast_4addr(bat_priv, tmp_skb,
596 cand[i].orig_node, 595 cand[i].orig_node,
597 packet_subtype)) { 596 packet_subtype)) {
598 kfree_skb(tmp_skb); 597 kfree_skb(tmp_skb);
599 goto free_neigh; 598 goto free_neigh;
600 } 599 }
@@ -990,10 +989,10 @@ bool batadv_dat_snoop_incoming_arp_request(struct batadv_priv *bat_priv,
990 * that a node not using the 4addr packet format doesn't support it. 989 * that a node not using the 4addr packet format doesn't support it.
991 */ 990 */
992 if (hdr_size == sizeof(struct batadv_unicast_4addr_packet)) 991 if (hdr_size == sizeof(struct batadv_unicast_4addr_packet))
993 err = batadv_unicast_4addr_send_skb(bat_priv, skb_new, 992 err = batadv_send_skb_unicast_4addr(bat_priv, skb_new,
994 BATADV_P_DAT_CACHE_REPLY); 993 BATADV_P_DAT_CACHE_REPLY);
995 else 994 else
996 err = batadv_unicast_send_skb(bat_priv, skb_new); 995 err = batadv_send_skb_unicast(bat_priv, skb_new);
997 996
998 if (!err) { 997 if (!err) {
999 batadv_inc_counter(bat_priv, BATADV_CNT_DAT_CACHED_REPLY_TX); 998 batadv_inc_counter(bat_priv, BATADV_CNT_DAT_CACHED_REPLY_TX);
diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c
index eeb667112d64..0c8602e5a5c4 100644
--- a/net/batman-adv/hard-interface.c
+++ b/net/batman-adv/hard-interface.c
@@ -444,7 +444,6 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface,
444 hard_iface->batman_adv_ptype.dev = hard_iface->net_dev; 444 hard_iface->batman_adv_ptype.dev = hard_iface->net_dev;
445 dev_add_pack(&hard_iface->batman_adv_ptype); 445 dev_add_pack(&hard_iface->batman_adv_ptype);
446 446
447 atomic_set(&hard_iface->frag_seqno, 1);
448 batadv_info(hard_iface->soft_iface, "Adding interface: %s\n", 447 batadv_info(hard_iface->soft_iface, "Adding interface: %s\n",
449 hard_iface->net_dev->name); 448 hard_iface->net_dev->name);
450 449
diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c
index 8b195e63e70e..8822fad5694e 100644
--- a/net/batman-adv/main.c
+++ b/net/batman-adv/main.c
@@ -36,7 +36,6 @@
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 "unicast.h"
40#include "gateway_common.h" 39#include "gateway_common.h"
41#include "hash.h" 40#include "hash.h"
42#include "bat_algo.h" 41#include "bat_algo.h"
@@ -399,7 +398,6 @@ static void batadv_recv_handler_init(void)
399 /* compile time checks for struct member offsets */ 398 /* compile time checks for struct member offsets */
400 BUILD_BUG_ON(offsetof(struct batadv_unicast_4addr_packet, src) != 10); 399 BUILD_BUG_ON(offsetof(struct batadv_unicast_4addr_packet, src) != 10);
401 BUILD_BUG_ON(offsetof(struct batadv_unicast_packet, dest) != 4); 400 BUILD_BUG_ON(offsetof(struct batadv_unicast_packet, dest) != 4);
402 BUILD_BUG_ON(offsetof(struct batadv_unicast_frag_packet, dest) != 4);
403 BUILD_BUG_ON(offsetof(struct batadv_unicast_tvlv_packet, dst) != 4); 401 BUILD_BUG_ON(offsetof(struct batadv_unicast_tvlv_packet, dst) != 4);
404 BUILD_BUG_ON(offsetof(struct batadv_icmp_packet, dst) != 4); 402 BUILD_BUG_ON(offsetof(struct batadv_icmp_packet, dst) != 4);
405 BUILD_BUG_ON(offsetof(struct batadv_icmp_packet_rr, dst) != 4); 403 BUILD_BUG_ON(offsetof(struct batadv_icmp_packet_rr, dst) != 4);
@@ -412,8 +410,6 @@ static void batadv_recv_handler_init(void)
412 batadv_rx_handler[BATADV_UNICAST_4ADDR] = batadv_recv_unicast_packet; 410 batadv_rx_handler[BATADV_UNICAST_4ADDR] = batadv_recv_unicast_packet;
413 /* unicast packet */ 411 /* unicast packet */
414 batadv_rx_handler[BATADV_UNICAST] = batadv_recv_unicast_packet; 412 batadv_rx_handler[BATADV_UNICAST] = batadv_recv_unicast_packet;
415 /* fragmented unicast packet */
416 batadv_rx_handler[BATADV_UNICAST_FRAG] = batadv_recv_ucast_frag_packet;
417 /* unicast tvlv packet */ 413 /* unicast tvlv packet */
418 batadv_rx_handler[BATADV_UNICAST_TVLV] = batadv_recv_unicast_tvlv; 414 batadv_rx_handler[BATADV_UNICAST_TVLV] = batadv_recv_unicast_tvlv;
419 /* batman icmp packet */ 415 /* batman icmp packet */
diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c
index 5d53d2f38377..898b0ce82cc2 100644
--- a/net/batman-adv/originator.c
+++ b/net/batman-adv/originator.c
@@ -25,7 +25,6 @@
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"
@@ -146,7 +145,6 @@ static void batadv_orig_node_free_rcu(struct rcu_head *rcu)
146 /* Free nc_nodes */ 145 /* Free nc_nodes */
147 batadv_nc_purge_orig(orig_node->bat_priv, orig_node, NULL); 146 batadv_nc_purge_orig(orig_node->bat_priv, orig_node, NULL);
148 147
149 batadv_frag_list_free(&orig_node->frag_list);
150 batadv_tt_global_del_orig(orig_node->bat_priv, orig_node, 148 batadv_tt_global_del_orig(orig_node->bat_priv, orig_node,
151 "originator timed out"); 149 "originator timed out");
152 150
@@ -269,9 +267,6 @@ struct batadv_orig_node *batadv_get_orig_node(struct batadv_priv *bat_priv,
269 size = bat_priv->num_ifaces * sizeof(uint8_t); 267 size = bat_priv->num_ifaces * sizeof(uint8_t);
270 orig_node->bcast_own_sum = kzalloc(size, GFP_ATOMIC); 268 orig_node->bcast_own_sum = kzalloc(size, GFP_ATOMIC);
271 269
272 INIT_LIST_HEAD(&orig_node->frag_list);
273 orig_node->last_frag_packet = 0;
274
275 if (!orig_node->bcast_own_sum) 270 if (!orig_node->bcast_own_sum)
276 goto free_bcast_own; 271 goto free_bcast_own;
277 272
@@ -393,10 +388,6 @@ static void _batadv_purge_orig(struct batadv_priv *bat_priv)
393 batadv_orig_node_free_ref(orig_node); 388 batadv_orig_node_free_ref(orig_node);
394 continue; 389 continue;
395 } 390 }
396
397 if (batadv_has_timed_out(orig_node->last_frag_packet,
398 BATADV_FRAG_TIMEOUT))
399 batadv_frag_list_free(&orig_node->frag_list);
400 } 391 }
401 spin_unlock_bh(list_lock); 392 spin_unlock_bh(list_lock);
402 } 393 }
diff --git a/net/batman-adv/packet.h b/net/batman-adv/packet.h
index 4361bae6186a..5e3b1026b509 100644
--- a/net/batman-adv/packet.h
+++ b/net/batman-adv/packet.h
@@ -91,12 +91,6 @@ enum batadv_icmp_packettype {
91 BATADV_PARAMETER_PROBLEM = 12, 91 BATADV_PARAMETER_PROBLEM = 12,
92}; 92};
93 93
94/* fragmentation defines */
95enum batadv_unicast_frag_flags {
96 BATADV_UNI_FRAG_HEAD = BIT(0),
97 BATADV_UNI_FRAG_LARGETAIL = BIT(1),
98};
99
100/* tt data subtypes */ 94/* tt data subtypes */
101#define BATADV_TT_DATA_TYPE_MASK 0x0F 95#define BATADV_TT_DATA_TYPE_MASK 0x0F
102 96
@@ -255,16 +249,6 @@ struct batadv_unicast_4addr_packet {
255 */ 249 */
256}; 250};
257 251
258struct batadv_unicast_frag_packet {
259 struct batadv_header header;
260 uint8_t ttvn; /* destination translation table version number */
261 uint8_t dest[ETH_ALEN];
262 uint8_t flags;
263 uint8_t align;
264 uint8_t orig[ETH_ALEN];
265 __be16 seqno;
266} __packed;
267
268struct batadv_bcast_packet { 252struct batadv_bcast_packet {
269 struct batadv_header header; 253 struct batadv_header header;
270 uint8_t reserved; 254 uint8_t reserved;
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
index 0dc1c0e84451..fd2cdbc3ea85 100644
--- a/net/batman-adv/routing.c
+++ b/net/batman-adv/routing.c
@@ -25,7 +25,6 @@
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 "unicast.h"
29#include "bridge_loop_avoidance.h" 28#include "bridge_loop_avoidance.h"
30#include "distributed-arp-table.h" 29#include "distributed-arp-table.h"
31#include "network-coding.h" 30#include "network-coding.h"
@@ -653,11 +652,9 @@ static int batadv_route_unicast_packet(struct sk_buff *skb,
653{ 652{
654 struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface); 653 struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface);
655 struct batadv_orig_node *orig_node = NULL; 654 struct batadv_orig_node *orig_node = NULL;
656 struct batadv_neigh_node *neigh_node = NULL;
657 struct batadv_unicast_packet *unicast_packet; 655 struct batadv_unicast_packet *unicast_packet;
658 struct ethhdr *ethhdr = eth_hdr(skb); 656 struct ethhdr *ethhdr = eth_hdr(skb);
659 int res, hdr_len, ret = NET_RX_DROP; 657 int res, hdr_len, ret = NET_RX_DROP;
660 struct sk_buff *new_skb;
661 658
662 unicast_packet = (struct batadv_unicast_packet *)skb->data; 659 unicast_packet = (struct batadv_unicast_packet *)skb->data;
663 660
@@ -674,46 +671,12 @@ static int batadv_route_unicast_packet(struct sk_buff *skb,
674 if (!orig_node) 671 if (!orig_node)
675 goto out; 672 goto out;
676 673
677 /* find_router() increases neigh_nodes refcount if found. */
678 neigh_node = batadv_find_router(bat_priv, orig_node, recv_if);
679
680 if (!neigh_node)
681 goto out;
682
683 /* create a copy of the skb, if needed, to modify it. */ 674 /* create a copy of the skb, if needed, to modify it. */
684 if (skb_cow(skb, ETH_HLEN) < 0) 675 if (skb_cow(skb, ETH_HLEN) < 0)
685 goto out; 676 goto out;
686 677
687 unicast_packet = (struct batadv_unicast_packet *)skb->data;
688
689 if (unicast_packet->header.packet_type == BATADV_UNICAST &&
690 atomic_read(&bat_priv->fragmentation) &&
691 skb->len > neigh_node->if_incoming->net_dev->mtu) {
692 ret = batadv_frag_send_skb(skb, bat_priv,
693 neigh_node->if_incoming,
694 neigh_node->addr);
695 goto out;
696 }
697
698 if (unicast_packet->header.packet_type == BATADV_UNICAST_FRAG &&
699 batadv_frag_can_reassemble(skb,
700 neigh_node->if_incoming->net_dev->mtu)) {
701 ret = batadv_frag_reassemble_skb(skb, bat_priv, &new_skb);
702
703 if (ret == NET_RX_DROP)
704 goto out;
705
706 /* packet was buffered for late merge */
707 if (!new_skb) {
708 ret = NET_RX_SUCCESS;
709 goto out;
710 }
711
712 skb = new_skb;
713 unicast_packet = (struct batadv_unicast_packet *)skb->data;
714 }
715
716 /* decrement ttl */ 678 /* decrement ttl */
679 unicast_packet = (struct batadv_unicast_packet *)skb->data;
717 unicast_packet->header.ttl--; 680 unicast_packet->header.ttl--;
718 681
719 switch (unicast_packet->header.packet_type) { 682 switch (unicast_packet->header.packet_type) {
@@ -748,8 +711,6 @@ static int batadv_route_unicast_packet(struct sk_buff *skb,
748 } 711 }
749 712
750out: 713out:
751 if (neigh_node)
752 batadv_neigh_node_free_ref(neigh_node);
753 if (orig_node) 714 if (orig_node)
754 batadv_orig_node_free_ref(orig_node); 715 batadv_orig_node_free_ref(orig_node);
755 return ret; 716 return ret;
@@ -1003,51 +964,6 @@ rx_success:
1003 return batadv_route_unicast_packet(skb, recv_if); 964 return batadv_route_unicast_packet(skb, recv_if);
1004} 965}
1005 966
1006int batadv_recv_ucast_frag_packet(struct sk_buff *skb,
1007 struct batadv_hard_iface *recv_if)
1008{
1009 struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface);
1010 struct batadv_unicast_frag_packet *unicast_packet;
1011 int hdr_size = sizeof(*unicast_packet);
1012 struct sk_buff *new_skb = NULL;
1013 int ret;
1014
1015 if (batadv_check_unicast_packet(bat_priv, skb, hdr_size) < 0)
1016 return NET_RX_DROP;
1017
1018 if (!batadv_check_unicast_ttvn(bat_priv, skb, hdr_size))
1019 return NET_RX_DROP;
1020
1021 unicast_packet = (struct batadv_unicast_frag_packet *)skb->data;
1022
1023 /* packet for me */
1024 if (batadv_is_my_mac(bat_priv, unicast_packet->dest)) {
1025 ret = batadv_frag_reassemble_skb(skb, bat_priv, &new_skb);
1026
1027 if (ret == NET_RX_DROP)
1028 return NET_RX_DROP;
1029
1030 /* packet was buffered for late merge */
1031 if (!new_skb)
1032 return NET_RX_SUCCESS;
1033
1034 if (batadv_dat_snoop_incoming_arp_request(bat_priv, new_skb,
1035 hdr_size))
1036 goto rx_success;
1037 if (batadv_dat_snoop_incoming_arp_reply(bat_priv, new_skb,
1038 hdr_size))
1039 goto rx_success;
1040
1041 batadv_interface_rx(recv_if->soft_iface, new_skb, recv_if,
1042 sizeof(struct batadv_unicast_packet), NULL);
1043
1044rx_success:
1045 return NET_RX_SUCCESS;
1046 }
1047
1048 return batadv_route_unicast_packet(skb, recv_if);
1049}
1050
1051/** 967/**
1052 * batadv_recv_unicast_tvlv - receive and process unicast tvlv packets 968 * batadv_recv_unicast_tvlv - receive and process unicast tvlv packets
1053 * @skb: unicast tvlv packet to process 969 * @skb: unicast tvlv packet to process
diff --git a/net/batman-adv/routing.h b/net/batman-adv/routing.h
index ea15fa6302ad..efab583fda02 100644
--- a/net/batman-adv/routing.h
+++ b/net/batman-adv/routing.h
@@ -30,8 +30,6 @@ 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,
34 struct batadv_hard_iface *recv_if);
35int batadv_recv_bcast_packet(struct sk_buff *skb, 33int batadv_recv_bcast_packet(struct sk_buff *skb,
36 struct batadv_hard_iface *recv_if); 34 struct batadv_hard_iface *recv_if);
37int batadv_recv_tt_query(struct sk_buff *skb, 35int batadv_recv_tt_query(struct sk_buff *skb,
diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c
index 81d69fb97c17..b8356ec067bf 100644
--- a/net/batman-adv/send.c
+++ b/net/batman-adv/send.c
@@ -25,6 +25,7 @@
25#include "soft-interface.h" 25#include "soft-interface.h"
26#include "hard-interface.h" 26#include "hard-interface.h"
27#include "gateway_common.h" 27#include "gateway_common.h"
28#include "gateway_client.h"
28#include "originator.h" 29#include "originator.h"
29#include "network-coding.h" 30#include "network-coding.h"
30 31
@@ -127,6 +128,179 @@ int batadv_send_skb_to_orig(struct sk_buff *skb,
127 return ret; 128 return ret;
128} 129}
129 130
131/**
132 * batadv_send_skb_push_fill_unicast - extend the buffer and initialize the
133 * common fields for unicast packets
134 * @skb: the skb carrying the unicast header to initialize
135 * @hdr_size: amount of bytes to push at the beginning of the skb
136 * @orig_node: the destination node
137 *
138 * Returns false if the buffer extension was not possible or true otherwise.
139 */
140static bool
141batadv_send_skb_push_fill_unicast(struct sk_buff *skb, int hdr_size,
142 struct batadv_orig_node *orig_node)
143{
144 struct batadv_unicast_packet *unicast_packet;
145 uint8_t ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn);
146
147 if (batadv_skb_head_push(skb, hdr_size) < 0)
148 return false;
149
150 unicast_packet = (struct batadv_unicast_packet *)skb->data;
151 unicast_packet->header.version = BATADV_COMPAT_VERSION;
152 /* batman packet type: unicast */
153 unicast_packet->header.packet_type = BATADV_UNICAST;
154 /* set unicast ttl */
155 unicast_packet->header.ttl = BATADV_TTL;
156 /* copy the destination for faster routing */
157 memcpy(unicast_packet->dest, orig_node->orig, ETH_ALEN);
158 /* set the destination tt version number */
159 unicast_packet->ttvn = ttvn;
160
161 return true;
162}
163
164/**
165 * batadv_send_skb_prepare_unicast - encapsulate an skb with a unicast header
166 * @skb: the skb containing the payload to encapsulate
167 * @orig_node: the destination node
168 *
169 * Returns false if the payload could not be encapsulated or true otherwise.
170 */
171static bool batadv_send_skb_prepare_unicast(struct sk_buff *skb,
172 struct batadv_orig_node *orig_node)
173{
174 size_t uni_size = sizeof(struct batadv_unicast_packet);
175
176 return batadv_send_skb_push_fill_unicast(skb, uni_size, orig_node);
177}
178
179/**
180 * batadv_send_skb_prepare_unicast_4addr - encapsulate an skb with a
181 * unicast 4addr header
182 * @bat_priv: the bat priv with all the soft interface information
183 * @skb: the skb containing the payload to encapsulate
184 * @orig_node: the destination node
185 * @packet_subtype: the unicast 4addr packet subtype to use
186 *
187 * Returns false if the payload could not be encapsulated or true otherwise.
188 */
189bool batadv_send_skb_prepare_unicast_4addr(struct batadv_priv *bat_priv,
190 struct sk_buff *skb,
191 struct batadv_orig_node *orig,
192 int packet_subtype)
193{
194 struct batadv_hard_iface *primary_if;
195 struct batadv_unicast_4addr_packet *uc_4addr_packet;
196 bool ret = false;
197
198 primary_if = batadv_primary_if_get_selected(bat_priv);
199 if (!primary_if)
200 goto out;
201
202 /* Pull the header space and fill the unicast_packet substructure.
203 * We can do that because the first member of the uc_4addr_packet
204 * is of type struct unicast_packet
205 */
206 if (!batadv_send_skb_push_fill_unicast(skb, sizeof(*uc_4addr_packet),
207 orig))
208 goto out;
209
210 uc_4addr_packet = (struct batadv_unicast_4addr_packet *)skb->data;
211 uc_4addr_packet->u.header.packet_type = BATADV_UNICAST_4ADDR;
212 memcpy(uc_4addr_packet->src, primary_if->net_dev->dev_addr, ETH_ALEN);
213 uc_4addr_packet->subtype = packet_subtype;
214 uc_4addr_packet->reserved = 0;
215
216 ret = true;
217out:
218 if (primary_if)
219 batadv_hardif_free_ref(primary_if);
220 return ret;
221}
222
223/**
224 * batadv_send_generic_unicast_skb - send an skb as unicast
225 * @bat_priv: the bat priv with all the soft interface information
226 * @skb: payload to send
227 * @packet_type: the batman unicast packet type to use
228 * @packet_subtype: the unicast 4addr packet subtype (only relevant for unicast
229 * 4addr packets)
230 *
231 * Returns 1 in case of error or 0 otherwise.
232 */
233int batadv_send_skb_generic_unicast(struct batadv_priv *bat_priv,
234 struct sk_buff *skb, int packet_type,
235 int packet_subtype)
236{
237 struct ethhdr *ethhdr = (struct ethhdr *)skb->data;
238 struct batadv_unicast_packet *unicast_packet;
239 struct batadv_orig_node *orig_node;
240 struct batadv_neigh_node *neigh_node;
241 int ret = NET_RX_DROP;
242
243 /* get routing information */
244 if (is_multicast_ether_addr(ethhdr->h_dest)) {
245 orig_node = batadv_gw_get_selected_orig(bat_priv);
246 if (orig_node)
247 goto find_router;
248 }
249
250 /* check for tt host - increases orig_node refcount.
251 * returns NULL in case of AP isolation
252 */
253 orig_node = batadv_transtable_search(bat_priv, ethhdr->h_source,
254 ethhdr->h_dest);
255
256find_router:
257 /* find_router():
258 * - if orig_node is NULL it returns NULL
259 * - increases neigh_nodes refcount if found.
260 */
261 neigh_node = batadv_find_router(bat_priv, orig_node, NULL);
262
263 if (!neigh_node)
264 goto out;
265
266 switch (packet_type) {
267 case BATADV_UNICAST:
268 batadv_send_skb_prepare_unicast(skb, orig_node);
269 break;
270 case BATADV_UNICAST_4ADDR:
271 batadv_send_skb_prepare_unicast_4addr(bat_priv, skb, orig_node,
272 packet_subtype);
273 break;
274 default:
275 /* this function supports UNICAST and UNICAST_4ADDR only. It
276 * should never be invoked with any other packet type
277 */
278 goto out;
279 }
280
281 unicast_packet = (struct batadv_unicast_packet *)skb->data;
282
283 /* inform the destination node that we are still missing a correct route
284 * for this client. The destination will receive this packet and will
285 * try to reroute it because the ttvn contained in the header is less
286 * than the current one
287 */
288 if (batadv_tt_global_client_is_roaming(bat_priv, ethhdr->h_dest))
289 unicast_packet->ttvn = unicast_packet->ttvn - 1;
290
291 if (batadv_send_skb_to_orig(skb, orig_node, NULL) != NET_XMIT_DROP)
292 ret = 0;
293
294out:
295 if (neigh_node)
296 batadv_neigh_node_free_ref(neigh_node);
297 if (orig_node)
298 batadv_orig_node_free_ref(orig_node);
299 if (ret == NET_RX_DROP)
300 kfree_skb(skb);
301 return ret;
302}
303
130void batadv_schedule_bat_ogm(struct batadv_hard_iface *hard_iface) 304void batadv_schedule_bat_ogm(struct batadv_hard_iface *hard_iface)
131{ 305{
132 struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface); 306 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..ad63184a4dd9 100644
--- a/net/batman-adv/send.h
+++ b/net/batman-adv/send.h
@@ -34,5 +34,45 @@ 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_generic_unicast(struct batadv_priv *bat_priv,
42 struct sk_buff *skb, int packet_type,
43 int packet_subtype);
44
45
46/**
47 * batadv_send_unicast_skb - send the skb encapsulated in a unicast packet
48 * @bat_priv: the bat priv with all the soft interface information
49 * @skb: the payload to send
50 *
51 * Returns 1 in case of error or 0 otherwise.
52 */
53static inline int batadv_send_skb_unicast(struct batadv_priv *bat_priv,
54 struct sk_buff *skb)
55{
56 return batadv_send_skb_generic_unicast(bat_priv, skb, BATADV_UNICAST,
57 0);
58}
59
60/**
61 * batadv_send_4addr_unicast_skb - send the skb encapsulated in a unicast 4addr
62 * packet
63 * @bat_priv: the bat priv with all the soft interface information
64 * @skb: the payload to send
65 * @packet_subtype: the unicast 4addr packet subtype to use
66 *
67 * Returns 1 in case of error or 0 otherwise.
68 */
69static inline int batadv_send_skb_unicast_4addr(struct batadv_priv *bat_priv,
70 struct sk_buff *skb,
71 int packet_subtype)
72{
73 return batadv_send_skb_generic_unicast(bat_priv, skb,
74 BATADV_UNICAST_4ADDR,
75 packet_subtype);
76}
37 77
38#endif /* _NET_BATMAN_ADV_SEND_H_ */ 78#endif /* _NET_BATMAN_ADV_SEND_H_ */
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
index 25e6004e8e01..504d0bbddc48 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
@@ -286,7 +284,7 @@ static int batadv_interface_tx(struct sk_buff *skb,
286 284
287 batadv_dat_snoop_outgoing_arp_reply(bat_priv, skb); 285 batadv_dat_snoop_outgoing_arp_reply(bat_priv, skb);
288 286
289 ret = batadv_unicast_send_skb(bat_priv, skb); 287 ret = batadv_send_skb_unicast(bat_priv, skb);
290 if (ret != 0) 288 if (ret != 0)
291 goto dropped_freed; 289 goto dropped_freed;
292 } 290 }
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index 8fbd89d167cd..795a0794ebfb 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -60,7 +60,6 @@ struct batadv_hard_iface_bat_iv {
60 * @if_num: identificator of the interface 60 * @if_num: identificator of the interface
61 * @if_status: status of the interface for batman-adv 61 * @if_status: status of the interface for batman-adv
62 * @net_dev: pointer to the net_device 62 * @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) 63 * @num_bcasts: number of payload re-broadcasts on this interface (ARQ)
65 * @hardif_obj: kobject of the per interface sysfs "mesh" directory 64 * @hardif_obj: kobject of the per interface sysfs "mesh" directory
66 * @refcount: number of contexts the object is used 65 * @refcount: number of contexts the object is used
@@ -76,7 +75,6 @@ struct batadv_hard_iface {
76 int16_t if_num; 75 int16_t if_num;
77 char if_status; 76 char if_status;
78 struct net_device *net_dev; 77 struct net_device *net_dev;
79 atomic_t frag_seqno;
80 uint8_t num_bcasts; 78 uint8_t num_bcasts;
81 struct kobject *hardif_obj; 79 struct kobject *hardif_obj;
82 atomic_t refcount; 80 atomic_t refcount;
@@ -116,9 +114,6 @@ struct batadv_hard_iface {
116 * last_bcast_seqno) 114 * last_bcast_seqno)
117 * @last_bcast_seqno: last broadcast sequence number received by this host 115 * @last_bcast_seqno: last broadcast sequence number received by this host
118 * @neigh_list: list of potential next hop neighbor towards this orig node 116 * @neigh_list: list of potential next hop neighbor towards this orig node
119 * @frag_list: fragmentation buffer list for fragment re-assembly
120 * @last_frag_packet: time when last fragmented packet from this node was
121 * received
122 * @neigh_list_lock: lock protecting neigh_list, router and bonding_list 117 * @neigh_list_lock: lock protecting neigh_list, router and bonding_list
123 * @hash_entry: hlist node for batadv_priv::orig_hash 118 * @hash_entry: hlist node for batadv_priv::orig_hash
124 * @bat_priv: pointer to soft_iface this orig node belongs to 119 * @bat_priv: pointer to soft_iface this orig node belongs to
@@ -159,8 +154,6 @@ struct batadv_orig_node {
159 DECLARE_BITMAP(bcast_bits, BATADV_TQ_LOCAL_WINDOW_SIZE); 154 DECLARE_BITMAP(bcast_bits, BATADV_TQ_LOCAL_WINDOW_SIZE);
160 uint32_t last_bcast_seqno; 155 uint32_t last_bcast_seqno;
161 struct hlist_head neigh_list; 156 struct hlist_head neigh_list;
162 struct list_head frag_list;
163 unsigned long last_frag_packet;
164 /* neigh_list_lock protects: neigh_list, router & bonding_list */ 157 /* neigh_list_lock protects: neigh_list, router & bonding_list */
165 spinlock_t neigh_list_lock; 158 spinlock_t neigh_list_lock;
166 struct hlist_node hash_entry; 159 struct hlist_node hash_entry;
@@ -874,18 +867,6 @@ struct batadv_forw_packet {
874}; 867};
875 868
876/** 869/**
877 * struct batadv_frag_packet_list_entry - storage for fragment packet
878 * @list: list node for orig_node::frag_list
879 * @seqno: sequence number of the fragment
880 * @skb: fragment's skb buffer
881 */
882struct batadv_frag_packet_list_entry {
883 struct list_head list;
884 uint16_t seqno;
885 struct sk_buff *skb;
886};
887
888/**
889 * struct batadv_algo_ops - mesh algorithm callbacks 870 * struct batadv_algo_ops - mesh algorithm callbacks
890 * @list: list node for the batadv_algo_list 871 * @list: list node for the batadv_algo_list
891 * @name: name of the algorithm 872 * @name: name of the algorithm
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_ */