summaryrefslogtreecommitdiffstats
path: root/net/batman-adv/send.c
diff options
context:
space:
mode:
authorMartin Hundebøll <martin@hundeboll.net>2013-05-23 16:53:03 +0200
committerAntonio Quartulli <antonio@meshcoding.com>2013-10-12 11:58:35 +0200
commitee75ed88879af88558818a5c6609d85f60ff0df4 (patch)
treeeb5edeaf224c481e962f8108bca429c6b1cc31d9 /net/batman-adv/send.c
parentbatman-adv: Receive fragmented packets and merge (diff)
downloadlinux-ee75ed88879af88558818a5c6609d85f60ff0df4.tar.xz
linux-ee75ed88879af88558818a5c6609d85f60ff0df4.zip
batman-adv: Fragment and send skbs larger than mtu
Non-broadcast packets larger than MTU are fragmented and sent with an encapsulating header. Up to 16 fragments are supported, which are sent in reverse order on the wire to allow minimal memory copying when creating fragments. 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>
Diffstat (limited to 'net/batman-adv/send.c')
-rw-r--r--net/batman-adv/send.c21
1 files changed, 17 insertions, 4 deletions
diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c
index b8356ec067bf..1a1aa59d78ee 100644
--- a/net/batman-adv/send.c
+++ b/net/batman-adv/send.c
@@ -28,8 +28,7 @@
#include "gateway_client.h"
#include "originator.h"
#include "network-coding.h"
-
-#include <linux/if_ether.h>
+#include "fragmentation.h"
static void batadv_send_outstanding_bcast_packet(struct work_struct *work);
@@ -109,7 +108,19 @@ int batadv_send_skb_to_orig(struct sk_buff *skb,
/* batadv_find_router() increases neigh_nodes refcount if found. */
neigh_node = batadv_find_router(bat_priv, orig_node, recv_if);
if (!neigh_node)
- return ret;
+ goto out;
+
+ /* Check if the skb is too large to send in one piece and fragment
+ * it if needed.
+ */
+ if (atomic_read(&bat_priv->fragmentation) &&
+ skb->len > neigh_node->if_incoming->net_dev->mtu) {
+ /* Fragment and send packet. */
+ if (batadv_frag_send_packet(skb, orig_node, neigh_node))
+ ret = NET_XMIT_SUCCESS;
+
+ goto out;
+ }
/* try to network code the packet, if it is received on an interface
* (i.e. being forwarded). If the packet originates from this node or if
@@ -123,7 +134,9 @@ int batadv_send_skb_to_orig(struct sk_buff *skb,
ret = NET_XMIT_SUCCESS;
}
- batadv_neigh_node_free_ref(neigh_node);
+out:
+ if (neigh_node)
+ batadv_neigh_node_free_ref(neigh_node);
return ret;
}