aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_fastopen.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-03-19 13:05:34 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-03-19 13:05:34 -0400
commit1200b6809dfd9d73bc4c7db76d288c35fa4b2ebe (patch)
tree552e03de245cdbd0780ca1215914edc4a26540f7 /net/ipv4/tcp_fastopen.c
parent6b5f04b6cf8ebab9a65d9c0026c650bb2538fd0f (diff)
parentfe30937b65354c7fec244caebbdaae68e28ca797 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
Pull networking updates from David Miller: "Highlights: 1) Support more Realtek wireless chips, from Jes Sorenson. 2) New BPF types for per-cpu hash and arrap maps, from Alexei Starovoitov. 3) Make several TCP sysctls per-namespace, from Nikolay Borisov. 4) Allow the use of SO_REUSEPORT in order to do per-thread processing of incoming TCP/UDP connections. The muxing can be done using a BPF program which hashes the incoming packet. From Craig Gallek. 5) Add a multiplexer for TCP streams, to provide a messaged based interface. BPF programs can be used to determine the message boundaries. From Tom Herbert. 6) Add 802.1AE MACSEC support, from Sabrina Dubroca. 7) Avoid factorial complexity when taking down an inetdev interface with lots of configured addresses. We were doing things like traversing the entire address less for each address removed, and flushing the entire netfilter conntrack table for every address as well. 8) Add and use SKB bulk free infrastructure, from Jesper Brouer. 9) Allow offloading u32 classifiers to hardware, and implement for ixgbe, from John Fastabend. 10) Allow configuring IRQ coalescing parameters on a per-queue basis, from Kan Liang. 11) Extend ethtool so that larger link mode masks can be supported. From David Decotigny. 12) Introduce devlink, which can be used to configure port link types (ethernet vs Infiniband, etc.), port splitting, and switch device level attributes as a whole. From Jiri Pirko. 13) Hardware offload support for flower classifiers, from Amir Vadai. 14) Add "Local Checksum Offload". Basically, for a tunneled packet the checksum of the outer header is 'constant' (because with the checksum field filled into the inner protocol header, the payload of the outer frame checksums to 'zero'), and we can take advantage of that in various ways. From Edward Cree" * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (1548 commits) bonding: fix bond_get_stats() net: bcmgenet: fix dma api length mismatch net/mlx4_core: Fix backward compatibility on VFs phy: mdio-thunder: Fix some Kconfig typos lan78xx: add ndo_get_stats64 lan78xx: handle statistics counter rollover RDS: TCP: Remove unused constant RDS: TCP: Add sysctl tunables for sndbuf/rcvbuf on rds-tcp socket net: smc911x: convert pxa dma to dmaengine team: remove duplicate set of flag IFF_MULTICAST bonding: remove duplicate set of flag IFF_MULTICAST net: fix a comment typo ethernet: micrel: fix some error codes ip_tunnels, bpf: define IP_TUNNEL_OPTS_MAX and use it bpf, dst: add and use dst_tclassid helper bpf: make skb->tc_classid also readable net: mvneta: bm: clarify dependencies cls_bpf: reset class and reuse major in da ldmvsw: Checkpatch sunvnet.c and sunvnet_common.c ldmvsw: Add ldmvsw.c driver code ...
Diffstat (limited to 'net/ipv4/tcp_fastopen.c')
-rw-r--r--net/ipv4/tcp_fastopen.c78
1 files changed, 48 insertions, 30 deletions
diff --git a/net/ipv4/tcp_fastopen.c b/net/ipv4/tcp_fastopen.c
index 4c65ca1a86d1..cffd8f9ed1a9 100644
--- a/net/ipv4/tcp_fastopen.c
+++ b/net/ipv4/tcp_fastopen.c
@@ -125,6 +125,49 @@ static bool tcp_fastopen_cookie_gen(struct request_sock *req,
125 return false; 125 return false;
126} 126}
127 127
128
129/* If an incoming SYN or SYNACK frame contains a payload and/or FIN,
130 * queue this additional data / FIN.
131 */
132void tcp_fastopen_add_skb(struct sock *sk, struct sk_buff *skb)
133{
134 struct tcp_sock *tp = tcp_sk(sk);
135
136 if (TCP_SKB_CB(skb)->end_seq == tp->rcv_nxt)
137 return;
138
139 skb = skb_clone(skb, GFP_ATOMIC);
140 if (!skb)
141 return;
142
143 skb_dst_drop(skb);
144 /* segs_in has been initialized to 1 in tcp_create_openreq_child().
145 * Hence, reset segs_in to 0 before calling tcp_segs_in()
146 * to avoid double counting. Also, tcp_segs_in() expects
147 * skb->len to include the tcp_hdrlen. Hence, it should
148 * be called before __skb_pull().
149 */
150 tp->segs_in = 0;
151 tcp_segs_in(tp, skb);
152 __skb_pull(skb, tcp_hdrlen(skb));
153 skb_set_owner_r(skb, sk);
154
155 TCP_SKB_CB(skb)->seq++;
156 TCP_SKB_CB(skb)->tcp_flags &= ~TCPHDR_SYN;
157
158 tp->rcv_nxt = TCP_SKB_CB(skb)->end_seq;
159 __skb_queue_tail(&sk->sk_receive_queue, skb);
160 tp->syn_data_acked = 1;
161
162 /* u64_stats_update_begin(&tp->syncp) not needed here,
163 * as we certainly are not changing upper 32bit value (0)
164 */
165 tp->bytes_received = skb->len;
166
167 if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN)
168 tcp_fin(sk);
169}
170
128static struct sock *tcp_fastopen_create_child(struct sock *sk, 171static struct sock *tcp_fastopen_create_child(struct sock *sk,
129 struct sk_buff *skb, 172 struct sk_buff *skb,
130 struct dst_entry *dst, 173 struct dst_entry *dst,
@@ -133,7 +176,6 @@ static struct sock *tcp_fastopen_create_child(struct sock *sk,
133 struct tcp_sock *tp; 176 struct tcp_sock *tp;
134 struct request_sock_queue *queue = &inet_csk(sk)->icsk_accept_queue; 177 struct request_sock_queue *queue = &inet_csk(sk)->icsk_accept_queue;
135 struct sock *child; 178 struct sock *child;
136 u32 end_seq;
137 bool own_req; 179 bool own_req;
138 180
139 req->num_retrans = 0; 181 req->num_retrans = 0;
@@ -179,35 +221,11 @@ static struct sock *tcp_fastopen_create_child(struct sock *sk,
179 tcp_init_metrics(child); 221 tcp_init_metrics(child);
180 tcp_init_buffer_space(child); 222 tcp_init_buffer_space(child);
181 223
182 /* Queue the data carried in the SYN packet. 224 tp->rcv_nxt = TCP_SKB_CB(skb)->seq + 1;
183 * We used to play tricky games with skb_get(). 225
184 * With lockless listener, it is a dead end. 226 tcp_fastopen_add_skb(child, skb);
185 * Do not think about it. 227
186 * 228 tcp_rsk(req)->rcv_nxt = tp->rcv_nxt;
187 * XXX (TFO) - we honor a zero-payload TFO request for now,
188 * (any reason not to?) but no need to queue the skb since
189 * there is no data. How about SYN+FIN?
190 */
191 end_seq = TCP_SKB_CB(skb)->end_seq;
192 if (end_seq != TCP_SKB_CB(skb)->seq + 1) {
193 struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
194
195 if (likely(skb2)) {
196 skb_dst_drop(skb2);
197 __skb_pull(skb2, tcp_hdrlen(skb));
198 skb_set_owner_r(skb2, child);
199 __skb_queue_tail(&child->sk_receive_queue, skb2);
200 tp->syn_data_acked = 1;
201
202 /* u64_stats_update_begin(&tp->syncp) not needed here,
203 * as we certainly are not changing upper 32bit value (0)
204 */
205 tp->bytes_received = end_seq - TCP_SKB_CB(skb)->seq - 1;
206 } else {
207 end_seq = TCP_SKB_CB(skb)->seq + 1;
208 }
209 }
210 tcp_rsk(req)->rcv_nxt = tp->rcv_nxt = end_seq;
211 /* tcp_conn_request() is sending the SYNACK, 229 /* tcp_conn_request() is sending the SYNACK,
212 * and queues the child into listener accept queue. 230 * and queues the child into listener accept queue.
213 */ 231 */