blob: 984a8d1a33594ede7106d7b6fea7a4b157e252a0 [file] [log] [blame]
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -08001/* (C) 1999-2001 Paul `Rusty' Russell
2 * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
Patrick McHardyf229f6c2013-04-06 15:24:29 +02003 * (C) 2002-2013 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
4 * (C) 2006-2012 Patrick McHardy <kaber@trash.net>
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -08005 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -08009 */
10
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -080011#include <linux/types.h>
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -080012#include <linux/timer.h>
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -080013#include <linux/module.h>
14#include <linux/in.h>
15#include <linux/tcp.h>
16#include <linux/spinlock.h>
17#include <linux/skbuff.h>
18#include <linux/ipv6.h>
19#include <net/ip6_checksum.h>
Mark H. Weaver534f81a2009-03-23 13:46:12 +010020#include <asm/unaligned.h>
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -080021
22#include <net/tcp.h>
23
24#include <linux/netfilter.h>
25#include <linux/netfilter_ipv4.h>
26#include <linux/netfilter_ipv6.h>
27#include <net/netfilter/nf_conntrack.h>
Martin Josefsson605dcad2006-11-29 02:35:06 +010028#include <net/netfilter/nf_conntrack_l4proto.h>
Martin Josefssonf6180122006-11-29 02:35:01 +010029#include <net/netfilter/nf_conntrack_ecache.h>
Patrick McHardy41d73ec2013-08-27 08:50:12 +020030#include <net/netfilter/nf_conntrack_seqadj.h>
Patrick McHardyf01ffbd2007-12-17 22:38:49 -080031#include <net/netfilter/nf_log.h>
Christoph Paasch9d2493f2009-03-16 15:15:35 +010032#include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
33#include <net/netfilter/ipv6/nf_conntrack_ipv6.h>
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -080034
YOSHIFUJI Hideaki601e68e2007-02-12 11:15:49 -080035/* "Be conservative in what you do,
36 be liberal in what you accept from others."
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -080037 If it's non-zero, we mark only out of window RST segments as INVALID. */
Patrick McHardy3aef0fd2007-02-12 11:16:58 -080038static int nf_ct_tcp_be_liberal __read_mostly = 0;
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -080039
Patrick McHardya09113c2007-02-07 15:05:33 -080040/* If it is set to zero, we disable picking up already established
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -080041 connections. */
Patrick McHardy3aef0fd2007-02-12 11:16:58 -080042static int nf_ct_tcp_loose __read_mostly = 1;
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -080043
YOSHIFUJI Hideaki601e68e2007-02-12 11:15:49 -080044/* Max number of the retransmitted packets without receiving an (acceptable)
45 ACK from the destination. If this number is reached, a shorter timer
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -080046 will be started. */
Patrick McHardy3aef0fd2007-02-12 11:16:58 -080047static int nf_ct_tcp_max_retrans __read_mostly = 3;
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -080048
49 /* FIXME: Examine ipfilter's timeouts and conntrack transitions more
50 closely. They're more complex. --RR */
51
Jan Engelhardt82f568f2008-01-31 04:52:07 -080052static const char *const tcp_conntrack_names[] = {
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -080053 "NONE",
54 "SYN_SENT",
55 "SYN_RECV",
56 "ESTABLISHED",
57 "FIN_WAIT",
58 "CLOSE_WAIT",
59 "LAST_ACK",
60 "TIME_WAIT",
61 "CLOSE",
Jozsef Kadlecsik874ab922009-06-02 13:58:56 +020062 "SYN_SENT2",
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -080063};
YOSHIFUJI Hideaki601e68e2007-02-12 11:15:49 -080064
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -080065#define SECS * HZ
66#define MINS * 60 SECS
67#define HOURS * 60 MINS
68#define DAYS * 24 HOURS
69
Pablo Neira Ayuso33ee4462012-02-28 16:56:31 +010070static unsigned int tcp_timeouts[TCP_CONNTRACK_TIMEOUT_MAX] __read_mostly = {
Patrick McHardy2d646282008-01-14 23:45:32 -080071 [TCP_CONNTRACK_SYN_SENT] = 2 MINS,
72 [TCP_CONNTRACK_SYN_RECV] = 60 SECS,
73 [TCP_CONNTRACK_ESTABLISHED] = 5 DAYS,
74 [TCP_CONNTRACK_FIN_WAIT] = 2 MINS,
75 [TCP_CONNTRACK_CLOSE_WAIT] = 60 SECS,
76 [TCP_CONNTRACK_LAST_ACK] = 30 SECS,
77 [TCP_CONNTRACK_TIME_WAIT] = 2 MINS,
78 [TCP_CONNTRACK_CLOSE] = 10 SECS,
Jozsef Kadlecsik874ab922009-06-02 13:58:56 +020079 [TCP_CONNTRACK_SYN_SENT2] = 2 MINS,
Pablo Neira Ayuso33ee4462012-02-28 16:56:31 +010080/* RFC1122 says the R2 limit should be at least 100 seconds.
81 Linux uses 15 packets as limit, which corresponds
82 to ~13-30min depending on RTO. */
83 [TCP_CONNTRACK_RETRANS] = 5 MINS,
84 [TCP_CONNTRACK_UNACK] = 5 MINS,
Patrick McHardy2d646282008-01-14 23:45:32 -080085};
YOSHIFUJI Hideaki601e68e2007-02-12 11:15:49 -080086
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -080087#define sNO TCP_CONNTRACK_NONE
88#define sSS TCP_CONNTRACK_SYN_SENT
89#define sSR TCP_CONNTRACK_SYN_RECV
90#define sES TCP_CONNTRACK_ESTABLISHED
91#define sFW TCP_CONNTRACK_FIN_WAIT
92#define sCW TCP_CONNTRACK_CLOSE_WAIT
93#define sLA TCP_CONNTRACK_LAST_ACK
94#define sTW TCP_CONNTRACK_TIME_WAIT
95#define sCL TCP_CONNTRACK_CLOSE
Jozsef Kadlecsik874ab922009-06-02 13:58:56 +020096#define sS2 TCP_CONNTRACK_SYN_SENT2
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -080097#define sIV TCP_CONNTRACK_MAX
98#define sIG TCP_CONNTRACK_IGNORE
99
100/* What TCP flags are set from RST/SYN/FIN/ACK. */
101enum tcp_bit_set {
102 TCP_SYN_SET,
103 TCP_SYNACK_SET,
104 TCP_FIN_SET,
105 TCP_ACK_SET,
106 TCP_RST_SET,
107 TCP_NONE_SET,
108};
YOSHIFUJI Hideaki601e68e2007-02-12 11:15:49 -0800109
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800110/*
111 * The TCP state transition table needs a few words...
112 *
113 * We are the man in the middle. All the packets go through us
114 * but might get lost in transit to the destination.
YOSHIFUJI Hideaki601e68e2007-02-12 11:15:49 -0800115 * It is assumed that the destinations can't receive segments
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800116 * we haven't seen.
117 *
118 * The checked segment is in window, but our windows are *not*
119 * equivalent with the ones of the sender/receiver. We always
120 * try to guess the state of the current sender.
121 *
122 * The meaning of the states are:
123 *
124 * NONE: initial state
YOSHIFUJI Hideaki601e68e2007-02-12 11:15:49 -0800125 * SYN_SENT: SYN-only packet seen
Jozsef Kadlecsik874ab922009-06-02 13:58:56 +0200126 * SYN_SENT2: SYN-only packet seen from reply dir, simultaneous open
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800127 * SYN_RECV: SYN-ACK packet seen
128 * ESTABLISHED: ACK packet seen
129 * FIN_WAIT: FIN packet seen
YOSHIFUJI Hideaki601e68e2007-02-12 11:15:49 -0800130 * CLOSE_WAIT: ACK seen (after FIN)
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800131 * LAST_ACK: FIN seen (after FIN)
132 * TIME_WAIT: last ACK seen
Jozsef Kadlecsikb2155e72008-02-07 17:54:56 -0800133 * CLOSE: closed connection (RST)
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800134 *
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800135 * Packets marked as IGNORED (sIG):
YOSHIFUJI Hideaki601e68e2007-02-12 11:15:49 -0800136 * if they may be either invalid or valid
137 * and the receiver may send back a connection
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800138 * closing RST or a SYN/ACK.
139 *
140 * Packets marked as INVALID (sIV):
Jozsef Kadlecsik874ab922009-06-02 13:58:56 +0200141 * if we regard them as truly invalid packets
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800142 */
Patrick McHardya5e73c22008-01-14 23:45:11 -0800143static const u8 tcp_conntracks[2][6][TCP_CONNTRACK_MAX] = {
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800144 {
145/* ORIGINAL */
Jozsef Kadlecsik874ab922009-06-02 13:58:56 +0200146/* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sS2 */
147/*syn*/ { sSS, sSS, sIG, sIG, sIG, sIG, sIG, sSS, sSS, sS2 },
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800148/*
149 * sNO -> sSS Initialize a new connection
150 * sSS -> sSS Retransmitted SYN
Jozsef Kadlecsik874ab922009-06-02 13:58:56 +0200151 * sS2 -> sS2 Late retransmitted SYN
152 * sSR -> sIG
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800153 * sES -> sIG Error: SYNs in window outside the SYN_SENT state
YOSHIFUJI Hideaki601e68e2007-02-12 11:15:49 -0800154 * are errors. Receiver will reply with RST
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800155 * and close the connection.
156 * Or we are not in sync and hold a dead connection.
157 * sFW -> sIG
158 * sCW -> sIG
159 * sLA -> sIG
160 * sTW -> sSS Reopened connection (RFC 1122).
161 * sCL -> sSS
162 */
Jozsef Kadlecsik874ab922009-06-02 13:58:56 +0200163/* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sS2 */
Jozsef Kadlecsik64f509c2012-08-31 09:55:53 +0000164/*synack*/ { sIV, sIV, sSR, sIV, sIV, sIV, sIV, sIV, sIV, sSR },
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800165/*
Jozsef Kadlecsik874ab922009-06-02 13:58:56 +0200166 * sNO -> sIV Too late and no reason to do anything
167 * sSS -> sIV Client can't send SYN and then SYN/ACK
168 * sS2 -> sSR SYN/ACK sent to SYN2 in simultaneous open
Jozsef Kadlecsik64f509c2012-08-31 09:55:53 +0000169 * sSR -> sSR Late retransmitted SYN/ACK in simultaneous open
170 * sES -> sIV Invalid SYN/ACK packets sent by the client
171 * sFW -> sIV
172 * sCW -> sIV
173 * sLA -> sIV
174 * sTW -> sIV
175 * sCL -> sIV
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800176 */
Jozsef Kadlecsik874ab922009-06-02 13:58:56 +0200177/* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sS2 */
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800178/*fin*/ { sIV, sIV, sFW, sFW, sLA, sLA, sLA, sTW, sCL, sIV },
179/*
180 * sNO -> sIV Too late and no reason to do anything...
181 * sSS -> sIV Client migth not send FIN in this state:
182 * we enforce waiting for a SYN/ACK reply first.
Jozsef Kadlecsik874ab922009-06-02 13:58:56 +0200183 * sS2 -> sIV
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800184 * sSR -> sFW Close started.
185 * sES -> sFW
186 * sFW -> sLA FIN seen in both directions, waiting for
YOSHIFUJI Hideaki601e68e2007-02-12 11:15:49 -0800187 * the last ACK.
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800188 * Migth be a retransmitted FIN as well...
189 * sCW -> sLA
190 * sLA -> sLA Retransmitted FIN. Remain in the same state.
191 * sTW -> sTW
192 * sCL -> sCL
193 */
Jozsef Kadlecsik874ab922009-06-02 13:58:56 +0200194/* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sS2 */
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800195/*ack*/ { sES, sIV, sES, sES, sCW, sCW, sTW, sTW, sCL, sIV },
196/*
197 * sNO -> sES Assumed.
198 * sSS -> sIV ACK is invalid: we haven't seen a SYN/ACK yet.
Jozsef Kadlecsik874ab922009-06-02 13:58:56 +0200199 * sS2 -> sIV
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800200 * sSR -> sES Established state is reached.
201 * sES -> sES :-)
202 * sFW -> sCW Normal close request answered by ACK.
203 * sCW -> sCW
204 * sLA -> sTW Last ACK detected.
205 * sTW -> sTW Retransmitted last ACK. Remain in the same state.
206 * sCL -> sCL
207 */
Jozsef Kadlecsik874ab922009-06-02 13:58:56 +0200208/* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sS2 */
209/*rst*/ { sIV, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL },
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800210/*none*/ { sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV }
211 },
212 {
213/* REPLY */
Jozsef Kadlecsik874ab922009-06-02 13:58:56 +0200214/* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sS2 */
215/*syn*/ { sIV, sS2, sIV, sIV, sIV, sIV, sIV, sIV, sIV, sS2 },
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800216/*
217 * sNO -> sIV Never reached.
Jozsef Kadlecsik874ab922009-06-02 13:58:56 +0200218 * sSS -> sS2 Simultaneous open
219 * sS2 -> sS2 Retransmitted simultaneous SYN
220 * sSR -> sIV Invalid SYN packets sent by the server
221 * sES -> sIV
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800222 * sFW -> sIV
223 * sCW -> sIV
224 * sLA -> sIV
225 * sTW -> sIV Reopened connection, but server may not do it.
226 * sCL -> sIV
227 */
Jozsef Kadlecsik874ab922009-06-02 13:58:56 +0200228/* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sS2 */
Pablo Neira Ayuso8a80c792011-02-28 17:59:15 +0100229/*synack*/ { sIV, sSR, sIG, sIG, sIG, sIG, sIG, sIG, sIG, sSR },
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800230/*
231 * sSS -> sSR Standard open.
Jozsef Kadlecsik874ab922009-06-02 13:58:56 +0200232 * sS2 -> sSR Simultaneous open
Pablo Neira Ayuso8a80c792011-02-28 17:59:15 +0100233 * sSR -> sIG Retransmitted SYN/ACK, ignore it.
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800234 * sES -> sIG Late retransmitted SYN/ACK?
235 * sFW -> sIG Might be SYN/ACK answering ignored SYN
236 * sCW -> sIG
237 * sLA -> sIG
238 * sTW -> sIG
239 * sCL -> sIG
240 */
Jozsef Kadlecsik874ab922009-06-02 13:58:56 +0200241/* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sS2 */
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800242/*fin*/ { sIV, sIV, sFW, sFW, sLA, sLA, sLA, sTW, sCL, sIV },
243/*
244 * sSS -> sIV Server might not send FIN in this state.
Jozsef Kadlecsik874ab922009-06-02 13:58:56 +0200245 * sS2 -> sIV
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800246 * sSR -> sFW Close started.
247 * sES -> sFW
248 * sFW -> sLA FIN seen in both directions.
249 * sCW -> sLA
250 * sLA -> sLA Retransmitted FIN.
251 * sTW -> sTW
252 * sCL -> sCL
253 */
Jozsef Kadlecsik874ab922009-06-02 13:58:56 +0200254/* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sS2 */
255/*ack*/ { sIV, sIG, sSR, sES, sCW, sCW, sTW, sTW, sCL, sIG },
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800256/*
Jozsef Kadlecsik73f30602005-12-01 14:28:58 -0800257 * sSS -> sIG Might be a half-open connection.
Jozsef Kadlecsik874ab922009-06-02 13:58:56 +0200258 * sS2 -> sIG
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800259 * sSR -> sSR Might answer late resent SYN.
260 * sES -> sES :-)
261 * sFW -> sCW Normal close request answered by ACK.
262 * sCW -> sCW
263 * sLA -> sTW Last ACK detected.
264 * sTW -> sTW Retransmitted last ACK.
265 * sCL -> sCL
266 */
Jozsef Kadlecsik874ab922009-06-02 13:58:56 +0200267/* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sS2 */
268/*rst*/ { sIV, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL },
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800269/*none*/ { sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV }
YOSHIFUJI Hideaki601e68e2007-02-12 11:15:49 -0800270 }
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800271};
272
Gao fengd2ba1fd2012-05-28 21:04:12 +0000273static inline struct nf_tcp_net *tcp_pernet(struct net *net)
274{
275 return &net->ct.nf_ct_proto.tcp;
276}
277
Jan Engelhardt09f263c2008-04-14 11:15:53 +0200278static bool tcp_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff,
279 struct nf_conntrack_tuple *tuple)
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800280{
Jan Engelhardt82f568f2008-01-31 04:52:07 -0800281 const struct tcphdr *hp;
282 struct tcphdr _hdr;
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800283
284 /* Actually only need first 8 bytes. */
285 hp = skb_header_pointer(skb, dataoff, 8, &_hdr);
286 if (hp == NULL)
Jan Engelhardt09f263c2008-04-14 11:15:53 +0200287 return false;
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800288
289 tuple->src.u.tcp.port = hp->source;
290 tuple->dst.u.tcp.port = hp->dest;
291
Jan Engelhardt09f263c2008-04-14 11:15:53 +0200292 return true;
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800293}
294
Jan Engelhardt09f263c2008-04-14 11:15:53 +0200295static bool tcp_invert_tuple(struct nf_conntrack_tuple *tuple,
296 const struct nf_conntrack_tuple *orig)
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800297{
298 tuple->src.u.tcp.port = orig->dst.u.tcp.port;
299 tuple->dst.u.tcp.port = orig->src.u.tcp.port;
Jan Engelhardt09f263c2008-04-14 11:15:53 +0200300 return true;
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800301}
302
303/* Print out the per-protocol part of the tuple. */
304static int tcp_print_tuple(struct seq_file *s,
305 const struct nf_conntrack_tuple *tuple)
306{
307 return seq_printf(s, "sport=%hu dport=%hu ",
308 ntohs(tuple->src.u.tcp.port),
309 ntohs(tuple->dst.u.tcp.port));
310}
311
312/* Print out the private part of the conntrack. */
Patrick McHardy440f0d52009-06-10 14:32:47 +0200313static int tcp_print_conntrack(struct seq_file *s, struct nf_conn *ct)
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800314{
315 enum tcp_conntrack state;
316
Patrick McHardy440f0d52009-06-10 14:32:47 +0200317 spin_lock_bh(&ct->lock);
Patrick McHardyc88130b2008-01-31 04:42:11 -0800318 state = ct->proto.tcp.state;
Patrick McHardy440f0d52009-06-10 14:32:47 +0200319 spin_unlock_bh(&ct->lock);
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800320
321 return seq_printf(s, "%s ", tcp_conntrack_names[state]);
322}
323
324static unsigned int get_conntrack_index(const struct tcphdr *tcph)
325{
326 if (tcph->rst) return TCP_RST_SET;
327 else if (tcph->syn) return (tcph->ack ? TCP_SYNACK_SET : TCP_SYN_SET);
328 else if (tcph->fin) return TCP_FIN_SET;
329 else if (tcph->ack) return TCP_ACK_SET;
330 else return TCP_NONE_SET;
331}
332
333/* TCP connection tracking based on 'Real Stateful TCP Packet Filtering
334 in IP Filter' by Guido van Rooij.
YOSHIFUJI Hideaki601e68e2007-02-12 11:15:49 -0800335
Justin P. Mattock631dd1a2010-10-18 11:03:14 +0200336 http://www.sane.nl/events/sane2000/papers.html
337 http://www.darkart.com/mirrors/www.obfuscation.org/ipf/
YOSHIFUJI Hideaki601e68e2007-02-12 11:15:49 -0800338
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800339 The boundaries and the conditions are changed according to RFC793:
340 the packet must intersect the window (i.e. segments may be
341 after the right or before the left edge) and thus receivers may ACK
342 segments after the right edge of the window.
343
YOSHIFUJI Hideaki601e68e2007-02-12 11:15:49 -0800344 td_maxend = max(sack + max(win,1)) seen in reply packets
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800345 td_maxwin = max(max(win, 1)) + (sack - ack) seen in sent packets
346 td_maxwin += seq + len - sender.td_maxend
347 if seq + len > sender.td_maxend
348 td_end = max(seq + len) seen in sent packets
YOSHIFUJI Hideaki601e68e2007-02-12 11:15:49 -0800349
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800350 I. Upper bound for valid data: seq <= sender.td_maxend
351 II. Lower bound for valid data: seq + len >= sender.td_end - receiver.td_maxwin
Jozsef Kadlecsik84ebe1c2008-06-30 12:41:30 -0700352 III. Upper bound for valid (s)ack: sack <= receiver.td_end
353 IV. Lower bound for valid (s)ack: sack >= receiver.td_end - MAXACKWINDOW
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800354
Jozsef Kadlecsik84ebe1c2008-06-30 12:41:30 -0700355 where sack is the highest right edge of sack block found in the packet
356 or ack in the case of packet without SACK option.
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800357
Jozsef Kadlecsik84ebe1c2008-06-30 12:41:30 -0700358 The upper bound limit for a valid (s)ack is not ignored -
YOSHIFUJI Hideaki601e68e2007-02-12 11:15:49 -0800359 we doesn't have to deal with fragments.
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800360*/
361
362static inline __u32 segment_seq_plus_len(__u32 seq,
363 size_t len,
364 unsigned int dataoff,
Jan Engelhardt82f568f2008-01-31 04:52:07 -0800365 const struct tcphdr *tcph)
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800366{
367 /* XXX Should I use payload length field in IP/IPv6 header ?
368 * - YK */
369 return (seq + len - dataoff - tcph->doff*4
370 + (tcph->syn ? 1 : 0) + (tcph->fin ? 1 : 0));
371}
YOSHIFUJI Hideaki601e68e2007-02-12 11:15:49 -0800372
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800373/* Fixme: what about big packets? */
374#define MAXACKWINCONST 66000
375#define MAXACKWINDOW(sender) \
376 ((sender)->td_maxwin > MAXACKWINCONST ? (sender)->td_maxwin \
377 : MAXACKWINCONST)
YOSHIFUJI Hideaki601e68e2007-02-12 11:15:49 -0800378
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800379/*
380 * Simplified tcp_parse_options routine from tcp_input.c
381 */
382static void tcp_options(const struct sk_buff *skb,
383 unsigned int dataoff,
Jan Engelhardt82f568f2008-01-31 04:52:07 -0800384 const struct tcphdr *tcph,
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800385 struct ip_ct_tcp_state *state)
386{
387 unsigned char buff[(15 * 4) - sizeof(struct tcphdr)];
Jan Engelhardt82f568f2008-01-31 04:52:07 -0800388 const unsigned char *ptr;
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800389 int length = (tcph->doff*4) - sizeof(struct tcphdr);
390
391 if (!length)
392 return;
393
394 ptr = skb_header_pointer(skb, dataoff + sizeof(struct tcphdr),
395 length, buff);
396 BUG_ON(ptr == NULL);
397
YOSHIFUJI Hideaki601e68e2007-02-12 11:15:49 -0800398 state->td_scale =
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800399 state->flags = 0;
400
401 while (length > 0) {
402 int opcode=*ptr++;
403 int opsize;
404
405 switch (opcode) {
406 case TCPOPT_EOL:
407 return;
408 case TCPOPT_NOP: /* Ref: RFC 793 section 3.1 */
409 length--;
410 continue;
411 default:
412 opsize=*ptr++;
413 if (opsize < 2) /* "silly options" */
414 return;
415 if (opsize > length)
Jozsef Kadlecsik4a5cc84a2011-08-30 15:45:10 +0200416 return; /* don't parse partial options */
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800417
YOSHIFUJI Hideaki601e68e2007-02-12 11:15:49 -0800418 if (opcode == TCPOPT_SACK_PERM
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800419 && opsize == TCPOLEN_SACK_PERM)
420 state->flags |= IP_CT_TCP_FLAG_SACK_PERM;
421 else if (opcode == TCPOPT_WINDOW
422 && opsize == TCPOLEN_WINDOW) {
423 state->td_scale = *(u_int8_t *)ptr;
424
425 if (state->td_scale > 14) {
426 /* See RFC1323 */
427 state->td_scale = 14;
428 }
429 state->flags |=
430 IP_CT_TCP_FLAG_WINDOW_SCALE;
431 }
432 ptr += opsize - 2;
433 length -= opsize;
434 }
435 }
436}
437
438static void tcp_sack(const struct sk_buff *skb, unsigned int dataoff,
Jan Engelhardt82f568f2008-01-31 04:52:07 -0800439 const struct tcphdr *tcph, __u32 *sack)
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800440{
YOSHIFUJI Hideaki601e68e2007-02-12 11:15:49 -0800441 unsigned char buff[(15 * 4) - sizeof(struct tcphdr)];
Jan Engelhardt82f568f2008-01-31 04:52:07 -0800442 const unsigned char *ptr;
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800443 int length = (tcph->doff*4) - sizeof(struct tcphdr);
444 __u32 tmp;
445
446 if (!length)
447 return;
448
449 ptr = skb_header_pointer(skb, dataoff + sizeof(struct tcphdr),
450 length, buff);
451 BUG_ON(ptr == NULL);
452
453 /* Fast path for timestamp-only option */
Jozsef Kadlecsikbb9fc372011-08-30 15:46:13 +0200454 if (length == TCPOLEN_TSTAMP_ALIGNED
YOSHIFUJI Hideaki8f05ce92007-03-07 14:21:00 +0900455 && *(__be32 *)ptr == htonl((TCPOPT_NOP << 24)
456 | (TCPOPT_NOP << 16)
457 | (TCPOPT_TIMESTAMP << 8)
458 | TCPOLEN_TIMESTAMP))
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800459 return;
460
461 while (length > 0) {
462 int opcode = *ptr++;
463 int opsize, i;
464
465 switch (opcode) {
466 case TCPOPT_EOL:
467 return;
468 case TCPOPT_NOP: /* Ref: RFC 793 section 3.1 */
469 length--;
470 continue;
471 default:
472 opsize = *ptr++;
473 if (opsize < 2) /* "silly options" */
474 return;
475 if (opsize > length)
Jozsef Kadlecsik4a5cc84a2011-08-30 15:45:10 +0200476 return; /* don't parse partial options */
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800477
YOSHIFUJI Hideaki601e68e2007-02-12 11:15:49 -0800478 if (opcode == TCPOPT_SACK
479 && opsize >= (TCPOLEN_SACK_BASE
480 + TCPOLEN_SACK_PERBLOCK)
481 && !((opsize - TCPOLEN_SACK_BASE)
482 % TCPOLEN_SACK_PERBLOCK)) {
483 for (i = 0;
484 i < (opsize - TCPOLEN_SACK_BASE);
485 i += TCPOLEN_SACK_PERBLOCK) {
Mark H. Weaver534f81a2009-03-23 13:46:12 +0100486 tmp = get_unaligned_be32((__be32 *)(ptr+i)+1);
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800487
488 if (after(tmp, *sack))
489 *sack = tmp;
490 }
491 return;
492 }
493 ptr += opsize - 2;
494 length -= opsize;
495 }
496 }
497}
498
Jan Engelhardt09f263c2008-04-14 11:15:53 +0200499static bool tcp_in_window(const struct nf_conn *ct,
500 struct ip_ct_tcp *state,
501 enum ip_conntrack_dir dir,
502 unsigned int index,
503 const struct sk_buff *skb,
504 unsigned int dataoff,
505 const struct tcphdr *tcph,
Jan Engelhardt76108ce2008-10-08 11:35:00 +0200506 u_int8_t pf)
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800507{
Alexey Dobriyanc2a2c7e2008-10-08 11:35:08 +0200508 struct net *net = nf_ct_net(ct);
Gao fengd2ba1fd2012-05-28 21:04:12 +0000509 struct nf_tcp_net *tn = tcp_pernet(net);
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800510 struct ip_ct_tcp_state *sender = &state->seen[dir];
511 struct ip_ct_tcp_state *receiver = &state->seen[!dir];
Jan Engelhardt82f568f2008-01-31 04:52:07 -0800512 const struct nf_conntrack_tuple *tuple = &ct->tuplehash[dir].tuple;
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800513 __u32 seq, ack, sack, end, win, swin;
Patrick McHardy2d89c682013-07-28 22:54:10 +0200514 s32 receiver_offset;
Yuchung Cheng356d7d82013-08-09 17:21:27 -0700515 bool res, in_recv_win;
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800516
517 /*
518 * Get the required data from the packet.
519 */
520 seq = ntohl(tcph->seq);
521 ack = sack = ntohl(tcph->ack_seq);
522 win = ntohs(tcph->window);
523 end = segment_seq_plus_len(seq, skb->len, dataoff, tcph);
524
525 if (receiver->flags & IP_CT_TCP_FLAG_SACK_PERM)
526 tcp_sack(skb, dataoff, tcph, &sack);
527
Jozsef Kadlecsikf9dd09c2009-11-06 00:43:42 -0800528 /* Take into account NAT sequence number mangling */
Patrick McHardy41d73ec2013-08-27 08:50:12 +0200529 receiver_offset = nf_ct_seq_offset(ct, !dir, ack - 1);
Jozsef Kadlecsikf9dd09c2009-11-06 00:43:42 -0800530 ack -= receiver_offset;
531 sack -= receiver_offset;
532
Patrick McHardy0d537782007-07-07 22:39:38 -0700533 pr_debug("tcp_in_window: START\n");
534 pr_debug("tcp_in_window: ");
Jan Engelhardt3c9fba62008-04-14 11:15:54 +0200535 nf_ct_dump_tuple(tuple);
Jozsef Kadlecsikf9dd09c2009-11-06 00:43:42 -0800536 pr_debug("seq=%u ack=%u+(%d) sack=%u+(%d) win=%u end=%u\n",
537 seq, ack, receiver_offset, sack, receiver_offset, win, end);
Patrick McHardy0d537782007-07-07 22:39:38 -0700538 pr_debug("tcp_in_window: sender end=%u maxend=%u maxwin=%u scale=%i "
539 "receiver end=%u maxend=%u maxwin=%u scale=%i\n",
540 sender->td_end, sender->td_maxend, sender->td_maxwin,
541 sender->td_scale,
542 receiver->td_end, receiver->td_maxend, receiver->td_maxwin,
543 receiver->td_scale);
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800544
Jozsef Kadlecsik874ab922009-06-02 13:58:56 +0200545 if (sender->td_maxwin == 0) {
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800546 /*
547 * Initialize sender data.
548 */
Jozsef Kadlecsik874ab922009-06-02 13:58:56 +0200549 if (tcph->syn) {
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800550 /*
Jozsef Kadlecsik874ab922009-06-02 13:58:56 +0200551 * SYN-ACK in reply to a SYN
552 * or SYN from reply direction in simultaneous open.
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800553 */
YOSHIFUJI Hideaki601e68e2007-02-12 11:15:49 -0800554 sender->td_end =
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800555 sender->td_maxend = end;
556 sender->td_maxwin = (win == 0 ? 1 : win);
557
558 tcp_options(skb, dataoff, tcph, sender);
YOSHIFUJI Hideaki601e68e2007-02-12 11:15:49 -0800559 /*
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800560 * RFC 1323:
561 * Both sides must send the Window Scale option
562 * to enable window scaling in either direction.
563 */
564 if (!(sender->flags & IP_CT_TCP_FLAG_WINDOW_SCALE
565 && receiver->flags & IP_CT_TCP_FLAG_WINDOW_SCALE))
YOSHIFUJI Hideaki601e68e2007-02-12 11:15:49 -0800566 sender->td_scale =
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800567 receiver->td_scale = 0;
Jozsef Kadlecsik874ab922009-06-02 13:58:56 +0200568 if (!tcph->ack)
569 /* Simultaneous open */
570 return true;
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800571 } else {
572 /*
573 * We are in the middle of a connection,
574 * its history is lost for us.
575 * Let's try to use the data from the packet.
YOSHIFUJI Hideaki601e68e2007-02-12 11:15:49 -0800576 */
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800577 sender->td_end = end;
Changli Gao6ee0b692012-04-01 17:25:06 +0000578 swin = win << sender->td_scale;
579 sender->td_maxwin = (swin == 0 ? 1 : swin);
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800580 sender->td_maxend = end + sender->td_maxwin;
Pablo Neira Ayusofac42a92010-07-15 17:09:04 +0200581 /*
582 * We haven't seen traffic in the other direction yet
583 * but we have to tweak window tracking to pass III
584 * and IV until that happens.
585 */
586 if (receiver->td_maxwin == 0)
587 receiver->td_end = receiver->td_maxend = sack;
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800588 }
589 } else if (((state->state == TCP_CONNTRACK_SYN_SENT
590 && dir == IP_CT_DIR_ORIGINAL)
591 || (state->state == TCP_CONNTRACK_SYN_RECV
592 && dir == IP_CT_DIR_REPLY))
593 && after(end, sender->td_end)) {
594 /*
595 * RFC 793: "if a TCP is reinitialized ... then it need
YOSHIFUJI Hideaki601e68e2007-02-12 11:15:49 -0800596 * not wait at all; it must only be sure to use sequence
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800597 * numbers larger than those recently used."
598 */
599 sender->td_end =
600 sender->td_maxend = end;
601 sender->td_maxwin = (win == 0 ? 1 : win);
602
603 tcp_options(skb, dataoff, tcph, sender);
604 }
605
606 if (!(tcph->ack)) {
607 /*
608 * If there is no ACK, just pretend it was set and OK.
609 */
610 ack = sack = receiver->td_end;
YOSHIFUJI Hideaki601e68e2007-02-12 11:15:49 -0800611 } else if (((tcp_flag_word(tcph) & (TCP_FLAG_ACK|TCP_FLAG_RST)) ==
612 (TCP_FLAG_ACK|TCP_FLAG_RST))
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800613 && (ack == 0)) {
614 /*
615 * Broken TCP stacks, that set ACK in RST packets as well
616 * with zero ack value.
617 */
618 ack = sack = receiver->td_end;
619 }
620
Jozsef Kadlecsik4a70bbf2012-08-31 09:55:54 +0000621 if (tcph->rst && seq == 0 && state->state == TCP_CONNTRACK_SYN_SENT)
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800622 /*
Jozsef Kadlecsik4a70bbf2012-08-31 09:55:54 +0000623 * RST sent answering SYN.
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800624 */
625 seq = end = sender->td_end;
626
Patrick McHardy0d537782007-07-07 22:39:38 -0700627 pr_debug("tcp_in_window: ");
Jan Engelhardt3c9fba62008-04-14 11:15:54 +0200628 nf_ct_dump_tuple(tuple);
Jozsef Kadlecsikf9dd09c2009-11-06 00:43:42 -0800629 pr_debug("seq=%u ack=%u+(%d) sack=%u+(%d) win=%u end=%u\n",
630 seq, ack, receiver_offset, sack, receiver_offset, win, end);
Patrick McHardy0d537782007-07-07 22:39:38 -0700631 pr_debug("tcp_in_window: sender end=%u maxend=%u maxwin=%u scale=%i "
632 "receiver end=%u maxend=%u maxwin=%u scale=%i\n",
633 sender->td_end, sender->td_maxend, sender->td_maxwin,
634 sender->td_scale,
635 receiver->td_end, receiver->td_maxend, receiver->td_maxwin,
636 receiver->td_scale);
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800637
Yuchung Cheng356d7d82013-08-09 17:21:27 -0700638 /* Is the ending sequence in the receive window (if available)? */
639 in_recv_win = !receiver->td_maxwin ||
640 after(end, sender->td_end - receiver->td_maxwin - 1);
641
Patrick McHardy0d537782007-07-07 22:39:38 -0700642 pr_debug("tcp_in_window: I=%i II=%i III=%i IV=%i\n",
643 before(seq, sender->td_maxend + 1),
Yuchung Cheng356d7d82013-08-09 17:21:27 -0700644 (in_recv_win ? 1 : 0),
Patrick McHardy0d537782007-07-07 22:39:38 -0700645 before(sack, receiver->td_end + 1),
Jozsef Kadlecsik84ebe1c2008-06-30 12:41:30 -0700646 after(sack, receiver->td_end - MAXACKWINDOW(sender) - 1));
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800647
Patrick McHardya09113c2007-02-07 15:05:33 -0800648 if (before(seq, sender->td_maxend + 1) &&
Yuchung Cheng356d7d82013-08-09 17:21:27 -0700649 in_recv_win &&
Patrick McHardya09113c2007-02-07 15:05:33 -0800650 before(sack, receiver->td_end + 1) &&
Jozsef Kadlecsik84ebe1c2008-06-30 12:41:30 -0700651 after(sack, receiver->td_end - MAXACKWINDOW(sender) - 1)) {
YOSHIFUJI Hideaki601e68e2007-02-12 11:15:49 -0800652 /*
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800653 * Take into account window scaling (RFC 1323).
654 */
655 if (!tcph->syn)
656 win <<= sender->td_scale;
657
658 /*
659 * Update sender data.
660 */
661 swin = win + (sack - ack);
662 if (sender->td_maxwin < swin)
663 sender->td_maxwin = swin;
Patrick McHardyae375042008-07-31 00:38:01 -0700664 if (after(end, sender->td_end)) {
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800665 sender->td_end = end;
Patrick McHardyae375042008-07-31 00:38:01 -0700666 sender->flags |= IP_CT_TCP_FLAG_DATA_UNACKNOWLEDGED;
667 }
Jozsef Kadlecsikbfcaa5022009-05-25 17:23:15 +0200668 if (tcph->ack) {
669 if (!(sender->flags & IP_CT_TCP_FLAG_MAXACK_SET)) {
670 sender->td_maxack = ack;
671 sender->flags |= IP_CT_TCP_FLAG_MAXACK_SET;
672 } else if (after(ack, sender->td_maxack))
673 sender->td_maxack = ack;
674 }
675
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800676 /*
677 * Update receiver data.
678 */
Pablo Neira Ayusofac42a92010-07-15 17:09:04 +0200679 if (receiver->td_maxwin != 0 && after(end, sender->td_maxend))
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800680 receiver->td_maxwin += end - sender->td_maxend;
681 if (after(sack + win, receiver->td_maxend - 1)) {
682 receiver->td_maxend = sack + win;
683 if (win == 0)
684 receiver->td_maxend++;
685 }
Patrick McHardyae375042008-07-31 00:38:01 -0700686 if (ack == receiver->td_end)
687 receiver->flags &= ~IP_CT_TCP_FLAG_DATA_UNACKNOWLEDGED;
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800688
YOSHIFUJI Hideaki601e68e2007-02-12 11:15:49 -0800689 /*
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800690 * Check retransmissions.
691 */
692 if (index == TCP_ACK_SET) {
693 if (state->last_dir == dir
694 && state->last_seq == seq
695 && state->last_ack == ack
George Hansperc1fe3ca2006-09-20 12:03:23 -0700696 && state->last_end == end
697 && state->last_win == win)
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800698 state->retrans++;
699 else {
700 state->last_dir = dir;
701 state->last_seq = seq;
702 state->last_ack = ack;
703 state->last_end = end;
George Hansperc1fe3ca2006-09-20 12:03:23 -0700704 state->last_win = win;
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800705 state->retrans = 0;
706 }
707 }
Jan Engelhardt09f263c2008-04-14 11:15:53 +0200708 res = true;
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800709 } else {
Jan Engelhardt09f263c2008-04-14 11:15:53 +0200710 res = false;
Patrick McHardya09113c2007-02-07 15:05:33 -0800711 if (sender->flags & IP_CT_TCP_FLAG_BE_LIBERAL ||
Gao fengd2ba1fd2012-05-28 21:04:12 +0000712 tn->tcp_be_liberal)
Jan Engelhardt09f263c2008-04-14 11:15:53 +0200713 res = true;
Alexey Dobriyanc2a2c7e2008-10-08 11:35:08 +0200714 if (!res && LOG_INVALID(net, IPPROTO_TCP))
Gao feng30e0c6a2013-03-24 23:50:40 +0000715 nf_log_packet(net, pf, 0, skb, NULL, NULL, NULL,
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800716 "nf_ct_tcp: %s ",
717 before(seq, sender->td_maxend + 1) ?
Yuchung Cheng356d7d82013-08-09 17:21:27 -0700718 in_recv_win ?
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800719 before(sack, receiver->td_end + 1) ?
Jozsef Kadlecsikf9dd09c2009-11-06 00:43:42 -0800720 after(sack, receiver->td_end - MAXACKWINDOW(sender) - 1) ? "BUG"
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800721 : "ACK is under the lower bound (possible overly delayed ACK)"
722 : "ACK is over the upper bound (ACKed data not seen yet)"
723 : "SEQ is under the lower bound (already ACKed data retransmitted)"
724 : "SEQ is over the upper bound (over the window of the receiver)");
YOSHIFUJI Hideaki601e68e2007-02-12 11:15:49 -0800725 }
726
Jan Engelhardt09f263c2008-04-14 11:15:53 +0200727 pr_debug("tcp_in_window: res=%u sender end=%u maxend=%u maxwin=%u "
Patrick McHardy0d537782007-07-07 22:39:38 -0700728 "receiver end=%u maxend=%u maxwin=%u\n",
729 res, sender->td_end, sender->td_maxend, sender->td_maxwin,
730 receiver->td_end, receiver->td_maxend, receiver->td_maxwin);
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800731
732 return res;
733}
734
Willy Tarreau5c8ce7c2007-03-14 16:44:53 -0700735/* table of valid flag combinations - PUSH, ECE and CWR are always valid */
Changli Gaoa3433f32010-06-12 14:01:43 +0000736static const u8 tcp_valid_flags[(TCPHDR_FIN|TCPHDR_SYN|TCPHDR_RST|TCPHDR_ACK|
737 TCPHDR_URG) + 1] =
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800738{
Changli Gaoa3433f32010-06-12 14:01:43 +0000739 [TCPHDR_SYN] = 1,
740 [TCPHDR_SYN|TCPHDR_URG] = 1,
741 [TCPHDR_SYN|TCPHDR_ACK] = 1,
742 [TCPHDR_RST] = 1,
743 [TCPHDR_RST|TCPHDR_ACK] = 1,
744 [TCPHDR_FIN|TCPHDR_ACK] = 1,
745 [TCPHDR_FIN|TCPHDR_ACK|TCPHDR_URG] = 1,
746 [TCPHDR_ACK] = 1,
747 [TCPHDR_ACK|TCPHDR_URG] = 1,
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800748};
749
750/* Protect conntrack agaist broken packets. Code taken from ipt_unclean.c. */
Patrick McHardy8fea97e2010-02-15 17:45:08 +0100751static int tcp_error(struct net *net, struct nf_conn *tmpl,
Alexey Dobriyan74c51a12008-10-08 11:35:05 +0200752 struct sk_buff *skb,
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800753 unsigned int dataoff,
754 enum ip_conntrack_info *ctinfo,
Jan Engelhardt76108ce2008-10-08 11:35:00 +0200755 u_int8_t pf,
Patrick McHardy96f6bf82006-04-06 14:19:24 -0700756 unsigned int hooknum)
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800757{
Jan Engelhardt82f568f2008-01-31 04:52:07 -0800758 const struct tcphdr *th;
759 struct tcphdr _tcph;
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800760 unsigned int tcplen = skb->len - dataoff;
761 u_int8_t tcpflags;
762
763 /* Smaller that minimal TCP header? */
764 th = skb_header_pointer(skb, dataoff, sizeof(_tcph), &_tcph);
765 if (th == NULL) {
Alexey Dobriyanc2a2c7e2008-10-08 11:35:08 +0200766 if (LOG_INVALID(net, IPPROTO_TCP))
Gao feng30e0c6a2013-03-24 23:50:40 +0000767 nf_log_packet(net, pf, 0, skb, NULL, NULL, NULL,
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800768 "nf_ct_tcp: short packet ");
769 return -NF_ACCEPT;
YOSHIFUJI Hideaki601e68e2007-02-12 11:15:49 -0800770 }
771
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800772 /* Not whole TCP header or malformed packet */
773 if (th->doff*4 < sizeof(struct tcphdr) || tcplen < th->doff*4) {
Alexey Dobriyanc2a2c7e2008-10-08 11:35:08 +0200774 if (LOG_INVALID(net, IPPROTO_TCP))
Gao feng30e0c6a2013-03-24 23:50:40 +0000775 nf_log_packet(net, pf, 0, skb, NULL, NULL, NULL,
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800776 "nf_ct_tcp: truncated/malformed packet ");
777 return -NF_ACCEPT;
778 }
YOSHIFUJI Hideaki601e68e2007-02-12 11:15:49 -0800779
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800780 /* Checksum invalid? Ignore.
781 * We skip checking packets on the outgoing path
Patrick McHardy84fa7932006-08-29 16:44:56 -0700782 * because the checksum is assumed to be correct.
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800783 */
784 /* FIXME: Source route IP option packets --RR */
Alexey Dobriyanc04d0552008-10-08 11:35:08 +0200785 if (net->ct.sysctl_checksum && hooknum == NF_INET_PRE_ROUTING &&
Patrick McHardy96f6bf82006-04-06 14:19:24 -0700786 nf_checksum(skb, hooknum, dataoff, IPPROTO_TCP, pf)) {
Alexey Dobriyanc2a2c7e2008-10-08 11:35:08 +0200787 if (LOG_INVALID(net, IPPROTO_TCP))
Gao feng30e0c6a2013-03-24 23:50:40 +0000788 nf_log_packet(net, pf, 0, skb, NULL, NULL, NULL,
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800789 "nf_ct_tcp: bad TCP checksum ");
790 return -NF_ACCEPT;
791 }
792
793 /* Check TCP flags. */
Changli Gaoa3433f32010-06-12 14:01:43 +0000794 tcpflags = (tcp_flag_byte(th) & ~(TCPHDR_ECE|TCPHDR_CWR|TCPHDR_PSH));
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800795 if (!tcp_valid_flags[tcpflags]) {
Alexey Dobriyanc2a2c7e2008-10-08 11:35:08 +0200796 if (LOG_INVALID(net, IPPROTO_TCP))
Gao feng30e0c6a2013-03-24 23:50:40 +0000797 nf_log_packet(net, pf, 0, skb, NULL, NULL, NULL,
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800798 "nf_ct_tcp: invalid TCP flag combination ");
799 return -NF_ACCEPT;
800 }
801
802 return NF_ACCEPT;
803}
804
Pablo Neira Ayuso2c8503f2012-02-28 18:23:31 +0100805static unsigned int *tcp_get_timeouts(struct net *net)
806{
Pablo Neira Ayusobe0593c2012-06-29 05:23:25 +0000807 return tcp_pernet(net)->timeouts;
Pablo Neira Ayuso2c8503f2012-02-28 18:23:31 +0100808}
809
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800810/* Returns verdict for packet, or -1 for invalid. */
Patrick McHardyc88130b2008-01-31 04:42:11 -0800811static int tcp_packet(struct nf_conn *ct,
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800812 const struct sk_buff *skb,
813 unsigned int dataoff,
814 enum ip_conntrack_info ctinfo,
Jan Engelhardt76108ce2008-10-08 11:35:00 +0200815 u_int8_t pf,
Pablo Neira Ayuso2c8503f2012-02-28 18:23:31 +0100816 unsigned int hooknum,
817 unsigned int *timeouts)
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800818{
Alexey Dobriyanc2a2c7e2008-10-08 11:35:08 +0200819 struct net *net = nf_ct_net(ct);
Gao fengd2ba1fd2012-05-28 21:04:12 +0000820 struct nf_tcp_net *tn = tcp_pernet(net);
Patrick McHardy0d537782007-07-07 22:39:38 -0700821 struct nf_conntrack_tuple *tuple;
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800822 enum tcp_conntrack new_state, old_state;
823 enum ip_conntrack_dir dir;
Jan Engelhardt82f568f2008-01-31 04:52:07 -0800824 const struct tcphdr *th;
825 struct tcphdr _tcph;
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800826 unsigned long timeout;
827 unsigned int index;
828
829 th = skb_header_pointer(skb, dataoff, sizeof(_tcph), &_tcph);
830 BUG_ON(th == NULL);
831
Patrick McHardy440f0d52009-06-10 14:32:47 +0200832 spin_lock_bh(&ct->lock);
Patrick McHardyc88130b2008-01-31 04:42:11 -0800833 old_state = ct->proto.tcp.state;
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800834 dir = CTINFO2DIR(ctinfo);
835 index = get_conntrack_index(th);
836 new_state = tcp_conntracks[dir][index][old_state];
Patrick McHardyc88130b2008-01-31 04:42:11 -0800837 tuple = &ct->tuplehash[dir].tuple;
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800838
839 switch (new_state) {
Jozsef Kadlecsik17311392007-10-11 14:35:52 -0700840 case TCP_CONNTRACK_SYN_SENT:
841 if (old_state < TCP_CONNTRACK_TIME_WAIT)
842 break;
Jozsef Kadlecsikb2155e72008-02-07 17:54:56 -0800843 /* RFC 1122: "When a connection is closed actively,
844 * it MUST linger in TIME-WAIT state for a time 2xMSL
845 * (Maximum Segment Lifetime). However, it MAY accept
846 * a new SYN from the remote TCP to reopen the connection
847 * directly from TIME-WAIT state, if..."
848 * We ignore the conditions because we are in the
849 * TIME-WAIT state anyway.
850 *
851 * Handle aborted connections: we and the server
852 * think there is an existing connection but the client
853 * aborts it and starts a new one.
854 */
855 if (((ct->proto.tcp.seen[dir].flags
856 | ct->proto.tcp.seen[!dir].flags)
857 & IP_CT_TCP_FLAG_CLOSE_INIT)
Patrick McHardyc88130b2008-01-31 04:42:11 -0800858 || (ct->proto.tcp.last_dir == dir
859 && ct->proto.tcp.last_index == TCP_RST_SET)) {
Jozsef Kadlecsikbc34b842007-10-18 05:20:12 -0700860 /* Attempt to reopen a closed/aborted connection.
861 * Delete this connection and look up again. */
Patrick McHardy440f0d52009-06-10 14:32:47 +0200862 spin_unlock_bh(&ct->lock);
David S. Miller2aec6092008-07-14 20:23:54 -0700863
Patrick McHardy6b69fe02008-07-09 15:06:12 -0700864 /* Only repeat if we can actually remove the timer.
865 * Destruction may already be in progress in process
866 * context and we must give it a chance to terminate.
867 */
David S. Miller2aec6092008-07-14 20:23:54 -0700868 if (nf_ct_kill(ct))
Patrick McHardy6b69fe02008-07-09 15:06:12 -0700869 return -NF_REPEAT;
Christoph Paaschec8d5402009-03-16 15:51:29 +0100870 return NF_DROP;
Jozsef Kadlecsik17311392007-10-11 14:35:52 -0700871 }
872 /* Fall through */
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800873 case TCP_CONNTRACK_IGNORE:
Jozsef Kadlecsik73f30602005-12-01 14:28:58 -0800874 /* Ignored packets:
875 *
Jozsef Kadlecsikb2155e72008-02-07 17:54:56 -0800876 * Our connection entry may be out of sync, so ignore
877 * packets which may signal the real connection between
878 * the client and the server.
879 *
Jozsef Kadlecsik73f30602005-12-01 14:28:58 -0800880 * a) SYN in ORIGINAL
881 * b) SYN/ACK in REPLY
YOSHIFUJI Hideaki601e68e2007-02-12 11:15:49 -0800882 * c) ACK in reply direction after initial SYN in original.
Jozsef Kadlecsikb2155e72008-02-07 17:54:56 -0800883 *
884 * If the ignored packet is invalid, the receiver will send
885 * a RST we'll catch below.
Jozsef Kadlecsik73f30602005-12-01 14:28:58 -0800886 */
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800887 if (index == TCP_SYNACK_SET
Patrick McHardyc88130b2008-01-31 04:42:11 -0800888 && ct->proto.tcp.last_index == TCP_SYN_SET
889 && ct->proto.tcp.last_dir != dir
890 && ntohl(th->ack_seq) == ct->proto.tcp.last_end) {
Jozsef Kadlecsikb2155e72008-02-07 17:54:56 -0800891 /* b) This SYN/ACK acknowledges a SYN that we earlier
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800892 * ignored as invalid. This means that the client and
893 * the server are both in sync, while the firewall is
Pablo Neira Ayusoc4832c72009-11-23 10:34:39 +0100894 * not. We get in sync from the previously annotated
895 * values.
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800896 */
Pablo Neira Ayusoc4832c72009-11-23 10:34:39 +0100897 old_state = TCP_CONNTRACK_SYN_SENT;
898 new_state = TCP_CONNTRACK_SYN_RECV;
899 ct->proto.tcp.seen[ct->proto.tcp.last_dir].td_end =
900 ct->proto.tcp.last_end;
901 ct->proto.tcp.seen[ct->proto.tcp.last_dir].td_maxend =
902 ct->proto.tcp.last_end;
903 ct->proto.tcp.seen[ct->proto.tcp.last_dir].td_maxwin =
904 ct->proto.tcp.last_win == 0 ?
905 1 : ct->proto.tcp.last_win;
906 ct->proto.tcp.seen[ct->proto.tcp.last_dir].td_scale =
907 ct->proto.tcp.last_wscale;
908 ct->proto.tcp.seen[ct->proto.tcp.last_dir].flags =
909 ct->proto.tcp.last_flags;
910 memset(&ct->proto.tcp.seen[dir], 0,
911 sizeof(struct ip_ct_tcp_state));
912 break;
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800913 }
Patrick McHardyc88130b2008-01-31 04:42:11 -0800914 ct->proto.tcp.last_index = index;
915 ct->proto.tcp.last_dir = dir;
916 ct->proto.tcp.last_seq = ntohl(th->seq);
917 ct->proto.tcp.last_end =
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800918 segment_seq_plus_len(ntohl(th->seq), skb->len, dataoff, th);
Pablo Neira Ayusoc4832c72009-11-23 10:34:39 +0100919 ct->proto.tcp.last_win = ntohs(th->window);
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800920
Pablo Neira Ayusoc4832c72009-11-23 10:34:39 +0100921 /* a) This is a SYN in ORIGINAL. The client and the server
922 * may be in sync but we are not. In that case, we annotate
923 * the TCP options and let the packet go through. If it is a
924 * valid SYN packet, the server will reply with a SYN/ACK, and
925 * then we'll get in sync. Otherwise, the server ignores it. */
926 if (index == TCP_SYN_SET && dir == IP_CT_DIR_ORIGINAL) {
927 struct ip_ct_tcp_state seen = {};
928
929 ct->proto.tcp.last_flags =
930 ct->proto.tcp.last_wscale = 0;
931 tcp_options(skb, dataoff, th, &seen);
932 if (seen.flags & IP_CT_TCP_FLAG_WINDOW_SCALE) {
933 ct->proto.tcp.last_flags |=
934 IP_CT_TCP_FLAG_WINDOW_SCALE;
935 ct->proto.tcp.last_wscale = seen.td_scale;
936 }
937 if (seen.flags & IP_CT_TCP_FLAG_SACK_PERM) {
938 ct->proto.tcp.last_flags |=
939 IP_CT_TCP_FLAG_SACK_PERM;
940 }
941 }
Patrick McHardy440f0d52009-06-10 14:32:47 +0200942 spin_unlock_bh(&ct->lock);
Alexey Dobriyanc2a2c7e2008-10-08 11:35:08 +0200943 if (LOG_INVALID(net, IPPROTO_TCP))
Gao feng30e0c6a2013-03-24 23:50:40 +0000944 nf_log_packet(net, pf, 0, skb, NULL, NULL, NULL,
Pablo Neira Ayuso1a4ac982012-05-14 10:55:03 +0200945 "nf_ct_tcp: invalid packet ignored in "
946 "state %s ", tcp_conntrack_names[old_state]);
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800947 return NF_ACCEPT;
948 case TCP_CONNTRACK_MAX:
949 /* Invalid packet */
Patrick McHardy0d537782007-07-07 22:39:38 -0700950 pr_debug("nf_ct_tcp: Invalid dir=%i index=%u ostate=%u\n",
951 dir, get_conntrack_index(th), old_state);
Patrick McHardy440f0d52009-06-10 14:32:47 +0200952 spin_unlock_bh(&ct->lock);
Alexey Dobriyanc2a2c7e2008-10-08 11:35:08 +0200953 if (LOG_INVALID(net, IPPROTO_TCP))
Gao feng30e0c6a2013-03-24 23:50:40 +0000954 nf_log_packet(net, pf, 0, skb, NULL, NULL, NULL,
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800955 "nf_ct_tcp: invalid state ");
956 return -NF_ACCEPT;
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800957 case TCP_CONNTRACK_CLOSE:
958 if (index == TCP_RST_SET
Jozsef Kadlecsikbfcaa5022009-05-25 17:23:15 +0200959 && (ct->proto.tcp.seen[!dir].flags & IP_CT_TCP_FLAG_MAXACK_SET)
960 && before(ntohl(th->seq), ct->proto.tcp.seen[!dir].td_maxack)) {
961 /* Invalid RST */
Patrick McHardy334a47f2009-06-11 16:16:09 +0200962 spin_unlock_bh(&ct->lock);
Jozsef Kadlecsikbfcaa5022009-05-25 17:23:15 +0200963 if (LOG_INVALID(net, IPPROTO_TCP))
Gao feng30e0c6a2013-03-24 23:50:40 +0000964 nf_log_packet(net, pf, 0, skb, NULL, NULL,
965 NULL, "nf_ct_tcp: invalid RST ");
Jozsef Kadlecsikbfcaa5022009-05-25 17:23:15 +0200966 return -NF_ACCEPT;
967 }
968 if (index == TCP_RST_SET
Patrick McHardyc88130b2008-01-31 04:42:11 -0800969 && ((test_bit(IPS_SEEN_REPLY_BIT, &ct->status)
970 && ct->proto.tcp.last_index == TCP_SYN_SET)
971 || (!test_bit(IPS_ASSURED_BIT, &ct->status)
972 && ct->proto.tcp.last_index == TCP_ACK_SET))
973 && ntohl(th->ack_seq) == ct->proto.tcp.last_end) {
Adrian Bunk93b1fae2006-01-10 00:13:33 +0100974 /* RST sent to invalid SYN or ACK we had let through
Jozsef Kadlecsik73f30602005-12-01 14:28:58 -0800975 * at a) and c) above:
976 *
977 * a) SYN was in window then
978 * c) we hold a half-open connection.
979 *
980 * Delete our connection entry.
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800981 * We skip window checking, because packet might ACK
Jozsef Kadlecsik73f30602005-12-01 14:28:58 -0800982 * segments we ignored. */
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800983 goto in_window;
984 }
Adrian Bunk93b1fae2006-01-10 00:13:33 +0100985 /* Just fall through */
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800986 default:
987 /* Keep compilers happy. */
988 break;
989 }
990
Patrick McHardyc88130b2008-01-31 04:42:11 -0800991 if (!tcp_in_window(ct, &ct->proto.tcp, dir, index,
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800992 skb, dataoff, th, pf)) {
Patrick McHardy440f0d52009-06-10 14:32:47 +0200993 spin_unlock_bh(&ct->lock);
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800994 return -NF_ACCEPT;
995 }
996 in_window:
997 /* From now on we have got in-window packets */
Patrick McHardyc88130b2008-01-31 04:42:11 -0800998 ct->proto.tcp.last_index = index;
999 ct->proto.tcp.last_dir = dir;
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -08001000
Patrick McHardy0d537782007-07-07 22:39:38 -07001001 pr_debug("tcp_conntracks: ");
Jan Engelhardt3c9fba62008-04-14 11:15:54 +02001002 nf_ct_dump_tuple(tuple);
Patrick McHardy0d537782007-07-07 22:39:38 -07001003 pr_debug("syn=%i ack=%i fin=%i rst=%i old=%i new=%i\n",
1004 (th->syn ? 1 : 0), (th->ack ? 1 : 0),
1005 (th->fin ? 1 : 0), (th->rst ? 1 : 0),
1006 old_state, new_state);
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -08001007
Patrick McHardyc88130b2008-01-31 04:42:11 -08001008 ct->proto.tcp.state = new_state;
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -08001009 if (old_state != new_state
Jozsef Kadlecsikd0c1fd72008-02-14 14:50:21 -08001010 && new_state == TCP_CONNTRACK_FIN_WAIT)
Patrick McHardyc88130b2008-01-31 04:42:11 -08001011 ct->proto.tcp.seen[dir].flags |= IP_CT_TCP_FLAG_CLOSE_INIT;
Patrick McHardyae375042008-07-31 00:38:01 -07001012
Gao fengd2ba1fd2012-05-28 21:04:12 +00001013 if (ct->proto.tcp.retrans >= tn->tcp_max_retrans &&
Pablo Neira Ayuso2c8503f2012-02-28 18:23:31 +01001014 timeouts[new_state] > timeouts[TCP_CONNTRACK_RETRANS])
1015 timeout = timeouts[TCP_CONNTRACK_RETRANS];
Patrick McHardyae375042008-07-31 00:38:01 -07001016 else if ((ct->proto.tcp.seen[0].flags | ct->proto.tcp.seen[1].flags) &
1017 IP_CT_TCP_FLAG_DATA_UNACKNOWLEDGED &&
Pablo Neira Ayuso2c8503f2012-02-28 18:23:31 +01001018 timeouts[new_state] > timeouts[TCP_CONNTRACK_UNACK])
1019 timeout = timeouts[TCP_CONNTRACK_UNACK];
Patrick McHardyae375042008-07-31 00:38:01 -07001020 else
Pablo Neira Ayuso2c8503f2012-02-28 18:23:31 +01001021 timeout = timeouts[new_state];
Patrick McHardy440f0d52009-06-10 14:32:47 +02001022 spin_unlock_bh(&ct->lock);
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -08001023
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -08001024 if (new_state != old_state)
Alexey Dobriyana71996f2008-10-08 11:35:07 +02001025 nf_conntrack_event_cache(IPCT_PROTOINFO, ct);
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -08001026
Patrick McHardyc88130b2008-01-31 04:42:11 -08001027 if (!test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) {
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -08001028 /* If only reply is a RST, we can consider ourselves not to
1029 have an established connection: this is a fairly common
1030 problem case, so we can delete the conntrack
1031 immediately. --RR */
1032 if (th->rst) {
Fabian Hugelshofer718d4ad2008-06-09 15:59:40 -07001033 nf_ct_kill_acct(ct, ctinfo, skb);
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -08001034 return NF_ACCEPT;
1035 }
Florian Westphal6547a222013-06-13 17:31:28 +02001036 /* ESTABLISHED without SEEN_REPLY, i.e. mid-connection
1037 * pickup with loose=1. Avoid large ESTABLISHED timeout.
1038 */
1039 if (new_state == TCP_CONNTRACK_ESTABLISHED &&
1040 timeout > timeouts[TCP_CONNTRACK_UNACK])
1041 timeout = timeouts[TCP_CONNTRACK_UNACK];
Patrick McHardyc88130b2008-01-31 04:42:11 -08001042 } else if (!test_bit(IPS_ASSURED_BIT, &ct->status)
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -08001043 && (old_state == TCP_CONNTRACK_SYN_RECV
1044 || old_state == TCP_CONNTRACK_ESTABLISHED)
1045 && new_state == TCP_CONNTRACK_ESTABLISHED) {
YOSHIFUJI Hideaki601e68e2007-02-12 11:15:49 -08001046 /* Set ASSURED if we see see valid ack in ESTABLISHED
1047 after SYN_RECV or a valid answer for a picked up
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -08001048 connection. */
Patrick McHardyc88130b2008-01-31 04:42:11 -08001049 set_bit(IPS_ASSURED_BIT, &ct->status);
Patrick McHardy858b31332010-02-03 13:48:53 +01001050 nf_conntrack_event_cache(IPCT_ASSURED, ct);
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -08001051 }
Patrick McHardyc88130b2008-01-31 04:42:11 -08001052 nf_ct_refresh_acct(ct, ctinfo, skb, timeout);
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -08001053
1054 return NF_ACCEPT;
1055}
YOSHIFUJI Hideaki601e68e2007-02-12 11:15:49 -08001056
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -08001057/* Called when a new connection for this protocol found. */
Jan Engelhardt09f263c2008-04-14 11:15:53 +02001058static bool tcp_new(struct nf_conn *ct, const struct sk_buff *skb,
Pablo Neira Ayuso2c8503f2012-02-28 18:23:31 +01001059 unsigned int dataoff, unsigned int *timeouts)
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -08001060{
1061 enum tcp_conntrack new_state;
Jan Engelhardt82f568f2008-01-31 04:52:07 -08001062 const struct tcphdr *th;
1063 struct tcphdr _tcph;
Gao fengd2ba1fd2012-05-28 21:04:12 +00001064 struct net *net = nf_ct_net(ct);
1065 struct nf_tcp_net *tn = tcp_pernet(net);
Jan Engelhardt82f568f2008-01-31 04:52:07 -08001066 const struct ip_ct_tcp_state *sender = &ct->proto.tcp.seen[0];
1067 const struct ip_ct_tcp_state *receiver = &ct->proto.tcp.seen[1];
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -08001068
1069 th = skb_header_pointer(skb, dataoff, sizeof(_tcph), &_tcph);
1070 BUG_ON(th == NULL);
1071
1072 /* Don't need lock here: this conntrack not in circulation yet */
Changli Gaoe5fc9e72010-11-12 17:33:17 +01001073 new_state = tcp_conntracks[0][get_conntrack_index(th)][TCP_CONNTRACK_NONE];
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -08001074
1075 /* Invalid: delete conntrack */
1076 if (new_state >= TCP_CONNTRACK_MAX) {
Patrick McHardy0d537782007-07-07 22:39:38 -07001077 pr_debug("nf_ct_tcp: invalid new deleting.\n");
Jan Engelhardt09f263c2008-04-14 11:15:53 +02001078 return false;
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -08001079 }
1080
1081 if (new_state == TCP_CONNTRACK_SYN_SENT) {
Changli Gaoe5fc9e72010-11-12 17:33:17 +01001082 memset(&ct->proto.tcp, 0, sizeof(ct->proto.tcp));
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -08001083 /* SYN packet */
Patrick McHardyc88130b2008-01-31 04:42:11 -08001084 ct->proto.tcp.seen[0].td_end =
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -08001085 segment_seq_plus_len(ntohl(th->seq), skb->len,
1086 dataoff, th);
Patrick McHardyc88130b2008-01-31 04:42:11 -08001087 ct->proto.tcp.seen[0].td_maxwin = ntohs(th->window);
1088 if (ct->proto.tcp.seen[0].td_maxwin == 0)
1089 ct->proto.tcp.seen[0].td_maxwin = 1;
1090 ct->proto.tcp.seen[0].td_maxend =
1091 ct->proto.tcp.seen[0].td_end;
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -08001092
Patrick McHardyc88130b2008-01-31 04:42:11 -08001093 tcp_options(skb, dataoff, th, &ct->proto.tcp.seen[0]);
Gao fengd2ba1fd2012-05-28 21:04:12 +00001094 } else if (tn->tcp_loose == 0) {
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -08001095 /* Don't try to pick up connections. */
Jan Engelhardt09f263c2008-04-14 11:15:53 +02001096 return false;
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -08001097 } else {
Changli Gaoe5fc9e72010-11-12 17:33:17 +01001098 memset(&ct->proto.tcp, 0, sizeof(ct->proto.tcp));
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -08001099 /*
1100 * We are in the middle of a connection,
1101 * its history is lost for us.
1102 * Let's try to use the data from the packet.
1103 */
Patrick McHardyc88130b2008-01-31 04:42:11 -08001104 ct->proto.tcp.seen[0].td_end =
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -08001105 segment_seq_plus_len(ntohl(th->seq), skb->len,
1106 dataoff, th);
Patrick McHardyc88130b2008-01-31 04:42:11 -08001107 ct->proto.tcp.seen[0].td_maxwin = ntohs(th->window);
1108 if (ct->proto.tcp.seen[0].td_maxwin == 0)
1109 ct->proto.tcp.seen[0].td_maxwin = 1;
1110 ct->proto.tcp.seen[0].td_maxend =
1111 ct->proto.tcp.seen[0].td_end +
1112 ct->proto.tcp.seen[0].td_maxwin;
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -08001113
Patrick McHardya09113c2007-02-07 15:05:33 -08001114 /* We assume SACK and liberal window checking to handle
1115 * window scaling */
Patrick McHardyc88130b2008-01-31 04:42:11 -08001116 ct->proto.tcp.seen[0].flags =
1117 ct->proto.tcp.seen[1].flags = IP_CT_TCP_FLAG_SACK_PERM |
1118 IP_CT_TCP_FLAG_BE_LIBERAL;
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -08001119 }
YOSHIFUJI Hideaki601e68e2007-02-12 11:15:49 -08001120
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -08001121 /* tcp_packet will set them */
Patrick McHardyc88130b2008-01-31 04:42:11 -08001122 ct->proto.tcp.last_index = TCP_NONE_SET;
YOSHIFUJI Hideaki601e68e2007-02-12 11:15:49 -08001123
Patrick McHardy0d537782007-07-07 22:39:38 -07001124 pr_debug("tcp_new: sender end=%u maxend=%u maxwin=%u scale=%i "
1125 "receiver end=%u maxend=%u maxwin=%u scale=%i\n",
1126 sender->td_end, sender->td_maxend, sender->td_maxwin,
1127 sender->td_scale,
1128 receiver->td_end, receiver->td_maxend, receiver->td_maxwin,
1129 receiver->td_scale);
Jan Engelhardt09f263c2008-04-14 11:15:53 +02001130 return true;
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -08001131}
Pablo Neira Ayusoc1d10ad2006-01-05 12:19:05 -08001132
Igor Maravićc0cd1152011-12-12 02:58:24 +00001133#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
Pablo Neira Ayusoc1d10ad2006-01-05 12:19:05 -08001134
1135#include <linux/netfilter/nfnetlink.h>
1136#include <linux/netfilter/nfnetlink_conntrack.h>
1137
Patrick McHardyfdf70832007-09-28 14:37:41 -07001138static int tcp_to_nlattr(struct sk_buff *skb, struct nlattr *nla,
Patrick McHardy440f0d52009-06-10 14:32:47 +02001139 struct nf_conn *ct)
Pablo Neira Ayusoc1d10ad2006-01-05 12:19:05 -08001140{
Patrick McHardydf6fb862007-09-28 14:37:03 -07001141 struct nlattr *nest_parms;
Pablo Neira Ayusoc8e20782007-03-14 16:45:19 -07001142 struct nf_ct_tcp_flags tmp = {};
YOSHIFUJI Hideaki601e68e2007-02-12 11:15:49 -08001143
Patrick McHardy440f0d52009-06-10 14:32:47 +02001144 spin_lock_bh(&ct->lock);
Patrick McHardydf6fb862007-09-28 14:37:03 -07001145 nest_parms = nla_nest_start(skb, CTA_PROTOINFO_TCP | NLA_F_NESTED);
1146 if (!nest_parms)
1147 goto nla_put_failure;
1148
David S. Miller4925a452012-04-01 18:50:08 -04001149 if (nla_put_u8(skb, CTA_PROTOINFO_TCP_STATE, ct->proto.tcp.state) ||
1150 nla_put_u8(skb, CTA_PROTOINFO_TCP_WSCALE_ORIGINAL,
1151 ct->proto.tcp.seen[0].td_scale) ||
1152 nla_put_u8(skb, CTA_PROTOINFO_TCP_WSCALE_REPLY,
1153 ct->proto.tcp.seen[1].td_scale))
1154 goto nla_put_failure;
Pablo Neira Ayusoc8e20782007-03-14 16:45:19 -07001155
1156 tmp.flags = ct->proto.tcp.seen[0].flags;
David S. Miller4925a452012-04-01 18:50:08 -04001157 if (nla_put(skb, CTA_PROTOINFO_TCP_FLAGS_ORIGINAL,
1158 sizeof(struct nf_ct_tcp_flags), &tmp))
1159 goto nla_put_failure;
Pablo Neira Ayusoc8e20782007-03-14 16:45:19 -07001160
1161 tmp.flags = ct->proto.tcp.seen[1].flags;
David S. Miller4925a452012-04-01 18:50:08 -04001162 if (nla_put(skb, CTA_PROTOINFO_TCP_FLAGS_REPLY,
1163 sizeof(struct nf_ct_tcp_flags), &tmp))
1164 goto nla_put_failure;
Patrick McHardy440f0d52009-06-10 14:32:47 +02001165 spin_unlock_bh(&ct->lock);
Pablo Neira Ayusoc1d10ad2006-01-05 12:19:05 -08001166
Patrick McHardydf6fb862007-09-28 14:37:03 -07001167 nla_nest_end(skb, nest_parms);
Pablo Neira Ayusoc1d10ad2006-01-05 12:19:05 -08001168
1169 return 0;
1170
Patrick McHardydf6fb862007-09-28 14:37:03 -07001171nla_put_failure:
Patrick McHardy440f0d52009-06-10 14:32:47 +02001172 spin_unlock_bh(&ct->lock);
Pablo Neira Ayusoc1d10ad2006-01-05 12:19:05 -08001173 return -1;
1174}
1175
Patrick McHardyf73e9242007-09-28 14:39:55 -07001176static const struct nla_policy tcp_nla_policy[CTA_PROTOINFO_TCP_MAX+1] = {
1177 [CTA_PROTOINFO_TCP_STATE] = { .type = NLA_U8 },
1178 [CTA_PROTOINFO_TCP_WSCALE_ORIGINAL] = { .type = NLA_U8 },
1179 [CTA_PROTOINFO_TCP_WSCALE_REPLY] = { .type = NLA_U8 },
1180 [CTA_PROTOINFO_TCP_FLAGS_ORIGINAL] = { .len = sizeof(struct nf_ct_tcp_flags) },
1181 [CTA_PROTOINFO_TCP_FLAGS_REPLY] = { .len = sizeof(struct nf_ct_tcp_flags) },
Pablo Neira Ayusoc1d10ad2006-01-05 12:19:05 -08001182};
1183
Patrick McHardyfdf70832007-09-28 14:37:41 -07001184static int nlattr_to_tcp(struct nlattr *cda[], struct nf_conn *ct)
Pablo Neira Ayusoc1d10ad2006-01-05 12:19:05 -08001185{
Stephen Hemminger2f0d2f12008-01-31 04:08:10 -08001186 struct nlattr *pattr = cda[CTA_PROTOINFO_TCP];
Patrick McHardydf6fb862007-09-28 14:37:03 -07001187 struct nlattr *tb[CTA_PROTOINFO_TCP_MAX+1];
Patrick McHardyf73e9242007-09-28 14:39:55 -07001188 int err;
Pablo Neira Ayusoc1d10ad2006-01-05 12:19:05 -08001189
1190 /* updates could not contain anything about the private
1191 * protocol info, in that case skip the parsing */
Stephen Hemminger2f0d2f12008-01-31 04:08:10 -08001192 if (!pattr)
Pablo Neira Ayusoc1d10ad2006-01-05 12:19:05 -08001193 return 0;
1194
Stephen Hemminger2f0d2f12008-01-31 04:08:10 -08001195 err = nla_parse_nested(tb, CTA_PROTOINFO_TCP_MAX, pattr, tcp_nla_policy);
Patrick McHardyf73e9242007-09-28 14:39:55 -07001196 if (err < 0)
1197 return err;
Pablo Neira Ayusoc1d10ad2006-01-05 12:19:05 -08001198
Patrick McHardy5f7da4d2008-04-14 11:15:52 +02001199 if (tb[CTA_PROTOINFO_TCP_STATE] &&
1200 nla_get_u8(tb[CTA_PROTOINFO_TCP_STATE]) >= TCP_CONNTRACK_MAX)
Pablo Neira Ayusoc1d10ad2006-01-05 12:19:05 -08001201 return -EINVAL;
1202
Patrick McHardy440f0d52009-06-10 14:32:47 +02001203 spin_lock_bh(&ct->lock);
Patrick McHardy5f7da4d2008-04-14 11:15:52 +02001204 if (tb[CTA_PROTOINFO_TCP_STATE])
1205 ct->proto.tcp.state = nla_get_u8(tb[CTA_PROTOINFO_TCP_STATE]);
Pablo Neira Ayusoc8e20782007-03-14 16:45:19 -07001206
Patrick McHardydf6fb862007-09-28 14:37:03 -07001207 if (tb[CTA_PROTOINFO_TCP_FLAGS_ORIGINAL]) {
Pablo Neira Ayusoc8e20782007-03-14 16:45:19 -07001208 struct nf_ct_tcp_flags *attr =
Patrick McHardydf6fb862007-09-28 14:37:03 -07001209 nla_data(tb[CTA_PROTOINFO_TCP_FLAGS_ORIGINAL]);
Pablo Neira Ayusoc8e20782007-03-14 16:45:19 -07001210 ct->proto.tcp.seen[0].flags &= ~attr->mask;
1211 ct->proto.tcp.seen[0].flags |= attr->flags & attr->mask;
1212 }
1213
Patrick McHardydf6fb862007-09-28 14:37:03 -07001214 if (tb[CTA_PROTOINFO_TCP_FLAGS_REPLY]) {
Pablo Neira Ayusoc8e20782007-03-14 16:45:19 -07001215 struct nf_ct_tcp_flags *attr =
Patrick McHardydf6fb862007-09-28 14:37:03 -07001216 nla_data(tb[CTA_PROTOINFO_TCP_FLAGS_REPLY]);
Pablo Neira Ayusoc8e20782007-03-14 16:45:19 -07001217 ct->proto.tcp.seen[1].flags &= ~attr->mask;
1218 ct->proto.tcp.seen[1].flags |= attr->flags & attr->mask;
1219 }
1220
Patrick McHardydf6fb862007-09-28 14:37:03 -07001221 if (tb[CTA_PROTOINFO_TCP_WSCALE_ORIGINAL] &&
1222 tb[CTA_PROTOINFO_TCP_WSCALE_REPLY] &&
Pablo Neira Ayusoc8e20782007-03-14 16:45:19 -07001223 ct->proto.tcp.seen[0].flags & IP_CT_TCP_FLAG_WINDOW_SCALE &&
1224 ct->proto.tcp.seen[1].flags & IP_CT_TCP_FLAG_WINDOW_SCALE) {
Patrick McHardy77236b62007-12-17 22:29:45 -08001225 ct->proto.tcp.seen[0].td_scale =
1226 nla_get_u8(tb[CTA_PROTOINFO_TCP_WSCALE_ORIGINAL]);
1227 ct->proto.tcp.seen[1].td_scale =
1228 nla_get_u8(tb[CTA_PROTOINFO_TCP_WSCALE_REPLY]);
Pablo Neira Ayusoc8e20782007-03-14 16:45:19 -07001229 }
Patrick McHardy440f0d52009-06-10 14:32:47 +02001230 spin_unlock_bh(&ct->lock);
Pablo Neira Ayusoc1d10ad2006-01-05 12:19:05 -08001231
1232 return 0;
1233}
Holger Eitzenbergera400c302009-03-25 21:53:39 +01001234
1235static int tcp_nlattr_size(void)
1236{
1237 return nla_total_size(0) /* CTA_PROTOINFO_TCP */
1238 + nla_policy_len(tcp_nla_policy, CTA_PROTOINFO_TCP_MAX + 1);
1239}
1240
1241static int tcp_nlattr_tuple_size(void)
1242{
1243 return nla_policy_len(nf_ct_port_nla_policy, CTA_PROTO_MAX + 1);
1244}
Pablo Neira Ayusoc1d10ad2006-01-05 12:19:05 -08001245#endif
Patrick McHardy933a41e2006-11-29 02:35:18 +01001246
Pablo Neira Ayuso50978462012-02-28 19:13:48 +01001247#if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
1248
1249#include <linux/netfilter/nfnetlink.h>
1250#include <linux/netfilter/nfnetlink_cttimeout.h>
1251
Gao feng8264deb2012-05-28 21:04:23 +00001252static int tcp_timeout_nlattr_to_obj(struct nlattr *tb[],
1253 struct net *net, void *data)
Pablo Neira Ayuso50978462012-02-28 19:13:48 +01001254{
1255 unsigned int *timeouts = data;
Gao feng8264deb2012-05-28 21:04:23 +00001256 struct nf_tcp_net *tn = tcp_pernet(net);
Pablo Neira Ayuso50978462012-02-28 19:13:48 +01001257 int i;
1258
1259 /* set default TCP timeouts. */
1260 for (i=0; i<TCP_CONNTRACK_TIMEOUT_MAX; i++)
Gao feng8264deb2012-05-28 21:04:23 +00001261 timeouts[i] = tn->timeouts[i];
Pablo Neira Ayuso50978462012-02-28 19:13:48 +01001262
1263 if (tb[CTA_TIMEOUT_TCP_SYN_SENT]) {
1264 timeouts[TCP_CONNTRACK_SYN_SENT] =
1265 ntohl(nla_get_be32(tb[CTA_TIMEOUT_TCP_SYN_SENT]))*HZ;
1266 }
1267 if (tb[CTA_TIMEOUT_TCP_SYN_RECV]) {
1268 timeouts[TCP_CONNTRACK_SYN_RECV] =
1269 ntohl(nla_get_be32(tb[CTA_TIMEOUT_TCP_SYN_RECV]))*HZ;
1270 }
1271 if (tb[CTA_TIMEOUT_TCP_ESTABLISHED]) {
1272 timeouts[TCP_CONNTRACK_ESTABLISHED] =
1273 ntohl(nla_get_be32(tb[CTA_TIMEOUT_TCP_ESTABLISHED]))*HZ;
1274 }
1275 if (tb[CTA_TIMEOUT_TCP_FIN_WAIT]) {
1276 timeouts[TCP_CONNTRACK_FIN_WAIT] =
1277 ntohl(nla_get_be32(tb[CTA_TIMEOUT_TCP_FIN_WAIT]))*HZ;
1278 }
1279 if (tb[CTA_TIMEOUT_TCP_CLOSE_WAIT]) {
1280 timeouts[TCP_CONNTRACK_CLOSE_WAIT] =
1281 ntohl(nla_get_be32(tb[CTA_TIMEOUT_TCP_CLOSE_WAIT]))*HZ;
1282 }
1283 if (tb[CTA_TIMEOUT_TCP_LAST_ACK]) {
1284 timeouts[TCP_CONNTRACK_LAST_ACK] =
1285 ntohl(nla_get_be32(tb[CTA_TIMEOUT_TCP_LAST_ACK]))*HZ;
1286 }
1287 if (tb[CTA_TIMEOUT_TCP_TIME_WAIT]) {
1288 timeouts[TCP_CONNTRACK_TIME_WAIT] =
1289 ntohl(nla_get_be32(tb[CTA_TIMEOUT_TCP_TIME_WAIT]))*HZ;
1290 }
1291 if (tb[CTA_TIMEOUT_TCP_CLOSE]) {
1292 timeouts[TCP_CONNTRACK_CLOSE] =
1293 ntohl(nla_get_be32(tb[CTA_TIMEOUT_TCP_CLOSE]))*HZ;
1294 }
1295 if (tb[CTA_TIMEOUT_TCP_SYN_SENT2]) {
1296 timeouts[TCP_CONNTRACK_SYN_SENT2] =
1297 ntohl(nla_get_be32(tb[CTA_TIMEOUT_TCP_SYN_SENT2]))*HZ;
1298 }
1299 if (tb[CTA_TIMEOUT_TCP_RETRANS]) {
1300 timeouts[TCP_CONNTRACK_RETRANS] =
1301 ntohl(nla_get_be32(tb[CTA_TIMEOUT_TCP_RETRANS]))*HZ;
1302 }
1303 if (tb[CTA_TIMEOUT_TCP_UNACK]) {
1304 timeouts[TCP_CONNTRACK_UNACK] =
1305 ntohl(nla_get_be32(tb[CTA_TIMEOUT_TCP_UNACK]))*HZ;
1306 }
1307 return 0;
1308}
1309
1310static int
1311tcp_timeout_obj_to_nlattr(struct sk_buff *skb, const void *data)
1312{
1313 const unsigned int *timeouts = data;
1314
David S. Miller4925a452012-04-01 18:50:08 -04001315 if (nla_put_be32(skb, CTA_TIMEOUT_TCP_SYN_SENT,
1316 htonl(timeouts[TCP_CONNTRACK_SYN_SENT] / HZ)) ||
1317 nla_put_be32(skb, CTA_TIMEOUT_TCP_SYN_RECV,
1318 htonl(timeouts[TCP_CONNTRACK_SYN_RECV] / HZ)) ||
1319 nla_put_be32(skb, CTA_TIMEOUT_TCP_ESTABLISHED,
1320 htonl(timeouts[TCP_CONNTRACK_ESTABLISHED] / HZ)) ||
1321 nla_put_be32(skb, CTA_TIMEOUT_TCP_FIN_WAIT,
1322 htonl(timeouts[TCP_CONNTRACK_FIN_WAIT] / HZ)) ||
1323 nla_put_be32(skb, CTA_TIMEOUT_TCP_CLOSE_WAIT,
1324 htonl(timeouts[TCP_CONNTRACK_CLOSE_WAIT] / HZ)) ||
1325 nla_put_be32(skb, CTA_TIMEOUT_TCP_LAST_ACK,
1326 htonl(timeouts[TCP_CONNTRACK_LAST_ACK] / HZ)) ||
1327 nla_put_be32(skb, CTA_TIMEOUT_TCP_TIME_WAIT,
1328 htonl(timeouts[TCP_CONNTRACK_TIME_WAIT] / HZ)) ||
1329 nla_put_be32(skb, CTA_TIMEOUT_TCP_CLOSE,
1330 htonl(timeouts[TCP_CONNTRACK_CLOSE] / HZ)) ||
1331 nla_put_be32(skb, CTA_TIMEOUT_TCP_SYN_SENT2,
1332 htonl(timeouts[TCP_CONNTRACK_SYN_SENT2] / HZ)) ||
1333 nla_put_be32(skb, CTA_TIMEOUT_TCP_RETRANS,
1334 htonl(timeouts[TCP_CONNTRACK_RETRANS] / HZ)) ||
1335 nla_put_be32(skb, CTA_TIMEOUT_TCP_UNACK,
1336 htonl(timeouts[TCP_CONNTRACK_UNACK] / HZ)))
1337 goto nla_put_failure;
Pablo Neira Ayuso50978462012-02-28 19:13:48 +01001338 return 0;
1339
1340nla_put_failure:
1341 return -ENOSPC;
1342}
1343
1344static const struct nla_policy tcp_timeout_nla_policy[CTA_TIMEOUT_TCP_MAX+1] = {
1345 [CTA_TIMEOUT_TCP_SYN_SENT] = { .type = NLA_U32 },
1346 [CTA_TIMEOUT_TCP_SYN_RECV] = { .type = NLA_U32 },
1347 [CTA_TIMEOUT_TCP_ESTABLISHED] = { .type = NLA_U32 },
1348 [CTA_TIMEOUT_TCP_FIN_WAIT] = { .type = NLA_U32 },
1349 [CTA_TIMEOUT_TCP_CLOSE_WAIT] = { .type = NLA_U32 },
1350 [CTA_TIMEOUT_TCP_LAST_ACK] = { .type = NLA_U32 },
1351 [CTA_TIMEOUT_TCP_TIME_WAIT] = { .type = NLA_U32 },
1352 [CTA_TIMEOUT_TCP_CLOSE] = { .type = NLA_U32 },
1353 [CTA_TIMEOUT_TCP_SYN_SENT2] = { .type = NLA_U32 },
Florian Westphal6d1fafc2012-11-22 01:32:46 +00001354 [CTA_TIMEOUT_TCP_RETRANS] = { .type = NLA_U32 },
1355 [CTA_TIMEOUT_TCP_UNACK] = { .type = NLA_U32 },
Pablo Neira Ayuso50978462012-02-28 19:13:48 +01001356};
1357#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
1358
Patrick McHardy933a41e2006-11-29 02:35:18 +01001359#ifdef CONFIG_SYSCTL
Patrick McHardy933a41e2006-11-29 02:35:18 +01001360static struct ctl_table tcp_sysctl_table[] = {
1361 {
Patrick McHardy933a41e2006-11-29 02:35:18 +01001362 .procname = "nf_conntrack_tcp_timeout_syn_sent",
Patrick McHardy933a41e2006-11-29 02:35:18 +01001363 .maxlen = sizeof(unsigned int),
1364 .mode = 0644,
Alexey Dobriyan6d9f2392008-11-03 18:21:05 -08001365 .proc_handler = proc_dointvec_jiffies,
Patrick McHardy933a41e2006-11-29 02:35:18 +01001366 },
1367 {
Patrick McHardy933a41e2006-11-29 02:35:18 +01001368 .procname = "nf_conntrack_tcp_timeout_syn_recv",
Patrick McHardy933a41e2006-11-29 02:35:18 +01001369 .maxlen = sizeof(unsigned int),
1370 .mode = 0644,
Alexey Dobriyan6d9f2392008-11-03 18:21:05 -08001371 .proc_handler = proc_dointvec_jiffies,
Patrick McHardy933a41e2006-11-29 02:35:18 +01001372 },
1373 {
Patrick McHardy933a41e2006-11-29 02:35:18 +01001374 .procname = "nf_conntrack_tcp_timeout_established",
Patrick McHardy933a41e2006-11-29 02:35:18 +01001375 .maxlen = sizeof(unsigned int),
1376 .mode = 0644,
Alexey Dobriyan6d9f2392008-11-03 18:21:05 -08001377 .proc_handler = proc_dointvec_jiffies,
Patrick McHardy933a41e2006-11-29 02:35:18 +01001378 },
1379 {
Patrick McHardy933a41e2006-11-29 02:35:18 +01001380 .procname = "nf_conntrack_tcp_timeout_fin_wait",
Patrick McHardy933a41e2006-11-29 02:35:18 +01001381 .maxlen = sizeof(unsigned int),
1382 .mode = 0644,
Alexey Dobriyan6d9f2392008-11-03 18:21:05 -08001383 .proc_handler = proc_dointvec_jiffies,
Patrick McHardy933a41e2006-11-29 02:35:18 +01001384 },
1385 {
Patrick McHardy933a41e2006-11-29 02:35:18 +01001386 .procname = "nf_conntrack_tcp_timeout_close_wait",
Patrick McHardy933a41e2006-11-29 02:35:18 +01001387 .maxlen = sizeof(unsigned int),
1388 .mode = 0644,
Alexey Dobriyan6d9f2392008-11-03 18:21:05 -08001389 .proc_handler = proc_dointvec_jiffies,
Patrick McHardy933a41e2006-11-29 02:35:18 +01001390 },
1391 {
Patrick McHardy933a41e2006-11-29 02:35:18 +01001392 .procname = "nf_conntrack_tcp_timeout_last_ack",
Patrick McHardy933a41e2006-11-29 02:35:18 +01001393 .maxlen = sizeof(unsigned int),
1394 .mode = 0644,
Alexey Dobriyan6d9f2392008-11-03 18:21:05 -08001395 .proc_handler = proc_dointvec_jiffies,
Patrick McHardy933a41e2006-11-29 02:35:18 +01001396 },
1397 {
Patrick McHardy933a41e2006-11-29 02:35:18 +01001398 .procname = "nf_conntrack_tcp_timeout_time_wait",
Patrick McHardy933a41e2006-11-29 02:35:18 +01001399 .maxlen = sizeof(unsigned int),
1400 .mode = 0644,
Alexey Dobriyan6d9f2392008-11-03 18:21:05 -08001401 .proc_handler = proc_dointvec_jiffies,
Patrick McHardy933a41e2006-11-29 02:35:18 +01001402 },
1403 {
Patrick McHardy933a41e2006-11-29 02:35:18 +01001404 .procname = "nf_conntrack_tcp_timeout_close",
Patrick McHardy933a41e2006-11-29 02:35:18 +01001405 .maxlen = sizeof(unsigned int),
1406 .mode = 0644,
Alexey Dobriyan6d9f2392008-11-03 18:21:05 -08001407 .proc_handler = proc_dointvec_jiffies,
Patrick McHardy933a41e2006-11-29 02:35:18 +01001408 },
1409 {
Patrick McHardy933a41e2006-11-29 02:35:18 +01001410 .procname = "nf_conntrack_tcp_timeout_max_retrans",
Patrick McHardy933a41e2006-11-29 02:35:18 +01001411 .maxlen = sizeof(unsigned int),
1412 .mode = 0644,
Alexey Dobriyan6d9f2392008-11-03 18:21:05 -08001413 .proc_handler = proc_dointvec_jiffies,
Patrick McHardy933a41e2006-11-29 02:35:18 +01001414 },
1415 {
Patrick McHardyae375042008-07-31 00:38:01 -07001416 .procname = "nf_conntrack_tcp_timeout_unacknowledged",
Patrick McHardyae375042008-07-31 00:38:01 -07001417 .maxlen = sizeof(unsigned int),
1418 .mode = 0644,
Alexey Dobriyan6d9f2392008-11-03 18:21:05 -08001419 .proc_handler = proc_dointvec_jiffies,
Patrick McHardyae375042008-07-31 00:38:01 -07001420 },
1421 {
Patrick McHardy933a41e2006-11-29 02:35:18 +01001422 .procname = "nf_conntrack_tcp_loose",
Patrick McHardy933a41e2006-11-29 02:35:18 +01001423 .maxlen = sizeof(unsigned int),
1424 .mode = 0644,
Alexey Dobriyan6d9f2392008-11-03 18:21:05 -08001425 .proc_handler = proc_dointvec,
Patrick McHardy933a41e2006-11-29 02:35:18 +01001426 },
1427 {
Patrick McHardy933a41e2006-11-29 02:35:18 +01001428 .procname = "nf_conntrack_tcp_be_liberal",
Patrick McHardy933a41e2006-11-29 02:35:18 +01001429 .maxlen = sizeof(unsigned int),
1430 .mode = 0644,
Alexey Dobriyan6d9f2392008-11-03 18:21:05 -08001431 .proc_handler = proc_dointvec,
Patrick McHardy933a41e2006-11-29 02:35:18 +01001432 },
1433 {
Patrick McHardy933a41e2006-11-29 02:35:18 +01001434 .procname = "nf_conntrack_tcp_max_retrans",
Patrick McHardy933a41e2006-11-29 02:35:18 +01001435 .maxlen = sizeof(unsigned int),
1436 .mode = 0644,
Alexey Dobriyan6d9f2392008-11-03 18:21:05 -08001437 .proc_handler = proc_dointvec,
Patrick McHardy933a41e2006-11-29 02:35:18 +01001438 },
Eric W. Biedermanf8572d82009-11-05 13:32:03 -08001439 { }
Patrick McHardy933a41e2006-11-29 02:35:18 +01001440};
Patrick McHardya999e682006-11-29 02:35:20 +01001441
1442#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
1443static struct ctl_table tcp_compat_sysctl_table[] = {
1444 {
Patrick McHardya999e682006-11-29 02:35:20 +01001445 .procname = "ip_conntrack_tcp_timeout_syn_sent",
Patrick McHardya999e682006-11-29 02:35:20 +01001446 .maxlen = sizeof(unsigned int),
1447 .mode = 0644,
Alexey Dobriyan6d9f2392008-11-03 18:21:05 -08001448 .proc_handler = proc_dointvec_jiffies,
Patrick McHardya999e682006-11-29 02:35:20 +01001449 },
1450 {
Jozsef Kadlecsik874ab922009-06-02 13:58:56 +02001451 .procname = "ip_conntrack_tcp_timeout_syn_sent2",
Jozsef Kadlecsik874ab922009-06-02 13:58:56 +02001452 .maxlen = sizeof(unsigned int),
1453 .mode = 0644,
1454 .proc_handler = proc_dointvec_jiffies,
1455 },
1456 {
Patrick McHardya999e682006-11-29 02:35:20 +01001457 .procname = "ip_conntrack_tcp_timeout_syn_recv",
Patrick McHardya999e682006-11-29 02:35:20 +01001458 .maxlen = sizeof(unsigned int),
1459 .mode = 0644,
Alexey Dobriyan6d9f2392008-11-03 18:21:05 -08001460 .proc_handler = proc_dointvec_jiffies,
Patrick McHardya999e682006-11-29 02:35:20 +01001461 },
1462 {
Patrick McHardya999e682006-11-29 02:35:20 +01001463 .procname = "ip_conntrack_tcp_timeout_established",
Patrick McHardya999e682006-11-29 02:35:20 +01001464 .maxlen = sizeof(unsigned int),
1465 .mode = 0644,
Alexey Dobriyan6d9f2392008-11-03 18:21:05 -08001466 .proc_handler = proc_dointvec_jiffies,
Patrick McHardya999e682006-11-29 02:35:20 +01001467 },
1468 {
Patrick McHardya999e682006-11-29 02:35:20 +01001469 .procname = "ip_conntrack_tcp_timeout_fin_wait",
Patrick McHardya999e682006-11-29 02:35:20 +01001470 .maxlen = sizeof(unsigned int),
1471 .mode = 0644,
Alexey Dobriyan6d9f2392008-11-03 18:21:05 -08001472 .proc_handler = proc_dointvec_jiffies,
Patrick McHardya999e682006-11-29 02:35:20 +01001473 },
1474 {
Patrick McHardya999e682006-11-29 02:35:20 +01001475 .procname = "ip_conntrack_tcp_timeout_close_wait",
Patrick McHardya999e682006-11-29 02:35:20 +01001476 .maxlen = sizeof(unsigned int),
1477 .mode = 0644,
Alexey Dobriyan6d9f2392008-11-03 18:21:05 -08001478 .proc_handler = proc_dointvec_jiffies,
Patrick McHardya999e682006-11-29 02:35:20 +01001479 },
1480 {
Patrick McHardya999e682006-11-29 02:35:20 +01001481 .procname = "ip_conntrack_tcp_timeout_last_ack",
Patrick McHardya999e682006-11-29 02:35:20 +01001482 .maxlen = sizeof(unsigned int),
1483 .mode = 0644,
Alexey Dobriyan6d9f2392008-11-03 18:21:05 -08001484 .proc_handler = proc_dointvec_jiffies,
Patrick McHardya999e682006-11-29 02:35:20 +01001485 },
1486 {
Patrick McHardya999e682006-11-29 02:35:20 +01001487 .procname = "ip_conntrack_tcp_timeout_time_wait",
Patrick McHardya999e682006-11-29 02:35:20 +01001488 .maxlen = sizeof(unsigned int),
1489 .mode = 0644,
Alexey Dobriyan6d9f2392008-11-03 18:21:05 -08001490 .proc_handler = proc_dointvec_jiffies,
Patrick McHardya999e682006-11-29 02:35:20 +01001491 },
1492 {
Patrick McHardya999e682006-11-29 02:35:20 +01001493 .procname = "ip_conntrack_tcp_timeout_close",
Patrick McHardya999e682006-11-29 02:35:20 +01001494 .maxlen = sizeof(unsigned int),
1495 .mode = 0644,
Alexey Dobriyan6d9f2392008-11-03 18:21:05 -08001496 .proc_handler = proc_dointvec_jiffies,
Patrick McHardya999e682006-11-29 02:35:20 +01001497 },
1498 {
Patrick McHardya999e682006-11-29 02:35:20 +01001499 .procname = "ip_conntrack_tcp_timeout_max_retrans",
Patrick McHardya999e682006-11-29 02:35:20 +01001500 .maxlen = sizeof(unsigned int),
1501 .mode = 0644,
Alexey Dobriyan6d9f2392008-11-03 18:21:05 -08001502 .proc_handler = proc_dointvec_jiffies,
Patrick McHardya999e682006-11-29 02:35:20 +01001503 },
1504 {
Patrick McHardya999e682006-11-29 02:35:20 +01001505 .procname = "ip_conntrack_tcp_loose",
Patrick McHardya999e682006-11-29 02:35:20 +01001506 .maxlen = sizeof(unsigned int),
1507 .mode = 0644,
Alexey Dobriyan6d9f2392008-11-03 18:21:05 -08001508 .proc_handler = proc_dointvec,
Patrick McHardya999e682006-11-29 02:35:20 +01001509 },
1510 {
Patrick McHardya999e682006-11-29 02:35:20 +01001511 .procname = "ip_conntrack_tcp_be_liberal",
Patrick McHardya999e682006-11-29 02:35:20 +01001512 .maxlen = sizeof(unsigned int),
1513 .mode = 0644,
Alexey Dobriyan6d9f2392008-11-03 18:21:05 -08001514 .proc_handler = proc_dointvec,
Patrick McHardya999e682006-11-29 02:35:20 +01001515 },
1516 {
Patrick McHardya999e682006-11-29 02:35:20 +01001517 .procname = "ip_conntrack_tcp_max_retrans",
Patrick McHardya999e682006-11-29 02:35:20 +01001518 .maxlen = sizeof(unsigned int),
1519 .mode = 0644,
Alexey Dobriyan6d9f2392008-11-03 18:21:05 -08001520 .proc_handler = proc_dointvec,
Patrick McHardya999e682006-11-29 02:35:20 +01001521 },
Eric W. Biedermanf8572d82009-11-05 13:32:03 -08001522 { }
Patrick McHardya999e682006-11-29 02:35:20 +01001523};
1524#endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
Patrick McHardy933a41e2006-11-29 02:35:18 +01001525#endif /* CONFIG_SYSCTL */
1526
Gao fengefa758f2012-06-21 04:36:43 +00001527static int tcp_kmemdup_sysctl_table(struct nf_proto_net *pn,
1528 struct nf_tcp_net *tn)
Gao fengd2ba1fd2012-05-28 21:04:12 +00001529{
1530#ifdef CONFIG_SYSCTL
Gao fengd2ba1fd2012-05-28 21:04:12 +00001531 if (pn->ctl_table)
1532 return 0;
1533
1534 pn->ctl_table = kmemdup(tcp_sysctl_table,
1535 sizeof(tcp_sysctl_table),
1536 GFP_KERNEL);
1537 if (!pn->ctl_table)
1538 return -ENOMEM;
1539
1540 pn->ctl_table[0].data = &tn->timeouts[TCP_CONNTRACK_SYN_SENT];
1541 pn->ctl_table[1].data = &tn->timeouts[TCP_CONNTRACK_SYN_RECV];
1542 pn->ctl_table[2].data = &tn->timeouts[TCP_CONNTRACK_ESTABLISHED];
1543 pn->ctl_table[3].data = &tn->timeouts[TCP_CONNTRACK_FIN_WAIT];
1544 pn->ctl_table[4].data = &tn->timeouts[TCP_CONNTRACK_CLOSE_WAIT];
1545 pn->ctl_table[5].data = &tn->timeouts[TCP_CONNTRACK_LAST_ACK];
1546 pn->ctl_table[6].data = &tn->timeouts[TCP_CONNTRACK_TIME_WAIT];
1547 pn->ctl_table[7].data = &tn->timeouts[TCP_CONNTRACK_CLOSE];
1548 pn->ctl_table[8].data = &tn->timeouts[TCP_CONNTRACK_RETRANS];
1549 pn->ctl_table[9].data = &tn->timeouts[TCP_CONNTRACK_UNACK];
1550 pn->ctl_table[10].data = &tn->tcp_loose;
1551 pn->ctl_table[11].data = &tn->tcp_be_liberal;
1552 pn->ctl_table[12].data = &tn->tcp_max_retrans;
1553#endif
1554 return 0;
1555}
1556
Gao fengefa758f2012-06-21 04:36:43 +00001557static int tcp_kmemdup_compat_sysctl_table(struct nf_proto_net *pn,
1558 struct nf_tcp_net *tn)
Gao fengd2ba1fd2012-05-28 21:04:12 +00001559{
1560#ifdef CONFIG_SYSCTL
1561#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
Gao fengd2ba1fd2012-05-28 21:04:12 +00001562 pn->ctl_compat_table = kmemdup(tcp_compat_sysctl_table,
1563 sizeof(tcp_compat_sysctl_table),
1564 GFP_KERNEL);
1565 if (!pn->ctl_compat_table)
1566 return -ENOMEM;
1567
1568 pn->ctl_compat_table[0].data = &tn->timeouts[TCP_CONNTRACK_SYN_SENT];
1569 pn->ctl_compat_table[1].data = &tn->timeouts[TCP_CONNTRACK_SYN_SENT2];
1570 pn->ctl_compat_table[2].data = &tn->timeouts[TCP_CONNTRACK_SYN_RECV];
1571 pn->ctl_compat_table[3].data = &tn->timeouts[TCP_CONNTRACK_ESTABLISHED];
1572 pn->ctl_compat_table[4].data = &tn->timeouts[TCP_CONNTRACK_FIN_WAIT];
1573 pn->ctl_compat_table[5].data = &tn->timeouts[TCP_CONNTRACK_CLOSE_WAIT];
1574 pn->ctl_compat_table[6].data = &tn->timeouts[TCP_CONNTRACK_LAST_ACK];
1575 pn->ctl_compat_table[7].data = &tn->timeouts[TCP_CONNTRACK_TIME_WAIT];
1576 pn->ctl_compat_table[8].data = &tn->timeouts[TCP_CONNTRACK_CLOSE];
1577 pn->ctl_compat_table[9].data = &tn->timeouts[TCP_CONNTRACK_RETRANS];
1578 pn->ctl_compat_table[10].data = &tn->tcp_loose;
1579 pn->ctl_compat_table[11].data = &tn->tcp_be_liberal;
1580 pn->ctl_compat_table[12].data = &tn->tcp_max_retrans;
1581#endif
1582#endif
1583 return 0;
1584}
1585
Gao fengefa758f2012-06-21 04:36:43 +00001586static int tcp_init_net(struct net *net, u_int16_t proto)
Gao fengd2ba1fd2012-05-28 21:04:12 +00001587{
Gao fengefa758f2012-06-21 04:36:43 +00001588 int ret;
Gao fengd2ba1fd2012-05-28 21:04:12 +00001589 struct nf_tcp_net *tn = tcp_pernet(net);
Gao fengefa758f2012-06-21 04:36:43 +00001590 struct nf_proto_net *pn = &tn->pn;
Gao fengd2ba1fd2012-05-28 21:04:12 +00001591
Gao fengefa758f2012-06-21 04:36:43 +00001592 if (!pn->users) {
1593 int i;
1594
Gao fengd2ba1fd2012-05-28 21:04:12 +00001595 for (i = 0; i < TCP_CONNTRACK_TIMEOUT_MAX; i++)
1596 tn->timeouts[i] = tcp_timeouts[i];
1597
1598 tn->tcp_loose = nf_ct_tcp_loose;
1599 tn->tcp_be_liberal = nf_ct_tcp_be_liberal;
1600 tn->tcp_max_retrans = nf_ct_tcp_max_retrans;
1601 }
1602
Gao fengefa758f2012-06-21 04:36:43 +00001603 if (proto == AF_INET) {
1604 ret = tcp_kmemdup_compat_sysctl_table(pn, tn);
1605 if (ret < 0)
1606 return ret;
Gao fengd2ba1fd2012-05-28 21:04:12 +00001607
Gao fengefa758f2012-06-21 04:36:43 +00001608 ret = tcp_kmemdup_sysctl_table(pn, tn);
1609 if (ret < 0)
1610 nf_ct_kfree_compat_sysctl_table(pn);
1611 } else
1612 ret = tcp_kmemdup_sysctl_table(pn, tn);
Gao fengd2ba1fd2012-05-28 21:04:12 +00001613
Gao fengd2ba1fd2012-05-28 21:04:12 +00001614 return ret;
1615}
1616
Pablo Neira Ayuso08911472012-06-29 05:23:24 +00001617static struct nf_proto_net *tcp_get_net_proto(struct net *net)
1618{
1619 return &net->ct.nf_ct_proto.tcp.pn;
1620}
1621
Patrick McHardy61075af2007-07-14 20:48:19 -07001622struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp4 __read_mostly =
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -08001623{
1624 .l3proto = PF_INET,
Martin Josefsson605dcad2006-11-29 02:35:06 +01001625 .l4proto = IPPROTO_TCP,
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -08001626 .name = "tcp",
1627 .pkt_to_tuple = tcp_pkt_to_tuple,
1628 .invert_tuple = tcp_invert_tuple,
1629 .print_tuple = tcp_print_tuple,
1630 .print_conntrack = tcp_print_conntrack,
1631 .packet = tcp_packet,
Pablo Neira Ayuso2c8503f2012-02-28 18:23:31 +01001632 .get_timeouts = tcp_get_timeouts,
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -08001633 .new = tcp_new,
Patrick McHardy96f6bf82006-04-06 14:19:24 -07001634 .error = tcp_error,
Igor Maravićc0cd1152011-12-12 02:58:24 +00001635#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
Patrick McHardyfdf70832007-09-28 14:37:41 -07001636 .to_nlattr = tcp_to_nlattr,
Holger Eitzenbergera400c302009-03-25 21:53:39 +01001637 .nlattr_size = tcp_nlattr_size,
Patrick McHardyfdf70832007-09-28 14:37:41 -07001638 .from_nlattr = nlattr_to_tcp,
1639 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
1640 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
Holger Eitzenbergera400c302009-03-25 21:53:39 +01001641 .nlattr_tuple_size = tcp_nlattr_tuple_size,
Patrick McHardyf73e9242007-09-28 14:39:55 -07001642 .nla_policy = nf_ct_port_nla_policy,
Pablo Neira Ayusoc1d10ad2006-01-05 12:19:05 -08001643#endif
Pablo Neira Ayuso50978462012-02-28 19:13:48 +01001644#if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
1645 .ctnl_timeout = {
1646 .nlattr_to_obj = tcp_timeout_nlattr_to_obj,
1647 .obj_to_nlattr = tcp_timeout_obj_to_nlattr,
1648 .nlattr_max = CTA_TIMEOUT_TCP_MAX,
1649 .obj_size = sizeof(unsigned int) *
1650 TCP_CONNTRACK_TIMEOUT_MAX,
1651 .nla_policy = tcp_timeout_nla_policy,
1652 },
1653#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
Gao fengefa758f2012-06-21 04:36:43 +00001654 .init_net = tcp_init_net,
Pablo Neira Ayuso08911472012-06-29 05:23:24 +00001655 .get_net_proto = tcp_get_net_proto,
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -08001656};
Patrick McHardy13b18332006-12-02 22:11:25 -08001657EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_tcp4);
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -08001658
Patrick McHardy61075af2007-07-14 20:48:19 -07001659struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp6 __read_mostly =
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -08001660{
1661 .l3proto = PF_INET6,
Martin Josefsson605dcad2006-11-29 02:35:06 +01001662 .l4proto = IPPROTO_TCP,
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -08001663 .name = "tcp",
1664 .pkt_to_tuple = tcp_pkt_to_tuple,
1665 .invert_tuple = tcp_invert_tuple,
1666 .print_tuple = tcp_print_tuple,
1667 .print_conntrack = tcp_print_conntrack,
1668 .packet = tcp_packet,
Pablo Neira Ayuso2c8503f2012-02-28 18:23:31 +01001669 .get_timeouts = tcp_get_timeouts,
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -08001670 .new = tcp_new,
Patrick McHardy96f6bf82006-04-06 14:19:24 -07001671 .error = tcp_error,
Igor Maravićc0cd1152011-12-12 02:58:24 +00001672#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
Patrick McHardyfdf70832007-09-28 14:37:41 -07001673 .to_nlattr = tcp_to_nlattr,
Holger Eitzenbergera400c302009-03-25 21:53:39 +01001674 .nlattr_size = tcp_nlattr_size,
Patrick McHardyfdf70832007-09-28 14:37:41 -07001675 .from_nlattr = nlattr_to_tcp,
1676 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
1677 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
Holger Eitzenbergera400c302009-03-25 21:53:39 +01001678 .nlattr_tuple_size = tcp_nlattr_tuple_size,
Patrick McHardyf73e9242007-09-28 14:39:55 -07001679 .nla_policy = nf_ct_port_nla_policy,
Pablo Neira Ayusoc1d10ad2006-01-05 12:19:05 -08001680#endif
Pablo Neira Ayuso50978462012-02-28 19:13:48 +01001681#if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
1682 .ctnl_timeout = {
1683 .nlattr_to_obj = tcp_timeout_nlattr_to_obj,
1684 .obj_to_nlattr = tcp_timeout_obj_to_nlattr,
1685 .nlattr_max = CTA_TIMEOUT_TCP_MAX,
1686 .obj_size = sizeof(unsigned int) *
1687 TCP_CONNTRACK_TIMEOUT_MAX,
1688 .nla_policy = tcp_timeout_nla_policy,
1689 },
1690#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
Gao fengefa758f2012-06-21 04:36:43 +00001691 .init_net = tcp_init_net,
Pablo Neira Ayuso08911472012-06-29 05:23:24 +00001692 .get_net_proto = tcp_get_net_proto,
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -08001693};
Patrick McHardy13b18332006-12-02 22:11:25 -08001694EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_tcp6);