aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/tcp_ipv6.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-07-26 21:09:01 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-07-26 21:09:01 -0400
commit1e30c1b3866968ff584ae3cd3909ef93957bb215 (patch)
tree0ee70a264f7bed4047f68ed3aeb68d6c4cf4e136 /net/ipv6/tcp_ipv6.c
parenta1857ebe752d77d96c89d964500a9528df6d320e (diff)
parentc7109986db3c945f50ceed884a30e0fd8af3b89b (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Pull networking updates and fixes from David Miller: 1) Reinstate the no-ref optimization for input route lookups in ipv4 to fix some routing cache removal perf regressions. 2) Make TCP socket pre-demux work on ipv6 side too, from Eric Dumazet. 3) Get RX hash value from correct place in be2net driver, from Sarveshwar Bandi. 4) Validation of FIB cached routes missing critical check, from Eric Dumazet. 5) EEH support in mlx4 driver, from Kleber Sacilotto de Souza. * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (23 commits) ipv6: Early TCP socket demux ipv4: Fix input route performance regression. pch_gbe: vlan skb len fix pch_gbe: add extra clean tx pch_gbe: fix transmit watchdog timeout ixgbe: fix panic while dumping packets on Tx hang with IOMMU be2net: Fix to parse RSS hash from Receive completions correctly. net/mlx4_en: Limit the RFS filter IDs to be < RPS_NO_FILTER hyperv: Add error handling to rndis_filter_device_add() hyperv: Add a check for ring_size value ipv4: rt_cache_valid must check expired routes net/pch_gpe: Cannot disable ethernet autonegation qeth: repair crash in qeth_l3_vlan_rx_kill_vid() netiucv: cleanup attribute usage net: wiznet add missing HAS_IOMEM dependency be2net: Missing byteswap in be_get_fw_log_level causes oops on PowerPC mlx4: Add support for EEH error recovery cdc-ncm: tag Ericsson WWAN devices (eg F5521gw) with FLAG_WWAN wanmain: comparing array with NULL caif: fix NULL pointer check ...
Diffstat (limited to 'net/ipv6/tcp_ipv6.c')
-rw-r--r--net/ipv6/tcp_ipv6.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index f49476e2d884..221224e72507 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -1674,6 +1674,43 @@ do_time_wait:
1674 goto discard_it; 1674 goto discard_it;
1675} 1675}
1676 1676
1677static void tcp_v6_early_demux(struct sk_buff *skb)
1678{
1679 const struct ipv6hdr *hdr;
1680 const struct tcphdr *th;
1681 struct sock *sk;
1682
1683 if (skb->pkt_type != PACKET_HOST)
1684 return;
1685
1686 if (!pskb_may_pull(skb, skb_transport_offset(skb) + sizeof(struct tcphdr)))
1687 return;
1688
1689 hdr = ipv6_hdr(skb);
1690 th = tcp_hdr(skb);
1691
1692 if (th->doff < sizeof(struct tcphdr) / 4)
1693 return;
1694
1695 sk = __inet6_lookup_established(dev_net(skb->dev), &tcp_hashinfo,
1696 &hdr->saddr, th->source,
1697 &hdr->daddr, ntohs(th->dest),
1698 inet6_iif(skb));
1699 if (sk) {
1700 skb->sk = sk;
1701 skb->destructor = sock_edemux;
1702 if (sk->sk_state != TCP_TIME_WAIT) {
1703 struct dst_entry *dst = sk->sk_rx_dst;
1704 struct inet_sock *icsk = inet_sk(sk);
1705 if (dst)
1706 dst = dst_check(dst, 0);
1707 if (dst &&
1708 icsk->rx_dst_ifindex == inet6_iif(skb))
1709 skb_dst_set_noref(skb, dst);
1710 }
1711 }
1712}
1713
1677static struct timewait_sock_ops tcp6_timewait_sock_ops = { 1714static struct timewait_sock_ops tcp6_timewait_sock_ops = {
1678 .twsk_obj_size = sizeof(struct tcp6_timewait_sock), 1715 .twsk_obj_size = sizeof(struct tcp6_timewait_sock),
1679 .twsk_unique = tcp_twsk_unique, 1716 .twsk_unique = tcp_twsk_unique,
@@ -1984,6 +2021,7 @@ struct proto tcpv6_prot = {
1984}; 2021};
1985 2022
1986static const struct inet6_protocol tcpv6_protocol = { 2023static const struct inet6_protocol tcpv6_protocol = {
2024 .early_demux = tcp_v6_early_demux,
1987 .handler = tcp_v6_rcv, 2025 .handler = tcp_v6_rcv,
1988 .err_handler = tcp_v6_err, 2026 .err_handler = tcp_v6_err,
1989 .gso_send_check = tcp_v6_gso_send_check, 2027 .gso_send_check = tcp_v6_gso_send_check,