[NET]: Add software TSOv4

This patch adds the GSO implementation for IPv4 TCP.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Herbert Xu
2006-06-22 03:02:40 -07:00
committed by David S. Miller
parent f6a78bfcb1
commit f4c50d990d
6 changed files with 243 additions and 0 deletions

View File

@@ -68,6 +68,7 @@
*/
#include <linux/config.h>
#include <linux/err.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/socket.h>
@@ -1096,6 +1097,54 @@ int inet_sk_rebuild_header(struct sock *sk)
EXPORT_SYMBOL(inet_sk_rebuild_header);
static struct sk_buff *inet_gso_segment(struct sk_buff *skb, int sg)
{
struct sk_buff *segs = ERR_PTR(-EINVAL);
struct iphdr *iph;
struct net_protocol *ops;
int proto;
int ihl;
int id;
if (!pskb_may_pull(skb, sizeof(*iph)))
goto out;
iph = skb->nh.iph;
ihl = iph->ihl * 4;
if (ihl < sizeof(*iph))
goto out;
if (!pskb_may_pull(skb, ihl))
goto out;
skb->h.raw = __skb_pull(skb, ihl);
iph = skb->nh.iph;
id = ntohs(iph->id);
proto = iph->protocol & (MAX_INET_PROTOS - 1);
segs = ERR_PTR(-EPROTONOSUPPORT);
rcu_read_lock();
ops = rcu_dereference(inet_protos[proto]);
if (ops && ops->gso_segment)
segs = ops->gso_segment(skb, sg);
rcu_read_unlock();
if (IS_ERR(segs))
goto out;
skb = segs;
do {
iph = skb->nh.iph;
iph->id = htons(id++);
iph->tot_len = htons(skb->len - skb->mac_len);
iph->check = 0;
iph->check = ip_fast_csum(skb->nh.raw, iph->ihl);
} while ((skb = skb->next));
out:
return segs;
}
#ifdef CONFIG_IP_MULTICAST
static struct net_protocol igmp_protocol = {
.handler = igmp_rcv,
@@ -1105,6 +1154,7 @@ static struct net_protocol igmp_protocol = {
static struct net_protocol tcp_protocol = {
.handler = tcp_v4_rcv,
.err_handler = tcp_v4_err,
.gso_segment = tcp_tso_segment,
.no_policy = 1,
};
@@ -1150,6 +1200,7 @@ static int ipv4_proc_init(void);
static struct packet_type ip_packet_type = {
.type = __constant_htons(ETH_P_IP),
.func = ip_rcv,
.gso_segment = inet_gso_segment,
};
static int __init inet_init(void)