|
@@ -351,7 +351,7 @@ static int ip_frag_queue(struct ipq *qp, struct sk_buff *skb)
|
|
|
ihl = ip_hdrlen(skb);
|
|
|
|
|
|
/* Determine the position of this fragment. */
|
|
|
- end = offset + skb->len - ihl;
|
|
|
+ end = offset + skb->len - skb_network_offset(skb) - ihl;
|
|
|
err = -EINVAL;
|
|
|
|
|
|
/* Is this the final fragment? */
|
|
@@ -381,7 +381,7 @@ static int ip_frag_queue(struct ipq *qp, struct sk_buff *skb)
|
|
|
goto err;
|
|
|
|
|
|
err = -ENOMEM;
|
|
|
- if (!pskb_pull(skb, ihl))
|
|
|
+ if (!pskb_pull(skb, skb_network_offset(skb) + ihl))
|
|
|
goto err;
|
|
|
|
|
|
err = pskb_trim_rcsum(skb, end - offset);
|
|
@@ -641,6 +641,8 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
|
|
|
iph->frag_off = 0;
|
|
|
}
|
|
|
|
|
|
+ ip_send_check(iph);
|
|
|
+
|
|
|
IP_INC_STATS_BH(net, IPSTATS_MIB_REASMOKS);
|
|
|
qp->q.fragments = NULL;
|
|
|
qp->q.fragments_tail = NULL;
|