summaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-06-30 15:40:17 -0700
committerLinus Torvalds <torvalds@g5.osdl.org>2006-06-30 15:40:17 -0700
commite37a72de84d27ee8bc0e7dbb5c2f1774ed306dbb (patch)
treef9da35cbd79b52a5bd08d4a0f960bde6af741da0 /net/ipv4/tcp.c
parent93fdf10d4c28edaa1b9f80e7f9c3002359186d00 (diff)
parentf83ef8c0b58dac17211a4c0b6df0e2b1bd6637b1 (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6: [IPV6]: Added GSO support for TCPv6 [NET]: Generalise TSO-specific bits from skb_setup_caps [IPV6]: Added GSO support for TCPv6 [IPV6]: Remove redundant length check on input [NETFILTER]: SCTP conntrack: fix crash triggered by packet without chunks [TG3]: Update version and reldate [TG3]: Add TSO workaround using GSO [TG3]: Turn on hw fix for ASF problems [TG3]: Add rx BD workaround [TG3]: Add tg3_netif_stop() in vlan functions [TCP]: Reset gso_segs if packet is dodgy
Diffstat (limited to 'net/ipv4/tcp.c')
-rw-r--r--net/ipv4/tcp.c17
1 files changed, 12 insertions, 5 deletions
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index a97450e9eb3..804458712d8 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -642,7 +642,7 @@ static inline int select_size(struct sock *sk, struct tcp_sock *tp)
int tmp = tp->mss_cache;
if (sk->sk_route_caps & NETIF_F_SG) {
- if (sk->sk_route_caps & NETIF_F_TSO)
+ if (sk_can_gso(sk))
tmp = 0;
else {
int pgbreak = SKB_MAX_HEAD(MAX_TCP_HEADER);
@@ -2165,13 +2165,19 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features)
if (!pskb_may_pull(skb, thlen))
goto out;
- segs = NULL;
- if (skb_gso_ok(skb, features | NETIF_F_GSO_ROBUST))
- goto out;
-
oldlen = (u16)~skb->len;
__skb_pull(skb, thlen);
+ if (skb_gso_ok(skb, features | NETIF_F_GSO_ROBUST)) {
+ /* Packet is from an untrusted source, reset gso_segs. */
+ int mss = skb_shinfo(skb)->gso_size;
+
+ skb_shinfo(skb)->gso_segs = (skb->len + mss - 1) / mss;
+
+ segs = NULL;
+ goto out;
+ }
+
segs = skb_segment(skb, features);
if (IS_ERR(segs))
goto out;
@@ -2208,6 +2214,7 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features)
out:
return segs;
}
+EXPORT_SYMBOL(tcp_tso_segment);
extern void __skb_cb_too_small_for_tcp(int, int);
extern struct tcp_congestion_ops tcp_reno;