#include <linux/mm.h>
#include <linux/string.h>
#include <linux/errno.h>
+#include <linux/config.h>
#include <linux/socket.h>
#include <linux/sockios.h>
return dst_output(skb);
}
#endif
- if (skb->len > dst_mtu(skb->dst) && !skb_is_gso(skb))
+ if (skb->len > dst_mtu(skb->dst) &&
+ !(skb_shinfo(skb)->ufo_size || skb_shinfo(skb)->tso_size))
return ip_fragment(skb, ip_finish_output2);
else
return ip_finish_output2(skb);
}
ip_select_ident_more(iph, &rt->u.dst, sk,
- (skb_shinfo(skb)->gso_segs ?: 1) - 1);
+ (skb_shinfo(skb)->tso_segs ?: 1) - 1);
/* Add an IP checksum. */
ip_send_check(iph);
nf_bridge_get(to->nf_bridge);
#endif
#endif
- skb_copy_secmark(to, from);
}
/*
iph = skb->nh.iph;
if (unlikely((iph->frag_off & htons(IP_DF)) && !skb->local_df)) {
- IP_INC_STATS(IPSTATS_MIB_FRAGFAILS);
icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
htonl(dst_mtu(&rt->u.dst)));
kfree_skb(skb);
err = output(skb);
- if (!err)
- IP_INC_STATS(IPSTATS_MIB_FRAGCREATES);
if (err || !frag)
break;
/*
* Put this fragment into the sending queue.
*/
+
+ IP_INC_STATS(IPSTATS_MIB_FRAGCREATES);
+
iph->tot_len = htons(len + hlen);
ip_send_check(iph);
err = output(skb2);
if (err)
goto fail;
-
- IP_INC_STATS(IPSTATS_MIB_FRAGCREATES);
}
kfree_skb(skb);
IP_INC_STATS(IPSTATS_MIB_FRAGOKS);
(length - transhdrlen));
if (!err) {
/* specify the length of each IP datagram fragment*/
- skb_shinfo(skb)->gso_size = mtu - fragheaderlen;
- skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
+ skb_shinfo(skb)->ufo_size = (mtu - fragheaderlen);
__skb_queue_tail(&sk->sk_write_queue, skb);
return 0;
*/
if (transhdrlen &&
length + fragheaderlen <= mtu &&
- rt->u.dst.dev->features & NETIF_F_ALL_CSUM &&
+ rt->u.dst.dev->features&(NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM) &&
!exthdrlen)
csummode = CHECKSUM_HW;
* because we have no idea what fragment will be
* the last.
*/
- if (datalen == length + fraggap)
+ if (datalen == length)
alloclen += rt->u.dst.trailer_len;
if (transhdrlen) {
skb_prev->csum = csum_sub(skb_prev->csum,
skb->csum);
data += fraggap;
- pskb_trim_unique(skb_prev, maxfraglen);
+ skb_trim(skb_prev, maxfraglen);
}
copy = datalen - transhdrlen - fraggap;
inet->cork.length += size;
if ((sk->sk_protocol == IPPROTO_UDP) &&
- (rt->u.dst.dev->features & NETIF_F_UFO)) {
- skb_shinfo(skb)->gso_size = mtu - fragheaderlen;
- skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
- }
+ (rt->u.dst.dev->features & NETIF_F_UFO))
+ skb_shinfo(skb)->ufo_size = (mtu - fragheaderlen);
while (size > 0) {
int i;
- if (skb_is_gso(skb))
+ if (skb_shinfo(skb)->ufo_size)
len = size;
else {
data, fraggap, 0);
skb_prev->csum = csum_sub(skb_prev->csum,
skb->csum);
- pskb_trim_unique(skb_prev, maxfraglen);
+ skb_trim(skb_prev, maxfraglen);
}
/*