aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2006-06-22 05:40:14 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2006-06-23 05:07:29 -0400
commit7967168cefdbc63bf332d6b1548eca7cd65ebbcc (patch)
treec45759149ae0acdc89d746e556a0ae278d11776d /include
parentd4828d85d188dc70ed172802e798d3978bb6e29e (diff)
[NET]: Merge TSO/UFO fields in sk_buff
Having separate fields in sk_buff for TSO/UFO (tso_size/ufo_size) is not going to scale if we add any more segmentation methods (e.g., DCCP). So let's merge them. They were used to tell the protocol of a packet. This function has been subsumed by the new gso_type field. This is essentially a set of netdev feature bits (shifted by 16 bits) that are required to process a specific skb. As such it's easy to tell whether a given device can process a GSO skb: you just have to and the gso_type field and the netdev's features field. I've made gso_type a conjunction. The idea is that you have a base type (e.g., SKB_GSO_TCPV4) that can be modified further to support new features. For example, if we add a hardware TSO type that supports ECN, they would declare NETIF_F_TSO | NETIF_F_TSO_ECN. All TSO packets with CWR set would have a gso_type of SKB_GSO_TCPV4 | SKB_GSO_TCPV4_ECN while all other TSO packets would be SKB_GSO_TCPV4. This means that only the CWR packets need to be emulated in software. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include')
-rw-r--r--include/linux/netdevice.h14
-rw-r--r--include/linux/skbuff.h12
-rw-r--r--include/net/tcp.h4
3 files changed, 23 insertions, 7 deletions
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index cead6be467ed..fa5671307b90 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -308,9 +308,12 @@ struct net_device
308#define NETIF_F_HW_VLAN_RX 256 /* Receive VLAN hw acceleration */ 308#define NETIF_F_HW_VLAN_RX 256 /* Receive VLAN hw acceleration */
309#define NETIF_F_HW_VLAN_FILTER 512 /* Receive filtering on VLAN */ 309#define NETIF_F_HW_VLAN_FILTER 512 /* Receive filtering on VLAN */
310#define NETIF_F_VLAN_CHALLENGED 1024 /* Device cannot handle VLAN packets */ 310#define NETIF_F_VLAN_CHALLENGED 1024 /* Device cannot handle VLAN packets */
311#define NETIF_F_TSO 2048 /* Can offload TCP/IP segmentation */
312#define NETIF_F_LLTX 4096 /* LockLess TX */ 311#define NETIF_F_LLTX 4096 /* LockLess TX */
313#define NETIF_F_UFO 8192 /* Can offload UDP Large Send*/ 312
313 /* Segmentation offload features */
314#define NETIF_F_GSO_SHIFT 16
315#define NETIF_F_TSO (SKB_GSO_TCPV4 << NETIF_F_GSO_SHIFT)
316#define NETIF_F_UFO (SKB_GSO_UDPV4 << NETIF_F_GSO_SHIFT)
314 317
315#define NETIF_F_GEN_CSUM (NETIF_F_NO_CSUM | NETIF_F_HW_CSUM) 318#define NETIF_F_GEN_CSUM (NETIF_F_NO_CSUM | NETIF_F_HW_CSUM)
316#define NETIF_F_ALL_CSUM (NETIF_F_IP_CSUM | NETIF_F_GEN_CSUM) 319#define NETIF_F_ALL_CSUM (NETIF_F_IP_CSUM | NETIF_F_GEN_CSUM)
@@ -979,6 +982,13 @@ extern void dev_seq_stop(struct seq_file *seq, void *v);
979 982
980extern void linkwatch_run_queue(void); 983extern void linkwatch_run_queue(void);
981 984
985static inline int netif_needs_gso(struct net_device *dev, struct sk_buff *skb)
986{
987 int feature = skb_shinfo(skb)->gso_type << NETIF_F_GSO_SHIFT;
988 return skb_shinfo(skb)->gso_size &&
989 (dev->features & feature) != feature;
990}
991
982#endif /* __KERNEL__ */ 992#endif /* __KERNEL__ */
983 993
984#endif /* _LINUX_DEV_H */ 994#endif /* _LINUX_DEV_H */
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index f8c7eb79a27f..97b0d2d1a6b0 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -134,9 +134,10 @@ struct skb_frag_struct {
134struct skb_shared_info { 134struct skb_shared_info {
135 atomic_t dataref; 135 atomic_t dataref;
136 unsigned short nr_frags; 136 unsigned short nr_frags;
137 unsigned short tso_size; 137 unsigned short gso_size;
138 unsigned short tso_segs; 138 /* Warning: this field is not always filled in (UFO)! */
139 unsigned short ufo_size; 139 unsigned short gso_segs;
140 unsigned short gso_type;
140 unsigned int ip6_frag_id; 141 unsigned int ip6_frag_id;
141 struct sk_buff *frag_list; 142 struct sk_buff *frag_list;
142 skb_frag_t frags[MAX_SKB_FRAGS]; 143 skb_frag_t frags[MAX_SKB_FRAGS];
@@ -168,6 +169,11 @@ enum {
168 SKB_FCLONE_CLONE, 169 SKB_FCLONE_CLONE,
169}; 170};
170 171
172enum {
173 SKB_GSO_TCPV4 = 1 << 0,
174 SKB_GSO_UDPV4 = 1 << 1,
175};
176
171/** 177/**
172 * struct sk_buff - socket buffer 178 * struct sk_buff - socket buffer
173 * @next: Next buffer in list 179 * @next: Next buffer in list
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 5f4eb5c79689..b197a9e615c1 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -569,13 +569,13 @@ struct tcp_skb_cb {
569 */ 569 */
570static inline int tcp_skb_pcount(const struct sk_buff *skb) 570static inline int tcp_skb_pcount(const struct sk_buff *skb)
571{ 571{
572 return skb_shinfo(skb)->tso_segs; 572 return skb_shinfo(skb)->gso_segs;
573} 573}
574 574
575/* This is valid iff tcp_skb_pcount() > 1. */ 575/* This is valid iff tcp_skb_pcount() > 1. */
576static inline int tcp_skb_mss(const struct sk_buff *skb) 576static inline int tcp_skb_mss(const struct sk_buff *skb)
577{ 577{
578 return skb_shinfo(skb)->tso_size; 578 return skb_shinfo(skb)->gso_size;
579} 579}
580 580
581static inline void tcp_dec_pcount_approx(__u32 *count, 581static inline void tcp_dec_pcount_approx(__u32 *count,