aboutsummaryrefslogtreecommitdiffstats
path: root/net/batman-adv
diff options
context:
space:
mode:
authorSven Eckelmann <sven@narfation.org>2011-01-25 16:59:26 -0500
committerSven Eckelmann <sven@narfation.org>2011-01-31 08:57:08 -0500
commit5c77d8bb8aeb4ec6804b6c32061109ba2ea6988d (patch)
tree7ffb0ce70d1185502eb9ed41351eff8083baa0fc /net/batman-adv
parent1bae4ce27c9c90344f23c65ea6966c50ffeae2f5 (diff)
batman-adv: Create roughly equal sized fragments
The routing algorithm must know how large two fragments are to be able to decide that it is safe to merge them or if it should resubmit without waiting for the second part. When these two fragments have a too different size, it is not possible to guess right in every situation. The user could easily configure the MTU of the attached cards so that one fragment is forwarded and the other one is added to the fragments table to wait for the missing part. For even sized packets, it is possible to split it so that the resulting packages are equal sized by ignoring the old non-fragment header at the beginning of the original packet. This still creates different sized fragments for uneven sized packets. Reported-by: Russell Senior <russell@personaltelco.net> Reported-by: Marek Lindner <lindner_marek@yahoo.de> Signed-off-by: Sven Eckelmann <sven@narfation.org>
Diffstat (limited to 'net/batman-adv')
-rw-r--r--net/batman-adv/unicast.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/net/batman-adv/unicast.c b/net/batman-adv/unicast.c
index ee41fef04b21..811f7fc7932d 100644
--- a/net/batman-adv/unicast.c
+++ b/net/batman-adv/unicast.c
@@ -224,7 +224,7 @@ int frag_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv,
224 struct unicast_frag_packet *frag1, *frag2; 224 struct unicast_frag_packet *frag1, *frag2;
225 int uc_hdr_len = sizeof(struct unicast_packet); 225 int uc_hdr_len = sizeof(struct unicast_packet);
226 int ucf_hdr_len = sizeof(struct unicast_frag_packet); 226 int ucf_hdr_len = sizeof(struct unicast_frag_packet);
227 int data_len = skb->len; 227 int data_len = skb->len - uc_hdr_len;
228 228
229 if (!bat_priv->primary_if) 229 if (!bat_priv->primary_if)
230 goto dropped; 230 goto dropped;
@@ -232,10 +232,11 @@ int frag_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv,
232 frag_skb = dev_alloc_skb(data_len - (data_len / 2) + ucf_hdr_len); 232 frag_skb = dev_alloc_skb(data_len - (data_len / 2) + ucf_hdr_len);
233 if (!frag_skb) 233 if (!frag_skb)
234 goto dropped; 234 goto dropped;
235 skb_reserve(frag_skb, ucf_hdr_len);
235 236
236 unicast_packet = (struct unicast_packet *) skb->data; 237 unicast_packet = (struct unicast_packet *) skb->data;
237 memcpy(&tmp_uc, unicast_packet, uc_hdr_len); 238 memcpy(&tmp_uc, unicast_packet, uc_hdr_len);
238 skb_split(skb, frag_skb, data_len / 2); 239 skb_split(skb, frag_skb, data_len / 2 + uc_hdr_len);
239 240
240 if (my_skb_head_push(skb, ucf_hdr_len - uc_hdr_len) < 0 || 241 if (my_skb_head_push(skb, ucf_hdr_len - uc_hdr_len) < 0 ||
241 my_skb_head_push(frag_skb, ucf_hdr_len) < 0) 242 my_skb_head_push(frag_skb, ucf_hdr_len) < 0)