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