aboutsummaryrefslogtreecommitdiffstats
path: root/net/batman-adv/unicast.c
diff options
context:
space:
mode:
authorAntonio Quartulli <ordex@autistici.org>2012-10-01 03:57:35 -0400
committerAntonio Quartulli <ordex@autistici.org>2012-11-07 14:00:18 -0500
commit7cdcf6dddc428c90ac867267a8d301e9e8b25612 (patch)
tree7cdbf95a57239352f9203b96dc915649bc0be253 /net/batman-adv/unicast.c
parentf6c57a460913f3c83b0e8eb51f4021fcf1c83cdc (diff)
batman-adv: add UNICAST_4ADDR packet type
The current unicast packet type does not contain the orig source address. This patches add a new unicast packet (called UNICAST_4ADDR) which provides two new fields: the originator source address and the subtype (the type of the data contained in the packet payload). The former is useful to identify the node which injected the packet into the network and the latter is useful to avoid creating new unicast packet types in the future: a macro defining a new subtype will be enough. Signed-off-by: Antonio Quartulli <ordex@autistici.org>
Diffstat (limited to 'net/batman-adv/unicast.c')
-rw-r--r--net/batman-adv/unicast.c135
1 files changed, 121 insertions, 14 deletions
diff --git a/net/batman-adv/unicast.c b/net/batman-adv/unicast.c
index f39723281ca1..c0d318b587ee 100644
--- a/net/batman-adv/unicast.c
+++ b/net/batman-adv/unicast.c
@@ -291,7 +291,111 @@ out:
291 return ret; 291 return ret;
292} 292}
293 293
294int batadv_unicast_send_skb(struct sk_buff *skb, struct batadv_priv *bat_priv) 294/**
295 * batadv_unicast_push_and_fill_skb - extends the buffer and initializes the
296 * common fields for unicast packets
297 * @skb: packet
298 * @hdr_size: amount of bytes to push at the beginning of the skb
299 * @orig_node: the destination node
300 *
301 * Returns false if the buffer extension was not possible or true otherwise
302 */
303static bool batadv_unicast_push_and_fill_skb(struct sk_buff *skb, int hdr_size,
304 struct batadv_orig_node *orig_node)
305{
306 struct batadv_unicast_packet *unicast_packet;
307 uint8_t ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn);
308
309 if (batadv_skb_head_push(skb, hdr_size) < 0)
310 return false;
311
312 unicast_packet = (struct batadv_unicast_packet *)skb->data;
313 unicast_packet->header.version = BATADV_COMPAT_VERSION;
314 /* batman packet type: unicast */
315 unicast_packet->header.packet_type = BATADV_UNICAST;
316 /* set unicast ttl */
317 unicast_packet->header.ttl = BATADV_TTL;
318 /* copy the destination for faster routing */
319 memcpy(unicast_packet->dest, orig_node->orig, ETH_ALEN);
320 /* set the destination tt version number */
321 unicast_packet->ttvn = ttvn;
322
323 return true;
324}
325
326/**
327 * batadv_unicast_prepare_skb - encapsulate an skb with a unicast header
328 * @skb: the skb containing the payload to encapsulate
329 * @orig_node: the destination node
330 *
331 * Returns false if the payload could not be encapsulated or true otherwise
332 */
333static bool batadv_unicast_prepare_skb(struct sk_buff *skb,
334 struct batadv_orig_node *orig_node)
335{
336 size_t uni_size = sizeof(struct batadv_unicast_packet);
337 return batadv_unicast_push_and_fill_skb(skb, uni_size, orig_node);
338}
339
340/**
341 * batadv_unicast_4addr_prepare_skb - encapsulate an skb with a unicast4addr
342 * header
343 * @bat_priv: the bat priv with all the soft interface information
344 * @skb: the skb containing the payload to encapsulate
345 * @orig_node: the destination node
346 * @packet_subtype: the batman 4addr packet subtype to use
347 *
348 * Returns false if the payload could not be encapsulated or true otherwise
349 */
350static bool batadv_unicast_4addr_prepare_skb(struct batadv_priv *bat_priv,
351 struct sk_buff *skb,
352 struct batadv_orig_node *orig,
353 int packet_subtype)
354{
355 struct batadv_hard_iface *primary_if;
356 struct batadv_unicast_4addr_packet *unicast_4addr_packet;
357 bool ret = false;
358
359 primary_if = batadv_primary_if_get_selected(bat_priv);
360 if (!primary_if)
361 goto out;
362
363 /* pull the header space and fill the unicast_packet substructure.
364 * We can do that because the first member of the unicast_4addr_packet
365 * is of type struct unicast_packet
366 */
367 if (!batadv_unicast_push_and_fill_skb(skb,
368 sizeof(*unicast_4addr_packet),
369 orig))
370 goto out;
371
372 unicast_4addr_packet = (struct batadv_unicast_4addr_packet *)skb->data;
373 unicast_4addr_packet->u.header.packet_type = BATADV_UNICAST_4ADDR;
374 memcpy(unicast_4addr_packet->src, primary_if->net_dev->dev_addr,
375 ETH_ALEN);
376 unicast_4addr_packet->subtype = packet_subtype;
377 unicast_4addr_packet->reserved = 0;
378
379 ret = true;
380out:
381 if (primary_if)
382 batadv_hardif_free_ref(primary_if);
383 return ret;
384}
385
386/**
387 * batadv_unicast_generic_send_skb - send an skb as unicast
388 * @bat_priv: the bat priv with all the soft interface information
389 * @skb: payload to send
390 * @packet_type: the batman unicast packet type to use
391 * @packet_subtype: the batman packet subtype. It is ignored if packet_type is
392 * not BATADV_UNICAT_4ADDR
393 *
394 * Returns 1 in case of error or 0 otherwise
395 */
396int batadv_unicast_generic_send_skb(struct batadv_priv *bat_priv,
397 struct sk_buff *skb, int packet_type,
398 int packet_subtype)
295{ 399{
296 struct ethhdr *ethhdr = (struct ethhdr *)skb->data; 400 struct ethhdr *ethhdr = (struct ethhdr *)skb->data;
297 struct batadv_unicast_packet *unicast_packet; 401 struct batadv_unicast_packet *unicast_packet;
@@ -324,21 +428,23 @@ find_router:
324 if (!neigh_node) 428 if (!neigh_node)
325 goto out; 429 goto out;
326 430
327 if (batadv_skb_head_push(skb, sizeof(*unicast_packet)) < 0) 431 switch (packet_type) {
432 case BATADV_UNICAST:
433 batadv_unicast_prepare_skb(skb, orig_node);
434 break;
435 case BATADV_UNICAST_4ADDR:
436 batadv_unicast_4addr_prepare_skb(bat_priv, skb, orig_node,
437 packet_subtype);
438 break;
439 default:
440 /* this function supports UNICAST and UNICAST_4ADDR only. It
441 * should never be invoked with any other packet type
442 */
328 goto out; 443 goto out;
444 }
329 445
330 unicast_packet = (struct batadv_unicast_packet *)skb->data; 446 unicast_packet = (struct batadv_unicast_packet *)skb->data;
331 447
332 unicast_packet->header.version = BATADV_COMPAT_VERSION;
333 /* batman packet type: unicast */
334 unicast_packet->header.packet_type = BATADV_UNICAST;
335 /* set unicast ttl */
336 unicast_packet->header.ttl = BATADV_TTL;
337 /* copy the destination for faster routing */
338 memcpy(unicast_packet->dest, orig_node->orig, ETH_ALEN);
339 /* set the destination tt version number */
340 unicast_packet->ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn);
341
342 /* inform the destination node that we are still missing a correct route 448 /* inform the destination node that we are still missing a correct route
343 * for this client. The destination will receive this packet and will 449 * for this client. The destination will receive this packet and will
344 * try to reroute it because the ttvn contained in the header is less 450 * try to reroute it because the ttvn contained in the header is less
@@ -348,7 +454,9 @@ find_router:
348 unicast_packet->ttvn = unicast_packet->ttvn - 1; 454 unicast_packet->ttvn = unicast_packet->ttvn - 1;
349 455
350 dev_mtu = neigh_node->if_incoming->net_dev->mtu; 456 dev_mtu = neigh_node->if_incoming->net_dev->mtu;
351 if (atomic_read(&bat_priv->fragmentation) && 457 /* fragmentation mechanism only works for UNICAST (now) */
458 if (packet_type == BATADV_UNICAST &&
459 atomic_read(&bat_priv->fragmentation) &&
352 data_len + sizeof(*unicast_packet) > dev_mtu) { 460 data_len + sizeof(*unicast_packet) > dev_mtu) {
353 /* send frag skb decreases ttl */ 461 /* send frag skb decreases ttl */
354 unicast_packet->header.ttl++; 462 unicast_packet->header.ttl++;
@@ -360,7 +468,6 @@ find_router:
360 468
361 batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); 469 batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
362 ret = 0; 470 ret = 0;
363 goto out;
364 471
365out: 472out:
366 if (neigh_node) 473 if (neigh_node)