unicast.c revision 46d160ef887963f26fee2df3d3b99eab54637014
1/* Copyright (C) 2010-2012 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 int 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 skb_reserve(frag_skb, ucf_hdr_len); 246 247 unicast_packet = (struct batadv_unicast_packet *)skb->data; 248 memcpy(&tmp_uc, unicast_packet, uc_hdr_len); 249 skb_split(skb, frag_skb, data_len / 2 + uc_hdr_len); 250 251 if (batadv_skb_head_push(skb, ucf_hdr_len - uc_hdr_len) < 0 || 252 batadv_skb_head_push(frag_skb, ucf_hdr_len) < 0) 253 goto drop_frag; 254 255 frag1 = (struct batadv_unicast_frag_packet *)skb->data; 256 frag2 = (struct batadv_unicast_frag_packet *)frag_skb->data; 257 258 memcpy(frag1, &tmp_uc, sizeof(tmp_uc)); 259 260 frag1->header.ttl--; 261 frag1->header.version = BATADV_COMPAT_VERSION; 262 frag1->header.packet_type = BATADV_UNICAST_FRAG; 263 264 memcpy(frag1->orig, primary_if->net_dev->dev_addr, ETH_ALEN); 265 memcpy(frag2, frag1, sizeof(*frag2)); 266 267 if (data_len & 1) 268 large_tail = BATADV_UNI_FRAG_LARGETAIL; 269 270 frag1->flags = BATADV_UNI_FRAG_HEAD | large_tail; 271 frag2->flags = large_tail; 272 273 seqno = atomic_add_return(2, &hard_iface->frag_seqno); 274 frag1->seqno = htons(seqno - 1); 275 frag2->seqno = htons(seqno); 276 277 batadv_send_skb_packet(skb, hard_iface, dstaddr); 278 batadv_send_skb_packet(frag_skb, hard_iface, dstaddr); 279 ret = NET_RX_SUCCESS; 280 goto out; 281 282drop_frag: 283 kfree_skb(frag_skb); 284dropped: 285 kfree_skb(skb); 286out: 287 if (primary_if) 288 batadv_hardif_free_ref(primary_if); 289 return ret; 290} 291 292/** 293 * batadv_unicast_push_and_fill_skb - extends the buffer and initializes the 294 * common fields for unicast packets 295 * @skb: packet 296 * @hdr_size: amount of bytes to push at the beginning of the skb 297 * @orig_node: the destination node 298 * 299 * Returns false if the buffer extension was not possible or true otherwise 300 */ 301static bool batadv_unicast_push_and_fill_skb(struct sk_buff *skb, int hdr_size, 302 struct batadv_orig_node *orig_node) 303{ 304 struct batadv_unicast_packet *unicast_packet; 305 uint8_t ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn); 306 307 if (batadv_skb_head_push(skb, hdr_size) < 0) 308 return false; 309 310 unicast_packet = (struct batadv_unicast_packet *)skb->data; 311 unicast_packet->header.version = BATADV_COMPAT_VERSION; 312 /* batman packet type: unicast */ 313 unicast_packet->header.packet_type = BATADV_UNICAST; 314 /* set unicast ttl */ 315 unicast_packet->header.ttl = BATADV_TTL; 316 /* copy the destination for faster routing */ 317 memcpy(unicast_packet->dest, orig_node->orig, ETH_ALEN); 318 /* set the destination tt version number */ 319 unicast_packet->ttvn = ttvn; 320 321 return true; 322} 323 324/** 325 * batadv_unicast_prepare_skb - encapsulate an skb with a unicast header 326 * @skb: the skb containing the payload to encapsulate 327 * @orig_node: the destination node 328 * 329 * Returns false if the payload could not be encapsulated or true otherwise 330 */ 331static bool batadv_unicast_prepare_skb(struct sk_buff *skb, 332 struct batadv_orig_node *orig_node) 333{ 334 size_t uni_size = sizeof(struct batadv_unicast_packet); 335 return batadv_unicast_push_and_fill_skb(skb, uni_size, orig_node); 336} 337 338/** 339 * batadv_unicast_4addr_prepare_skb - encapsulate an skb with a unicast4addr 340 * header 341 * @bat_priv: the bat priv with all the soft interface information 342 * @skb: the skb containing the payload to encapsulate 343 * @orig_node: the destination node 344 * @packet_subtype: the batman 4addr packet subtype to use 345 * 346 * Returns false if the payload could not be encapsulated or true otherwise 347 */ 348bool batadv_unicast_4addr_prepare_skb(struct batadv_priv *bat_priv, 349 struct sk_buff *skb, 350 struct batadv_orig_node *orig, 351 int packet_subtype) 352{ 353 struct batadv_hard_iface *primary_if; 354 struct batadv_unicast_4addr_packet *unicast_4addr_packet; 355 bool ret = false; 356 357 primary_if = batadv_primary_if_get_selected(bat_priv); 358 if (!primary_if) 359 goto out; 360 361 /* pull the header space and fill the unicast_packet substructure. 362 * We can do that because the first member of the unicast_4addr_packet 363 * is of type struct unicast_packet 364 */ 365 if (!batadv_unicast_push_and_fill_skb(skb, 366 sizeof(*unicast_4addr_packet), 367 orig)) 368 goto out; 369 370 unicast_4addr_packet = (struct batadv_unicast_4addr_packet *)skb->data; 371 unicast_4addr_packet->u.header.packet_type = BATADV_UNICAST_4ADDR; 372 memcpy(unicast_4addr_packet->src, primary_if->net_dev->dev_addr, 373 ETH_ALEN); 374 unicast_4addr_packet->subtype = packet_subtype; 375 unicast_4addr_packet->reserved = 0; 376 377 ret = true; 378out: 379 if (primary_if) 380 batadv_hardif_free_ref(primary_if); 381 return ret; 382} 383 384/** 385 * batadv_unicast_generic_send_skb - send an skb as unicast 386 * @bat_priv: the bat priv with all the soft interface information 387 * @skb: payload to send 388 * @packet_type: the batman unicast packet type to use 389 * @packet_subtype: the batman packet subtype. It is ignored if packet_type is 390 * not BATADV_UNICAT_4ADDR 391 * 392 * Returns 1 in case of error or 0 otherwise 393 */ 394int batadv_unicast_generic_send_skb(struct batadv_priv *bat_priv, 395 struct sk_buff *skb, int packet_type, 396 int packet_subtype) 397{ 398 struct ethhdr *ethhdr = (struct ethhdr *)skb->data; 399 struct batadv_unicast_packet *unicast_packet; 400 struct batadv_orig_node *orig_node; 401 struct batadv_neigh_node *neigh_node; 402 int data_len = skb->len; 403 int ret = NET_RX_DROP; 404 unsigned int dev_mtu; 405 406 /* get routing information */ 407 if (is_multicast_ether_addr(ethhdr->h_dest)) { 408 orig_node = batadv_gw_get_selected_orig(bat_priv); 409 if (orig_node) 410 goto find_router; 411 } 412 413 /* check for tt host - increases orig_node refcount. 414 * returns NULL in case of AP isolation 415 */ 416 orig_node = batadv_transtable_search(bat_priv, ethhdr->h_source, 417 ethhdr->h_dest); 418 419find_router: 420 /* find_router(): 421 * - if orig_node is NULL it returns NULL 422 * - increases neigh_nodes refcount if found. 423 */ 424 neigh_node = batadv_find_router(bat_priv, orig_node, NULL); 425 426 if (!neigh_node) 427 goto out; 428 429 switch (packet_type) { 430 case BATADV_UNICAST: 431 batadv_unicast_prepare_skb(skb, orig_node); 432 break; 433 case BATADV_UNICAST_4ADDR: 434 batadv_unicast_4addr_prepare_skb(bat_priv, skb, orig_node, 435 packet_subtype); 436 break; 437 default: 438 /* this function supports UNICAST and UNICAST_4ADDR only. It 439 * should never be invoked with any other packet type 440 */ 441 goto out; 442 } 443 444 unicast_packet = (struct batadv_unicast_packet *)skb->data; 445 446 /* inform the destination node that we are still missing a correct route 447 * for this client. The destination will receive this packet and will 448 * try to reroute it because the ttvn contained in the header is less 449 * than the current one 450 */ 451 if (batadv_tt_global_client_is_roaming(bat_priv, ethhdr->h_dest)) 452 unicast_packet->ttvn = unicast_packet->ttvn - 1; 453 454 dev_mtu = neigh_node->if_incoming->net_dev->mtu; 455 /* fragmentation mechanism only works for UNICAST (now) */ 456 if (packet_type == BATADV_UNICAST && 457 atomic_read(&bat_priv->fragmentation) && 458 data_len + sizeof(*unicast_packet) > dev_mtu) { 459 /* send frag skb decreases ttl */ 460 unicast_packet->header.ttl++; 461 ret = batadv_frag_send_skb(skb, bat_priv, 462 neigh_node->if_incoming, 463 neigh_node->addr); 464 goto out; 465 } 466 467 if (batadv_send_skb_to_orig(skb, orig_node, NULL)) 468 ret = 0; 469 470out: 471 if (neigh_node) 472 batadv_neigh_node_free_ref(neigh_node); 473 if (orig_node) 474 batadv_orig_node_free_ref(orig_node); 475 if (ret == NET_RX_DROP) 476 kfree_skb(skb); 477 return ret; 478} 479