aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/tcp.c')
-rw-r--r--net/ipv4/tcp.c29
1 files changed, 23 insertions, 6 deletions
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 0336422c88a0..f6a2d9223d07 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -247,7 +247,6 @@
247 * TCP_CLOSE socket is finished 247 * TCP_CLOSE socket is finished
248 */ 248 */
249 249
250#include <linux/config.h>
251#include <linux/module.h> 250#include <linux/module.h>
252#include <linux/types.h> 251#include <linux/types.h>
253#include <linux/fcntl.h> 252#include <linux/fcntl.h>
@@ -643,7 +642,7 @@ static inline int select_size(struct sock *sk, struct tcp_sock *tp)
643 int tmp = tp->mss_cache; 642 int tmp = tp->mss_cache;
644 643
645 if (sk->sk_route_caps & NETIF_F_SG) { 644 if (sk->sk_route_caps & NETIF_F_SG) {
646 if (sk->sk_route_caps & NETIF_F_TSO) 645 if (sk_can_gso(sk))
647 tmp = 0; 646 tmp = 0;
648 else { 647 else {
649 int pgbreak = SKB_MAX_HEAD(MAX_TCP_HEADER); 648 int pgbreak = SKB_MAX_HEAD(MAX_TCP_HEADER);
@@ -2166,13 +2165,30 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features)
2166 if (!pskb_may_pull(skb, thlen)) 2165 if (!pskb_may_pull(skb, thlen))
2167 goto out; 2166 goto out;
2168 2167
2169 segs = NULL;
2170 if (skb_gso_ok(skb, features | NETIF_F_GSO_ROBUST))
2171 goto out;
2172
2173 oldlen = (u16)~skb->len; 2168 oldlen = (u16)~skb->len;
2174 __skb_pull(skb, thlen); 2169 __skb_pull(skb, thlen);
2175 2170
2171 if (skb_gso_ok(skb, features | NETIF_F_GSO_ROBUST)) {
2172 /* Packet is from an untrusted source, reset gso_segs. */
2173 int type = skb_shinfo(skb)->gso_type;
2174 int mss;
2175
2176 if (unlikely(type &
2177 ~(SKB_GSO_TCPV4 |
2178 SKB_GSO_DODGY |
2179 SKB_GSO_TCP_ECN |
2180 SKB_GSO_TCPV6 |
2181 0) ||
2182 !(type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6))))
2183 goto out;
2184
2185 mss = skb_shinfo(skb)->gso_size;
2186 skb_shinfo(skb)->gso_segs = (skb->len + mss - 1) / mss;
2187
2188 segs = NULL;
2189 goto out;
2190 }
2191
2176 segs = skb_segment(skb, features); 2192 segs = skb_segment(skb, features);
2177 if (IS_ERR(segs)) 2193 if (IS_ERR(segs))
2178 goto out; 2194 goto out;
@@ -2209,6 +2225,7 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features)
2209out: 2225out:
2210 return segs; 2226 return segs;
2211} 2227}
2228EXPORT_SYMBOL(tcp_tso_segment);
2212 2229
2213extern void __skb_cb_too_small_for_tcp(int, int); 2230extern void __skb_cb_too_small_for_tcp(int, int);
2214extern struct tcp_congestion_ops tcp_reno; 2231extern struct tcp_congestion_ops tcp_reno;