aboutsummaryrefslogtreecommitdiffstats
path: root/include/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2012-06-20 00:22:05 -0400
committerDavid S. Miller <davem@davemloft.net>2012-06-20 00:22:05 -0400
commit41063e9dd11956f2d285e12e4342e1d232ba0ea2 (patch)
treed4df2f51044b4724a4767f0498c3df2f606b5ad7 /include/net
parentf9242b6b28d61295f2bf7e8adfb1060b382e5381 (diff)
ipv4: Early TCP socket demux.
Input packet processing for local sockets involves two major demuxes. One for the route and one for the socket. But we can optimize this down to one demux for certain kinds of local sockets. Currently we only do this for established TCP sockets, but it could at least in theory be expanded to other kinds of connections. If a TCP socket is established then it's identity is fully specified. This means that whatever input route was used during the three-way handshake must work equally well for the rest of the connection since the keys will not change. Once we move to established state, we cache the receive packet's input route to use later. Like the existing cached route in sk->sk_dst_cache used for output packets, we have to check for route invalidations using dst->obsolete and dst->ops->check(). Early demux occurs outside of a socket locked section, so when a route invalidation occurs we defer the fixup of sk->sk_rx_dst until we are actually inside of established state packet processing and thus have the socket locked. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/net')
-rw-r--r--include/net/inet_hashtables.h4
-rw-r--r--include/net/protocol.h1
-rw-r--r--include/net/sock.h2
-rw-r--r--include/net/tcp.h1
4 files changed, 6 insertions, 2 deletions
diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h
index 808fc5f76b03..54be0287eb98 100644
--- a/include/net/inet_hashtables.h
+++ b/include/net/inet_hashtables.h
@@ -379,10 +379,10 @@ static inline struct sock *__inet_lookup_skb(struct inet_hashinfo *hashinfo,
379 const __be16 sport, 379 const __be16 sport,
380 const __be16 dport) 380 const __be16 dport)
381{ 381{
382 struct sock *sk; 382 struct sock *sk = skb_steal_sock(skb);
383 const struct iphdr *iph = ip_hdr(skb); 383 const struct iphdr *iph = ip_hdr(skb);
384 384
385 if (unlikely(sk = skb_steal_sock(skb))) 385 if (sk)
386 return sk; 386 return sk;
387 else 387 else
388 return __inet_lookup(dev_net(skb_dst(skb)->dev), hashinfo, 388 return __inet_lookup(dev_net(skb_dst(skb)->dev), hashinfo,
diff --git a/include/net/protocol.h b/include/net/protocol.h
index a1b1b530c338..967b926cbfb1 100644
--- a/include/net/protocol.h
+++ b/include/net/protocol.h
@@ -37,6 +37,7 @@
37 37
38/* This is used to register protocols. */ 38/* This is used to register protocols. */
39struct net_protocol { 39struct net_protocol {
40 int (*early_demux)(struct sk_buff *skb);
40 int (*handler)(struct sk_buff *skb); 41 int (*handler)(struct sk_buff *skb);
41 void (*err_handler)(struct sk_buff *skb, u32 info); 42 void (*err_handler)(struct sk_buff *skb, u32 info);
42 int (*gso_send_check)(struct sk_buff *skb); 43 int (*gso_send_check)(struct sk_buff *skb);
diff --git a/include/net/sock.h b/include/net/sock.h
index 4a4521699563..87b424ae750a 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -319,6 +319,7 @@ struct sock {
319 unsigned long sk_flags; 319 unsigned long sk_flags;
320 struct dst_entry *sk_dst_cache; 320 struct dst_entry *sk_dst_cache;
321 spinlock_t sk_dst_lock; 321 spinlock_t sk_dst_lock;
322 struct dst_entry *sk_rx_dst;
322 atomic_t sk_wmem_alloc; 323 atomic_t sk_wmem_alloc;
323 atomic_t sk_omem_alloc; 324 atomic_t sk_omem_alloc;
324 int sk_sndbuf; 325 int sk_sndbuf;
@@ -1426,6 +1427,7 @@ extern struct sk_buff *sock_rmalloc(struct sock *sk,
1426 gfp_t priority); 1427 gfp_t priority);
1427extern void sock_wfree(struct sk_buff *skb); 1428extern void sock_wfree(struct sk_buff *skb);
1428extern void sock_rfree(struct sk_buff *skb); 1429extern void sock_rfree(struct sk_buff *skb);
1430extern void sock_edemux(struct sk_buff *skb);
1429 1431
1430extern int sock_setsockopt(struct socket *sock, int level, 1432extern int sock_setsockopt(struct socket *sock, int level,
1431 int op, char __user *optval, 1433 int op, char __user *optval,
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 9332f342259a..6660ffc4963d 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -325,6 +325,7 @@ extern void tcp_v4_err(struct sk_buff *skb, u32);
325 325
326extern void tcp_shutdown (struct sock *sk, int how); 326extern void tcp_shutdown (struct sock *sk, int how);
327 327
328extern int tcp_v4_early_demux(struct sk_buff *skb);
328extern int tcp_v4_rcv(struct sk_buff *skb); 329extern int tcp_v4_rcv(struct sk_buff *skb);
329 330
330extern struct inet_peer *tcp_v4_get_peer(struct sock *sk); 331extern struct inet_peer *tcp_v4_get_peer(struct sock *sk);