diff options
Diffstat (limited to 'net/batman-adv/unicast.c')
-rw-r--r-- | net/batman-adv/unicast.c | 15 |
1 files changed, 10 insertions, 5 deletions
diff --git a/net/batman-adv/unicast.c b/net/batman-adv/unicast.c index ee41fef04b21..cbf022cb3121 100644 --- a/net/batman-adv/unicast.c +++ b/net/batman-adv/unicast.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2010 B.A.T.M.A.N. contributors: | 2 | * Copyright (C) 2010-2011 B.A.T.M.A.N. contributors: |
3 | * | 3 | * |
4 | * Andreas Langer | 4 | * Andreas Langer |
5 | * | 5 | * |
@@ -224,7 +224,8 @@ 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 | int large_tail = 0; | ||
228 | 229 | ||
229 | if (!bat_priv->primary_if) | 230 | if (!bat_priv->primary_if) |
230 | goto dropped; | 231 | goto dropped; |
@@ -232,10 +233,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); | 233 | frag_skb = dev_alloc_skb(data_len - (data_len / 2) + ucf_hdr_len); |
233 | if (!frag_skb) | 234 | if (!frag_skb) |
234 | goto dropped; | 235 | goto dropped; |
236 | skb_reserve(frag_skb, ucf_hdr_len); | ||
235 | 237 | ||
236 | unicast_packet = (struct unicast_packet *) skb->data; | 238 | unicast_packet = (struct unicast_packet *) skb->data; |
237 | memcpy(&tmp_uc, unicast_packet, uc_hdr_len); | 239 | memcpy(&tmp_uc, unicast_packet, uc_hdr_len); |
238 | skb_split(skb, frag_skb, data_len / 2); | 240 | skb_split(skb, frag_skb, data_len / 2 + uc_hdr_len); |
239 | 241 | ||
240 | if (my_skb_head_push(skb, ucf_hdr_len - uc_hdr_len) < 0 || | 242 | if (my_skb_head_push(skb, ucf_hdr_len - uc_hdr_len) < 0 || |
241 | my_skb_head_push(frag_skb, ucf_hdr_len) < 0) | 243 | my_skb_head_push(frag_skb, ucf_hdr_len) < 0) |
@@ -253,8 +255,11 @@ int frag_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv, | |||
253 | memcpy(frag1->orig, bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN); | 255 | memcpy(frag1->orig, bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN); |
254 | memcpy(frag2, frag1, sizeof(struct unicast_frag_packet)); | 256 | memcpy(frag2, frag1, sizeof(struct unicast_frag_packet)); |
255 | 257 | ||
256 | frag1->flags |= UNI_FRAG_HEAD; | 258 | if (data_len & 1) |
257 | frag2->flags &= ~UNI_FRAG_HEAD; | 259 | large_tail = UNI_FRAG_LARGETAIL; |
260 | |||
261 | frag1->flags = UNI_FRAG_HEAD | large_tail; | ||
262 | frag2->flags = large_tail; | ||
258 | 263 | ||
259 | frag1->seqno = htons((uint16_t)atomic_inc_return( | 264 | frag1->seqno = htons((uint16_t)atomic_inc_return( |
260 | &batman_if->frag_seqno)); | 265 | &batman_if->frag_seqno)); |