On Sonntag, 29. Januar 2017 06:14:28 CET Linus Lüssing wrote: [...]
However, currently "Fragmentation v2" does not support re-fragmentation. Which means that once a packet is split into two packets of 1400 + x bytes for instance and the next hop provides an interface with an even smaller MTU of 1280 bytes, then the larger fragment is lost.
[...]
Beside this change, did you try to make the fragments more equally sized? Here is just some really ugly and untested pseudo code:
@@ -454,7 +454,7 @@ int batadv_frag_send_packet(struct sk_buff *skb, struct sk_buff *skb_fragment; unsigned int mtu = neigh_node->if_incoming->net_dev->mtu; unsigned int header_size = sizeof(frag_header); - unsigned int max_fragment_size, max_packet_size; + unsigned int max_fragment_size, num_fragments; int ret;
/* To avoid merge and refragmentation at next-hops we never send @@ -462,10 +462,17 @@ int batadv_frag_send_packet(struct sk_buff *skb, */ mtu = min_t(unsigned int, mtu, BATADV_FRAG_MAX_FRAG_SIZE); max_fragment_size = mtu - header_size; - max_packet_size = max_fragment_size * BATADV_FRAG_MAX_FRAGMENTS; + + if (skb->len == 0) + return -EINVAL; + +#define ceil_div(x, y) (1 + ((x - 1) / y)) + num_fragments = ceil_div(skb->len, max_fragment_size); + max_fragment_size = ceil_div(skb->len, num_fragments); +#undef ceil_div
/* Don't even try to fragment, if we need more than 16 fragments */ - if (skb->len > max_packet_size) { + if (num_fragments > BATADV_FRAG_MAX_FRAGMENTS) { ret = -EAGAIN; goto free_skb; }
Kind regards, Sven