* [PATCH] ipv6: Early TCP socket demux
@ 2012-07-26 10:34 Eric Dumazet
2012-07-26 21:29 ` David Miller
0 siblings, 1 reply; 3+ messages in thread
From: Eric Dumazet @ 2012-07-26 10:34 UTC (permalink / raw)
To: David Miller; +Cc: netdev
From: Eric Dumazet <edumazet@google.com>
This is the IPv6 missing bits for infratructure added in commit
41063e9dd1195 (ipv4: Early TCP socket demux.)
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
include/net/protocol.h | 2 ++
net/ipv6/ip6_input.c | 13 +++++++++++--
net/ipv6/tcp_ipv6.c | 38 ++++++++++++++++++++++++++++++++++++++
3 files changed, 51 insertions(+), 2 deletions(-)
diff --git a/include/net/protocol.h b/include/net/protocol.h
index 057f2d3..929528c 100644
--- a/include/net/protocol.h
+++ b/include/net/protocol.h
@@ -52,6 +52,8 @@ struct net_protocol {
#if IS_ENABLED(CONFIG_IPV6)
struct inet6_protocol {
+ void (*early_demux)(struct sk_buff *skb);
+
int (*handler)(struct sk_buff *skb);
void (*err_handler)(struct sk_buff *skb,
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
index 5ab923e..47975e3 100644
--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -47,9 +47,18 @@
-inline int ip6_rcv_finish( struct sk_buff *skb)
+int ip6_rcv_finish(struct sk_buff *skb)
{
- if (skb_dst(skb) == NULL)
+ if (sysctl_ip_early_demux && !skb_dst(skb)) {
+ const struct inet6_protocol *ipprot;
+
+ rcu_read_lock();
+ ipprot = rcu_dereference(inet6_protos[ipv6_hdr(skb)->nexthdr]);
+ if (ipprot && ipprot->early_demux)
+ ipprot->early_demux(skb);
+ rcu_read_unlock();
+ }
+ if (!skb_dst(skb))
ip6_route_input(skb);
return dst_input(skb);
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index f49476e..221224e 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -1674,6 +1674,43 @@ do_time_wait:
goto discard_it;
}
+static void tcp_v6_early_demux(struct sk_buff *skb)
+{
+ const struct ipv6hdr *hdr;
+ const struct tcphdr *th;
+ struct sock *sk;
+
+ if (skb->pkt_type != PACKET_HOST)
+ return;
+
+ if (!pskb_may_pull(skb, skb_transport_offset(skb) + sizeof(struct tcphdr)))
+ return;
+
+ hdr = ipv6_hdr(skb);
+ th = tcp_hdr(skb);
+
+ if (th->doff < sizeof(struct tcphdr) / 4)
+ return;
+
+ sk = __inet6_lookup_established(dev_net(skb->dev), &tcp_hashinfo,
+ &hdr->saddr, th->source,
+ &hdr->daddr, ntohs(th->dest),
+ inet6_iif(skb));
+ if (sk) {
+ skb->sk = sk;
+ skb->destructor = sock_edemux;
+ if (sk->sk_state != TCP_TIME_WAIT) {
+ struct dst_entry *dst = sk->sk_rx_dst;
+ struct inet_sock *icsk = inet_sk(sk);
+ if (dst)
+ dst = dst_check(dst, 0);
+ if (dst &&
+ icsk->rx_dst_ifindex == inet6_iif(skb))
+ skb_dst_set_noref(skb, dst);
+ }
+ }
+}
+
static struct timewait_sock_ops tcp6_timewait_sock_ops = {
.twsk_obj_size = sizeof(struct tcp6_timewait_sock),
.twsk_unique = tcp_twsk_unique,
@@ -1984,6 +2021,7 @@ struct proto tcpv6_prot = {
};
static const struct inet6_protocol tcpv6_protocol = {
+ .early_demux = tcp_v6_early_demux,
.handler = tcp_v6_rcv,
.err_handler = tcp_v6_err,
.gso_send_check = tcp_v6_gso_send_check,
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH] ipv6: Early TCP socket demux
2012-07-26 10:34 [PATCH] ipv6: Early TCP socket demux Eric Dumazet
@ 2012-07-26 21:29 ` David Miller
2012-07-26 22:12 ` Eric Dumazet
0 siblings, 1 reply; 3+ messages in thread
From: David Miller @ 2012-07-26 21:29 UTC (permalink / raw)
To: eric.dumazet; +Cc: netdev
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Thu, 26 Jul 2012 12:34:28 +0200
> + if (sysctl_ip_early_demux && !skb_dst(skb)) {
You obviously don't build ipv6 modular.
sysctl_ip_early_demux needs to be exported to modules in order
for this to work.
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] ipv6: Early TCP socket demux
2012-07-26 21:29 ` David Miller
@ 2012-07-26 22:12 ` Eric Dumazet
0 siblings, 0 replies; 3+ messages in thread
From: Eric Dumazet @ 2012-07-26 22:12 UTC (permalink / raw)
To: David Miller; +Cc: netdev
On Thu, 2012-07-26 at 14:29 -0700, David Miller wrote:
> From: Eric Dumazet <eric.dumazet@gmail.com>
> Date: Thu, 26 Jul 2012 12:34:28 +0200
>
> > + if (sysctl_ip_early_demux && !skb_dst(skb)) {
>
> You obviously don't build ipv6 modular.
>
> sysctl_ip_early_demux needs to be exported to modules in order
> for this to work.
Humpf....
I'll also remove the unlikely() in __inet6_lookup_skb() in v2
Thanks
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2012-07-26 22:13 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-07-26 10:34 [PATCH] ipv6: Early TCP socket demux Eric Dumazet
2012-07-26 21:29 ` David Miller
2012-07-26 22:12 ` Eric Dumazet
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).