|
@@ -404,7 +404,7 @@ out:
|
|
* batadv_frag_create - create a fragment from skb
|
|
* batadv_frag_create - create a fragment from skb
|
|
* @skb: skb to create fragment from
|
|
* @skb: skb to create fragment from
|
|
* @frag_head: header to use in new fragment
|
|
* @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
|
|
* 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
|
|
* passed mtu and the old one with the rest. The new skb contains data from the
|
|
@@ -414,11 +414,11 @@ out:
|
|
*/
|
|
*/
|
|
static struct sk_buff *batadv_frag_create(struct sk_buff *skb,
|
|
static struct sk_buff *batadv_frag_create(struct sk_buff *skb,
|
|
struct batadv_frag_packet *frag_head,
|
|
struct batadv_frag_packet *frag_head,
|
|
- unsigned int mtu)
|
|
|
|
|
|
+ unsigned int fragment_size)
|
|
{
|
|
{
|
|
struct sk_buff *skb_fragment;
|
|
struct sk_buff *skb_fragment;
|
|
unsigned int header_size = sizeof(*frag_head);
|
|
unsigned int header_size = sizeof(*frag_head);
|
|
- unsigned int fragment_size = mtu - header_size;
|
|
|
|
|
|
+ unsigned int mtu = fragment_size + header_size;
|
|
|
|
|
|
skb_fragment = netdev_alloc_skb(NULL, mtu + ETH_HLEN);
|
|
skb_fragment = netdev_alloc_skb(NULL, mtu + ETH_HLEN);
|
|
if (!skb_fragment)
|
|
if (!skb_fragment)
|
|
@@ -456,7 +456,7 @@ int batadv_frag_send_packet(struct sk_buff *skb,
|
|
struct sk_buff *skb_fragment;
|
|
struct sk_buff *skb_fragment;
|
|
unsigned int mtu = neigh_node->if_incoming->net_dev->mtu;
|
|
unsigned int mtu = neigh_node->if_incoming->net_dev->mtu;
|
|
unsigned int header_size = sizeof(frag_header);
|
|
unsigned int header_size = sizeof(frag_header);
|
|
- unsigned int max_fragment_size, max_packet_size;
|
|
|
|
|
|
+ unsigned int max_fragment_size, num_fragments;
|
|
int ret;
|
|
int ret;
|
|
|
|
|
|
/* To avoid merge and refragmentation at next-hops we never send
|
|
/* To avoid merge and refragmentation at next-hops we never send
|
|
@@ -464,10 +464,15 @@ int batadv_frag_send_packet(struct sk_buff *skb,
|
|
*/
|
|
*/
|
|
mtu = min_t(unsigned int, mtu, BATADV_FRAG_MAX_FRAG_SIZE);
|
|
mtu = min_t(unsigned int, mtu, BATADV_FRAG_MAX_FRAG_SIZE);
|
|
max_fragment_size = mtu - header_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)
|
|
|
|
+ return -EINVAL;
|
|
|
|
+
|
|
|
|
+ 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 */
|
|
/* 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;
|
|
ret = -EAGAIN;
|
|
goto free_skb;
|
|
goto free_skb;
|
|
}
|
|
}
|
|
@@ -507,7 +512,8 @@ int batadv_frag_send_packet(struct sk_buff *skb,
|
|
goto put_primary_if;
|
|
goto put_primary_if;
|
|
}
|
|
}
|
|
|
|
|
|
- skb_fragment = batadv_frag_create(skb, &frag_header, mtu);
|
|
|
|
|
|
+ skb_fragment = batadv_frag_create(skb, &frag_header,
|
|
|
|
+ max_fragment_size);
|
|
if (!skb_fragment) {
|
|
if (!skb_fragment) {
|
|
ret = -ENOMEM;
|
|
ret = -ENOMEM;
|
|
goto put_primary_if;
|
|
goto put_primary_if;
|