1 /* Copyright (C) 2010-2012 B.A.T.M.A.N. contributors:
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.
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.
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
23 #include "soft-interface.h"
24 #include "gateway_client.h"
25 #include "originator.h"
27 #include "translation-table.h"
29 #include "hard-interface.h"
32 static struct sk_buff
*
33 batadv_frag_merge_packet(struct list_head
*head
,
34 struct batadv_frag_packet_list_entry
*tfp
,
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
;
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
) {
53 if (skb_linearize(skb
) < 0 || skb_linearize(tmp_skb
) < 0)
56 skb_pull(tmp_skb
, sizeof(*up
));
57 if (pskb_expand_head(skb
, 0, tmp_skb
->len
, GFP_ATOMIC
) < 0)
60 /* move free entry to end */
63 list_move_tail(&tfp
->list
, head
);
65 memcpy(skb_put(skb
, tmp_skb
->len
), tmp_skb
->data
, tmp_skb
->len
);
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
;
76 /* free buffered skb, skb will be freed later */
81 static void batadv_frag_create_entry(struct list_head
*head
,
84 struct batadv_frag_packet_list_entry
*tfp
;
85 struct batadv_unicast_frag_packet
*up
;
87 up
= (struct batadv_unicast_frag_packet
*)skb
->data
;
89 /* free and oldest packets stand at the end */
90 tfp
= list_entry((head
)->prev
, typeof(*tfp
), list
);
93 tfp
->seqno
= ntohs(up
->seqno
);
95 list_move(&tfp
->list
, head
);
99 static int batadv_frag_create_buffer(struct list_head
*head
)
102 struct batadv_frag_packet_list_entry
*tfp
;
104 for (i
= 0; i
< BATADV_FRAG_BUFFER_SIZE
; i
++) {
105 tfp
= kmalloc(sizeof(*tfp
), GFP_ATOMIC
);
107 batadv_frag_list_free(head
);
112 INIT_LIST_HEAD(&tfp
->list
);
113 list_add(&tfp
->list
, head
);
119 static struct batadv_frag_packet_list_entry
*
120 batadv_frag_search_packet(struct list_head
*head
,
121 const struct batadv_unicast_frag_packet
*up
)
123 struct batadv_frag_packet_list_entry
*tfp
;
124 struct batadv_unicast_frag_packet
*tmp_up
= NULL
;
125 int is_head_tmp
, is_head
;
126 uint16_t search_seqno
;
128 if (up
->flags
& BATADV_UNI_FRAG_HEAD
)
129 search_seqno
= ntohs(up
->seqno
)+1;
131 search_seqno
= ntohs(up
->seqno
)-1;
133 is_head
= !!(up
->flags
& BATADV_UNI_FRAG_HEAD
);
135 list_for_each_entry(tfp
, head
, list
) {
140 if (tfp
->seqno
== ntohs(up
->seqno
))
143 tmp_up
= (struct batadv_unicast_frag_packet
*)tfp
->skb
->data
;
145 if (tfp
->seqno
== search_seqno
) {
146 is_head_tmp
= !!(tmp_up
->flags
& BATADV_UNI_FRAG_HEAD
);
147 if (is_head_tmp
!= is_head
)
156 list_move_tail(&tfp
->list
, head
);
160 void batadv_frag_list_free(struct list_head
*head
)
162 struct batadv_frag_packet_list_entry
*pf
, *tmp_pf
;
164 if (!list_empty(head
)) {
166 list_for_each_entry_safe(pf
, tmp_pf
, head
, list
) {
175 /* frag_reassemble_skb():
176 * returns NET_RX_DROP if the operation failed - skb is left intact
177 * returns NET_RX_SUCCESS if the fragment was buffered (skb_new will be NULL)
178 * or the skb could be reassembled (skb_new will point to the new packet and
181 int batadv_frag_reassemble_skb(struct sk_buff
*skb
,
182 struct batadv_priv
*bat_priv
,
183 struct sk_buff
**new_skb
)
185 struct batadv_orig_node
*orig_node
;
186 struct batadv_frag_packet_list_entry
*tmp_frag_entry
;
187 int ret
= NET_RX_DROP
;
188 struct batadv_unicast_frag_packet
*unicast_packet
;
190 unicast_packet
= (struct batadv_unicast_frag_packet
*)skb
->data
;
193 orig_node
= batadv_orig_hash_find(bat_priv
, unicast_packet
->orig
);
197 orig_node
->last_frag_packet
= jiffies
;
199 if (list_empty(&orig_node
->frag_list
) &&
200 batadv_frag_create_buffer(&orig_node
->frag_list
)) {
201 pr_debug("couldn't create frag buffer\n");
205 tmp_frag_entry
= batadv_frag_search_packet(&orig_node
->frag_list
,
208 if (!tmp_frag_entry
) {
209 batadv_frag_create_entry(&orig_node
->frag_list
, skb
);
210 ret
= NET_RX_SUCCESS
;
214 *new_skb
= batadv_frag_merge_packet(&orig_node
->frag_list
,
215 tmp_frag_entry
, skb
);
216 /* if not, merge failed */
218 ret
= NET_RX_SUCCESS
;
222 batadv_orig_node_free_ref(orig_node
);
226 int batadv_frag_send_skb(struct sk_buff
*skb
, struct batadv_priv
*bat_priv
,
227 struct batadv_hard_iface
*hard_iface
,
228 const uint8_t dstaddr
[])
230 struct batadv_unicast_packet tmp_uc
, *unicast_packet
;
231 struct batadv_hard_iface
*primary_if
;
232 struct sk_buff
*frag_skb
;
233 struct batadv_unicast_frag_packet
*frag1
, *frag2
;
234 int uc_hdr_len
= sizeof(*unicast_packet
);
235 int ucf_hdr_len
= sizeof(*frag1
);
236 int data_len
= skb
->len
- uc_hdr_len
;
237 int large_tail
= 0, ret
= NET_RX_DROP
;
240 primary_if
= batadv_primary_if_get_selected(bat_priv
);
244 frag_skb
= dev_alloc_skb(data_len
- (data_len
/ 2) + ucf_hdr_len
);
247 skb_reserve(frag_skb
, ucf_hdr_len
);
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
);
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)
257 frag1
= (struct batadv_unicast_frag_packet
*)skb
->data
;
258 frag2
= (struct batadv_unicast_frag_packet
*)frag_skb
->data
;
260 memcpy(frag1
, &tmp_uc
, sizeof(tmp_uc
));
263 frag1
->header
.version
= BATADV_COMPAT_VERSION
;
264 frag1
->header
.packet_type
= BATADV_UNICAST_FRAG
;
266 memcpy(frag1
->orig
, primary_if
->net_dev
->dev_addr
, ETH_ALEN
);
267 memcpy(frag2
, frag1
, sizeof(*frag2
));
270 large_tail
= BATADV_UNI_FRAG_LARGETAIL
;
272 frag1
->flags
= BATADV_UNI_FRAG_HEAD
| large_tail
;
273 frag2
->flags
= large_tail
;
275 seqno
= atomic_add_return(2, &hard_iface
->frag_seqno
);
276 frag1
->seqno
= htons(seqno
- 1);
277 frag2
->seqno
= htons(seqno
);
279 batadv_send_skb_packet(skb
, hard_iface
, dstaddr
);
280 batadv_send_skb_packet(frag_skb
, hard_iface
, dstaddr
);
281 ret
= NET_RX_SUCCESS
;
290 batadv_hardif_free_ref(primary_if
);
294 int batadv_unicast_send_skb(struct sk_buff
*skb
, struct batadv_priv
*bat_priv
)
296 struct ethhdr
*ethhdr
= (struct ethhdr
*)skb
->data
;
297 struct batadv_unicast_packet
*unicast_packet
;
298 struct batadv_orig_node
*orig_node
;
299 struct batadv_neigh_node
*neigh_node
;
300 int data_len
= skb
->len
;
302 unsigned int dev_mtu
;
304 /* get routing information */
305 if (is_multicast_ether_addr(ethhdr
->h_dest
)) {
306 orig_node
= batadv_gw_get_selected_orig(bat_priv
);
311 /* check for tt host - increases orig_node refcount.
312 * returns NULL in case of AP isolation
314 orig_node
= batadv_transtable_search(bat_priv
, ethhdr
->h_source
,
319 * - if orig_node is NULL it returns NULL
320 * - increases neigh_nodes refcount if found.
322 neigh_node
= batadv_find_router(bat_priv
, orig_node
, NULL
);
327 if (batadv_skb_head_push(skb
, sizeof(*unicast_packet
)) < 0)
330 unicast_packet
= (struct batadv_unicast_packet
*)skb
->data
;
332 unicast_packet
->header
.version
= BATADV_COMPAT_VERSION
;
333 /* batman packet type: unicast */
334 unicast_packet
->header
.packet_type
= BATADV_UNICAST
;
335 /* set unicast ttl */
336 unicast_packet
->header
.ttl
= BATADV_TTL
;
337 /* copy the destination for faster routing */
338 memcpy(unicast_packet
->dest
, orig_node
->orig
, ETH_ALEN
);
339 /* set the destination tt version number */
340 unicast_packet
->ttvn
= (uint8_t)atomic_read(&orig_node
->last_ttvn
);
342 /* inform the destination node that we are still missing a correct route
343 * for this client. The destination will receive this packet and will
344 * try to reroute it because the ttvn contained in the header is less
345 * than the current one
347 if (batadv_tt_global_client_is_roaming(bat_priv
, ethhdr
->h_dest
))
348 unicast_packet
->ttvn
= unicast_packet
->ttvn
- 1;
350 dev_mtu
= neigh_node
->if_incoming
->net_dev
->mtu
;
351 if (atomic_read(&bat_priv
->fragmentation
) &&
352 data_len
+ sizeof(*unicast_packet
) > dev_mtu
) {
353 /* send frag skb decreases ttl */
354 unicast_packet
->header
.ttl
++;
355 ret
= batadv_frag_send_skb(skb
, bat_priv
,
356 neigh_node
->if_incoming
,
361 batadv_send_skb_packet(skb
, neigh_node
->if_incoming
, neigh_node
->addr
);
367 batadv_neigh_node_free_ref(neigh_node
);
369 batadv_orig_node_free_ref(orig_node
);