aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/linux/netdevice.h12
-rw-r--r--include/net/sock.h13
-rw-r--r--include/net/tcp.h2
3 files changed, 20 insertions, 7 deletions
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index aa2d3c12c4d8..6db03ab7cec8 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -313,6 +313,7 @@ struct net_device
313 313
314 /* Segmentation offload features */ 314 /* Segmentation offload features */
315#define NETIF_F_GSO_SHIFT 16 315#define NETIF_F_GSO_SHIFT 16
316#define NETIF_F_GSO_MASK 0xffff0000
316#define NETIF_F_TSO (SKB_GSO_TCPV4 << NETIF_F_GSO_SHIFT) 317#define NETIF_F_TSO (SKB_GSO_TCPV4 << NETIF_F_GSO_SHIFT)
317#define NETIF_F_UFO (SKB_GSO_UDPV4 << NETIF_F_GSO_SHIFT) 318#define NETIF_F_UFO (SKB_GSO_UDPV4 << NETIF_F_GSO_SHIFT)
318#define NETIF_F_GSO_ROBUST (SKB_GSO_DODGY << NETIF_F_GSO_SHIFT) 319#define NETIF_F_GSO_ROBUST (SKB_GSO_DODGY << NETIF_F_GSO_SHIFT)
@@ -991,13 +992,18 @@ extern void dev_seq_stop(struct seq_file *seq, void *v);
991 992
992extern void linkwatch_run_queue(void); 993extern void linkwatch_run_queue(void);
993 994
994static inline int skb_gso_ok(struct sk_buff *skb, int features) 995static inline int net_gso_ok(int features, int gso_type)
995{ 996{
996 int feature = skb_shinfo(skb)->gso_size ? 997 int feature = gso_type << NETIF_F_GSO_SHIFT;
997 skb_shinfo(skb)->gso_type << NETIF_F_GSO_SHIFT : 0;
998 return (features & feature) == feature; 998 return (features & feature) == feature;
999} 999}
1000 1000
1001static inline int skb_gso_ok(struct sk_buff *skb, int features)
1002{
1003 return net_gso_ok(features, skb_shinfo(skb)->gso_size ?
1004 skb_shinfo(skb)->gso_type : 0);
1005}
1006
1001static inline int netif_needs_gso(struct net_device *dev, struct sk_buff *skb) 1007static inline int netif_needs_gso(struct net_device *dev, struct sk_buff *skb)
1002{ 1008{
1003 return !skb_gso_ok(skb, dev->features); 1009 return !skb_gso_ok(skb, dev->features);
diff --git a/include/net/sock.h b/include/net/sock.h
index 7136bae48c2f..7b3d6b856946 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -140,6 +140,7 @@ struct sock_common {
140 * @sk_flags: %SO_LINGER (l_onoff), %SO_BROADCAST, %SO_KEEPALIVE, %SO_OOBINLINE settings 140 * @sk_flags: %SO_LINGER (l_onoff), %SO_BROADCAST, %SO_KEEPALIVE, %SO_OOBINLINE settings
141 * @sk_no_check: %SO_NO_CHECK setting, wether or not checkup packets 141 * @sk_no_check: %SO_NO_CHECK setting, wether or not checkup packets
142 * @sk_route_caps: route capabilities (e.g. %NETIF_F_TSO) 142 * @sk_route_caps: route capabilities (e.g. %NETIF_F_TSO)
143 * @sk_gso_type: GSO type (e.g. %SKB_GSO_TCPV4)
143 * @sk_lingertime: %SO_LINGER l_linger setting 144 * @sk_lingertime: %SO_LINGER l_linger setting
144 * @sk_backlog: always used with the per-socket spinlock held 145 * @sk_backlog: always used with the per-socket spinlock held
145 * @sk_callback_lock: used with the callbacks in the end of this struct 146 * @sk_callback_lock: used with the callbacks in the end of this struct
@@ -211,6 +212,7 @@ struct sock {
211 gfp_t sk_allocation; 212 gfp_t sk_allocation;
212 int sk_sndbuf; 213 int sk_sndbuf;
213 int sk_route_caps; 214 int sk_route_caps;
215 int sk_gso_type;
214 int sk_rcvlowat; 216 int sk_rcvlowat;
215 unsigned long sk_flags; 217 unsigned long sk_flags;
216 unsigned long sk_lingertime; 218 unsigned long sk_lingertime;
@@ -1025,15 +1027,20 @@ extern struct dst_entry *__sk_dst_check(struct sock *sk, u32 cookie);
1025 1027
1026extern struct dst_entry *sk_dst_check(struct sock *sk, u32 cookie); 1028extern struct dst_entry *sk_dst_check(struct sock *sk, u32 cookie);
1027 1029
1030static inline int sk_can_gso(const struct sock *sk)
1031{
1032 return net_gso_ok(sk->sk_route_caps, sk->sk_gso_type);
1033}
1034
1028static inline void sk_setup_caps(struct sock *sk, struct dst_entry *dst) 1035static inline void sk_setup_caps(struct sock *sk, struct dst_entry *dst)
1029{ 1036{
1030 __sk_dst_set(sk, dst); 1037 __sk_dst_set(sk, dst);
1031 sk->sk_route_caps = dst->dev->features; 1038 sk->sk_route_caps = dst->dev->features;
1032 if (sk->sk_route_caps & NETIF_F_GSO) 1039 if (sk->sk_route_caps & NETIF_F_GSO)
1033 sk->sk_route_caps |= NETIF_F_TSO; 1040 sk->sk_route_caps |= NETIF_F_GSO_MASK;
1034 if (sk->sk_route_caps & NETIF_F_TSO) { 1041 if (sk_can_gso(sk)) {
1035 if (dst->header_len) 1042 if (dst->header_len)
1036 sk->sk_route_caps &= ~NETIF_F_TSO; 1043 sk->sk_route_caps &= ~NETIF_F_GSO_MASK;
1037 else 1044 else
1038 sk->sk_route_caps |= NETIF_F_SG | NETIF_F_HW_CSUM; 1045 sk->sk_route_caps |= NETIF_F_SG | NETIF_F_HW_CSUM;
1039 } 1046 }
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 624921e76332..3cd803b0d7a5 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -751,7 +751,7 @@ static inline int tcp_is_cwnd_limited(const struct sock *sk, u32 in_flight)
751 if (in_flight >= tp->snd_cwnd) 751 if (in_flight >= tp->snd_cwnd)
752 return 1; 752 return 1;
753 753
754 if (!(sk->sk_route_caps & NETIF_F_TSO)) 754 if (!sk_can_gso(sk))
755 return 0; 755 return 0;
756 756
757 left = tp->snd_cwnd - in_flight; 757 left = tp->snd_cwnd - in_flight;