diff options
Diffstat (limited to 'net/ipv4/tcp_ipv4.c')
-rw-r--r-- | net/ipv4/tcp_ipv4.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 26b9030747cc..10172487921b 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -2346,6 +2346,41 @@ void tcp4_proc_exit(void) | |||
2346 | } | 2346 | } |
2347 | #endif /* CONFIG_PROC_FS */ | 2347 | #endif /* CONFIG_PROC_FS */ |
2348 | 2348 | ||
2349 | struct sk_buff **tcp4_gro_receive(struct sk_buff **head, struct sk_buff *skb) | ||
2350 | { | ||
2351 | struct iphdr *iph = ip_hdr(skb); | ||
2352 | |||
2353 | switch (skb->ip_summed) { | ||
2354 | case CHECKSUM_COMPLETE: | ||
2355 | if (!tcp_v4_check(skb->len, iph->saddr, iph->daddr, | ||
2356 | skb->csum)) { | ||
2357 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
2358 | break; | ||
2359 | } | ||
2360 | |||
2361 | /* fall through */ | ||
2362 | case CHECKSUM_NONE: | ||
2363 | NAPI_GRO_CB(skb)->flush = 1; | ||
2364 | return NULL; | ||
2365 | } | ||
2366 | |||
2367 | return tcp_gro_receive(head, skb); | ||
2368 | } | ||
2369 | EXPORT_SYMBOL(tcp4_gro_receive); | ||
2370 | |||
2371 | int tcp4_gro_complete(struct sk_buff *skb) | ||
2372 | { | ||
2373 | struct iphdr *iph = ip_hdr(skb); | ||
2374 | struct tcphdr *th = tcp_hdr(skb); | ||
2375 | |||
2376 | th->check = ~tcp_v4_check(skb->len - skb_transport_offset(skb), | ||
2377 | iph->saddr, iph->daddr, 0); | ||
2378 | skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4; | ||
2379 | |||
2380 | return tcp_gro_complete(skb); | ||
2381 | } | ||
2382 | EXPORT_SYMBOL(tcp4_gro_complete); | ||
2383 | |||
2349 | struct proto tcp_prot = { | 2384 | struct proto tcp_prot = { |
2350 | .name = "TCP", | 2385 | .name = "TCP", |
2351 | .owner = THIS_MODULE, | 2386 | .owner = THIS_MODULE, |