diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2006-06-22 05:40:14 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-06-23 05:07:29 -0400 |
commit | 7967168cefdbc63bf332d6b1548eca7cd65ebbcc (patch) | |
tree | c45759149ae0acdc89d746e556a0ae278d11776d /net/ipv4/ip_output.c | |
parent | d4828d85d188dc70ed172802e798d3978bb6e29e (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 'net/ipv4/ip_output.c')
-rw-r--r-- | net/ipv4/ip_output.c | 16 |
1 files changed, 9 insertions, 7 deletions
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 8538aac3d148..7624fd1d8f9f 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c | |||
@@ -210,8 +210,7 @@ static inline int ip_finish_output(struct sk_buff *skb) | |||
210 | return dst_output(skb); | 210 | return dst_output(skb); |
211 | } | 211 | } |
212 | #endif | 212 | #endif |
213 | if (skb->len > dst_mtu(skb->dst) && | 213 | if (skb->len > dst_mtu(skb->dst) && !skb_shinfo(skb)->gso_size) |
214 | !(skb_shinfo(skb)->ufo_size || skb_shinfo(skb)->tso_size)) | ||
215 | return ip_fragment(skb, ip_finish_output2); | 214 | return ip_fragment(skb, ip_finish_output2); |
216 | else | 215 | else |
217 | return ip_finish_output2(skb); | 216 | return ip_finish_output2(skb); |
@@ -362,7 +361,7 @@ packet_routed: | |||
362 | } | 361 | } |
363 | 362 | ||
364 | ip_select_ident_more(iph, &rt->u.dst, sk, | 363 | ip_select_ident_more(iph, &rt->u.dst, sk, |
365 | (skb_shinfo(skb)->tso_segs ?: 1) - 1); | 364 | (skb_shinfo(skb)->gso_segs ?: 1) - 1); |
366 | 365 | ||
367 | /* Add an IP checksum. */ | 366 | /* Add an IP checksum. */ |
368 | ip_send_check(iph); | 367 | ip_send_check(iph); |
@@ -744,7 +743,8 @@ static inline int ip_ufo_append_data(struct sock *sk, | |||
744 | (length - transhdrlen)); | 743 | (length - transhdrlen)); |
745 | if (!err) { | 744 | if (!err) { |
746 | /* specify the length of each IP datagram fragment*/ | 745 | /* specify the length of each IP datagram fragment*/ |
747 | skb_shinfo(skb)->ufo_size = (mtu - fragheaderlen); | 746 | skb_shinfo(skb)->gso_size = mtu - fragheaderlen; |
747 | skb_shinfo(skb)->gso_type = SKB_GSO_UDPV4; | ||
748 | __skb_queue_tail(&sk->sk_write_queue, skb); | 748 | __skb_queue_tail(&sk->sk_write_queue, skb); |
749 | 749 | ||
750 | return 0; | 750 | return 0; |
@@ -1087,14 +1087,16 @@ ssize_t ip_append_page(struct sock *sk, struct page *page, | |||
1087 | 1087 | ||
1088 | inet->cork.length += size; | 1088 | inet->cork.length += size; |
1089 | if ((sk->sk_protocol == IPPROTO_UDP) && | 1089 | if ((sk->sk_protocol == IPPROTO_UDP) && |
1090 | (rt->u.dst.dev->features & NETIF_F_UFO)) | 1090 | (rt->u.dst.dev->features & NETIF_F_UFO)) { |
1091 | skb_shinfo(skb)->ufo_size = (mtu - fragheaderlen); | 1091 | skb_shinfo(skb)->gso_size = mtu - fragheaderlen; |
1092 | skb_shinfo(skb)->gso_type = SKB_GSO_UDPV4; | ||
1093 | } | ||
1092 | 1094 | ||
1093 | 1095 | ||
1094 | while (size > 0) { | 1096 | while (size > 0) { |
1095 | int i; | 1097 | int i; |
1096 | 1098 | ||
1097 | if (skb_shinfo(skb)->ufo_size) | 1099 | if (skb_shinfo(skb)->gso_size) |
1098 | len = size; | 1100 | len = size; |
1099 | else { | 1101 | else { |
1100 | 1102 | ||