diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-07-09 15:50:41 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-07-09 15:50:41 -0700 |
commit | 09075ef0fd585fb093bb9a6cd1240272114f89cf (patch) | |
tree | c01d2cc260a18df73f785bea4de1c1cfbcbbd16f /net/ipv4/af_inet.c | |
parent | c87fed1546bd00b42ee75f26c6b45393e4bf7559 (diff) | |
parent | 1b30dd359ebec22d035e8b145751319f63772ca1 (diff) |
Merge commit master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6 of HEAD
* HEAD:
[AX.25]: Use kzalloc
[ATM] net/atm/clip.c: fix PROC_FS=n compile
[PKT_SCHED]: act_api: Fix module leak while flushing actions
[NET]: Fix IPv4/DECnet routing rule dumping
[NET] gso: Fix up GSO packets with broken checksums
[NET] gso: Add skb_is_gso
[IRDA]: fix drivers/net/irda/ali-ircc.c:ali_ircc_init()
[ATM]: fix possible recursive locking in skb_migrate()
[ATM]: Typo in drivers/atm/Kconfig...
[TG3]: add amd8131 to "write reorder" chipsets
[NET]: Fix network device interface printk message priority
Diffstat (limited to 'net/ipv4/af_inet.c')
-rw-r--r-- | net/ipv4/af_inet.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 318d4674faa..c84a32070f8 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -1097,6 +1097,40 @@ int inet_sk_rebuild_header(struct sock *sk) EXPORT_SYMBOL(inet_sk_rebuild_header); +static int inet_gso_send_check(struct sk_buff *skb) +{ + struct iphdr *iph; + struct net_protocol *ops; + int proto; + int ihl; + int err = -EINVAL; + + if (unlikely(!pskb_may_pull(skb, sizeof(*iph)))) + goto out; + + iph = skb->nh.iph; + ihl = iph->ihl * 4; + if (ihl < sizeof(*iph)) + goto out; + + if (unlikely(!pskb_may_pull(skb, ihl))) + goto out; + + skb->h.raw = __skb_pull(skb, ihl); + iph = skb->nh.iph; + proto = iph->protocol & (MAX_INET_PROTOS - 1); + err = -EPROTONOSUPPORT; + + rcu_read_lock(); + ops = rcu_dereference(inet_protos[proto]); + if (likely(ops && ops->gso_send_check)) + err = ops->gso_send_check(skb); + rcu_read_unlock(); + +out: + return err; +} + static struct sk_buff *inet_gso_segment(struct sk_buff *skb, int features) { struct sk_buff *segs = ERR_PTR(-EINVAL); @@ -1162,6 +1196,7 @@ static struct net_protocol igmp_protocol = { static struct net_protocol tcp_protocol = { .handler = tcp_v4_rcv, .err_handler = tcp_v4_err, + .gso_send_check = tcp_v4_gso_send_check, .gso_segment = tcp_tso_segment, .no_policy = 1, }; @@ -1208,6 +1243,7 @@ static int ipv4_proc_init(void); static struct packet_type ip_packet_type = { .type = __constant_htons(ETH_P_IP), .func = ip_rcv, + .gso_send_check = inet_gso_send_check, .gso_segment = inet_gso_segment, }; |