[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:

committed by
David S. Miller

parent
f6a78bfcb1
commit
f4c50d990d
@@ -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)
|
||||
|
Reference in New Issue
Block a user