diff options
Diffstat (limited to 'net/batman-adv/fragmentation.c')
-rw-r--r-- | net/batman-adv/fragmentation.c | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/net/batman-adv/fragmentation.c b/net/batman-adv/fragmentation.c index 9751b207b01f..3aceac21b283 100644 --- a/net/batman-adv/fragmentation.c +++ b/net/batman-adv/fragmentation.c @@ -396,7 +396,7 @@ out: * batadv_frag_create - create a fragment from skb * @skb: skb to create fragment from * @frag_head: header to use in new fragment - * @mtu: size of new fragment + * @fragment_size: size of new fragment * * Split the passed skb into two fragments: A new one with size matching the * passed mtu and the old one with the rest. The new skb contains data from the @@ -406,11 +406,11 @@ out: */ static struct sk_buff *batadv_frag_create(struct sk_buff *skb, struct batadv_frag_packet *frag_head, - unsigned int mtu) + unsigned int fragment_size) { struct sk_buff *skb_fragment; unsigned header_size = sizeof(*frag_head); - unsigned fragment_size = mtu - header_size; + unsigned mtu = fragment_size + header_size; skb_fragment = netdev_alloc_skb(NULL, mtu + ETH_HLEN); if (!skb_fragment) @@ -448,7 +448,7 @@ bool batadv_frag_send_packet(struct sk_buff *skb, struct sk_buff *skb_fragment; unsigned mtu = neigh_node->if_incoming->net_dev->mtu; unsigned header_size = sizeof(frag_header); - unsigned max_fragment_size, max_packet_size; + unsigned max_fragment_size, num_fragments; bool ret = false; /* To avoid merge and refragmentation at next-hops we never send @@ -456,10 +456,15 @@ bool batadv_frag_send_packet(struct sk_buff *skb, */ mtu = min_t(unsigned, 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 || max_fragment_size == 0) + goto out_err; + + num_fragments = (skb->len - 1) / max_fragment_size + 1; + max_fragment_size = (skb->len - 1) / num_fragments + 1; /* 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) goto out_err; bat_priv = orig_node->bat_priv; @@ -484,7 +489,8 @@ bool batadv_frag_send_packet(struct sk_buff *skb, if (frag_header.no == BATADV_FRAG_MAX_FRAGMENTS - 1) goto out_err; - skb_fragment = batadv_frag_create(skb, &frag_header, mtu); + skb_fragment = batadv_frag_create(skb, &frag_header, + max_fragment_size); if (!skb_fragment) goto out_err; |